[PATCH V11 7/9] famfs_fuse: fail I/O on invalid or errored daxdevs
John Groves <[email protected]> Mon, 20 Jul 2026 03:46:35 +0000
| Newsgroups | dev.linux.lists.fuse-devel,dev.linux.lists.nvdimm,org.kernel.vger.linux-cxl,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]>=0D=0A=0D=0AGate the iomap resolution = path on the state of the daxdev backing each=0D=0Areferenced extent. famf= s_dax_err() returns an error if the daxdev slot is=0D=0Ainvalid (-EIO), w= as flagged dax_err (-EIO), or has reported a memory error=0D=0Avia notify= _failure (-EHWPOISON). famfs_fileofs_to_daxofs() calls it and,=0D=0Aon er= ror, marks the file (meta->error) and stops allowing access.=0D=0A=0D=0AM= emory errors are at least somewhat more likely on disaggregated memory=0D= =0Athan on-board memory. In general the recovery is to unmount and=0D=0Ar= e-initialize the memory, though degraded modes may be possible in the=0D=0A= future when famfs supports file systems backed by more than one daxdev=0D= =0A(data on a working daxdev can still be accessed). For now, return erro= rs=0D=0Afor any file that has touched an invalid or errored daxdev.=0D=0A= =0D=0ASigned-off-by: John Groves <[email protected]>=0D=0A---=0D=0A fs/fuse= /famfs.c | 28 ++++++++++++++++++++++++++++=0D=0A 1 file changed, 28 inser= tions(+)=0D=0A=0D=0Adiff --git a/fs/fuse/famfs.c b/fs/fuse/famfs.c=0D=0Ai= ndex ac56317944d9..8d13282e8949 100644=0D=0A--- a/fs/fuse/famfs.c=0D=0A++= + b/fs/fuse/famfs.c=0D=0A@@ -589,6 +589,26 @@ famfs_file_init_dax(=0D=0A=20= =0D=0A static int famfs_file_bad(struct inode *inode);=0D=0A=20=0D=0A+sta= tic int famfs_dax_err(struct famfs_daxdev *dd)=0D=0A+{=0D=0A+=09if (!dd->= valid) {=0D=0A+=09=09pr_err("%s: daxdev=3D%s invalid\n",=0D=0A+=09=09 = __func__, dd->name);=0D=0A+=09=09return -EIO;=0D=0A+=09}=0D=0A+=09if (= dd->dax_err) {=0D=0A+=09=09pr_err("%s: daxdev=3D%s dax_err\n",=0D=0A+=09=09= __func__, dd->name);=0D=0A+=09=09return -EIO;=0D=0A+=09}=0D=0A+=09= if (dd->error) {=0D=0A+=09=09pr_err("%s: daxdev=3D%s memory error\n",=0D=0A= +=09=09 __func__, dd->name);=0D=0A+=09=09return -EHWPOISON;=0D=0A+=09= }=0D=0A+=09return 0;=0D=0A+}=0D=0A+=0D=0A /**=0D=0A * famfs_fileofs_to_d= axofs() - Resolve (file, offset, len) to (daxdev, offset, len)=0D=0A *=0D= =0A@@ -661,6 +681,7 @@ famfs_fileofs_to_daxofs(struct inode *inode, struc= t iomap *iomap,=0D=0A =09=09u64 daxdev_idx =3D meta->se[i].dev_= index;=0D=0A =09=09loff_t ext_len_remainder =3D dax_ext_len - local_offse= t;=0D=0A =09=09struct famfs_daxdev *dd;=0D=0A+=09=09int rc;=0D=0A=20=0D=0A= =09=09if (daxdev_idx >=3D fc->dax_devlist->nslots) {=0D=0A =09=09=09pr_e= rr("%s: daxdev_idx %llu >=3D nslots %d\n",=0D=0A@@ -670,6 +691,13 @@ famf= s_fileofs_to_daxofs(struct inode *inode, struct iomap *iomap,=0D=0A=20=0D= =0A =09=09dd =3D &fc->dax_devlist->devlist[daxdev_idx];=0D=0A=20=0D=0A+=09= =09rc =3D famfs_dax_err(dd);=0D=0A+=09=09if (rc) {=0D=0A+=09=09=09/* Shut= down access to this file */=0D=0A+=09=09=09meta->error =3D true;=0D=0A+=09= =09=09return rc;=0D=0A+=09=09}=0D=0A+=0D=0A =09=09iomap->addr =3D dax_= ext_offset + local_offset;=0D=0A =09=09iomap->offset =3D file_offset;=0D= =0A =09=09iomap->length =3D min_t(loff_t, len, ext_len_remainder);=0D=0A= --=20=0D=0A2.53.0=0D=0A=0D=0A