summaryrefslogtreecommitdiff
path: root/fs/autofs4
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-09-29 14:54:27 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-10-09 02:38:41 -0400
commit8d85b4845a668d9a72649005c5aa932657311bd4 (patch)
tree47d8ce0b4836404030837c8ad3abb28e047ad594 /fs/autofs4
parent6d13f69444bd3d4888e43f7756449748f5a98bad (diff)
Allow sharing external names after __d_move()
* 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: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/autofs4')
0 files changed, 0 insertions, 0 deletions