diff options
Diffstat (limited to 'sys-cluster/lustre/files/0006-LU-1337-vfs-kernel-3.2-protects-inode-i_nlink.patch')
-rw-r--r-- | sys-cluster/lustre/files/0006-LU-1337-vfs-kernel-3.2-protects-inode-i_nlink.patch | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/sys-cluster/lustre/files/0006-LU-1337-vfs-kernel-3.2-protects-inode-i_nlink.patch b/sys-cluster/lustre/files/0006-LU-1337-vfs-kernel-3.2-protects-inode-i_nlink.patch new file mode 100644 index 000000000..4866ce2dd --- /dev/null +++ b/sys-cluster/lustre/files/0006-LU-1337-vfs-kernel-3.2-protects-inode-i_nlink.patch @@ -0,0 +1,194 @@ +From 7fefbc7487f55b0edaa7a85f0e5b9fea68d5ff15 Mon Sep 17 00:00:00 2001 +From: Liu Xuezhao <xuezhao.liu@emc.com> +Date: Thu, 9 Aug 2012 10:31:10 +0800 +Subject: [PATCH 06/13] LU-1337 vfs: kernel 3.2 protects inode->i_nlink + +Kernel 3.2 protects inode->i_nlink from direct modification. +Filesystems may only read i_nlink directly. They shall use the +(set|clear|inc|drop)_nlink for modification. +See kernel commit a78ef704a8dd430225955f0709b22d4a6ba21deb. + +This patch adds LC_HAVE_PROTECT_I_NLINK checking and implements +set_nlink for old kernel, clear/inc/drop_nlink exists after 2.6.18 +so need not to be re-implemented. + +Signed-off-by: Liu Xuezhao <xuezhao.liu@emc.com> +Change-Id: Ie958cb308291ecc48d409a1282fed7ea3549a561 +--- + lustre/autoconf/lustre-core.m4 | 22 ++++++++++++++++++++++ + lustre/include/linux/lustre_compat25.h | 8 ++++++++ + lustre/llite/dcache.c | 4 ++-- + lustre/llite/file.c | 2 +- + lustre/llite/llite_lib.c | 4 ++-- + lustre/osd-ldiskfs/osd_handler.c | 12 ++++++------ + 6 files changed, 41 insertions(+), 11 deletions(-) + +diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 +index 420d81e..84f1678 100644 +--- a/lustre/autoconf/lustre-core.m4 ++++ b/lustre/autoconf/lustre-core.m4 +@@ -1895,6 +1895,27 @@ LB_LINUX_TRY_COMPILE([ + ]) + + # ++# 3.2 protects inode->i_nlink from direct modification ++# see kernel commit a78ef704a8dd430225955f0709b22d4a6ba21deb ++# at the same time, add set_nlink() ++# ++AC_DEFUN([LC_HAVE_PROTECT_I_NLINK], ++[AC_MSG_CHECKING([if inode->i_nlink is protected from direct modification]) ++LB_LINUX_TRY_COMPILE([ ++ #include <linux/fs.h> ++],[ ++ struct inode i; ++ i.i_nlink = 0; ++],[ ++ AC_MSG_RESULT([no]) ++],[ ++ AC_DEFINE(HAVE_PROTECT_I_NLINK, 1, ++ [inode->i_nlink is protected from direct modification]) ++ AC_MSG_RESULT([yes]) ++]) ++]) ++ ++# + # 3.3 introduces migrate_mode.h and migratepage has 4 args + # + AC_DEFUN([LC_HAVE_MIGRATE_HEADER], +@@ -2084,6 +2105,7 @@ AC_DEFUN([LC_PROG_LINUX], + + # 3.2 + LC_HAVE_VOID_MAKE_REQUEST_FN ++ LC_HAVE_PROTECT_I_NLINK + + # 3.3 + LC_HAVE_MIGRATE_HEADER +diff --git a/lustre/include/linux/lustre_compat25.h b/lustre/include/linux/lustre_compat25.h +index 2d0dd0e..7ead133 100644 +--- a/lustre/include/linux/lustre_compat25.h ++++ b/lustre/include/linux/lustre_compat25.h +@@ -839,5 +839,13 @@ static inline int ll_namei_to_lookup_intent_flag(int flag) + # define LL_MRF_RETURN(rc) RETURN(rc) + #endif + ++#include <linux/fs.h> ++#ifndef HAVE_PROTECT_I_NLINK ++static inline void set_nlink(struct inode *inode, unsigned int nlink) ++{ ++ inode->i_nlink = nlink; ++} ++#endif ++ + #endif /* __KERNEL__ */ + #endif /* _COMPAT25_H */ +diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c +index 14fb634..b507408 100644 +--- a/lustre/llite/dcache.c ++++ b/lustre/llite/dcache.c +@@ -187,7 +187,7 @@ static int ll_ddelete(HAVE_D_DELETE_CONST struct dentry *de) + /* if not ldlm lock for this inode, set i_nlink to 0 so that + * this inode can be recycled later b=20433 */ + if (de->d_inode && !find_cbdata(de->d_inode)) +- de->d_inode->i_nlink = 0; ++ clear_nlink(de->d_inode); + #endif + + if (d_lustre_invalid((struct dentry *)de)) +@@ -687,7 +687,7 @@ void ll_d_iput(struct dentry *de, struct inode *inode) + { + LASSERT(inode); + if (!find_cbdata(inode)) +- inode->i_nlink = 0; ++ clear_nlink(inode); + iput(inode); + } + +diff --git a/lustre/llite/file.c b/lustre/llite/file.c +index bf9ba2f..8840295 100644 +--- a/lustre/llite/file.c ++++ b/lustre/llite/file.c +@@ -2315,7 +2315,7 @@ ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits, + static int ll_inode_revalidate_fini(struct inode *inode, int rc) { + if (rc == -ENOENT) { /* Already unlinked. Just update nlink + * and return success */ +- inode->i_nlink = 0; ++ clear_nlink(inode); + /* This path cannot be hit for regular files unless in + * case of obscure races, so no need to to validate + * size. */ +diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c +index 7f3ac28..07efcfc 100644 +--- a/lustre/llite/llite_lib.c ++++ b/lustre/llite/llite_lib.c +@@ -1218,7 +1218,7 @@ int ll_md_setattr(struct dentry *dentry, struct md_op_data *op_data, + if (rc) { + ptlrpc_req_finished(request); + if (rc == -ENOENT) { +- inode->i_nlink = 0; ++ clear_nlink(inode); + /* Unlinked special device node? Or just a race? + * Pretend we done everything. */ + if (!S_ISREG(inode->i_mode) && +@@ -1724,7 +1724,7 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) + if (body->valid & OBD_MD_FLFLAGS) + inode->i_flags = ll_ext_to_inode_flags(body->flags); + if (body->valid & OBD_MD_FLNLINK) +- inode->i_nlink = body->nlink; ++ set_nlink(inode, body->nlink); + if (body->valid & OBD_MD_FLRDEV) + inode->i_rdev = old_decode_dev(body->rdev); + +diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c +index 1c37bd9..ec9dfb6 100644 +--- a/lustre/osd-ldiskfs/osd_handler.c ++++ b/lustre/osd-ldiskfs/osd_handler.c +@@ -1518,7 +1518,7 @@ static int osd_inode_setattr(const struct lu_env *env, + if (bits & LA_GID) + inode->i_gid = attr->la_gid; + if (bits & LA_NLINK) +- inode->i_nlink = attr->la_nlink; ++ set_nlink(inode, attr->la_nlink); + if (bits & LA_RDEV) + inode->i_rdev = attr->la_rdev; + +@@ -2076,7 +2076,7 @@ static int osd_object_destroy(const struct lu_env *env, + LASSERT(osd_inode_unlinked(inode) || + inode->i_nlink == 1); + cfs_spin_lock(&obj->oo_guard); +- inode->i_nlink = 0; ++ clear_nlink(inode); + cfs_spin_unlock(&obj->oo_guard); + inode->i_sb->s_op->dirty_inode(inode); + } else { +@@ -2283,11 +2283,11 @@ static int osd_object_ref_add(const struct lu_env *env, + * do not actually care whether this flag is set or not. + */ + cfs_spin_lock(&obj->oo_guard); +- inode->i_nlink++; ++ inc_nlink(inode); + if (S_ISDIR(inode->i_mode) && inode->i_nlink > 1) { + if (inode->i_nlink >= LDISKFS_LINK_MAX || + inode->i_nlink == 2) +- inode->i_nlink = 1; ++ set_nlink(inode, 1); + } + LASSERT(inode->i_nlink <= LDISKFS_LINK_MAX); + cfs_spin_unlock(&obj->oo_guard); +@@ -2333,12 +2333,12 @@ static int osd_object_ref_del(const struct lu_env *env, struct dt_object *dt, + + cfs_spin_lock(&obj->oo_guard); + LASSERT(inode->i_nlink > 0); +- inode->i_nlink--; ++ drop_nlink(inode); + /* If this is/was a many-subdir directory (nlink > LDISKFS_LINK_MAX) + * then the nlink count is 1. Don't let it be set to 0 or the directory + * inode will be deleted incorrectly. */ + if (S_ISDIR(inode->i_mode) && inode->i_nlink == 0) +- inode->i_nlink++; ++ inc_nlink(inode); + cfs_spin_unlock(&obj->oo_guard); + inode->i_sb->s_op->dirty_inode(inode); + LINVRNT(osd_invariant(obj)); +-- +1.7.12 + |