Skip to content

Commit

Permalink
ext4: fix sleep inside spinlock issue with quota and dealloc (#14739)
Browse files Browse the repository at this point in the history
commit 39bc680 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Dmitry Monakhov authored and Greg Kroah-Hartman committed Jan 6, 2010
1 parent 8227f06 commit 710854e
Showing 1 changed file with 5 additions and 6 deletions.
11 changes: 5 additions & 6 deletions fs/ext4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1854,30 +1854,29 @@ static int ext4_da_reserve_space(struct inode *inode, int nrblocks)

md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks;
total = md_needed + nrblocks;
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);

/*
* Make quota reservation here to prevent quota overflow
* later. Real quota accounting is done at pages writeout
* time.
*/
if (vfs_dq_reserve_block(inode, total)) {
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
if (vfs_dq_reserve_block(inode, total))
return -EDQUOT;
}

if (ext4_claim_free_blocks(sbi, total)) {
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
vfs_dq_release_reservation_block(inode, total);
if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
yield();
goto repeat;
}
return -ENOSPC;
}
spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
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);

return 0; /* success */
}

Expand Down

0 comments on commit 710854e

Please sign in to comment.