add patch remove-unneeded-test-of-ret-variable
[ext4-patch-queue.git] / fix-xfstest-generic-299-block-validity-failures
blob092ca91741f468f1682a88033a371f18d96378d7
1 ext4: fix xfstest generic/299 block validity failures
3 From: Eric Whitney <enwlinux@gmail.com>
5 Commit a115f749c1 (ext4: remove wait for unwritten extent conversion from
6 ext4_truncate) exposed a bug in ext4_ext_handle_uninitialized_extents().
7 It can be triggered by xfstest generic/299 when run on a test file
8 system created without a journal.  This test continuously fallocates and
9 truncates files to which random dio/aio writes are simultaneously
10 performed by a separate process.  The test completes successfully, but
11 if the test filesystem is mounted with the block_validity option, a
12 warning message stating that a logical block has been mapped to an
13 illegal physical block is posted in the kernel log.
15 The bug occurs when an extent is being converted to the written state
16 by ext4_end_io_dio() and ext4_ext_handle_uninitialized_extents()
17 discovers a mapping for an existing uninitialized extent. Although it
18 sets EXT4_MAP_MAPPED in map->m_flags, it fails to set map->m_pblk to
19 the discovered physical block number.  Because map->m_pblk is not
20 otherwise initialized or set by this function or its callers, its
21 uninitialized value is returned to ext4_map_blocks(), where it is
22 stored as a bogus mapping in the extent status tree.
24 Since map->m_pblk can accidentally contain illegal values that are
25 larger than the physical size of the file system,  calls to
26 check_block_validity() in ext4_map_blocks() that are enabled if the
27 block_validity mount option is used can fail, resulting in the logged
28 warning message.
30 Signed-off-by: Eric Whitney <enwlinux@gmail.com>
31 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
32 Cc: stable@vger.kernel.org  # 3.11+
33 ---
34  fs/ext4/extents.c | 1 +
35  1 file changed, 1 insertion(+)
37 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
38 index 10cff47..74bc2d5 100644
39 --- a/fs/ext4/extents.c
40 +++ b/fs/ext4/extents.c
41 @@ -3906,6 +3906,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
42                 } else
43                         err = ret;
44                 map->m_flags |= EXT4_MAP_MAPPED;
45 +               map->m_pblk = newblock;
46                 if (allocated > map->m_len)
47                         allocated = map->m_len;
48                 map->m_len = allocated;
49 -- 
50 1.8.3.2