From 65bd768543c4de3d2ffd8d17efbd79e1e03666a4 Mon Sep 17 00:00:00 2001 From: Raghavendra G Date: Mon, 30 Mar 2009 06:33:06 -0700 Subject: libglusterfsclient - move lookup timeout related code to libgf_client_path_lookup - this simplifies the resolution of path to inode, the apis which receive path as argument just need to call libgf_client_path_lookup for path->inode translation. Signed-off-by: Anand V. Avati --- libglusterfsclient/src/libglusterfsclient-dentry.c | 78 +++++- .../src/libglusterfsclient-internals.h | 47 +++- libglusterfsclient/src/libglusterfsclient.c | 283 ++++++--------------- 3 files changed, 181 insertions(+), 227 deletions(-) (limited to 'libglusterfsclient') 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 (¤t, 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 (¤t, 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 (¤t, 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 (¤t, 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 (¤t, 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); -- cgit