Linux 3.6: d_alias and i_dentry are now hlists
authorMarc Dionne <marc.c.dionne@gmail.com>
Tue, 14 Aug 2012 01:55:25 +0000 (21:55 -0400)
committerDerrick Brashear <shadow@dementix.org>
Fri, 17 Aug 2012 18:14:02 +0000 (11:14 -0700)
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 <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementix.org>

acinclude.m4
src/afs/LINUX/osi_vcache.c
src/afs/LINUX/osi_vnodeops.c
src/afs/afs_daemons.c
src/cf/linux-test4.m4

index 260c754..7a76b8b 100644 (file)
@@ -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
index e82d78e..cd61c65 100644 (file)
@@ -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)) {
index 7d5e166..48e2614 100644 (file)
@@ -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;
index 75d057e..05e4287 100644 (file)
@@ -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)
index 6c1ae52..75561bf 100644 (file)
@@ -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 <linux/fs.h>],
+                       [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],
+                       [])
+])