]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Linux: 2.6.38: deal with dcache_lock removal
authorMarc Dionne <marc.c.dionne@gmail.com>
Sat, 29 Jan 2011 01:59:17 +0000 (20:59 -0500)
committerRuss Allbery <rra@debian.org>
Tue, 1 Mar 2011 00:03:11 +0000 (16:03 -0800)
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: Ic544db9bcf820f01f23227b71684847d742fa41f
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
Reviewed-on: http://gerrit.openafs.org/3998
Reviewed-by: Simon Wilkinson <sxw@inf.ed.ac.uk>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Marc Dionne <marc.c.dionne@gmail.com>
Reviewed-by: Russ Allbery <rra@stanford.edu>
(cherry picked from commit 9e614fafad635704acd7958283903ee2f88dc1c6)

acinclude.m4
src/afs/afs_daemons.c
src/afs/afs_vcache.c
src/cf/linux-test4.m4

index 7904e209204fc09337aa0702fc2d3ed92abe0c96..655fb11adaad1362f08d251d6ed990e82571d348 100644 (file)
@@ -817,6 +817,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
                 LINUX_GENERIC_FILE_AIO_READ
                 LINUX_INIT_WORK_HAS_DATA
                 LINUX_REGISTER_SYSCTL_TABLE_NOFLAG
+                LINUX_HAVE_DCACHE_LOCK
                 LINUX_SYSCTL_TABLE_CHECKING
                 LINUX_STRUCT_CTL_TABLE_HAS_CTL_NAME
                 LINUX_HAVE_IGET
index bd5bba88ec5dbf9413f5ba861c179c0612e77361..3d9d9776d4895f1276b25c7882cccd977e264690 100644 (file)
@@ -376,7 +376,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
@@ -388,7 +392,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);
                    
index 201bae7f17be8558196413adb0d2907c2d930099..63e6a278ed638d877075002164f2faf9881ce42c 100644 (file)
@@ -673,12 +673,15 @@ afs_ShakeLooseVCaches(afs_int32 anumber)
 #if defined(AFS_LINUX22_ENV)
            if (tvc != afs_globalVp && VREFCOUNT(tvc) > 1 && tvc->opens == 0) {
                 struct dentry *dentry;
+               struct inode *inode = AFSTOV(tvc);
                 struct list_head *cur, *head;
                 AFS_GUNLOCK();
+
+#if defined(HAVE_DCACHE_LOCK)
 #if defined(AFS_LINUX24_ENV)
                 spin_lock(&dcache_lock);
 #endif
-               head = &(AFSTOV(tvc))->i_dentry;
+               head = &inode->i_dentry;
 
 restart:
                 cur = head;
@@ -687,7 +690,6 @@ restart:
 
                    if (d_unhashed(dentry))
                        continue;
-
                    dget_locked(dentry);
 
 #if defined(AFS_LINUX24_ENV)
@@ -707,6 +709,35 @@ restart:
 #if defined(AFS_LINUX24_ENV)
                spin_unlock(&dcache_lock);
 #endif
+#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();
            }
index 88e48636a0da2c7cbb050cf937a903969b1b8dca..2f426ce64799b6e1a7c10bb70183bcb3d9466fa6 100644 (file)
@@ -1316,3 +1316,14 @@ AC_DEFUN([LINUX_HAVE_INODE_SETATTR], [
   if test "x$ac_cv_linux_inode_setattr" = "xyes"; then
     AC_DEFINE([HAVE_LINUX_INODE_SETATTR], 1, [define if your kernel has inode_setattr()])
   fi])
+
+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],
+                       [])
+])
+