--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
-@@ -4737,8 +4737,7 @@ static inline int ext4_iget_extra_inode(
+@@ -4735,8 +4735,7 @@ static inline int ext4_iget_extra_inode(
__le32 *magic = (void *)raw_inode +
EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize;
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
-@@ -1756,7 +1756,14 @@ static void mpage_release_unused_pages(s
+@@ -1754,7 +1754,14 @@ static void mpage_release_unused_pages(s
ext4_lblk_t start, last;
start = index << (PAGE_SHIFT - inode->i_blkbits);
last = end << (PAGE_SHIFT - inode->i_blkbits);
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
-@@ -2179,8 +2179,9 @@ int ext4_xattr_ibody_find(struct inode *
+@@ -2187,8 +2187,9 @@ int ext4_xattr_ibody_find(struct inode *
struct ext4_inode *raw_inode;
int error;
raw_inode = ext4_raw_inode(&is->iloc);
header = IHDR(inode, raw_inode);
is->s.base = is->s.first = IFIRST(header);
-@@ -2208,8 +2209,9 @@ int ext4_xattr_ibody_inline_set(handle_t
+@@ -2216,8 +2217,9 @@ int ext4_xattr_ibody_inline_set(handle_t
struct ext4_xattr_search *s = &is->s;
int error;
+++ /dev/null
-From 6bc0d63dad7f9f54d381925ee855b402f652fa39 Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Tue, 12 Jul 2022 12:54:22 +0200
-Subject: ext4: remove EA inode entry from mbcache on inode eviction
-
-From: Jan Kara <jack@suse.cz>
-
-commit 6bc0d63dad7f9f54d381925ee855b402f652fa39 upstream.
-
-Currently we remove EA inode from mbcache as soon as its xattr refcount
-drops to zero. However there can be pending attempts to reuse the inode
-and thus refcount handling code has to handle the situation when
-refcount increases from zero anyway. So save some work and just keep EA
-inode in mbcache until it is getting evicted. At that moment we are sure
-following iget() of EA inode will fail anyway (or wait for eviction to
-finish and load things from the disk again) and so removing mbcache
-entry at that moment is fine and simplifies the code a bit.
-
-CC: stable@vger.kernel.org
-Fixes: 82939d7999df ("ext4: convert to mbcache2")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220712105436.32204-3-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/ext4/inode.c | 2 ++
- fs/ext4/xattr.c | 24 ++++++++----------------
- fs/ext4/xattr.h | 1 +
- 3 files changed, 11 insertions(+), 16 deletions(-)
-
---- a/fs/ext4/inode.c
-+++ b/fs/ext4/inode.c
-@@ -206,6 +206,8 @@ void ext4_evict_inode(struct inode *inod
-
- trace_ext4_evict_inode(inode);
-
-+ if (EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)
-+ ext4_evict_ea_inode(inode);
- if (inode->i_nlink) {
- /*
- * When journalling data dirty buffers are tracked only in the
---- a/fs/ext4/xattr.c
-+++ b/fs/ext4/xattr.c
-@@ -433,6 +433,14 @@ error:
- return err;
- }
-
-+/* Remove entry from mbcache when EA inode is getting evicted */
-+void ext4_evict_ea_inode(struct inode *inode)
-+{
-+ if (EA_INODE_CACHE(inode))
-+ mb_cache_entry_delete(EA_INODE_CACHE(inode),
-+ ext4_xattr_inode_get_hash(inode), inode->i_ino);
-+}
-+
- static int
- ext4_xattr_inode_verify_hashes(struct inode *ea_inode,
- struct ext4_xattr_entry *entry, void *buffer,
-@@ -1018,10 +1026,8 @@ static int ext4_xattr_ensure_credits(han
- static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
- int ref_change)
- {
-- struct mb_cache *ea_inode_cache = EA_INODE_CACHE(ea_inode);
- struct ext4_iloc iloc;
- s64 ref_count;
-- u32 hash;
- int ret;
-
- inode_lock(ea_inode);
-@@ -1046,14 +1052,6 @@ static int ext4_xattr_inode_update_ref(h
-
- set_nlink(ea_inode, 1);
- ext4_orphan_del(handle, ea_inode);
--
-- if (ea_inode_cache) {
-- hash = ext4_xattr_inode_get_hash(ea_inode);
-- mb_cache_entry_create(ea_inode_cache,
-- GFP_NOFS, hash,
-- ea_inode->i_ino,
-- true /* reusable */);
-- }
- }
- } else {
- WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld",
-@@ -1066,12 +1064,6 @@ static int ext4_xattr_inode_update_ref(h
-
- clear_nlink(ea_inode);
- ext4_orphan_add(handle, ea_inode);
--
-- if (ea_inode_cache) {
-- hash = ext4_xattr_inode_get_hash(ea_inode);
-- mb_cache_entry_delete(ea_inode_cache, hash,
-- ea_inode->i_ino);
-- }
- }
- }
-
---- a/fs/ext4/xattr.h
-+++ b/fs/ext4/xattr.h
-@@ -190,6 +190,7 @@ extern void ext4_xattr_inode_array_free(
-
- extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
- struct ext4_inode *raw_inode, handle_t *handle);
-+extern void ext4_evict_ea_inode(struct inode *inode);
-
- extern const struct xattr_handler *ext4_xattr_handlers[];
-
+++ /dev/null
-From 58318914186c157477b978b1739dfe2f1b9dc0fe Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Tue, 12 Jul 2022 12:54:20 +0200
-Subject: mbcache: don't reclaim used entries
-
-From: Jan Kara <jack@suse.cz>
-
-commit 58318914186c157477b978b1739dfe2f1b9dc0fe upstream.
-
-Do not reclaim entries that are currently used by somebody from a
-shrinker. Firstly, these entries are likely useful. Secondly, we will
-need to keep such entries to protect pending increment of xattr block
-refcount.
-
-CC: stable@vger.kernel.org
-Fixes: 82939d7999df ("ext4: convert to mbcache2")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220712105436.32204-1-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/mbcache.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
---- a/fs/mbcache.c
-+++ b/fs/mbcache.c
-@@ -285,7 +285,7 @@ static unsigned long mb_cache_shrink(str
- while (nr_to_scan-- && !list_empty(&cache->c_list)) {
- entry = list_first_entry(&cache->c_list,
- struct mb_cache_entry, e_list);
-- if (entry->e_referenced) {
-+ if (entry->e_referenced || atomic_read(&entry->e_refcnt) > 2) {
- entry->e_referenced = 0;
- list_move_tail(&entry->e_list, &cache->c_list);
- continue;
-@@ -299,6 +299,14 @@ static unsigned long mb_cache_shrink(str
- spin_unlock(&cache->c_list_lock);
- head = mb_cache_entry_head(cache, entry->e_key);
- hlist_bl_lock(head);
-+ /* Now a reliable check if the entry didn't get used... */
-+ if (atomic_read(&entry->e_refcnt) > 2) {
-+ hlist_bl_unlock(head);
-+ spin_lock(&cache->c_list_lock);
-+ list_add_tail(&entry->e_list, &cache->c_list);
-+ cache->c_entry_count++;
-+ continue;
-+ }
- if (!hlist_bl_unhashed(&entry->e_hash_list)) {
- hlist_bl_del_init(&entry->e_hash_list);
- atomic_dec(&entry->e_refcnt);
iio-light-isl29028-fix-the-warning-in-isl29028_remove.patch
fuse-limit-nsec.patch
md-raid10-fix-kasan-warning.patch
-mbcache-don-t-reclaim-used-entries.patch
ia64-processor-fix-wincompatible-pointer-types-in-ia64_get_irr.patch
pci-add-defines-for-normal-and-subtractive-pci-bridges.patch
powerpc-fsl-pci-fix-class-code-of-pcie-root-port.patch
spmi-trace-fix-stack-out-of-bound-access-in-spmi-tracing-functions.patch
ext4-add-ext4_inode_has_xattr_space-macro-in-xattr.h.patch
ext4-make-sure-ext4_append-always-allocates-new-block.patch
-ext4-remove-ea-inode-entry-from-mbcache-on-inode-eviction.patch
ext4-fix-use-after-free-in-ext4_xattr_set_entry.patch
ext4-update-s_overhead_clusters-in-the-superblock-during-an-on-line-resize.patch
ext4-fix-extent-status-tree-race-in-writeback-error-recovery-path.patch
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
-@@ -4846,8 +4846,7 @@ static inline int ext4_iget_extra_inode(
+@@ -4844,8 +4844,7 @@ static inline int ext4_iget_extra_inode(
__le32 *magic = (void *)raw_inode +
EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize;
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
-@@ -1757,7 +1757,14 @@ static void mpage_release_unused_pages(s
+@@ -1755,7 +1755,14 @@ static void mpage_release_unused_pages(s
ext4_lblk_t start, last;
start = index << (PAGE_SHIFT - inode->i_blkbits);
last = end << (PAGE_SHIFT - inode->i_blkbits);
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
-@@ -2180,8 +2180,9 @@ int ext4_xattr_ibody_find(struct inode *
+@@ -2188,8 +2188,9 @@ int ext4_xattr_ibody_find(struct inode *
struct ext4_inode *raw_inode;
int error;
raw_inode = ext4_raw_inode(&is->iloc);
header = IHDR(inode, raw_inode);
is->s.base = is->s.first = IFIRST(header);
-@@ -2209,8 +2210,9 @@ int ext4_xattr_ibody_inline_set(handle_t
+@@ -2217,8 +2218,9 @@ int ext4_xattr_ibody_inline_set(handle_t
struct ext4_xattr_search *s = &is->s;
int error;
+++ /dev/null
-From 6bc0d63dad7f9f54d381925ee855b402f652fa39 Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Tue, 12 Jul 2022 12:54:22 +0200
-Subject: ext4: remove EA inode entry from mbcache on inode eviction
-
-From: Jan Kara <jack@suse.cz>
-
-commit 6bc0d63dad7f9f54d381925ee855b402f652fa39 upstream.
-
-Currently we remove EA inode from mbcache as soon as its xattr refcount
-drops to zero. However there can be pending attempts to reuse the inode
-and thus refcount handling code has to handle the situation when
-refcount increases from zero anyway. So save some work and just keep EA
-inode in mbcache until it is getting evicted. At that moment we are sure
-following iget() of EA inode will fail anyway (or wait for eviction to
-finish and load things from the disk again) and so removing mbcache
-entry at that moment is fine and simplifies the code a bit.
-
-CC: stable@vger.kernel.org
-Fixes: 82939d7999df ("ext4: convert to mbcache2")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220712105436.32204-3-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/ext4/inode.c | 2 ++
- fs/ext4/xattr.c | 24 ++++++++----------------
- fs/ext4/xattr.h | 1 +
- 3 files changed, 11 insertions(+), 16 deletions(-)
-
---- a/fs/ext4/inode.c
-+++ b/fs/ext4/inode.c
-@@ -207,6 +207,8 @@ void ext4_evict_inode(struct inode *inod
-
- trace_ext4_evict_inode(inode);
-
-+ if (EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)
-+ ext4_evict_ea_inode(inode);
- if (inode->i_nlink) {
- /*
- * When journalling data dirty buffers are tracked only in the
---- a/fs/ext4/xattr.c
-+++ b/fs/ext4/xattr.c
-@@ -434,6 +434,14 @@ error:
- return err;
- }
-
-+/* Remove entry from mbcache when EA inode is getting evicted */
-+void ext4_evict_ea_inode(struct inode *inode)
-+{
-+ if (EA_INODE_CACHE(inode))
-+ mb_cache_entry_delete(EA_INODE_CACHE(inode),
-+ ext4_xattr_inode_get_hash(inode), inode->i_ino);
-+}
-+
- static int
- ext4_xattr_inode_verify_hashes(struct inode *ea_inode,
- struct ext4_xattr_entry *entry, void *buffer,
-@@ -1019,10 +1027,8 @@ static int ext4_xattr_ensure_credits(han
- static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
- int ref_change)
- {
-- struct mb_cache *ea_inode_cache = EA_INODE_CACHE(ea_inode);
- struct ext4_iloc iloc;
- s64 ref_count;
-- u32 hash;
- int ret;
-
- inode_lock(ea_inode);
-@@ -1047,14 +1053,6 @@ static int ext4_xattr_inode_update_ref(h
-
- set_nlink(ea_inode, 1);
- ext4_orphan_del(handle, ea_inode);
--
-- if (ea_inode_cache) {
-- hash = ext4_xattr_inode_get_hash(ea_inode);
-- mb_cache_entry_create(ea_inode_cache,
-- GFP_NOFS, hash,
-- ea_inode->i_ino,
-- true /* reusable */);
-- }
- }
- } else {
- WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld",
-@@ -1067,12 +1065,6 @@ static int ext4_xattr_inode_update_ref(h
-
- clear_nlink(ea_inode);
- ext4_orphan_add(handle, ea_inode);
--
-- if (ea_inode_cache) {
-- hash = ext4_xattr_inode_get_hash(ea_inode);
-- mb_cache_entry_delete(ea_inode_cache, hash,
-- ea_inode->i_ino);
-- }
- }
- }
-
---- a/fs/ext4/xattr.h
-+++ b/fs/ext4/xattr.h
-@@ -190,6 +190,7 @@ extern void ext4_xattr_inode_array_free(
-
- extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
- struct ext4_inode *raw_inode, handle_t *handle);
-+extern void ext4_evict_ea_inode(struct inode *inode);
-
- extern const struct xattr_handler *ext4_xattr_handlers[];
-
+++ /dev/null
-From 3dc96bba65f53daa217f0a8f43edad145286a8f5 Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Tue, 12 Jul 2022 12:54:21 +0200
-Subject: mbcache: add functions to delete entry if unused
-
-From: Jan Kara <jack@suse.cz>
-
-commit 3dc96bba65f53daa217f0a8f43edad145286a8f5 upstream.
-
-Add function mb_cache_entry_delete_or_get() to delete mbcache entry if
-it is unused and also add a function to wait for entry to become unused
-- mb_cache_entry_wait_unused(). We do not share code between the two
-deleting function as one of them will go away soon.
-
-CC: stable@vger.kernel.org
-Fixes: 82939d7999df ("ext4: convert to mbcache2")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220712105436.32204-2-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/mbcache.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++--
- include/linux/mbcache.h | 10 ++++++-
- 2 files changed, 73 insertions(+), 3 deletions(-)
-
---- a/fs/mbcache.c
-+++ b/fs/mbcache.c
-@@ -10,7 +10,7 @@
- /*
- * Mbcache is a simple key-value store. Keys need not be unique, however
- * key-value pairs are expected to be unique (we use this fact in
-- * mb_cache_entry_delete()).
-+ * mb_cache_entry_delete_or_get()).
- *
- * Ext2 and ext4 use this cache for deduplication of extended attribute blocks.
- * Ext4 also uses it for deduplication of xattr values stored in inodes.
-@@ -124,6 +124,19 @@ void __mb_cache_entry_free(struct mb_cac
- }
- EXPORT_SYMBOL(__mb_cache_entry_free);
-
-+/*
-+ * mb_cache_entry_wait_unused - wait to be the last user of the entry
-+ *
-+ * @entry - entry to work on
-+ *
-+ * Wait to be the last user of the entry.
-+ */
-+void mb_cache_entry_wait_unused(struct mb_cache_entry *entry)
-+{
-+ wait_var_event(&entry->e_refcnt, atomic_read(&entry->e_refcnt) <= 3);
-+}
-+EXPORT_SYMBOL(mb_cache_entry_wait_unused);
-+
- static struct mb_cache_entry *__entry_find(struct mb_cache *cache,
- struct mb_cache_entry *entry,
- u32 key)
-@@ -216,7 +229,7 @@ out:
- }
- EXPORT_SYMBOL(mb_cache_entry_get);
-
--/* mb_cache_entry_delete - remove a cache entry
-+/* mb_cache_entry_delete - try to remove a cache entry
- * @cache - cache we work with
- * @key - key
- * @value - value
-@@ -253,6 +266,55 @@ void mb_cache_entry_delete(struct mb_cac
- }
- EXPORT_SYMBOL(mb_cache_entry_delete);
-
-+/* mb_cache_entry_delete_or_get - remove a cache entry if it has no users
-+ * @cache - cache we work with
-+ * @key - key
-+ * @value - value
-+ *
-+ * Remove entry from cache @cache with key @key and value @value. The removal
-+ * happens only if the entry is unused. The function returns NULL in case the
-+ * entry was successfully removed or there's no entry in cache. Otherwise the
-+ * function grabs reference of the entry that we failed to delete because it
-+ * still has users and return it.
-+ */
-+struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache,
-+ u32 key, u64 value)
-+{
-+ struct hlist_bl_node *node;
-+ struct hlist_bl_head *head;
-+ struct mb_cache_entry *entry;
-+
-+ head = mb_cache_entry_head(cache, key);
-+ hlist_bl_lock(head);
-+ hlist_bl_for_each_entry(entry, node, head, e_hash_list) {
-+ if (entry->e_key == key && entry->e_value == value) {
-+ if (atomic_read(&entry->e_refcnt) > 2) {
-+ atomic_inc(&entry->e_refcnt);
-+ hlist_bl_unlock(head);
-+ return entry;
-+ }
-+ /* We keep hash list reference to keep entry alive */
-+ hlist_bl_del_init(&entry->e_hash_list);
-+ hlist_bl_unlock(head);
-+ spin_lock(&cache->c_list_lock);
-+ if (!list_empty(&entry->e_list)) {
-+ list_del_init(&entry->e_list);
-+ if (!WARN_ONCE(cache->c_entry_count == 0,
-+ "mbcache: attempt to decrement c_entry_count past zero"))
-+ cache->c_entry_count--;
-+ atomic_dec(&entry->e_refcnt);
-+ }
-+ spin_unlock(&cache->c_list_lock);
-+ mb_cache_entry_put(cache, entry);
-+ return NULL;
-+ }
-+ }
-+ hlist_bl_unlock(head);
-+
-+ return NULL;
-+}
-+EXPORT_SYMBOL(mb_cache_entry_delete_or_get);
-+
- /* mb_cache_entry_touch - cache entry got used
- * @cache - cache the entry belongs to
- * @entry - entry that got used
---- a/include/linux/mbcache.h
-+++ b/include/linux/mbcache.h
-@@ -30,15 +30,23 @@ void mb_cache_destroy(struct mb_cache *c
- int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
- u64 value, bool reusable);
- void __mb_cache_entry_free(struct mb_cache_entry *entry);
-+void mb_cache_entry_wait_unused(struct mb_cache_entry *entry);
- static inline int mb_cache_entry_put(struct mb_cache *cache,
- struct mb_cache_entry *entry)
- {
-- if (!atomic_dec_and_test(&entry->e_refcnt))
-+ unsigned int cnt = atomic_dec_return(&entry->e_refcnt);
-+
-+ if (cnt > 0) {
-+ if (cnt <= 3)
-+ wake_up_var(&entry->e_refcnt);
- return 0;
-+ }
- __mb_cache_entry_free(entry);
- return 1;
- }
-
-+struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache,
-+ u32 key, u64 value);
- void mb_cache_entry_delete(struct mb_cache *cache, u32 key, u64 value);
- struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *cache, u32 key,
- u64 value);
+++ /dev/null
-From 58318914186c157477b978b1739dfe2f1b9dc0fe Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Tue, 12 Jul 2022 12:54:20 +0200
-Subject: mbcache: don't reclaim used entries
-
-From: Jan Kara <jack@suse.cz>
-
-commit 58318914186c157477b978b1739dfe2f1b9dc0fe upstream.
-
-Do not reclaim entries that are currently used by somebody from a
-shrinker. Firstly, these entries are likely useful. Secondly, we will
-need to keep such entries to protect pending increment of xattr block
-refcount.
-
-CC: stable@vger.kernel.org
-Fixes: 82939d7999df ("ext4: convert to mbcache2")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220712105436.32204-1-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/mbcache.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
---- a/fs/mbcache.c
-+++ b/fs/mbcache.c
-@@ -287,7 +287,7 @@ static unsigned long mb_cache_shrink(str
- while (nr_to_scan-- && !list_empty(&cache->c_list)) {
- entry = list_first_entry(&cache->c_list,
- struct mb_cache_entry, e_list);
-- if (entry->e_referenced) {
-+ if (entry->e_referenced || atomic_read(&entry->e_refcnt) > 2) {
- entry->e_referenced = 0;
- list_move_tail(&entry->e_list, &cache->c_list);
- continue;
-@@ -301,6 +301,14 @@ static unsigned long mb_cache_shrink(str
- spin_unlock(&cache->c_list_lock);
- head = mb_cache_entry_head(cache, entry->e_key);
- hlist_bl_lock(head);
-+ /* Now a reliable check if the entry didn't get used... */
-+ if (atomic_read(&entry->e_refcnt) > 2) {
-+ hlist_bl_unlock(head);
-+ spin_lock(&cache->c_list_lock);
-+ list_add_tail(&entry->e_list, &cache->c_list);
-+ cache->c_entry_count++;
-+ continue;
-+ }
- if (!hlist_bl_unhashed(&entry->e_hash_list)) {
- hlist_bl_del_init(&entry->e_hash_list);
- atomic_dec(&entry->e_refcnt);
fuse-limit-nsec.patch
serial-mvebu-uart-uart2-error-bits-clearing.patch
md-raid10-fix-kasan-warning.patch
-mbcache-don-t-reclaim-used-entries.patch
-mbcache-add-functions-to-delete-entry-if-unused.patch
ia64-processor-fix-wincompatible-pointer-types-in-ia64_get_irr.patch
pci-add-defines-for-normal-and-subtractive-pci-bridges.patch
powerpc-fsl-pci-fix-class-code-of-pcie-root-port.patch
spmi-trace-fix-stack-out-of-bound-access-in-spmi-tracing-functions.patch
ext4-add-ext4_inode_has_xattr_space-macro-in-xattr.h.patch
ext4-make-sure-ext4_append-always-allocates-new-block.patch
-ext4-remove-ea-inode-entry-from-mbcache-on-inode-eviction.patch
ext4-fix-use-after-free-in-ext4_xattr_set_entry.patch
ext4-update-s_overhead_clusters-in-the-superblock-during-an-on-line-resize.patch
ext4-fix-extent-status-tree-race-in-writeback-error-recovery-path.patch
+++ /dev/null
-From 58318914186c157477b978b1739dfe2f1b9dc0fe Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Tue, 12 Jul 2022 12:54:20 +0200
-Subject: mbcache: don't reclaim used entries
-
-From: Jan Kara <jack@suse.cz>
-
-commit 58318914186c157477b978b1739dfe2f1b9dc0fe upstream.
-
-Do not reclaim entries that are currently used by somebody from a
-shrinker. Firstly, these entries are likely useful. Secondly, we will
-need to keep such entries to protect pending increment of xattr block
-refcount.
-
-CC: stable@vger.kernel.org
-Fixes: 82939d7999df ("ext4: convert to mbcache2")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220712105436.32204-1-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/mbcache.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
---- a/fs/mbcache.c
-+++ b/fs/mbcache.c
-@@ -285,7 +285,7 @@ static unsigned long mb_cache_shrink(str
- while (nr_to_scan-- && !list_empty(&cache->c_list)) {
- entry = list_first_entry(&cache->c_list,
- struct mb_cache_entry, e_list);
-- if (entry->e_referenced) {
-+ if (entry->e_referenced || atomic_read(&entry->e_refcnt) > 2) {
- entry->e_referenced = 0;
- list_move_tail(&cache->c_list, &entry->e_list);
- continue;
-@@ -299,6 +299,14 @@ static unsigned long mb_cache_shrink(str
- spin_unlock(&cache->c_list_lock);
- head = mb_cache_entry_head(cache, entry->e_key);
- hlist_bl_lock(head);
-+ /* Now a reliable check if the entry didn't get used... */
-+ if (atomic_read(&entry->e_refcnt) > 2) {
-+ hlist_bl_unlock(head);
-+ spin_lock(&cache->c_list_lock);
-+ list_add_tail(&entry->e_list, &cache->c_list);
-+ cache->c_entry_count++;
-+ continue;
-+ }
- if (!hlist_bl_unhashed(&entry->e_hash_list)) {
- hlist_bl_del_init(&entry->e_hash_list);
- atomic_dec(&entry->e_refcnt);
bpf-fix-overflow-in-prog-accounting.patch
fuse-limit-nsec.patch
md-raid10-fix-kasan-warning.patch
-mbcache-don-t-reclaim-used-entries.patch
ia64-processor-fix-wincompatible-pointer-types-in-ia64_get_irr.patch
pci-add-defines-for-normal-and-subtractive-pci-bridges.patch
powerpc-fsl-pci-fix-class-code-of-pcie-root-port.patch
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
-@@ -4615,8 +4615,7 @@ static inline int ext4_iget_extra_inode(
+@@ -4613,8 +4613,7 @@ static inline int ext4_iget_extra_inode(
__le32 *magic = (void *)raw_inode +
EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize;
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
-@@ -1579,7 +1579,14 @@ static void mpage_release_unused_pages(s
+@@ -1577,7 +1577,14 @@ static void mpage_release_unused_pages(s
ext4_lblk_t start, last;
start = index << (PAGE_SHIFT - inode->i_blkbits);
last = end << (PAGE_SHIFT - inode->i_blkbits);
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
-@@ -2159,8 +2159,9 @@ int ext4_xattr_ibody_find(struct inode *
+@@ -2167,8 +2167,9 @@ int ext4_xattr_ibody_find(struct inode *
struct ext4_inode *raw_inode;
int error;
raw_inode = ext4_raw_inode(&is->iloc);
header = IHDR(inode, raw_inode);
is->s.base = is->s.first = IFIRST(header);
-@@ -2188,8 +2189,9 @@ int ext4_xattr_ibody_inline_set(handle_t
+@@ -2196,8 +2197,9 @@ int ext4_xattr_ibody_inline_set(handle_t
struct ext4_xattr_search *s = &is->s;
int error;
+++ /dev/null
-From 6bc0d63dad7f9f54d381925ee855b402f652fa39 Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Tue, 12 Jul 2022 12:54:22 +0200
-Subject: ext4: remove EA inode entry from mbcache on inode eviction
-
-From: Jan Kara <jack@suse.cz>
-
-commit 6bc0d63dad7f9f54d381925ee855b402f652fa39 upstream.
-
-Currently we remove EA inode from mbcache as soon as its xattr refcount
-drops to zero. However there can be pending attempts to reuse the inode
-and thus refcount handling code has to handle the situation when
-refcount increases from zero anyway. So save some work and just keep EA
-inode in mbcache until it is getting evicted. At that moment we are sure
-following iget() of EA inode will fail anyway (or wait for eviction to
-finish and load things from the disk again) and so removing mbcache
-entry at that moment is fine and simplifies the code a bit.
-
-CC: stable@vger.kernel.org
-Fixes: 82939d7999df ("ext4: convert to mbcache2")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220712105436.32204-3-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/ext4/inode.c | 2 ++
- fs/ext4/xattr.c | 24 ++++++++----------------
- fs/ext4/xattr.h | 1 +
- 3 files changed, 11 insertions(+), 16 deletions(-)
-
---- a/fs/ext4/inode.c
-+++ b/fs/ext4/inode.c
-@@ -179,6 +179,8 @@ void ext4_evict_inode(struct inode *inod
-
- trace_ext4_evict_inode(inode);
-
-+ if (EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)
-+ ext4_evict_ea_inode(inode);
- if (inode->i_nlink) {
- /*
- * When journalling data dirty buffers are tracked only in the
---- a/fs/ext4/xattr.c
-+++ b/fs/ext4/xattr.c
-@@ -436,6 +436,14 @@ error:
- return err;
- }
-
-+/* Remove entry from mbcache when EA inode is getting evicted */
-+void ext4_evict_ea_inode(struct inode *inode)
-+{
-+ if (EA_INODE_CACHE(inode))
-+ mb_cache_entry_delete(EA_INODE_CACHE(inode),
-+ ext4_xattr_inode_get_hash(inode), inode->i_ino);
-+}
-+
- static int
- ext4_xattr_inode_verify_hashes(struct inode *ea_inode,
- struct ext4_xattr_entry *entry, void *buffer,
-@@ -972,10 +980,8 @@ int __ext4_xattr_set_credits(struct supe
- static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
- int ref_change)
- {
-- struct mb_cache *ea_inode_cache = EA_INODE_CACHE(ea_inode);
- struct ext4_iloc iloc;
- s64 ref_count;
-- u32 hash;
- int ret;
-
- inode_lock(ea_inode);
-@@ -998,14 +1004,6 @@ static int ext4_xattr_inode_update_ref(h
-
- set_nlink(ea_inode, 1);
- ext4_orphan_del(handle, ea_inode);
--
-- if (ea_inode_cache) {
-- hash = ext4_xattr_inode_get_hash(ea_inode);
-- mb_cache_entry_create(ea_inode_cache,
-- GFP_NOFS, hash,
-- ea_inode->i_ino,
-- true /* reusable */);
-- }
- }
- } else {
- WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld",
-@@ -1018,12 +1016,6 @@ static int ext4_xattr_inode_update_ref(h
-
- clear_nlink(ea_inode);
- ext4_orphan_add(handle, ea_inode);
--
-- if (ea_inode_cache) {
-- hash = ext4_xattr_inode_get_hash(ea_inode);
-- mb_cache_entry_delete(ea_inode_cache, hash,
-- ea_inode->i_ino);
-- }
- }
- }
-
---- a/fs/ext4/xattr.h
-+++ b/fs/ext4/xattr.h
-@@ -191,6 +191,7 @@ extern void ext4_xattr_inode_array_free(
-
- extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
- struct ext4_inode *raw_inode, handle_t *handle);
-+extern void ext4_evict_ea_inode(struct inode *inode);
-
- extern const struct xattr_handler *ext4_xattr_handlers[];
-
+++ /dev/null
-From 3dc96bba65f53daa217f0a8f43edad145286a8f5 Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Tue, 12 Jul 2022 12:54:21 +0200
-Subject: mbcache: add functions to delete entry if unused
-
-From: Jan Kara <jack@suse.cz>
-
-commit 3dc96bba65f53daa217f0a8f43edad145286a8f5 upstream.
-
-Add function mb_cache_entry_delete_or_get() to delete mbcache entry if
-it is unused and also add a function to wait for entry to become unused
-- mb_cache_entry_wait_unused(). We do not share code between the two
-deleting function as one of them will go away soon.
-
-CC: stable@vger.kernel.org
-Fixes: 82939d7999df ("ext4: convert to mbcache2")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220712105436.32204-2-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/mbcache.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++--
- include/linux/mbcache.h | 10 ++++++-
- 2 files changed, 73 insertions(+), 3 deletions(-)
-
---- a/fs/mbcache.c
-+++ b/fs/mbcache.c
-@@ -11,7 +11,7 @@
- /*
- * Mbcache is a simple key-value store. Keys need not be unique, however
- * key-value pairs are expected to be unique (we use this fact in
-- * mb_cache_entry_delete()).
-+ * mb_cache_entry_delete_or_get()).
- *
- * Ext2 and ext4 use this cache for deduplication of extended attribute blocks.
- * Ext4 also uses it for deduplication of xattr values stored in inodes.
-@@ -125,6 +125,19 @@ void __mb_cache_entry_free(struct mb_cac
- }
- EXPORT_SYMBOL(__mb_cache_entry_free);
-
-+/*
-+ * mb_cache_entry_wait_unused - wait to be the last user of the entry
-+ *
-+ * @entry - entry to work on
-+ *
-+ * Wait to be the last user of the entry.
-+ */
-+void mb_cache_entry_wait_unused(struct mb_cache_entry *entry)
-+{
-+ wait_var_event(&entry->e_refcnt, atomic_read(&entry->e_refcnt) <= 3);
-+}
-+EXPORT_SYMBOL(mb_cache_entry_wait_unused);
-+
- static struct mb_cache_entry *__entry_find(struct mb_cache *cache,
- struct mb_cache_entry *entry,
- u32 key)
-@@ -217,7 +230,7 @@ out:
- }
- EXPORT_SYMBOL(mb_cache_entry_get);
-
--/* mb_cache_entry_delete - remove a cache entry
-+/* mb_cache_entry_delete - try to remove a cache entry
- * @cache - cache we work with
- * @key - key
- * @value - value
-@@ -254,6 +267,55 @@ void mb_cache_entry_delete(struct mb_cac
- }
- EXPORT_SYMBOL(mb_cache_entry_delete);
-
-+/* mb_cache_entry_delete_or_get - remove a cache entry if it has no users
-+ * @cache - cache we work with
-+ * @key - key
-+ * @value - value
-+ *
-+ * Remove entry from cache @cache with key @key and value @value. The removal
-+ * happens only if the entry is unused. The function returns NULL in case the
-+ * entry was successfully removed or there's no entry in cache. Otherwise the
-+ * function grabs reference of the entry that we failed to delete because it
-+ * still has users and return it.
-+ */
-+struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache,
-+ u32 key, u64 value)
-+{
-+ struct hlist_bl_node *node;
-+ struct hlist_bl_head *head;
-+ struct mb_cache_entry *entry;
-+
-+ head = mb_cache_entry_head(cache, key);
-+ hlist_bl_lock(head);
-+ hlist_bl_for_each_entry(entry, node, head, e_hash_list) {
-+ if (entry->e_key == key && entry->e_value == value) {
-+ if (atomic_read(&entry->e_refcnt) > 2) {
-+ atomic_inc(&entry->e_refcnt);
-+ hlist_bl_unlock(head);
-+ return entry;
-+ }
-+ /* We keep hash list reference to keep entry alive */
-+ hlist_bl_del_init(&entry->e_hash_list);
-+ hlist_bl_unlock(head);
-+ spin_lock(&cache->c_list_lock);
-+ if (!list_empty(&entry->e_list)) {
-+ list_del_init(&entry->e_list);
-+ if (!WARN_ONCE(cache->c_entry_count == 0,
-+ "mbcache: attempt to decrement c_entry_count past zero"))
-+ cache->c_entry_count--;
-+ atomic_dec(&entry->e_refcnt);
-+ }
-+ spin_unlock(&cache->c_list_lock);
-+ mb_cache_entry_put(cache, entry);
-+ return NULL;
-+ }
-+ }
-+ hlist_bl_unlock(head);
-+
-+ return NULL;
-+}
-+EXPORT_SYMBOL(mb_cache_entry_delete_or_get);
-+
- /* mb_cache_entry_touch - cache entry got used
- * @cache - cache the entry belongs to
- * @entry - entry that got used
---- a/include/linux/mbcache.h
-+++ b/include/linux/mbcache.h
-@@ -30,15 +30,23 @@ void mb_cache_destroy(struct mb_cache *c
- int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
- u64 value, bool reusable);
- void __mb_cache_entry_free(struct mb_cache_entry *entry);
-+void mb_cache_entry_wait_unused(struct mb_cache_entry *entry);
- static inline int mb_cache_entry_put(struct mb_cache *cache,
- struct mb_cache_entry *entry)
- {
-- if (!atomic_dec_and_test(&entry->e_refcnt))
-+ unsigned int cnt = atomic_dec_return(&entry->e_refcnt);
-+
-+ if (cnt > 0) {
-+ if (cnt <= 3)
-+ wake_up_var(&entry->e_refcnt);
- return 0;
-+ }
- __mb_cache_entry_free(entry);
- return 1;
- }
-
-+struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache,
-+ u32 key, u64 value);
- void mb_cache_entry_delete(struct mb_cache *cache, u32 key, u64 value);
- struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *cache, u32 key,
- u64 value);
+++ /dev/null
-From 58318914186c157477b978b1739dfe2f1b9dc0fe Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Tue, 12 Jul 2022 12:54:20 +0200
-Subject: mbcache: don't reclaim used entries
-
-From: Jan Kara <jack@suse.cz>
-
-commit 58318914186c157477b978b1739dfe2f1b9dc0fe upstream.
-
-Do not reclaim entries that are currently used by somebody from a
-shrinker. Firstly, these entries are likely useful. Secondly, we will
-need to keep such entries to protect pending increment of xattr block
-refcount.
-
-CC: stable@vger.kernel.org
-Fixes: 82939d7999df ("ext4: convert to mbcache2")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220712105436.32204-1-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/mbcache.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
---- a/fs/mbcache.c
-+++ b/fs/mbcache.c
-@@ -288,7 +288,7 @@ static unsigned long mb_cache_shrink(str
- while (nr_to_scan-- && !list_empty(&cache->c_list)) {
- entry = list_first_entry(&cache->c_list,
- struct mb_cache_entry, e_list);
-- if (entry->e_referenced) {
-+ if (entry->e_referenced || atomic_read(&entry->e_refcnt) > 2) {
- entry->e_referenced = 0;
- list_move_tail(&entry->e_list, &cache->c_list);
- continue;
-@@ -302,6 +302,14 @@ static unsigned long mb_cache_shrink(str
- spin_unlock(&cache->c_list_lock);
- head = mb_cache_entry_head(cache, entry->e_key);
- hlist_bl_lock(head);
-+ /* Now a reliable check if the entry didn't get used... */
-+ if (atomic_read(&entry->e_refcnt) > 2) {
-+ hlist_bl_unlock(head);
-+ spin_lock(&cache->c_list_lock);
-+ list_add_tail(&entry->e_list, &cache->c_list);
-+ cache->c_entry_count++;
-+ continue;
-+ }
- if (!hlist_bl_unhashed(&entry->e_hash_list)) {
- hlist_bl_del_init(&entry->e_hash_list);
- atomic_dec(&entry->e_refcnt);
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- drivers/pci/pcie/portdrv_pci.c | 5 ++++-
- include/linux/pci_ids.h | 1 +
- include/uapi/linux/pci_regs.h | 7 +++++++
+ drivers/pci/pcie/portdrv_pci.c | 5 ++++-
+ include/linux/pci_ids.h | 1 +
+ include/uapi/linux/pci_regs.h | 7 +++++++
3 files changed, 12 insertions(+), 1 deletion(-)
-diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
-index d4559cf88f79..26259630fd10 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
-@@ -106,7 +106,8 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
+@@ -106,7 +106,8 @@ static int pcie_portdrv_probe(struct pci
if (!pci_is_pcie(dev) ||
((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) &&
(pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM) &&
return -ENODEV;
status = pcie_port_device_register(dev);
-@@ -195,6 +196,8 @@ static const struct pci_device_id port_pci_ids[] = {
+@@ -195,6 +196,8 @@ static const struct pci_device_id port_p
{ PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0) },
/* subtractive decode PCI-to-PCI bridge, class type is 060401h */
{ PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x01), ~0) },
{ },
};
-diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
-index 635a9243cce0..ece7c28affa0 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
-@@ -81,6 +81,7 @@
+@@ -83,6 +83,7 @@
#define PCI_CLASS_SYSTEM_RTC 0x0803
#define PCI_CLASS_SYSTEM_PCI_HOTPLUG 0x0804
#define PCI_CLASS_SYSTEM_SDHCI 0x0805
#define PCI_CLASS_SYSTEM_OTHER 0x0880
#define PCI_BASE_CLASS_INPUT 0x09
-diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
-index 142b184eca8b..7e0d526dd96f 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -837,6 +837,13 @@
/* Vendor-Specific (VSEC, PCI_EXT_CAP_ID_VNDR) */
#define PCI_VNDR_HEADER 4 /* Vendor-Specific Header */
#define PCI_VNDR_HEADER_ID(x) ((x) & 0xffff)
---
-2.35.1
-
serial-mvebu-uart-uart2-error-bits-clearing.patch
md-raid-destroy-the-bitmap-after-destroying-the-thread.patch
md-raid10-fix-kasan-warning.patch
-mbcache-don-t-reclaim-used-entries.patch
-mbcache-add-functions-to-delete-entry-if-unused.patch
media-pci-atomisp_cmd-fix-three-missing-checks-on-list-iterator.patch
ia64-processor-fix-wincompatible-pointer-types-in-ia64_get_irr.patch
pci-add-defines-for-normal-and-subtractive-pci-bridges.patch
ext4-add-ext4_inode_has_xattr_space-macro-in-xattr.h.patch
ext4-fix-warning-in-ext4_iomap_begin-as-race-between-bmap-and-write.patch
ext4-make-sure-ext4_append-always-allocates-new-block.patch
-ext4-remove-ea-inode-entry-from-mbcache-on-inode-eviction.patch
ext4-fix-use-after-free-in-ext4_xattr_set_entry.patch
ext4-update-s_overhead_clusters-in-the-superblock-during-an-on-line-resize.patch
ext4-fix-extent-status-tree-race-in-writeback-error-recovery-path.patch
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
-@@ -4843,8 +4843,7 @@ static inline int ext4_iget_extra_inode(
+@@ -4841,8 +4841,7 @@ static inline int ext4_iget_extra_inode(
__le32 *magic = (void *)raw_inode +
EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize;
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
-@@ -1719,7 +1719,14 @@ static void mpage_release_unused_pages(s
+@@ -1717,7 +1717,14 @@ static void mpage_release_unused_pages(s
ext4_lblk_t start, last;
start = index << (PAGE_SHIFT - inode->i_blkbits);
last = end << (PAGE_SHIFT - inode->i_blkbits);
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
-@@ -2176,8 +2176,9 @@ int ext4_xattr_ibody_find(struct inode *
+@@ -2184,8 +2184,9 @@ int ext4_xattr_ibody_find(struct inode *
struct ext4_inode *raw_inode;
int error;
raw_inode = ext4_raw_inode(&is->iloc);
header = IHDR(inode, raw_inode);
is->s.base = is->s.first = IFIRST(header);
-@@ -2205,8 +2206,9 @@ int ext4_xattr_ibody_inline_set(handle_t
+@@ -2213,8 +2214,9 @@ int ext4_xattr_ibody_inline_set(handle_t
struct ext4_xattr_search *s = &is->s;
int error;
+++ /dev/null
-From 6bc0d63dad7f9f54d381925ee855b402f652fa39 Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Tue, 12 Jul 2022 12:54:22 +0200
-Subject: ext4: remove EA inode entry from mbcache on inode eviction
-
-From: Jan Kara <jack@suse.cz>
-
-commit 6bc0d63dad7f9f54d381925ee855b402f652fa39 upstream.
-
-Currently we remove EA inode from mbcache as soon as its xattr refcount
-drops to zero. However there can be pending attempts to reuse the inode
-and thus refcount handling code has to handle the situation when
-refcount increases from zero anyway. So save some work and just keep EA
-inode in mbcache until it is getting evicted. At that moment we are sure
-following iget() of EA inode will fail anyway (or wait for eviction to
-finish and load things from the disk again) and so removing mbcache
-entry at that moment is fine and simplifies the code a bit.
-
-CC: stable@vger.kernel.org
-Fixes: 82939d7999df ("ext4: convert to mbcache2")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220712105436.32204-3-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/ext4/inode.c | 2 ++
- fs/ext4/xattr.c | 24 ++++++++----------------
- fs/ext4/xattr.h | 1 +
- 3 files changed, 11 insertions(+), 16 deletions(-)
-
---- a/fs/ext4/inode.c
-+++ b/fs/ext4/inode.c
-@@ -207,6 +207,8 @@ void ext4_evict_inode(struct inode *inod
-
- trace_ext4_evict_inode(inode);
-
-+ if (EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)
-+ ext4_evict_ea_inode(inode);
- if (inode->i_nlink) {
- /*
- * When journalling data dirty buffers are tracked only in the
---- a/fs/ext4/xattr.c
-+++ b/fs/ext4/xattr.c
-@@ -434,6 +434,14 @@ error:
- return err;
- }
-
-+/* Remove entry from mbcache when EA inode is getting evicted */
-+void ext4_evict_ea_inode(struct inode *inode)
-+{
-+ if (EA_INODE_CACHE(inode))
-+ mb_cache_entry_delete(EA_INODE_CACHE(inode),
-+ ext4_xattr_inode_get_hash(inode), inode->i_ino);
-+}
-+
- static int
- ext4_xattr_inode_verify_hashes(struct inode *ea_inode,
- struct ext4_xattr_entry *entry, void *buffer,
-@@ -1019,10 +1027,8 @@ static int ext4_xattr_ensure_credits(han
- static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
- int ref_change)
- {
-- struct mb_cache *ea_inode_cache = EA_INODE_CACHE(ea_inode);
- struct ext4_iloc iloc;
- s64 ref_count;
-- u32 hash;
- int ret;
-
- inode_lock(ea_inode);
-@@ -1045,14 +1051,6 @@ static int ext4_xattr_inode_update_ref(h
-
- set_nlink(ea_inode, 1);
- ext4_orphan_del(handle, ea_inode);
--
-- if (ea_inode_cache) {
-- hash = ext4_xattr_inode_get_hash(ea_inode);
-- mb_cache_entry_create(ea_inode_cache,
-- GFP_NOFS, hash,
-- ea_inode->i_ino,
-- true /* reusable */);
-- }
- }
- } else {
- WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld",
-@@ -1065,12 +1063,6 @@ static int ext4_xattr_inode_update_ref(h
-
- clear_nlink(ea_inode);
- ext4_orphan_add(handle, ea_inode);
--
-- if (ea_inode_cache) {
-- hash = ext4_xattr_inode_get_hash(ea_inode);
-- mb_cache_entry_delete(ea_inode_cache, hash,
-- ea_inode->i_ino);
-- }
- }
- }
-
---- a/fs/ext4/xattr.h
-+++ b/fs/ext4/xattr.h
-@@ -190,6 +190,7 @@ extern void ext4_xattr_inode_array_free(
-
- extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
- struct ext4_inode *raw_inode, handle_t *handle);
-+extern void ext4_evict_ea_inode(struct inode *inode);
-
- extern const struct xattr_handler *ext4_xattr_handlers[];
-
+++ /dev/null
-From 3dc96bba65f53daa217f0a8f43edad145286a8f5 Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Tue, 12 Jul 2022 12:54:21 +0200
-Subject: mbcache: add functions to delete entry if unused
-
-From: Jan Kara <jack@suse.cz>
-
-commit 3dc96bba65f53daa217f0a8f43edad145286a8f5 upstream.
-
-Add function mb_cache_entry_delete_or_get() to delete mbcache entry if
-it is unused and also add a function to wait for entry to become unused
-- mb_cache_entry_wait_unused(). We do not share code between the two
-deleting function as one of them will go away soon.
-
-CC: stable@vger.kernel.org
-Fixes: 82939d7999df ("ext4: convert to mbcache2")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220712105436.32204-2-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/mbcache.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++--
- include/linux/mbcache.h | 10 ++++++-
- 2 files changed, 73 insertions(+), 3 deletions(-)
-
---- a/fs/mbcache.c
-+++ b/fs/mbcache.c
-@@ -11,7 +11,7 @@
- /*
- * Mbcache is a simple key-value store. Keys need not be unique, however
- * key-value pairs are expected to be unique (we use this fact in
-- * mb_cache_entry_delete()).
-+ * mb_cache_entry_delete_or_get()).
- *
- * Ext2 and ext4 use this cache for deduplication of extended attribute blocks.
- * Ext4 also uses it for deduplication of xattr values stored in inodes.
-@@ -125,6 +125,19 @@ void __mb_cache_entry_free(struct mb_cac
- }
- EXPORT_SYMBOL(__mb_cache_entry_free);
-
-+/*
-+ * mb_cache_entry_wait_unused - wait to be the last user of the entry
-+ *
-+ * @entry - entry to work on
-+ *
-+ * Wait to be the last user of the entry.
-+ */
-+void mb_cache_entry_wait_unused(struct mb_cache_entry *entry)
-+{
-+ wait_var_event(&entry->e_refcnt, atomic_read(&entry->e_refcnt) <= 3);
-+}
-+EXPORT_SYMBOL(mb_cache_entry_wait_unused);
-+
- static struct mb_cache_entry *__entry_find(struct mb_cache *cache,
- struct mb_cache_entry *entry,
- u32 key)
-@@ -217,7 +230,7 @@ out:
- }
- EXPORT_SYMBOL(mb_cache_entry_get);
-
--/* mb_cache_entry_delete - remove a cache entry
-+/* mb_cache_entry_delete - try to remove a cache entry
- * @cache - cache we work with
- * @key - key
- * @value - value
-@@ -254,6 +267,55 @@ void mb_cache_entry_delete(struct mb_cac
- }
- EXPORT_SYMBOL(mb_cache_entry_delete);
-
-+/* mb_cache_entry_delete_or_get - remove a cache entry if it has no users
-+ * @cache - cache we work with
-+ * @key - key
-+ * @value - value
-+ *
-+ * Remove entry from cache @cache with key @key and value @value. The removal
-+ * happens only if the entry is unused. The function returns NULL in case the
-+ * entry was successfully removed or there's no entry in cache. Otherwise the
-+ * function grabs reference of the entry that we failed to delete because it
-+ * still has users and return it.
-+ */
-+struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache,
-+ u32 key, u64 value)
-+{
-+ struct hlist_bl_node *node;
-+ struct hlist_bl_head *head;
-+ struct mb_cache_entry *entry;
-+
-+ head = mb_cache_entry_head(cache, key);
-+ hlist_bl_lock(head);
-+ hlist_bl_for_each_entry(entry, node, head, e_hash_list) {
-+ if (entry->e_key == key && entry->e_value == value) {
-+ if (atomic_read(&entry->e_refcnt) > 2) {
-+ atomic_inc(&entry->e_refcnt);
-+ hlist_bl_unlock(head);
-+ return entry;
-+ }
-+ /* We keep hash list reference to keep entry alive */
-+ hlist_bl_del_init(&entry->e_hash_list);
-+ hlist_bl_unlock(head);
-+ spin_lock(&cache->c_list_lock);
-+ if (!list_empty(&entry->e_list)) {
-+ list_del_init(&entry->e_list);
-+ if (!WARN_ONCE(cache->c_entry_count == 0,
-+ "mbcache: attempt to decrement c_entry_count past zero"))
-+ cache->c_entry_count--;
-+ atomic_dec(&entry->e_refcnt);
-+ }
-+ spin_unlock(&cache->c_list_lock);
-+ mb_cache_entry_put(cache, entry);
-+ return NULL;
-+ }
-+ }
-+ hlist_bl_unlock(head);
-+
-+ return NULL;
-+}
-+EXPORT_SYMBOL(mb_cache_entry_delete_or_get);
-+
- /* mb_cache_entry_touch - cache entry got used
- * @cache - cache the entry belongs to
- * @entry - entry that got used
---- a/include/linux/mbcache.h
-+++ b/include/linux/mbcache.h
-@@ -30,15 +30,23 @@ void mb_cache_destroy(struct mb_cache *c
- int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
- u64 value, bool reusable);
- void __mb_cache_entry_free(struct mb_cache_entry *entry);
-+void mb_cache_entry_wait_unused(struct mb_cache_entry *entry);
- static inline int mb_cache_entry_put(struct mb_cache *cache,
- struct mb_cache_entry *entry)
- {
-- if (!atomic_dec_and_test(&entry->e_refcnt))
-+ unsigned int cnt = atomic_dec_return(&entry->e_refcnt);
-+
-+ if (cnt > 0) {
-+ if (cnt <= 3)
-+ wake_up_var(&entry->e_refcnt);
- return 0;
-+ }
- __mb_cache_entry_free(entry);
- return 1;
- }
-
-+struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache,
-+ u32 key, u64 value);
- void mb_cache_entry_delete(struct mb_cache *cache, u32 key, u64 value);
- struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *cache, u32 key,
- u64 value);
+++ /dev/null
-From 58318914186c157477b978b1739dfe2f1b9dc0fe Mon Sep 17 00:00:00 2001
-From: Jan Kara <jack@suse.cz>
-Date: Tue, 12 Jul 2022 12:54:20 +0200
-Subject: mbcache: don't reclaim used entries
-
-From: Jan Kara <jack@suse.cz>
-
-commit 58318914186c157477b978b1739dfe2f1b9dc0fe upstream.
-
-Do not reclaim entries that are currently used by somebody from a
-shrinker. Firstly, these entries are likely useful. Secondly, we will
-need to keep such entries to protect pending increment of xattr block
-refcount.
-
-CC: stable@vger.kernel.org
-Fixes: 82939d7999df ("ext4: convert to mbcache2")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20220712105436.32204-1-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/mbcache.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
---- a/fs/mbcache.c
-+++ b/fs/mbcache.c
-@@ -288,7 +288,7 @@ static unsigned long mb_cache_shrink(str
- while (nr_to_scan-- && !list_empty(&cache->c_list)) {
- entry = list_first_entry(&cache->c_list,
- struct mb_cache_entry, e_list);
-- if (entry->e_referenced) {
-+ if (entry->e_referenced || atomic_read(&entry->e_refcnt) > 2) {
- entry->e_referenced = 0;
- list_move_tail(&entry->e_list, &cache->c_list);
- continue;
-@@ -302,6 +302,14 @@ static unsigned long mb_cache_shrink(str
- spin_unlock(&cache->c_list_lock);
- head = mb_cache_entry_head(cache, entry->e_key);
- hlist_bl_lock(head);
-+ /* Now a reliable check if the entry didn't get used... */
-+ if (atomic_read(&entry->e_refcnt) > 2) {
-+ hlist_bl_unlock(head);
-+ spin_lock(&cache->c_list_lock);
-+ list_add_tail(&entry->e_list, &cache->c_list);
-+ cache->c_entry_count++;
-+ continue;
-+ }
- if (!hlist_bl_unhashed(&entry->e_hash_list)) {
- hlist_bl_del_init(&entry->e_hash_list);
- atomic_dec(&entry->e_refcnt);
fuse-limit-nsec.patch
serial-mvebu-uart-uart2-error-bits-clearing.patch
md-raid10-fix-kasan-warning.patch
-mbcache-don-t-reclaim-used-entries.patch
-mbcache-add-functions-to-delete-entry-if-unused.patch
ia64-processor-fix-wincompatible-pointer-types-in-ia64_get_irr.patch
pci-add-defines-for-normal-and-subtractive-pci-bridges.patch
powerpc-fsl-pci-fix-class-code-of-pcie-root-port.patch
btrfs-reset-block-group-chunk-force-if-we-have-to-wait.patch
ext4-add-ext4_inode_has_xattr_space-macro-in-xattr.h.patch
ext4-make-sure-ext4_append-always-allocates-new-block.patch
-ext4-remove-ea-inode-entry-from-mbcache-on-inode-eviction.patch
ext4-fix-use-after-free-in-ext4_xattr_set_entry.patch
ext4-update-s_overhead_clusters-in-the-superblock-during-an-on-line-resize.patch
ext4-fix-extent-status-tree-race-in-writeback-error-recovery-path.patch