diff options
| author | Anand Avati <avati@redhat.com> | 2013-10-30 14:30:26 -0700 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2013-11-13 10:48:18 -0800 | 
| commit | c1109ed6c6c7bff0df22c304158e9f392f83cf59 (patch) | |
| tree | 4ca5b363a23ea1ece521d1a234fb61293f0e507c /api/src | |
| parent | eeac099cf405849f07989c410968e77f95acdc77 (diff) | |
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>
Diffstat (limited to 'api/src')
| -rw-r--r-- | api/src/glfs-fops.c | 74 | ||||
| -rw-r--r-- | api/src/glfs-internal.h | 1 | ||||
| -rw-r--r-- | api/src/glfs-mem-types.h | 1 | ||||
| -rw-r--r-- | api/src/glfs.c | 3 | ||||
| -rw-r--r-- | api/src/glfs.h | 19 | 
5 files changed, 96 insertions, 2 deletions
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c index 7572a94f2ac..10bb7d38b4d 100644 --- a/api/src/glfs-fops.c +++ b/api/src/glfs-fops.c @@ -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)  { diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h index 1b1c1c7f624..ec1d5579df7 100644 --- a/api/src/glfs-internal.h +++ b/api/src/glfs-internal.h @@ -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 diff --git a/api/src/glfs-mem-types.h b/api/src/glfs-mem-types.h index 25b155b9c8a..3301b3da537 100644 --- a/api/src/glfs-mem-types.h +++ b/api/src/glfs-mem-types.h @@ -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  }; diff --git a/api/src/glfs.c b/api/src/glfs.c index ed731eae958..e94419c2d57 100644 --- a/api/src/glfs.c +++ b/api/src/glfs.c @@ -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);  } diff --git a/api/src/glfs.h b/api/src/glfs.h index d179b87ba42..18fda496ea2 100644 --- a/api/src/glfs.h +++ b/api/src/glfs.h @@ -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);  | 
