Skip to content

Commit 9621787

Browse files
Jan Karasashalevin
authored andcommitted
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 <[email protected]> Signed-off-by: Theodore Ts'o <[email protected]> Reviewed-by: Mingming Cao <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 248766f commit 9621787

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

fs/ext4/extents.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4798,6 +4798,10 @@ static long ext4_zero_range(struct file *file, loff_t offset,
47984798
if (mode & FALLOC_FL_KEEP_SIZE)
47994799
flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
48004800

4801+
/* Wait all existing dio workers, newcomers will block on i_mutex */
4802+
ext4_inode_block_unlocked_dio(inode);
4803+
inode_dio_wait(inode);
4804+
48014805
/* Preallocate the range including the unaligned edges */
48024806
if (partial_begin || partial_end) {
48034807
ret = ext4_alloc_file_blocks(file,
@@ -4806,7 +4810,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
48064810
round_down(offset, 1 << blkbits)) >> blkbits,
48074811
new_size, flags, mode);
48084812
if (ret)
4809-
goto out_mutex;
4813+
goto out_dio;
48104814

48114815
}
48124816

@@ -4815,10 +4819,6 @@ static long ext4_zero_range(struct file *file, loff_t offset,
48154819
flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN |
48164820
EXT4_EX_NOCACHE);
48174821

4818-
/* Wait all existing dio workers, newcomers will block on i_mutex */
4819-
ext4_inode_block_unlocked_dio(inode);
4820-
inode_dio_wait(inode);
4821-
48224822
/*
48234823
* Prevent page faults from reinstantiating pages we have
48244824
* released from page cache.
@@ -4958,8 +4958,13 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
49584958
goto out;
49594959
}
49604960

4961+
/* Wait all existing dio workers, newcomers will block on i_mutex */
4962+
ext4_inode_block_unlocked_dio(inode);
4963+
inode_dio_wait(inode);
4964+
49614965
ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
49624966
flags, mode);
4967+
ext4_inode_resume_unlocked_dio(inode);
49634968
if (ret)
49644969
goto out;
49654970

0 commit comments

Comments
 (0)