summaryrefslogtreecommitdiffstats
path: root/net/packet
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2018-03-10 23:15:52 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2018-03-29 15:07:49 -0400
commit076515fc926793e162fc6525bed1679ef2bbf269 (patch)
treeafadea0e756147f4631df6b1bbef1c0e670b9494 /net/packet
parenta7498968338da9b928f5d8054acc8be6ed2bc14c (diff)
downloadlinux-076515fc926793e162fc6525bed1679ef2bbf269.tar.bz2
make non-exchanging __d_move() copy ->d_parent rather than swap them
Currently d_move(from, to) does the following: * name/parent of from <- old name/parent of to, from hashed there * to is unhashed * name of to is preserved * if from used to be detached, to gets detached * if from used to be attached, parent of to <- old parent of from. That's both user-visibly bogus and complicates reasoning a lot. Much saner semantics would be * name/parent of from <- name/parent of to, from hashed there. * to is unhashed * name/parent of to is unchanged. The price, of course, is that old parent of from might lose a reference. However, * all potentially cross-directory callers of d_move() have both parents pinned directly; typically, dentries themselves are grabbed only after we have grabbed and locked both parents. IOW, the decrement of old parent's refcount in case of d_move() won't reach zero. * __d_move() from d_splice_alias() is done to detached alias. No refcount decrements in that case * __d_move() from __d_unalias() *can* get the refcount to zero. So let's grab a reference to alias' old parent before calling __d_unalias() and dput() it after we'd dropped rename_lock. That does make d_splice_alias() potentially blocking. However, it has no callers in non-sleepable contexts (and the case where we'd grown that dget/dput pair is _very_ rare, so performance is not an issue). Another thing that needs adjustment is unlocking in the end of __d_move(); folded it in. And cleaned the remnants of bogus ordering from the "lock them in the beginning" counterpart - it's never been right and now (well, for 7 years now) we have that thing always serialized on rename_lock anyway. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net/packet')
0 files changed, 0 insertions, 0 deletions