From patchwork Mon Jan 25 22:55:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruan Shiyang X-Patchwork-Id: 12044655 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=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,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 B8206C433E0 for ; Mon, 25 Jan 2021 22:55:39 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 60DEC221FD for ; Mon, 25 Jan 2021 22:55:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 60DEC221FD Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=cn.fujitsu.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvdimm-bounces@lists.01.org Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id A6FF9100EBBD8; Mon, 25 Jan 2021 14:55:38 -0800 (PST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=183.91.158.132; helo=heian.cn.fujitsu.com; envelope-from=ruansy.fnst@cn.fujitsu.com; receiver= Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by ml01.01.org (Postfix) with ESMTP id 9CEB7100ED498 for ; Mon, 25 Jan 2021 14:55:35 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.79,374,1602518400"; d="scan'208";a="103820569" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 26 Jan 2021 06:55:32 +0800 Received: from G08CNEXMBPEKD06.g08.fujitsu.local (unknown [10.167.33.206]) by cn.fujitsu.com (Postfix) with ESMTP id 455A54CE6782; Tue, 26 Jan 2021 06:55:32 +0800 (CST) Received: from G08CNEXJMPEKD02.g08.fujitsu.local (10.167.33.202) by G08CNEXMBPEKD06.g08.fujitsu.local (10.167.33.206) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:32 +0800 Received: from G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.200) by G08CNEXJMPEKD02.g08.fujitsu.local (10.167.33.202) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:30 +0800 Received: from irides.mr.mr.mr (10.167.225.141) by G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.209) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 26 Jan 2021 06:55:30 +0800 From: Shiyang Ruan To: , , , Subject: [PATCH v2 01/10] pagemap: Introduce ->memory_failure() Date: Tue, 26 Jan 2021 06:55:17 +0800 Message-ID: <20210125225526.1048877-2-ruansy.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> References: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-yoursite-MailScanner-ID: 455A54CE6782.AA1D2 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: ruansy.fnst@cn.fujitsu.com Message-ID-Hash: Z24GP5ZN2W67DD6674I7NJJ5JHHBNGAQ X-Message-ID-Hash: Z24GP5ZN2W67DD6674I7NJJ5JHHBNGAQ X-MailFrom: ruansy.fnst@cn.fujitsu.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: linux-fsdevel@vger.kernel.org, linux-raid@vger.kernel.org, darrick.wong@oracle.com, david@fromorbit.com, hch@lst.de, song@kernel.org, rgoldwyn@suse.de, qi.fuli@fujitsu.com, y-goto@fujitsu.com X-Mailman-Version: 3.1.1 Precedence: list List-Id: "Linux-nvdimm developer list." Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: When memory-failure occurs, we call this function which is implemented by each kind of devices. For the fsdax case, pmem device driver implements it. Pmem device driver will find out the block device where the error page locates in, and try to get the filesystem on this block device. And finally call filesystem handler to deal with the error. The filesystem will try to recover the corrupted data if possiable. Signed-off-by: Shiyang Ruan --- include/linux/memremap.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/linux/memremap.h b/include/linux/memremap.h index 79c49e7f5c30..0bcf2b1e20bd 100644 --- a/include/linux/memremap.h +++ b/include/linux/memremap.h @@ -87,6 +87,14 @@ struct dev_pagemap_ops { * the page back to a CPU accessible page. */ vm_fault_t (*migrate_to_ram)(struct vm_fault *vmf); + + /* + * Handle the memory failure happens on one page. Notify the processes + * who are using this page, and try to recover the data on this page + * if necessary. + */ + int (*memory_failure)(struct dev_pagemap *pgmap, unsigned long pfn, + int flags); }; #define PGMAP_ALTMAP_VALID (1 << 0) From patchwork Mon Jan 25 22:55:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruan Shiyang X-Patchwork-Id: 12044657 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=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,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 11F90C43381 for ; Mon, 25 Jan 2021 22:55:41 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C0BFB2220F for ; Mon, 25 Jan 2021 22:55:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C0BFB2220F Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=cn.fujitsu.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvdimm-bounces@lists.01.org Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id BE5D3100EBBDA; Mon, 25 Jan 2021 14:55:39 -0800 (PST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=183.91.158.132; helo=heian.cn.fujitsu.com; envelope-from=ruansy.fnst@cn.fujitsu.com; receiver= Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by ml01.01.org (Postfix) with ESMTP id 5604E100ED498 for ; Mon, 25 Jan 2021 14:55:36 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.79,374,1602518400"; d="scan'208";a="103820570" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 26 Jan 2021 06:55:32 +0800 Received: from G08CNEXMBPEKD05.g08.fujitsu.local (unknown [10.167.33.204]) by cn.fujitsu.com (Postfix) with ESMTP id BB90D4CE678B; Tue, 26 Jan 2021 06:55:32 +0800 (CST) Received: from G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.200) by G08CNEXMBPEKD05.g08.fujitsu.local (10.167.33.204) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:33 +0800 Received: from irides.mr.mr.mr (10.167.225.141) by G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.209) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 26 Jan 2021 06:55:31 +0800 From: Shiyang Ruan To: , , , Subject: [PATCH v2 02/10] blk: Introduce ->corrupted_range() for block device Date: Tue, 26 Jan 2021 06:55:18 +0800 Message-ID: <20210125225526.1048877-3-ruansy.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> References: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-yoursite-MailScanner-ID: BB90D4CE678B.AC883 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: ruansy.fnst@cn.fujitsu.com Message-ID-Hash: K4KVZAYQH67VENQCDINRJR4M6CHQSLYX X-Message-ID-Hash: K4KVZAYQH67VENQCDINRJR4M6CHQSLYX X-MailFrom: ruansy.fnst@cn.fujitsu.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: linux-fsdevel@vger.kernel.org, linux-raid@vger.kernel.org, darrick.wong@oracle.com, david@fromorbit.com, hch@lst.de, song@kernel.org, rgoldwyn@suse.de, qi.fuli@fujitsu.com, y-goto@fujitsu.com X-Mailman-Version: 3.1.1 Precedence: list List-Id: "Linux-nvdimm developer list." Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: In fsdax mode, the memory failure happens on block device. So, it is needed to introduce an interface for block devices. Each kind of block device can handle the memory failure in ther own ways. Signed-off-by: Shiyang Ruan --- include/linux/blkdev.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index f94ee3089e01..e0f5585aa06f 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1867,6 +1867,8 @@ struct block_device_operations { int (*report_zones)(struct gendisk *, sector_t sector, unsigned int nr_zones, report_zones_cb cb, void *data); char *(*devnode)(struct gendisk *disk, umode_t *mode); + int (*corrupted_range)(struct gendisk *disk, struct block_device *bdev, + loff_t offset, size_t len, void *data); struct module *owner; const struct pr_ops *pr_ops; }; From patchwork Mon Jan 25 22:55:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruan Shiyang X-Patchwork-Id: 12044665 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=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,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 84022C4332B for ; Mon, 25 Jan 2021 22:55:48 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 471C4224BE for ; Mon, 25 Jan 2021 22:55:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 471C4224BE Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=cn.fujitsu.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvdimm-bounces@lists.01.org Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 76960100EBB73; Mon, 25 Jan 2021 14:55:45 -0800 (PST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=183.91.158.132; helo=heian.cn.fujitsu.com; envelope-from=ruansy.fnst@cn.fujitsu.com; receiver= Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by ml01.01.org (Postfix) with ESMTP id 7873B100EBBDD for ; Mon, 25 Jan 2021 14:55:42 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.79,374,1602518400"; d="scan'208";a="103820576" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 26 Jan 2021 06:55:38 +0800 Received: from G08CNEXMBPEKD04.g08.fujitsu.local (unknown [10.167.33.201]) by cn.fujitsu.com (Postfix) with ESMTP id 32B4748990D2; Tue, 26 Jan 2021 06:55:34 +0800 (CST) Received: from G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.200) by G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:32 +0800 Received: from irides.mr.mr.mr (10.167.225.141) by G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.209) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 26 Jan 2021 06:55:32 +0800 From: Shiyang Ruan To: , , , Subject: [PATCH v2 03/10] fs: Introduce ->corrupted_range() for superblock Date: Tue, 26 Jan 2021 06:55:19 +0800 Message-ID: <20210125225526.1048877-4-ruansy.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> References: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-yoursite-MailScanner-ID: 32B4748990D2.A8752 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: ruansy.fnst@cn.fujitsu.com Message-ID-Hash: D4JZ53QBR4CQCKZTF4C2EDICUSC5VHBE X-Message-ID-Hash: D4JZ53QBR4CQCKZTF4C2EDICUSC5VHBE X-MailFrom: ruansy.fnst@cn.fujitsu.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: linux-fsdevel@vger.kernel.org, linux-raid@vger.kernel.org, darrick.wong@oracle.com, david@fromorbit.com, hch@lst.de, song@kernel.org, rgoldwyn@suse.de, qi.fuli@fujitsu.com, y-goto@fujitsu.com X-Mailman-Version: 3.1.1 Precedence: list List-Id: "Linux-nvdimm developer list." Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Memory failure occurs in fsdax mode will finally be handled in filesystem. We introduce this interface to find out files or metadata affected by the corrupted range, and try to recover the corrupted data if possiable. Signed-off-by: Shiyang Ruan --- include/linux/fs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/fs.h b/include/linux/fs.h index fd47deea7c17..4cc9ff9caa87 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1963,6 +1963,8 @@ struct super_operations { struct shrink_control *); long (*free_cached_objects)(struct super_block *, struct shrink_control *); + int (*corrupted_range)(struct super_block *sb, struct block_device *bdev, + loff_t offset, size_t len, void *data); }; /* From patchwork Mon Jan 25 22:55:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruan Shiyang X-Patchwork-Id: 12044661 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=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,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 2A474C433E0 for ; Mon, 25 Jan 2021 22:55:46 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D6A4822460 for ; Mon, 25 Jan 2021 22:55:45 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D6A4822460 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=cn.fujitsu.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvdimm-bounces@lists.01.org Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 4262F100EBB6F; Mon, 25 Jan 2021 14:55:44 -0800 (PST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=183.91.158.132; helo=heian.cn.fujitsu.com; envelope-from=ruansy.fnst@cn.fujitsu.com; receiver= Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by ml01.01.org (Postfix) with ESMTP id 64A01100EBBDB for ; Mon, 25 Jan 2021 14:55:41 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.79,374,1602518400"; d="scan'208";a="103820572" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 26 Jan 2021 06:55:38 +0800 Received: from G08CNEXMBPEKD05.g08.fujitsu.local (unknown [10.167.33.204]) by cn.fujitsu.com (Postfix) with ESMTP id D0E804CE6014; Tue, 26 Jan 2021 06:55:35 +0800 (CST) Received: from G08CNEXJMPEKD02.g08.fujitsu.local (10.167.33.202) by G08CNEXMBPEKD05.g08.fujitsu.local (10.167.33.204) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:37 +0800 Received: from G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.200) by G08CNEXJMPEKD02.g08.fujitsu.local (10.167.33.202) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:34 +0800 Received: from irides.mr.mr.mr (10.167.225.141) by G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.209) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 26 Jan 2021 06:55:33 +0800 From: Shiyang Ruan To: , , , Subject: [PATCH v2 04/10] mm, fsdax: Refactor memory-failure handler for dax mapping Date: Tue, 26 Jan 2021 06:55:20 +0800 Message-ID: <20210125225526.1048877-5-ruansy.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> References: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-yoursite-MailScanner-ID: D0E804CE6014.AC670 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: ruansy.fnst@cn.fujitsu.com Message-ID-Hash: UVGG3WYE3OBLD4H3V7Y4KOFYF3I5BM4Q X-Message-ID-Hash: UVGG3WYE3OBLD4H3V7Y4KOFYF3I5BM4Q X-MailFrom: ruansy.fnst@cn.fujitsu.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: linux-fsdevel@vger.kernel.org, linux-raid@vger.kernel.org, darrick.wong@oracle.com, david@fromorbit.com, hch@lst.de, song@kernel.org, rgoldwyn@suse.de, qi.fuli@fujitsu.com, y-goto@fujitsu.com X-Mailman-Version: 3.1.1 Precedence: list List-Id: "Linux-nvdimm developer list." Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: The current memory_failure_dev_pagemap() can only handle single-mapped dax page for fsdax mode. The dax page could be mapped by multiple files and offsets if we let reflink feature & fsdax mode work together. So, we refactor current implementation to support handle memory failure on each file and offset. Signed-off-by: Shiyang Ruan --- fs/dax.c | 21 ++++++++++ include/linux/dax.h | 1 + include/linux/mm.h | 9 +++++ mm/memory-failure.c | 98 ++++++++++++++++++++++++++++++++++----------- 4 files changed, 105 insertions(+), 24 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index 26d5dcd2d69e..c64c3a0e76a6 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -378,6 +378,27 @@ static struct page *dax_busy_page(void *entry) return NULL; } +/* + * dax_load_pfn - Load pfn of the DAX entry corresponding to a page + * @mapping: The file whose entry we want to load + * @index: The offset where the DAX entry located in + * + * Return: pfn of the DAX entry + */ +unsigned long dax_load_pfn(struct address_space *mapping, unsigned long index) +{ + XA_STATE(xas, &mapping->i_pages, index); + void *entry; + unsigned long pfn; + + xas_lock_irq(&xas); + entry = xas_load(&xas); + pfn = dax_to_pfn(entry); + xas_unlock_irq(&xas); + + return pfn; +} + /* * dax_lock_mapping_entry - Lock the DAX entry corresponding to a page * @page: The page whose entry we want to lock diff --git a/include/linux/dax.h b/include/linux/dax.h index b52f084aa643..89e56ceeffc7 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -150,6 +150,7 @@ int dax_writeback_mapping_range(struct address_space *mapping, struct page *dax_layout_busy_page(struct address_space *mapping); struct page *dax_layout_busy_page_range(struct address_space *mapping, loff_t start, loff_t end); +unsigned long dax_load_pfn(struct address_space *mapping, unsigned long index); dax_entry_t dax_lock_page(struct page *page); void dax_unlock_page(struct page *page, dax_entry_t cookie); #else diff --git a/include/linux/mm.h b/include/linux/mm.h index ecdf8a8cd6ae..ab52bc633d84 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1157,6 +1157,14 @@ static inline bool is_device_private_page(const struct page *page) page->pgmap->type == MEMORY_DEVICE_PRIVATE; } +static inline bool is_device_fsdax_page(const struct page *page) +{ + return IS_ENABLED(CONFIG_DEV_PAGEMAP_OPS) && + IS_ENABLED(CONFIG_FS_DAX) && + is_zone_device_page(page) && + page->pgmap->type == MEMORY_DEVICE_FS_DAX; +} + static inline bool is_pci_p2pdma_page(const struct page *page) { return IS_ENABLED(CONFIG_DEV_PAGEMAP_OPS) && @@ -3045,6 +3053,7 @@ enum mf_flags { MF_MUST_KILL = 1 << 2, MF_SOFT_OFFLINE = 1 << 3, }; +extern int mf_dax_mapping_kill_procs(struct address_space *mapping, pgoff_t index, int flags); extern int memory_failure(unsigned long pfn, int flags); extern void memory_failure_queue(unsigned long pfn, int flags); extern void memory_failure_queue_kick(int cpu); diff --git a/mm/memory-failure.c b/mm/memory-failure.c index e9481632fcd1..158fe0c8e602 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -56,6 +56,7 @@ #include #include #include +#include #include "internal.h" #include "ras/ras_event.h" @@ -120,6 +121,13 @@ static int hwpoison_filter_dev(struct page *p) if (PageSlab(p)) return -EINVAL; + if (pfn_valid(page_to_pfn(p))) { + if (is_device_fsdax_page(p)) + return 0; + else + return -EINVAL; + } + mapping = page_mapping(p); if (mapping == NULL || mapping->host == NULL) return -EINVAL; @@ -286,10 +294,9 @@ void shake_page(struct page *p, int access) } EXPORT_SYMBOL_GPL(shake_page); -static unsigned long dev_pagemap_mapping_shift(struct page *page, - struct vm_area_struct *vma) +static unsigned long dev_pagemap_mapping_shift(struct vm_area_struct *vma, + unsigned long address) { - unsigned long address = vma_address(page, vma); pgd_t *pgd; p4d_t *p4d; pud_t *pud; @@ -329,9 +336,8 @@ static unsigned long dev_pagemap_mapping_shift(struct page *page, * Schedule a process for later kill. * Uses GFP_ATOMIC allocations to avoid potential recursions in the VM. */ -static void add_to_kill(struct task_struct *tsk, struct page *p, - struct vm_area_struct *vma, - struct list_head *to_kill) +static void add_to_kill(struct task_struct *tsk, struct page *p, pgoff_t pgoff, + struct vm_area_struct *vma, struct list_head *to_kill) { struct to_kill *tk; @@ -342,9 +348,12 @@ static void add_to_kill(struct task_struct *tsk, struct page *p, } tk->addr = page_address_in_vma(p, vma); - if (is_zone_device_page(p)) - tk->size_shift = dev_pagemap_mapping_shift(p, vma); - else + if (is_zone_device_page(p)) { + if (is_device_fsdax_page(p)) + tk->addr = vma->vm_start + + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); + tk->size_shift = dev_pagemap_mapping_shift(vma, tk->addr); + } else tk->size_shift = page_shift(compound_head(p)); /* @@ -492,7 +501,7 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill, if (!page_mapped_in_vma(page, vma)) continue; if (vma->vm_mm == t->mm) - add_to_kill(t, page, vma, to_kill); + add_to_kill(t, page, 0, vma, to_kill); } } read_unlock(&tasklist_lock); @@ -502,24 +511,19 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill, /* * Collect processes when the error hit a file mapped page. */ -static void collect_procs_file(struct page *page, struct list_head *to_kill, - int force_early) +static void collect_procs_file(struct page *page, struct address_space *mapping, + pgoff_t pgoff, struct list_head *to_kill, int force_early) { struct vm_area_struct *vma; struct task_struct *tsk; - struct address_space *mapping = page->mapping; - pgoff_t pgoff; i_mmap_lock_read(mapping); read_lock(&tasklist_lock); - pgoff = page_to_pgoff(page); for_each_process(tsk) { struct task_struct *t = task_early_kill(tsk, force_early); - if (!t) continue; - vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, - pgoff) { + vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) { /* * Send early kill signal to tasks where a vma covers * the page but the corrupted page is not necessarily @@ -528,7 +532,7 @@ static void collect_procs_file(struct page *page, struct list_head *to_kill, * to be informed of all such data corruptions. */ if (vma->vm_mm == t->mm) - add_to_kill(t, page, vma, to_kill); + add_to_kill(t, page, pgoff, vma, to_kill); } } read_unlock(&tasklist_lock); @@ -547,7 +551,8 @@ static void collect_procs(struct page *page, struct list_head *tokill, if (PageAnon(page)) collect_procs_anon(page, tokill, force_early); else - collect_procs_file(page, tokill, force_early); + collect_procs_file(page, page_mapping(page), page_to_pgoff(page), + tokill, force_early); } static const char *action_name[] = { @@ -1214,6 +1219,50 @@ static int try_to_split_thp_page(struct page *page, const char *msg) return 0; } +int mf_dax_mapping_kill_procs(struct address_space *mapping, pgoff_t index, int flags) +{ + const bool unmap_success = true; + unsigned long pfn, size = 0; + struct to_kill *tk; + LIST_HEAD(to_kill); + int rc = -EBUSY; + loff_t start; + + /* load the pfn of the dax mapping file */ + pfn = dax_load_pfn(mapping, index); + if (!pfn) + return rc; + /* + * Unlike System-RAM there is no possibility to swap in a + * different physical page at a given virtual address, so all + * userspace consumption of ZONE_DEVICE memory necessitates + * SIGBUS (i.e. MF_MUST_KILL) + */ + flags |= MF_ACTION_REQUIRED | MF_MUST_KILL; + collect_procs_file(pfn_to_page(pfn), mapping, index, &to_kill, + flags & MF_ACTION_REQUIRED); + + list_for_each_entry(tk, &to_kill, nd) + if (tk->size_shift) + size = max(size, 1UL << tk->size_shift); + if (size) { + /* + * Unmap the largest mapping to avoid breaking up + * device-dax mappings which are constant size. The + * actual size of the mapping being torn down is + * communicated in siginfo, see kill_proc() + */ + start = (index << PAGE_SHIFT) & ~(size - 1); + unmap_mapping_range(mapping, start, start + size, 0); + } + + kill_procs(&to_kill, flags & MF_MUST_KILL, !unmap_success, + pfn, flags); + rc = 0; + return rc; +} +EXPORT_SYMBOL_GPL(mf_dax_mapping_kill_procs); + static int memory_failure_hugetlb(unsigned long pfn, int flags) { struct page *p = pfn_to_page(pfn); @@ -1297,7 +1346,7 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags, const bool unmap_success = true; unsigned long size = 0; struct to_kill *tk; - LIST_HEAD(tokill); + LIST_HEAD(to_kill); int rc = -EBUSY; loff_t start; dax_entry_t cookie; @@ -1345,9 +1394,10 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags, * SIGBUS (i.e. MF_MUST_KILL) */ flags |= MF_ACTION_REQUIRED | MF_MUST_KILL; - collect_procs(page, &tokill, flags & MF_ACTION_REQUIRED); + collect_procs_file(page, page->mapping, page->index, &to_kill, + flags & MF_ACTION_REQUIRED); - list_for_each_entry(tk, &tokill, nd) + list_for_each_entry(tk, &to_kill, nd) if (tk->size_shift) size = max(size, 1UL << tk->size_shift); if (size) { @@ -1360,7 +1410,7 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags, start = (page->index << PAGE_SHIFT) & ~(size - 1); unmap_mapping_range(page->mapping, start, start + size, 0); } - kill_procs(&tokill, flags & MF_MUST_KILL, !unmap_success, pfn, flags); + kill_procs(&to_kill, flags & MF_MUST_KILL, !unmap_success, pfn, flags); rc = 0; unlock: dax_unlock_page(page, cookie); From patchwork Mon Jan 25 22:55:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruan Shiyang X-Patchwork-Id: 12044663 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=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,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 9D1A4C433E9 for ; Mon, 25 Jan 2021 22:55:47 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 516F9227BF for ; Mon, 25 Jan 2021 22:55:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 516F9227BF Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=cn.fujitsu.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvdimm-bounces@lists.01.org Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 59D64100EBBDD; Mon, 25 Jan 2021 14:55:45 -0800 (PST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=183.91.158.132; helo=heian.cn.fujitsu.com; envelope-from=ruansy.fnst@cn.fujitsu.com; receiver= Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by ml01.01.org (Postfix) with ESMTP id 98D56100EBBDD for ; Mon, 25 Jan 2021 14:55:41 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.79,374,1602518400"; d="scan'208";a="103820574" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 26 Jan 2021 06:55:38 +0800 Received: from G08CNEXMBPEKD05.g08.fujitsu.local (unknown [10.167.33.204]) by cn.fujitsu.com (Postfix) with ESMTP id 5E4BE4CE6781; Tue, 26 Jan 2021 06:55:36 +0800 (CST) Received: from G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.200) by G08CNEXMBPEKD05.g08.fujitsu.local (10.167.33.204) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:37 +0800 Received: from irides.mr.mr.mr (10.167.225.141) by G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.209) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 26 Jan 2021 06:55:34 +0800 From: Shiyang Ruan To: , , , Subject: [PATCH v2 05/10] mm, pmem: Implement ->memory_failure() in pmem driver Date: Tue, 26 Jan 2021 06:55:21 +0800 Message-ID: <20210125225526.1048877-6-ruansy.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> References: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-yoursite-MailScanner-ID: 5E4BE4CE6781.AB943 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: ruansy.fnst@cn.fujitsu.com Message-ID-Hash: LRE6HR2WTYWIQDGJF7PXGNFQONMRIN3B X-Message-ID-Hash: LRE6HR2WTYWIQDGJF7PXGNFQONMRIN3B X-MailFrom: ruansy.fnst@cn.fujitsu.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: linux-fsdevel@vger.kernel.org, linux-raid@vger.kernel.org, darrick.wong@oracle.com, david@fromorbit.com, hch@lst.de, song@kernel.org, rgoldwyn@suse.de, qi.fuli@fujitsu.com, y-goto@fujitsu.com X-Mailman-Version: 3.1.1 Precedence: list List-Id: "Linux-nvdimm developer list." Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Call the ->memory_failure() which is implemented by pmem driver, in order to finally notify filesystem to handle the corrupted data. The handler which collects and kills processes are moved into mf_dax_mapping_kill_procs(), which will be called by filesystem. Keep the old handler in order to roll back if driver/device/filesystem does not support ->memory_failure()/->corrupted_range(). Signed-off-by: Shiyang Ruan --- drivers/nvdimm/pmem.c | 25 +++++++++++ mm/memory-failure.c | 102 +++++++++++++++++++++++++----------------- 2 files changed, 86 insertions(+), 41 deletions(-) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 875076b0ea6c..c9e4fb38f94a 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -363,9 +363,34 @@ static void pmem_release_disk(void *__pmem) put_disk(pmem->disk); } +static int pmem_pagemap_memory_failure(struct dev_pagemap *pgmap, + unsigned long pfn, int flags) +{ + struct pmem_device *pdev; + struct gendisk *disk; + loff_t disk_offset; + int rc = 0; + unsigned long size = page_size(pfn_to_page(pfn)); + + pdev = container_of(pgmap, struct pmem_device, pgmap); + disk = pdev->disk; + if (!disk) + return -ENXIO; + + disk_offset = PFN_PHYS(pfn) - pdev->phys_addr - pdev->data_offset; + if (disk->fops->corrupted_range) { + rc = disk->fops->corrupted_range(disk, NULL, disk_offset, size, &flags); + if (rc == -ENODEV) + rc = -ENXIO; + } else + rc = -EOPNOTSUPP; + return rc; +} + static const struct dev_pagemap_ops fsdax_pagemap_ops = { .kill = pmem_pagemap_kill, .cleanup = pmem_pagemap_cleanup, + .memory_failure = pmem_pagemap_memory_failure, }; static int pmem_attach_disk(struct device *dev, diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 158fe0c8e602..670e29cd263e 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1219,6 +1219,54 @@ static int try_to_split_thp_page(struct page *page, const char *msg) return 0; } +int mf_generic_kill_procs(unsigned long long pfn, int flags) +{ + struct page *page = pfn_to_page(pfn); + const bool unmap_success = true; + unsigned long size = 0; + struct to_kill *tk; + LIST_HEAD(to_kill); + loff_t start; + dax_entry_t cookie; + + /* + * Prevent the inode from being freed while we are interrogating + * the address_space, typically this would be handled by + * lock_page(), but dax pages do not use the page lock. This + * also prevents changes to the mapping of this pfn until + * poison signaling is complete. + */ + cookie = dax_lock_page(page); + if (!cookie) + return -EBUSY; + /* + * Unlike System-RAM there is no possibility to swap in a + * different physical page at a given virtual address, so all + * userspace consumption of ZONE_DEVICE memory necessitates + * SIGBUS (i.e. MF_MUST_KILL) + */ + flags |= MF_ACTION_REQUIRED | MF_MUST_KILL; + collect_procs(page, &to_kill, flags & MF_ACTION_REQUIRED); + + list_for_each_entry(tk, &to_kill, nd) + if (tk->size_shift) + size = max(size, 1UL << tk->size_shift); + if (size) { + /* + * Unmap the largest mapping to avoid breaking up + * device-dax mappings which are constant size. The + * actual size of the mapping being torn down is + * communicated in siginfo, see kill_proc() + */ + start = (page->index << PAGE_SHIFT) & ~(size - 1); + unmap_mapping_range(page->mapping, start, start + size, 0); + } + kill_procs(&to_kill, flags & MF_MUST_KILL, !unmap_success, pfn, flags); + + dax_unlock_page(page, cookie); + return 0; +} + int mf_dax_mapping_kill_procs(struct address_space *mapping, pgoff_t index, int flags) { const bool unmap_success = true; @@ -1343,13 +1391,7 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags, struct dev_pagemap *pgmap) { struct page *page = pfn_to_page(pfn); - const bool unmap_success = true; - unsigned long size = 0; - struct to_kill *tk; - LIST_HEAD(to_kill); int rc = -EBUSY; - loff_t start; - dax_entry_t cookie; if (flags & MF_COUNT_INCREASED) /* @@ -1357,20 +1399,9 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags, */ put_page(page); - /* - * Prevent the inode from being freed while we are interrogating - * the address_space, typically this would be handled by - * lock_page(), but dax pages do not use the page lock. This - * also prevents changes to the mapping of this pfn until - * poison signaling is complete. - */ - cookie = dax_lock_page(page); - if (!cookie) - goto out; - if (hwpoison_filter(page)) { rc = 0; - goto unlock; + goto out; } if (pgmap->type == MEMORY_DEVICE_PRIVATE) { @@ -1378,7 +1409,7 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags, * TODO: Handle HMM pages which may need coordination * with device-side memory. */ - goto unlock; + goto out; } /* @@ -1388,32 +1419,21 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags, SetPageHWPoison(page); /* - * Unlike System-RAM there is no possibility to swap in a - * different physical page at a given virtual address, so all - * userspace consumption of ZONE_DEVICE memory necessitates - * SIGBUS (i.e. MF_MUST_KILL) + * Call driver's implementation to handle the memory failure, + * otherwise roll back to generic handler. */ - flags |= MF_ACTION_REQUIRED | MF_MUST_KILL; - collect_procs_file(page, page->mapping, page->index, &to_kill, - flags & MF_ACTION_REQUIRED); - - list_for_each_entry(tk, &to_kill, nd) - if (tk->size_shift) - size = max(size, 1UL << tk->size_shift); - if (size) { + if (pgmap->ops->memory_failure) { + rc = pgmap->ops->memory_failure(pgmap, pfn, flags); /* - * Unmap the largest mapping to avoid breaking up - * device-dax mappings which are constant size. The - * actual size of the mapping being torn down is - * communicated in siginfo, see kill_proc() + * Roll back to generic handler too if operation is not + * supported inside the driver/device/filesystem. */ - start = (page->index << PAGE_SHIFT) & ~(size - 1); - unmap_mapping_range(page->mapping, start, start + size, 0); + if (rc != EOPNOTSUPP) + goto out; } - kill_procs(&to_kill, flags & MF_MUST_KILL, !unmap_success, pfn, flags); - rc = 0; -unlock: - dax_unlock_page(page, cookie); + + rc = mf_generic_kill_procs(pfn, flags); + out: /* drop pgmap ref acquired in caller */ put_dev_pagemap(pgmap); From patchwork Mon Jan 25 22:55:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruan Shiyang X-Patchwork-Id: 12044659 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=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,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 CD023C433E9 for ; Mon, 25 Jan 2021 22:55:44 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 51BB3221EB for ; Mon, 25 Jan 2021 22:55:44 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 51BB3221EB Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=cn.fujitsu.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvdimm-bounces@lists.01.org Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id F3E88100EBB63; Mon, 25 Jan 2021 14:55:43 -0800 (PST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=183.91.158.132; helo=heian.cn.fujitsu.com; envelope-from=ruansy.fnst@cn.fujitsu.com; receiver= Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by ml01.01.org (Postfix) with ESMTP id B972E100EBBDB for ; Mon, 25 Jan 2021 14:55:40 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.79,374,1602518400"; d="scan'208";a="103820575" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 26 Jan 2021 06:55:38 +0800 Received: from G08CNEXMBPEKD06.g08.fujitsu.local (unknown [10.167.33.206]) by cn.fujitsu.com (Postfix) with ESMTP id 7F0044CE6782; Tue, 26 Jan 2021 06:55:37 +0800 (CST) Received: from G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.200) by G08CNEXMBPEKD06.g08.fujitsu.local (10.167.33.206) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:37 +0800 Received: from irides.mr.mr.mr (10.167.225.141) by G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.209) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 26 Jan 2021 06:55:35 +0800 From: Shiyang Ruan To: , , , Subject: [PATCH v2 06/10] pmem: Implement ->corrupted_range() for pmem driver Date: Tue, 26 Jan 2021 06:55:22 +0800 Message-ID: <20210125225526.1048877-7-ruansy.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> References: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-yoursite-MailScanner-ID: 7F0044CE6782.AAEB5 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: ruansy.fnst@cn.fujitsu.com Message-ID-Hash: SUGPHK253N3ATSVHJYZFUBDDNFRKA7PC X-Message-ID-Hash: SUGPHK253N3ATSVHJYZFUBDDNFRKA7PC X-MailFrom: ruansy.fnst@cn.fujitsu.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: linux-fsdevel@vger.kernel.org, linux-raid@vger.kernel.org, darrick.wong@oracle.com, david@fromorbit.com, hch@lst.de, song@kernel.org, rgoldwyn@suse.de, qi.fuli@fujitsu.com, y-goto@fujitsu.com X-Mailman-Version: 3.1.1 Precedence: list List-Id: "Linux-nvdimm developer list." Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Obtain the superblock of a pmem disk, and call filesystem's ->corrupted_range() to handle the corrupted data. Signed-off-by: Shiyang Ruan --- block/genhd.c | 6 ++++++ drivers/nvdimm/pmem.c | 24 ++++++++++++++++++++++++ include/linux/genhd.h | 1 + 3 files changed, 31 insertions(+) diff --git a/block/genhd.c b/block/genhd.c index 419548e92d82..fd7cf03b65a8 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -936,6 +936,12 @@ struct block_device *bdget_disk(struct gendisk *disk, int partno) return bdev; } +struct block_device *bdget_disk_sector(struct gendisk *disk, sector_t sector) +{ + return disk_map_sector_rcu(disk, sector); +} +EXPORT_SYMBOL(bdget_disk_sector); + /* * print a full list of all partitions - intended for places where the root * filesystem can't be mounted and thus to give the victim some idea of what diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index c9e4fb38f94a..501959947d48 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -253,6 +253,29 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector, return blk_status_to_errno(rc); } +static int pmem_corrupted_range(struct gendisk *disk, struct block_device *bdev, + loff_t disk_offset, size_t len, void *data) +{ + struct super_block *sb; + loff_t bdev_offset; + sector_t disk_sector = disk_offset >> SECTOR_SHIFT; + int rc = 0; + + bdev = bdget_disk_sector(disk, disk_sector); + if (!bdev) + return -ENODEV; + + bdev_offset = (disk_sector - get_start_sect(bdev)) << SECTOR_SHIFT; + sb = get_super(bdev); + if (sb && sb->s_op->corrupted_range) { + rc = sb->s_op->corrupted_range(sb, bdev, bdev_offset, len, data); + drop_super(sb); + } + + bdput(bdev); + return rc; +} + /* see "strong" declaration in tools/testing/nvdimm/pmem-dax.c */ __weak long __pmem_direct_access(struct pmem_device *pmem, pgoff_t pgoff, long nr_pages, void **kaddr, pfn_t *pfn) @@ -281,6 +304,7 @@ static const struct block_device_operations pmem_fops = { .owner = THIS_MODULE, .submit_bio = pmem_submit_bio, .rw_page = pmem_rw_page, + .corrupted_range = pmem_corrupted_range, }; static int pmem_dax_zero_page_range(struct dax_device *dax_dev, pgoff_t pgoff, diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 809aaa32d53c..4da480798955 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -248,6 +248,7 @@ static inline void add_disk_no_queue_reg(struct gendisk *disk) extern void del_gendisk(struct gendisk *gp); extern struct block_device *bdget_disk(struct gendisk *disk, int partno); +extern struct block_device *bdget_disk_sector(struct gendisk *disk, sector_t sector); extern void set_disk_ro(struct gendisk *disk, int flag); From patchwork Mon Jan 25 22:55:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruan Shiyang X-Patchwork-Id: 12044673 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=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,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 AB8C1C433DB for ; Mon, 25 Jan 2021 22:55:43 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 325EF221EB for ; Mon, 25 Jan 2021 22:55:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 325EF221EB Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=cn.fujitsu.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvdimm-bounces@lists.01.org Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id DA48B100EBBDF; Mon, 25 Jan 2021 14:55:42 -0800 (PST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=183.91.158.132; helo=heian.cn.fujitsu.com; envelope-from=ruansy.fnst@cn.fujitsu.com; receiver= Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by ml01.01.org (Postfix) with ESMTP id D9D2A100EBBDD for ; Mon, 25 Jan 2021 14:55:39 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.79,374,1602518400"; d="scan'208";a="103820573" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 26 Jan 2021 06:55:38 +0800 Received: from G08CNEXMBPEKD04.g08.fujitsu.local (unknown [10.167.33.201]) by cn.fujitsu.com (Postfix) with ESMTP id A142F4CE6031; Tue, 26 Jan 2021 06:55:38 +0800 (CST) Received: from G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.200) by G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:37 +0800 Received: from irides.mr.mr.mr (10.167.225.141) by G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.209) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 26 Jan 2021 06:55:36 +0800 From: Shiyang Ruan To: , , , Subject: [PATCH v2 07/10] dm: Introduce ->rmap() to find bdev offset Date: Tue, 26 Jan 2021 06:55:23 +0800 Message-ID: <20210125225526.1048877-8-ruansy.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> References: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-yoursite-MailScanner-ID: A142F4CE6031.A9CC7 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: ruansy.fnst@cn.fujitsu.com Message-ID-Hash: PPDKRO36ZHMEQQWGO3PVVSZAY3XAJSZ7 X-Message-ID-Hash: PPDKRO36ZHMEQQWGO3PVVSZAY3XAJSZ7 X-MailFrom: ruansy.fnst@cn.fujitsu.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: linux-fsdevel@vger.kernel.org, linux-raid@vger.kernel.org, darrick.wong@oracle.com, david@fromorbit.com, hch@lst.de, song@kernel.org, rgoldwyn@suse.de, qi.fuli@fujitsu.com, y-goto@fujitsu.com X-Mailman-Version: 3.1.1 Precedence: list List-Id: "Linux-nvdimm developer list." Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Pmem device could be a target of mapped device. In order to obtain superblock on the mapped device, we introduce this to translate offset from target device to md device. Currently, we implement it on linear target, which is easy to do the translation. Other targets will be supported in the future. However, some targets may not support it because of the non-linear mapping. Signed-off-by: Shiyang Ruan --- drivers/md/dm-linear.c | 20 ++++++++++++++++++++ include/linux/device-mapper.h | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 00774b5d7668..90fdb4700afd 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -5,6 +5,7 @@ */ #include "dm.h" +#include "dm-core.h" #include #include #include @@ -119,6 +120,24 @@ static void linear_status(struct dm_target *ti, status_type_t type, } } +static int linear_rmap(struct dm_target *ti, sector_t offset, + rmap_callout_fn fn, void *data) +{ + struct linear_c *lc = (struct linear_c *) ti->private; + struct mapped_device *md = ti->table->md; + struct block_device *bdev; + sector_t disk_sect = offset - dm_target_offset(ti, lc->start); + int rc = -ENODEV; + + bdev = bdget_disk_sector(md->disk, offset); + if (!bdev) + return rc; + + rc = fn(ti, bdev, disk_sect, data); + bdput(bdev); + return rc; +} + static int linear_prepare_ioctl(struct dm_target *ti, struct block_device **bdev) { struct linear_c *lc = (struct linear_c *) ti->private; @@ -238,6 +257,7 @@ static struct target_type linear_target = { .ctr = linear_ctr, .dtr = linear_dtr, .map = linear_map, + .rmap = linear_rmap, .status = linear_status, .prepare_ioctl = linear_prepare_ioctl, .iterate_devices = linear_iterate_devices, diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 61a66fb8ebb3..c5cd1009a08d 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -58,6 +58,10 @@ typedef void (*dm_dtr_fn) (struct dm_target *ti); * = 2: The target wants to push back the io */ typedef int (*dm_map_fn) (struct dm_target *ti, struct bio *bio); +typedef int (*rmap_callout_fn) (struct dm_target *ti, struct block_device *bdev, + sector_t sect, void *data); +typedef int (*dm_rmap_fn) (struct dm_target *ti, sector_t offset, + rmap_callout_fn fn, void *data); typedef int (*dm_clone_and_map_request_fn) (struct dm_target *ti, struct request *rq, union map_info *map_context, @@ -175,6 +179,7 @@ struct target_type { dm_ctr_fn ctr; dm_dtr_fn dtr; dm_map_fn map; + dm_rmap_fn rmap; dm_clone_and_map_request_fn clone_and_map_rq; dm_release_clone_request_fn release_clone_rq; dm_endio_fn end_io; From patchwork Mon Jan 25 22:55:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruan Shiyang X-Patchwork-Id: 12044669 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=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,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 978D3C43381 for ; Mon, 25 Jan 2021 22:55:52 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5935822482 for ; Mon, 25 Jan 2021 22:55:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5935822482 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=cn.fujitsu.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvdimm-bounces@lists.01.org Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id E73C9100EBB63; Mon, 25 Jan 2021 14:55:51 -0800 (PST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=183.91.158.132; helo=heian.cn.fujitsu.com; envelope-from=ruansy.fnst@cn.fujitsu.com; receiver= Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by ml01.01.org (Postfix) with ESMTP id 0458C100EBBD7 for ; Mon, 25 Jan 2021 14:55:48 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.79,374,1602518400"; d="scan'208";a="103820588" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 26 Jan 2021 06:55:45 +0800 Received: from G08CNEXMBPEKD04.g08.fujitsu.local (unknown [10.167.33.201]) by cn.fujitsu.com (Postfix) with ESMTP id 63DF448990D2; Tue, 26 Jan 2021 06:55:40 +0800 (CST) Received: from G08CNEXJMPEKD02.g08.fujitsu.local (10.167.33.202) by G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:39 +0800 Received: from G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.200) by G08CNEXJMPEKD02.g08.fujitsu.local (10.167.33.202) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:38 +0800 Received: from irides.mr.mr.mr (10.167.225.141) by G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.209) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 26 Jan 2021 06:55:38 +0800 From: Shiyang Ruan To: , , , Subject: [PATCH v2 08/10] md: Implement ->corrupted_range() Date: Tue, 26 Jan 2021 06:55:24 +0800 Message-ID: <20210125225526.1048877-9-ruansy.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> References: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-yoursite-MailScanner-ID: 63DF448990D2.AA2D8 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: ruansy.fnst@cn.fujitsu.com Message-ID-Hash: QVMSDUA54FMTGL74HTN7NWITVZGYL73X X-Message-ID-Hash: QVMSDUA54FMTGL74HTN7NWITVZGYL73X X-MailFrom: ruansy.fnst@cn.fujitsu.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: linux-fsdevel@vger.kernel.org, linux-raid@vger.kernel.org, darrick.wong@oracle.com, david@fromorbit.com, hch@lst.de, song@kernel.org, rgoldwyn@suse.de, qi.fuli@fujitsu.com, y-goto@fujitsu.com X-Mailman-Version: 3.1.1 Precedence: list List-Id: "Linux-nvdimm developer list." Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: With the support of ->rmap(), it is possible to obtain the superblock on a mapped device. If a pmem device is used as one target of mapped device, we cannot obtain its superblock directly. With the help of SYSFS, the mapped device can be found on the target devices. So, we iterate the bdev->bd_holder_disks to obtain its mapped device. Signed-off-by: Shiyang Ruan --- drivers/md/dm.c | 61 +++++++++++++++++++++++++++++++++++++++++++ drivers/nvdimm/pmem.c | 11 +++----- fs/block_dev.c | 42 ++++++++++++++++++++++++++++- include/linux/genhd.h | 2 ++ 4 files changed, 107 insertions(+), 9 deletions(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 7bac564f3faa..31b0c340b695 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -507,6 +507,66 @@ static int dm_blk_report_zones(struct gendisk *disk, sector_t sector, #define dm_blk_report_zones NULL #endif /* CONFIG_BLK_DEV_ZONED */ +struct corrupted_hit_info { + struct block_device *bdev; + sector_t offset; +}; + +static int dm_blk_corrupted_hit(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t count, void *data) +{ + struct corrupted_hit_info *bc = data; + + return bc->bdev == (void *)dev->bdev && + (start <= bc->offset && bc->offset < start + count); +} + +struct corrupted_do_info { + size_t length; + void *data; +}; + +static int dm_blk_corrupted_do(struct dm_target *ti, struct block_device *bdev, + sector_t disk_sect, void *data) +{ + struct corrupted_do_info *bc = data; + loff_t disk_off = to_bytes(disk_sect); + loff_t bdev_off = to_bytes(disk_sect - get_start_sect(bdev)); + + return bd_corrupted_range(bdev, disk_off, bdev_off, bc->length, bc->data); +} + +static int dm_blk_corrupted_range(struct gendisk *disk, + struct block_device *target_bdev, + loff_t target_offset, size_t len, void *data) +{ + struct mapped_device *md = disk->private_data; + struct dm_table *map; + struct dm_target *ti; + sector_t target_sect = to_sector(target_offset); + struct corrupted_hit_info hi = {target_bdev, target_sect}; + struct corrupted_do_info di = {len, data}; + int srcu_idx, i, rc = -ENODEV; + + map = dm_get_live_table(md, &srcu_idx); + if (!map) + return rc; + + for (i = 0; i < dm_table_get_num_targets(map); i++) { + ti = dm_table_get_target(map, i); + if (!(ti->type->iterate_devices && ti->type->rmap)) + continue; + if (!ti->type->iterate_devices(ti, dm_blk_corrupted_hit, &hi)) + continue; + + rc = ti->type->rmap(ti, target_sect, dm_blk_corrupted_do, &di); + break; + } + + dm_put_live_table(md, srcu_idx); + return rc; +} + static int dm_prepare_ioctl(struct mapped_device *md, int *srcu_idx, struct block_device **bdev) { @@ -3062,6 +3122,7 @@ static const struct block_device_operations dm_blk_dops = { .getgeo = dm_blk_getgeo, .report_zones = dm_blk_report_zones, .pr_ops = &dm_pr_ops, + .corrupted_range = dm_blk_corrupted_range, .owner = THIS_MODULE }; diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 501959947d48..3d9f4ccbbd9e 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -256,21 +256,16 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector, static int pmem_corrupted_range(struct gendisk *disk, struct block_device *bdev, loff_t disk_offset, size_t len, void *data) { - struct super_block *sb; loff_t bdev_offset; sector_t disk_sector = disk_offset >> SECTOR_SHIFT; - int rc = 0; + int rc = -ENODEV; bdev = bdget_disk_sector(disk, disk_sector); if (!bdev) - return -ENODEV; + return rc; bdev_offset = (disk_sector - get_start_sect(bdev)) << SECTOR_SHIFT; - sb = get_super(bdev); - if (sb && sb->s_op->corrupted_range) { - rc = sb->s_op->corrupted_range(sb, bdev, bdev_offset, len, data); - drop_super(sb); - } + rc = bd_corrupted_range(bdev, bdev_offset, bdev_offset, len, data); bdput(bdev); return rc; diff --git a/fs/block_dev.c b/fs/block_dev.c index 3b8963e228a1..3cc2b2911e3a 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1079,6 +1079,27 @@ struct bd_holder_disk { int refcnt; }; +static int bd_disk_holder_corrupted_range(struct block_device *bdev, loff_t off, + size_t len, void *data) +{ + struct bd_holder_disk *holder; + struct gendisk *disk; + int rc = 0; + + if (list_empty(&(bdev->bd_holder_disks))) + return -ENODEV; + + list_for_each_entry(holder, &bdev->bd_holder_disks, list) { + disk = holder->disk; + if (disk->fops->corrupted_range) { + rc = disk->fops->corrupted_range(disk, bdev, off, len, data); + if (rc != -ENODEV) + break; + } + } + return rc; +} + static struct bd_holder_disk *bd_find_holder_disk(struct block_device *bdev, struct gendisk *disk) { @@ -1212,7 +1233,26 @@ void bd_unlink_disk_holder(struct block_device *bdev, struct gendisk *disk) mutex_unlock(&bdev->bd_mutex); } EXPORT_SYMBOL_GPL(bd_unlink_disk_holder); -#endif +#endif /* CONFIG_SYSFS */ + +int bd_corrupted_range(struct block_device *bdev, loff_t disk_off, + loff_t bdev_off, size_t len, void *data) +{ + struct super_block *sb = get_super(bdev); + int rc = -EOPNOTSUPP; + + if (!sb) { +#ifdef CONFIG_SYSFS + rc = bd_disk_holder_corrupted_range(bdev, disk_off, len, data); +#endif /* CONFIG_SYSFS */ + return rc; + } else if (sb->s_op->corrupted_range) + rc = sb->s_op->corrupted_range(sb, bdev, bdev_off, len, data); + drop_super(sb); + + return rc; +} +EXPORT_SYMBOL(bd_corrupted_range); static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part); diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 4da480798955..996f91b08d48 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -315,6 +315,8 @@ void unregister_blkdev(unsigned int major, const char *name); bool bdev_check_media_change(struct block_device *bdev); int __invalidate_device(struct block_device *bdev, bool kill_dirty); void set_capacity(struct gendisk *disk, sector_t size); +int bd_corrupted_range(struct block_device *bdev, loff_t disk_off, + loff_t bdev_off, size_t len, void *data); /* for drivers/char/raw.c: */ int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); From patchwork Mon Jan 25 22:55:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruan Shiyang X-Patchwork-Id: 12044671 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=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,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 8ECE6C433E0 for ; Mon, 25 Jan 2021 22:55:51 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 46F1C22482 for ; Mon, 25 Jan 2021 22:55:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 46F1C22482 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=cn.fujitsu.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvdimm-bounces@lists.01.org Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id C52EE100EBBDF; Mon, 25 Jan 2021 14:55:50 -0800 (PST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=183.91.158.132; helo=heian.cn.fujitsu.com; envelope-from=ruansy.fnst@cn.fujitsu.com; receiver= Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by ml01.01.org (Postfix) with ESMTP id BCE93100EBBDA for ; Mon, 25 Jan 2021 14:55:47 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.79,374,1602518400"; d="scan'208";a="103820589" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 26 Jan 2021 06:55:45 +0800 Received: from G08CNEXMBPEKD05.g08.fujitsu.local (unknown [10.167.33.204]) by cn.fujitsu.com (Postfix) with ESMTP id EB5904CE6781; Tue, 26 Jan 2021 06:55:40 +0800 (CST) Received: from G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.200) by G08CNEXMBPEKD05.g08.fujitsu.local (10.167.33.204) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:41 +0800 Received: from irides.mr.mr.mr (10.167.225.141) by G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.209) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 26 Jan 2021 06:55:39 +0800 From: Shiyang Ruan To: , , , Subject: [PATCH v2 09/10] xfs: Implement ->corrupted_range() for XFS Date: Tue, 26 Jan 2021 06:55:25 +0800 Message-ID: <20210125225526.1048877-10-ruansy.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> References: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-yoursite-MailScanner-ID: EB5904CE6781.AB736 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: ruansy.fnst@cn.fujitsu.com Message-ID-Hash: EQ3MHDRFPWJGU5VXFIMBQF6NE3JNSBZN X-Message-ID-Hash: EQ3MHDRFPWJGU5VXFIMBQF6NE3JNSBZN X-MailFrom: ruansy.fnst@cn.fujitsu.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: linux-fsdevel@vger.kernel.org, linux-raid@vger.kernel.org, darrick.wong@oracle.com, david@fromorbit.com, hch@lst.de, song@kernel.org, rgoldwyn@suse.de, qi.fuli@fujitsu.com, y-goto@fujitsu.com X-Mailman-Version: 3.1.1 Precedence: list List-Id: "Linux-nvdimm developer list." Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: This function is used to handle errors which may cause data lost in filesystem. Such as memory failure in fsdax mode. In XFS, it requires "rmapbt" feature in order to query for files or metadata which associated to the corrupted data. Then we could call fs recover functions to try to repair the corrupted data.(did not implemented in this patchset) After that, the memory failure also needs to notify the processes who are using those files. Only support data device. Realtime device is not supported for now. Signed-off-by: Shiyang Ruan --- fs/xfs/xfs_fsops.c | 5 +++ fs/xfs/xfs_mount.h | 1 + fs/xfs/xfs_super.c | 109 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 959ce91a3755..f03901a5c673 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -498,6 +498,11 @@ xfs_do_force_shutdown( "Corruption of in-memory data detected. Shutting down filesystem"); if (XFS_ERRLEVEL_HIGH <= xfs_error_level) xfs_stack_trace(); + } else if (flags & SHUTDOWN_CORRUPT_META) { + xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_CORRUPT, +"Corruption of on-disk metadata detected. Shutting down filesystem"); + if (XFS_ERRLEVEL_HIGH <= xfs_error_level) + xfs_stack_trace(); } else if (logerror) { xfs_alert_tag(mp, XFS_PTAG_SHUTDOWN_LOGERROR, "Log I/O Error Detected. Shutting down filesystem"); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index dfa429b77ee2..8f0df67ffcc1 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -274,6 +274,7 @@ void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, #define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */ #define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */ #define SHUTDOWN_CORRUPT_INCORE 0x0008 /* corrupt in-memory data structures */ +#define SHUTDOWN_CORRUPT_META 0x0010 /* corrupt metadata on device */ /* * Flags for xfs_mountfs diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 813be879a5e5..93093fe0ee8a 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -35,6 +35,11 @@ #include "xfs_refcount_item.h" #include "xfs_bmap_item.h" #include "xfs_reflink.h" +#include "xfs_alloc.h" +#include "xfs_rmap.h" +#include "xfs_rmap_btree.h" +#include "xfs_rtalloc.h" +#include "xfs_bit.h" #include #include @@ -1105,6 +1110,109 @@ xfs_fs_free_cached_objects( return xfs_reclaim_inodes_nr(XFS_M(sb), sc->nr_to_scan); } +static int +xfs_corrupt_helper( + struct xfs_btree_cur *cur, + struct xfs_rmap_irec *rec, + void *data) +{ + struct xfs_inode *ip; + struct address_space *mapping; + int rc = 0; + int *flags = data; + + if (XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) || + (rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))) { + // TODO check and try to fix metadata + rc = -EFSCORRUPTED; + } else { + /* + * Get files that incore, filter out others that are not in use. + */ + rc = xfs_iget(cur->bc_mp, cur->bc_tp, rec->rm_owner, + XFS_IGET_INCORE, 0, &ip); + if (rc || !ip) + return rc; + if (!VFS_I(ip)->i_mapping) + goto out; + + mapping = VFS_I(ip)->i_mapping; + if (IS_DAX(VFS_I(ip))) + rc = mf_dax_mapping_kill_procs(mapping, rec->rm_offset, + *flags); + else + mapping_set_error(mapping, -EIO); + + // TODO try to fix data +out: + xfs_irele(ip); + } + + return rc; +} + +static int +xfs_fs_corrupted_range( + struct super_block *sb, + struct block_device *bdev, + loff_t offset, + size_t len, + void *data) +{ + struct xfs_mount *mp = XFS_M(sb); + struct xfs_trans *tp = NULL; + struct xfs_btree_cur *cur = NULL; + struct xfs_rmap_irec rmap_low, rmap_high; + struct xfs_buf *agf_bp = NULL; + xfs_fsblock_t fsbno = XFS_B_TO_FSB(mp, offset); + xfs_filblks_t bcnt = XFS_B_TO_FSB(mp, len); + xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, fsbno); + xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, fsbno); + int error = 0; + + if (mp->m_rtdev_targp && mp->m_rtdev_targp->bt_bdev == bdev) { + xfs_warn(mp, "corrupted_range support not available for realtime device!"); + return 0; + } + if (mp->m_logdev_targp && mp->m_logdev_targp->bt_bdev == bdev && + mp->m_logdev_targp != mp->m_ddev_targp) { + xfs_err(mp, "ondisk log corrupt, shutting down fs!"); + xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_META); + return 0; + } + + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) { + xfs_warn(mp, "corrupted_range needs rmapbt enabled!"); + return 0; + } + + error = xfs_trans_alloc_empty(mp, &tp); + if (error) + return error; + + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agf_bp); + if (error) + goto out_cancel_tp; + + cur = xfs_rmapbt_init_cursor(mp, tp, agf_bp, agno); + + /* Construct a range for rmap query */ + memset(&rmap_low, 0, sizeof(rmap_low)); + memset(&rmap_high, 0xFF, sizeof(rmap_high)); + rmap_low.rm_startblock = rmap_high.rm_startblock = agbno; + rmap_low.rm_blockcount = rmap_high.rm_blockcount = bcnt; + + error = xfs_rmap_query_range(cur, &rmap_low, &rmap_high, xfs_corrupt_helper, data); + if (error == -EFSCORRUPTED) + xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_META); + + xfs_btree_del_cursor(cur, error); + xfs_trans_brelse(tp, agf_bp); +out_cancel_tp: + xfs_trans_cancel(tp); + return error; +} + static const struct super_operations xfs_super_operations = { .alloc_inode = xfs_fs_alloc_inode, .destroy_inode = xfs_fs_destroy_inode, @@ -1118,6 +1226,7 @@ static const struct super_operations xfs_super_operations = { .show_options = xfs_fs_show_options, .nr_cached_objects = xfs_fs_nr_cached_objects, .free_cached_objects = xfs_fs_free_cached_objects, + .corrupted_range = xfs_fs_corrupted_range, }; static int From patchwork Mon Jan 25 22:55:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ruan Shiyang X-Patchwork-Id: 12044667 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=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,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 2C9D6C433E6 for ; Mon, 25 Jan 2021 22:55:51 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B694122482 for ; Mon, 25 Jan 2021 22:55:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B694122482 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=cn.fujitsu.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvdimm-bounces@lists.01.org Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id A1603100EBBD9; Mon, 25 Jan 2021 14:55:50 -0800 (PST) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=183.91.158.132; helo=heian.cn.fujitsu.com; envelope-from=ruansy.fnst@cn.fujitsu.com; receiver= Received: from heian.cn.fujitsu.com (mail.cn.fujitsu.com [183.91.158.132]) by ml01.01.org (Postfix) with ESMTP id 45C37100EBBDA for ; Mon, 25 Jan 2021 14:55:47 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.79,374,1602518400"; d="scan'208";a="103820587" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 26 Jan 2021 06:55:45 +0800 Received: from G08CNEXMBPEKD06.g08.fujitsu.local (unknown [10.167.33.206]) by cn.fujitsu.com (Postfix) with ESMTP id 143E24CE6014; Tue, 26 Jan 2021 06:55:42 +0800 (CST) Received: from G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.200) by G08CNEXMBPEKD06.g08.fujitsu.local (10.167.33.206) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 26 Jan 2021 06:55:41 +0800 Received: from irides.mr.mr.mr (10.167.225.141) by G08CNEXCHPEKD04.g08.fujitsu.local (10.167.33.209) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 26 Jan 2021 06:55:40 +0800 From: Shiyang Ruan To: , , , Subject: [PATCH v2 10/10] fs/dax: Remove useless functions Date: Tue, 26 Jan 2021 06:55:26 +0800 Message-ID: <20210125225526.1048877-11-ruansy.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> References: <20210125225526.1048877-1-ruansy.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-yoursite-MailScanner-ID: 143E24CE6014.ACA70 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: ruansy.fnst@cn.fujitsu.com Message-ID-Hash: IFGVWT45H6LJ2JWB26BQTRQGDVUVSTXW X-Message-ID-Hash: IFGVWT45H6LJ2JWB26BQTRQGDVUVSTXW X-MailFrom: ruansy.fnst@cn.fujitsu.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: linux-fsdevel@vger.kernel.org, linux-raid@vger.kernel.org, darrick.wong@oracle.com, david@fromorbit.com, hch@lst.de, song@kernel.org, rgoldwyn@suse.de, qi.fuli@fujitsu.com, y-goto@fujitsu.com X-Mailman-Version: 3.1.1 Precedence: list List-Id: "Linux-nvdimm developer list." Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Since owner tarcking is triggerred by pmem device, these functions are useless. So remove it. Signed-off-by: Shiyang Ruan --- fs/dax.c | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index c64c3a0e76a6..e20a5df03eec 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -323,48 +323,6 @@ static unsigned long dax_end_pfn(void *entry) for (pfn = dax_to_pfn(entry); \ pfn < dax_end_pfn(entry); pfn++) -/* - * TODO: for reflink+dax we need a way to associate a single page with - * multiple address_space instances at different linear_page_index() - * offsets. - */ -static void dax_associate_entry(void *entry, struct address_space *mapping, - struct vm_area_struct *vma, unsigned long address) -{ - unsigned long size = dax_entry_size(entry), pfn, index; - int i = 0; - - if (IS_ENABLED(CONFIG_FS_DAX_LIMITED)) - return; - - index = linear_page_index(vma, address & ~(size - 1)); - for_each_mapped_pfn(entry, pfn) { - struct page *page = pfn_to_page(pfn); - - WARN_ON_ONCE(page->mapping); - page->mapping = mapping; - page->index = index + i++; - } -} - -static void dax_disassociate_entry(void *entry, struct address_space *mapping, - bool trunc) -{ - unsigned long pfn; - - if (IS_ENABLED(CONFIG_FS_DAX_LIMITED)) - return; - - for_each_mapped_pfn(entry, pfn) { - struct page *page = pfn_to_page(pfn); - - WARN_ON_ONCE(trunc && page_ref_count(page) > 1); - WARN_ON_ONCE(page->mapping && page->mapping != mapping); - page->mapping = NULL; - page->index = 0; - } -} - static struct page *dax_busy_page(void *entry) { unsigned long pfn; @@ -543,7 +501,6 @@ static void *grab_mapping_entry(struct xa_state *xas, xas_lock_irq(xas); } - dax_disassociate_entry(entry, mapping, false); xas_store(xas, NULL); /* undo the PMD join */ dax_wake_entry(xas, entry, true); mapping->nrexceptional--; @@ -680,7 +637,6 @@ static int __dax_invalidate_entry(struct address_space *mapping, (xas_get_mark(&xas, PAGECACHE_TAG_DIRTY) || xas_get_mark(&xas, PAGECACHE_TAG_TOWRITE))) goto out; - dax_disassociate_entry(entry, mapping, trunc); xas_store(&xas, NULL); mapping->nrexceptional--; ret = 1; @@ -774,8 +730,6 @@ static void *dax_insert_entry(struct xa_state *xas, if (dax_is_zero_entry(entry) || dax_is_empty_entry(entry)) { void *old; - dax_disassociate_entry(entry, mapping, false); - dax_associate_entry(new_entry, mapping, vmf->vma, vmf->address); /* * Only swap our new entry into the page cache if the current * entry is a zero page or an empty entry. If a normal PTE or