aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dax/fsdev.c
AgeCommit message (Collapse)AuthorFilesLines
2026-07-14dax: fsdev.c minor formatting cleanupJohn Groves1-7/+8
Address some comments from Jonathan that were missed in the merged series. Fix line wrapping in fsdev_dax_recovery_write() and fsdev_dax_zero_page_range() signatures. Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Signed-off-by: John Groves <john@groves.net> Link: https://patch.msgid.link/0100019ecc09f607-b558c192-72fc-4c2d-9f64-3b82796e7dd4-000000@email.amazonses.com Signed-off-by: Alison Schofield <alison.schofield@intel.com>
2026-07-14dax/fsdev: fail probe on invalid pgmap offsetJohn Groves1-2/+6
Convert the WARN_ON to a fatal error when pgmap_phys > phys. This condition means the remapped region starts after the device's data region, which is an impossible state. Previously the probe continued with data_offset=0, leaving virt_addr silently misaligned. Now probe returns -EINVAL with a diagnostic message. Fixes: 759455848df0b ("dax: Save the kva from memremap") Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Pankaj Gupta <pankaj.gupta@amd.com> Signed-off-by: John Groves <john@groves.net> Link: https://patch.msgid.link/0100019ecc0999fa-97574544-8b6b-46cf-9f33-423abdbeee7f-000000@email.amazonses.com Signed-off-by: Alison Schofield <alison.schofield@intel.com>
2026-07-14dax/fsdev: use __va(phys) for kaddr in direct_accessJohn Groves1-6/+2
Use __va(phys) instead of virt_addr + linear_offset for the kaddr return in __fsdev_dax_direct_access(). The previous code added a device-linear byte offset to virt_addr (which is __va of ranges[0]), but for multi-range devices with physical gaps between ranges, this linear arithmetic crosses the gap and produces a wrong kernel virtual address. Using __va(phys) where phys comes from dax_pgoff_to_phys() is correct for any range layout because the direct map translates each physical address independently. This leaves dev_dax->virt_addr write-only, so remove the field (suggested by Dave Jiang). Fixes: 759455848df0b ("dax: Save the kva from memremap") Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Signed-off-by: John Groves <john@groves.net> Link: https://patch.msgid.link/0100019ecc096de8-8bc254a7-d2cc-44b6-82b1-1394fda8bb41-000000@email.amazonses.com Signed-off-by: Alison Schofield <alison.schofield@intel.com>
2026-07-14dax/fsdev: clear pgmap ops and owner on unbindJohn Groves1-0/+22
fsdev_dax_probe() sets pgmap->ops = &fsdev_pagemap_ops and pgmap->owner = dev_dax, but nothing ever clears them. For a dynamic device the pgmap is devm-allocated and freed on unbind, so this is harmless. For a static device the pgmap is the shared, long-lived one owned by the dax bus (kill_dev_dax() only NULLs dev_dax->pgmap for the non-static case), and device.c's probe sets only pgmap->type, never clearing ops/owner. So after fsdev unbinds a static device the stale fsdev_pagemap_ops survives on the shared pgmap. If the device is then rebound to device_dax (MEMORY_DEVICE_GENERIC, which installs no ->memory_failure), or the fsdev_dax module is unloaded, a subsequent memory_failure on that pgmap dispatches through the stale -- and possibly freed -- handler. Register a devm action that clears pgmap->ops and pgmap->owner on unbind, symmetric with setting them at probe, so the pgmap carries no fsdev state once fsdev is detached. Suggested-by: Richard Cheng <icheng@nvidia.com> Fixes: d5406bd458b0a ("dax: add fsdev.c driver for fs-dax on character dax") Signed-off-by: John Groves <john@groves.net> Reviewed-by: Richard Cheng <icheng@nvidia.com> Link: https://patch.msgid.link/0100019ecc094b6e-fc163bde-0396-4a33-909f-fb88e740be27-000000@email.amazonses.com Signed-off-by: Alison Schofield <alison.schofield@intel.com>
2026-07-14dax/fsdev: don't leave a dangling dev_dax->pgmap on probe failureJohn Groves1-28/+49
After the dynamic path set dev_dax->pgmap, any later probe failure left dev_dax->pgmap dangling: devres frees the devm_kzalloc'd pgmap on probe failure, and subsequent probe attempts would hit the "dynamic-dax with pre-populated page map" check and fail permanently. Factor pgmap acquisition out into fsdev_acquire_pgmap(), and defer the dev_dax->pgmap assignment until probe can no longer fail. A failed probe now never publishes the pointer at all, so there is nothing to unwind. This also matches kill_dev_dax(), which already clears the dynamic pgmap pointer on unbind: dev_dax->pgmap is now non-NULL only while the pgmap is actually valid. Refactor suggested by Dave Jiang. Fixes: d5406bd458b0a ("dax: add fsdev.c driver for fs-dax on character dax") Reviewed-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: John Groves <john@groves.net> Link: https://patch.msgid.link/0100019ecc092ca1-ffc7a5fd-1252-4be5-882c-fd5efdc102a9-000000@email.amazonses.com Signed-off-by: Alison Schofield <alison.schofield@intel.com>
2026-07-14dax/fsdev: clear vmemmap_shift when binding static pgmapJohn Groves1-0/+1
Clear pgmap->vmemmap_shift for static DAX devices. When rebinding a static device from device_dax (which may set vmemmap_shift based on alignment) to fsdev_dax, the stale vmemmap_shift persists on the shared pgmap. Explicitly zero it before devm_memremap_pages() so the vmemmap is built for order-0 folios as fsdev requires. Fixes: d5406bd458b0a ("dax: add fsdev.c driver for fs-dax on character dax") Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Signed-off-by: John Groves <john@groves.net> Link: https://patch.msgid.link/0100019ecc090eea-7c46f51e-5393-402c-850d-78059bb6d343-000000@email.amazonses.com Signed-off-by: Alison Schofield <alison.schofield@intel.com>
2026-07-14dax/fsdev: fix multi-range offset in memory_failure handlerJohn Groves1-1/+16
Fix memory_failure offset calculation for multi-range devices. The old code subtracted ranges[0].range.start from the faulting PFN's physical address, which produces an incorrect (inflated) logical offset when the PFN falls in ranges[1] or beyond due to physical gaps between ranges. Add fsdev_pfn_to_offset() to walk the range list and compute the correct device-linear byte offset relative to ranges[0].start (the device data start) -- the base the holder (xfs, famfs) maps from -- for both static and dynamic devices. V5 walked the pagemap's immutable pgmap->ranges[] instead, to avoid reading the mutable dev_dax->ranges[] from this callback. That had a different problem: it regressed static devices, where pgmap->ranges[0].start can sit data_offset below the data start, so the reported offset came out data_offset too high and the holder would act on the wrong blocks. For dynamic devices the two arrays are identical, so pgmap->ranges[] only ever helped the dynamic case while breaking the static one. Walk dev_dax->ranges[] instead. (Richard Cheng spotted the static regression.) Reading dev_dax->ranges[] here may race a concurrent krealloc() of the range array via sysfs (mapping_store(), under dax_region_rwsem, which this ->memory_failure callback does not hold). That exposure is pre-existing -- the original single-range code read dev_dax->ranges[0] locklessly as well -- so this patch does not make it worse; a proper fix (locking or snapshotting) belongs in a separate change. Fixes: d5406bd458b0a ("dax: add fsdev.c driver for fs-dax on character dax") Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Signed-off-by: John Groves <john@groves.net> Reviewed-by: Richard Cheng <icheng@nvidia.com> Link: https://patch.msgid.link/0100019ecc08d74f-ec0d09b8-11e9-4e5b-af48-8c6d382af486-000000@email.amazonses.com Signed-off-by: Alison Schofield <alison.schofield@intel.com>
2026-04-13dax/fsdev: fix uninitialized kaddr in fsdev_dax_zero_page_range()John Groves1-1/+4
__fsdev_dax_direct_access() returns -EFAULT without setting *kaddr when dax_pgoff_to_phys() returns -1 (pgoff out of range). The return value was ignored, leaving kaddr uninitialized before being passed to fsdev_write_dax(). Check the return value and propagate the error. Thanks to Dan Carpenter and the smatch project for reporting this. Signed-off-by: John Groves <john@groves.net> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://patch.msgid.link/0100019d8262cda2-9714d31c-8fc1-4ca5-b32d-4df678240d14-000000@email.amazonses.com Signed-off-by: Ira Weiny <ira.weiny@intel.com>
2026-03-30dax: Add dax_set_ops() for setting dax_operations at bind timeJohn Groves1-0/+16
Add a new dax_set_ops() function that allows drivers to set the dax_operations after the dax_device has been allocated. This is needed for fsdev_dax where the operations need to be set during probe and cleared during unbind. The fsdev driver uses devm_add_action_or_reset() for cleanup consistency, avoiding the complexity of mixing devm-managed resources with manual cleanup in a remove() callback. This ensures cleanup happens automatically in the correct reverse order when the device is unbound. Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Signed-off-by: John Groves <john@groves.net> Link: https://patch.msgid.link/0100019d311d65a0-b9c1419e-f3a0-4afd-b0bd-848f18ff5950-000000@email.amazonses.com Signed-off-by: Ira Weiny <ira.weiny@intel.com>
2026-03-30dax: Add dax_operations for use by fs-dax on fsdev daxJohn Groves1-0/+84
fsdev: Add dax_operations for use by famfs. This replicates the functionality from drivers/nvdimm/pmem.c that conventional fs-dax file systems (e.g. xfs) use to support dax read/write/mmap to a daxdev - without which famfs can't sit atop a daxdev. - These methods are based on pmem_dax_ops from drivers/nvdimm/pmem.c - fsdev_dax_direct_access() returns the hpa, pfn and kva. The kva was newly stored as dev_dax->virt_addr by dev_dax_probe(). - The hpa/pfn are used for mmap (dax_iomap_fault()), and the kva is used for read/write (dax_iomap_rw()) - fsdev_dax_recovery_write() and dev_dax_zero_page_range() have not been tested yet. I'm looking for suggestions as to how to test those. - dax-private.h: add dev_dax->cached_size, which fsdev needs to remember. The dev_dax size cannot change while a driver is bound (dev_dax_resize returns -EBUSY if dev->driver is set). Caching the size at probe time allows fsdev's direct_access path can use it without acquiring dax_dev_rwsem (which isn't exported anyway). Signed-off-by: John Groves <john@groves.net> Link: https://patch.msgid.link/0100019d311d415a-bd6af0fe-5445-484c-9d39-210b8170b686-000000@email.amazonses.com Signed-off-by: Ira Weiny <ira.weiny@intel.com>
2026-03-30dax: Save the kva from memremapJohn Groves1-1/+2
Save the kva from memremap because we need it for iomap rw support. Prior to famfs, there were no iomap users of /dev/dax - so the virtual address from memremap was not needed. Reviewed-by: Ira Weiny <ira.weiny@intel.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Signed-off-by: John Groves <john@groves.net> Link: https://patch.msgid.link/0100019d311d1d08-dd372cb9-5934-43b8-bef8-089660d04a81-000000@email.amazonses.com Signed-off-by: Ira Weiny <ira.weiny@intel.com>
2026-03-30dax: add fsdev.c driver for fs-dax on character daxJohn Groves1-0/+245
The new fsdev driver provides pages/folios initialized compatibly with fsdax - normal rather than devdax-style refcounting, and starting out with order-0 folios. When fsdev binds to a daxdev, it is usually (always?) switching from the devdax mode (device.c), which pre-initializes compound folios according to its alignment. Fsdev uses fsdev_clear_folio_state() to switch the folios into a fsdax-compatible state. A side effect of this is that raw mmap doesn't (can't?) work on an fsdev dax instance. Accordingly, The fsdev driver does not provide raw mmap - devices must be put in 'devdax' mode (drivers/dax/device.c) to get raw mmap capability. In this commit is just the framework, which remaps pages/folios compatibly with fsdax. Enabling dax changes: - bus.h: add DAXDRV_FSDEV_TYPE driver type - bus.c: allow DAXDRV_FSDEV_TYPE drivers to bind to daxdevs - dax.h: prototype inode_dax(), which fsdev needs Suggested-by: Dan Williams <dan.j.williams@intel.com> Suggested-by: Gregory Price <gourry@gourry.net> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Signed-off-by: John Groves <john@groves.net> Link: https://patch.msgid.link/0100019d311cf904-419e9526-bdaf-4daa-97f1-5060b31a5c9f-000000@email.amazonses.com Signed-off-by: Ira Weiny <ira.weiny@intel.com>