From: Shiyang Ruan <ruansy.fnst@cn.fujitsu.com>
To: <linux-kernel@vger.kernel.org>, <linux-xfs@vger.kernel.org>,
<linux-nvdimm@lists.01.org>, <linux-mm@kvack.org>
Cc: <linux-fsdevel@vger.kernel.org>, <linux-raid@vger.kernel.org>,
<darrick.wong@oracle.com>, <dan.j.williams@intel.com>,
<david@fromorbit.com>, <hch@lst.de>, <song@kernel.org>,
<rgoldwyn@suse.de>, <qi.fuli@fujitsu.com>, <y-goto@fujitsu.com>
Subject: [RFC PATCH v2 1/6] fs: introduce ->storage_lost() for memory-failure
Date: Mon, 23 Nov 2020 08:41:11 +0800 [thread overview]
Message-ID: <20201123004116.2453-2-ruansy.fnst@cn.fujitsu.com> (raw)
In-Reply-To: <20201123004116.2453-1-ruansy.fnst@cn.fujitsu.com>
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 <ruansy.fnst@cn.fujitsu.com>
---
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 <linux/magic.h>
#include <linux/fs_context.h>
@@ -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
next prev parent reply other threads:[~2020-11-23 0:41 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-23 0:41 [RFC PATCH v2 0/6] fsdax: introduce fs query to support reflink Shiyang Ruan
2020-11-23 0:41 ` Shiyang Ruan [this message]
2020-11-23 0:41 ` [RFC PATCH v2 2/6] blk: introduce ->block_lost() to handle memory-failure Shiyang Ruan
2020-11-23 0:41 ` [RFC PATCH v2 3/6] md: implement ->block_lost() for memory-failure Shiyang Ruan
2020-11-23 0:41 ` [RFC PATCH v2 4/6] pagemap: introduce ->memory_failure() Shiyang Ruan
2020-11-23 0:41 ` [RFC PATCH v2 5/6] mm, fsdax: refactor dax handler in memory-failure Shiyang Ruan
2020-11-23 0:41 ` [RFC PATCH v2 6/6] fsdax: remove useless (dis)associate functions Shiyang Ruan
2020-11-29 22:47 ` [RFC PATCH v2 0/6] fsdax: introduce fs query to support reflink Dave Chinner
2020-12-02 7:12 ` Ruan Shiyang
2020-12-06 22:55 ` Dave Chinner
2020-12-14 20:58 ` Jane Chu
2020-12-15 11:58 ` Ruan Shiyang
2020-12-15 19:05 ` Jane Chu
2020-12-15 23:10 ` Dave Chinner
2020-12-16 2:46 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201123004116.2453-2-ruansy.fnst@cn.fujitsu.com \
--to=ruansy.fnst@cn.fujitsu.com \
--cc=dan.j.williams@intel.com \
--cc=darrick.wong@oracle.com \
--cc=david@fromorbit.com \
--cc=hch@lst.de \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-nvdimm@lists.01.org \
--cc=linux-raid@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
--cc=qi.fuli@fujitsu.com \
--cc=rgoldwyn@suse.de \
--cc=song@kernel.org \
--cc=y-goto@fujitsu.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).