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 | |
| 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>
| -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__ */  | 
