From: Greg Kroah-Hartman Date: Mon, 2 Dec 2024 09:00:09 +0000 (+0100) Subject: 6.6-stable patches X-Git-Tag: v4.19.325~117 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e280175bace430d2098c9aca7b62e7fb58886a8b;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: f2fs-fix-fiemap-failure-issue-when-page-size-is-16kb.patch --- diff --git a/queue-6.6/f2fs-fix-fiemap-failure-issue-when-page-size-is-16kb.patch b/queue-6.6/f2fs-fix-fiemap-failure-issue-when-page-size-is-16kb.patch new file mode 100644 index 00000000000..b4524ff57b5 --- /dev/null +++ b/queue-6.6/f2fs-fix-fiemap-failure-issue-when-page-size-is-16kb.patch @@ -0,0 +1,109 @@ +From a7a7c1d423a6351a6541e95c797da5358e5ad1ea Mon Sep 17 00:00:00 2001 +From: Xiuhong Wang +Date: Tue, 29 Oct 2024 14:15:35 +0800 +Subject: f2fs: fix fiemap failure issue when page size is 16KB + +From: Xiuhong Wang + +commit a7a7c1d423a6351a6541e95c797da5358e5ad1ea upstream. + +After enable 16K page size, an infinite loop may occur in +fiemap (fm_length=UINT64_MAX) on a file, such as the 16KB +scratch.img during the remount operation in Android. + +The condition for whether fiemap continues to map is to check +whether the number of bytes corresponding to the next map.m_lblk +exceeds blks_to_bytes(inode,max_inode_blocks(inode)) if there are HOLE. +The latter does not take into account the maximum size of a file with 16KB +page size, so the loop cannot be jumped out. + +The following is the fail trace: +When f2fs_map_blocks reaches map.m_lblk=3936, it needs to go to the +first direct node block, so the map is 3936 + 4090 = 8026, +The next map is the second direct node block, that is, +8026 + 4090 = 12116, +The next map is the first indirect node block, that is, +12116 + 4090 * 4090 = 16740216, +The next map is the second indirect node block, that is, +16740216 + 4090 * 4090 = 33468316, +The next map is the first double indirect node block, that is, +33468316 + 4090 * 4090 * 4090 = 68451397316 +Since map.m_lblk represents the address of a block, which is 32 +bits, truncation will occur, that is, 68451397316 becomes +4026887876, and the number of bytes corresponding to the block +number does not exceed blks_to_bytes(inode,max_inode_blocks(inode)), +so the loop will not be jumped out. +The next time, it will be considered that it should still be a +double indirect node block, that is, +4026887876 + 4090 * 4090 * 4090 = 72444816876, which will be +truncated to 3725340140, and the loop will not be jumped out. + +156.374871: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 0, start blkaddr = 0x8e00, len = 0x200, flags = 2,seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 +156.374916: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 512, start blkaddr = 0x0, len = 0x0, flags = 0 , seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 +156.374920: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 513, start blkaddr = 0x0, len = 0x0, flags = 0, seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 +...... +156.385747: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 3935, start blkaddr = 0x0, len = 0x0, flags = 0, seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 +156.385752: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 3936, start blkaddr = 0x0, len = 0x0, flags = 0, seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 +156.385755: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 8026, start blkaddr = 0x0, len = 0x0, flags = 0, seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 +156.385758: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 12116, start blkaddr = 0x0, len = 0x0, flags = 0, seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 +156.385761: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 16740216, start blkaddr = 0x0, len = 0x0, flags = 0, seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 +156.385764: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 33468316, start blkaddr = 0x0, len = 0x0, flags = 0, seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 +156.385767: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 4026887876, start blkaddr = 0x0, len = 0x0, flags = 0, seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 +156.385770: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 3725340140, start blkaddr = 0x0, len = 0x0, flags = 0, seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 +156.385772: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 4026887876, start blkaddr = 0x0, len = 0x0, flags = 0, seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 +156.385775: f2fs_map_blocks: dev = (254,57), ino = 7449, file offset = 3725340140, start blkaddr = 0x0, len = 0x0, flags = 0, seg_type = 8, may_create = 0, multidevice = 0, flag = 1, err = 0 + +Commit a6a010f5def5 ("f2fs: Restrict max filesize for 16K f2fs") +has set the maximum allowed file size to (U32_MAX + 1) * F2FS_BLKSIZE, +so max_file_blocks should be used here to limit it, that is, +maxbytes defined above. And the max_inode_blocks function is not +called by other functions except here, so cleanup it. + +Signed-off-by: Xiuhong Wang +Signed-off-by: Zhiguo Niu +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Cc: Daniel Rosenberg +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/data.c | 22 +--------------------- + 1 file changed, 1 insertion(+), 21 deletions(-) + +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -1873,25 +1873,6 @@ static int f2fs_xattr_fiemap(struct inod + return (err < 0 ? err : 0); + } + +-static loff_t max_inode_blocks(struct inode *inode) +-{ +- loff_t result = ADDRS_PER_INODE(inode); +- loff_t leaf_count = ADDRS_PER_BLOCK(inode); +- +- /* two direct node blocks */ +- result += (leaf_count * 2); +- +- /* two indirect node blocks */ +- leaf_count *= NIDS_PER_BLOCK; +- result += (leaf_count * 2); +- +- /* one double indirect node block */ +- leaf_count *= NIDS_PER_BLOCK; +- result += leaf_count; +- +- return result; +-} +- + int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + u64 start, u64 len) + { +@@ -1964,8 +1945,7 @@ next: + if (!compr_cluster && !(map.m_flags & F2FS_MAP_FLAGS)) { + start_blk = next_pgofs; + +- if (blks_to_bytes(inode, start_blk) < blks_to_bytes(inode, +- max_inode_blocks(inode))) ++ if (blks_to_bytes(inode, start_blk) < maxbytes) + goto prep_next; + + flags |= FIEMAP_EXTENT_LAST; diff --git a/queue-6.6/series b/queue-6.6/series index 9bedc15cd69..4c19a4adea0 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -450,3 +450,4 @@ apparmor-fix-do-simple-duplicate-message-elimination.patch asoc-amd-yc-fix-for-enabling-dmic-on-acp6x-via-_dsd-.patch gfs2-don-t-set-glf_lock-in-gfs2_dispose_glock_lru.patch gfs2-remove-and-replace-gfs2_glock_queue_work.patch +f2fs-fix-fiemap-failure-issue-when-page-size-is-16kb.patch