From: Wu Libin Date: Fri, 24 Apr 2015 21:00:30 +0000 (-0400) Subject: LU-6428 llite: Add check of d_alias and d_child X-Git-Tag: 2.7.53~8 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=1a14c28cb1136f1f67fdb14e848b2d461b26f941;p=fs%2Flustre-release.git LU-6428 llite: Add check of d_alias and d_child In some specific kernel versions like debian wheezy 3.2 or Ubuntu 14.04, d_alias has been moved to d_u.d_alias and d_u.d_child has been moved to d_child in struct dentry in . This patch add a check of this two members to make the llite be compatible with those versions. Signed-off-by: Wu Libin Signed-off-by: James Simmons Change-Id: I8ae63fdd887609e2049ac5e90f2bf4ff2ab14fd4 Reviewed-on: http://review.whamcloud.com/14060 Reviewed-by: Bob Glossman Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Thomas Stibor Reviewed-by: Oleg Drokin --- diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index f597182..1d89199 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -1154,30 +1154,35 @@ generic_file_llseek_size_5args, [ ]) # LC_FILE_LLSEEK_SIZE_5ARG # -# LC_HAVE_DENTRY_D_ALIAS_HLIST +# LC_LLITE_DATA_IS_LIST # # 3.6 switch i_dentry/d_alias from list to hlist # -AC_DEFUN([LC_HAVE_DENTRY_D_ALIAS_HLIST], [ +# In the upstream kernels d_alias first changes +# to a hlist and then in later version, 3.11, gets +# moved to the union d_u. Due to some distros having +# d_alias in the d_u union as a struct list, which +# has never existed upstream stream, we can't test +# if d_alias is a list or hlist directly. If ever +# i_dentry and d_alias even up different combos then +# the build will fail. In that case then we will need +# to separate out the i_dentry and d_alias test below. +# +AC_DEFUN([LC_DATA_FOR_LLITE_IS_LIST], [ tmp_flags="$EXTRA_KCFLAGS" EXTRA_KCFLAGS="-Werror" -LB_CHECK_COMPILE([if 'i_dentry/d_alias' uses 'hlist'], -i_dentry_d_alias_hlist, [ +LB_CHECK_COMPILE([if 'i_dentry/d_alias' uses 'list'], +i_dentry_d_alias_list, [ #include - #include ],[ struct inode inode; - struct dentry dentry; - struct hlist_head head; - struct hlist_node node; - inode.i_dentry = head; - dentry.d_alias = node; + INIT_LIST_HEAD(&inode.i_dentry); ],[ - AC_DEFINE(HAVE_DENTRY_D_ALIAS_HLIST, 1, - [have i_dentry/d_alias uses hlist]) + AC_DEFINE(DATA_FOR_LLITE_IS_LIST, 1, + [both i_dentry/d_alias uses list]) ]) EXTRA_KCFLAGS="$tmp_flags" -]) # LC_HAVE_DENTRY_D_ALIAS_HLIST +]) # LC_DATA_FOR_LLITE_IS_LIST # # LC_DENTRY_OPEN_USE_PATH @@ -1282,9 +1287,10 @@ hlist_for_each_entry_3args, [ #include #include ],[ + struct hlist_head *head = NULL; struct inode *inode; - struct dentry *dentry; - hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { + + hlist_for_each_entry(inode, head, i_hash) { continue; } ],[ @@ -1456,6 +1462,61 @@ truncate_pagecache_old_size, [ ]) # LC_OLDSIZE_TRUNCATE_PAGECACHE # +# LC_HAVE_DENTRY_D_U_D_ALIAS +# +# 3.11 kernel moved d_alias to the union d_u in struct dentry +# +# Some distros move d_alias to d_u but it is still a struct list +# +AC_DEFUN([LC_HAVE_DENTRY_D_U_D_ALIAS], [ +AS_IF([test "x$lb_cv_compile_i_dentry_d_alias_list" = xyes], [ + LB_CHECK_COMPILE([if list 'dentry.d_u.d_alias' exist], + d_alias, [ + #include + #include + ],[ + struct dentry de; + INIT_LIST_HEAD(&de.d_u.d_alias); + ],[ + AC_DEFINE(HAVE_DENTRY_D_U_D_ALIAS, 1, + [list dentry.d_u.d_alias exist]) + ]) +],[ + LB_CHECK_COMPILE([if hlist 'dentry.d_u.d_alias' exist], + d_alias, [ + #include + #include + ],[ + struct dentry de; + INIT_HLIST_NODE(&de.d_u.d_alias); + ],[ + AC_DEFINE(HAVE_DENTRY_D_U_D_ALIAS, 1, + [hlist dentry.d_u.d_alias exist]) + ]) +]) +]) # LC_HAVE_DENTRY_D_U_D_ALIAS + +# +# LC_HAVE_DENTRY_D_CHILD +# +# 3.11 kernel d_child has been moved out of the union d_u +# in struct dentry +# +AC_DEFUN([LC_HAVE_DENTRY_D_CHILD], [ +LB_CHECK_COMPILE([if 'dentry.d_child' exist], +d_child, [ + #include + #include +],[ + struct dentry de; + INIT_LIST_HEAD(&de.d_child); +],[ + AC_DEFINE(HAVE_DENTRY_D_CHILD, 1, + [dentry.d_child exist]) +]) +]) # LC_HAVE_DENTRY_D_CHILD + +# # LC_KIOCB_KI_LEFT # # 3.12 ki_left removed from struct kiocb @@ -1541,6 +1602,7 @@ truncate_ipages_final, [ [kernel has truncate_inode_pages_final]) ]) ]) # LC_HAVE_TRUNCATE_IPAGES_FINAL + # # LC_VFS_RENAME_6ARGS # @@ -1645,7 +1707,7 @@ AC_DEFUN([LC_PROG_LINUX], [ LC_FILE_LLSEEK_SIZE_5ARG # 3.6 - LC_HAVE_DENTRY_D_ALIAS_HLIST + LC_DATA_FOR_LLITE_IS_LIST LC_DENTRY_OPEN_USE_PATH LC_HAVE_IOP_ATOMIC_OPEN @@ -1670,6 +1732,8 @@ AC_DEFUN([LC_PROG_LINUX], [ LC_HAVE_DIR_CONTEXT LC_D_COMPARE_5ARGS LC_HAVE_DCOUNT + LC_HAVE_DENTRY_D_U_D_ALIAS + LC_HAVE_DENTRY_D_CHILD # 3.12 LC_OLDSIZE_TRUNCATE_PAGECACHE diff --git a/lustre/include/lustre_compat.h b/lustre/include/lustre_compat.h index 9918a7a..0c0dc918 100644 --- a/lustre/include/lustre_compat.h +++ b/lustre/include/lustre_compat.h @@ -219,28 +219,36 @@ unsigned int ll_crypto_tfm_alg_min_keysize(struct crypto_blkcipher *tfm) #define clear_inode(i) end_writeback(i) #endif -#ifdef HAVE_DENTRY_D_ALIAS_HLIST +#ifndef HAVE_DENTRY_D_CHILD +#define d_child d_u.d_child +#endif + +#ifdef HAVE_DENTRY_D_U_D_ALIAS +#define d_alias d_u.d_alias +#endif + +#ifndef DATA_FOR_LLITE_IS_LIST #define ll_d_hlist_node hlist_node #define ll_d_hlist_empty(list) hlist_empty(list) #define ll_d_hlist_entry(ptr, type, name) hlist_entry(ptr.first, type, name) #define ll_d_hlist_for_each(tmp, i_dentry) hlist_for_each(tmp, i_dentry) -#ifdef HAVE_HLIST_FOR_EACH_3ARG -#define ll_d_hlist_for_each_entry(dentry, p, i_dentry, alias) \ - p = NULL; hlist_for_each_entry(dentry, i_dentry, alias) -#else -#define ll_d_hlist_for_each_entry(dentry, p, i_dentry, alias) \ - hlist_for_each_entry(dentry, p, i_dentry, alias) -#endif +# ifdef HAVE_HLIST_FOR_EACH_3ARG +# define ll_d_hlist_for_each_entry(dentry, p, i_dentry) \ + p = NULL; hlist_for_each_entry(dentry, i_dentry, d_alias) +# else +# define ll_d_hlist_for_each_entry(dentry, p, i_dentry) \ + hlist_for_each_entry(dentry, p, i_dentry, d_alias) +# endif #define DECLARE_LL_D_HLIST_NODE_PTR(name) struct ll_d_hlist_node *name #else #define ll_d_hlist_node list_head #define ll_d_hlist_empty(list) list_empty(list) #define ll_d_hlist_entry(ptr, type, name) list_entry(ptr.next, type, name) #define ll_d_hlist_for_each(tmp, i_dentry) list_for_each(tmp, i_dentry) -#define ll_d_hlist_for_each_entry(dentry, p, i_dentry, alias) \ - list_for_each_entry(dentry, i_dentry, alias) +#define ll_d_hlist_for_each_entry(dentry, p, i_dentry) \ + list_for_each_entry(dentry, i_dentry, d_alias) #define DECLARE_LL_D_HLIST_NODE_PTR(name) /* nothing */ -#endif +#endif /* !DATA_FOR_LLITE_IS_LIST */ #ifndef QUOTA_OK # define QUOTA_OK 0 diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index 074bc34..a8b122d 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -294,7 +294,7 @@ void ll_invalidate_aliases(struct inode *inode) PFID(ll_inode2fid(inode)), inode); ll_lock_dcache(inode); - ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) { + ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry) { CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p " "inode %p flags %d\n", dentry->d_name.len, dentry->d_name.name, dentry, dentry->d_parent, diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 768c09b..eb56578 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -758,7 +758,7 @@ void lustre_dump_dentry(struct dentry *dentry, int recur) return; list_for_each(tmp, &dentry->d_subdirs) { - struct dentry *d = list_entry(tmp, struct dentry, d_u.d_child); + struct dentry *d = list_entry(tmp, struct dentry, d_child); lustre_dump_dentry(d, recur - 1); } } diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 82d1612..adcdf2c 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -157,14 +157,14 @@ static void ll_invalidate_negative_children(struct inode *dir) DECLARE_LL_D_HLIST_NODE_PTR(p); ll_lock_dcache(dir); - ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry, d_alias) { + ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry) { spin_lock(&dentry->d_lock); if (!list_empty(&dentry->d_subdirs)) { struct dentry *child; list_for_each_entry_safe(child, tmp_subdir, &dentry->d_subdirs, - d_u.d_child) { + d_child) { if (child->d_inode == NULL) d_lustre_invalidate(child, 1); } @@ -364,7 +364,7 @@ static struct dentry *ll_find_alias(struct inode *inode, struct dentry *dentry) discon_alias = invalid_alias = NULL; ll_lock_dcache(inode); - ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) { + ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry) { LASSERT(alias != dentry); spin_lock(&alias->d_lock);