aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2009-12-10 11:36:27 -0500
committerJan Kara <jack@suse.cz>2009-12-23 07:44:12 -0500
commit39bc680a8160bb9d6743f7873b535d553ff61058 (patch)
tree6aac2c11b09870bffb877dcaf6ae44b34b56d4db /fs/ext4/inode.c
parentd21cd8f163ac44b15c465aab7306db931c606908 (diff)
ext4: fix sleep inside spinlock issue with quota and dealloc (#14739)
Unlock i_block_reservation_lock before vfs_dq_reserve_block(). This patch fixes http://bugzilla.kernel.org/show_bug.cgi?id=14739 CC: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index ddd0a9c87d9e..ab807963a614 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1816,19 +1816,17 @@ repeat:
1816 1816
1817 md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks; 1817 md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks;
1818 total = md_needed + nrblocks; 1818 total = md_needed + nrblocks;
1819 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1819 1820
1820 /* 1821 /*
1821 * Make quota reservation here to prevent quota overflow 1822 * Make quota reservation here to prevent quota overflow
1822 * later. Real quota accounting is done at pages writeout 1823 * later. Real quota accounting is done at pages writeout
1823 * time. 1824 * time.
1824 */ 1825 */
1825 if (vfs_dq_reserve_block(inode, total)) { 1826 if (vfs_dq_reserve_block(inode, total))
1826 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1827 return -EDQUOT; 1827 return -EDQUOT;
1828 }
1829 1828
1830 if (ext4_claim_free_blocks(sbi, total)) { 1829 if (ext4_claim_free_blocks(sbi, total)) {
1831 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1832 vfs_dq_release_reservation_block(inode, total); 1830 vfs_dq_release_reservation_block(inode, total);
1833 if (ext4_should_retry_alloc(inode->i_sb, &retries)) { 1831 if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
1834 yield(); 1832 yield();
@@ -1836,10 +1834,11 @@ repeat:
1836 } 1834 }
1837 return -ENOSPC; 1835 return -ENOSPC;
1838 } 1836 }
1837 spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
1839 EXT4_I(inode)->i_reserved_data_blocks += nrblocks; 1838 EXT4_I(inode)->i_reserved_data_blocks += nrblocks;
1840 EXT4_I(inode)->i_reserved_meta_blocks = mdblocks; 1839 EXT4_I(inode)->i_reserved_meta_blocks += md_needed;
1841
1842 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); 1840 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1841
1843 return 0; /* success */ 1842 return 0; /* success */
1844} 1843}
1845 1844