diff options
Diffstat (limited to 'xlators/features/snapview-client/src/snapview-client.c')
-rw-r--r-- | xlators/features/snapview-client/src/snapview-client.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/xlators/features/snapview-client/src/snapview-client.c b/xlators/features/snapview-client/src/snapview-client.c index 3ddb284bfbb..4ec2bd87c28 100644 --- a/xlators/features/snapview-client/src/snapview-client.c +++ b/xlators/features/snapview-client/src/snapview-client.c @@ -1665,6 +1665,14 @@ gf_svc_readdirp_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, dict_unref (xdata); if (op_ret) { + if (op_errno == ESTALE && !local->revalidate) { + local->revalidate = 1; + ret = gf_svc_special_dir_revalidate_lookup (frame, + this); + + if (!ret) + return 0; + } op_ret = 0; op_errno = ENOENT; goto out; @@ -1714,6 +1722,75 @@ out: return 0; } +int +gf_svc_special_dir_revalidate_lookup (call_frame_t *frame, xlator_t *this) +{ + svc_private_t *private = NULL; + svc_local_t *local = NULL; + loc_t *loc = NULL; + dict_t *tmp_xdata = NULL; + char *path = NULL; + int ret = -1; + + GF_VALIDATE_OR_GOTO ("snapview-client", this, out); + GF_VALIDATE_OR_GOTO (this->name, this->private, out); + + private = this->private; + + local = frame->local; + loc = &local->loc; + + inode_unref (loc->inode); + loc->inode = inode_new (loc->parent->table); + if (!loc->inode) { + gf_log (this->name, GF_LOG_ERROR, "failed to " + "allocate new inode"); + goto out; + } + + gf_uuid_copy (local->loc.gfid, loc->inode->gfid); + ret = inode_path (loc->parent, private->path, &path); + if (ret < 0) + goto out; + + if (loc->path) + GF_FREE ((char *)loc->path); + + loc->path = gf_strdup (path); + if (loc->path) { + if (!loc->name || + (loc->name && !strcmp (loc->name, ""))) { + loc->name = strrchr (loc->path, '/'); + if (loc->name) + loc->name++; + } + } else + loc->path = NULL; + + tmp_xdata = dict_new (); + if (!tmp_xdata) { + ret = -1; + goto out; + } + + ret = dict_set_str (tmp_xdata, "entry-point", "true"); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "failed to set dict"); + goto out; + } + + STACK_WIND (frame, gf_svc_readdirp_lookup_cbk, + SECOND_CHILD (this), + SECOND_CHILD (this)->fops->lookup, loc, + tmp_xdata); +out: + if (tmp_xdata) + dict_unref (tmp_xdata); + + GF_FREE (path); + return ret; +} + static gf_boolean_t gf_svc_readdir_on_special_dir (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, |