summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfsclient/src/libglusterfsclient-dentry.c78
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient-internals.h47
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient.c283
3 files changed, 181 insertions, 227 deletions
diff --git a/libglusterfsclient/src/libglusterfsclient-dentry.c b/libglusterfsclient/src/libglusterfsclient-dentry.c
index ee2389c044e..cbaf587bf64 100644
--- a/libglusterfsclient/src/libglusterfsclient-dentry.c
+++ b/libglusterfsclient/src/libglusterfsclient-dentry.c
@@ -93,6 +93,7 @@ strcpy_till (char *dest, const char *dname, char delim)
static inode_t *
__libgf_client_path_to_parenti (inode_table_t *itable,
const char *path,
+ time_t lookup_timeout,
char **reslv)
{
char *resolved_till = NULL;
@@ -103,6 +104,10 @@ __libgf_client_path_to_parenti (inode_table_t *itable,
inode_t *curr = NULL;
inode_t *parent = NULL;
size_t pathlen = 0;
+ time_t current, prev;
+ libglusterfs_client_inode_ctx_t *inode_ctx = NULL;
+ uint64_t ptr = 0;
+ int32_t op_ret = 0;
pathlen = STRLEN_0 (path);
resolved_till = CALLOC (1, pathlen);
@@ -122,6 +127,27 @@ __libgf_client_path_to_parenti (inode_table_t *itable,
break;
}
+ op_ret = inode_ctx_get (curr, itable->xl, &ptr);
+ if (op_ret == -1) {
+ errno = EINVAL;
+ break;
+ }
+
+ inode_ctx = (libglusterfs_client_inode_ctx_t *)(long)ptr;
+ memset (&current, 0, sizeof (current));
+ current = time (NULL);
+
+ pthread_mutex_lock (&inode_ctx->lock);
+ {
+ prev = inode_ctx->previous_lookup_time;
+ }
+ pthread_mutex_unlock (&inode_ctx->lock);
+
+ if ((prev < 0)
+ || (lookup_timeout < (current - prev))) {
+ break;
+ }
+
/* It is OK to append the component even if it is the
last component in the path, because, if 'next_component'
returns NULL, @parent will remain the same and
@@ -192,16 +218,15 @@ libgf_client_update_resolved (const char *path, char *resolved)
/* __do_path_resolve - resolve @loc->path into @loc->inode and @loc->parent. also
* update the dentry cache
*
- * @loc - loc to resolve.
- * @ctx - libglusterfsclient context
+ * @loc - loc to resolve.
+ * @ctx - libglusterfsclient context
*
* return - 0 on success
* -1 on failure
*
*/
static int32_t
-__do_path_resolve (loc_t *loc,
- libglusterfs_client_ctx_t *ctx)
+__do_path_resolve (loc_t *loc, libglusterfs_client_ctx_t *ctx)
{
int32_t op_ret = -1;
char *resolved = NULL;
@@ -210,6 +235,9 @@ __do_path_resolve (loc_t *loc,
loc_t new_loc = {0, };
char *pathname = NULL, *directory = NULL;
char *file = NULL;
+ time_t current, prev;
+ libglusterfs_client_inode_ctx_t *inode_ctx = NULL;
+ uint64_t ptr = 0;
parent = loc->parent;
if (parent) {
@@ -222,6 +250,7 @@ __do_path_resolve (loc_t *loc,
resolved = dirname (resolved);
} else {
parent = __libgf_client_path_to_parenti (ctx->itable, loc->path,
+ ctx->lookup_timeout,
&resolved);
}
@@ -261,10 +290,29 @@ __do_path_resolve (loc_t *loc,
new_loc.inode = inode_search (ctx->itable, parent->ino, file);
if (new_loc.inode) {
- dentry = dentry_search_for_inode (new_loc.inode,
- parent->ino, file);
+ op_ret = inode_ctx_get (new_loc.inode, ctx->itable->xl,
+ &ptr);
+ if (op_ret != -1) {
+ inode_ctx = (libglusterfs_client_inode_ctx_t *)(long)ptr;
+ memset (&current, 0, sizeof (current));
+ current = time (NULL);
+
+ pthread_mutex_lock (&inode_ctx->lock);
+ {
+ prev = inode_ctx->previous_lookup_time;
+ }
+ pthread_mutex_unlock (&inode_ctx->lock);
+
+ if ((prev >= 0)
+ && (ctx->lookup_timeout
+ >= (current - prev))) {
+ dentry = dentry_search_for_inode (new_loc.inode,
+ parent->ino,
+ file);
+ }
+ }
}
-
+
if (dentry == NULL) {
op_ret = libgf_client_lookup (ctx, &new_loc, NULL, NULL,
0);
@@ -286,22 +334,24 @@ __do_path_resolve (loc_t *loc,
pathname = NULL;
}
- pathname = strdup (loc->path);
- file = basename (pathname);
+ pathname = strdup (loc->path);
+ file = basename (pathname);
inode = inode_search (ctx->itable, parent->ino, file);
if (!inode) {
- libgf_client_loc_fill (&new_loc, ctx, 0, parent->ino, file);
+ libgf_client_loc_fill (&new_loc, ctx, 0, parent->ino,
+ file);
- op_ret = libgf_client_lookup (ctx, &new_loc, NULL, NULL, 0);
+ op_ret = libgf_client_lookup (ctx, &new_loc, NULL, NULL,
+ 0);
if (op_ret == -1) {
- /* parent is resolved, file referred by the path may not
- be present on the storage*/
+ /* parent is resolved, file referred by the
+ path may not be present on the storage*/
if (strcmp (loc->path, "/") != 0) {
op_ret = 0;
}
- libgf_client_loc_wipe (&new_loc);
+ libgf_client_loc_wipe (&new_loc);
goto out;
}
diff --git a/libglusterfsclient/src/libglusterfsclient-internals.h b/libglusterfsclient/src/libglusterfsclient-internals.h
index f9e3fc4288a..a547da3039e 100755
--- a/libglusterfsclient/src/libglusterfsclient-internals.h
+++ b/libglusterfsclient/src/libglusterfsclient-internals.h
@@ -65,6 +65,52 @@ typedef struct {
}fop;
}libgf_client_local_t;
+typedef struct {
+ pthread_cond_t init_con_established;
+ pthread_mutex_t lock;
+ char complete;
+}libglusterfs_client_private_t;
+
+typedef struct {
+ pthread_mutex_t lock;
+ uint32_t previous_lookup_time;
+ uint32_t previous_stat_time;
+ struct stat stbuf;
+} libglusterfs_client_inode_ctx_t;
+
+typedef struct {
+ pthread_mutex_t lock;
+ off_t offset;
+ libglusterfs_client_ctx_t *ctx;
+} libglusterfs_client_fd_ctx_t;
+
+typedef struct libglusterfs_client_async_local {
+ void *cbk_data;
+ union {
+ struct {
+ fd_t *fd;
+ glusterfs_readv_cbk_t cbk;
+ }readv_cbk;
+
+ struct {
+ fd_t *fd;
+ glusterfs_write_cbk_t cbk;
+ }write_cbk;
+
+ struct {
+ fd_t *fd;
+ }close_cbk;
+
+ struct {
+ void *buf;
+ size_t size;
+ loc_t *loc;
+ char is_revalidate;
+ glusterfs_get_cbk_t cbk;
+ }lookup_cbk;
+ }fop;
+}libglusterfs_client_async_local_t;
+
#define LIBGF_STACK_WIND_AND_WAIT(frame, rfn, obj, fn, params ...) \
do { \
STACK_WIND (frame, rfn, obj, fn, params); \
@@ -79,7 +125,6 @@ typedef struct {
} while (0)
-
#define LIBGF_CLIENT_SIGNAL(signal_handler_list, signo, handler) \
do { \
libgf_client_signal_handler_t *libgf_handler = CALLOC (1, \
diff --git a/libglusterfsclient/src/libglusterfsclient.c b/libglusterfsclient/src/libglusterfsclient.c
index a118f2e408b..c9020247f9d 100755
--- a/libglusterfsclient/src/libglusterfsclient.c
+++ b/libglusterfsclient/src/libglusterfsclient.c
@@ -44,52 +44,6 @@
#define XLATOR_NAME "libglusterfsclient"
#define LIBGLUSTERFS_INODE_TABLE_LRU_LIMIT 1000 //14057
-typedef struct {
- pthread_cond_t init_con_established;
- pthread_mutex_t lock;
- char complete;
-}libglusterfs_client_private_t;
-
-typedef struct {
- pthread_mutex_t lock;
- uint32_t previous_lookup_time;
- uint32_t previous_stat_time;
- struct stat stbuf;
-} libglusterfs_client_inode_ctx_t;
-
-typedef struct {
- pthread_mutex_t lock;
- off_t offset;
- libglusterfs_client_ctx_t *ctx;
-} libglusterfs_client_fd_ctx_t;
-
-typedef struct libglusterfs_client_async_local {
- void *cbk_data;
- union {
- struct {
- fd_t *fd;
- glusterfs_readv_cbk_t cbk;
- }readv_cbk;
-
- struct {
- fd_t *fd;
- glusterfs_write_cbk_t cbk;
- }write_cbk;
-
- struct {
- fd_t *fd;
- }close_cbk;
-
- struct {
- void *buf;
- size_t size;
- loc_t *loc;
- char is_revalidate;
- glusterfs_get_cbk_t cbk;
- }lookup_cbk;
- }fop;
-}libglusterfs_client_async_local_t;
-
static inline xlator_t *
libglusterfs_graph (xlator_t *graph);
@@ -1561,8 +1515,6 @@ glusterfs_open (glusterfs_handle_t handle,
loc_t loc = {0, };
long op_ret = 0;
fd_t *fd = NULL;
- struct stat stbuf;
- char lookup_required = 1;
int32_t ret = -1;
xlator_t *this = NULL;
libglusterfs_client_ctx_t *ctx = handle;
@@ -1576,18 +1528,23 @@ glusterfs_open (glusterfs_handle_t handle,
loc.path = strdup (path);
op_ret = libgf_client_path_lookup (&loc, ctx, 1);
- if (op_ret == -1) {
+ if ((op_ret == -1) && ((errno != ENOENT)
+ && ((flags & O_CREAT) != O_CREAT))) {
gf_log ("libglusterfsclient",
GF_LOG_ERROR,
"path lookup failed for (%s)", path);
goto out;
}
- pathname = strdup (path);
- name = basename (pathname);
+ if (!op_ret && ((flags & O_CREAT) == O_CREAT)
+ && ((flags & O_EXCL) == O_EXCL)) {
+ errno = EEXIST;
+ op_ret = -1;
+ goto out;
+ }
- op_ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, name);
- if (op_ret == -1) {
+ ret = libgf_client_loc_fill (&loc, ctx, 0, loc.parent->ino, name);
+ if (ret == -1) {
gf_log ("libglusterfsclient",
GF_LOG_ERROR,
"libgf_client_loc_fill returned -1, returning EINVAL");
@@ -1595,110 +1552,76 @@ glusterfs_open (glusterfs_handle_t handle,
goto out;
}
- this = ctx->gf_ctx.graph;
-
- if (loc.inode) {
- libglusterfs_client_inode_ctx_t *inode_ctx = NULL;
- time_t current, prev;
- uint64_t ptr = 0;
-
- ret = inode_ctx_get (loc.inode, this, &ptr);
- if (ret == 0) {
- inode_ctx = (libglusterfs_client_inode_ctx_t *)(long)ptr;
- memset (&current, 0, sizeof (current));
+ pathname = strdup (path);
+ name = basename (pathname);
- pthread_mutex_lock (&inode_ctx->lock);
- {
- prev = inode_ctx->previous_lookup_time;
- }
- pthread_mutex_unlock (&inode_ctx->lock);
+ this = ctx->gf_ctx.graph;
+ fd = fd_create (loc.inode, 0);
+ fd->flags = flags;
- current = time (NULL);
- if ((prev >= 0)
- && (ctx->lookup_timeout >= (current - prev))) {
- lookup_required = 0;
- }
+ if (!op_ret) {
+ if (S_ISDIR (loc.inode->st_mode)) {
+ if (((flags & O_RDONLY) == O_RDONLY) &&
+ ((flags & O_WRONLY) == 0) &&
+ ((flags & O_RDWR) == 0)) {
+ op_ret = libgf_client_opendir (ctx,
+ &loc, fd);
+ } else {
+ op_ret = -1;
+ errno = EISDIR;
+ }
+ } else {
+ op_ret = libgf_client_open (ctx, &loc, fd,
+ flags);
}
+ } else {
+ op_ret = libgf_client_creat (ctx, &loc, fd, flags,
+ mode);
}
- if (lookup_required) {
- op_ret = libgf_client_lookup (ctx, &loc, &stbuf, NULL, NULL);
- if (!op_ret && ((flags & O_CREAT) == O_CREAT)
- && ((flags & O_EXCL) == O_EXCL)) {
- errno = EEXIST;
- op_ret = -1;
+ if (op_ret == -1) {
+ fd_unref (fd);
+ fd = NULL;
+ } else {
+ libglusterfs_client_fd_ctx_t *fd_ctx = NULL;
+ libglusterfs_client_inode_ctx_t *inode_ctx = NULL;
+ data_t *ctx_data = NULL;
+
+ ctx_data = dict_get (fd->ctx, XLATOR_NAME);
+ if (!ctx_data) {
+ fd_ctx = CALLOC (1, sizeof (*fd_ctx));
+ ERR_ABORT (fd_ctx);
+ pthread_mutex_init (&fd_ctx->lock, NULL);
}
- }
-
- if (!op_ret || ((op_ret == -1) && (errno == ENOENT)
- && ((flags & O_CREAT) == O_CREAT))) {
- fd = fd_create (loc.inode, 0);
- fd->flags = flags;
- if (!op_ret) {
- if (S_ISDIR (loc.inode->st_mode)) {
- if (((flags & O_RDONLY) == O_RDONLY) &&
- ((flags & O_WRONLY) == 0) &&
- ((flags & O_RDWR) == 0)) {
- op_ret = libgf_client_opendir (ctx,
- &loc, fd);
- } else {
- op_ret = -1;
- errno = EISDIR;
- }
- } else {
- op_ret = libgf_client_open (ctx, &loc, fd,
- flags);
- }
- } else {
- op_ret = libgf_client_creat (ctx, &loc, fd, flags,
- mode);
+ pthread_mutex_lock (&fd_ctx->lock);
+ {
+ fd_ctx->ctx = ctx;
}
+ pthread_mutex_unlock (&fd_ctx->lock);
- if (op_ret == -1) {
- fd_unref (fd);
- fd = NULL;
- } else {
- libglusterfs_client_fd_ctx_t *fd_ctx = NULL;
- libglusterfs_client_inode_ctx_t *inode_ctx = NULL;
- data_t *ctx_data = NULL;
-
- ctx_data = dict_get (fd->ctx, XLATOR_NAME);
- if (!ctx_data) {
- fd_ctx = CALLOC (1, sizeof (*fd_ctx));
- ERR_ABORT (fd_ctx);
- pthread_mutex_init (&fd_ctx->lock, NULL);
- }
-
- pthread_mutex_lock (&fd_ctx->lock);
- {
- fd_ctx->ctx = ctx;
- }
- pthread_mutex_unlock (&fd_ctx->lock);
-
- if (!ctx_data) {
- dict_set (fd->ctx, XLATOR_NAME,
- data_from_dynptr (fd_ctx,
- sizeof (*fd_ctx)));
- }
+ if (!ctx_data) {
+ dict_set (fd->ctx, XLATOR_NAME,
+ data_from_dynptr (fd_ctx,
+ sizeof (*fd_ctx)));
+ }
- if ((flags & O_TRUNC) && ((flags & O_RDWR)
- || (flags & O_WRONLY))) {
- uint64_t ptr = 0;
- ret = inode_ctx_get (fd->inode, this, &ptr);
- if (ret == 0) {
- inode_ctx = (libglusterfs_client_inode_ctx_t *)(long)ptr;
- if (S_ISREG (inode_ctx->stbuf.st_mode)) {
- inode_ctx->stbuf.st_size = 0;
- inode_ctx->stbuf.st_blocks = 0;
- }
- } else {
- gf_log ("libglusterfsclient",
- GF_LOG_WARNING,
- "inode_ctx is NULL for inode (%p) belonging to fd (%p)",
- fd->inode, fd);
- }
- }
+ if ((flags & O_TRUNC) && ((flags & O_RDWR)
+ || (flags & O_WRONLY))) {
+ uint64_t ptr = 0;
+ ret = inode_ctx_get (fd->inode, this, &ptr);
+ if (ret == 0) {
+ inode_ctx = (libglusterfs_client_inode_ctx_t *)(long)ptr;
+ if (S_ISREG (inode_ctx->stbuf.st_mode)) {
+ inode_ctx->stbuf.st_size = 0;
+ inode_ctx->stbuf.st_blocks = 0;
+ }
+ } else {
+ gf_log ("libglusterfsclient",
+ GF_LOG_WARNING,
+ "inode_ctx is NULL for inode (%p) belonging to fd (%p)",
+ fd->inode, fd);
+ }
}
}
@@ -1854,7 +1777,6 @@ glusterfs_setxattr (glusterfs_handle_t handle,
{
int32_t op_ret = 0;
loc_t loc = {0, };
- char lookup_required = 1;
xlator_t *this = NULL;
libglusterfs_client_ctx_t *ctx = handle;
char *file = NULL;
@@ -1887,36 +1809,6 @@ glusterfs_setxattr (glusterfs_handle_t handle,
}
this = ctx->gf_ctx.graph;
- if (loc.inode) {
- time_t current, prev;
- libglusterfs_client_inode_ctx_t *inode_ctx = NULL;
- uint64_t ptr = 0;
-
- op_ret = inode_ctx_get (loc.inode, this, &ptr);
- if (op_ret == -1) {
- errno = EINVAL;
- goto out;
- }
-
- inode_ctx = (libglusterfs_client_inode_ctx_t *)(long)ptr;
- memset (&current, 0, sizeof (current));
- current = time (NULL);
-
- pthread_mutex_lock (&inode_ctx->lock);
- {
- prev = inode_ctx->previous_lookup_time;
- }
- pthread_mutex_unlock (&inode_ctx->lock);
-
- if ((prev >= 0) && ctx->lookup_timeout >= (current - prev)) {
- lookup_required = 0;
- }
- }
-
- if (lookup_required) {
- op_ret = libgf_client_lookup (ctx, &loc, NULL, NULL, NULL);
- }
-
if (!op_ret)
op_ret = libgf_client_setxattr (ctx, &loc, name, value, size,
flags);
@@ -1977,7 +1869,7 @@ glusterfs_fsetxattr (glusterfs_file_t fd,
}
this = ctx->gf_ctx.graph;
- if (loc.inode) {
+ if (loc.inode) {
time_t current, prev;
libglusterfs_client_inode_ctx_t *inode_ctx = NULL;
uint64_t ptr = 0;
@@ -3159,7 +3051,6 @@ glusterfs_stat (glusterfs_handle_t handle,
{
int32_t op_ret = 0;
loc_t loc = {0, };
- char lookup_required = 1;
libglusterfs_client_ctx_t *ctx = handle;
xlator_t *this = NULL;
char *name = NULL, *pathname = NULL;
@@ -3192,42 +3083,10 @@ glusterfs_stat (glusterfs_handle_t handle,
}
this = ctx->gf_ctx.graph;
- if (loc.inode) {
- time_t current, prev;
- libglusterfs_client_inode_ctx_t *inode_ctx = NULL;
- uint64_t ptr = 0;
-
- op_ret = inode_ctx_get (loc.inode, this, &ptr);
- if (op_ret == -1) {
- inode_unref (loc.inode);
- errno = EINVAL;
- goto out;
- }
-
- inode_ctx = (libglusterfs_client_inode_ctx_t *)(long)ptr;
- memset (&current, 0, sizeof (current));
- current = time (NULL);
-
- pthread_mutex_lock (&inode_ctx->lock);
- {
- prev = inode_ctx->previous_lookup_time;
- }
- pthread_mutex_unlock (&inode_ctx->lock);
-
- if (prev >= 0 && ctx->lookup_timeout >= (current - prev)) {
- lookup_required = 0;
- }
- }
-
- if (lookup_required) {
- op_ret = libgf_client_lookup (ctx, &loc, buf, NULL, NULL);
- }
-
if (!op_ret) {
op_ret = libgf_client_stat (ctx, &loc, buf);
}
-
out:
if (pathname) {
FREE (pathname);