From fe8d833e53938319d1fb6e20153a50a74bed5860 Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Wed, 2 Feb 2011 21:55:27 -0500 Subject: [PATCH] Linux: 2.6.38: dentry->d_count is not an atomic d_count is now an int protected by the dentry's d_lock. Take the lock when we use it, instead of using an atomic_* function. Reviewed-on: http://gerrit.openafs.org/3883 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 281f5bf5fbb0a546edcce62ef4e097ae9bbdbf73) Change-Id: Id30054cb110720632f6f4a7fc4d7860cb69cb1e7 Signed-off-by: Anders Kaseorg Reviewed-on: http://gerrit.openafs.org/3999 Tested-by: BuildBot Reviewed-by: Russ Allbery --- acinclude.m4 | 1 + src/afs/LINUX/osi_vnodeops.c | 9 +++++++++ src/cf/linux-test4.m4 | 12 ++++++++++++ 3 files changed, 22 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 3211cfcf40..84dd9b09d7 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -828,6 +828,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_INIT_WORK_HAS_DATA LINUX_REGISTER_SYSCTL_TABLE_NOFLAG LINUX_HAVE_DCACHE_LOCK + LINUX_D_COUNT_IS_INT LINUX_SYSCTL_TABLE_CHECKING LINUX_STRUCT_CTL_TABLE_HAS_CTL_NAME LINUX_HAVE_IGET diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 2d86914ac4..345e7ab7c0 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -1396,10 +1396,19 @@ afs_linux_rename(struct inode *oldip, struct dentry *olddp, #endif #if defined(AFS_LINUX24_ENV) +#if defined(D_COUNT_INT) + spin_lock(&olddp->d_lock); + if (olddp->d_count > 1) { + spin_unlock(&olddp->d_lock); + shrink_dcache_parent(olddp); + } else + spin_unlock(&olddp->d_lock); +#else if (atomic_read(&olddp->d_count) > 1) shrink_dcache_parent(olddp); #endif + AFS_GLOCK(); code = afs_rename(VTOAFS(oldip), oldname, VTOAFS(newip), newname, credp); AFS_GUNLOCK(); diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index 2f426ce647..b428f37549 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -1327,3 +1327,15 @@ AC_DEFUN([LINUX_HAVE_DCACHE_LOCK], [ []) ]) + +AC_DEFUN([LINUX_D_COUNT_IS_INT], [ + AC_CHECK_LINUX_BUILD([if dentry->d_count is an int], + [ac_cv_linux_d_count_int], + [#include ], + [struct dentry _d; + dget(&_d); + _d.d_count = 1;], + [D_COUNT_INT], + [define if dentry->d_count is an int], + [-Werror]) +])