From: Marc Dionne Date: Tue, 3 Sep 2013 11:55:14 +0000 (-0400) Subject: Linux 3.11: Adapt to d_count changes X-Git-Tag: openafs-stable-1_8_0pre1~1016 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=1f577e41b65e9bd213a915a296ecf5bedd17fcc1;hp=d9db6fbd17db2640648716815a6f0a8e8c0b9561 Linux 3.11: Adapt to d_count changes In preparation for upcoming changes in the 3.12 cycle, d_lockref was introduced late in the 3.11 cycle. The dentry's d_lock and d_count are moved to this new structure. A new d_lock macro makes the change transparent for locking, but direct users of d_count must adapt. A new d_count() helper function is provided and should now be used. Use the new d_count() helper function if available, and move some of the ifdef logic into a helper compatibility function. Change-Id: I32a21a174d763fb7df8f1e04da3bb7260684571d Reviewed-on: http://gerrit.openafs.org/10219 Tested-by: Jeffrey Altman Reviewed-by: Simon Wilkinson Reviewed-by: Jeffrey Altman --- diff --git a/acinclude.m4 b/acinclude.m4 index 15b5ad8..800333b 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -897,6 +897,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) AC_CHECK_LINUX_FUNC([d_alloc_anon], [#include ], [d_alloc_anon(NULL);]) + AC_CHECK_LINUX_FUNC([d_count], + [#include ], + [d_count(NULL);]) AC_CHECK_LINUX_FUNC([d_make_root], [#include ], [d_make_root(NULL);]) diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h index ce9178e..fdddf59 100644 --- a/src/afs/LINUX/osi_compat.h +++ b/src/afs/LINUX/osi_compat.h @@ -608,4 +608,32 @@ afs_proc_create(char *name, umode_t mode, struct proc_dir_entry *parent, struct #endif } +static inline int +afs_dentry_count(struct dentry *dp) +{ +#if defined(HAVE_LINUX_D_COUNT) + return d_count(dp); +#elif defined(D_COUNT_INT) + return dp->d_count; +#else + return atomic_read(&dp->d_count); +#endif +} + +static inline void +afs_maybe_shrink_dcache(struct dentry *dp) +{ +#if defined(HAVE_LINUX_D_COUNT) || defined(D_COUNT_INT) + spin_lock(&dp->d_lock); + if (afs_dentry_count(dp) > 1) { + spin_unlock(&dp->d_lock); + shrink_dcache_parent(dp); + } else + spin_unlock(&dp->d_lock); +#else + if (afs_dentry_count(dp) > 1) + shrink_dcache_parent(dp); +#endif +} + #endif /* AFS_LINUX_OSI_COMPAT_H */ diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index e9191ae..a60027e 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -1684,17 +1684,7 @@ afs_linux_rename(struct inode *oldip, struct dentry *olddp, rehash = newdp; } -#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_maybe_shrink_dcache(olddp); AFS_GLOCK(); code = afs_rename(VTOAFS(oldip), (char *)oldname, VTOAFS(newip), (char *)newname, credp);