summaryrefslogtreecommitdiffstats
path: root/xlators/features/snapview-client/src/snapview-client.c
diff options
context:
space:
mode:
authorMohammed Rafi KC <rkavunga@redhat.com>2017-07-03 12:45:38 +0530
committerAtin Mukherjee <amukherj@redhat.com>2017-07-09 04:57:48 +0000
commit70a5dfdea4980dea5da5b5008a16fd155a3adf34 (patch)
treeabe5e3198095ee5535332fbffa015e222153f136 /xlators/features/snapview-client/src/snapview-client.c
parentecd92d42bbd9249aa637b1ad3000aa242308cb04 (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/features/snapview-client/src/snapview-client.c')
-rw-r--r--xlators/features/snapview-client/src/snapview-client.c77
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,