drivers/dax/fsdev.c
Source file repositories/reference/linux-study-clean/drivers/dax/fsdev.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/dax/fsdev.c- Extension
.c- Size
- 9434 bytes
- Lines
- 350
- Domain
- Driver Families
- Bucket
- drivers/dax
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/memremap.hlinux/pagemap.hlinux/module.hlinux/device.hlinux/cdev.hlinux/slab.hlinux/dax.hlinux/uio.hlinux/fs.hlinux/mm.hdax-private.hbus.h
Detected Declarations
function alignmentfunction __fsdev_dax_direct_accessfunction fsdev_dax_zero_page_rangefunction fsdev_dax_direct_accessfunction fsdev_dax_recovery_writefunction fsdev_cdev_delfunction fsdev_killfunction fsdev_clear_opsfunction free_zone_device_foliofunction fsdev_clear_folio_statefunction fsdev_clear_folio_state_actionfunction fsdev_openfunction fsdev_releasefunction fsdev_dax_probefunction dax_initfunction dax_exitmodule init dax_init
Annotated Snippet
static const struct file_operations fsdev_fops = {
.llseek = noop_llseek,
.owner = THIS_MODULE,
.open = fsdev_open,
.release = fsdev_release,
};
static int fsdev_dax_probe(struct dev_dax *dev_dax)
{
struct dax_device *dax_dev = dev_dax->dax_dev;
struct device *dev = &dev_dax->dev;
struct dev_pagemap *pgmap;
struct inode *inode;
u64 data_offset = 0;
struct cdev *cdev;
void *addr;
int rc, i;
if (static_dev_dax(dev_dax)) {
if (dev_dax->nr_range > 1) {
dev_warn(dev, "static pgmap / multi-range device conflict\n");
return -EINVAL;
}
pgmap = dev_dax->pgmap;
} else {
size_t pgmap_size;
if (dev_dax->pgmap) {
dev_warn(dev, "dynamic-dax with pre-populated page map\n");
return -EINVAL;
}
pgmap_size = struct_size(pgmap, ranges, dev_dax->nr_range - 1);
pgmap = devm_kzalloc(dev, pgmap_size, GFP_KERNEL);
if (!pgmap)
return -ENOMEM;
pgmap->nr_range = dev_dax->nr_range;
dev_dax->pgmap = pgmap;
for (i = 0; i < dev_dax->nr_range; i++) {
struct range *range = &dev_dax->ranges[i].range;
pgmap->ranges[i] = *range;
}
}
for (i = 0; i < dev_dax->nr_range; i++) {
struct range *range = &dev_dax->ranges[i].range;
if (!devm_request_mem_region(dev, range->start,
range_len(range), dev_name(dev))) {
dev_warn(dev, "mapping%d: %#llx-%#llx could not reserve range\n",
i, range->start, range->end);
return -EBUSY;
}
}
/* Cache size now; it cannot change while driver is bound */
dev_dax->cached_size = 0;
for (i = 0; i < dev_dax->nr_range; i++)
dev_dax->cached_size += range_len(&dev_dax->ranges[i].range);
/*
* Use MEMORY_DEVICE_FS_DAX without setting vmemmap_shift, leaving
* folios at order-0. Unlike device.c (MEMORY_DEVICE_GENERIC), this
* lets fs-dax dynamically build compound folios as needed, similar
* to pmem behavior.
*/
pgmap->type = MEMORY_DEVICE_FS_DAX;
pgmap->ops = &fsdev_pagemap_ops;
pgmap->owner = dev_dax;
addr = devm_memremap_pages(dev, pgmap);
if (IS_ERR(addr))
return PTR_ERR(addr);
/*
* Clear any stale compound folio state left over from a previous
* driver (e.g., device_dax with vmemmap_shift). Also register this
* as a devm action so folio state is cleared on unbind, ensuring
* clean pages for subsequent drivers (e.g., kmem for system-ram).
*/
fsdev_clear_folio_state(dev_dax);
rc = devm_add_action_or_reset(dev, fsdev_clear_folio_state_action,
dev_dax);
if (rc)
return rc;
Annotation
- Immediate include surface: `linux/memremap.h`, `linux/pagemap.h`, `linux/module.h`, `linux/device.h`, `linux/cdev.h`, `linux/slab.h`, `linux/dax.h`, `linux/uio.h`.
- Detected declarations: `function alignment`, `function __fsdev_dax_direct_access`, `function fsdev_dax_zero_page_range`, `function fsdev_dax_direct_access`, `function fsdev_dax_recovery_write`, `function fsdev_cdev_del`, `function fsdev_kill`, `function fsdev_clear_ops`, `function free_zone_device_folio`, `function fsdev_clear_folio_state`.
- Atlas domain: Driver Families / drivers/dax.
- Implementation status: pattern implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.