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