a3470f
From 01dcc756aa82ad535d349b40cc1d639734b5f7ca Mon Sep 17 00:00:00 2001
a3470f
From: Pranith Kumar K <pkarampu@redhat.com>
a3470f
Date: Fri, 17 Nov 2017 07:12:42 +0530
a3470f
Subject: [PATCH 235/236] cluster-syncop: Implement tiebreaker inodelk/entrylk
a3470f
a3470f
In this implementation, inodelk/entrylk will be tried for the subvols
a3470f
given with trylock. In this attempt if all locks are obtained, then
a3470f
inodelk is successful, otherwise, if it gets success on the first
a3470f
available subvolume, then it will go for blocking lock, where as other
a3470f
subvolumes will not try and this acts as tie-breaker.
a3470f
a3470f
 >Updates gluster/glusterfs#354
a3470f
Upstream-patch: https://review.gluster.org/18819
a3470f
a3470f
BUG: 1562744
a3470f
Change-Id: Ia2521b9ccb81a42bd6104ab21f610f761ba2b801
a3470f
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
a3470f
Reviewed-on: https://code.engineering.redhat.com/gerrit/134278
a3470f
Tested-by: RHGS Build Bot <nigelb@redhat.com>
a3470f
Reviewed-by: Ashish Pandey <aspandey@redhat.com>
a3470f
---
a3470f
 libglusterfs/src/cluster-syncop.c | 96 +++++++++++++++++++++++++++++++++++++++
a3470f
 libglusterfs/src/cluster-syncop.h |  7 +++
a3470f
 2 files changed, 103 insertions(+)
a3470f
a3470f
diff --git a/libglusterfs/src/cluster-syncop.c b/libglusterfs/src/cluster-syncop.c
a3470f
index b7f4dfe..75ba640 100644
a3470f
--- a/libglusterfs/src/cluster-syncop.c
a3470f
+++ b/libglusterfs/src/cluster-syncop.c
a3470f
@@ -1191,3 +1191,99 @@ cluster_entrylk (xlator_t **subvols, unsigned char *on, int numsubvols,
a3470f
         loc_wipe (&loc;;
a3470f
         return cluster_fop_success_fill (replies, numsubvols, locked_on);
a3470f
 }
a3470f
+
a3470f
+int
a3470f
+cluster_tiebreaker_inodelk (xlator_t **subvols, unsigned char *on,
a3470f
+                            int numsubvols, default_args_cbk_t *replies,
a3470f
+                            unsigned char *locked_on, call_frame_t *frame,
a3470f
+                            xlator_t *this, char *dom, inode_t *inode,
a3470f
+                            off_t off, size_t size)
a3470f
+{
a3470f
+        struct gf_flock flock = {0, };
a3470f
+        int i = 0;
a3470f
+        int num_success = 0;
a3470f
+        loc_t loc = {0};
a3470f
+        unsigned char *output = NULL;
a3470f
+
a3470f
+        flock.l_type = F_WRLCK;
a3470f
+        flock.l_start = off;
a3470f
+        flock.l_len = size;
a3470f
+
a3470f
+        output = alloca(numsubvols);
a3470f
+        loc.inode = inode_ref (inode);
a3470f
+        gf_uuid_copy (loc.gfid, inode->gfid);
a3470f
+        FOP_ONLIST (subvols, on, numsubvols, replies, locked_on, frame,
a3470f
+                    inodelk, dom, &loc, F_SETLK, &flock, NULL);
a3470f
+
a3470f
+        for (i = 0; i < numsubvols; i++) {
a3470f
+                if (replies[i].valid && replies[i].op_ret == 0) {
a3470f
+                        num_success++;
a3470f
+                        continue;
a3470f
+                }
a3470f
+                if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) {
a3470f
+                        cluster_fop_success_fill (replies, numsubvols,
a3470f
+                                                  locked_on);
a3470f
+                        cluster_uninodelk (subvols, locked_on, numsubvols,
a3470f
+                                           replies, output, frame, this, dom,
a3470f
+                                           inode, off, size);
a3470f
+
a3470f
+                        if (num_success) {
a3470f
+                                FOP_SEQ (subvols, on, numsubvols, replies,
a3470f
+                                         locked_on, frame, inodelk, dom, &loc,
a3470f
+                                         F_SETLKW, &flock, NULL);
a3470f
+                        } else {
a3470f
+                                memset (locked_on, 0, numsubvols);
a3470f
+                        }
a3470f
+                        break;
a3470f
+                }
a3470f
+        }
a3470f
+
a3470f
+        loc_wipe (&loc;;
a3470f
+        return cluster_fop_success_fill (replies, numsubvols, locked_on);
a3470f
+}
a3470f
+
a3470f
+int
a3470f
+cluster_tiebreaker_entrylk (xlator_t **subvols, unsigned char *on,
a3470f
+                            int numsubvols, default_args_cbk_t *replies,
a3470f
+                            unsigned char *locked_on, call_frame_t *frame,
a3470f
+                            xlator_t *this, char *dom, inode_t *inode,
a3470f
+                            const char *name)
a3470f
+{
a3470f
+        int i = 0;
a3470f
+        loc_t loc = {0};
a3470f
+        unsigned char *output = NULL;
a3470f
+        int num_success = 0;
a3470f
+
a3470f
+        output = alloca(numsubvols);
a3470f
+        loc.inode = inode_ref (inode);
a3470f
+        gf_uuid_copy (loc.gfid, inode->gfid);
a3470f
+        FOP_ONLIST (subvols, on, numsubvols, replies, locked_on, frame,
a3470f
+                    entrylk, dom, &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK,
a3470f
+                    NULL);
a3470f
+
a3470f
+        for (i = 0; i < numsubvols; i++) {
a3470f
+                if (replies[i].valid && replies[i].op_ret == 0) {
a3470f
+                        num_success++;
a3470f
+                        continue;
a3470f
+                }
a3470f
+                if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) {
a3470f
+                        cluster_fop_success_fill (replies, numsubvols,
a3470f
+                                                  locked_on);
a3470f
+                        cluster_unentrylk (subvols, locked_on, numsubvols,
a3470f
+                                           replies, output, frame, this, dom,
a3470f
+                                           inode, name);
a3470f
+                        if (num_success) {
a3470f
+                                FOP_SEQ (subvols, on, numsubvols, replies,
a3470f
+                                         locked_on, frame, entrylk, dom, &loc,
a3470f
+                                         name, ENTRYLK_LOCK, ENTRYLK_WRLCK,
a3470f
+                                         NULL);
a3470f
+                        } else {
a3470f
+                                memset (locked_on, 0, numsubvols);
a3470f
+                        }
a3470f
+                        break;
a3470f
+                }
a3470f
+        }
a3470f
+
a3470f
+        loc_wipe (&loc;;
a3470f
+        return cluster_fop_success_fill (replies, numsubvols, locked_on);
a3470f
+}
a3470f
diff --git a/libglusterfs/src/cluster-syncop.h b/libglusterfs/src/cluster-syncop.h
a3470f
index ff9387a..b91a09e 100644
a3470f
--- a/libglusterfs/src/cluster-syncop.h
a3470f
+++ b/libglusterfs/src/cluster-syncop.h
a3470f
@@ -209,4 +209,11 @@ int32_t
a3470f
 cluster_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
a3470f
                      int32_t op_ret, int32_t op_errno, dict_t *dict,
a3470f
                      dict_t *xdata);
a3470f
+
a3470f
+int
a3470f
+cluster_tiebreaker_inodelk (xlator_t **subvols, unsigned char *on,
a3470f
+                            int numsubvols, default_args_cbk_t *replies,
a3470f
+                            unsigned char *locked_on, call_frame_t *frame,
a3470f
+                            xlator_t *this, char *dom, inode_t *inode,
a3470f
+                            off_t off, size_t size);
a3470f
 #endif /* !_CLUSTER_SYNCOP_H */
a3470f
-- 
a3470f
1.8.3.1
a3470f