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
#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);
#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;
if (d_unhashed(dentry))
continue;
-
dget_locked(dentry);
#if defined(AFS_LINUX24_ENV)
#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();
}
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],
+ [])
+])
+