From: Sasha Levin Date: Thu, 9 Jan 2025 13:52:25 +0000 (-0500) Subject: Fixes for 6.1 X-Git-Tag: v6.6.71~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=af4a0e4be42aa2a79e6bd9dd43a0378db91caf2f;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.1 Signed-off-by: Sasha Levin --- diff --git a/queue-6.1/dm-array-fix-cursor-index-when-skipping-across-block.patch b/queue-6.1/dm-array-fix-cursor-index-when-skipping-across-block.patch new file mode 100644 index 00000000000..ce88313cbf6 --- /dev/null +++ b/queue-6.1/dm-array-fix-cursor-index-when-skipping-across-block.patch @@ -0,0 +1,74 @@ +From 514b3c4a2a842fde3721b453bba83bed48156508 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Dec 2024 19:41:53 +0800 +Subject: dm array: fix cursor index when skipping across block boundaries + +From: Ming-Hung Tsai + +[ Upstream commit 0bb1968da2737ba68fd63857d1af2b301a18d3bf ] + +dm_array_cursor_skip() seeks to the target position by loading array +blocks iteratively until the specified number of entries to skip is +reached. When seeking across block boundaries, it uses +dm_array_cursor_next() to step into the next block. +dm_array_cursor_skip() must first move the cursor index to the end +of the current block; otherwise, the cursor position could incorrectly +remain in the same block, causing the actual number of skipped entries +to be much smaller than expected. + +This bug affects cache resizing in v2 metadata and could lead to data +loss if the fast device is shrunk during the first-time resume. For +example: + +1. create a cache metadata consists of 32768 blocks, with a dirty block + assigned to the second bitmap block. cache_restore v1.0 is required. + +cat <> cmeta.xml + + + + + +EOF +dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" +cache_restore -i cmeta.xml -o /dev/mapper/cmeta --metadata-version=2 + +2. bring up the cache while attempt to discard all the blocks belonging + to the second bitmap block (block# 32576 to 32767). The last command + is expected to fail, but it actually succeeds. + +dmsetup create cdata --table "0 2084864 linear /dev/sdc 8192" +dmsetup create corig --table "0 65536 linear /dev/sdc 2105344" +dmsetup create cache --table "0 65536 cache /dev/mapper/cmeta \ +/dev/mapper/cdata /dev/mapper/corig 64 2 metadata2 writeback smq \ +2 migration_threshold 0" + +In addition to the reproducer described above, this fix can be +verified using the "array_cursor/skip" tests in dm-unit: + dm-unit run /pdata/array_cursor/skip/ --kernel-dir + +Signed-off-by: Ming-Hung Tsai +Fixes: 9b696229aa7d ("dm persistent data: add cursor skip functions to the cursor APIs") +Reviewed-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Sasha Levin +--- + drivers/md/persistent-data/dm-array.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/md/persistent-data/dm-array.c b/drivers/md/persistent-data/dm-array.c +index aab0385ed53b..767ab60507d9 100644 +--- a/drivers/md/persistent-data/dm-array.c ++++ b/drivers/md/persistent-data/dm-array.c +@@ -998,6 +998,7 @@ int dm_array_cursor_skip(struct dm_array_cursor *c, uint32_t count) + } + + count -= remaining; ++ c->index += (remaining - 1); + r = dm_array_cursor_next(c); + + } while (!r); +-- +2.39.5 + diff --git a/queue-6.1/dm-array-fix-releasing-a-faulty-array-block-twice-in.patch b/queue-6.1/dm-array-fix-releasing-a-faulty-array-block-twice-in.patch new file mode 100644 index 00000000000..c9520deb871 --- /dev/null +++ b/queue-6.1/dm-array-fix-releasing-a-faulty-array-block-twice-in.patch @@ -0,0 +1,110 @@ +From d729736fde888aa5f48ab2a77658a716de413677 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Dec 2024 19:41:51 +0800 +Subject: dm array: fix releasing a faulty array block twice in + dm_array_cursor_end + +From: Ming-Hung Tsai + +[ Upstream commit f2893c0804d86230ffb8f1c8703fdbb18648abc8 ] + +When dm_bm_read_lock() fails due to locking or checksum errors, it +releases the faulty block implicitly while leaving an invalid output +pointer behind. The caller of dm_bm_read_lock() should not operate on +this invalid dm_block pointer, or it will lead to undefined result. +For example, the dm_array_cursor incorrectly caches the invalid pointer +on reading a faulty array block, causing a double release in +dm_array_cursor_end(), then hitting the BUG_ON in dm-bufio cache_put(). + +Reproduce steps: + +1. initialize a cache device + +dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" +dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" +dmsetup create corig --table "0 524288 linear /dev/sdc $262144" +dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 +dmsetup create cache --table "0 524288 cache /dev/mapper/cmeta \ +/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" + +2. wipe the second array block offline + +dmsteup remove cache cmeta cdata corig +mapping_root=$(dd if=/dev/sdc bs=1c count=8 skip=192 \ +2>/dev/null | hexdump -e '1/8 "%u\n"') +ablock=$(dd if=/dev/sdc bs=1c count=8 skip=$((4096*mapping_root+2056)) \ +2>/dev/null | hexdump -e '1/8 "%u\n"') +dd if=/dev/zero of=/dev/sdc bs=4k count=1 seek=$ablock + +3. try reopen the cache device + +dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" +dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" +dmsetup create corig --table "0 524288 linear /dev/sdc $262144" +dmsetup create cache --table "0 524288 cache /dev/mapper/cmeta \ +/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" + +Kernel logs: + +(snip) +device-mapper: array: array_block_check failed: blocknr 0 != wanted 10 +device-mapper: block manager: array validator check failed for block 10 +device-mapper: array: get_ablock failed +device-mapper: cache metadata: dm_array_cursor_next for mapping failed +------------[ cut here ]------------ +kernel BUG at drivers/md/dm-bufio.c:638! + +Fix by setting the cached block pointer to NULL on errors. + +In addition to the reproducer described above, this fix can be +verified using the "array_cursor/damaged" test in dm-unit: + dm-unit run /pdata/array_cursor/damaged --kernel-dir + +Signed-off-by: Ming-Hung Tsai +Fixes: fdd1315aa5f0 ("dm array: introduce cursor api") +Reviewed-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Sasha Levin +--- + drivers/md/persistent-data/dm-array.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/md/persistent-data/dm-array.c b/drivers/md/persistent-data/dm-array.c +index eff9b41869f2..d8ec2c6c1b2e 100644 +--- a/drivers/md/persistent-data/dm-array.c ++++ b/drivers/md/persistent-data/dm-array.c +@@ -912,23 +912,27 @@ static int load_ablock(struct dm_array_cursor *c) + if (c->block) + unlock_ablock(c->info, c->block); + +- c->block = NULL; +- c->ab = NULL; + c->index = 0; + + r = dm_btree_cursor_get_value(&c->cursor, &key, &value_le); + if (r) { + DMERR("dm_btree_cursor_get_value failed"); +- dm_btree_cursor_end(&c->cursor); ++ goto out; + + } else { + r = get_ablock(c->info, le64_to_cpu(value_le), &c->block, &c->ab); + if (r) { + DMERR("get_ablock failed"); +- dm_btree_cursor_end(&c->cursor); ++ goto out; + } + } + ++ return 0; ++ ++out: ++ dm_btree_cursor_end(&c->cursor); ++ c->block = NULL; ++ c->ab = NULL; + return r; + } + +-- +2.39.5 + diff --git a/queue-6.1/dm-array-fix-unreleased-btree-blocks-on-closing-a-fa.patch b/queue-6.1/dm-array-fix-unreleased-btree-blocks-on-closing-a-fa.patch new file mode 100644 index 00000000000..7bcec160d96 --- /dev/null +++ b/queue-6.1/dm-array-fix-unreleased-btree-blocks-on-closing-a-fa.patch @@ -0,0 +1,49 @@ +From 32bb2fa69aa8c618ba325ff2d2c39512879f47df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Dec 2024 19:41:52 +0800 +Subject: dm array: fix unreleased btree blocks on closing a faulty array + cursor + +From: Ming-Hung Tsai + +[ Upstream commit 626f128ee9c4133b1cfce4be2b34a1508949370e ] + +The cached block pointer in dm_array_cursor might be NULL if it reaches +an unreadable array block, or the array is empty. Therefore, +dm_array_cursor_end() should call dm_btree_cursor_end() unconditionally, +to prevent leaving unreleased btree blocks. + +This fix can be verified using the "array_cursor/iterate/empty" test +in dm-unit: + dm-unit run /pdata/array_cursor/iterate/empty --kernel-dir + +Signed-off-by: Ming-Hung Tsai +Fixes: fdd1315aa5f0 ("dm array: introduce cursor api") +Reviewed-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Sasha Levin +--- + drivers/md/persistent-data/dm-array.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/md/persistent-data/dm-array.c b/drivers/md/persistent-data/dm-array.c +index d8ec2c6c1b2e..aab0385ed53b 100644 +--- a/drivers/md/persistent-data/dm-array.c ++++ b/drivers/md/persistent-data/dm-array.c +@@ -955,10 +955,10 @@ EXPORT_SYMBOL_GPL(dm_array_cursor_begin); + + void dm_array_cursor_end(struct dm_array_cursor *c) + { +- if (c->block) { ++ if (c->block) + unlock_ablock(c->info, c->block); +- dm_btree_cursor_end(&c->cursor); +- } ++ ++ dm_btree_cursor_end(&c->cursor); + } + EXPORT_SYMBOL_GPL(dm_array_cursor_end); + +-- +2.39.5 + diff --git a/queue-6.1/exfat-fix-the-infinite-loop-in-__exfat_free_cluster.patch b/queue-6.1/exfat-fix-the-infinite-loop-in-__exfat_free_cluster.patch new file mode 100644 index 00000000000..36cec6b46f2 --- /dev/null +++ b/queue-6.1/exfat-fix-the-infinite-loop-in-__exfat_free_cluster.patch @@ -0,0 +1,53 @@ +From dac4fb0032e2ffc79eb5ddfc0dbcb2428a7475c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Dec 2024 13:39:42 +0800 +Subject: exfat: fix the infinite loop in __exfat_free_cluster() + +From: Yuezhang Mo + +[ Upstream commit a5324b3a488d883aa2d42f72260054e87d0940a0 ] + +In __exfat_free_cluster(), the cluster chain is traversed until the +EOF cluster. If the cluster chain includes a loop due to file system +corruption, the EOF cluster cannot be traversed, resulting in an +infinite loop. + +This commit uses the total number of clusters to prevent this infinite +loop. + +Reported-by: syzbot+1de5a37cb85a2d536330@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=1de5a37cb85a2d536330 +Tested-by: syzbot+1de5a37cb85a2d536330@syzkaller.appspotmail.com +Fixes: 31023864e67a ("exfat: add fat entry operations") +Signed-off-by: Yuezhang Mo +Reviewed-by: Sungjong Seo +Signed-off-by: Namjae Jeon +Signed-off-by: Sasha Levin +--- + fs/exfat/fatent.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c +index 41ae4cce1f42..fe007ae2f23c 100644 +--- a/fs/exfat/fatent.c ++++ b/fs/exfat/fatent.c +@@ -216,6 +216,16 @@ static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain + + if (err) + goto dec_used_clus; ++ ++ if (num_clusters >= sbi->num_clusters - EXFAT_FIRST_CLUSTER) { ++ /* ++ * The cluster chain includes a loop, scan the ++ * bitmap to get the number of used clusters. ++ */ ++ exfat_count_used_clusters(sb, &sbi->used_clusters); ++ ++ return 0; ++ } + } while (clu != EXFAT_EOF_CLUSTER); + } + +-- +2.39.5 + diff --git a/queue-6.1/exfat-fix-the-infinite-loop-in-exfat_readdir.patch b/queue-6.1/exfat-fix-the-infinite-loop-in-exfat_readdir.patch new file mode 100644 index 00000000000..a0c515029a0 --- /dev/null +++ b/queue-6.1/exfat-fix-the-infinite-loop-in-exfat_readdir.patch @@ -0,0 +1,57 @@ +From 15334402127bd8b63d7ae801a5d95f3e031478c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Dec 2024 13:08:37 +0800 +Subject: exfat: fix the infinite loop in exfat_readdir() + +From: Yuezhang Mo + +[ Upstream commit fee873761bd978d077d8c55334b4966ac4cb7b59 ] + +If the file system is corrupted so that a cluster is linked to +itself in the cluster chain, and there is an unused directory +entry in the cluster, 'dentry' will not be incremented, causing +condition 'dentry < max_dentries' unable to prevent an infinite +loop. + +This infinite loop causes s_lock not to be released, and other +tasks will hang, such as exfat_sync_fs(). + +This commit stops traversing the cluster chain when there is unused +directory entry in the cluster to avoid this infinite loop. + +Reported-by: syzbot+205c2644abdff9d3f9fc@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=205c2644abdff9d3f9fc +Tested-by: syzbot+205c2644abdff9d3f9fc@syzkaller.appspotmail.com +Fixes: ca06197382bd ("exfat: add directory operations") +Signed-off-by: Yuezhang Mo +Reviewed-by: Sungjong Seo +Signed-off-by: Namjae Jeon +Signed-off-by: Sasha Levin +--- + fs/exfat/dir.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c +index d58c69018051..e651ffb06a43 100644 +--- a/fs/exfat/dir.c ++++ b/fs/exfat/dir.c +@@ -125,7 +125,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent + type = exfat_get_entry_type(ep); + if (type == TYPE_UNUSED) { + brelse(bh); +- break; ++ goto out; + } + + if (type != TYPE_FILE && type != TYPE_DIR) { +@@ -185,6 +185,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent + } + } + ++out: + dir_entry->namebuf.lfn[0] = '\0'; + *cpos = EXFAT_DEN_TO_B(dentry); + return 0; +-- +2.39.5 + diff --git a/queue-6.1/jbd2-flush-filesystem-device-before-updating-tail-se.patch b/queue-6.1/jbd2-flush-filesystem-device-before-updating-tail-se.patch new file mode 100644 index 00000000000..c280972d522 --- /dev/null +++ b/queue-6.1/jbd2-flush-filesystem-device-before-updating-tail-se.patch @@ -0,0 +1,45 @@ +From ee77af575945b1b4c9cea75bc427e66fab2f2609 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2024 09:44:07 +0800 +Subject: jbd2: flush filesystem device before updating tail sequence + +From: Zhang Yi + +[ Upstream commit a0851ea9cd555c333795b85ddd908898b937c4e1 ] + +When committing transaction in jbd2_journal_commit_transaction(), the +disk caches for the filesystem device should be flushed before updating +the journal tail sequence. However, this step is missed if the journal +is not located on the filesystem device. As a result, the filesystem may +become inconsistent following a power failure or system crash. Fix it by +ensuring that the filesystem device is flushed appropriately. + +Fixes: 3339578f0578 ("jbd2: cleanup journal tail after transaction commit") +Signed-off-by: Zhang Yi +Link: https://lore.kernel.org/r/20241203014407.805916-3-yi.zhang@huaweicloud.com +Reviewed-by: Jan Kara +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/jbd2/commit.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c +index 7b34deec8b87..6d02dcad8ffd 100644 +--- a/fs/jbd2/commit.c ++++ b/fs/jbd2/commit.c +@@ -811,9 +811,9 @@ void jbd2_journal_commit_transaction(journal_t *journal) + /* + * If the journal is not located on the file system device, + * then we must flush the file system device before we issue +- * the commit record ++ * the commit record and update the journal tail sequence. + */ +- if (commit_transaction->t_need_data_flush && ++ if ((commit_transaction->t_need_data_flush || update_tail) && + (journal->j_fs_dev != journal->j_dev) && + (journal->j_flags & JBD2_BARRIER)) + blkdev_issue_flush(journal->j_fs_dev); +-- +2.39.5 + diff --git a/queue-6.1/jbd2-increase-io-priority-for-writing-revoke-records.patch b/queue-6.1/jbd2-increase-io-priority-for-writing-revoke-records.patch new file mode 100644 index 00000000000..55dbd362a89 --- /dev/null +++ b/queue-6.1/jbd2-increase-io-priority-for-writing-revoke-records.patch @@ -0,0 +1,41 @@ +From f93bc0c8474acf30c2c5ddbfb4c63c8fee5967a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2024 09:44:06 +0800 +Subject: jbd2: increase IO priority for writing revoke records + +From: Zhang Yi + +[ Upstream commit ac1e21bd8c883aeac2f1835fc93b39c1e6838b35 ] + +Commit '6a3afb6ac6df ("jbd2: increase the journal IO's priority")' +increases the priority of journal I/O by marking I/O with the +JBD2_JOURNAL_REQ_FLAGS. However, that commit missed the revoke buffers, +so also addresses that kind of I/Os. + +Fixes: 6a3afb6ac6df ("jbd2: increase the journal IO's priority") +Signed-off-by: Zhang Yi +Link: https://lore.kernel.org/r/20241203014407.805916-2-yi.zhang@huaweicloud.com +Reviewed-by: Kemeng Shi +Reviewed-by: Jan Kara +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/jbd2/revoke.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c +index 4556e4689024..ce63d5fde9c3 100644 +--- a/fs/jbd2/revoke.c ++++ b/fs/jbd2/revoke.c +@@ -654,7 +654,7 @@ static void flush_descriptor(journal_t *journal, + set_buffer_jwrite(descriptor); + BUFFER_TRACE(descriptor, "write"); + set_buffer_dirty(descriptor); +- write_dirty_buffer(descriptor, REQ_SYNC); ++ write_dirty_buffer(descriptor, JBD2_JOURNAL_REQ_FLAGS); + } + #endif + +-- +2.39.5 + diff --git a/queue-6.1/series b/queue-6.1/series index 45ab75e91df..746848cd253 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -1,3 +1,10 @@ ceph-give-up-on-paths-longer-than-path_max.patch bpf-sockmap-fix-race-between-element-replace-and-close.patch sched-task_stack-fix-object_is_on_stack-for-kasan-tagged-pointers.patch +jbd2-increase-io-priority-for-writing-revoke-records.patch +jbd2-flush-filesystem-device-before-updating-tail-se.patch +dm-array-fix-releasing-a-faulty-array-block-twice-in.patch +dm-array-fix-unreleased-btree-blocks-on-closing-a-fa.patch +dm-array-fix-cursor-index-when-skipping-across-block.patch +exfat-fix-the-infinite-loop-in-exfat_readdir.patch +exfat-fix-the-infinite-loop-in-__exfat_free_cluster.patch