forked from Minki/linux
ext4: move unlocked dio protection from ext4_alloc_file_blocks()
Currently ext4_alloc_file_blocks() was handling protection against unlocked DIO. However we now need to sometimes call it under i_mmap_sem and sometimes not and DIO protection ranks above it (although strictly speaking this cannot currently create any deadlocks). Also ext4_zero_range() was actually getting & releasing unlocked DIO protection twice in some cases. Luckily it didn't introduce any real bug but it was a land mine waiting to be stepped on. So move DIO protection out from ext4_alloc_file_blocks() into the two callsites. Signed-off-by: Jan Kara <jack@suse.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
ea3d7209ca
commit
17048e8a08
@ -4685,10 +4685,6 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
|
||||
if (len <= EXT_UNWRITTEN_MAX_LEN)
|
||||
flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
|
||||
|
||||
/* Wait all existing dio workers, newcomers will block on i_mutex */
|
||||
ext4_inode_block_unlocked_dio(inode);
|
||||
inode_dio_wait(inode);
|
||||
|
||||
/*
|
||||
* credits to insert 1 extent into extent tree
|
||||
*/
|
||||
@ -4752,8 +4748,6 @@ retry:
|
||||
goto retry;
|
||||
}
|
||||
|
||||
ext4_inode_resume_unlocked_dio(inode);
|
||||
|
||||
return ret > 0 ? ret2 : ret;
|
||||
}
|
||||
|
||||
@ -4827,6 +4821,10 @@ static long ext4_zero_range(struct file *file, loff_t offset,
|
||||
if (mode & FALLOC_FL_KEEP_SIZE)
|
||||
flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
|
||||
|
||||
/* Wait all existing dio workers, newcomers will block on i_mutex */
|
||||
ext4_inode_block_unlocked_dio(inode);
|
||||
inode_dio_wait(inode);
|
||||
|
||||
/* Preallocate the range including the unaligned edges */
|
||||
if (partial_begin || partial_end) {
|
||||
ret = ext4_alloc_file_blocks(file,
|
||||
@ -4835,7 +4833,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
|
||||
round_down(offset, 1 << blkbits)) >> blkbits,
|
||||
new_size, flags, mode);
|
||||
if (ret)
|
||||
goto out_mutex;
|
||||
goto out_dio;
|
||||
|
||||
}
|
||||
|
||||
@ -4844,10 +4842,6 @@ static long ext4_zero_range(struct file *file, loff_t offset,
|
||||
flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN |
|
||||
EXT4_EX_NOCACHE);
|
||||
|
||||
/* Wait all existing dio workers, newcomers will block on i_mutex */
|
||||
ext4_inode_block_unlocked_dio(inode);
|
||||
inode_dio_wait(inode);
|
||||
|
||||
/*
|
||||
* Prevent page faults from reinstantiating pages we have
|
||||
* released from page cache.
|
||||
@ -4992,8 +4986,13 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Wait all existing dio workers, newcomers will block on i_mutex */
|
||||
ext4_inode_block_unlocked_dio(inode);
|
||||
inode_dio_wait(inode);
|
||||
|
||||
ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
|
||||
flags, mode);
|
||||
ext4_inode_resume_unlocked_dio(inode);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user