From patchwork Sun Oct 14 18:58:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Simmons X-Patchwork-Id: 10640839 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C2A4F1508 for ; Sun, 14 Oct 2018 18:59:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 737DC2951D for ; Sun, 14 Oct 2018 18:59:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 679FE29542; Sun, 14 Oct 2018 18:59:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from pdx1-mailman02.dreamhost.com (pdx1-mailman02.dreamhost.com [64.90.62.194]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EFE1F2951D for ; Sun, 14 Oct 2018 18:59:17 +0000 (UTC) Received: from pdx1-mailman02.dreamhost.com (localhost [IPv6:::1]) by pdx1-mailman02.dreamhost.com (Postfix) with ESMTP id EBCC421FC1B; Sun, 14 Oct 2018 11:58:56 -0700 (PDT) X-Original-To: lustre-devel@lists.lustre.org Delivered-To: lustre-devel-lustre.org@pdx1-mailman02.dreamhost.com Received: from smtp3.ccs.ornl.gov (smtp3.ccs.ornl.gov [160.91.203.39]) by pdx1-mailman02.dreamhost.com (Postfix) with ESMTP id 5EB8721F6E1 for ; Sun, 14 Oct 2018 11:58:26 -0700 (PDT) Received: from star.ccs.ornl.gov (star.ccs.ornl.gov [160.91.202.134]) by smtp3.ccs.ornl.gov (Postfix) with ESMTP id 4CBE82243; Sun, 14 Oct 2018 14:58:21 -0400 (EDT) Received: by star.ccs.ornl.gov (Postfix, from userid 2004) id 4B6962AC; Sun, 14 Oct 2018 14:58:21 -0400 (EDT) From: James Simmons To: Andreas Dilger , Oleg Drokin , NeilBrown Date: Sun, 14 Oct 2018 14:58:05 -0400 Message-Id: <1539543498-29105-16-git-send-email-jsimmons@infradead.org> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1539543498-29105-1-git-send-email-jsimmons@infradead.org> References: <1539543498-29105-1-git-send-email-jsimmons@infradead.org> Subject: [lustre-devel] [PATCH 15/28] lustre: llite: fix for stat under kthread and X86_X32 X-BeenThere: lustre-devel@lists.lustre.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "For discussing Lustre software development." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lustre Development List MIME-Version: 1.0 Errors-To: lustre-devel-bounces@lists.lustre.org Sender: "lustre-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Frank Zago Under the following conditions, ll_getattr will flatten the inode number when it shouldn't: - the X86_X32 architecture is defined CONFIG_X86_X32, and not even used, - ll_getattr is called from a kernel thread (though vfs_getattr for instance.) This has the result that inode numbers are different whether the same file is stat'ed from a kernel thread, or from a syscall. For instance, 4198401 vs. 144115205272502273. ll_getattr calls ll_need_32bit_api to determine whether the task is 32 bits. When the combination is kthread+X86_X32, that function returns that the task is 32 bits, which is incorrect, as the kernel is 64 bits. The solution is to check whether the call is from a kernel thread (which is 64 bits) and act consequently. Signed-off-by: Frank Zago WC-bug-id: https://jira.whamcloud.com/browse/LU-9468 Reviewed-on: https://review.whamcloud.com/26992 Reviewed-by: Andreas Dilger Reviewed-by: Dmitry Eremin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/llite/dir.c | 6 +++--- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 2 +- .../staging/lustre/lustre/llite/llite_internal.h | 22 +++++++++++++++++----- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 231b351..19c5e9c 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -202,7 +202,7 @@ int ll_dir_read(struct inode *inode, __u64 *ppos, struct md_op_data *op_data, { struct ll_sb_info *sbi = ll_i2sbi(inode); __u64 pos = *ppos; - int is_api32 = ll_need_32bit_api(sbi); + bool is_api32 = ll_need_32bit_api(sbi); int is_hash64 = sbi->ll_flags & LL_SBI_64BIT_HASH; struct page *page; bool done = false; @@ -296,7 +296,7 @@ static int ll_readdir(struct file *filp, struct dir_context *ctx) struct ll_sb_info *sbi = ll_i2sbi(inode); __u64 pos = lfd ? lfd->lfd_pos : 0; int hash64 = sbi->ll_flags & LL_SBI_64BIT_HASH; - int api32 = ll_need_32bit_api(sbi); + bool api32 = ll_need_32bit_api(sbi); struct md_op_data *op_data; int rc; @@ -1674,7 +1674,7 @@ static loff_t ll_dir_seek(struct file *file, loff_t offset, int origin) struct inode *inode = file->f_mapping->host; struct ll_file_data *fd = LUSTRE_FPRIVATE(file); struct ll_sb_info *sbi = ll_i2sbi(inode); - int api32 = ll_need_32bit_api(sbi); + bool api32 = ll_need_32bit_api(sbi); loff_t ret = -EINVAL; switch (origin) { diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 30f17ea..20a3c74 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -267,7 +267,7 @@ void cl_inode_fini(struct inode *inode) /** * build inode number from passed @fid */ -__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) +u64 cl_fid_build_ino(const struct lu_fid *fid, bool api32) { if (BITS_PER_LONG == 32 || api32) return fid_flatten32(fid); diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index dcb2fed..796a8ae 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -651,13 +651,25 @@ static inline struct inode *ll_info2i(struct ll_inode_info *lli) __u32 ll_i2suppgid(struct inode *i); void ll_i2gids(__u32 *suppgids, struct inode *i1, struct inode *i2); -static inline int ll_need_32bit_api(struct ll_sb_info *sbi) +static inline bool ll_need_32bit_api(struct ll_sb_info *sbi) { #if BITS_PER_LONG == 32 - return 1; + return true; #elif defined(CONFIG_COMPAT) - return unlikely(in_compat_syscall() || - (sbi->ll_flags & LL_SBI_32BIT_API)); + if (unlikely(sbi->ll_flags & LL_SBI_32BIT_API)) + return true; + +#ifdef CONFIG_X86_X32 + /* in_compat_syscall() returns true when called from a kthread + * and CONFIG_X86_X32 is enabled, which is wrong. So check + * whether the caller comes from a syscall (ie. not a kthread) + * before calling in_compat_syscall(). + */ + if (current->flags & PF_KTHREAD) + return false; +#endif + + return unlikely(in_compat_syscall()); #else return unlikely(sbi->ll_flags & LL_SBI_32BIT_API); #endif @@ -1353,7 +1365,7 @@ int cl_setattr_ost(struct cl_object *obj, const struct iattr *attr, int cl_file_inode_init(struct inode *inode, struct lustre_md *md); void cl_inode_fini(struct inode *inode); -__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32); +u64 cl_fid_build_ino(const struct lu_fid *fid, bool api32); __u32 cl_fid_build_gen(const struct lu_fid *fid); #endif /* LLITE_INTERNAL_H */