Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp496993pxu; Sun, 22 Nov 2020 16:47:04 -0800 (PST) X-Google-Smtp-Source: ABdhPJyG8rEjiprBzmnRuNZAL+H65zPvp6iRsiJMCVIkM7evRni8utsFaLBsMAHFm+S5587ayjo/ X-Received: by 2002:a17:906:2581:: with SMTP id m1mr41022712ejb.28.1606092424371; Sun, 22 Nov 2020 16:47:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1606092424; cv=none; d=google.com; s=arc-20160816; b=BGTbtmuFh7yUZnQWkcW3xKQEZJF6bDNBiVKNHAocqmgq4iXABMRUd8cn/YLFx57P08 hb/0kSGahq64xzd6ey6wUGAg+IHbph5EQltoFZuCMvNtm2cLTitBh2O+XsuQsoyzEMOU MtQIERcoK8/EcgDlh7Y9XHD1TNhNiEEvy9eCojgwOPzEs/zPm3b8OCEQwslzlrv8f0Yf IP1JSpjbrOSAFOYzTwMD6JJq5GCaL+7Fo/2lwMnjKVOqy2Sm/XLHVWacC7UiTu0+9nft woZZKH6r4SEOZ6ujBfxLzIB3U+27YwP8ZYn0xlGcS0TGQcf2YtI6FxUgk9LZIDc+vkKh 6dUw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=42l2e94j2vMH1rlQauMZK5wBUv0u583gKuN9elNZT+8=; b=ZoqReVY3wpA5F/6HW+2U+CrRPRXqNsjD3/Ia0jaZWkymY8tlq0L3zMaMDe7j1NKNkM xsSbdSyhv+007YX7aHm3uvCPLeLF7YYmfQT85TfJKZtyjAv7q7xu6ixvwsPmz/uTbj/X H/sW45t8+TQZz0CQBf6L8YDxEG2TFPbWOw+kcbhGezA5ufhqeINxi8vtvMdYHIfxL9yv 5fjwPDqIjtn4uqUvnfJcP3EM0DQKeuGEtAHIJkLt5X1hWQL0hehRe1ODxzXPfVaKaU+j z7NQ4TUUQzMnND1F8xY4LvCdGSLG++wuZYcQUSCYrTnDLe/pM4TlG7D6WiTEY9I4Igqc 7PGg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h22si1086418ejd.742.2020.11.22.16.46.41; Sun, 22 Nov 2020 16:47:04 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726955AbgKWAlv (ORCPT + 99 others); Sun, 22 Nov 2020 19:41:51 -0500 Received: from mail.cn.fujitsu.com ([183.91.158.132]:44470 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726822AbgKWAlt (ORCPT ); Sun, 22 Nov 2020 19:41:49 -0500 X-IronPort-AV: E=Sophos;i="5.78,361,1599494400"; d="scan'208";a="101635236" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 23 Nov 2020 08:41:41 +0800 Received: from G08CNEXMBPEKD04.g08.fujitsu.local (unknown [10.167.33.201]) by cn.fujitsu.com (Postfix) with ESMTP id E1F334CE5458; Mon, 23 Nov 2020 08:41:39 +0800 (CST) Received: from G08CNEXCHPEKD05.g08.fujitsu.local (10.167.33.203) by G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 23 Nov 2020 08:41:41 +0800 Received: from localhost.localdomain (10.167.225.141) by G08CNEXCHPEKD05.g08.fujitsu.local (10.167.33.209) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Mon, 23 Nov 2020 08:41:19 +0800 From: Shiyang Ruan To: , , , CC: , , , , , , , , , Subject: [RFC PATCH v2 1/6] fs: introduce ->storage_lost() for memory-failure Date: Mon, 23 Nov 2020 08:41:11 +0800 Message-ID: <20201123004116.2453-2-ruansy.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201123004116.2453-1-ruansy.fnst@cn.fujitsu.com> References: <20201123004116.2453-1-ruansy.fnst@cn.fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-yoursite-MailScanner-ID: E1F334CE5458.AB364 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: ruansy.fnst@cn.fujitsu.com X-Spam-Status: No Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 broken block. Then we could call fs recover functions to try to repair the damaged data.(did not implemented in this patch) After that, the memory-failure also needs to kill processes who are using those files. The struct mf_recover_controller is created to store necessary parameters. Only support data device. Realtime device is not supported for now. Signed-off-by: Shiyang Ruan --- fs/xfs/xfs_super.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 2 ++ include/linux/mm.h | 6 ++++ 3 files changed, 95 insertions(+) diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index e3e229e52512..f9a109217a80 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 @@ -1103,6 +1108,87 @@ xfs_fs_free_cached_objects( return xfs_reclaim_inodes_nr(XFS_M(sb), sc->nr_to_scan); } +static int +xfs_storage_lost_helper( + struct xfs_btree_cur *cur, + struct xfs_rmap_irec *rec, + void *priv) +{ + struct xfs_inode *ip; + struct mf_recover_controller *mfrc = priv; + int rc = 0; + + if (XFS_RMAP_NON_INODE_OWNER(rec->rm_owner)) { + // TODO check and try to fix metadata + } 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; + + rc = mfrc->recover_fn(mfrc->pfn, mfrc->flags, + VFS_I(ip)->i_mapping, rec->rm_offset); + + // TODO try to fix data +out: + xfs_irele(ip); + } + + return rc; +} + +static int +xfs_fs_storage_lost( + struct super_block *sb, + struct block_device *bdev, + loff_t offset, + void *priv) +{ + 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_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, "storage lost support not available for realtime device!"); + 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) + return error; + + 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; + + error = xfs_rmap_query_range(cur, &rmap_low, &rmap_high, + xfs_storage_lost_helper, priv); + if (error == -ECANCELED) + error = 0; + + xfs_btree_del_cursor(cur, error); + xfs_trans_brelse(tp, agf_bp); + return error; +} + static const struct super_operations xfs_super_operations = { .alloc_inode = xfs_fs_alloc_inode, .destroy_inode = xfs_fs_destroy_inode, @@ -1116,6 +1202,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, + .storage_lost = xfs_fs_storage_lost, }; static int diff --git a/include/linux/fs.h b/include/linux/fs.h index 0bd126418bb6..8c4f753e3ed9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1949,6 +1949,8 @@ struct super_operations { struct shrink_control *); long (*free_cached_objects)(struct super_block *, struct shrink_control *); + int (*storage_lost)(struct super_block *sb, struct block_device *bdev, + loff_t offset, void *priv); }; /* diff --git a/include/linux/mm.h b/include/linux/mm.h index ef360fe70aaf..872b51ebe57b 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -3031,6 +3031,12 @@ extern void shake_page(struct page *p, int access); extern atomic_long_t num_poisoned_pages __read_mostly; extern int soft_offline_page(unsigned long pfn, int flags); +struct mf_recover_controller { + int (*recover_fn)(unsigned long pfn, int flags, + struct address_space *mapping, pgoff_t index); + unsigned long pfn; + int flags; +}; /* * Error handlers for various types of pages. -- 2.29.2