The locks_insert/delete_block() functions are used for flock, posix
and leases types. blocked_lock_lock is used to serialize all access to
fl_link, fl_block, fl_next and blocked_hash. Here, we prepare the
stage for using blocked_lock_lock to protect blocked_hash.

Signed-off-by: Daniel Wagner <[email protected]>
Cc: Jeff Layton <[email protected]>
Cc: "J. Bruce Fields" <[email protected]>
Cc: Alexander Viro <[email protected]>
---
 fs/locks.c | 48 ++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 40 insertions(+), 8 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index f63aa92..142e4fd 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -607,11 +607,20 @@ static void locks_delete_global_blocked(struct file_lock 
*waiter)
  */
 static void __locks_delete_block(struct file_lock *waiter)
 {
-       locks_delete_global_blocked(waiter);
        list_del_init(&waiter->fl_block);
        waiter->fl_next = NULL;
 }
 
+/* Posix block variant of __locks_delete_block.
+ *
+ * Must be called with blocked_lock_lock held.
+ */
+static void __locks_delete_posix_block(struct file_lock *waiter)
+{
+       locks_delete_global_blocked(waiter);
+       __locks_delete_block(waiter);
+}
+
 static void locks_delete_block(struct file_lock *waiter)
 {
        spin_lock(&blocked_lock_lock);
@@ -619,6 +628,13 @@ static void locks_delete_block(struct file_lock *waiter)
        spin_unlock(&blocked_lock_lock);
 }
 
+static void locks_delete_posix_block(struct file_lock *waiter)
+{
+       spin_lock(&blocked_lock_lock);
+       __locks_delete_posix_block(waiter);
+       spin_unlock(&blocked_lock_lock);
+}
+
 /* Insert waiter into blocker's block list.
  * We use a circular list so that processes can be easily woken up in
  * the order they blocked. The documentation doesn't require this but
@@ -635,7 +651,17 @@ static void __locks_insert_block(struct file_lock *blocker,
        BUG_ON(!list_empty(&waiter->fl_block));
        waiter->fl_next = blocker;
        list_add_tail(&waiter->fl_block, &blocker->fl_block);
-       if (IS_POSIX(blocker) && !IS_OFDLCK(blocker))
+}
+
+/* Posix block variant of __locks_insert_block.
+ *
+ * Must be called with flc_lock and blocked_lock_lock held.
+ */
+static void __locks_insert_posix_block(struct file_lock *blocker,
+                                       struct file_lock *waiter)
+{
+       __locks_insert_block(blocker, waiter);
+       if (!IS_OFDLCK(blocker))
                locks_insert_global_blocked(waiter);
 }
 
@@ -671,7 +697,10 @@ static void locks_wake_up_blocks(struct file_lock *blocker)
 
                waiter = list_first_entry(&blocker->fl_block,
                                struct file_lock, fl_block);
-               __locks_delete_block(waiter);
+               if (IS_POSIX(blocker))
+                       __locks_delete_posix_block(waiter);
+               else
+                       __locks_delete_block(waiter);
                if (waiter->fl_lmops && waiter->fl_lmops->lm_notify)
                        waiter->fl_lmops->lm_notify(waiter);
                else
@@ -979,7 +1008,7 @@ static int __posix_lock_file(struct inode *inode, struct 
file_lock *request, str
                        spin_lock(&blocked_lock_lock);
                        if (likely(!posix_locks_deadlock(request, fl))) {
                                error = FILE_LOCK_DEFERRED;
-                               __locks_insert_block(fl, request);
+                               __locks_insert_posix_block(fl, request);
                        }
                        spin_unlock(&blocked_lock_lock);
                        goto out;
@@ -1180,7 +1209,7 @@ int posix_lock_file_wait(struct file *filp, struct 
file_lock *fl)
                if (!error)
                        continue;
 
-               locks_delete_block(fl);
+               locks_delete_posix_block(fl);
                break;
        }
        return error;
@@ -1277,7 +1306,7 @@ int locks_mandatory_area(int read_write, struct inode 
*inode,
                                continue;
                }
 
-               locks_delete_block(&fl);
+               locks_delete_posix_block(&fl);
                break;
        }
 
@@ -2097,7 +2126,10 @@ static int do_lock_file_wait(struct file *filp, unsigned 
int cmd,
                if (!error)
                        continue;
 
-               locks_delete_block(fl);
+               if (IS_POSIX(fl))
+                       locks_delete_posix_block(fl);
+               else
+                       locks_delete_block(fl);
                break;
        }
 
@@ -2461,7 +2493,7 @@ posix_unblock_lock(struct file_lock *waiter)
 
        spin_lock(&blocked_lock_lock);
        if (waiter->fl_next)
-               __locks_delete_block(waiter);
+               __locks_delete_posix_block(waiter);
        else
                status = -ENOENT;
        spin_unlock(&blocked_lock_lock);
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to