]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Thu, 9 Jan 2025 13:52:25 +0000 (08:52 -0500)
committerSasha Levin <sashal@kernel.org>
Thu, 9 Jan 2025 13:52:25 +0000 (08:52 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.1/dm-array-fix-cursor-index-when-skipping-across-block.patch [new file with mode: 0644]
queue-6.1/dm-array-fix-releasing-a-faulty-array-block-twice-in.patch [new file with mode: 0644]
queue-6.1/dm-array-fix-unreleased-btree-blocks-on-closing-a-fa.patch [new file with mode: 0644]
queue-6.1/exfat-fix-the-infinite-loop-in-__exfat_free_cluster.patch [new file with mode: 0644]
queue-6.1/exfat-fix-the-infinite-loop-in-exfat_readdir.patch [new file with mode: 0644]
queue-6.1/jbd2-flush-filesystem-device-before-updating-tail-se.patch [new file with mode: 0644]
queue-6.1/jbd2-increase-io-priority-for-writing-revoke-records.patch [new file with mode: 0644]
queue-6.1/series

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 (file)
index 0000000..ce88313
--- /dev/null
@@ -0,0 +1,74 @@
+From 514b3c4a2a842fde3721b453bba83bed48156508 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Dec 2024 19:41:53 +0800
+Subject: dm array: fix cursor index when skipping across block boundaries
+
+From: Ming-Hung Tsai <mtsai@redhat.com>
+
+[ 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 <<EOF >> cmeta.xml
+<superblock uuid="" block_size="64" nr_cache_blocks="32768" \
+policy="smq" hint_width="4">
+  <mappings>
+    <mapping cache_block="32767" origin_block="0" dirty="true"/>
+  </mappings>
+</superblock>
+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 <KERNEL_DIR>
+
+Signed-off-by: Ming-Hung Tsai <mtsai@redhat.com>
+Fixes: 9b696229aa7d ("dm persistent data: add cursor skip functions to the cursor APIs")
+Reviewed-by: Joe Thornber <thornber@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..c9520de
--- /dev/null
@@ -0,0 +1,110 @@
+From d729736fde888aa5f48ab2a77658a716de413677 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <mtsai@redhat.com>
+
+[ 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 <KERNEL_DIR>
+
+Signed-off-by: Ming-Hung Tsai <mtsai@redhat.com>
+Fixes: fdd1315aa5f0 ("dm array: introduce cursor api")
+Reviewed-by: Joe Thornber <thornber@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..7bcec16
--- /dev/null
@@ -0,0 +1,49 @@
+From 32bb2fa69aa8c618ba325ff2d2c39512879f47df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <mtsai@redhat.com>
+
+[ 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 <KERNEL_DIR>
+
+Signed-off-by: Ming-Hung Tsai <mtsai@redhat.com>
+Fixes: fdd1315aa5f0 ("dm array: introduce cursor api")
+Reviewed-by: Joe Thornber <thornber@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..36cec6b
--- /dev/null
@@ -0,0 +1,53 @@
+From dac4fb0032e2ffc79eb5ddfc0dbcb2428a7475c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Dec 2024 13:39:42 +0800
+Subject: exfat: fix the infinite loop in __exfat_free_cluster()
+
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+
+[ 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 <Yuezhang.Mo@sony.com>
+Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..a0c5150
--- /dev/null
@@ -0,0 +1,57 @@
+From 15334402127bd8b63d7ae801a5d95f3e031478c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Dec 2024 13:08:37 +0800
+Subject: exfat: fix the infinite loop in exfat_readdir()
+
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+
+[ 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 <Yuezhang.Mo@sony.com>
+Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..c280972
--- /dev/null
@@ -0,0 +1,45 @@
+From ee77af575945b1b4c9cea75bc427e66fab2f2609 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Dec 2024 09:44:07 +0800
+Subject: jbd2: flush filesystem device before updating tail sequence
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ 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 <yi.zhang@huawei.com>
+Link: https://lore.kernel.org/r/20241203014407.805916-3-yi.zhang@huaweicloud.com
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..55dbd36
--- /dev/null
@@ -0,0 +1,41 @@
+From f93bc0c8474acf30c2c5ddbfb4c63c8fee5967a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Dec 2024 09:44:06 +0800
+Subject: jbd2: increase IO priority for writing revoke records
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ 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 <yi.zhang@huawei.com>
+Link: https://lore.kernel.org/r/20241203014407.805916-2-yi.zhang@huaweicloud.com
+Reviewed-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
index 45ab75e91df416938f7629dd52731dec7dd0bd32..746848cd253ff8d9eaae53ae50336d4c336ff4dd 100644 (file)
@@ -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