CIFS: Separate pushing mandatory locks and lock_sem handling
authorPavel Shilovsky <piastry@etersoft.ru>
Thu, 22 Nov 2012 13:07:16 +0000 (17:07 +0400)
committerSteve French <smfrench@gmail.com>
Wed, 5 Dec 2012 19:27:29 +0000 (13:27 -0600)
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <smfrench@gmail.com>
fs/cifs/file.c
fs/cifs/smb2file.c

index 5fbbf99e61f9da0619ab3251087efd3badceecfe..1747cbff7ddfd9d869df67b494a3618542502ce3 100644 (file)
@@ -948,7 +948,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
        int rc = 0, stored_rc;
        struct cifsLockInfo *li, *tmp;
        struct cifs_tcon *tcon;
-       struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
        unsigned int num, max_num, max_buf;
        LOCKING_ANDX_RANGE *buf, *cur;
        int types[] = {LOCKING_ANDX_LARGE_FILES,
@@ -958,21 +957,12 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
        xid = get_xid();
        tcon = tlink_tcon(cfile->tlink);
 
-       /* we are going to update can_cache_brlcks here - need a write access */
-       down_write(&cinode->lock_sem);
-       if (!cinode->can_cache_brlcks) {
-               up_write(&cinode->lock_sem);
-               free_xid(xid);
-               return rc;
-       }
-
        /*
         * Accessing maxBuf is racy with cifs_reconnect - need to store value
         * and check it for zero before using.
         */
        max_buf = tcon->ses->server->maxBuf;
        if (!max_buf) {
-               up_write(&cinode->lock_sem);
                free_xid(xid);
                return -EINVAL;
        }
@@ -981,7 +971,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
                                                sizeof(LOCKING_ANDX_RANGE);
        buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
        if (!buf) {
-               up_write(&cinode->lock_sem);
                free_xid(xid);
                return -ENOMEM;
        }
@@ -1018,9 +1007,6 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
                }
        }
 
-       cinode->can_cache_brlcks = false;
-       up_write(&cinode->lock_sem);
-
        kfree(buf);
        free_xid(xid);
        return rc;
@@ -1041,7 +1027,7 @@ struct lock_to_push {
 };
 
 static int
-cifs_push_posix_locks_locked(struct cifsFileInfo *cfile)
+cifs_push_posix_locks(struct cifsFileInfo *cfile)
 {
        struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
        struct file_lock *flock, **before;
@@ -1129,9 +1115,11 @@ err_out:
 }
 
 static int
-cifs_push_posix_locks(struct cifsFileInfo *cfile)
+cifs_push_locks(struct cifsFileInfo *cfile)
 {
+       struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
        struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
+       struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
        int rc = 0;
 
        /* we are going to update can_cache_brlcks here - need a write access */
@@ -1140,24 +1128,17 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
                up_write(&cinode->lock_sem);
                return rc;
        }
-       rc = cifs_push_posix_locks_locked(cfile);
-       cinode->can_cache_brlcks = false;
-       up_write(&cinode->lock_sem);
-       return rc;
-}
-
-static int
-cifs_push_locks(struct cifsFileInfo *cfile)
-{
-       struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
-       struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
 
        if (cap_unix(tcon->ses) &&
            (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
            ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
-               return cifs_push_posix_locks(cfile);
+               rc = cifs_push_posix_locks(cfile);
+       else
+               rc = tcon->ses->server->ops->push_mand_locks(cfile);
 
-       return tcon->ses->server->ops->push_mand_locks(cfile);
+       cinode->can_cache_brlcks = false;
+       up_write(&cinode->lock_sem);
+       return rc;
 }
 
 static void
index a93eec30a50d2dab9626025fda82b4f9b62c9c88..71e6aed4b382442525df0571d47329c0ddf8db90 100644 (file)
@@ -260,13 +260,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
        struct cifs_fid_locks *fdlocks;
 
        xid = get_xid();
-       /* we are going to update can_cache_brlcks here - need a write access */
-       down_write(&cinode->lock_sem);
-       if (!cinode->can_cache_brlcks) {
-               up_write(&cinode->lock_sem);
-               free_xid(xid);
-               return rc;
-       }
 
        /*
         * Accessing maxBuf is racy with cifs_reconnect - need to store value
@@ -274,7 +267,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
         */
        max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf;
        if (!max_buf) {
-               up_write(&cinode->lock_sem);
                free_xid(xid);
                return -EINVAL;
        }
@@ -282,7 +274,6 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
        max_num = max_buf / sizeof(struct smb2_lock_element);
        buf = kzalloc(max_num * sizeof(struct smb2_lock_element), GFP_KERNEL);
        if (!buf) {
-               up_write(&cinode->lock_sem);
                free_xid(xid);
                return -ENOMEM;
        }
@@ -293,10 +284,7 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
                        rc = stored_rc;
        }
 
-       cinode->can_cache_brlcks = false;
        kfree(buf);
-
-       up_write(&cinode->lock_sem);
        free_xid(xid);
        return rc;
 }