From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4A95CC64EAD for ; Tue, 9 Oct 2018 13:53:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 16D5C214C5 for ; Tue, 9 Oct 2018 13:53:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 16D5C214C5 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727353AbeJIVKk (ORCPT ); Tue, 9 Oct 2018 17:10:40 -0400 Received: from szxga04-in.huawei.com ([45.249.212.190]:13607 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726434AbeJIVKj (ORCPT ); Tue, 9 Oct 2018 17:10:39 -0400 Received: from DGGEMS408-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id DDDB2C1F9E6B6; Tue, 9 Oct 2018 21:53:30 +0800 (CST) Received: from localhost.localdomain (10.175.124.28) by smtp.huawei.com (10.3.19.208) with Microsoft SMTP Server (TLS) id 14.3.399.0; Tue, 9 Oct 2018 21:53:23 +0800 From: Gao Xiang To: Greg Kroah-Hartman , CC: LKML , , "Chao Yu" , Miao Xie , , Gao Xiang Subject: [PATCH] staging: erofs: harden inode lookup for 32-bit platforms Date: Tue, 9 Oct 2018 22:07:13 +0800 Message-ID: <20181009140713.29629-1-gaoxiang25@huawei.com> X-Mailer: git-send-email 2.14.4 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.175.124.28] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch introduces inode hash function, test and set callbacks, and iget5_locked to find the right inode for 32-bit platforms. Reviewed-by: Chao Yu Signed-off-by: Gao Xiang --- The patch has been previewed in the linux-erofs mailing list, submit to the staging mailing list for linux-4.20. Thanks, Gao Xiang drivers/staging/erofs/inode.c | 37 ++++++++++++++++++++++++++++++++++++- drivers/staging/erofs/internal.h | 9 +++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/staging/erofs/inode.c b/drivers/staging/erofs/inode.c index da8693a7c3d3..04c61a9d7b76 100644 --- a/drivers/staging/erofs/inode.c +++ b/drivers/staging/erofs/inode.c @@ -232,10 +232,45 @@ static int fill_inode(struct inode *inode, int isdir) return err; } +/* + * erofs nid is 64bits, but i_ino is 'unsigned long', therefore + * we should do more for 32-bit platform to find the right inode. + */ +#if BITS_PER_LONG == 32 +static int erofs_ilookup_test_actor(struct inode *inode, void *opaque) +{ + const erofs_nid_t nid = *(erofs_nid_t *)opaque; + + return EROFS_V(inode)->nid == nid; +} + +static int erofs_iget_set_actor(struct inode *inode, void *opaque) +{ + const erofs_nid_t nid = *(erofs_nid_t *)opaque; + + inode->i_ino = erofs_inode_hash(nid); + return 0; +} +#endif + +static inline struct inode *erofs_iget_locked(struct super_block *sb, + erofs_nid_t nid) +{ + const unsigned long hashval = erofs_inode_hash(nid); + +#if BITS_PER_LONG >= 64 + /* it is safe to use iget_locked for >= 64-bit platform */ + return iget_locked(sb, hashval); +#else + return iget5_locked(sb, hashval, erofs_ilookup_test_actor, + erofs_iget_set_actor, &nid); +#endif +} + struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid, bool isdir) { - struct inode *inode = iget_locked(sb, nid); + struct inode *inode = erofs_iget_locked(sb, nid); if (unlikely(inode == NULL)) return ERR_PTR(-ENOMEM); diff --git a/drivers/staging/erofs/internal.h b/drivers/staging/erofs/internal.h index 5096b27bcf0d..57575c7f5635 100644 --- a/drivers/staging/erofs/internal.h +++ b/drivers/staging/erofs/internal.h @@ -517,6 +517,15 @@ erofs_get_inline_page(struct inode *inode, } /* inode.c */ +static inline unsigned long erofs_inode_hash(erofs_nid_t nid) +{ +#if BITS_PER_LONG == 32 + return (nid >> 32) ^ (nid & 0xffffffff); +#else + return nid; +#endif +} + extern struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid, bool dir); -- 2.14.4