| From: Lukas Czerner <lczerner@redhat.com> |
| Date: Mon, 15 Jun 2015 00:23:53 -0400 |
| Subject: ext4: wait for existing dio workers in ext4_alloc_file_blocks() |
| |
| commit 0d306dcf86e8f065dff42a4a934ae9d99af35ba5 upstream. |
| |
| Currently existing dio workers can jump in and potentially increase |
| extent tree depth while we're allocating blocks in |
| ext4_alloc_file_blocks(). This may cause us to underestimate the |
| number of credits needed for the transaction because the extent tree |
| depth can change after our estimation. |
| |
| Fix this by waiting for all the existing dio workers in the same way |
| as we do it in ext4_punch_hole. We've seen errors caused by this in |
| xfstest generic/299, however it's really hard to reproduce. |
| |
| Signed-off-by: Lukas Czerner <lczerner@redhat.com> |
| Signed-off-by: Theodore Ts'o <tytso@mit.edu> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| fs/ext4/extents.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| --- a/fs/ext4/extents.c |
| +++ b/fs/ext4/extents.c |
| @@ -4707,6 +4707,10 @@ static int ext4_alloc_file_blocks(struct |
| 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 |
| */ |
| @@ -4756,6 +4760,8 @@ retry: |
| goto retry; |
| } |
| |
| + ext4_inode_resume_unlocked_dio(inode); |
| + |
| return ret > 0 ? ret2 : ret; |
| } |
| |