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

