android_kernel_sony_sdm845/fs/ext4
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Jeffle Xu e09cb9c8a3 ext4: fix partial cluster initialization when splitting extent
[ Upstream commit cfb3c85a600c6aa25a2581b3c1c4db3460f14e46 ]

Fix the bug when calculating the physical block number of the first
block in the split extent.

This bug will cause xfstests shared/298 failure on ext4 with bigalloc
enabled occasionally. Ext4 error messages indicate that previously freed
blocks are being freed again, and the following fsck will fail due to
the inconsistency of block bitmap and bg descriptor.

The following is an example case:

1. First, Initialize a ext4 filesystem with cluster size '16K', block size
'4K', in which case, one cluster contains four blocks.

2. Create one file (e.g., xxx.img) on this ext4 filesystem. Now the extent
tree of this file is like:

...
36864:[0]4:220160
36868:[0]14332:145408
51200:[0]2:231424
...

3. Then execute PUNCH_HOLE fallocate on this file. The hole range is
like:

..
ext4_ext_remove_space: dev 254,16 ino 12 since 49506 end 49506 depth 1
ext4_ext_remove_space: dev 254,16 ino 12 since 49544 end 49546 depth 1
ext4_ext_remove_space: dev 254,16 ino 12 since 49605 end 49607 depth 1
...

4. Then the extent tree of this file after punching is like

...
49507:[0]37:158047
49547:[0]58:158087
...

5. Detailed procedure of punching hole [49544, 49546]

5.1. The block address space:
```
lblk        ~49505  49506   49507~49543     49544~49546    49547~
	  ---------+------+-------------+----------------+--------
	    extent | hole |   extent	|	hole	 | extent
	  ---------+------+-------------+----------------+--------
pblk       ~158045  158046  158047~158083  158084~158086   158087~
```

5.2. The detailed layout of cluster 39521:
```
		cluster 39521
	<------------------------------->

		hole		  extent
	<----------------------><--------

lblk      49544   49545   49546   49547
	+-------+-------+-------+-------+
	|	|	|	|	|
	+-------+-------+-------+-------+
pblk     158084  1580845  158086  158087
```

5.3. The ftrace output when punching hole [49544, 49546]:
- ext4_ext_remove_space (start 49544, end 49546)
  - ext4_ext_rm_leaf (start 49544, end 49546, last_extent [49507(158047), 40], partial [pclu 39522 lblk 0 state 2])
    - ext4_remove_blocks (extent [49507(158047), 40], from 49544 to 49546, partial [pclu 39522 lblk 0 state 2]
      - ext4_free_blocks: (block 158084 count 4)
        - ext4_mballoc_free (extent 1/6753/1)

5.4. Ext4 error message in dmesg:
EXT4-fs error (device vdb): mb_free_blocks:1457: group 1, block 158084:freeing already freed block (bit 6753); block bitmap corrupt.
EXT4-fs error (device vdb): ext4_mb_generate_buddy:747: group 1, block bitmap and bg descriptor inconsistent: 19550 vs 19551 free clusters

In this case, the whole cluster 39521 is freed mistakenly when freeing
pblock 158084~158086 (i.e., the first three blocks of this cluster),
although pblock 158087 (the last remaining block of this cluster) has
not been freed yet.

The root cause of this isuue is that, the pclu of the partial cluster is
calculated mistakenly in ext4_ext_remove_space(). The correct
partial_cluster.pclu (i.e., the cluster number of the first block in the
next extent, that is, lblock 49597 (pblock 158086)) should be 39521 rather
than 39522.

Fixes: f4226d9ea4 ("ext4: fix partial cluster initialization")
Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
Reviewed-by: Eric Whitney <enwlinux@gmail.com>
Cc: stable@kernel.org # v3.19+
Link: https://lore.kernel.org/r/1590121124-37096-1-git-send-email-jefflexu@linux.alibaba.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2020-06-30 15:38:31 -04:00
..
acl.c ext4: Don't clear SGID when inheriting ACLs 2017-10-12 11:51:26 +02:00
acl.h ext2/3/4: use generic posix ACL infrastructure 2014-01-25 23:58:19 -05:00
balloc.c ext4: fix potential race between online resizing and write operations 2020-03-11 07:53:01 +01:00
bitmap.c ext4: remove unused header files 2015-04-02 23:47:42 -04:00
block_validity.c ext4: add cond_resched() to ext4_protect_reserved_inode 2020-05-20 08:15:29 +02:00
dir.c ext4: fix checksum errors with indexed dirs 2020-02-28 15:42:12 +01:00
ext4.h ext4: avoid declaring fs inconsistent due to invalid file handles 2020-05-02 17:23:18 +02:00
ext4_extents.h ext4: fix EXT_MAX_EXTENT/INDEX to check for zeroed eh_max 2020-06-20 10:24:19 +02:00
ext4_jbd2.c ext4: fix potential use after free in __ext4_journal_stop 2015-10-17 22:57:06 -04:00
ext4_jbd2.h ext4: fix NULL pointer dereference while journal is aborted 2019-03-27 14:13:03 +09:00
extents.c ext4: fix partial cluster initialization when splitting extent 2020-06-30 15:38:31 -04:00
extents_status.c ext4: remove trailing \n from ext4_warning/ext4_error calls 2016-04-27 01:11:21 -04:00
extents_status.h ext4: move procfs registration code to fs/ext4/sysfs.c 2015-09-23 12:46:17 -04:00
file.c ext4: fix data corruption caused by overlapping unaligned and aligned IO 2019-05-21 18:49:01 +02:00
fsync.c ext4: fix race between ext4_sync_parent() and rename() 2020-06-20 10:24:19 +02:00
hash.c ext4: remove unused header files 2015-04-02 23:47:42 -04:00
ialloc.c ext4: avoid declaring fs inconsistent due to invalid file handles 2020-05-02 17:23:18 +02:00
indirect.c ext4: cleanup bh release code in ext4_ind_remove_space() 2019-04-05 22:29:04 +02:00
inline.c ext4: set error return correctly when ext4_htree_store_dirent fails 2020-01-29 10:24:29 +01:00
inode.c ext4: fix special inode number checks in __ext4_iget() 2020-05-05 19:14:29 +02:00
ioctl.c ext4: avoid declaring fs inconsistent due to invalid file handles 2020-05-02 17:23:18 +02:00
Kconfig ext4 crypto: migrate into vfs's crypto engine 2016-07-10 14:01:03 -04:00
Makefile ext4 crypto: migrate into vfs's crypto engine 2016-07-10 14:01:03 -04:00
mballoc.c ext4: convert BUG_ON's to WARN_ON's in mballoc.c 2020-05-02 17:23:18 +02:00
mballoc.h ext4: add missing KERN_CONT to a few more debugging uses 2016-10-15 09:57:31 -04:00
migrate.c ext4: fix race between writepages and enabling EXT4_EXTENTS_FL 2020-02-28 15:42:52 +01:00
mmp.c ext4: don't assume that mmp_nodename/bdevname have NUL 2020-02-28 15:42:11 +01:00
move_extent.c ext4: fix argument checking in EXT4_IOC_MOVE_EXT 2018-11-13 11:16:52 -08:00
namei.c ext4: avoid declaring fs inconsistent due to invalid file handles 2020-05-02 17:23:18 +02:00
page-io.c ext4: fix deadlock allocating crypto bounce page from mempool 2020-02-14 16:31:07 -05:00
readpage.c Merge branch 'akpm' (patches from Andrew) 2016-07-26 19:55:54 -07:00
resize.c ext4: avoid declaring fs inconsistent due to invalid file handles 2020-05-02 17:23:18 +02:00
super.c ext4: check for non-zero journal inum in ext4_calculate_overhead 2020-05-02 17:23:19 +02:00
symlink.c Merge branch 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 17:11:50 -07:00
sysfs.c ext4: sysfs: print ext4_super_block fields as little-endian 2018-09-05 09:20:06 +02:00
truncate.h ext4: fix races between page faults and hole punching 2015-12-07 14:28:03 -05:00
xattr.c ext4: include terminating u32 in size of xattr entries when expanding inodes 2019-01-09 16:16:43 +01:00
xattr.h ext4: fix deadlock between inline_data and ext4_expand_extra_isize_ea() 2017-03-12 06:41:41 +01:00
xattr_security.c switch xattr_handler->set() to passing dentry and inode separately 2016-05-27 15:39:43 -04:00
xattr_trusted.c switch xattr_handler->set() to passing dentry and inode separately 2016-05-27 15:39:43 -04:00
xattr_user.c switch xattr_handler->set() to passing dentry and inode separately 2016-05-27 15:39:43 -04:00