linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
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 2/6] blk: introduce ->block_lost() to handle memory-failure
Date: Mon, 23 Nov 2020 08:41:12 +0800	[thread overview]
Message-ID: <20201123004116.2453-3-ruansy.fnst@cn.fujitsu.com> (raw)
In-Reply-To: <20201123004116.2453-1-ruansy.fnst@cn.fujitsu.com>

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.

Usually, a block device is used directly to mkfs on it.  The filesystem
on it is easily to obtain by 'get_super()'.  The block device can also
be divided into several partitions, or used as a target by mapped
device.  It is hard to get filesystem's superblock in this two ways.
So, add 'bdget_disk_sector()' to get the block device of a partition
where the broken sector located in.  And add
'bd_disk_holder_block_lost()' iterate the mapped devices on it.

Signed-off-by: Shiyang Ruan <ruansy.fnst@cn.fujitsu.com>
---
 block/genhd.c          | 12 ++++++++++++
 drivers/nvdimm/pmem.c  | 27 +++++++++++++++++++++++++++
 fs/block_dev.c         | 23 +++++++++++++++++++++++
 include/linux/blkdev.h |  2 ++
 include/linux/genhd.h  |  9 +++++++++
 5 files changed, 73 insertions(+)

diff --git a/block/genhd.c b/block/genhd.c
index 0a273211fec2..2c7304f123fa 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1055,6 +1055,18 @@ struct block_device *bdget_disk(struct gendisk *disk, int partno)
 }
 EXPORT_SYMBOL(bdget_disk);
 
+struct block_device *bdget_disk_sector(struct gendisk *disk, sector_t sector)
+{
+	struct block_device *bdev = NULL;
+	struct hd_struct *part = disk_map_sector_rcu(disk, sector);
+
+	if (part)
+		bdev = bdget_part(part);
+
+	return bdev;
+}
+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 875076b0ea6c..d75a3f370f3c 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -253,6 +253,32 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector,
 	return blk_status_to_errno(rc);
 }
 
+int pmem_block_lost(struct gendisk *disk, struct block_device *bdev,
+		    loff_t disk_offset, void *data)
+{
+	struct super_block *sb;
+	sector_t bdev_sector, disk_sector = disk_offset >> SECTOR_SHIFT;
+	int rc = 0;
+
+	bdev = bdget_disk_sector(disk, disk_sector);
+	if (!bdev)
+		return -ENODEV;
+
+	bdev_sector = disk_sector - get_start_sect(bdev);
+	sb = get_super(bdev);
+	if (!sb) {
+		rc = bd_disk_holder_block_lost(bdev, bdev_sector, data);
+		goto out;
+	} else if (sb->s_op->storage_lost)
+		rc = sb->s_op->storage_lost(sb, bdev,
+					    bdev_sector << SECTOR_SHIFT, data);
+	drop_super(sb);
+
+out:
+	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 +307,7 @@ static const struct block_device_operations pmem_fops = {
 	.owner =		THIS_MODULE,
 	.submit_bio =		pmem_submit_bio,
 	.rw_page =		pmem_rw_page,
+	.block_lost =		pmem_block_lost,
 };
 
 static int pmem_dax_zero_page_range(struct dax_device *dax_dev, pgoff_t pgoff,
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 9e84b1928b94..e1e30828fb9f 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1171,6 +1171,29 @@ struct bd_holder_disk {
 	int			refcnt;
 };
 
+int bd_disk_holder_block_lost(struct block_device *bdev, sector_t offset,
+			      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->block_lost) {
+			rc = disk->fops->block_lost(disk, bdev,
+					       offset << SECTOR_SHIFT, data);
+			if (rc != -ENODEV)
+				break;
+		}
+	}
+	return rc;
+}
+EXPORT_SYMBOL_GPL(bd_disk_holder_block_lost);
+
 static struct bd_holder_disk *bd_find_holder_disk(struct block_device *bdev,
 						  struct gendisk *disk)
 {
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 639cae2c158b..ddeb268cc938 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1855,6 +1855,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 (*block_lost)(struct gendisk *disk, struct block_device *bdev,
+			  loff_t offset, void *data);
 	struct module *owner;
 	const struct pr_ops *pr_ops;
 };
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 38f23d757013..9d8f5b5dab9f 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -303,6 +303,8 @@ static inline void add_disk_no_queue_reg(struct gendisk *disk)
 extern void del_gendisk(struct gendisk *gp);
 extern struct gendisk *get_gendisk(dev_t dev, int *partno);
 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_device_ro(struct block_device *bdev, int flag);
 extern void set_disk_ro(struct gendisk *disk, int flag);
@@ -381,9 +383,16 @@ int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long);
 long compat_blkdev_ioctl(struct file *, unsigned, unsigned long);
 
 #ifdef CONFIG_SYSFS
+int bd_disk_holder_block_lost(struct block_device *bdev, sector_t offset,
+			      void *data);
 int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk);
 void bd_unlink_disk_holder(struct block_device *bdev, struct gendisk *disk);
 #else
+static inline int bd_disk_holder_block_lost(struct block_device *bdev,
+					    sector_t offset, void *data)
+{
+	return 0;
+}
 static inline int bd_link_disk_holder(struct block_device *bdev,
 				      struct gendisk *disk)
 {
-- 
2.29.2





  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 ` [RFC PATCH v2 1/6] fs: introduce ->storage_lost() for memory-failure Shiyang Ruan
2020-11-23  0:41 ` Shiyang Ruan [this message]
2020-11-23  0:41 ` [RFC PATCH v2 3/6] md: implement ->block_lost() " 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-3-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).