Whamcloud - gitweb
b=19808 fix d_obtain_alias() misuse due to compat macro
authorAndreas Dilger <andreas.dilger@oracle.com>
Fri, 17 Dec 2010 16:01:15 +0000 (17:01 +0100)
committerJohann Lombardi <johann.lombardi@oracle.com>
Fri, 17 Dec 2010 16:01:15 +0000 (17:01 +0100)
i=oleg
i=yangsheng

lustre/autoconf/lustre-core.m4
lustre/include/linux/lustre_compat25.h
lustre/llite/llite_nfs.c

index c8e1264..006f3b1 100644 (file)
@@ -620,26 +620,6 @@ LB_LINUX_TRY_COMPILE([
 ])
 ])
 
-#
-# LC_D_OBTAIN_ALIAS
-# starting from 2.6.18 kernel don't export do_kern_mount
-# and want to use vfs_kern_mount instead.
-#
-AC_DEFUN([LC_D_OBTAIN_ALIAS],
-[AC_MSG_CHECKING([d_obtain_alias exist in kernel])
-LB_LINUX_TRY_COMPILE([
-        #include <linux/dcache.h>
-],[
-        d_obtain_alias(NULL);
-],[
-        AC_DEFINE(HAVE_D_OBTAIN_ALIAS, 1,
-                [d_obtain_alias exist in kernel])
-        AC_MSG_RESULT([yes])
-],[
-        AC_MSG_RESULT([no])
-])
-])
-
 # 
 # LC_INVALIDATEPAGE_RETURN_INT
 # 2.6.17 changes return type for invalidatepage to 'void' from 'int'
@@ -1659,6 +1639,26 @@ AC_DEFUN([LC_EXPORT_BDI_INIT],
 ])
 ])
 
+#
+# LC_D_OBTAIN_ALIAS
+# starting from 2.6.28 kernel replaces d_alloc_anon() with
+# d_obtain_alias() for getting anonymous dentries
+#
+AC_DEFUN([LC_D_OBTAIN_ALIAS],
+[AC_MSG_CHECKING([d_obtain_alias exist in kernel])
+LB_LINUX_TRY_COMPILE([
+        #include <linux/dcache.h>
+],[
+        d_obtain_alias(NULL);
+],[
+        AC_DEFINE(HAVE_D_OBTAIN_ALIAS, 1,
+                [d_obtain_alias exist in kernel])
+        AC_MSG_RESULT([yes])
+],[
+        AC_MSG_RESULT([no])
+])
+])
+
 # 2.6.29 change prepare/commit_write to write_begin/end
 AC_DEFUN([LC_WRITE_BEGIN_END],
 [AC_MSG_CHECKING([if kernel has .write_begin/end])
index 554bef8..44c11f1 100644 (file)
@@ -411,7 +411,17 @@ ll_kern_mount(const char *fstype, int flags, const char *name, void *data)
 #endif
 
 #ifndef HAVE_D_OBTAIN_ALIAS
-#define d_obtain_alias(inode) d_alloc_anon(inode)
+/* The old d_alloc_anon() didn't free the inode reference on error
+ * like d_obtain_alias().  Hide that difference/inconvenience here. */
+static inline struct dentry *d_obtain_alias(struct inode *inode)
+{
+       struct dentry *anon = d_alloc_anon(inode);
+
+       if (anon == NULL)
+               iput(inode);
+
+       return anon;
+}
 #endif
 
 #ifdef HAVE_UNREGISTER_BLKDEV_RETURN_INT
index 01cdbc3..fc5e9b5 100644 (file)
@@ -133,10 +133,8 @@ static struct dentry *ll_iget_for_nfs(struct super_block *sb,
         }
 
         result = d_obtain_alias(inode);
-        if (!result) {
-                iput(inode);
+        if (!result)
                 RETURN(ERR_PTR(-ENOMEM));
-        }
         ll_dops_init(result, 1);
 
         RETURN(result);