Patch "ext4: be more strict when migrating to non-extent based file" has been added to the 3.14-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
ext4: be more strict when migrating to non-extent based file
to the 3.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
ext4-be-more-strict-when-migrating-to-non-extent-based-file.patch
and it can be found in the queue-3.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
d6f123a9297496ad0b6335fe881504c4b5b2a5e5Mon Sep 17 00:00:00 2001
From: Eryu Guan <[email protected]>
Date: Fri, 3 Jul 2015 23:56:50 -0400
Subject: ext4: be more strict when migrating to non-extent based file
From: Eryu Guan <[email protected]>
commit d6f123a9297496ad0b6335fe881504c4b5b2a5e5 upstream.
Currently the check in ext4_ind_migrate() is not enough before doing the real conversion:
a) delayed allocated extents could bypass the check on eh->eh_entries and eh->eh_depth
This can be demonstrated by this script
xfs_io -fc "pwrite 0 4k" -c "pwrite 8k 4k" /mnt/ext4/testfile chattr -e /mnt/ext4/testfile
where testfile has two extents but still be converted to non-extent based file format.
b) only extent length is checked but not the offset, which would result in data lose (delalloc) or fs corruption (nodelalloc), because non-extent based file only supports at most (12 + 2^10 + 2^20 + 2^30) blocks
This can be demostrated by
xfs_io -fc "pwrite 5T 4k" /mnt/ext4/testfile
chattr -e /mnt/ext4/testfile
sync
If delalloc is enabled, dmesg prints
EXT4-fs warning (device dm-4): ext4_block_to_path:105: block 1342177280 > max in inode 53
EXT4-fs (dm-4): Delayed block allocation failed for inode 53 at logical offset 1342177280 with max blocks 1 with error 5 EXT4-fs (dm-4): This should not happen!! Data will be lost
If delalloc is disabled, e2fsck -nf shows corruption
Inode 53, i_size is 5497558142976, should be 4096. Fix? no
Fix the two issues by
a) forcing all delayed allocation blocks to be allocated before checking eh->eh_depth and eh->eh_entries
b) limiting the last logical block of the extent is within direct map
--- fs/ext4/migrate.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
fs/ext4/migrate.c +11 -1
@@ -616,6 +616,7 @@ int ext4_ind_migrate(struct inode *inodestruct ext4_inode_info *ei =EXT4_I (inode);struct ext4_extent *ex;unsigned int i, len; +ext4_lblk_t end;ext4_fsblk_t blk;handle_t *handle;int ret;
@@ -629,6 +630,14 @@ int ext4_ind_migrate(struct inode *inode EXT4_FEATURE_RO_COMPAT_BIGALLOC))return -EOPNOTSUPP ; +/* +* In order to get correct extent info, force all delayed allocation +* blocks to be allocated, otherwise delayed allocation blocks may not +* be reflected and bypass the checks on extent header. +*/ +if (test_opt (inode->i_sb,DELALLOC )) +ext4_alloc_da_blocks (inode); + handle =ext4_journal_start (inode,EXT4_HT_MIGRATE ,1 );if (IS_ERR (handle))return PTR_ERR (handle);
@@ -650,7 +659,8 @@ int ext4_ind_migrate(struct inode *inodeelse { len =le16_to_cpu (ex->ee_len); blk =ext4_ext_pblock (ex); -if (len >EXT4_NDIR_BLOCKS ) { + end =le32_to_cpu (ex->ee_block) + len -1 ; +if (end >=EXT4_NDIR_BLOCKS ) { ret = -EOPNOTSUPP ; goto errout; }
Patches currently in stable-queue which might be from [email protected] are
queue-3.14/ext4-correctly-migrate-a-file-with-a-hole-at-the-beginning.patch queue-3.14/ext4-be-more-strict-when-migrating-to-non-extent-based-file.patch