--- /dev/null
+From 8ed10e3be3d7f6905f1a98b67b823e83668664e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Jun 2023 11:27:41 +0100
+Subject: btrfs: do not BUG_ON() on tree mod log failure at balance_level()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 39020d8abc7ec62c4de9b260e3d10d4a1c2478ce ]
+
+At balance_level(), instead of doing a BUG_ON() in case we fail to record
+tree mod log operations, do a transaction abort and return the error to
+the callers. There's really no need for the BUG_ON() as we can release
+all resources in this context, and we have to abort because other future
+tree searches that use the tree mod log (btrfs_search_old_slot()) may get
+inconsistent results if other operations modify the tree after that
+failure and before the tree mod log based search.
+
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/ctree.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
+index ab9f8d6c4f1b9..1cd6ce6aafb00 100644
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -935,7 +935,12 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
+ }
+
+ ret = btrfs_tree_mod_log_insert_root(root->node, child, true);
+- BUG_ON(ret < 0);
++ if (ret < 0) {
++ btrfs_tree_unlock(child);
++ free_extent_buffer(child);
++ btrfs_abort_transaction(trans, ret);
++ goto enospc;
++ }
+ rcu_assign_pointer(root->node, child);
+
+ add_root_to_dirty_list(root);
+@@ -1017,7 +1022,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
+ btrfs_node_key(right, &right_key, 0);
+ ret = btrfs_tree_mod_log_insert_key(parent, pslot + 1,
+ BTRFS_MOD_LOG_KEY_REPLACE, GFP_NOFS);
+- BUG_ON(ret < 0);
++ if (ret < 0) {
++ btrfs_abort_transaction(trans, ret);
++ goto enospc;
++ }
+ btrfs_set_node_key(parent, &right_key, pslot + 1);
+ btrfs_mark_buffer_dirty(parent);
+ }
+@@ -1064,6 +1072,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
+ ret = btrfs_tree_mod_log_insert_key(parent, pslot,
+ BTRFS_MOD_LOG_KEY_REPLACE, GFP_NOFS);
+ BUG_ON(ret < 0);
++ if (ret < 0) {
++ btrfs_abort_transaction(trans, ret);
++ goto enospc;
++ }
+ btrfs_set_node_key(parent, &mid_key, pslot);
+ btrfs_mark_buffer_dirty(parent);
+ }
+--
+2.39.2
+
--- /dev/null
+From 675613846fe006664753948bf9100f1ce52009c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Feb 2023 18:55:47 +0100
+Subject: dm: avoid split of quoted strings where possible
+
+From: Heinz Mauelshagen <heinzm@redhat.com>
+
+[ Upstream commit 2e84fecf19e1694338deec8bf6c90ff84f8f31fb ]
+
+Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Stable-dep-of: 249bed821b4d ("dm ioctl: Avoid double-fetch of version")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-crypt.c | 3 +--
+ drivers/md/dm-ioctl.c | 6 ++----
+ drivers/md/dm-log-userspace-transfer.c | 5 ++---
+ drivers/md/dm-log.c | 3 +--
+ drivers/md/dm-raid1.c | 7 +++----
+ drivers/md/dm-snap-persistent.c | 6 ++----
+ drivers/md/dm-snap-transient.c | 3 +--
+ drivers/md/dm-snap.c | 21 +++++++--------------
+ drivers/md/dm-stripe.c | 12 ++++--------
+ drivers/md/dm-table.c | 18 ++++++------------
+ drivers/md/dm-thin-metadata.c | 8 ++++----
+ drivers/md/dm-zoned-metadata.c | 12 ++++--------
+ 12 files changed, 37 insertions(+), 67 deletions(-)
+
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index ee269b1d09fac..ff515437d81e7 100644
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -733,8 +733,7 @@ static int crypt_iv_eboiv_ctr(struct crypt_config *cc, struct dm_target *ti,
+ }
+
+ if (crypto_skcipher_blocksize(any_tfm(cc)) != cc->iv_size) {
+- ti->error = "Block size of EBOIV cipher does "
+- "not match IV size of block cipher";
++ ti->error = "Block size of EBOIV cipher does not match IV size of block cipher";
+ return -EINVAL;
+ }
+
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 9fc4a5d51b3fc..2ced382cdd70b 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -434,8 +434,7 @@ static struct mapped_device *dm_hash_rename(struct dm_ioctl *param,
+ hc = __get_name_cell(new);
+
+ if (hc) {
+- DMERR("Unable to change %s on mapped device %s to one that "
+- "already exists: %s",
++ DMERR("Unable to change %s on mapped device %s to one that already exists: %s",
+ change_uuid ? "uuid" : "name",
+ param->name, new);
+ dm_put(hc->md);
+@@ -1822,8 +1821,7 @@ static int check_version(unsigned int cmd, struct dm_ioctl __user *user)
+
+ if ((DM_VERSION_MAJOR != version[0]) ||
+ (DM_VERSION_MINOR < version[1])) {
+- DMERR("ioctl interface mismatch: "
+- "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)",
++ DMERR("ioctl interface mismatch: kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)",
+ DM_VERSION_MAJOR, DM_VERSION_MINOR,
+ DM_VERSION_PATCHLEVEL,
+ version[0], version[1], version[2], cmd);
+diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
+index 072559b709edd..ee5586e8e1c1e 100644
+--- a/drivers/md/dm-log-userspace-transfer.c
++++ b/drivers/md/dm-log-userspace-transfer.c
+@@ -108,9 +108,8 @@ static int fill_pkg(struct cn_msg *msg, struct dm_ulog_request *tfr)
+ if (pkg->error != -EAGAIN)
+ *(pkg->data_size) = 0;
+ } else if (tfr->data_size > *(pkg->data_size)) {
+- DMERR("Insufficient space to receive package [%u] "
+- "(%u vs %zu)", tfr->request_type,
+- tfr->data_size, *(pkg->data_size));
++ DMERR("Insufficient space to receive package [%u] (%u vs %zu)",
++ tfr->request_type, tfr->data_size, *(pkg->data_size));
+
+ *(pkg->data_size) = 0;
+ pkg->error = -ENOSPC;
+diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
+index 159f2c05dfd3c..05141eea18d3c 100644
+--- a/drivers/md/dm-log.c
++++ b/drivers/md/dm-log.c
+@@ -382,8 +382,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
+ else if (!strcmp(argv[1], "nosync"))
+ sync = NOSYNC;
+ else {
+- DMWARN("unrecognised sync argument to "
+- "dirty region log: %s", argv[1]);
++ DMWARN("unrecognised sync argument to dirty region log: %s", argv[1]);
+ return -EINVAL;
+ }
+ }
+diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
+index 8bd7e87d3538e..c38e63706d911 100644
+--- a/drivers/md/dm-raid1.c
++++ b/drivers/md/dm-raid1.c
+@@ -236,8 +236,8 @@ static void fail_mirror(struct mirror *m, enum dm_raid1_error error_type)
+ * Better to issue requests to same failing device
+ * than to risk returning corrupt data.
+ */
+- DMERR("Primary mirror (%s) failed while out-of-sync: "
+- "Reads may fail.", m->dev->name);
++ DMERR("Primary mirror (%s) failed while out-of-sync: Reads may fail.",
++ m->dev->name);
+ goto out;
+ }
+
+@@ -517,8 +517,7 @@ static void read_callback(unsigned long error, void *context)
+ fail_mirror(m, DM_RAID1_READ_ERROR);
+
+ if (likely(default_ok(m)) || mirror_available(m->ms, bio)) {
+- DMWARN_LIMIT("Read failure on mirror device %s. "
+- "Trying alternative device.",
++ DMWARN_LIMIT("Read failure on mirror device %s. Trying alternative device.",
+ m->dev->name);
+ queue_bio(m->ms, bio, bio_data_dir(bio));
+ return;
+diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
+index 5176810f5d243..80b95746a43e0 100644
+--- a/drivers/md/dm-snap-persistent.c
++++ b/drivers/md/dm-snap-persistent.c
+@@ -354,8 +354,7 @@ static int read_header(struct pstore *ps, int *new_snapshot)
+ return 0;
+
+ if (chunk_size_supplied)
+- DMWARN("chunk size %u in device metadata overrides "
+- "table chunk size of %u.",
++ DMWARN("chunk size %u in device metadata overrides table chunk size of %u.",
+ chunk_size, ps->store->chunk_size);
+
+ /* We had a bogus chunk_size. Fix stuff up. */
+@@ -958,8 +957,7 @@ int dm_persistent_snapshot_init(void)
+
+ r = dm_exception_store_type_register(&_persistent_compat_type);
+ if (r) {
+- DMERR("Unable to register old-style persistent exception "
+- "store type");
++ DMERR("Unable to register old-style persistent exception store type");
+ dm_exception_store_type_unregister(&_persistent_type);
+ return r;
+ }
+diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c
+index d83a0565bd101..11de107f5f462 100644
+--- a/drivers/md/dm-snap-transient.c
++++ b/drivers/md/dm-snap-transient.c
+@@ -140,8 +140,7 @@ int dm_transient_snapshot_init(void)
+
+ r = dm_exception_store_type_register(&_transient_compat_type);
+ if (r) {
+- DMWARN("Unable to register old-style transient "
+- "exception store type");
++ DMWARN("Unable to register old-style transient exception store type");
+ dm_exception_store_type_unregister(&_transient_type);
+ return r;
+ }
+diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
+index cb80d03b37370..b748901a4fb55 100644
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -490,8 +490,7 @@ static int __validate_exception_handover(struct dm_snapshot *snap)
+ if ((__find_snapshots_sharing_cow(snap, &snap_src, &snap_dest,
+ &snap_merge) == 2) ||
+ snap_dest) {
+- snap->ti->error = "Snapshot cow pairing for exception "
+- "table handover failed";
++ snap->ti->error = "Snapshot cow pairing for exception table handover failed";
+ return -EINVAL;
+ }
+
+@@ -518,8 +517,7 @@ static int __validate_exception_handover(struct dm_snapshot *snap)
+
+ if (!snap_src->store->type->prepare_merge ||
+ !snap_src->store->type->commit_merge) {
+- snap->ti->error = "Snapshot exception store does not "
+- "support snapshot-merge.";
++ snap->ti->error = "Snapshot exception store does not support snapshot-merge.";
+ return -EINVAL;
+ }
+
+@@ -937,8 +935,7 @@ static int __remove_single_exception_chunk(struct dm_snapshot *s,
+
+ e = dm_lookup_exception(&s->complete, old_chunk);
+ if (!e) {
+- DMERR("Corruption detected: exception for block %llu is "
+- "on disk but not in memory",
++ DMERR("Corruption detected: exception for block %llu is on disk but not in memory",
+ (unsigned long long)old_chunk);
+ return -EINVAL;
+ }
+@@ -965,8 +962,7 @@ static int __remove_single_exception_chunk(struct dm_snapshot *s,
+ e->new_chunk++;
+ } else if (old_chunk != e->old_chunk +
+ dm_consecutive_chunk_count(e)) {
+- DMERR("Attempt to merge block %llu from the "
+- "middle of a chunk range [%llu - %llu]",
++ DMERR("Attempt to merge block %llu from the middle of a chunk range [%llu - %llu]",
+ (unsigned long long)old_chunk,
+ (unsigned long long)e->old_chunk,
+ (unsigned long long)
+@@ -1059,8 +1055,7 @@ static void snapshot_merge_next_chunks(struct dm_snapshot *s)
+ &new_chunk);
+ if (linear_chunks <= 0) {
+ if (linear_chunks < 0) {
+- DMERR("Read error in exception store: "
+- "shutting down merge");
++ DMERR("Read error in exception store: shutting down merge");
+ down_write(&s->lock);
+ s->merge_failed = true;
+ up_write(&s->lock);
+@@ -2208,12 +2203,10 @@ static int snapshot_preresume(struct dm_target *ti)
+ if (snap_src && snap_dest) {
+ down_read(&snap_src->lock);
+ if (s == snap_src) {
+- DMERR("Unable to resume snapshot source until "
+- "handover completes.");
++ DMERR("Unable to resume snapshot source until handover completes.");
+ r = -EINVAL;
+ } else if (!dm_suspended(snap_src->ti)) {
+- DMERR("Unable to perform snapshot handover until "
+- "source is suspended.");
++ DMERR("Unable to perform snapshot handover until source is suspended.");
+ r = -EINVAL;
+ }
+ up_read(&snap_src->lock);
+diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
+index a81ed080730a7..547aefe85c076 100644
+--- a/drivers/md/dm-stripe.c
++++ b/drivers/md/dm-stripe.c
+@@ -108,15 +108,13 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+
+ width = ti->len;
+ if (sector_div(width, stripes)) {
+- ti->error = "Target length not divisible by "
+- "number of stripes";
++ ti->error = "Target length not divisible by number of stripes";
+ return -EINVAL;
+ }
+
+ tmp_len = width;
+ if (sector_div(tmp_len, chunk_size)) {
+- ti->error = "Target length not divisible by "
+- "chunk size";
++ ti->error = "Target length not divisible by chunk size";
+ return -EINVAL;
+ }
+
+@@ -124,15 +122,13 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ * Do we have enough arguments for that many stripes ?
+ */
+ if (argc != (2 + 2 * stripes)) {
+- ti->error = "Not enough destinations "
+- "specified";
++ ti->error = "Not enough destinations specified";
+ return -EINVAL;
+ }
+
+ sc = kmalloc(struct_size(sc, stripe, stripes), GFP_KERNEL);
+ if (!sc) {
+- ti->error = "Memory allocation for striped context "
+- "failed";
++ ti->error = "Memory allocation for striped context failed";
+ return -ENOMEM;
+ }
+
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index 337e667323c4a..288f600ee56dc 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -234,8 +234,7 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
+ return 0;
+
+ if ((start >= dev_size) || (start + len > dev_size)) {
+- DMERR("%s: %pg too small for target: "
+- "start=%llu, len=%llu, dev_size=%llu",
++ DMERR("%s: %pg too small for target: start=%llu, len=%llu, dev_size=%llu",
+ dm_device_name(ti->table->md), bdev,
+ (unsigned long long)start,
+ (unsigned long long)len,
+@@ -280,8 +279,7 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
+ return 0;
+
+ if (start & (logical_block_size_sectors - 1)) {
+- DMERR("%s: start=%llu not aligned to h/w "
+- "logical block size %u of %pg",
++ DMERR("%s: start=%llu not aligned to h/w logical block size %u of %pg",
+ dm_device_name(ti->table->md),
+ (unsigned long long)start,
+ limits->logical_block_size, bdev);
+@@ -289,8 +287,7 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
+ }
+
+ if (len & (logical_block_size_sectors - 1)) {
+- DMERR("%s: len=%llu not aligned to h/w "
+- "logical block size %u of %pg",
++ DMERR("%s: len=%llu not aligned to h/w logical block size %u of %pg",
+ dm_device_name(ti->table->md),
+ (unsigned long long)len,
+ limits->logical_block_size, bdev);
+@@ -880,8 +877,7 @@ static int dm_table_determine_type(struct dm_table *t)
+ bio_based = 1;
+
+ if (bio_based && request_based) {
+- DMERR("Inconsistent table: different target types"
+- " can't be mixed up");
++ DMERR("Inconsistent table: different target types can't be mixed up");
+ return -EINVAL;
+ }
+ }
+@@ -1184,8 +1180,7 @@ static int dm_table_register_integrity(struct dm_table *t)
+ * profile the new profile should not conflict.
+ */
+ if (blk_integrity_compare(dm_disk(md), template_disk) < 0) {
+- DMERR("%s: conflict with existing integrity profile: "
+- "%s profile mismatch",
++ DMERR("%s: conflict with existing integrity profile: %s profile mismatch",
+ dm_device_name(t->md),
+ template_disk->disk_name);
+ return 1;
+@@ -1698,8 +1693,7 @@ int dm_calculate_queue_limits(struct dm_table *t,
+ * for the table.
+ */
+ if (blk_stack_limits(limits, &ti_limits, 0) < 0)
+- DMWARN("%s: adding target device "
+- "(start sect %llu len %llu) "
++ DMWARN("%s: adding target device (start sect %llu len %llu) "
+ "caused an alignment inconsistency",
+ dm_device_name(t->md),
+ (unsigned long long) ti->begin,
+diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
+index 59eb1cb7037a0..4a0e15109997b 100644
+--- a/drivers/md/dm-thin-metadata.c
++++ b/drivers/md/dm-thin-metadata.c
+@@ -265,15 +265,15 @@ static int sb_check(struct dm_block_validator *v,
+ __le32 csum_le;
+
+ if (dm_block_location(b) != le64_to_cpu(disk_super->blocknr)) {
+- DMERR("sb_check failed: blocknr %llu: "
+- "wanted %llu", le64_to_cpu(disk_super->blocknr),
++ DMERR("sb_check failed: blocknr %llu: wanted %llu",
++ le64_to_cpu(disk_super->blocknr),
+ (unsigned long long)dm_block_location(b));
+ return -ENOTBLK;
+ }
+
+ if (le64_to_cpu(disk_super->magic) != THIN_SUPERBLOCK_MAGIC) {
+- DMERR("sb_check failed: magic %llu: "
+- "wanted %llu", le64_to_cpu(disk_super->magic),
++ DMERR("sb_check failed: magic %llu: wanted %llu",
++ le64_to_cpu(disk_super->magic),
+ (unsigned long long)THIN_SUPERBLOCK_MAGIC);
+ return -EILSEQ;
+ }
+diff --git a/drivers/md/dm-zoned-metadata.c b/drivers/md/dm-zoned-metadata.c
+index 13070c25adc3d..0548b5d925f74 100644
+--- a/drivers/md/dm-zoned-metadata.c
++++ b/drivers/md/dm-zoned-metadata.c
+@@ -1014,10 +1014,8 @@ static int dmz_check_sb(struct dmz_metadata *zmd, struct dmz_sb *dsb,
+
+ sb_block = le64_to_cpu(sb->sb_block);
+ if (sb_block != (u64)dsb->zone->id << zmd->zone_nr_blocks_shift) {
+- dmz_dev_err(dev, "Invalid superblock position "
+- "(is %llu expected %llu)",
+- sb_block,
+- (u64)dsb->zone->id << zmd->zone_nr_blocks_shift);
++ dmz_dev_err(dev, "Invalid superblock position (is %llu expected %llu)",
++ sb_block, (u64)dsb->zone->id << zmd->zone_nr_blocks_shift);
+ return -EINVAL;
+ }
+ if (zmd->sb_version > 1) {
+@@ -1030,16 +1028,14 @@ static int dmz_check_sb(struct dmz_metadata *zmd, struct dmz_sb *dsb,
+ } else if (uuid_is_null(&zmd->uuid)) {
+ uuid_copy(&zmd->uuid, &sb_uuid);
+ } else if (!uuid_equal(&zmd->uuid, &sb_uuid)) {
+- dmz_dev_err(dev, "mismatching DM-Zoned uuid, "
+- "is %pUl expected %pUl",
++ dmz_dev_err(dev, "mismatching DM-Zoned uuid, is %pUl expected %pUl",
+ &sb_uuid, &zmd->uuid);
+ return -ENXIO;
+ }
+ if (!strlen(zmd->label))
+ memcpy(zmd->label, sb->dmz_label, BDEVNAME_SIZE);
+ else if (memcmp(zmd->label, sb->dmz_label, BDEVNAME_SIZE)) {
+- dmz_dev_err(dev, "mismatching DM-Zoned label, "
+- "is %s expected %s",
++ dmz_dev_err(dev, "mismatching DM-Zoned label, is %s expected %s",
+ sb->dmz_label, zmd->label);
+ return -ENXIO;
+ }
+--
+2.39.2
+
--- /dev/null
+From c48635352f2ae2859fa3de2e494ecfa079af65cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Jan 2023 21:43:57 +0100
+Subject: dm: fix undue/missing spaces
+
+From: Heinz Mauelshagen <heinzm@redhat.com>
+
+[ Upstream commit 43be9c743c2553519c2093d1798b542f28095a51 ]
+
+Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Stable-dep-of: 249bed821b4d ("dm ioctl: Avoid double-fetch of version")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-ioctl.c | 4 ++--
+ drivers/md/dm-mpath.c | 2 +-
+ drivers/md/dm-ps-service-time.c | 3 +--
+ drivers/md/dm-snap.c | 6 +++---
+ drivers/md/dm-table.c | 2 +-
+ drivers/md/dm-uevent.h | 2 +-
+ drivers/md/dm-writecache.c | 4 ++--
+ drivers/md/dm-zoned-metadata.c | 2 +-
+ 8 files changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 6ae1c19b82433..9fc4a5d51b3fc 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -1572,7 +1572,7 @@ static void retrieve_deps(struct dm_table *table,
+ /*
+ * Count the devices.
+ */
+- list_for_each (tmp, dm_table_get_devices(table))
++ list_for_each(tmp, dm_table_get_devices(table))
+ count++;
+
+ /*
+@@ -1589,7 +1589,7 @@ static void retrieve_deps(struct dm_table *table,
+ */
+ deps->count = count;
+ count = 0;
+- list_for_each_entry (dd, dm_table_get_devices(table), list)
++ list_for_each_entry(dd, dm_table_get_devices(table), list)
+ deps->dev[count++] = huge_encode_dev(dd->dm_dev->bdev->bd_dev);
+
+ param->data_size = param->data_start + needed;
+diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
+index 91c25ad8eed84..66032ab3c4e92 100644
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -1086,7 +1086,7 @@ static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m)
+ goto fail;
+ }
+ j = sprintf(p, "%d", hw_argc - 1);
+- for (i = 0, p+=j+1; i <= hw_argc - 2; i++, p+=j+1)
++ for (i = 0, p += j + 1; i <= hw_argc - 2; i++, p += j + 1)
+ j = sprintf(p, "%s", as->argv[i]);
+ }
+ dm_consume_args(as, hw_argc - 1);
+diff --git a/drivers/md/dm-ps-service-time.c b/drivers/md/dm-ps-service-time.c
+index 84d26234dc053..eba2293be6864 100644
+--- a/drivers/md/dm-ps-service-time.c
++++ b/drivers/md/dm-ps-service-time.c
+@@ -127,8 +127,7 @@ static int st_add_path(struct path_selector *ps, struct dm_path *path,
+ * The valid range: 0-<ST_MAX_RELATIVE_THROUGHPUT>
+ * If not given, minimum value '1' is used.
+ * If '0' is given, the path isn't selected while
+- * other paths having a positive value are
+- * available.
++ * other paths having a positive value are available.
+ */
+ if (argc > 2) {
+ *error = "service-time ps: incorrect number of arguments";
+diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
+index c64d987c544d7..cb80d03b37370 100644
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -388,7 +388,7 @@ static struct origin *__lookup_origin(struct block_device *origin)
+ struct origin *o;
+
+ ol = &_origins[origin_hash(origin)];
+- list_for_each_entry (o, ol, hash_list)
++ list_for_each_entry(o, ol, hash_list)
+ if (bdev_equal(o->bdev, origin))
+ return o;
+
+@@ -407,7 +407,7 @@ static struct dm_origin *__lookup_dm_origin(struct block_device *origin)
+ struct dm_origin *o;
+
+ ol = &_dm_origins[origin_hash(origin)];
+- list_for_each_entry (o, ol, hash_list)
++ list_for_each_entry(o, ol, hash_list)
+ if (bdev_equal(o->dev->bdev, origin))
+ return o;
+
+@@ -2446,7 +2446,7 @@ static int __origin_write(struct list_head *snapshots, sector_t sector,
+ chunk_t chunk;
+
+ /* Do all the snapshots on this origin */
+- list_for_each_entry (snap, snapshots, list) {
++ list_for_each_entry(snap, snapshots, list) {
+ /*
+ * Don't make new exceptions in a merging snapshot
+ * because it has effectively been deleted
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index 3acded2f976db..337e667323c4a 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -211,7 +211,7 @@ static struct dm_dev_internal *find_device(struct list_head *l, dev_t dev)
+ {
+ struct dm_dev_internal *dd;
+
+- list_for_each_entry (dd, l, list)
++ list_for_each_entry(dd, l, list)
+ if (dd->dm_dev->bdev->bd_dev == dev)
+ return dd;
+
+diff --git a/drivers/md/dm-uevent.h b/drivers/md/dm-uevent.h
+index 2c9ba561fd8e9..12a5d4fb7d441 100644
+--- a/drivers/md/dm-uevent.h
++++ b/drivers/md/dm-uevent.h
+@@ -3,7 +3,7 @@
+ * Device Mapper Uevent Support
+ *
+ * Copyright IBM Corporation, 2007
+- * Author: Mike Anderson <andmike@linux.vnet.ibm.com>
++ * Author: Mike Anderson <andmike@linux.vnet.ibm.com>
+ */
+ #ifndef DM_UEVENT_H
+ #define DM_UEVENT_H
+diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
+index 431c84595ddb7..c6ff43a8f0b25 100644
+--- a/drivers/md/dm-writecache.c
++++ b/drivers/md/dm-writecache.c
+@@ -85,12 +85,12 @@ struct wc_entry {
+ unsigned short wc_list_contiguous;
+ bool write_in_progress
+ #if BITS_PER_LONG == 64
+- :1
++ : 1
+ #endif
+ ;
+ unsigned long index
+ #if BITS_PER_LONG == 64
+- :47
++ : 47
+ #endif
+ ;
+ unsigned long age;
+diff --git a/drivers/md/dm-zoned-metadata.c b/drivers/md/dm-zoned-metadata.c
+index c795ea7da7917..13070c25adc3d 100644
+--- a/drivers/md/dm-zoned-metadata.c
++++ b/drivers/md/dm-zoned-metadata.c
+@@ -1013,7 +1013,7 @@ static int dmz_check_sb(struct dmz_metadata *zmd, struct dmz_sb *dsb,
+ }
+
+ sb_block = le64_to_cpu(sb->sb_block);
+- if (sb_block != (u64)dsb->zone->id << zmd->zone_nr_blocks_shift ) {
++ if (sb_block != (u64)dsb->zone->id << zmd->zone_nr_blocks_shift) {
+ dmz_dev_err(dev, "Invalid superblock position "
+ "(is %llu expected %llu)",
+ sb_block,
+--
+2.39.2
+
--- /dev/null
+From edad1af6376d882614441fb3632a88a31e49a527 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Jun 2023 10:52:42 -0400
+Subject: dm ioctl: Avoid double-fetch of version
+
+From: Demi Marie Obenour <demi@invisiblethingslab.com>
+
+[ Upstream commit 249bed821b4db6d95a99160f7d6d236ea5fe6362 ]
+
+The version is fetched once in check_version(), which then does some
+validation and then overwrites the version in userspace with the API
+version supported by the kernel. copy_params() then fetches the version
+from userspace *again*, and this time no validation is done. The result
+is that the kernel's version number is completely controllable by
+userspace, provided that userspace can win a race condition.
+
+Fix this flaw by not copying the version back to the kernel the second
+time. This is not exploitable as the version is not further used in the
+kernel. However, it could become a problem if future patches start
+relying on the version field.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Demi Marie Obenour <demi@invisiblethingslab.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-ioctl.c | 33 +++++++++++++++++++++------------
+ 1 file changed, 21 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 6aeae095086d7..2afd2d2a0f407 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -1811,30 +1811,36 @@ static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags)
+ * As well as checking the version compatibility this always
+ * copies the kernel interface version out.
+ */
+-static int check_version(unsigned int cmd, struct dm_ioctl __user *user)
++static int check_version(unsigned int cmd, struct dm_ioctl __user *user,
++ struct dm_ioctl *kernel_params)
+ {
+- uint32_t version[3];
+ int r = 0;
+
+- if (copy_from_user(version, user->version, sizeof(version)))
++ /* Make certain version is first member of dm_ioctl struct */
++ BUILD_BUG_ON(offsetof(struct dm_ioctl, version) != 0);
++
++ if (copy_from_user(kernel_params->version, user->version, sizeof(kernel_params->version)))
+ return -EFAULT;
+
+- if ((version[0] != DM_VERSION_MAJOR) ||
+- (version[1] > DM_VERSION_MINOR)) {
++ if ((kernel_params->version[0] != DM_VERSION_MAJOR) ||
++ (kernel_params->version[1] > DM_VERSION_MINOR)) {
+ DMERR("ioctl interface mismatch: kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)",
+ DM_VERSION_MAJOR, DM_VERSION_MINOR,
+ DM_VERSION_PATCHLEVEL,
+- version[0], version[1], version[2], cmd);
++ kernel_params->version[0],
++ kernel_params->version[1],
++ kernel_params->version[2],
++ cmd);
+ r = -EINVAL;
+ }
+
+ /*
+ * Fill in the kernel version.
+ */
+- version[0] = DM_VERSION_MAJOR;
+- version[1] = DM_VERSION_MINOR;
+- version[2] = DM_VERSION_PATCHLEVEL;
+- if (copy_to_user(user->version, version, sizeof(version)))
++ kernel_params->version[0] = DM_VERSION_MAJOR;
++ kernel_params->version[1] = DM_VERSION_MINOR;
++ kernel_params->version[2] = DM_VERSION_PATCHLEVEL;
++ if (copy_to_user(user->version, kernel_params->version, sizeof(kernel_params->version)))
+ return -EFAULT;
+
+ return r;
+@@ -1860,7 +1866,10 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern
+ const size_t minimum_data_size = offsetof(struct dm_ioctl, data);
+ unsigned int noio_flag;
+
+- if (copy_from_user(param_kernel, user, minimum_data_size))
++ /* check_version() already copied version from userspace, avoid TOCTOU */
++ if (copy_from_user((char *)param_kernel + sizeof(param_kernel->version),
++ (char __user *)user + sizeof(param_kernel->version),
++ minimum_data_size - sizeof(param_kernel->version)))
+ return -EFAULT;
+
+ if (param_kernel->data_size < minimum_data_size) {
+@@ -1972,7 +1981,7 @@ static int ctl_ioctl(struct file *file, uint command, struct dm_ioctl __user *us
+ * Check the interface version passed in. This also
+ * writes out the kernel's interface version.
+ */
+- r = check_version(cmd, user);
++ r = check_version(cmd, user, ¶m_kernel);
+ if (r)
+ return r;
+
+--
+2.39.2
+
--- /dev/null
+From 052a2a7fb71535990d598215ed59df6f3f877b93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Feb 2023 21:47:45 +0100
+Subject: dm ioctl: have constant on the right side of the test
+
+From: Heinz Mauelshagen <heinzm@redhat.com>
+
+[ Upstream commit 5cae0aa77397015f530aeb34f3ced32db6ac2875 ]
+
+Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Stable-dep-of: 249bed821b4d ("dm ioctl: Avoid double-fetch of version")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-ioctl.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 2ced382cdd70b..6aeae095086d7 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -1819,8 +1819,8 @@ static int check_version(unsigned int cmd, struct dm_ioctl __user *user)
+ if (copy_from_user(version, user->version, sizeof(version)))
+ return -EFAULT;
+
+- if ((DM_VERSION_MAJOR != version[0]) ||
+- (DM_VERSION_MINOR < version[1])) {
++ if ((version[0] != DM_VERSION_MAJOR) ||
++ (version[1] > DM_VERSION_MINOR)) {
+ DMERR("ioctl interface mismatch: kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)",
+ DM_VERSION_MAJOR, DM_VERSION_MINOR,
+ DM_VERSION_PATCHLEVEL,
+--
+2.39.2
+
--- /dev/null
+From 9f5bfea0b5ba2e38c84d8c8c7d95a32fb6711001 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 23:35:44 +0100
+Subject: extcon: usbc-tusb320: Convert to i2c's .probe_new()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 5313121b22fd11db0d14f305c110168b8176efdc ]
+
+The probe function doesn't make use of the i2c_device_id * parameter so it
+can be trivially converted.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Stable-dep-of: 3adbaa30d973 ("extcon: usbc-tusb320: Unregister typec port on driver removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/extcon/extcon-usbc-tusb320.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c
+index 9dfa545427ca1..b408ce989c223 100644
+--- a/drivers/extcon/extcon-usbc-tusb320.c
++++ b/drivers/extcon/extcon-usbc-tusb320.c
+@@ -428,8 +428,7 @@ static int tusb320_typec_probe(struct i2c_client *client,
+ return 0;
+ }
+
+-static int tusb320_probe(struct i2c_client *client,
+- const struct i2c_device_id *id)
++static int tusb320_probe(struct i2c_client *client)
+ {
+ struct tusb320_priv *priv;
+ const void *match_data;
+@@ -502,7 +501,7 @@ static const struct of_device_id tusb320_extcon_dt_match[] = {
+ MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match);
+
+ static struct i2c_driver tusb320_extcon_driver = {
+- .probe = tusb320_probe,
++ .probe_new = tusb320_probe,
+ .driver = {
+ .name = "extcon-tusb320",
+ .of_match_table = tusb320_extcon_dt_match,
+--
+2.39.2
+
--- /dev/null
+From 68a8b84789909bdb72515d4b9b476d1b6d90e989 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Mar 2023 15:15:47 +0100
+Subject: extcon: usbc-tusb320: Unregister typec port on driver removal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alvin Šipraga <alsi@bang-olufsen.dk>
+
+[ Upstream commit 3adbaa30d973093a4f37927baf9596cca51b593d ]
+
+The driver can register a typec port if suitable firmware properties are
+present. But if the driver is removed through sysfs unbind, rmmod or
+similar, then it does not clean up after itself and the typec port
+device remains registered. This can be seen in sysfs, where stale typec
+ports get left over in /sys/class/typec.
+
+In order to fix this we have to add an i2c_driver remove function and
+call typec_unregister_port(), which is a no-op in the case where no
+typec port is created and the pointer remains NULL.
+
+In the process we should also put the fwnode_handle when the typec port
+isn't registered anymore, including if an error occurs during probe. The
+typec subsystem does not increase or decrease the reference counter for
+us, so we track it in the driver's private data.
+
+Note that the conditional check on TYPEC_PWR_MODE_PD was removed in the
+probe path because a call to tusb320_set_adv_pwr_mode() will perform an
+even more robust validation immediately after, hence there is no
+functional change here.
+
+Fixes: bf7571c00dca ("extcon: usbc-tusb320: Add USB TYPE-C support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/extcon/extcon-usbc-tusb320.c | 42 ++++++++++++++++++++++------
+ 1 file changed, 34 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c
+index b408ce989c223..10dff1c512c41 100644
+--- a/drivers/extcon/extcon-usbc-tusb320.c
++++ b/drivers/extcon/extcon-usbc-tusb320.c
+@@ -78,6 +78,7 @@ struct tusb320_priv {
+ struct typec_capability cap;
+ enum typec_port_type port_type;
+ enum typec_pwr_opmode pwr_opmode;
++ struct fwnode_handle *connector_fwnode;
+ };
+
+ static const char * const tusb_attached_states[] = {
+@@ -391,27 +392,25 @@ static int tusb320_typec_probe(struct i2c_client *client,
+ /* Type-C connector found. */
+ ret = typec_get_fw_cap(&priv->cap, connector);
+ if (ret)
+- return ret;
++ goto err_put;
+
+ priv->port_type = priv->cap.type;
+
+ /* This goes into register 0x8 field CURRENT_MODE_ADVERTISE */
+ ret = fwnode_property_read_string(connector, "typec-power-opmode", &cap_str);
+ if (ret)
+- return ret;
++ goto err_put;
+
+ ret = typec_find_pwr_opmode(cap_str);
+ if (ret < 0)
+- return ret;
+- if (ret == TYPEC_PWR_MODE_PD)
+- return -EINVAL;
++ goto err_put;
+
+ priv->pwr_opmode = ret;
+
+ /* Initialize the hardware with the devicetree settings. */
+ ret = tusb320_set_adv_pwr_mode(priv);
+ if (ret)
+- return ret;
++ goto err_put;
+
+ priv->cap.revision = USB_TYPEC_REV_1_1;
+ priv->cap.accessory[0] = TYPEC_ACCESSORY_AUDIO;
+@@ -422,10 +421,25 @@ static int tusb320_typec_probe(struct i2c_client *client,
+ priv->cap.fwnode = connector;
+
+ priv->port = typec_register_port(&client->dev, &priv->cap);
+- if (IS_ERR(priv->port))
+- return PTR_ERR(priv->port);
++ if (IS_ERR(priv->port)) {
++ ret = PTR_ERR(priv->port);
++ goto err_put;
++ }
++
++ priv->connector_fwnode = connector;
+
+ return 0;
++
++err_put:
++ fwnode_handle_put(connector);
++
++ return ret;
++}
++
++static void tusb320_typec_remove(struct tusb320_priv *priv)
++{
++ typec_unregister_port(priv->port);
++ fwnode_handle_put(priv->connector_fwnode);
+ }
+
+ static int tusb320_probe(struct i2c_client *client)
+@@ -438,7 +452,9 @@ static int tusb320_probe(struct i2c_client *client)
+ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
++
+ priv->dev = &client->dev;
++ i2c_set_clientdata(client, priv);
+
+ priv->regmap = devm_regmap_init_i2c(client, &tusb320_regmap_config);
+ if (IS_ERR(priv->regmap))
+@@ -489,10 +505,19 @@ static int tusb320_probe(struct i2c_client *client)
+ tusb320_irq_handler,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ client->name, priv);
++ if (ret)
++ tusb320_typec_remove(priv);
+
+ return ret;
+ }
+
++static void tusb320_remove(struct i2c_client *client)
++{
++ struct tusb320_priv *priv = i2c_get_clientdata(client);
++
++ tusb320_typec_remove(priv);
++}
++
+ static const struct of_device_id tusb320_extcon_dt_match[] = {
+ { .compatible = "ti,tusb320", .data = &tusb320_ops, },
+ { .compatible = "ti,tusb320l", .data = &tusb320l_ops, },
+@@ -502,6 +527,7 @@ MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match);
+
+ static struct i2c_driver tusb320_extcon_driver = {
+ .probe_new = tusb320_probe,
++ .remove = tusb320_remove,
+ .driver = {
+ .name = "extcon-tusb320",
+ .of_match_table = tusb320_extcon_dt_match,
+--
+2.39.2
+
sh-dma-fix-dma-channel-offset-calculation.patch
apparmor-fix-missing-error-check-for-rhashtable_inse.patch
i2c-xiic-don-t-try-to-handle-more-interrupt-events-a.patch
+dm-fix-undue-missing-spaces.patch
+dm-avoid-split-of-quoted-strings-where-possible.patch
+dm-ioctl-have-constant-on-the-right-side-of-the-test.patch
+dm-ioctl-avoid-double-fetch-of-version.patch
+extcon-usbc-tusb320-convert-to-i2c-s-.probe_new.patch
+extcon-usbc-tusb320-unregister-typec-port-on-driver-.patch
+btrfs-do-not-bug_on-on-tree-mod-log-failure-at-balan.patch