Merge tag 'locks-v3.20-1' of git://git.samba.org/jlayton/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Feb 2015 23:34:42 +0000 (15:34 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Feb 2015 23:34:42 +0000 (15:34 -0800)
Pull file locking related changes #1 from Jeff Layton:
 "This patchset contains a fairly major overhaul of how file locks are
  tracked within the inode.  Rather than a single list, we now create a
  per-inode "lock context" that contains individual lists for the file
  locks, and a new dedicated spinlock for them.

  There are changes in other trees that are based on top of this set so
  it may be easiest to pull this in early"

* tag 'locks-v3.20-1' of git://git.samba.org/jlayton/linux:
  locks: update comments that refer to inode->i_flock
  locks: consolidate NULL i_flctx checks in locks_remove_file
  locks: keep a count of locks on the flctx lists
  locks: clean up the lm_change prototype
  locks: add a dedicated spinlock to protect i_flctx lists
  locks: remove i_flock field from struct inode
  locks: convert lease handling to file_lock_context
  locks: convert posix locks to file_lock_context
  locks: move flock locks to file_lock_context
  ceph: move spinlocking into ceph_encode_locks_to_buffer and ceph_count_locks
  locks: add a new struct file_locking_context pointer to struct inode
  locks: have locks_release_file use flock_lock_file to release generic flock locks
  locks: add new struct list_head to struct file_lock

1  2 
fs/cifs/file.c

diff --combined fs/cifs/file.c
@@@ -366,7 -366,6 +366,7 @@@ void cifsFileInfo_put(struct cifsFileIn
        struct cifsLockInfo *li, *tmp;
        struct cifs_fid fid;
        struct cifs_pending_open open;
 +      bool oplock_break_cancelled;
  
        spin_lock(&cifs_file_list_lock);
        if (--cifs_file->count > 0) {
        }
        spin_unlock(&cifs_file_list_lock);
  
 -      cancel_work_sync(&cifs_file->oplock_break);
 +      oplock_break_cancelled = cancel_work_sync(&cifs_file->oplock_break);
  
        if (!tcon->need_reconnect && !cifs_file->invalidHandle) {
                struct TCP_Server_Info *server = tcon->ses->server;
                _free_xid(xid);
        }
  
 +      if (oplock_break_cancelled)
 +              cifs_done_oplock_break(cifsi);
 +
        cifs_del_pending_open(&open);
  
        /*
@@@ -1113,11 -1109,6 +1113,6 @@@ cifs_push_mandatory_locks(struct cifsFi
        return rc;
  }
  
- /* copied from fs/locks.c with a name change */
- #define cifs_for_each_lock(inode, lockp) \
-       for (lockp = &inode->i_flock; *lockp != NULL; \
-            lockp = &(*lockp)->fl_next)
  struct lock_to_push {
        struct list_head llist;
        __u64 offset;
@@@ -1132,8 -1123,9 +1127,9 @@@ cifs_push_posix_locks(struct cifsFileIn
  {
        struct inode *inode = cfile->dentry->d_inode;
        struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
-       struct file_lock *flock, **before;
-       unsigned int count = 0, i = 0;
+       struct file_lock *flock;
+       struct file_lock_context *flctx = inode->i_flctx;
+       unsigned int i;
        int rc = 0, xid, type;
        struct list_head locks_to_send, *el;
        struct lock_to_push *lck, *tmp;
  
        xid = get_xid();
  
-       spin_lock(&inode->i_lock);
-       cifs_for_each_lock(inode, before) {
-               if ((*before)->fl_flags & FL_POSIX)
-                       count++;
-       }
-       spin_unlock(&inode->i_lock);
+       if (!flctx)
+               goto out;
  
        INIT_LIST_HEAD(&locks_to_send);
  
        /*
-        * Allocating count locks is enough because no FL_POSIX locks can be
-        * added to the list while we are holding cinode->lock_sem that
+        * Allocating flc_posix_cnt locks is enough because no FL_POSIX locks
+        * can be added to the list while we are holding cinode->lock_sem that
         * protects locking operations of this inode.
         */
-       for (; i < count; i++) {
+       for (i = 0; i < flctx->flc_posix_cnt; i++) {
                lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL);
                if (!lck) {
                        rc = -ENOMEM;
        }
  
        el = locks_to_send.next;
-       spin_lock(&inode->i_lock);
-       cifs_for_each_lock(inode, before) {
-               flock = *before;
-               if ((flock->fl_flags & FL_POSIX) == 0)
-                       continue;
+       spin_lock(&flctx->flc_lock);
+       list_for_each_entry(flock, &flctx->flc_posix, fl_list) {
                if (el == &locks_to_send) {
                        /*
                         * The list ended. We don't have enough allocated
                lck->length = length;
                lck->type = type;
                lck->offset = flock->fl_start;
-               el = el->next;
        }
-       spin_unlock(&inode->i_lock);
+       spin_unlock(&flctx->flc_lock);
  
        list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) {
                int stored_rc;