diff options
| author | vmallika <vmallika@redhat.com> | 2016-02-10 13:53:12 +0530 | 
|---|---|---|
| committer | Rajesh Joseph <rjoseph@redhat.com> | 2016-02-15 00:23:20 -0800 | 
| commit | b47f741b5f42d2e7d994cd06e1c1c679fd9e9535 (patch) | |
| tree | 08f1d875c4743456e50534035ea36deb8ec4ebd9 | |
| parent | fa3df1f5eaf3104c0eb597b954dd17b1a067db8c (diff) | |
USS: pre-existing .snaps should not be listed with 'ls -a' with USS
enabled
This is a backport of http://review.gluster.org/#/c/13330/
If there is a .snaps directory pre-exists and when USS is enabled,
it should not be listed with 'ls -a'
> Change-Id: I1c43e2decc0bbbd3213b190b675e3a32d04b22d3
> BUG: 1303828
> Signed-off-by: vmallika <vmallika@redhat.com>
Change-Id: I76c632239b45f7eb7296cbfe3b73bc68e5bd1655
BUG: 1306163
Signed-off-by: vmallika <vmallika@redhat.com>
Reviewed-on: http://review.gluster.org/13419
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>
| -rw-r--r-- | xlators/features/snapview-client/src/snapview-client.c | 79 | 
1 files changed, 66 insertions, 13 deletions
diff --git a/xlators/features/snapview-client/src/snapview-client.c b/xlators/features/snapview-client/src/snapview-client.c index e784ff6652c..3df327e9c13 100644 --- a/xlators/features/snapview-client/src/snapview-client.c +++ b/xlators/features/snapview-client/src/snapview-client.c @@ -1540,6 +1540,42 @@ out:          return 0;  } +int32_t +svc_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                 int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, +                 dict_t *xdata) +{ +        gf_dirent_t   *entry      = NULL; +        gf_dirent_t   *tmpentry  = NULL; +        svc_local_t   *local      = NULL; +        svc_private_t *priv       = NULL; + +        if (op_ret < 0) +                goto out; + +        GF_VALIDATE_OR_GOTO (this->name, this->private, out); + +        priv = this->private; +        local = frame->local; + +        /* If .snaps pre-exists, then it should not be listed +         * in the NORMAL INODE directory when USS is enabled, +         * so filter the .snaps entry if exists. +         * However it is OK to list .snaps in VIRTUAL world +         */ +        if (local->subvolume != FIRST_CHILD (this)) +                goto out; + +        list_for_each_entry_safe (entry, tmpentry, &entries->list, list) { +                if (strcmp(priv->path, entry->d_name) == 0) +                        gf_dirent_entry_free (entry); +        } + +out: +        SVC_STACK_UNWIND (readdir, frame, op_ret, op_errno, entries, xdata); +        return 0; +} +  static int32_t  svc_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,               size_t size, off_t off, @@ -1547,6 +1583,7 @@ svc_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,  {          int           inode_type = -1;          xlator_t     *subvolume  = NULL; +        svc_local_t  *local      = NULL;          int           ret        = -1;          int           op_ret     = -1;          int           op_errno   = EINVAL; @@ -1577,8 +1614,16 @@ svc_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,          SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret,                                   fd->inode, subvolume, out); -        STACK_WIND_TAIL (frame, subvolume, subvolume->fops->readdir, fd, size, -                         off, xdata); +        local = mem_get0 (this->local_pool); +        if (!local) { +                gf_log (this->name, GF_LOG_ERROR, "failed to allocate local"); +                goto out; +        } +        local->subvolume = subvolume; +        frame->local = local; + +        STACK_WIND (frame, svc_readdir_cbk, subvolume, subvolume->fops->readdir, +                    fd, size, off, xdata);          wind = _gf_true; @@ -1795,18 +1840,20 @@ svc_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                    gf_dirent_t *entries, dict_t *xdata)  {          gf_dirent_t   *entry      = NULL; +        gf_dirent_t   *tmpentry   = NULL;          svc_local_t   *local      = NULL; -        gf_boolean_t   real       = _gf_true;          int            inode_type = -1;          int            ret        = -1;          svc_fd_t      *svc_fd     = NULL;          gf_boolean_t   unwind     = _gf_true; - -        GF_VALIDATE_OR_GOTO ("snapview-client", this, out); +        svc_private_t *priv       = NULL;          if (op_ret < 0)                  goto out; +        GF_VALIDATE_OR_GOTO ("snapview-client", this, out); +        GF_VALIDATE_OR_GOTO (this->name, this->private, out); +        priv = this->private;          local = frame->local;          svc_fd = svc_fd_ctx_get (this, local->fd); @@ -1817,18 +1864,24 @@ svc_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          }          if (local->subvolume == FIRST_CHILD (this)) -                real = _gf_true; +                inode_type = NORMAL_INODE;          else -                real = _gf_false; +                inode_type = VIRTUAL_INODE; -        list_for_each_entry (entry, &entries->list, list) { -                if (!entry->inode) +        list_for_each_entry_safe (entry, tmpentry, &entries->list, list) { +                /* If .snaps pre-exists, then it should not be listed +                 * in the NORMAL INODE directory when USS is enabled, +                 * so filter the .snaps entry if exists. +                 * However it is OK to list .snaps in VIRTUAL world +                 */ +                if (inode_type == NORMAL_INODE && +                    !strcmp(priv->path, entry->d_name)) { +                        gf_dirent_entry_free (entry);                          continue; +                } -                if (real) -                        inode_type = NORMAL_INODE; -                else -                        inode_type = VIRTUAL_INODE; +                if (!entry->inode) +                        continue;                  ret = svc_inode_ctx_set (this, entry->inode, inode_type);                  if (ret)  | 
