From 64b238d3a5caf7bdb32bca25946f84e0afe9bc7a Mon Sep 17 00:00:00 2001
From: Krutika Dhananjay <kdhananj@redhat.com>
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 <kdhananj@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/154861
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Xavi Hernandez <xhernandez@redhat.com>
Tested-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
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