From b47f741b5f42d2e7d994cd06e1c1c679fd9e9535 Mon Sep 17 00:00:00 2001 From: vmallika Date: Wed, 10 Feb 2016 13:53:12 +0530 Subject: 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 Change-Id: I76c632239b45f7eb7296cbfe3b73bc68e5bd1655 BUG: 1306163 Signed-off-by: vmallika Reviewed-on: http://review.gluster.org/13419 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Rajesh Joseph --- .../features/snapview-client/src/snapview-client.c | 79 ++++++++++++++++++---- 1 file changed, 66 insertions(+), 13 deletions(-) (limited to 'xlators/features/snapview-client') 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) -- cgit