Re: Q: spin_unlock(dentry) after lock_parent(dentry)

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

 



Al Viro,

I think I could find a clearer problematic scenario.
Can it happen in real world?

- /.../dirA/dirB/fileC exists.
- shrink_dentry_list() gets a list containing fileC and dirB, but not
  dirA
  + Round 1: fileC
    - shrink_dentry_list() gets d_parent which is dirB
    - dirB is DCACHE_SHRINK_LIST set, so __dentry_kill() is called but
      not dentry_free()
    - shrink_dentry_list() gets higher d_parent which is dirA
    - dirA is not DCACHE_SHRINK_LIST set, so both of __dentry_kill() and
      dentry_free() are is called
  + Round 2: dirB
    - shrink_dentry_list() tries getting d_parent which is dirA
    - dirA is freed by RCU. if RCU already activated __d_free(), BANG!


> In the case of concurrent dentry_kill() and shrink_dentry_list(),
> dentry_kill() kills the dentry and calls list_del(&dentry->d_u.d_child).
> lock_parent() (called by shrink_dentry_list()) doesn't check d_child
> nor DCACHE_DENTRY_KILLED. So shrink_dentry_list() may get a parent of a
> dead dentry and tries traversing via d_parent.
> Is it correct to track d_parent after list_del(&dentry->d_u.d_child)?
> Should lock_parent() consider DCACHE_DENTRY_KILLED too?
>
> --- a/fs/dcache.c
> +++ b/fs/dcache.c
> @@ -533,7 +533,8 @@ failed:
>  static inline struct dentry *lock_parent(struct dentry *dentry)
>  {
>  	struct dentry *parent = dentry->d_parent;
> -	if (IS_ROOT(dentry))
> +	if (IS_ROOT(dentry)
> +	    || (dentry->d_flags & DCACHE_DENTRY_KILLED))
>  		return NULL;
>  	if (likely(spin_trylock(&parent->d_lock)))
>  		return parent;


J. R. Okajima
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux