summaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/inode.c
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2013-08-08 17:34:47 -0400
committerJeff Mahoney <jeffm@suse.de>2013-08-08 17:34:47 -0400
commitd2d0395fd1778d4bf714adc5bfd23a5d748d7802 (patch)
tree7205eff1242051818b57423142394690620c2731 /fs/reiserfs/inode.c
parent278f6679f454bf185a07d9a4ca355b153482d17a (diff)
reiserfs: locking, release lock around quota operations
Previous commits released the write lock across quota operations but missed several places. In particular, the free operations can also call into the file system code and take the write lock, causing deadlocks. This patch introduces some more helpers and uses them for quota call sites. Without this patch applied, reiserfs + quotas runs into deadlocks under anything more than trivial load. Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Diffstat (limited to 'fs/reiserfs/inode.c')
-rw-r--r--fs/reiserfs/inode.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 4a3a57c66820..ad62bdbb451e 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -57,8 +57,11 @@ void reiserfs_evict_inode(struct inode *inode)
57 /* Do quota update inside a transaction for journaled quotas. We must do that 57 /* Do quota update inside a transaction for journaled quotas. We must do that
58 * after delete_object so that quota updates go into the same transaction as 58 * after delete_object so that quota updates go into the same transaction as
59 * stat data deletion */ 59 * stat data deletion */
60 if (!err) 60 if (!err) {
61 int depth = reiserfs_write_unlock_nested(inode->i_sb);
61 dquot_free_inode(inode); 62 dquot_free_inode(inode);
63 reiserfs_write_lock_nested(inode->i_sb, depth);
64 }
62 65
63 if (journal_end(&th, inode->i_sb, jbegin_count)) 66 if (journal_end(&th, inode->i_sb, jbegin_count))
64 goto out; 67 goto out;
@@ -1768,7 +1771,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
1768 struct inode *inode, 1771 struct inode *inode,
1769 struct reiserfs_security_handle *security) 1772 struct reiserfs_security_handle *security)
1770{ 1773{
1771 struct super_block *sb; 1774 struct super_block *sb = dir->i_sb;
1772 struct reiserfs_iget_args args; 1775 struct reiserfs_iget_args args;
1773 INITIALIZE_PATH(path_to_key); 1776 INITIALIZE_PATH(path_to_key);
1774 struct cpu_key key; 1777 struct cpu_key key;
@@ -1780,9 +1783,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
1780 1783
1781 BUG_ON(!th->t_trans_id); 1784 BUG_ON(!th->t_trans_id);
1782 1785
1783 reiserfs_write_unlock(inode->i_sb); 1786 depth = reiserfs_write_unlock_nested(sb);
1784 err = dquot_alloc_inode(inode); 1787 err = dquot_alloc_inode(inode);
1785 reiserfs_write_lock(inode->i_sb); 1788 reiserfs_write_lock_nested(sb, depth);
1786 if (err) 1789 if (err)
1787 goto out_end_trans; 1790 goto out_end_trans;
1788 if (!dir->i_nlink) { 1791 if (!dir->i_nlink) {
@@ -1790,8 +1793,6 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
1790 goto out_bad_inode; 1793 goto out_bad_inode;
1791 } 1794 }
1792 1795
1793 sb = dir->i_sb;
1794
1795 /* item head of new item */ 1796 /* item head of new item */
1796 ih.ih_key.k_dir_id = reiserfs_choose_packing(dir); 1797 ih.ih_key.k_dir_id = reiserfs_choose_packing(dir);
1797 ih.ih_key.k_objectid = cpu_to_le32(reiserfs_get_unused_objectid(th)); 1798 ih.ih_key.k_objectid = cpu_to_le32(reiserfs_get_unused_objectid(th));
@@ -1983,14 +1984,16 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
1983 INODE_PKEY(inode)->k_objectid = 0; 1984 INODE_PKEY(inode)->k_objectid = 0;
1984 1985
1985 /* Quota change must be inside a transaction for journaling */ 1986 /* Quota change must be inside a transaction for journaling */
1987 depth = reiserfs_write_unlock_nested(inode->i_sb);
1986 dquot_free_inode(inode); 1988 dquot_free_inode(inode);
1989 reiserfs_write_lock_nested(inode->i_sb, depth);
1987 1990
1988 out_end_trans: 1991 out_end_trans:
1989 journal_end(th, th->t_super, th->t_blocks_allocated); 1992 journal_end(th, th->t_super, th->t_blocks_allocated);
1990 reiserfs_write_unlock(inode->i_sb);
1991 /* Drop can be outside and it needs more credits so it's better to have it outside */ 1993 /* Drop can be outside and it needs more credits so it's better to have it outside */
1994 depth = reiserfs_write_unlock_nested(inode->i_sb);
1992 dquot_drop(inode); 1995 dquot_drop(inode);
1993 reiserfs_write_lock(inode->i_sb); 1996 reiserfs_write_lock_nested(inode->i_sb, depth);
1994 inode->i_flags |= S_NOQUOTA; 1997 inode->i_flags |= S_NOQUOTA;
1995 make_bad_inode(inode); 1998 make_bad_inode(inode);
1996 1999