Skip to content

Commit 6bc0d63

Browse files
jankaratytso
authored andcommitted
ext4: remove EA inode entry from mbcache on inode eviction
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: [email protected] Fixes: 82939d7 ("ext4: convert to mbcache2") Signed-off-by: Jan Kara <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 3dc96bb commit 6bc0d63

File tree

3 files changed

+11
-16
lines changed

3 files changed

+11
-16
lines changed

fs/ext4/inode.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ void ext4_evict_inode(struct inode *inode)
177177

178178
trace_ext4_evict_inode(inode);
179179

180+
if (EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)
181+
ext4_evict_ea_inode(inode);
180182
if (inode->i_nlink) {
181183
/*
182184
* When journalling data dirty buffers are tracked only in the

fs/ext4/xattr.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,14 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,
436436
return err;
437437
}
438438

439+
/* Remove entry from mbcache when EA inode is getting evicted */
440+
void ext4_evict_ea_inode(struct inode *inode)
441+
{
442+
if (EA_INODE_CACHE(inode))
443+
mb_cache_entry_delete(EA_INODE_CACHE(inode),
444+
ext4_xattr_inode_get_hash(inode), inode->i_ino);
445+
}
446+
439447
static int
440448
ext4_xattr_inode_verify_hashes(struct inode *ea_inode,
441449
struct ext4_xattr_entry *entry, void *buffer,
@@ -976,10 +984,8 @@ int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode,
976984
static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
977985
int ref_change)
978986
{
979-
struct mb_cache *ea_inode_cache = EA_INODE_CACHE(ea_inode);
980987
struct ext4_iloc iloc;
981988
s64 ref_count;
982-
u32 hash;
983989
int ret;
984990

985991
inode_lock(ea_inode);
@@ -1002,14 +1008,6 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
10021008

10031009
set_nlink(ea_inode, 1);
10041010
ext4_orphan_del(handle, ea_inode);
1005-
1006-
if (ea_inode_cache) {
1007-
hash = ext4_xattr_inode_get_hash(ea_inode);
1008-
mb_cache_entry_create(ea_inode_cache,
1009-
GFP_NOFS, hash,
1010-
ea_inode->i_ino,
1011-
true /* reusable */);
1012-
}
10131011
}
10141012
} else {
10151013
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,
10221020

10231021
clear_nlink(ea_inode);
10241022
ext4_orphan_add(handle, ea_inode);
1025-
1026-
if (ea_inode_cache) {
1027-
hash = ext4_xattr_inode_get_hash(ea_inode);
1028-
mb_cache_entry_delete(ea_inode_cache, hash,
1029-
ea_inode->i_ino);
1030-
}
10311023
}
10321024
}
10331025

fs/ext4/xattr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ extern void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *array);
191191

192192
extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
193193
struct ext4_inode *raw_inode, handle_t *handle);
194+
extern void ext4_evict_ea_inode(struct inode *inode);
194195

195196
extern const struct xattr_handler *ext4_xattr_handlers[];
196197

0 commit comments

Comments
 (0)