From 64b238d3a5caf7bdb32bca25946f84e0afe9bc7a Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Tue, 17 Apr 2018 22:14:20 +0530 Subject: [PATCH 427/444] features/shard: Add option to barrier parallel lookup and unlink of shards > Upstream: https://review.gluster.org/19915 > BUG: 1568521 > Change-Id: Ib0f90a5f62abdfa89cda7bef9f3ff99f349ec332 Also move the common parallel unlink callback for GF_FOP_TRUNCATE and GF_FOP_FTRUNCATE into a separate function. Change-Id: Ib0f90a5f62abdfa89cda7bef9f3ff99f349ec332 BUG: 1520882 Signed-off-by: Krutika Dhananjay Reviewed-on: https://code.engineering.redhat.com/gerrit/154861 Tested-by: RHGS Build Bot Reviewed-by: Xavi Hernandez Tested-by: Sunil Kumar Heggodu Gopala Acharya --- xlators/features/shard/src/shard.c | 113 ++++++++++++++++++++++++++++--------- xlators/features/shard/src/shard.h | 4 ++ 2 files changed, 89 insertions(+), 28 deletions(-) diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c index 5ff04df..268ba20 100644 --- a/xlators/features/shard/src/shard.c +++ b/xlators/features/shard/src/shard.c @@ -475,6 +475,7 @@ shard_local_wipe (shard_local_t *local) count = local->num_blocks; + syncbarrier_destroy (&local->barrier); loc_wipe (&local->loc); loc_wipe (&local->dot_shard_loc); loc_wipe (&local->loc2); @@ -861,6 +862,7 @@ shard_common_resolve_shards (call_frame_t *frame, xlator_t *this, priv = this->private; local = frame->local; + local->call_count = 0; shard_idx_iter = local->first_block; res_inode = local->resolver_base_inode; @@ -1780,6 +1782,37 @@ shard_unlink_shards_do_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct iatt *preparent, struct iatt *postparent, dict_t *xdata); +void +shard_unlink_block_inode (shard_local_t *local, int shard_block_num); + +int +shard_truncate_htol_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, + struct iatt *preparent, struct iatt *postparent, + dict_t *xdata) +{ + int call_count = 0; + int shard_block_num = (long) cookie; + shard_local_t *local = NULL; + + local = frame->local; + + if (op_ret < 0) { + local->op_ret = op_ret; + local->op_errno = op_errno; + goto done; + } + + shard_unlink_block_inode (local, shard_block_num); +done: + call_count = shard_call_count_return (frame); + if (call_count == 0) { + SHARD_UNSET_ROOT_FS_ID (frame, local); + shard_truncate_last_shard (frame, this, local->inode_list[0]); + } + return 0; +} + int shard_truncate_htol (call_frame_t *frame, xlator_t *this, inode_t *inode) { @@ -1839,10 +1872,9 @@ shard_truncate_htol (call_frame_t *frame, xlator_t *this, inode_t *inode) continue; } if (wind_failed) { - shard_unlink_shards_do_cbk (frame, - (void *)(long) cur_block, - this, -1, ENOMEM, NULL, - NULL, NULL); + shard_truncate_htol_cbk (frame, (void *)(long) cur_block, + this, -1, ENOMEM, NULL, NULL, + NULL); goto next; } @@ -1860,10 +1892,9 @@ shard_truncate_htol (call_frame_t *frame, xlator_t *this, inode_t *inode) local->op_errno = ENOMEM; loc_wipe (&loc); wind_failed = _gf_true; - shard_unlink_shards_do_cbk (frame, - (void *)(long) cur_block, - this, -1, ENOMEM, NULL, - NULL, NULL); + shard_truncate_htol_cbk (frame, (void *)(long) cur_block, + this, -1, ENOMEM, NULL, NULL, + NULL); goto next; } loc.name = strrchr (loc.path, '/'); @@ -1871,7 +1902,7 @@ shard_truncate_htol (call_frame_t *frame, xlator_t *this, inode_t *inode) loc.name++; loc.inode = inode_ref (local->inode_list[i]); - STACK_WIND_COOKIE (frame, shard_unlink_shards_do_cbk, + STACK_WIND_COOKIE (frame, shard_truncate_htol_cbk, (void *) (long) cur_block, FIRST_CHILD(this), FIRST_CHILD (this)->fops->unlink, &loc, 0, NULL); @@ -2022,13 +2053,18 @@ shard_common_lookup_shards_cbk (call_frame_t *frame, void *cookie, done: call_count = shard_call_count_return (frame); - if (call_count == 0) { - if (!local->first_lookup_done) - local->first_lookup_done = _gf_true; - if (local->op_ret < 0) - goto unwind; - else - local->pls_fop_handler (frame, this); + if (local->lookup_shards_barriered) { + syncbarrier_wake (&local->barrier); + return 0; + } else { + if (call_count == 0) { + if (!local->first_lookup_done) + local->first_lookup_done = _gf_true; + if (local->op_ret < 0) + goto unwind; + else + local->pls_fop_handler (frame, this); + } } return 0; @@ -2074,6 +2110,7 @@ shard_common_lookup_shards (call_frame_t *frame, xlator_t *this, inode_t *inode, { int i = 0; int ret = 0; + int count = 0; int call_count = 0; int32_t shard_idx_iter = 0; int last_block = 0; @@ -2087,10 +2124,12 @@ shard_common_lookup_shards (call_frame_t *frame, xlator_t *this, inode_t *inode, priv = this->private; local = frame->local; - call_count = local->call_count; + count = call_count = local->call_count; shard_idx_iter = local->first_block; last_block = local->last_block; local->pls_fop_handler = handler; + if (local->lookup_shards_barriered) + local->barrier.waitfor = local->call_count; while (shard_idx_iter <= last_block) { if (local->inode_list[i]) { @@ -2162,7 +2201,8 @@ next: if (!--call_count) break; } - + if (local->lookup_shards_barriered) + syncbarrier_wait (&local->barrier, count); return 0; } @@ -2400,6 +2440,9 @@ shard_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, frame->local = local; + ret = syncbarrier_init (&local->barrier); + if (ret) + goto err; loc_copy (&local->loc, loc); local->offset = offset; local->block_size = block_size; @@ -2450,6 +2493,9 @@ shard_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, goto err; frame->local = local; + ret = syncbarrier_init (&local->barrier); + if (ret) + goto err; local->fd = fd_ref (fd); local->offset = offset; local->block_size = block_size; @@ -2881,18 +2927,19 @@ shard_unlink_shards_do_cbk (call_frame_t *frame, void *cookie, xlator_t *this, done: call_count = shard_call_count_return (frame); - if (call_count == 0) { - SHARD_UNSET_ROOT_FS_ID (frame, local); + if (local->unlink_shards_barriered) { + syncbarrier_wake (&local->barrier); + } else { - if (local->fop == GF_FOP_UNLINK) - shard_unlink_cbk (frame, this); - else if (local->fop == GF_FOP_RENAME) - shard_rename_cbk (frame, this); - else - shard_truncate_last_shard (frame, this, - local->inode_list[0]); - } + if (call_count == 0) { + SHARD_UNSET_ROOT_FS_ID (frame, local); + if (local->fop == GF_FOP_UNLINK) + shard_unlink_cbk (frame, this); + else if (local->fop == GF_FOP_RENAME) + shard_rename_cbk (frame, this); + } + } return 0; } @@ -2952,6 +2999,8 @@ shard_unlink_shards_do (call_frame_t *frame, xlator_t *this, inode_t *inode) local->call_count = call_count = count; cur_block = 1; SHARD_SET_ROOT_FS_ID (frame, local); + if (local->unlink_shards_barriered) + local->barrier.waitfor = count; /* Ignore the base file and start iterating from the first block shard. */ @@ -3006,6 +3055,8 @@ next: if (!--call_count) break; } + if (local->unlink_shards_barriered) + syncbarrier_wait (&local->barrier, count); return 0; } @@ -3947,6 +3998,9 @@ shard_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, frame->local = local; + ret = syncbarrier_init (&local->barrier); + if (ret) + goto err; local->fd = fd_ref (fd); local->block_size = block_size; local->offset = offset; @@ -5414,6 +5468,9 @@ shard_common_inode_write_begin (call_frame_t *frame, xlator_t *this, frame->local = local; + ret = syncbarrier_init (&local->barrier); + if (ret) + goto out; local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new (); if (!local->xattr_req) goto out; diff --git a/xlators/features/shard/src/shard.h b/xlators/features/shard/src/shard.h index a1adb6a..225caa0 100644 --- a/xlators/features/shard/src/shard.h +++ b/xlators/features/shard/src/shard.h @@ -15,6 +15,7 @@ #include "xlator.h" #include "compat-errno.h" #include "shard-messages.h" +#include "syncop.h" #define GF_SHARD_DIR ".shard" #define SHARD_MIN_BLOCK_SIZE (4 * GF_UNIT_MB) @@ -257,6 +258,9 @@ typedef struct shard_local { } lock; inode_t *resolver_base_inode; gf_boolean_t first_lookup_done; + syncbarrier_t barrier; + gf_boolean_t lookup_shards_barriered; + gf_boolean_t unlink_shards_barriered; } shard_local_t; typedef struct shard_inode_ctx { -- 1.8.3.1