21ab4e
From bf379e85fb74cb3ac8db8c926967813697328559 Mon Sep 17 00:00:00 2001
21ab4e
From: Pranith Kumar K <pkarampu@redhat.com>
21ab4e
Date: Fri, 22 Sep 2017 12:50:43 +0530
21ab4e
Subject: [PATCH 620/620] features/locks: Maintain separation of
21ab4e
 lock->client_pid, flock->l_pid
21ab4e
21ab4e
	Backport of https://review.gluster.org/17826
21ab4e
21ab4e
Problem:
21ab4e
grant_blocked_locks() constructs flock from lock. Locks xlator uses
21ab4e
frame->root->pid interchangeably flock->l_pid. With gNFS frame->root->pid
21ab4e
(which translates to lock->client_pid) is not same as flock->l_pid, this leads
21ab4e
to lk's cbk returning flock with l_pid from lock->client_pid instead of input
21ab4e
flock->l_pid. This triggers EC's error code path leading to failure of lk call,
21ab4e
because the response' flock->l_pid is different from request's flock->l_pid.
21ab4e
21ab4e
Fix:
21ab4e
Maintain separation of lock->client_pid, flock->l_pid. Always unwind with
21ab4e
flock with correct pid.
21ab4e
21ab4e
BUG: 1411338
21ab4e
Change-Id: Ifab35c458662cf0082b902f37782f8c5321d823d
21ab4e
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/119040
21ab4e
---
21ab4e
 xlators/features/locks/src/common.c | 46 ++++++++++++-------------------------
21ab4e
 xlators/features/locks/src/posix.c  |  3 ---
21ab4e
 2 files changed, 15 insertions(+), 34 deletions(-)
21ab4e
21ab4e
diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c
21ab4e
index 68904f6..015464c 100644
21ab4e
--- a/xlators/features/locks/src/common.c
21ab4e
+++ b/xlators/features/locks/src/common.c
21ab4e
@@ -485,6 +485,7 @@ new_posix_lock (struct gf_flock *flock, client_t *client, pid_t client_pid,
21ab4e
         lock->lk_flags   = lk_flags;
21ab4e
 
21ab4e
         lock->blocking  = blocking;
21ab4e
+        memcpy (&lock->user_flock, flock, sizeof (lock->user_flock));
21ab4e
 
21ab4e
         INIT_LIST_HEAD (&lock->list);
21ab4e
 
21ab4e
@@ -522,6 +523,7 @@ __copy_lock(posix_lock_t *src)
21ab4e
                         GF_FREE(dst);
21ab4e
                         dst = NULL;
21ab4e
                 }
21ab4e
+                INIT_LIST_HEAD (&dst->list);
21ab4e
         }
21ab4e
 
21ab4e
         return dst;
21ab4e
@@ -531,7 +533,7 @@ __copy_lock(posix_lock_t *src)
21ab4e
 void
21ab4e
 posix_lock_to_flock (posix_lock_t *lock, struct gf_flock *flock)
21ab4e
 {
21ab4e
-        flock->l_pid   = lock->client_pid;
21ab4e
+        flock->l_pid   = lock->user_flock.l_pid;
21ab4e
         flock->l_type  = lock->fl_type;
21ab4e
         flock->l_start = lock->fl_start;
21ab4e
         flock->l_owner = lock->owner;
21ab4e
@@ -601,18 +603,19 @@ __delete_unlck_locks (pl_inode_t *pl_inode)
21ab4e
 
21ab4e
 /* Add two locks */
21ab4e
 static posix_lock_t *
21ab4e
-add_locks (posix_lock_t *l1, posix_lock_t *l2)
21ab4e
+add_locks (posix_lock_t *l1, posix_lock_t *l2, posix_lock_t *dst)
21ab4e
 {
21ab4e
         posix_lock_t *sum = NULL;
21ab4e
 
21ab4e
-        sum = GF_CALLOC (1, sizeof (posix_lock_t),
21ab4e
-                         gf_locks_mt_posix_lock_t);
21ab4e
+        sum = __copy_lock (dst);
21ab4e
         if (!sum)
21ab4e
                 return NULL;
21ab4e
 
21ab4e
         sum->fl_start = min (l1->fl_start, l2->fl_start);
21ab4e
         sum->fl_end   = max (l1->fl_end, l2->fl_end);
21ab4e
 
21ab4e
+        posix_lock_to_flock (sum, &sum->user_flock);
21ab4e
+
21ab4e
         return sum;
21ab4e
 }
21ab4e
 
21ab4e
@@ -637,6 +640,7 @@ subtract_locks (posix_lock_t *big, posix_lock_t *small)
21ab4e
                 }
21ab4e
 
21ab4e
                 v.locks[0]->fl_type = small->fl_type;
21ab4e
+                v.locks[0]->user_flock.l_type = small->fl_type;
21ab4e
                 goto done;
21ab4e
         }
21ab4e
 
21ab4e
@@ -653,6 +657,8 @@ subtract_locks (posix_lock_t *big, posix_lock_t *small)
21ab4e
 
21ab4e
                 v.locks[0]->fl_end = small->fl_start - 1;
21ab4e
                 v.locks[2]->fl_start = small->fl_end + 1;
21ab4e
+                posix_lock_to_flock (v.locks[0], &v.locks[0]->user_flock);
21ab4e
+                posix_lock_to_flock (v.locks[2], &v.locks[2]->user_flock);
21ab4e
                 goto done;
21ab4e
 
21ab4e
         }
21ab4e
@@ -666,6 +672,7 @@ subtract_locks (posix_lock_t *big, posix_lock_t *small)
21ab4e
                 }
21ab4e
 
21ab4e
                 v.locks[0]->fl_start = small->fl_end + 1;
21ab4e
+                posix_lock_to_flock (v.locks[0], &v.locks[0]->user_flock);
21ab4e
                 goto done;
21ab4e
         }
21ab4e
 
21ab4e
@@ -677,6 +684,7 @@ subtract_locks (posix_lock_t *big, posix_lock_t *small)
21ab4e
                 }
21ab4e
 
21ab4e
                 v.locks[0]->fl_end = small->fl_start - 1;
21ab4e
+                posix_lock_to_flock (v.locks[0], &v.locks[0]->user_flock);
21ab4e
                 goto done;
21ab4e
         }
21ab4e
 
21ab4e
@@ -787,7 +795,6 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock)
21ab4e
         posix_lock_t  *sum = NULL;
21ab4e
         int            i = 0;
21ab4e
         struct _values v = { .locks = {0, 0, 0} };
21ab4e
-        client_t      *client = NULL;
21ab4e
 
21ab4e
         list_for_each_entry_safe (conf, t, &pl_inode->ext_list, list) {
21ab4e
                 if (conf->blocked)
21ab4e
@@ -798,17 +805,7 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock)
21ab4e
                 if (same_owner (conf, lock)) {
21ab4e
                         if (conf->fl_type == lock->fl_type &&
21ab4e
                                         conf->lk_flags == lock->lk_flags) {
21ab4e
-                                sum = add_locks (lock, conf);
21ab4e
-
21ab4e
-                                sum->fl_type    = lock->fl_type;
21ab4e
-                                sum->client     = lock->client;
21ab4e
-                                client          = sum->client;
21ab4e
-                                sum->client_uid =
21ab4e
-                                         gf_strdup (client->client_uid);
21ab4e
-                                sum->fd_num     = lock->fd_num;
21ab4e
-                                sum->client_pid = lock->client_pid;
21ab4e
-                                sum->owner      = lock->owner;
21ab4e
-                                sum->lk_flags   = lock->lk_flags;
21ab4e
+                                sum = add_locks (lock, conf, lock);
21ab4e
 
21ab4e
                                 __delete_lock (conf);
21ab4e
                                 __destroy_lock (conf);
21ab4e
@@ -820,18 +817,7 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock)
21ab4e
 
21ab4e
                                 return;
21ab4e
                         } else {
21ab4e
-                                sum = add_locks (lock, conf);
21ab4e
-
21ab4e
-                                sum->fl_type    = conf->fl_type;
21ab4e
-                                sum->client     = conf->client;
21ab4e
-                                client          = sum->client;
21ab4e
-                                sum->client_uid =
21ab4e
-                                         gf_strdup (client->client_uid);
21ab4e
-
21ab4e
-                                sum->fd_num     = conf->fd_num;
21ab4e
-                                sum->client_pid = conf->client_pid;
21ab4e
-                                sum->owner      = conf->owner;
21ab4e
-                                sum->lk_flags   = conf->lk_flags;
21ab4e
+                                sum = add_locks (lock, conf, conf);
21ab4e
 
21ab4e
                                 v = subtract_locks (sum, lock);
21ab4e
 
21ab4e
@@ -847,9 +833,6 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock)
21ab4e
                                         if (!v.locks[i])
21ab4e
                                                 continue;
21ab4e
 
21ab4e
-                                        INIT_LIST_HEAD (&v.locks[i]->list);
21ab4e
-                                        posix_lock_to_flock (v.locks[i],
21ab4e
-                                                       &v.locks[i]->user_flock);
21ab4e
                                         __insert_and_merge (pl_inode,
21ab4e
                                                             v.locks[i]);
21ab4e
                                 }
21ab4e
@@ -984,6 +967,7 @@ pl_send_prelock_unlock (xlator_t *this, pl_inode_t *pl_inode,
21ab4e
         flock.l_whence = old_lock->user_flock.l_whence;
21ab4e
         flock.l_start  = old_lock->user_flock.l_start;
21ab4e
         flock.l_len    = old_lock->user_flock.l_len;
21ab4e
+        flock.l_pid    = old_lock->user_flock.l_pid;
21ab4e
 
21ab4e
 
21ab4e
         unlock_lock = new_posix_lock (&flock, old_lock->client,
21ab4e
diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c
21ab4e
index c9b3f82..feca2f1 100644
21ab4e
--- a/xlators/features/locks/src/posix.c
21ab4e
+++ b/xlators/features/locks/src/posix.c
21ab4e
@@ -2304,7 +2304,6 @@ pl_lk (call_frame_t *frame, xlator_t *this,
21ab4e
 
21ab4e
                 /* fall through */
21ab4e
         case F_RESLK_LCK:
21ab4e
-                memcpy (&reqlock->user_flock, flock, sizeof (struct gf_flock));
21ab4e
                 reqlock->frame = frame;
21ab4e
                 reqlock->this = this;
21ab4e
 
21ab4e
@@ -2388,8 +2387,6 @@ pl_lk (call_frame_t *frame, xlator_t *this,
21ab4e
                 reqlock->frame  = frame;
21ab4e
                 reqlock->this   = this;
21ab4e
 
21ab4e
-                memcpy (&reqlock->user_flock, flock, sizeof (struct gf_flock));
21ab4e
-
21ab4e
                 pthread_mutex_lock (&pl_inode->mutex);
21ab4e
                 {
21ab4e
                         if (pl_inode->migrated) {
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e