gfapi: introduce glfs_readdir() and glfs_readdirplus() APIs
Change-Id: I6b233bf647585675f233898351bf593f251716cc BUG: 839950 Signed-off-by: Anand Avati <avati@redhat.com> Reviewed-on: http://review.gluster.org/6201 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Raghavendra Talur <rtalur@redhat.com>
This commit is contained in:
parent
eeac099cf4
commit
c1109ed6c6
@ -13,7 +13,15 @@
|
||||
#include "glfs-mem-types.h"
|
||||
#include "syncop.h"
|
||||
#include "glfs.h"
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef NAME_MAX
|
||||
#define GF_NAME_MAX NAME_MAX
|
||||
#else
|
||||
#define GF_NAME_MAX 255
|
||||
#endif
|
||||
|
||||
#define READDIRBUF_SIZE (sizeof(struct dirent) + GF_NAME_MAX + 1)
|
||||
|
||||
int
|
||||
glfs_loc_link (loc_t *loc, struct iatt *iatt)
|
||||
@ -1918,7 +1926,7 @@ gf_dirent_to_dirent (gf_dirent_t *gf_dirent, struct dirent *dirent)
|
||||
dirent->d_namlen = strlen (gf_dirent->d_name);
|
||||
#endif
|
||||
|
||||
strncpy (dirent->d_name, gf_dirent->d_name, 256);
|
||||
strncpy (dirent->d_name, gf_dirent->d_name, GF_NAME_MAX + 1);
|
||||
}
|
||||
|
||||
|
||||
@ -2012,16 +2020,56 @@ glfd_entry_next (struct glfs_fd *glfd, int plus)
|
||||
}
|
||||
|
||||
|
||||
static struct dirent *
|
||||
glfs_readdirbuf_get (struct glfs_fd *glfd)
|
||||
{
|
||||
struct dirent *buf = NULL;
|
||||
|
||||
LOCK (&glfd->fd->lock);
|
||||
{
|
||||
buf = glfd->readdirbuf;
|
||||
if (buf) {
|
||||
memset (buf, 0, READDIRBUF_SIZE);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
buf = GF_CALLOC (1, READDIRBUF_SIZE, glfs_mt_readdirbuf_t);
|
||||
if (!buf) {
|
||||
errno = ENOMEM;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
glfd->readdirbuf = buf;
|
||||
}
|
||||
unlock:
|
||||
UNLOCK (&glfd->fd->lock);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_readdirplus_r (struct glfs_fd *glfd, struct stat *stat, struct dirent *buf,
|
||||
glfs_readdirplus_r (struct glfs_fd *glfd, struct stat *stat, struct dirent *ext,
|
||||
struct dirent **res)
|
||||
{
|
||||
int ret = 0;
|
||||
gf_dirent_t *entry = NULL;
|
||||
struct dirent *buf = NULL;
|
||||
|
||||
__glfs_entry_fd (glfd);
|
||||
|
||||
errno = 0;
|
||||
|
||||
if (ext)
|
||||
buf = ext;
|
||||
else
|
||||
buf = glfs_readdirbuf_get (glfd);
|
||||
|
||||
if (!buf) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry = glfd_entry_next (glfd, !!stat);
|
||||
if (errno)
|
||||
ret = -1;
|
||||
@ -2050,6 +2098,28 @@ glfs_readdir_r (struct glfs_fd *glfd, struct dirent *buf, struct dirent **res)
|
||||
}
|
||||
|
||||
|
||||
struct dirent *
|
||||
glfs_readdirplus (struct glfs_fd *glfd, struct stat *stat)
|
||||
{
|
||||
struct dirent *res = NULL;
|
||||
int ret = -1;
|
||||
|
||||
ret = glfs_readdirplus_r (glfd, stat, NULL, &res);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct dirent *
|
||||
glfs_readdir (struct glfs_fd *glfd)
|
||||
{
|
||||
return glfs_readdirplus (glfd, NULL);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
glfs_statvfs (struct glfs *fs, const char *path, struct statvfs *buf)
|
||||
{
|
||||
|
@ -95,6 +95,7 @@ struct glfs_fd {
|
||||
fd_t *fd; /* Currently guared by @fs->mutex. TODO: per-glfd lock */
|
||||
struct list_head entries;
|
||||
gf_dirent_t *next;
|
||||
struct dirent *readdirbuf;
|
||||
};
|
||||
|
||||
/* glfs object handle introduced for the alternate gfapi implementation based
|
||||
|
@ -24,6 +24,7 @@ enum glfs_mem_types_ {
|
||||
glfs_mt_volfile_t,
|
||||
glfs_mt_xlator_cmdline_option_t,
|
||||
glfs_mt_glfs_object_t,
|
||||
glfs_mt_readdirbuf_t,
|
||||
glfs_mt_end
|
||||
|
||||
};
|
||||
|
@ -384,6 +384,9 @@ glfs_fd_destroy (struct glfs_fd *glfd)
|
||||
|
||||
if (glfd->fd)
|
||||
fd_unref (glfd->fd);
|
||||
|
||||
GF_FREE (glfd->readdirbuf);
|
||||
|
||||
GF_FREE (glfd);
|
||||
}
|
||||
|
||||
|
@ -468,12 +468,31 @@ int glfs_link (glfs_t *fs, const char *oldpath, const char *newpath);
|
||||
|
||||
glfs_fd_t *glfs_opendir (glfs_t *fs, const char *path);
|
||||
|
||||
/*
|
||||
* @glfs_readdir_r and @glfs_readdirplus_r ARE thread safe AND re-entrant,
|
||||
* but the interface has ambiguity about the size of @dirent to be allocated
|
||||
* before calling the APIs. 512 byte buffer (for @dirent) is sufficient for
|
||||
* all known systems which are tested againt glusterfs/gfapi, but may be
|
||||
* insufficient in the future.
|
||||
*/
|
||||
|
||||
int glfs_readdir_r (glfs_fd_t *fd, struct dirent *dirent,
|
||||
struct dirent **result);
|
||||
|
||||
int glfs_readdirplus_r (glfs_fd_t *fd, struct stat *stat, struct dirent *dirent,
|
||||
struct dirent **result);
|
||||
|
||||
/*
|
||||
* @glfs_readdir and @glfs_readdirplus are NEITHER thread safe NOR re-entrant
|
||||
* when called on the same directory handle. However they ARE thread safe
|
||||
* AND re-entrant when called on different directory handles (which may be
|
||||
* referring to the same directory too.)
|
||||
*/
|
||||
|
||||
struct dirent *glfs_readdir (glfs_fd_t *fd);
|
||||
|
||||
struct dirent *glfs_readdirplus (glfs_fd_t *fd, struct stat *stat);
|
||||
|
||||
long glfs_telldir (glfs_fd_t *fd);
|
||||
|
||||
void glfs_seekdir (glfs_fd_t *fd, long offset);
|
||||
|
Loading…
x
Reference in New Issue
Block a user