summaryrefslogtreecommitdiffstats
path: root/libglusterfsclient/src/libglusterfsclient-dentry.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfsclient/src/libglusterfsclient-dentry.c')
-rw-r--r--libglusterfsclient/src/libglusterfsclient-dentry.c78
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 (&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;
}