LINUX: split dentry eviction from osi_TryEvictVCache

To make osi_TryEvictVCache clearer, and to prepare for a future change
in dentry eviction, split the dentry eviction logic into its own routine
osi_TryEvictDentries.

No functional difference should be incurred by this commit.

Reviewed-on: https://gerrit.openafs.org/12362
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Joe Gorse <jhgorse@gmail.com>
(cherry picked from commit 742643e306929ac979ab69515a33ee2a3f2fa3fa)

Change-Id: I750fc7606ca56e784a60bdbc13a32d21fe307429
Reviewed-on: https://gerrit.openafs.org/12448
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
This commit is contained in:
Mark Vitale 2016-08-04 18:18:15 -04:00 committed by Stephan Wiesand
parent f8fcaaa064
commit 362f11de08

View File

@ -15,77 +15,88 @@
#include "osi_compat.h"
int
osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) {
int code;
void
osi_TryEvictDentries(struct vcache *avc)
{
struct dentry *dentry;
struct inode *inode = AFSTOV(avc);
#if defined(D_ALIAS_IS_HLIST) && !defined(HLIST_ITERATOR_NO_NODE)
struct hlist_node *p;
#endif
/* First, see if we can evict the inode from the dcache */
if (defersleep && avc != afs_globalVp && VREFCOUNT(avc) > 1 && avc->opens == 0) {
*slept = 1;
AFS_FAST_HOLD(avc);
ReleaseWriteLock(&afs_xvcache);
AFS_GUNLOCK();
#if defined(HAVE_DCACHE_LOCK)
spin_lock(&dcache_lock);
spin_lock(&dcache_lock);
restart:
list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
if (d_unhashed(dentry))
continue;
dget_locked(dentry);
list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
if (d_unhashed(dentry))
continue;
dget_locked(dentry);
spin_unlock(&dcache_lock);
if (d_invalidate(dentry) == -EBUSY) {
dput(dentry);
/* perhaps lock and try to continue? (use cur as head?) */
goto inuse;
}
dput(dentry);
spin_lock(&dcache_lock);
goto restart;
}
spin_unlock(&dcache_lock);
if (d_invalidate(dentry) == -EBUSY) {
dput(dentry);
/* perhaps lock and try to continue? (use cur as head?) */
goto inuse;
}
dput(dentry);
spin_lock(&dcache_lock);
goto restart;
}
spin_unlock(&dcache_lock);
#else /* HAVE_DCACHE_LOCK */
spin_lock(&inode->i_lock);
spin_lock(&inode->i_lock);
restart:
#if defined(D_ALIAS_IS_HLIST)
# if defined(HLIST_ITERATOR_NO_NODE)
hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
# else
hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {
hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {
# endif
#else
list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
#endif
spin_lock(&dentry->d_lock);
if (d_unhashed(dentry)) {
spin_unlock(&dentry->d_lock);
continue;
}
spin_lock(&dentry->d_lock);
if (d_unhashed(dentry)) {
spin_unlock(&dentry->d_lock);
dget(dentry);
spin_unlock(&inode->i_lock);
if (afs_d_invalidate(dentry) == -EBUSY) {
dput(dentry);
/* perhaps lock and try to continue? (use cur as head?) */
goto inuse;
}
dput(dentry);
spin_lock(&inode->i_lock);
goto restart;
continue;
}
spin_unlock(&dentry->d_lock);
dget(dentry);
spin_unlock(&inode->i_lock);
if (afs_d_invalidate(dentry) == -EBUSY) {
dput(dentry);
/* perhaps lock and try to continue? (use cur as head?) */
goto inuse;
}
dput(dentry);
spin_lock(&inode->i_lock);
goto restart;
}
spin_unlock(&inode->i_lock);
#endif /* HAVE_DCACHE_LOCK */
inuse:
return;
}
int
osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep)
{
int code;
/* First, see if we can evict the inode from the dcache */
if (defersleep && avc != afs_globalVp && VREFCOUNT(avc) > 1
&& avc->opens == 0) {
*slept = 1;
AFS_FAST_HOLD(avc);
ReleaseWriteLock(&afs_xvcache);
AFS_GUNLOCK();
osi_TryEvictDentries(avc);
AFS_GLOCK();
ObtainWriteLock(&afs_xvcache, 733);
AFS_FAST_RELE(avc);