diff options
Diffstat (limited to 'libglusterfsclient/src/libglusterfsclient-dentry.c')
| -rw-r--r-- | libglusterfsclient/src/libglusterfsclient-dentry.c | 78 | 
1 files changed, 64 insertions, 14 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 (¤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;                  }  | 
