diff options
author | Mohammed Rafi KC <rkavunga@redhat.com> | 2017-07-03 12:45:38 +0530 |
---|---|---|
committer | Atin Mukherjee <amukherj@redhat.com> | 2017-07-09 04:57:48 +0000 |
commit | 70a5dfdea4980dea5da5b5008a16fd155a3adf34 (patch) | |
tree | abe5e3198095ee5535332fbffa015e222153f136 /xlators | |
parent | ecd92d42bbd9249aa637b1ad3000aa242308cb04 (diff) |
svc: send revalidate lookup on special dir
.snaps directory is a virtual direcotory, that doesn't
exist on the backend. Even though it is a special dentry,
it doesn't have a dedicated inode. So the inode number is
always random. Which means it will get different inode
number when reboot happens on snapd process.
Now with windows client the show-direcotry feature requires
a lookup on the .snpas direcoty post readdirp on root.
If the snapd restarted after a lookup, then subsequent lookup
will fail, because linked inode will be stale.
This patch will do a revalidate lookup with a new inode.
Change-Id: If97c07ecb307cefe7c86be8ebd05e28cbf678d1f
BUG: 1467513
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
Reviewed-on: https://review.gluster.org/17690
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
Smoke: Gluster Build System <jenkins@build.gluster.org>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/features/snapview-client/src/snapview-client.c | 77 | ||||
-rw-r--r-- | xlators/features/snapview-client/src/snapview-client.h | 4 |
2 files changed, 81 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, diff --git a/xlators/features/snapview-client/src/snapview-client.h b/xlators/features/snapview-client/src/snapview-client.h index 5b7a862cf3f..e1fcb371e8c 100644 --- a/xlators/features/snapview-client/src/snapview-client.h +++ b/xlators/features/snapview-client/src/snapview-client.h @@ -23,6 +23,7 @@ struct __svc_local { fd_t *fd; void *cookie; dict_t *xdata; + uint16_t revalidate; }; typedef struct __svc_local svc_local_t; @@ -94,4 +95,7 @@ typedef enum { VIRTUAL_INODE } inode_type_t; +int +gf_svc_special_dir_revalidate_lookup (call_frame_t *frame, xlator_t *this); + #endif /* __SNAP_VIEW_CLIENT_H__ */ |