LINUX: Avoid d_invalidate() during afs_ShakeLooseVCaches() 30/12830/7
authorMark Vitale <mvitale@sinenomine.net>
Fri, 1 Dec 2017 01:26:46 +0000 (20:26 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Tue, 2 Jan 2018 03:50:39 +0000 (22:50 -0500)
commitafbc199f152cc06edc877333f229604c28638d07
treebac53cca2765dbb1671cc96aad0406d1852e9ce1
parent5076dfc14b980aed310f3862875d5e9919fa199d
LINUX: Avoid d_invalidate() during afs_ShakeLooseVCaches()

With recent changes to d_invalidate's semantics (it returns void in Linux 3.11,
and always returns success in RHEL 7.4), it has become increasingly clear that
d_invalidate() is not the best function for use in our best-effort
(nondisruptive) attempt to free up vcaches that is afs_ShakeLooseVCaches().
The new d_invalidate() semantics always force the invalidation of a directory
dentry, which contradicts our desire to be nondisruptive, especially when
that directory is being used as the current working directory for a process.
Our call to d_invalidate(), intended to merely probe for whether a dentry
can be discarded without affecting other consumers, instead would cause
processes using that dentry as a CWD to receive ENOENT errors from getcwd().

A previous commit (c3bbf0b4444db88192eea4580ac9e9ca3de0d286) tried to address
this issue by calling d_prune_aliases() instead of d_invalidate(), but
d_prune_aliases() does not recursively descend into children of the given
dentry while pruning, leaving it an incomplete solution for our use-case.

To address these issues, modify the shakeloose routine TryEvictDentries() to
call shrink_dcache_parent() and maybe __d_drop() for directories, and
d_prune_aliases() for non-directories, instead of d_invalidate().  (Calls to
d_prune_aliases() for directories have already been removed by reverting commit
c3bbf0b4444db88192eea4580ac9e9ca3de0d286.)

Just like d_invalidate(), shrink_dcache_parent() has been around "forever"
(since pre-git v2.6.12).  Also like d_invalidate(), it "walks" the parent
dentry's subdirectories and "shrinks" (unhashes) unused dentries.  But unlike
d_invalidate(), shrink_dcache_parent() will not unhash an in-use dentry, and
has never changed its signature or semantics.

d_prune_aliases() has also been available "forever", and has also never changed
its signature or semantics.  The lack of recursive descent is not an issue for
non-directories, which cannot have such children.

[kaduk@mit.edu: apply review feedback to fix locking and avoid extraneous
changes, and reword commit message]

Change-Id: Icb6138ee5785e0ef82a9b85b1d2651dfd0830043
Reviewed-on: https://gerrit.openafs.org/12830
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
src/afs/LINUX/osi_vcache.c