diff options
Diffstat (limited to '0382-features-shard-Aggregate-file-size-block-count-befor.patch')
-rw-r--r-- | 0382-features-shard-Aggregate-file-size-block-count-befor.patch | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/0382-features-shard-Aggregate-file-size-block-count-befor.patch b/0382-features-shard-Aggregate-file-size-block-count-befor.patch new file mode 100644 index 0000000..a6528f5 --- /dev/null +++ b/0382-features-shard-Aggregate-file-size-block-count-befor.patch @@ -0,0 +1,422 @@ +From 4097a748cbb7616d78886b35e3360177d570b7a6 Mon Sep 17 00:00:00 2001 +From: Krutika Dhananjay <kdhananj@redhat.com> +Date: Fri, 22 May 2020 13:25:26 +0530 +Subject: [PATCH 382/382] features/shard: Aggregate file size, block-count + before unwinding removexattr + +Posix translator returns pre and postbufs in the dict in {F}REMOVEXATTR fops. +These iatts are further cached at layers like md-cache. +Shard translator, in its current state, simply returns these values without +updating the aggregated file size and block-count. + +This patch fixes this problem. + +Upstream patch: +> Upstream patch link: https://review.gluster.org/c/glusterfs/+/24480 +> Change-Id: I4b2dd41ede472c5829af80a67401ec5a6376d872 +> Fixes: #1243 +> Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com> + +Change-Id: I4b2dd41ede472c5829af80a67401ec5a6376d872 +BUG: 1823423 +Signed-off-by: Xavi Hernandez <xhernandez@redhat.com> +Reviewed-on: https://code.engineering.redhat.com/gerrit/201456 +Tested-by: RHGS Build Bot <nigelb@redhat.com> +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com> +--- + tests/bugs/shard/issue-1243.t | 12 ++ + xlators/features/shard/src/shard.c | 293 ++++++++++++++++++++++++++----------- + xlators/features/shard/src/shard.h | 1 + + 3 files changed, 224 insertions(+), 82 deletions(-) + +diff --git a/tests/bugs/shard/issue-1243.t b/tests/bugs/shard/issue-1243.t +index b0c092c..ba22d2b 100644 +--- a/tests/bugs/shard/issue-1243.t ++++ b/tests/bugs/shard/issue-1243.t +@@ -1,6 +1,7 @@ + #!/bin/bash + + . $(dirname $0)/../../include.rc ++. $(dirname $0)/../../volume.rc + + cleanup; + +@@ -22,10 +23,21 @@ TEST $CLI volume set $V0 md-cache-timeout 10 + # Write data into a file such that its size crosses shard-block-size + TEST dd if=/dev/zero of=$M0/foo bs=1048576 count=8 oflag=direct + ++EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 ++TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0 ++ + # Execute a setxattr on the file. + TEST setfattr -n trusted.libvirt -v some-value $M0/foo + + # Size of the file should be the aggregated size, not the shard-block-size + EXPECT '8388608' stat -c %s $M0/foo + ++EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 ++TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0 ++ ++# Execute a removexattr on the file. ++TEST setfattr -x trusted.libvirt $M0/foo ++ ++# Size of the file should be the aggregated size, not the shard-block-size ++EXPECT '8388608' stat -c %s $M0/foo + cleanup +diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c +index 6ae4c41..2e2ef5d 100644 +--- a/xlators/features/shard/src/shard.c ++++ b/xlators/features/shard/src/shard.c +@@ -442,6 +442,9 @@ void shard_local_wipe(shard_local_t *local) { + loc_wipe(&local->int_entrylk.loc); + loc_wipe(&local->newloc); + ++ if (local->name) ++ GF_FREE(local->name); ++ + if (local->int_entrylk.basename) + GF_FREE(local->int_entrylk.basename); + if (local->fd) +@@ -5819,46 +5822,216 @@ int32_t shard_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, + return 0; + } + +-int32_t shard_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, +- const char *name, dict_t *xdata) { +- int op_errno = EINVAL; ++int32_t ++shard_modify_and_set_iatt_in_dict(dict_t *xdata, shard_local_t *local, ++ char *key) ++{ ++ int ret = 0; ++ struct iatt *tmpbuf = NULL; ++ struct iatt *stbuf = NULL; ++ data_t *data = NULL; + +- if (frame->root->pid != GF_CLIENT_PID_GSYNCD) { +- GF_IF_NATIVE_XATTR_GOTO(SHARD_XATTR_PREFIX "*", name, op_errno, out); +- } ++ if (!xdata) ++ return 0; + +- if (xdata && (frame->root->pid != GF_CLIENT_PID_GSYNCD)) { +- dict_del(xdata, GF_XATTR_SHARD_BLOCK_SIZE); +- dict_del(xdata, GF_XATTR_SHARD_FILE_SIZE); +- } ++ data = dict_get(xdata, key); ++ if (!data) ++ return 0; + +- STACK_WIND_TAIL(frame, FIRST_CHILD(this), +- FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); +- return 0; +-out: +- shard_common_failure_unwind(GF_FOP_REMOVEXATTR, frame, -1, op_errno); +- return 0; ++ tmpbuf = data_to_iatt(data, key); ++ stbuf = GF_MALLOC(sizeof(struct iatt), gf_common_mt_char); ++ if (stbuf == NULL) { ++ local->op_ret = -1; ++ local->op_errno = ENOMEM; ++ goto err; ++ } ++ *stbuf = *tmpbuf; ++ stbuf->ia_size = local->prebuf.ia_size; ++ stbuf->ia_blocks = local->prebuf.ia_blocks; ++ ret = dict_set_iatt(xdata, key, stbuf, false); ++ if (ret < 0) { ++ local->op_ret = -1; ++ local->op_errno = ENOMEM; ++ goto err; ++ } ++ return 0; ++ ++err: ++ GF_FREE(stbuf); ++ return -1; + } + +-int32_t shard_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, +- const char *name, dict_t *xdata) { +- int op_errno = EINVAL; ++int32_t ++shard_common_remove_xattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, ++ int32_t op_ret, int32_t op_errno, dict_t *xdata) ++{ ++ int ret = -1; ++ shard_local_t *local = NULL; + +- if (frame->root->pid != GF_CLIENT_PID_GSYNCD) { +- GF_IF_NATIVE_XATTR_GOTO(SHARD_XATTR_PREFIX "*", name, op_errno, out); +- } ++ local = frame->local; + +- if (xdata && (frame->root->pid != GF_CLIENT_PID_GSYNCD)) { +- dict_del(xdata, GF_XATTR_SHARD_BLOCK_SIZE); +- dict_del(xdata, GF_XATTR_SHARD_FILE_SIZE); +- } ++ if (op_ret < 0) { ++ local->op_ret = op_ret; ++ local->op_errno = op_errno; ++ goto err; ++ } + +- STACK_WIND_TAIL(frame, FIRST_CHILD(this), +- FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); +- return 0; +-out: +- shard_common_failure_unwind(GF_FOP_FREMOVEXATTR, frame, -1, op_errno); +- return 0; ++ ret = shard_modify_and_set_iatt_in_dict(xdata, local, GF_PRESTAT); ++ if (ret < 0) ++ goto err; ++ ++ ret = shard_modify_and_set_iatt_in_dict(xdata, local, GF_POSTSTAT); ++ if (ret < 0) ++ goto err; ++ ++ if (local->fd) ++ SHARD_STACK_UNWIND(fremovexattr, frame, local->op_ret, local->op_errno, ++ xdata); ++ else ++ SHARD_STACK_UNWIND(removexattr, frame, local->op_ret, local->op_errno, ++ xdata); ++ return 0; ++ ++err: ++ shard_common_failure_unwind(local->fop, frame, local->op_ret, ++ local->op_errno); ++ return 0; ++} ++ ++int32_t ++shard_post_lookup_remove_xattr_handler(call_frame_t *frame, xlator_t *this) ++{ ++ shard_local_t *local = NULL; ++ ++ local = frame->local; ++ ++ if (local->op_ret < 0) { ++ shard_common_failure_unwind(local->fop, frame, local->op_ret, ++ local->op_errno); ++ return 0; ++ } ++ ++ if (local->fd) ++ STACK_WIND(frame, shard_common_remove_xattr_cbk, FIRST_CHILD(this), ++ FIRST_CHILD(this)->fops->fremovexattr, local->fd, ++ local->name, local->xattr_req); ++ else ++ STACK_WIND(frame, shard_common_remove_xattr_cbk, FIRST_CHILD(this), ++ FIRST_CHILD(this)->fops->removexattr, &local->loc, ++ local->name, local->xattr_req); ++ return 0; ++} ++ ++int32_t ++shard_common_remove_xattr(call_frame_t *frame, xlator_t *this, ++ glusterfs_fop_t fop, loc_t *loc, fd_t *fd, ++ const char *name, dict_t *xdata) ++{ ++ int ret = -1; ++ int op_errno = ENOMEM; ++ uint64_t block_size = 0; ++ shard_local_t *local = NULL; ++ inode_t *inode = loc ? loc->inode : fd->inode; ++ ++ if ((IA_ISDIR(inode->ia_type)) || (IA_ISLNK(inode->ia_type))) { ++ if (loc) ++ STACK_WIND_TAIL(frame, FIRST_CHILD(this), ++ FIRST_CHILD(this)->fops->removexattr, loc, name, ++ xdata); ++ else ++ STACK_WIND_TAIL(frame, FIRST_CHILD(this), ++ FIRST_CHILD(this)->fops->fremovexattr, fd, name, ++ xdata); ++ return 0; ++ } ++ ++ /* If shard's special xattrs are attempted to be removed, ++ * fail the fop with EPERM (except if the client is gsyncd). ++ */ ++ if (frame->root->pid != GF_CLIENT_PID_GSYNCD) { ++ GF_IF_NATIVE_XATTR_GOTO(SHARD_XATTR_PREFIX "*", name, op_errno, err); ++ } ++ ++ /* Repeat the same check for bulk-removexattr */ ++ if (xdata && (frame->root->pid != GF_CLIENT_PID_GSYNCD)) { ++ dict_del(xdata, GF_XATTR_SHARD_BLOCK_SIZE); ++ dict_del(xdata, GF_XATTR_SHARD_FILE_SIZE); ++ } ++ ++ ret = shard_inode_ctx_get_block_size(inode, this, &block_size); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_ERROR, 0, SHARD_MSG_INODE_CTX_GET_FAILED, ++ "Failed to get block size from inode ctx of %s", ++ uuid_utoa(inode->gfid)); ++ goto err; ++ } ++ ++ if (!block_size || frame->root->pid == GF_CLIENT_PID_GSYNCD) { ++ if (loc) ++ STACK_WIND_TAIL(frame, FIRST_CHILD(this), ++ FIRST_CHILD(this)->fops->removexattr, loc, name, ++ xdata); ++ else ++ STACK_WIND_TAIL(frame, FIRST_CHILD(this), ++ FIRST_CHILD(this)->fops->fremovexattr, fd, name, ++ xdata); ++ return 0; ++ } ++ ++ local = mem_get0(this->local_pool); ++ if (!local) ++ goto err; ++ ++ frame->local = local; ++ local->fop = fop; ++ if (loc) { ++ if (loc_copy(&local->loc, loc) != 0) ++ goto err; ++ } ++ ++ if (fd) { ++ local->fd = fd_ref(fd); ++ local->loc.inode = inode_ref(fd->inode); ++ gf_uuid_copy(local->loc.gfid, fd->inode->gfid); ++ } ++ ++ if (name) { ++ local->name = gf_strdup(name); ++ if (!local->name) ++ goto err; ++ } ++ ++ if (xdata) ++ local->xattr_req = dict_ref(xdata); ++ ++ /* To-Do: Switch from LOOKUP which is path-based, to FSTAT if the fop is ++ * on an fd. This comes under a generic class of bugs in shard tracked by ++ * bz #1782428. ++ */ ++ shard_lookup_base_file(frame, this, &local->loc, ++ shard_post_lookup_remove_xattr_handler); ++ return 0; ++err: ++ shard_common_failure_unwind(fop, frame, -1, op_errno); ++ return 0; ++} ++ ++int32_t ++shard_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, ++ const char *name, dict_t *xdata) ++{ ++ shard_common_remove_xattr(frame, this, GF_FOP_REMOVEXATTR, loc, NULL, name, ++ xdata); ++ return 0; ++} ++ ++int32_t ++shard_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, ++ const char *name, dict_t *xdata) ++{ ++ shard_common_remove_xattr(frame, this, GF_FOP_FREMOVEXATTR, NULL, fd, name, ++ xdata); ++ return 0; + } + + int32_t shard_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +@@ -5933,10 +6106,6 @@ int32_t shard_common_set_xattr_cbk(call_frame_t *frame, void *cookie, + xlator_t *this, int32_t op_ret, + int32_t op_errno, dict_t *xdata) { + int ret = -1; +- struct iatt *prebuf = NULL; +- struct iatt *postbuf = NULL; +- struct iatt *stbuf = NULL; +- data_t *data = NULL; + shard_local_t *local = NULL; + + local = frame->local; +@@ -5947,52 +6116,14 @@ int32_t shard_common_set_xattr_cbk(call_frame_t *frame, void *cookie, + goto err; + } + +- if (!xdata) +- goto unwind; +- +- data = dict_get(xdata, GF_PRESTAT); +- if (data) { +- stbuf = data_to_iatt(data, GF_PRESTAT); +- prebuf = GF_MALLOC(sizeof(struct iatt), gf_common_mt_char); +- if (prebuf == NULL) { +- local->op_ret = -1; +- local->op_errno = ENOMEM; +- goto err; +- } +- *prebuf = *stbuf; +- prebuf->ia_size = local->prebuf.ia_size; +- prebuf->ia_blocks = local->prebuf.ia_blocks; +- ret = dict_set_iatt(xdata, GF_PRESTAT, prebuf, false); +- if (ret < 0) { +- local->op_ret = -1; +- local->op_errno = ENOMEM; +- goto err; +- } +- prebuf = NULL; +- } ++ ret = shard_modify_and_set_iatt_in_dict(xdata, local, GF_PRESTAT); ++ if (ret < 0) ++ goto err; + +- data = dict_get(xdata, GF_POSTSTAT); +- if (data) { +- stbuf = data_to_iatt(data, GF_POSTSTAT); +- postbuf = GF_MALLOC(sizeof(struct iatt), gf_common_mt_char); +- if (postbuf == NULL) { +- local->op_ret = -1; +- local->op_errno = ENOMEM; +- goto err; +- } +- *postbuf = *stbuf; +- postbuf->ia_size = local->prebuf.ia_size; +- postbuf->ia_blocks = local->prebuf.ia_blocks; +- ret = dict_set_iatt(xdata, GF_POSTSTAT, postbuf, false); +- if (ret < 0) { +- local->op_ret = -1; +- local->op_errno = ENOMEM; +- goto err; +- } +- postbuf = NULL; +- } ++ ret = shard_modify_and_set_iatt_in_dict(xdata, local, GF_POSTSTAT); ++ if (ret < 0) ++ goto err; + +-unwind: + if (local->fd) + SHARD_STACK_UNWIND(fsetxattr, frame, local->op_ret, local->op_errno, + xdata); +@@ -6002,8 +6133,6 @@ unwind: + return 0; + + err: +- GF_FREE(prebuf); +- GF_FREE(postbuf); + shard_common_failure_unwind(local->fop, frame, local->op_ret, + local->op_errno); + return 0; +diff --git a/xlators/features/shard/src/shard.h b/xlators/features/shard/src/shard.h +index 04abd62..1721417 100644 +--- a/xlators/features/shard/src/shard.h ++++ b/xlators/features/shard/src/shard.h +@@ -318,6 +318,7 @@ typedef struct shard_local { + uint32_t deletion_rate; + gf_boolean_t cleanup_required; + uuid_t base_gfid; ++ char *name; + } shard_local_t; + + typedef struct shard_inode_ctx { +-- +1.8.3.1 + |