From: Greg Kroah-Hartman Date: Sun, 16 Jul 2023 09:24:22 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v6.1.39~87 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=572e08834bda461b7c7f138f5028ae73a98542fa;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: bcache-remove-unnecessary-null-point-check-in-node-allocations.patch ext4-remove-ext4-locking-of-moved-directory.patch fs-avoid-empty-option-when-generating-legacy-mount-string.patch fs-establish-locking-order-for-unrelated-directories.patch fs-lock-moved-directories.patch integrity-fix-possible-multiple-allocation-in-integrity_inode_get.patch jffs2-reduce-stack-usage-in-jffs2_build_xattr_subsystem.patch mmc-core-disable-trim-on-kingston-emmc04g-m627.patch mmc-core-disable-trim-on-micron-mtfc4gacajcn-1m.patch mmc-sdhci-fix-dma-configure-compatibility-issue-when-64bit-dma-mode-is-used.patch nfsd-add-encoding-of-op_recall-flag-for-write-delegation.patch revert-f2fs-fix-potential-corruption-when-moving-a-directory.patch wifi-ath10k-serialize-wake_tx_queue-ops.patch --- diff --git a/queue-5.4/bcache-remove-unnecessary-null-point-check-in-node-allocations.patch b/queue-5.4/bcache-remove-unnecessary-null-point-check-in-node-allocations.patch new file mode 100644 index 00000000000..342fba66031 --- /dev/null +++ b/queue-5.4/bcache-remove-unnecessary-null-point-check-in-node-allocations.patch @@ -0,0 +1,92 @@ +From 028ddcac477b691dd9205c92f991cc15259d033e Mon Sep 17 00:00:00 2001 +From: Zheng Wang +Date: Thu, 15 Jun 2023 20:12:21 +0800 +Subject: bcache: Remove unnecessary NULL point check in node allocations + +From: Zheng Wang + +commit 028ddcac477b691dd9205c92f991cc15259d033e upstream. + +Due to the previous fix of __bch_btree_node_alloc, the return value will +never be a NULL pointer. So IS_ERR is enough to handle the failure +situation. Fix it by replacing IS_ERR_OR_NULL check by an IS_ERR check. + +Fixes: cafe56359144 ("bcache: A block layer cache") +Cc: stable@vger.kernel.org +Signed-off-by: Zheng Wang +Signed-off-by: Coly Li +Link: https://lore.kernel.org/r/20230615121223.22502-5-colyli@suse.de +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/bcache/btree.c | 10 +++++----- + drivers/md/bcache/super.c | 4 ++-- + 2 files changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/md/bcache/btree.c ++++ b/drivers/md/bcache/btree.c +@@ -1186,7 +1186,7 @@ static struct btree *btree_node_alloc_re + { + struct btree *n = bch_btree_node_alloc(b->c, op, b->level, b->parent); + +- if (!IS_ERR_OR_NULL(n)) { ++ if (!IS_ERR(n)) { + mutex_lock(&n->write_lock); + bch_btree_sort_into(&b->keys, &n->keys, &b->c->sort); + bkey_copy_key(&n->key, &b->key); +@@ -1389,7 +1389,7 @@ static int btree_gc_coalesce(struct btre + memset(new_nodes, 0, sizeof(new_nodes)); + closure_init_stack(&cl); + +- while (nodes < GC_MERGE_NODES && !IS_ERR_OR_NULL(r[nodes].b)) ++ while (nodes < GC_MERGE_NODES && !IS_ERR(r[nodes].b)) + keys += r[nodes++].keys; + + blocks = btree_default_blocks(b->c) * 2 / 3; +@@ -1401,7 +1401,7 @@ static int btree_gc_coalesce(struct btre + + for (i = 0; i < nodes; i++) { + new_nodes[i] = btree_node_alloc_replacement(r[i].b, NULL); +- if (IS_ERR_OR_NULL(new_nodes[i])) ++ if (IS_ERR(new_nodes[i])) + goto out_nocoalesce; + } + +@@ -1536,7 +1536,7 @@ out_nocoalesce: + bch_keylist_free(&keylist); + + for (i = 0; i < nodes; i++) +- if (!IS_ERR_OR_NULL(new_nodes[i])) { ++ if (!IS_ERR(new_nodes[i])) { + btree_node_free(new_nodes[i]); + rw_unlock(true, new_nodes[i]); + } +@@ -1718,7 +1718,7 @@ static int bch_btree_gc_root(struct btre + if (should_rewrite) { + n = btree_node_alloc_replacement(b, NULL); + +- if (!IS_ERR_OR_NULL(n)) { ++ if (!IS_ERR(n)) { + bch_btree_node_write_sync(n); + + bch_btree_set_root(n); +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -1633,7 +1633,7 @@ static void cache_set_flush(struct closu + if (!IS_ERR_OR_NULL(c->gc_thread)) + kthread_stop(c->gc_thread); + +- if (!IS_ERR_OR_NULL(c->root)) ++ if (!IS_ERR(c->root)) + list_add(&c->root->list, &c->btree_cache); + + /* +@@ -2000,7 +2000,7 @@ static int run_cache_set(struct cache_se + + err = "cannot allocate new btree root"; + c->root = __bch_btree_node_alloc(c, NULL, 0, true, NULL); +- if (IS_ERR_OR_NULL(c->root)) ++ if (IS_ERR(c->root)) + goto err; + + mutex_lock(&c->root->write_lock); diff --git a/queue-5.4/ext4-remove-ext4-locking-of-moved-directory.patch b/queue-5.4/ext4-remove-ext4-locking-of-moved-directory.patch new file mode 100644 index 00000000000..c63387664ab --- /dev/null +++ b/queue-5.4/ext4-remove-ext4-locking-of-moved-directory.patch @@ -0,0 +1,59 @@ +From 3658840cd363f2be094f5dfd2f0b174a9055dd0f Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 1 Jun 2023 12:58:21 +0200 +Subject: ext4: Remove ext4 locking of moved directory + +From: Jan Kara + +commit 3658840cd363f2be094f5dfd2f0b174a9055dd0f upstream. + +Remove locking of moved directory in ext4_rename2(). We will take care +of it in VFS instead. This effectively reverts commit 0813299c586b +("ext4: Fix possible corruption when moving a directory") and followup +fixes. + +CC: Ted Tso +CC: stable@vger.kernel.org +Signed-off-by: Jan Kara +Message-Id: <20230601105830.13168-1-jack@suse.cz> +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/namei.c | 17 ++--------------- + 1 file changed, 2 insertions(+), 15 deletions(-) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -3795,19 +3795,10 @@ static int ext4_rename(struct inode *old + return retval; + } + +- /* +- * We need to protect against old.inode directory getting converted +- * from inline directory format into a normal one. +- */ +- if (S_ISDIR(old.inode->i_mode)) +- inode_lock_nested(old.inode, I_MUTEX_NONDIR2); +- + old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, + &old.inlined); +- if (IS_ERR(old.bh)) { +- retval = PTR_ERR(old.bh); +- goto unlock_moved_dir; +- } ++ if (IS_ERR(old.bh)) ++ return PTR_ERR(old.bh); + + /* + * Check for inode number is _not_ due to possible IO errors. +@@ -3968,10 +3959,6 @@ release_bh: + brelse(old.bh); + brelse(new.bh); + +-unlock_moved_dir: +- if (S_ISDIR(old.inode->i_mode)) +- inode_unlock(old.inode); +- + return retval; + } + diff --git a/queue-5.4/fs-avoid-empty-option-when-generating-legacy-mount-string.patch b/queue-5.4/fs-avoid-empty-option-when-generating-legacy-mount-string.patch new file mode 100644 index 00000000000..1e106d6befe --- /dev/null +++ b/queue-5.4/fs-avoid-empty-option-when-generating-legacy-mount-string.patch @@ -0,0 +1,43 @@ +From 62176420274db5b5127cd7a0083a9aeb461756ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= +Date: Wed, 7 Jun 2023 19:28:48 +0200 +Subject: fs: avoid empty option when generating legacy mount string +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +commit 62176420274db5b5127cd7a0083a9aeb461756ee upstream. + +As each option string fragment is always prepended with a comma it would +happen that the whole string always starts with a comma. This could be +interpreted by filesystem drivers as an empty option and may produce +errors. + +For example the NTFS driver from ntfs.ko behaves like this and fails +when mounted via the new API. + +Link: https://github.com/util-linux/util-linux/issues/2298 +Signed-off-by: Thomas Weißschuh +Fixes: 3e1aeb00e6d1 ("vfs: Implement a filesystem superblock creation/configuration context") +Cc: stable@vger.kernel.org +Message-Id: <20230607-fs-empty-option-v1-1-20c8dbf4671b@weissschuh.net> +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/fs_context.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/fs_context.c ++++ b/fs/fs_context.c +@@ -598,7 +598,8 @@ static int legacy_parse_param(struct fs_ + return -ENOMEM; + } + +- ctx->legacy_data[size++] = ','; ++ if (size) ++ ctx->legacy_data[size++] = ','; + len = strlen(param->key); + memcpy(ctx->legacy_data + size, param->key, len); + size += len; diff --git a/queue-5.4/fs-establish-locking-order-for-unrelated-directories.patch b/queue-5.4/fs-establish-locking-order-for-unrelated-directories.patch new file mode 100644 index 00000000000..170233691c5 --- /dev/null +++ b/queue-5.4/fs-establish-locking-order-for-unrelated-directories.patch @@ -0,0 +1,104 @@ +From f23ce757185319886ca80c4864ce5f81ac6cc9e9 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 1 Jun 2023 12:58:24 +0200 +Subject: fs: Establish locking order for unrelated directories + +From: Jan Kara + +commit f23ce757185319886ca80c4864ce5f81ac6cc9e9 upstream. + +Currently the locking order of inode locks for directories that are not +in ancestor relationship is not defined because all operations that +needed to lock two directories like this were serialized by +sb->s_vfs_rename_mutex. However some filesystems need to lock two +subdirectories for RENAME_EXCHANGE operations and for this we need the +locking order established even for two tree-unrelated directories. +Provide a helper function lock_two_inodes() that establishes lock +ordering for any two inodes and use it in lock_two_directories(). + +CC: stable@vger.kernel.org +Signed-off-by: Jan Kara +Message-Id: <20230601105830.13168-4-jack@suse.cz> +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/inode.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + fs/internal.h | 2 ++ + fs/namei.c | 4 ++-- + 3 files changed, 46 insertions(+), 2 deletions(-) + +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -1013,6 +1013,48 @@ void discard_new_inode(struct inode *ino + EXPORT_SYMBOL(discard_new_inode); + + /** ++ * lock_two_inodes - lock two inodes (may be regular files but also dirs) ++ * ++ * Lock any non-NULL argument. The caller must make sure that if he is passing ++ * in two directories, one is not ancestor of the other. Zero, one or two ++ * objects may be locked by this function. ++ * ++ * @inode1: first inode to lock ++ * @inode2: second inode to lock ++ * @subclass1: inode lock subclass for the first lock obtained ++ * @subclass2: inode lock subclass for the second lock obtained ++ */ ++void lock_two_inodes(struct inode *inode1, struct inode *inode2, ++ unsigned subclass1, unsigned subclass2) ++{ ++ if (!inode1 || !inode2) { ++ /* ++ * Make sure @subclass1 will be used for the acquired lock. ++ * This is not strictly necessary (no current caller cares) but ++ * let's keep things consistent. ++ */ ++ if (!inode1) ++ swap(inode1, inode2); ++ goto lock; ++ } ++ ++ /* ++ * If one object is directory and the other is not, we must make sure ++ * to lock directory first as the other object may be its child. ++ */ ++ if (S_ISDIR(inode2->i_mode) == S_ISDIR(inode1->i_mode)) { ++ if (inode1 > inode2) ++ swap(inode1, inode2); ++ } else if (!S_ISDIR(inode1->i_mode)) ++ swap(inode1, inode2); ++lock: ++ if (inode1) ++ inode_lock_nested(inode1, subclass1); ++ if (inode2 && inode2 != inode1) ++ inode_lock_nested(inode2, subclass2); ++} ++ ++/** + * lock_two_nondirectories - take two i_mutexes on non-directory objects + * + * Lock any non-NULL argument that is not a directory. +--- a/fs/internal.h ++++ b/fs/internal.h +@@ -138,6 +138,8 @@ extern int vfs_open(const struct path *, + extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc); + extern void inode_add_lru(struct inode *inode); + extern int dentry_needs_remove_privs(struct dentry *dentry); ++void lock_two_inodes(struct inode *inode1, struct inode *inode2, ++ unsigned subclass1, unsigned subclass2); + + /* + * fs-writeback.c +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -2870,8 +2870,8 @@ struct dentry *lock_rename(struct dentry + return p; + } + +- inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); +- inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2); ++ lock_two_inodes(p1->d_inode, p2->d_inode, ++ I_MUTEX_PARENT, I_MUTEX_PARENT2); + return NULL; + } + EXPORT_SYMBOL(lock_rename); diff --git a/queue-5.4/fs-lock-moved-directories.patch b/queue-5.4/fs-lock-moved-directories.patch new file mode 100644 index 00000000000..4e5219a3e37 --- /dev/null +++ b/queue-5.4/fs-lock-moved-directories.patch @@ -0,0 +1,126 @@ +From 28eceeda130f5058074dd007d9c59d2e8bc5af2e Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 1 Jun 2023 12:58:25 +0200 +Subject: fs: Lock moved directories + +From: Jan Kara + +commit 28eceeda130f5058074dd007d9c59d2e8bc5af2e upstream. + +When a directory is moved to a different directory, some filesystems +(udf, ext4, ocfs2, f2fs, and likely gfs2, reiserfs, and others) need to +update their pointer to the parent and this must not race with other +operations on the directory. Lock the directories when they are moved. +Although not all filesystems need this locking, we perform it in +vfs_rename() because getting the lock ordering right is really difficult +and we don't want to expose these locking details to filesystems. + +CC: stable@vger.kernel.org +Signed-off-by: Jan Kara +Message-Id: <20230601105830.13168-5-jack@suse.cz> +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/filesystems/directory-locking.rst | 26 ++++++++++++------------ + fs/namei.c | 22 ++++++++++++-------- + 2 files changed, 28 insertions(+), 20 deletions(-) + +--- a/Documentation/filesystems/directory-locking.rst ++++ b/Documentation/filesystems/directory-locking.rst +@@ -22,12 +22,11 @@ exclusive. + 3) object removal. Locking rules: caller locks parent, finds victim, + locks victim and calls the method. Locks are exclusive. + +-4) rename() that is _not_ cross-directory. Locking rules: caller locks +-the parent and finds source and target. In case of exchange (with +-RENAME_EXCHANGE in flags argument) lock both. In any case, +-if the target already exists, lock it. If the source is a non-directory, +-lock it. If we need to lock both, lock them in inode pointer order. +-Then call the method. All locks are exclusive. ++4) rename() that is _not_ cross-directory. Locking rules: caller locks the ++parent and finds source and target. We lock both (provided they exist). If we ++need to lock two inodes of different type (dir vs non-dir), we lock directory ++first. If we need to lock two inodes of the same type, lock them in inode ++pointer order. Then call the method. All locks are exclusive. + NB: we might get away with locking the the source (and target in exchange + case) shared. + +@@ -44,15 +43,17 @@ All locks are exclusive. + rules: + + * lock the filesystem +- * lock parents in "ancestors first" order. ++ * lock parents in "ancestors first" order. If one is not ancestor of ++ the other, lock them in inode pointer order. + * find source and target. + * if old parent is equal to or is a descendent of target + fail with -ENOTEMPTY + * if new parent is equal to or is a descendent of source + fail with -ELOOP +- * If it's an exchange, lock both the source and the target. +- * If the target exists, lock it. If the source is a non-directory, +- lock it. If we need to lock both, do so in inode pointer order. ++ * Lock both the source and the target provided they exist. If we ++ need to lock two inodes of different type (dir vs non-dir), we lock ++ the directory first. If we need to lock two inodes of the same type, ++ lock them in inode pointer order. + * call the method. + + All ->i_rwsem are taken exclusive. Again, we might get away with locking +@@ -66,8 +67,9 @@ If no directory is its own ancestor, the + + Proof: + +- First of all, at any moment we have a partial ordering of the +- objects - A < B iff A is an ancestor of B. ++ First of all, at any moment we have a linear ordering of the ++ objects - A < B iff (A is an ancestor of B) or (B is not an ancestor ++ of A and ptr(A) < ptr(B)). + + That ordering can change. However, the following is true: + +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -4367,7 +4367,7 @@ SYSCALL_DEFINE2(link, const char __user + * sb->s_vfs_rename_mutex. We might be more accurate, but that's another + * story. + * c) we have to lock _four_ objects - parents and victim (if it exists), +- * and source (if it is not a directory). ++ * and source. + * And that - after we got ->i_mutex on parents (until then we don't know + * whether the target exists). Solution: try to be smart with locking + * order for inodes. We rely on the fact that tree topology may change +@@ -4444,10 +4444,16 @@ int vfs_rename(struct inode *old_dir, st + + take_dentry_name_snapshot(&old_name, old_dentry); + dget(new_dentry); +- if (!is_dir || (flags & RENAME_EXCHANGE)) +- lock_two_nondirectories(source, target); +- else if (target) +- inode_lock(target); ++ /* ++ * Lock all moved children. Moved directories may need to change parent ++ * pointer so they need the lock to prevent against concurrent ++ * directory changes moving parent pointer. For regular files we've ++ * historically always done this. The lockdep locking subclasses are ++ * somewhat arbitrary but RENAME_EXCHANGE in particular can swap ++ * regular files and directories so it's difficult to tell which ++ * subclasses to use. ++ */ ++ lock_two_inodes(source, target, I_MUTEX_NORMAL, I_MUTEX_NONDIR2); + + error = -EBUSY; + if (is_local_mountpoint(old_dentry) || is_local_mountpoint(new_dentry)) +@@ -4491,9 +4497,9 @@ int vfs_rename(struct inode *old_dir, st + d_exchange(old_dentry, new_dentry); + } + out: +- if (!is_dir || (flags & RENAME_EXCHANGE)) +- unlock_two_nondirectories(source, target); +- else if (target) ++ if (source) ++ inode_unlock(source); ++ if (target) + inode_unlock(target); + dput(new_dentry); + if (!error) { diff --git a/queue-5.4/integrity-fix-possible-multiple-allocation-in-integrity_inode_get.patch b/queue-5.4/integrity-fix-possible-multiple-allocation-in-integrity_inode_get.patch new file mode 100644 index 00000000000..5c5d648e351 --- /dev/null +++ b/queue-5.4/integrity-fix-possible-multiple-allocation-in-integrity_inode_get.patch @@ -0,0 +1,62 @@ +From 9df6a4870dc371136e90330cfbbc51464ee66993 Mon Sep 17 00:00:00 2001 +From: Tianjia Zhang +Date: Thu, 1 Jun 2023 14:42:44 +0800 +Subject: integrity: Fix possible multiple allocation in integrity_inode_get() + +From: Tianjia Zhang + +commit 9df6a4870dc371136e90330cfbbc51464ee66993 upstream. + +When integrity_inode_get() is querying and inserting the cache, there +is a conditional race in the concurrent environment. + +The race condition is the result of not properly implementing +"double-checked locking". In this case, it first checks to see if the +iint cache record exists before taking the lock, but doesn't check +again after taking the integrity_iint_lock. + +Fixes: bf2276d10ce5 ("ima: allocating iint improvements") +Signed-off-by: Tianjia Zhang +Cc: Dmitry Kasatkin +Cc: # v3.10+ +Signed-off-by: Mimi Zohar +Signed-off-by: Greg Kroah-Hartman +--- + security/integrity/iint.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/security/integrity/iint.c ++++ b/security/integrity/iint.c +@@ -43,12 +43,10 @@ static struct integrity_iint_cache *__in + else if (inode > iint->inode) + n = n->rb_right; + else +- break; ++ return iint; + } +- if (!n) +- return NULL; + +- return iint; ++ return NULL; + } + + /* +@@ -121,10 +119,15 @@ struct integrity_iint_cache *integrity_i + parent = *p; + test_iint = rb_entry(parent, struct integrity_iint_cache, + rb_node); +- if (inode < test_iint->inode) ++ if (inode < test_iint->inode) { + p = &(*p)->rb_left; +- else ++ } else if (inode > test_iint->inode) { + p = &(*p)->rb_right; ++ } else { ++ write_unlock(&integrity_iint_lock); ++ kmem_cache_free(iint_cache, iint); ++ return test_iint; ++ } + } + + iint->inode = inode; diff --git a/queue-5.4/jffs2-reduce-stack-usage-in-jffs2_build_xattr_subsystem.patch b/queue-5.4/jffs2-reduce-stack-usage-in-jffs2_build_xattr_subsystem.patch new file mode 100644 index 00000000000..7ffa2036cfa --- /dev/null +++ b/queue-5.4/jffs2-reduce-stack-usage-in-jffs2_build_xattr_subsystem.patch @@ -0,0 +1,128 @@ +From 1168f095417643f663caa341211e117db552989f Mon Sep 17 00:00:00 2001 +From: Fabian Frederick +Date: Sat, 6 May 2023 06:56:12 +0200 +Subject: jffs2: reduce stack usage in jffs2_build_xattr_subsystem() + +From: Fabian Frederick + +commit 1168f095417643f663caa341211e117db552989f upstream. + +Use kcalloc() for allocation/flush of 128 pointers table to +reduce stack usage. + +Function now returns -ENOMEM or 0 on success. + +stackusage +Before: +./fs/jffs2/xattr.c:775 jffs2_build_xattr_subsystem 1208 +dynamic,bounded + +After: +./fs/jffs2/xattr.c:775 jffs2_build_xattr_subsystem 192 +dynamic,bounded + +Also update definition when CONFIG_JFFS2_FS_XATTR is not enabled + +Tested with an MTD mount point and some user set/getfattr. + +Many current target on OpenWRT also suffer from a compilation warning +(that become an error with CONFIG_WERROR) with the following output: + +fs/jffs2/xattr.c: In function 'jffs2_build_xattr_subsystem': +fs/jffs2/xattr.c:887:1: error: the frame size of 1088 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] + 887 | } + | ^ + +Using dynamic allocation fix this compilation warning. + +Fixes: c9f700f840bd ("[JFFS2][XATTR] using 'delete marker' for xdatum/xref deletion") +Reported-by: Tim Gardner +Reported-by: kernel test robot +Reported-by: Ron Economos +Reported-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Signed-off-by: Fabian Frederick +Signed-off-by: Christian Marangi +Cc: stable@vger.kernel.org +Message-Id: <20230506045612.16616-1-ansuelsmth@gmail.com> +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/jffs2/build.c | 5 ++++- + fs/jffs2/xattr.c | 13 +++++++++---- + fs/jffs2/xattr.h | 4 ++-- + 3 files changed, 15 insertions(+), 7 deletions(-) + +--- a/fs/jffs2/build.c ++++ b/fs/jffs2/build.c +@@ -211,7 +211,10 @@ static int jffs2_build_filesystem(struct + ic->scan_dents = NULL; + cond_resched(); + } +- jffs2_build_xattr_subsystem(c); ++ ret = jffs2_build_xattr_subsystem(c); ++ if (ret) ++ goto exit; ++ + c->flags &= ~JFFS2_SB_FLAG_BUILDING; + + dbg_fsbuild("FS build complete\n"); +--- a/fs/jffs2/xattr.c ++++ b/fs/jffs2/xattr.c +@@ -772,10 +772,10 @@ void jffs2_clear_xattr_subsystem(struct + } + + #define XREF_TMPHASH_SIZE (128) +-void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) ++int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) + { + struct jffs2_xattr_ref *ref, *_ref; +- struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE]; ++ struct jffs2_xattr_ref **xref_tmphash; + struct jffs2_xattr_datum *xd, *_xd; + struct jffs2_inode_cache *ic; + struct jffs2_raw_node_ref *raw; +@@ -784,9 +784,12 @@ void jffs2_build_xattr_subsystem(struct + + BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING)); + ++ xref_tmphash = kcalloc(XREF_TMPHASH_SIZE, ++ sizeof(struct jffs2_xattr_ref *), GFP_KERNEL); ++ if (!xref_tmphash) ++ return -ENOMEM; ++ + /* Phase.1 : Merge same xref */ +- for (i=0; i < XREF_TMPHASH_SIZE; i++) +- xref_tmphash[i] = NULL; + for (ref=c->xref_temp; ref; ref=_ref) { + struct jffs2_xattr_ref *tmp; + +@@ -884,6 +887,8 @@ void jffs2_build_xattr_subsystem(struct + "%u of xref (%u dead, %u orphan) found.\n", + xdatum_count, xdatum_unchecked_count, xdatum_orphan_count, + xref_count, xref_dead_count, xref_orphan_count); ++ kfree(xref_tmphash); ++ return 0; + } + + struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, +--- a/fs/jffs2/xattr.h ++++ b/fs/jffs2/xattr.h +@@ -71,7 +71,7 @@ static inline int is_xattr_ref_dead(stru + #ifdef CONFIG_JFFS2_FS_XATTR + + extern void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c); +-extern void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c); ++extern int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c); + extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c); + + extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, +@@ -103,7 +103,7 @@ extern ssize_t jffs2_listxattr(struct de + #else + + #define jffs2_init_xattr_subsystem(c) +-#define jffs2_build_xattr_subsystem(c) ++#define jffs2_build_xattr_subsystem(c) (0) + #define jffs2_clear_xattr_subsystem(c) + + #define jffs2_xattr_do_crccheck_inode(c, ic) diff --git a/queue-5.4/mmc-core-disable-trim-on-kingston-emmc04g-m627.patch b/queue-5.4/mmc-core-disable-trim-on-kingston-emmc04g-m627.patch new file mode 100644 index 00000000000..c77405ac358 --- /dev/null +++ b/queue-5.4/mmc-core-disable-trim-on-kingston-emmc04g-m627.patch @@ -0,0 +1,46 @@ +From f1738a1f816233e6dfc2407f24a31d596643fd90 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Mon, 19 Jun 2023 21:35:58 +0200 +Subject: mmc: core: disable TRIM on Kingston EMMC04G-M627 + +From: Robert Marko + +commit f1738a1f816233e6dfc2407f24a31d596643fd90 upstream. + +It seems that Kingston EMMC04G-M627 despite advertising TRIM support does +not work when the core is trying to use REQ_OP_WRITE_ZEROES. + +We are seeing I/O errors in OpenWrt under 6.1 on Zyxel NBG7815 that we did +not previously have and tracked it down to REQ_OP_WRITE_ZEROES. + +Trying to use fstrim seems to also throw errors like: +[93010.835112] I/O error, dev loop0, sector 16902 op 0x3:(DISCARD) flags 0x800 phys_seg 1 prio class 2 + +Disabling TRIM makes the error go away, so lets add a quirk for this eMMC +to disable TRIM. + +Signed-off-by: Robert Marko +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20230619193621.437358-1-robimarko@gmail.com +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/core/quirks.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/mmc/core/quirks.h ++++ b/drivers/mmc/core/quirks.h +@@ -91,6 +91,13 @@ static const struct mmc_fixup mmc_blk_fi + MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), + + /* ++ * Kingston EMMC04G-M627 advertises TRIM but it does not seems to ++ * support being used to offload WRITE_ZEROES. ++ */ ++ MMC_FIXUP("M62704", CID_MANFID_KINGSTON, 0x0100, add_quirk_mmc, ++ MMC_QUIRK_TRIM_BROKEN), ++ ++ /* + * On Some Kingston eMMCs, performing trim can result in + * unrecoverable data conrruption occasionally due to a firmware bug. + */ diff --git a/queue-5.4/mmc-core-disable-trim-on-micron-mtfc4gacajcn-1m.patch b/queue-5.4/mmc-core-disable-trim-on-micron-mtfc4gacajcn-1m.patch new file mode 100644 index 00000000000..6730eea968d --- /dev/null +++ b/queue-5.4/mmc-core-disable-trim-on-micron-mtfc4gacajcn-1m.patch @@ -0,0 +1,44 @@ +From dbfbddcddcebc9ce8a08757708d4e4a99d238e44 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Tue, 30 May 2023 23:32:59 +0200 +Subject: mmc: core: disable TRIM on Micron MTFC4GACAJCN-1M + +From: Robert Marko + +commit dbfbddcddcebc9ce8a08757708d4e4a99d238e44 upstream. + +It seems that Micron MTFC4GACAJCN-1M despite advertising TRIM support does +not work when the core is trying to use REQ_OP_WRITE_ZEROES. + +We are seeing the following errors in OpenWrt under 6.1 on Qnap Qhora 301W +that we did not previously have and tracked it down to REQ_OP_WRITE_ZEROES: +[ 18.085950] I/O error, dev loop0, sector 596 op 0x9:(WRITE_ZEROES) flags 0x800 phys_seg 0 prio class 2 + +Disabling TRIM makes the error go away, so lets add a quirk for this eMMC +to disable TRIM. + +Signed-off-by: Robert Marko +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20230530213259.1776512-1-robimarko@gmail.com +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/core/quirks.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/mmc/core/quirks.h ++++ b/drivers/mmc/core/quirks.h +@@ -98,6 +98,13 @@ static const struct mmc_fixup mmc_blk_fi + MMC_QUIRK_TRIM_BROKEN), + + /* ++ * Micron MTFC4GACAJCN-1M advertises TRIM but it does not seems to ++ * support being used to offload WRITE_ZEROES. ++ */ ++ MMC_FIXUP("Q2J54A", CID_MANFID_MICRON, 0x014e, add_quirk_mmc, ++ MMC_QUIRK_TRIM_BROKEN), ++ ++ /* + * On Some Kingston eMMCs, performing trim can result in + * unrecoverable data conrruption occasionally due to a firmware bug. + */ diff --git a/queue-5.4/mmc-sdhci-fix-dma-configure-compatibility-issue-when-64bit-dma-mode-is-used.patch b/queue-5.4/mmc-sdhci-fix-dma-configure-compatibility-issue-when-64bit-dma-mode-is-used.patch new file mode 100644 index 00000000000..12bbf97742d --- /dev/null +++ b/queue-5.4/mmc-sdhci-fix-dma-configure-compatibility-issue-when-64bit-dma-mode-is-used.patch @@ -0,0 +1,58 @@ +From 20dbd07ef0a8bc29eb03d6a95258ac8934cbe52d Mon Sep 17 00:00:00 2001 +From: Chevron Li +Date: Tue, 23 May 2023 19:11:14 +0800 +Subject: mmc: sdhci: fix DMA configure compatibility issue when 64bit DMA mode is used. + +From: Chevron Li + +commit 20dbd07ef0a8bc29eb03d6a95258ac8934cbe52d upstream. + +Bayhub SD host has hardware limitation: +1.The upper 32bit address is inhibited to be written at SD Host Register + [03E][13]=0 (32bits addressing) mode, is admitted to be written only at + SD Host Register [03E][13]=1 (64bits addressing) mode. +2.Because of above item#1, need to configure SD Host Register [03E][13] to + 1(64bits addressing mode) before set 64bit ADMA system address's higher + 32bits SD Host Register [05F~05C] if 64 bits addressing mode is used. + +The hardware limitation is reasonable for below reasons: +1.Normal flow should set DMA working mode first, then do + DMA-transfer-related configuration, such as system address. +2.The hardware limitation may avoid the software to configure wrong higher + 32bit address at 32bits addressing mode although it is redundant. + +The change that set 32bits/64bits addressing mode before set ADMA address, + has no side-effect to other host IPs for below reason: +The setting order is reasonable and standard: DMA Mode setting first and + then DMA address setting. It meets all DMA setting sequence. + +Signed-off-by: Chevron Li +Acked-by: Adrian Hunter +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20230523111114.18124-1-chevron_li@126.com +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -1104,6 +1104,8 @@ static void sdhci_prepare_data(struct sd + } + } + ++ sdhci_config_dma(host); ++ + if (host->flags & SDHCI_REQ_USE_DMA) { + int sg_cnt = sdhci_pre_dma_transfer(host, data, COOKIE_MAPPED); + +@@ -1123,8 +1125,6 @@ static void sdhci_prepare_data(struct sd + } + } + +- sdhci_config_dma(host); +- + if (!(host->flags & SDHCI_REQ_USE_DMA)) { + int flags; + diff --git a/queue-5.4/nfsd-add-encoding-of-op_recall-flag-for-write-delegation.patch b/queue-5.4/nfsd-add-encoding-of-op_recall-flag-for-write-delegation.patch new file mode 100644 index 00000000000..560fb054aca --- /dev/null +++ b/queue-5.4/nfsd-add-encoding-of-op_recall-flag-for-write-delegation.patch @@ -0,0 +1,32 @@ +From 58f5d894006d82ed7335e1c37182fbc5f08c2f51 Mon Sep 17 00:00:00 2001 +From: Dai Ngo +Date: Tue, 6 Jun 2023 16:41:02 -0700 +Subject: NFSD: add encoding of op_recall flag for write delegation + +From: Dai Ngo + +commit 58f5d894006d82ed7335e1c37182fbc5f08c2f51 upstream. + +Modified nfsd4_encode_open to encode the op_recall flag properly +for OPEN result with write delegation granted. + +Signed-off-by: Dai Ngo +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4xdr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -3409,7 +3409,7 @@ nfsd4_encode_open(struct nfsd4_compoundr + p = xdr_reserve_space(xdr, 32); + if (!p) + return nfserr_resource; +- *p++ = cpu_to_be32(0); ++ *p++ = cpu_to_be32(open->op_recall); + + /* + * TODO: space_limit's in delegations diff --git a/queue-5.4/revert-f2fs-fix-potential-corruption-when-moving-a-directory.patch b/queue-5.4/revert-f2fs-fix-potential-corruption-when-moving-a-directory.patch new file mode 100644 index 00000000000..239c487f011 --- /dev/null +++ b/queue-5.4/revert-f2fs-fix-potential-corruption-when-moving-a-directory.patch @@ -0,0 +1,66 @@ +From cde3c9d7e2a359e337216855dcb333a19daaa436 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 1 Jun 2023 12:58:23 +0200 +Subject: Revert "f2fs: fix potential corruption when moving a directory" + +From: Jan Kara + +commit cde3c9d7e2a359e337216855dcb333a19daaa436 upstream. + +This reverts commit d94772154e524b329a168678836745d2773a6e02. The +locking is going to be provided by VFS. + +CC: Jaegeuk Kim +CC: stable@vger.kernel.org +Signed-off-by: Jan Kara +Message-Id: <20230601105830.13168-3-jack@suse.cz> +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/namei.c | 16 +--------------- + 1 file changed, 1 insertion(+), 15 deletions(-) + +--- a/fs/f2fs/namei.c ++++ b/fs/f2fs/namei.c +@@ -892,20 +892,12 @@ static int f2fs_rename(struct inode *old + goto out; + } + +- /* +- * Copied from ext4_rename: we need to protect against old.inode +- * directory getting converted from inline directory format into +- * a normal one. +- */ +- if (S_ISDIR(old_inode->i_mode)) +- inode_lock_nested(old_inode, I_MUTEX_NONDIR2); +- + err = -ENOENT; + old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); + if (!old_entry) { + if (IS_ERR(old_page)) + err = PTR_ERR(old_page); +- goto out_unlock_old; ++ goto out; + } + + if (S_ISDIR(old_inode->i_mode)) { +@@ -1033,9 +1025,6 @@ static int f2fs_rename(struct inode *old + + f2fs_unlock_op(sbi); + +- if (S_ISDIR(old_inode->i_mode)) +- inode_unlock(old_inode); +- + if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) + f2fs_sync_fs(sbi->sb, 1); + +@@ -1051,9 +1040,6 @@ out_dir: + f2fs_put_page(old_dir_page, 0); + out_old: + f2fs_put_page(old_page, 0); +-out_unlock_old: +- if (S_ISDIR(old_inode->i_mode)) +- inode_unlock(old_inode); + out: + if (whiteout) + iput(whiteout); diff --git a/queue-5.4/series b/queue-5.4/series index b6118770332..e6ba18128f3 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -162,3 +162,16 @@ sh-dma-fix-dma-channel-offset-calculation.patch i2c-xiic-defer-xiic_wakeup-and-__xiic_start_xfer-in-.patch i2c-xiic-don-t-try-to-handle-more-interrupt-events-a.patch alsa-jack-fix-mutex-call-in-snd_jack_report.patch +nfsd-add-encoding-of-op_recall-flag-for-write-delegation.patch +mmc-core-disable-trim-on-kingston-emmc04g-m627.patch +mmc-core-disable-trim-on-micron-mtfc4gacajcn-1m.patch +mmc-sdhci-fix-dma-configure-compatibility-issue-when-64bit-dma-mode-is-used.patch +wifi-ath10k-serialize-wake_tx_queue-ops.patch +bcache-remove-unnecessary-null-point-check-in-node-allocations.patch +integrity-fix-possible-multiple-allocation-in-integrity_inode_get.patch +jffs2-reduce-stack-usage-in-jffs2_build_xattr_subsystem.patch +fs-avoid-empty-option-when-generating-legacy-mount-string.patch +ext4-remove-ext4-locking-of-moved-directory.patch +revert-f2fs-fix-potential-corruption-when-moving-a-directory.patch +fs-establish-locking-order-for-unrelated-directories.patch +fs-lock-moved-directories.patch diff --git a/queue-5.4/wifi-ath10k-serialize-wake_tx_queue-ops.patch b/queue-5.4/wifi-ath10k-serialize-wake_tx_queue-ops.patch new file mode 100644 index 00000000000..6692e808056 --- /dev/null +++ b/queue-5.4/wifi-ath10k-serialize-wake_tx_queue-ops.patch @@ -0,0 +1,86 @@ +From b719ebc37a1eacd4fd4f1264f731b016e5ec0c6e Mon Sep 17 00:00:00 2001 +From: Alexander Wetzel +Date: Thu, 23 Mar 2023 17:55:27 +0100 +Subject: wifi: ath10k: Serialize wake_tx_queue ops + +From: Alexander Wetzel + +commit b719ebc37a1eacd4fd4f1264f731b016e5ec0c6e upstream. + +Serialize the ath10k implementation of the wake_tx_queue ops. +ath10k_mac_op_wake_tx_queue() must not run concurrent since it's using +ieee80211_txq_schedule_start(). + +The intend of this patch is to sort out an issue discovered in the discussion +referred to by the Link tag. + +I can't test it with real hardware and thus just implemented the per-ac queue +lock Felix suggested. One obvious alternative to the per-ac lock would be to +bring back the txqs_lock commit bb2edb733586 ("ath10k: migrate to mac80211 txq +scheduling") dropped. + +Fixes: bb2edb733586 ("ath10k: migrate to mac80211 txq scheduling") +Reported-by: Felix Fietkau +Link: https://lore.kernel.org/r/519b5bb9-8899-ae7c-4eff-f3116cdfdb56@nbd.name +CC: +Signed-off-by: Alexander Wetzel +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230323165527.156414-1-alexander@wetzel-home.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath10k/core.c | 3 +++ + drivers/net/wireless/ath/ath10k/core.h | 3 +++ + drivers/net/wireless/ath/ath10k/mac.c | 6 ++++-- + 3 files changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -3195,6 +3195,9 @@ struct ath10k *ath10k_core_create(size_t + mutex_init(&ar->dump_mutex); + spin_lock_init(&ar->data_lock); + ++ for (int ac = 0; ac < IEEE80211_NUM_ACS; ac++) ++ spin_lock_init(&ar->queue_lock[ac]); ++ + INIT_LIST_HEAD(&ar->peers); + init_waitqueue_head(&ar->peer_mapping_wq); + init_waitqueue_head(&ar->htt.empty_tx_wq); +--- a/drivers/net/wireless/ath/ath10k/core.h ++++ b/drivers/net/wireless/ath/ath10k/core.h +@@ -1089,6 +1089,9 @@ struct ath10k { + /* protects shared structure data */ + spinlock_t data_lock; + ++ /* serialize wake_tx_queue calls per ac */ ++ spinlock_t queue_lock[IEEE80211_NUM_ACS]; ++ + struct list_head arvifs; + struct list_head peers; + struct ath10k_peer *peer_map[ATH10K_MAX_NUM_PEER_IDS]; +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -4406,13 +4406,14 @@ static void ath10k_mac_op_wake_tx_queue( + { + struct ath10k *ar = hw->priv; + int ret; +- u8 ac; ++ u8 ac = txq->ac; + + ath10k_htt_tx_txq_update(hw, txq); + if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH) + return; + +- ac = txq->ac; ++ spin_lock_bh(&ar->queue_lock[ac]); ++ + ieee80211_txq_schedule_start(hw, ac); + txq = ieee80211_next_txq(hw, ac); + if (!txq) +@@ -4427,6 +4428,7 @@ static void ath10k_mac_op_wake_tx_queue( + ath10k_htt_tx_txq_update(hw, txq); + out: + ieee80211_txq_schedule_end(hw, ac); ++ spin_unlock_bh(&ar->queue_lock[ac]); + } + + /* Must not be called with conf_mutex held as workers can use that also. */