[PATCH V11 7/9] famfs_fuse: fail I/O on invalid or errored daxdevs
From: John Groves
Date: Sun Jul 19 2026 - 23:50:25 EST
From: John Groves <john@xxxxxxxxxx>
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 <john@xxxxxxxxxx>
---
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