From: Marc Dionne Date: Tue, 14 Aug 2012 01:55:25 +0000 (-0400) Subject: Linux 3.6: d_alias and i_dentry are now hlists X-Git-Tag: upstream/1.8.0_pre1^2~2082 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=6bea047fb404bde828c6358ae06f7941aa2bc959;p=packages%2Fo%2Fopenafs.git Linux 3.6: d_alias and i_dentry are now hlists The d_alias pointer is now the head of an hlist. This means the iterator is a different macro and has no "reverse" version since hlists have no direct pointer to the list tail. inode->i_dentry gets the same treatment. Adjust where we use it. Change-Id: Ibcdd8ab6f8a571a8f94c646949ebe0503f075574 Reviewed-on: http://gerrit.openafs.org/7983 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- diff --git a/acinclude.m4 b/acinclude.m4 index 260c75416..7a76b8b17 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -977,6 +977,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_EXPORT_OP_ENCODE_FH_TAKES_INODES LINUX_KMAP_ATOMIC_TAKES_NO_KM_TYPE LINUX_DENTRY_OPEN_TAKES_PATH + LINUX_D_ALIAS_IS_HLIST dnl If we are guaranteed that keyrings will work - that is dnl a) The kernel has keyrings enabled diff --git a/src/afs/LINUX/osi_vcache.c b/src/afs/LINUX/osi_vcache.c index e82d78e5d..cd61c6565 100644 --- a/src/afs/LINUX/osi_vcache.c +++ b/src/afs/LINUX/osi_vcache.c @@ -19,7 +19,11 @@ osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) { struct dentry *dentry; struct inode *inode = AFSTOV(avc); +#if defined(D_ALIAS_IS_HLIST) + struct hlist_node *cur, *head; +#else struct list_head *cur, *head; +#endif /* First, see if we can evict the inode from the dcache */ if (defersleep && avc != afs_globalVp && VREFCOUNT(avc) > 1 && avc->opens == 0) { @@ -53,12 +57,20 @@ restart: spin_unlock(&dcache_lock); #else /* HAVE_DCACHE_LOCK */ spin_lock(&inode->i_lock); +#if defined(D_ALIAS_IS_HLIST) + head = inode->i_dentry.first; +#else head = &inode->i_dentry; +#endif restart: cur = head; while ((cur = cur->next) != head) { +#if defined(D_ALIAS_IS_HLIST) + dentry = hlist_entry(cur, struct dentry, d_alias); +#else dentry = list_entry(cur, struct dentry, d_alias); +#endif spin_lock(&dentry->d_lock); if (d_unhashed(dentry)) { diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 7d5e166b0..48e2614fa 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -779,6 +779,9 @@ canonical_dentry(struct inode *ip) { struct vcache *vcp = VTOAFS(ip); struct dentry *first = NULL, *ret = NULL, *cur; +#if defined(D_ALIAS_IS_HLIST) + struct hlist_node *p; +#endif /* general strategy: * if vcp->target_link is set, and can be found in ip->i_dentry, use that. @@ -798,7 +801,11 @@ canonical_dentry(struct inode *ip) spin_lock(&ip->i_lock); # endif +#if defined(D_ALIAS_IS_HLIST) + hlist_for_each_entry(cur, p, &ip->i_dentry, d_alias) { +#else list_for_each_entry_reverse(cur, &ip->i_dentry, d_alias) { +#endif if (!vcp->target_link || cur == vcp->target_link) { ret = cur; diff --git a/src/afs/afs_daemons.c b/src/afs/afs_daemons.c index 75d057e9c..05e428720 100644 --- a/src/afs/afs_daemons.c +++ b/src/afs/afs_daemons.c @@ -397,8 +397,13 @@ afs_CheckRootVolume(void) spin_lock(&dp->d_lock); #endif #endif +#if defined(D_ALIAS_IS_HLIST) + hlist_del_init(&dp->d_alias); + hlist_add_head(&dp->d_alias, &(AFSTOV(vcp)->i_dentry)); +#else list_del_init(&dp->d_alias); list_add(&dp->d_alias, &(AFSTOV(vcp)->i_dentry)); +#endif dp->d_inode = AFSTOV(vcp); #if defined(AFS_LINUX24_ENV) #if defined(AFS_LINUX26_ENV) diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index 6c1ae52bc..75561bff6 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -689,3 +689,16 @@ AC_DEFUN([LINUX_DENTRY_OPEN_TAKES_PATH], [ [define if dentry_open takes a path argument], [-Werror]) ]) + + +AC_DEFUN([LINUX_D_ALIAS_IS_HLIST], [ + AC_CHECK_LINUX_BUILD([whether dentry->d_alias is an hlist], + [ac_cv_linux_d_alias_is_hlist], + [#include ], + [struct dentry *d = NULL; + struct hlist_node *hn = NULL; + d->d_alias = *hn;], + [D_ALIAS_IS_HLIST], + [define if dentry->d_alias is an hlist], + []) +])