Linux: 2.6.38: deal with dcache_lock removal

dcache_lock is gone in 2.6.38, and some of the vfs locking rules
have changed.

Of interest for openafs:
- inode->i_lock protects the d_alias list
- dentry->d_lock protects d_unhashed()

Add a new configure test for dcache_lock, and replace its use by
the appropriate new lock(s).

Reviewed-on: http://gerrit.openafs.org/3771
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
(cherry picked from commit 2eca7aef7b2940e4ef5f9901ce28481af6edb6dd)

Change-Id: Ic6cff1884a55aeb2ab29518e8d160000c6254fc5
Reviewed-on: http://gerrit.openafs.org/3918
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
This commit is contained in:
Marc Dionne 2011-01-28 20:59:17 -05:00 committed by Derrick Brashear
parent af5e870f59
commit cc0382da34
4 changed files with 53 additions and 2 deletions

View File

@ -902,6 +902,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
LINUX_KEY_ALLOC_NEEDS_CRED
LINUX_INIT_WORK_HAS_DATA
LINUX_REGISTER_SYSCTL_TABLE_NOFLAG
LINUX_HAVE_DCACHE_LOCK
dnl If we are guaranteed that keyrings will work - that is
dnl a) The kernel has keyrings enabled

View File

@ -18,6 +18,7 @@ osi_TryEvictVCache(struct vcache *avc, int *slept) {
int code;
struct dentry *dentry;
struct inode *inode = AFSTOV(avc);
struct list_head *cur, *head;
/* First, see if we can evict the inode from the dcache */
@ -25,8 +26,10 @@ osi_TryEvictVCache(struct vcache *avc, int *slept) {
*slept = 1;
ReleaseWriteLock(&afs_xvcache);
AFS_GUNLOCK();
#if defined(HAVE_DCACHE_LOCK)
spin_lock(&dcache_lock);
head = &(AFSTOV(avc))->i_dentry;
head = &inode->i_dentry;
restart:
cur = head;
@ -35,7 +38,6 @@ restart:
if (d_unhashed(dentry))
continue;
dget_locked(dentry);
spin_unlock(&dcache_lock);
@ -49,6 +51,35 @@ restart:
goto restart;
}
spin_unlock(&dcache_lock);
#else /* HAVE_DCACHE_LOCK */
spin_lock(&inode->i_lock);
head = &inode->i_dentry;
restart:
cur = head;
while ((cur = cur->next) != head) {
dentry = list_entry(cur, struct dentry, d_alias);
spin_lock(&dentry->d_lock);
if (d_unhashed(dentry)) {
spin_unlock(&dentry->d_lock);
continue;
}
spin_unlock(&dentry->d_lock);
dget(dentry);
spin_unlock(&inode->i_lock);
if (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:
AFS_GLOCK();
ObtainWriteLock(&afs_xvcache, 733);

View File

@ -389,7 +389,11 @@ afs_CheckRootVolume(void)
dp = d_find_alias(AFSTOV(afs_globalVp));
#if defined(AFS_LINUX24_ENV)
#if defined(HAVE_DCACHE_LOCK)
spin_lock(&dcache_lock);
#else
spin_lock(&AFSTOV(vcp)->i_lock);
#endif
#if defined(AFS_LINUX26_ENV)
spin_lock(&dp->d_lock);
#endif
@ -401,7 +405,11 @@ afs_CheckRootVolume(void)
#if defined(AFS_LINUX26_ENV)
spin_unlock(&dp->d_lock);
#endif
#if defined(HAVE_DCACHE_LOCK)
spin_unlock(&dcache_lock);
#else
spin_unlock(&AFSTOV(vcp)->i_lock);
#endif
#endif
dput(dp);

View File

@ -581,3 +581,14 @@ AC_DEFUN([LINUX_HAVE_TRY_TO_FREEZE], [
[])
])
AC_DEFUN([LINUX_HAVE_DCACHE_LOCK], [
AC_CHECK_LINUX_BUILD([for dcache_lock],
[ac_cv_linux_have_dcache_lock],
[#include <linux/dcache.h> ],
[printk("%p", &dcache_lock);],
[HAVE_DCACHE_LOCK],
[define if dcache_lock exists],
[])
])