On Thu 16-06-22 20:31:18, Ritesh Harjani wrote: > On 22/06/14 06:05PM, Jan Kara wrote: > > 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@xxxxxxxxxxxxxxx > > Fixes: 82939d7999df ("ext4: convert to mbcache2") > > Signed-off-by: Jan Kara <jack@xxxxxxx> > > --- > > fs/ext4/inode.c | 2 ++ > > fs/ext4/xattr.c | 24 ++++++++---------------- > > fs/ext4/xattr.h | 1 + > > 3 files changed, 11 insertions(+), 16 deletions(-) > > > > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > > index 3dce7d058985..7450ee734262 100644 > > --- a/fs/ext4/inode.c > > +++ b/fs/ext4/inode.c > > @@ -177,6 +177,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 > > diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c > > index 042325349098..7fc40fb1e6b3 100644 > > --- a/fs/ext4/xattr.c > > +++ b/fs/ext4/xattr.c > > @@ -436,6 +436,14 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino, > > 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 */); > > - } > > Ok, so if I understand this correctly, since we are not immediately removing the > ea_inode_cache entry when the recount reaches 0, hence when the refcount is > reaches 1 from 0, we need not create mb_cache entry is it? > Is this since the entry never got deleted in the first place? Correct. > But what happens when the entry is created the very first time? > I might need to study xattr code to understand how this condition is > taken care. There are other places that take care of creating the entry in that case. E.g. ext4_xattr_inode_get() or ext4_xattr_inode_lookup_create(). Honza -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR