mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 03:06:10 +00:00
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>
This commit is contained in:
parent
d21cd8f163
commit
39bc680a81
1 changed files with 5 additions and 6 deletions
|
@ -1816,19 +1816,17 @@ repeat:
|
||||||
|
|
||||||
md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks;
|
md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks;
|
||||||
total = md_needed + nrblocks;
|
total = md_needed + nrblocks;
|
||||||
|
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make quota reservation here to prevent quota overflow
|
* Make quota reservation here to prevent quota overflow
|
||||||
* later. Real quota accounting is done at pages writeout
|
* later. Real quota accounting is done at pages writeout
|
||||||
* time.
|
* time.
|
||||||
*/
|
*/
|
||||||
if (vfs_dq_reserve_block(inode, total)) {
|
if (vfs_dq_reserve_block(inode, total))
|
||||||
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
|
|
||||||
return -EDQUOT;
|
return -EDQUOT;
|
||||||
}
|
|
||||||
|
|
||||||
if (ext4_claim_free_blocks(sbi, total)) {
|
if (ext4_claim_free_blocks(sbi, total)) {
|
||||||
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
|
|
||||||
vfs_dq_release_reservation_block(inode, total);
|
vfs_dq_release_reservation_block(inode, total);
|
||||||
if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
|
if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
|
||||||
yield();
|
yield();
|
||||||
|
@ -1836,10 +1834,11 @@ repeat:
|
||||||
}
|
}
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
|
spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
|
||||||
EXT4_I(inode)->i_reserved_data_blocks += nrblocks;
|
EXT4_I(inode)->i_reserved_data_blocks += nrblocks;
|
||||||
EXT4_I(inode)->i_reserved_meta_blocks = mdblocks;
|
EXT4_I(inode)->i_reserved_meta_blocks += md_needed;
|
||||||
|
|
||||||
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
|
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
|
||||||
|
|
||||||
return 0; /* success */
|
return 0; /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue