From c34be0c6c8e5e37a9b17947aaac3d21d861e9270 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Fri, 17 Dec 2010 17:01:15 +0100 Subject: [PATCH] b=19808 fix d_obtain_alias() misuse due to compat macro i=oleg i=yangsheng --- lustre/autoconf/lustre-core.m4 | 40 +++++++++++++++++----------------- lustre/include/linux/lustre_compat25.h | 12 +++++++++- lustre/llite/llite_nfs.c | 4 +--- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index c8e1264..006f3b1 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -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 -],[ - 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 +],[ + 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]) diff --git a/lustre/include/linux/lustre_compat25.h b/lustre/include/linux/lustre_compat25.h index 554bef8..44c11f1 100644 --- a/lustre/include/linux/lustre_compat25.h +++ b/lustre/include/linux/lustre_compat25.h @@ -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 diff --git a/lustre/llite/llite_nfs.c b/lustre/llite/llite_nfs.c index 01cdbc3..fc5e9b5 100644 --- a/lustre/llite/llite_nfs.c +++ b/lustre/llite/llite_nfs.c @@ -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); -- 1.8.3.1