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