[Devel] [PATCH rh7 3/3] dcache: zap dentry_lru_del()

Dmitry Monakhov dmonakhov at openvz.org
Thu Mar 24 08:01:35 PDT 2016


Vladimir Davydov <vdavydov at virtuozzo.com> writes:

> dentry_lru_del() is buggy - it tries to remove a dentry from a shrink
> list, which is not protected by any locks and can only be safely
> modified by a caller of dcache shrinker. Previous two patches replaced
> this function calls with d_lru_del() and corresponding checks in two
> places where it could result in corrupting shrink lists - dentry_kill()
> and select_collect(). The only place left, shrink_dcache_for_umount(),
> should be safe, because shrinker should be already unregistered there.
>
> Still, to make sure that it doesn't race with a shrinker, let's replace
> dentry_lru_del() with d_lru_del() there and make it issue a warning if
> it encounters a dentry which is on a shrink list. After that
> dentry_lru_del() is not used anywhere and can be removed. Note, it was
> removed upstream either, but there are quite a few patches to be
> backported.
>
> Signed-off-by: Vladimir Davydov <vdavydov at virtuozzo.com>
Ack-by: dmonakhov at openvz.org

> ---
>  fs/dcache.c | 20 +++-----------------
>  1 file changed, 3 insertions(+), 17 deletions(-)
>
> diff --git a/fs/dcache.c b/fs/dcache.c
> index cba54cf702f5..518c519010e3 100644
> --- a/fs/dcache.c
> +++ b/fs/dcache.c
> @@ -427,22 +427,6 @@ static void dentry_lru_add(struct dentry *dentry)
>  		d_lru_add(dentry);
>  }
>  
> -/*
> - * Remove a dentry with references from the LRU.
> - *
> - * If we are on the shrink list, then we can get to try_prune_one_dentry() and
> - * lose our last reference through the parent walk. In this case, we need to
> - * remove ourselves from the shrink list, not the LRU.
> - */
> -static void dentry_lru_del(struct dentry *dentry)
> -{
> -	if (dentry->d_flags & DCACHE_LRU_LIST) {
> -		if (dentry->d_flags & DCACHE_SHRINK_LIST)
> -			return d_shrink_del(dentry);
> -		d_lru_del(dentry);
> -	}
> -}
> -
>  /**
>   * d_kill - kill dentry and return parent
>   * @dentry: dentry to kill
> @@ -1109,7 +1093,9 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
>  			    !d_unhashed(dentry))
>  				dentry->d_op->d_prune(dentry);
>  
> -			dentry_lru_del(dentry);
> +			WARN_ON_ONCE(dentry->d_flags & DCACHE_SHRINK_LIST);
> +			if (dentry->d_flags & DCACHE_LRU_LIST)
> +				d_lru_del(dentry);
>  			__d_shrink(dentry);
>  
>  			if (dentry->d_lockref.count != 0) {
> -- 
> 2.1.4
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 472 bytes
Desc: not available
URL: <http://lists.openvz.org/pipermail/devel/attachments/20160324/36bb405e/attachment.sig>


More information about the Devel mailing list