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:
Anand Avati 2013-10-30 14:30:26 -07:00
parent eeac099cf4
commit c1109ed6c6
5 changed files with 96 additions and 2 deletions

View File

@ -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)
{

View File

@ -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

View File

@ -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
};

View File

@ -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);
}

View File

@ -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);