Whamcloud - gitweb
b=19808 fix d_obtain_alias() misuse due to compat macro.
authoryangsheng <sheng.yang@oracle.com>
Wed, 24 Nov 2010 14:09:01 +0000 (22:09 +0800)
committerVitaly Fertman <vitaly.fertman@oracle.com>
Fri, 26 Nov 2010 22:58:04 +0000 (01:58 +0300)
o=Adreas.Dilger
i=yangsheng
i=Oleg.Drokin

ll_iget_for_nfs() get a change from d_alloc_anon() to d_obtain_alias().
The former would NOT release the inode reference if there was an error, while
the latter does.  Hide this detail in the d_obtain_alias() compat macro, for
kernels that do not have this function, and remove it from the error handling
code at the caller, where it would drop the inode reference twice in rare error
cases on all kernels WITH d_obtain_alias() support (RHEL5 and newer).

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

index c632a48..eae0087 100644 (file)
@@ -700,26 +700,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'
 #
@@ -1850,6 +1830,26 @@ LB_LINUX_TRY_COMPILE([
 ])
 ])
 
+#
+# 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.31 replaces blk_queue_hardsect_size by blk_queue_logical_block_size function
 AC_DEFUN([LC_BLK_QUEUE_LOG_BLK_SIZE],
 [AC_MSG_CHECKING([if blk_queue_logical_block_size is defined])
index 05af255..67af966 100644 (file)
@@ -438,7 +438,17 @@ int ll_unregister_blkdev(unsigned int dev, const char *name)
 #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
 
 /* add a lustre compatible layer for crypto API */
index 25352ae..40b8513 100644 (file)
@@ -138,10 +138,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);