]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ext4: remove EA inode entry from mbcache on inode eviction
authorJan Kara <jack@suse.cz>
Tue, 12 Jul 2022 10:54:22 +0000 (12:54 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Aug 2022 12:24:27 +0000 (14:24 +0200)
[ Upstream commit ce4b72c551af34a83e0143bc4f9f200d0af55e94 ]

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: 75980e9575cf ("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: Sasha Levin <sashal@kernel.org>
fs/ext4/inode.c
fs/ext4/xattr.c
fs/ext4/xattr.h

index 360a7d1539557c1c6eea3999403d92aa1869fcbb..98f381f6fc1802aaba758b3d24719fe26f25a104 100644 (file)
@@ -179,6 +179,8 @@ void ext4_evict_inode(struct inode *inode)
 
        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
index c3c3194f3ee10e441f9e6f0e52dba774fb21b7d4..b57fd07fbdbafa4f5401f912f6def08fcf8981f3 100644 (file)
@@ -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,
@@ -976,10 +984,8 @@ int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode,
 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);
@@ -1002,14 +1008,6 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
 
                        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",
@@ -1022,12 +1020,6 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
 
                        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);
-                       }
                }
        }
 
index f885f362add4af8f3f044e07ccb285e91f70c0ba..e5e36bd11f0556697e170c55a4690786e7e848a2 100644 (file)
@@ -191,6 +191,7 @@ extern void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *array);
 
 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[];