Blob Blame History Raw
From eff25494501810de50cfefa414403f7fdbf8fb25 Mon Sep 17 00:00:00 2001
From: Mohammed Rafi KC <rkavunga@redhat.com>
Date: Mon, 3 Jul 2017 12:45:38 +0530
Subject: [PATCH 555/557] 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.
Back port of>
>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>

Change-Id: If97c07ecb307cefe7c86be8ebd05e28cbf678d1f
BUG: 1191480
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/111807
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
---
 .../features/snapview-client/src/snapview-client.c | 77 ++++++++++++++++++++++
 .../features/snapview-client/src/snapview-client.h |  4 ++
 2 files changed, 81 insertions(+)

diff --git a/xlators/features/snapview-client/src/snapview-client.c b/xlators/features/snapview-client/src/snapview-client.c
index 6eb7cc0..efc3362 100644
--- a/xlators/features/snapview-client/src/snapview-client.c
+++ b/xlators/features/snapview-client/src/snapview-client.c
@@ -1666,6 +1666,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;
@@ -1715,6 +1723,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 5b7a862..e1fcb37 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__ */
-- 
1.8.3.1