Re: [PATCH] ceph: drop negtive child dentries before try pruning inode's alias

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

 



On Thu, 2017-11-30 at 22:12 +0800, Yan, Zheng wrote:
> negtive child dentry holds reference on inode's alias, it makes
> d_prune_aliases() do nothing.
> 
> Signed-off-by: "Yan, Zheng" <zyan@xxxxxxxxxx>
> ---
>  fs/ceph/mds_client.c | 43 ++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 36 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
> index da181acd4a61..9e7bb5fa9295 100644
> --- a/fs/ceph/mds_client.c
> +++ b/fs/ceph/mds_client.c
> @@ -1440,6 +1440,30 @@ static int __close_session(struct ceph_mds_client *mdsc,
>  	return request_close_session(mdsc, session);
>  }
>  
> +static bool drop_negative_children(struct dentry *dentry)
> +{
> +	struct dentry *child;
> +	bool all_negtive = true;
> +
> +	if (!d_is_dir(dentry))
> +		goto out;
> +
> +	spin_lock(&dentry->d_lock);
> +	list_for_each_entry(child, &dentry->d_subdirs, d_child) {
> +		if (d_really_is_positive(child)) {
> +			all_negtive = false;
> +			break;
> +		}
> +	}
> +	spin_unlock(&dentry->d_lock);
> +
> +	if (all_negtive)
> +		shrink_dcache_parent(dentry);
> +out:
> +	dput(dentry);

It's sort of nasty to drop the reference here. It makes it harder to
track how that gets done when you acquire and drop references across a
function boundary like this. There's also no reason for it since you
always do it last here anyway.

It'd be nicer to just move that into the caller.

> +	return all_negtive;
> +}
> +
>  /*
>   * Trim old(er) caps.
>   *
> @@ -1495,15 +1519,20 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
>  		__ceph_remove_cap(cap, true);
>  		session->s_trim_caps--;
>  	} else {
> -		int refs;
> +		struct dentry *dentry;
>  		/* try dropping referring dentries */
>  		spin_unlock(&ci->i_ceph_lock);
> -		d_prune_aliases(inode);
> -		refs = atomic_read(&inode->i_count);
> -		if (refs == 1)
> -			session->s_trim_caps--;
> -		dout("trim_caps_cb %p cap %p  pruned, count now %d\n",
> -		     inode, cap, refs);
> +		dentry = d_find_any_alias(inode);
> +		/* drop_negative_children() calls dput() */
> +		if (dentry && drop_negative_children(dentry)) {
> +			int refs;
> +			d_prune_aliases(inode);
> +			refs = atomic_read(&inode->i_count);
> +			if (refs == 1)
> +				session->s_trim_caps--;
> +			dout("trim_caps_cb %p cap %p pruned, count now %d\n",
> +			     inode, cap, refs);
> +		}
>  		return 0;
>  	}
>  

I think the rest looks fine though.

-- 
Jeff Layton <jlayton@xxxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux