[PATCH V11 7/9] famfs_fuse: fail I/O on invalid or errored daxdevs

John Groves <[email protected]>
Newsgroups org.kernel.vger.linux-cxl,dev.linux.lists.fuse-devel,dev.linux.lists.nvdimm,org.kernel.vger.linux-doc,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel
Message-ID <0100019f7da1faa3-75c84002-18fc-4762-a69c-ef33d15a449d-000000@email.amazonses.com>
From: John Groves <[email protected]>

Gate the iomap resolution path on the state of the daxdev backing each
referenced extent. famfs_dax_err() returns an error if the daxdev slot is
invalid (-EIO), was flagged dax_err (-EIO), or has reported a memory error
via notify_failure (-EHWPOISON). famfs_fileofs_to_daxofs() calls it and,
on error, marks the file (meta->error) and stops allowing access.

Memory errors are at least somewhat more likely on disaggregated memory
than on-board memory. In general the recovery is to unmount and
re-initialize the memory, though degraded modes may be possible in the
future when famfs supports file systems backed by more than one daxdev
(data on a working daxdev can still be accessed). For now, return errors
for any file that has touched an invalid or errored daxdev.

Signed-off-by: John Groves <[email protected]>
---
 fs/fuse/famfs.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/fs/fuse/famfs.c b/fs/fuse/famfs.c
index ac56317944d9..8d13282e8949 100644
--- a/fs/fuse/famfs.c
+++ b/fs/fuse/famfs.c
@@ -589,6 +589,26 @@ famfs_file_init_dax(
 
 static int famfs_file_bad(struct inode *inode);
 
+static int famfs_dax_err(struct famfs_daxdev *dd)
+{
+	if (!dd->valid) {
+		pr_err("%s: daxdev=%s invalid\n",
+		       __func__, dd->name);
+		return -EIO;
+	}
+	if (dd->dax_err) {
+		pr_err("%s: daxdev=%s dax_err\n",
+		       __func__, dd->name);
+		return -EIO;
+	}
+	if (dd->error) {
+		pr_err("%s: daxdev=%s memory error\n",
+		       __func__, dd->name);
+		return -EHWPOISON;
+	}
+	return 0;
+}
+
 /**
  * famfs_fileofs_to_daxofs() - Resolve (file, offset, len) to (daxdev, offset, len)
  *
@@ -661,6 +681,7 @@ famfs_fileofs_to_daxofs(struct inode *inode, struct iomap *iomap,
 		u64 daxdev_idx           = meta->se[i].dev_index;
 		loff_t ext_len_remainder = dax_ext_len - local_offset;
 		struct famfs_daxdev *dd;
+		int rc;
 
 		if (daxdev_idx >= fc->dax_devlist->nslots) {
 			pr_err("%s: daxdev_idx %llu >= nslots %d\n",
@@ -670,6 +691,13 @@ famfs_fileofs_to_daxofs(struct inode *inode, struct iomap *iomap,
 
 		dd = &fc->dax_devlist->devlist[daxdev_idx];
 
+		rc = famfs_dax_err(dd);
+		if (rc) {
+			/* Shut down access to this file */
+			meta->error = true;
+			return rc;
+		}
+
 		iomap->addr    = dax_ext_offset + local_offset;
 		iomap->offset  = file_offset;
 		iomap->length  = min_t(loff_t, len, ext_len_remainder);
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.