fs/ufs: revert "ufs: fix deadlocks introduced by sb mutex merge"
authorFabian Frederick <fabf@skynet.be>
Wed, 10 Jun 2015 00:09:32 +0000 (10:09 +1000)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 14 Jun 2015 15:31:51 +0000 (11:31 -0400)
This reverts commit 9ef7db7f38d0 ("ufs: fix deadlocks introduced by sb
mutex merge") That patch tried to solve commit 0244756edc4b98c ("ufs: sb
mutex merge + mutex_destroy") which is itself partially reverted due to
multiple deadlocks.

Signed-off-by: Fabian Frederick <fabf@skynet.be>
Suggested-by: Jan Kara <jack@suse.cz>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Evgeniy Dushistov <dushistov@mail.ru>
Cc: Alexey Khoroshilov <khoroshilov@ispras.ru>
Cc: Roger Pau Monne <roger.pau@citrix.com>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/ufs/inode.c
fs/ufs/namei.c

index be7d42c7d9382bf8072a7e6e9eff7e03b24bab25..2d93ab07da8a6cc58f228ee0b088de326ddc99a6 100644 (file)
@@ -902,6 +902,9 @@ void ufs_evict_inode(struct inode * inode)
        invalidate_inode_buffers(inode);
        clear_inode(inode);
 
-       if (want_delete)
+       if (want_delete) {
+               lock_ufs(inode->i_sb);
                ufs_free_inode(inode);
+               unlock_ufs(inode->i_sb);
+       }
 }
index e491a93a7e9af14c4227ee5072fa4a9d0bc17709..1f5223c9e1e2c94ac22f94de629da756fbce8e8c 100644 (file)
@@ -128,12 +128,12 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry,
        if (l > sb->s_blocksize)
                goto out_notlocked;
 
+       lock_ufs(dir->i_sb);
        inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO);
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
-               goto out_notlocked;
+               goto out;
 
-       lock_ufs(dir->i_sb);
        if (l > UFS_SB(sb)->s_uspi->s_maxsymlinklen) {
                /* slow symlink */
                inode->i_op = &ufs_symlink_inode_operations;
@@ -184,9 +184,13 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
        struct inode * inode;
        int err;
 
+       lock_ufs(dir->i_sb);
+       inode_inc_link_count(dir);
+
        inode = ufs_new_inode(dir, S_IFDIR|mode);
+       err = PTR_ERR(inode);
        if (IS_ERR(inode))
-               return PTR_ERR(inode);
+               goto out_dir;
 
        inode->i_op = &ufs_dir_inode_operations;
        inode->i_fop = &ufs_dir_operations;
@@ -194,9 +198,6 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
 
        inode_inc_link_count(inode);
 
-       lock_ufs(dir->i_sb);
-       inode_inc_link_count(dir);
-
        err = ufs_make_empty(inode, dir);
        if (err)
                goto out_fail;
@@ -215,6 +216,7 @@ out_fail:
        inode_dec_link_count(inode);
        unlock_new_inode(inode);
        iput (inode);
+out_dir:
        inode_dec_link_count(dir);
        unlock_ufs(dir->i_sb);
        goto out;