• Al Viro's avatar
    Allow sharing external names after __d_move() · 8d85b484
    Al Viro authored
    * external dentry names get a small structure prepended to them
    (struct external_name).
    * it contains an atomic refcount, matching the number of struct dentry
    instances that have ->d_name.name pointing to that external name.  The
    first thing free_dentry() does is decrementing refcount of external name,
    so the instances that are between the call of free_dentry() and
    RCU-delayed actual freeing do not contribute.
    * __d_move(x, y, false) makes the name of x equal to the name of y,
    external or not.  If y has an external name, extra reference is grabbed
    and put into x->d_name.name.  If x used to have an external name, the
    reference to the old name is dropped and, should it reach zero, freeing
    is scheduled via kfree_rcu().
    * free_dentry() in dentry with external name decrements the refcount of
    that name and, should it reach zero, does RCU-delayed call that will
    free both the dentry and external name.  Otherwise it does what it
    used to do, except that __d_free() doesn't even look at ->d_name.name;
    it simply frees the dentry.
    
    All non-RCU accesses to dentry external name are safe wrt freeing since they
    all should happen before free_dentry() is called.  RCU accesses might run
    into a dentry seen by free_dentry() or into an old name that got already
    dropped by __d_move(); however, in both cases dentry must have been
    alive and refer to that name at some point after we'd done rcu_read_lock(),
    which means that any freeing must be still pending.
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    8d85b484
dcache.c 88.9 KB