Re: [PATCH 03/10] ext4: Remove EA inode entry from mbcache on inode eviction

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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?

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.

-ritesh


>  		}
>  	} 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);
> -			}
>  		}
>  	}
>
> diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
> index 77efb9a627ad..060b7a2f485c 100644
> --- a/fs/ext4/xattr.h
> +++ b/fs/ext4/xattr.h
> @@ -178,6 +178,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[];
>
> --
> 2.35.3
>



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux