drivers/dax/super.c

Source file repositories/reference/linux-study-clean/drivers/dax/super.c

File Facts

System
Linux kernel
Corpus path
drivers/dax/super.c
Extension
.c
Size
17611 bytes
Lines
713
Domain
Driver Families
Bucket
drivers/dax
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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.

Dependency Surface

Detected Declarations

Annotated Snippet

* via access_ok() in vfs_write, so use the 'no check' version to bypass
	 * the HARDENED_USERCOPY overhead.
	 */
	if (test_bit(DAXDEV_NOCACHE, &dax_dev->flags))
		return _copy_from_iter_flushcache(addr, bytes, i);
	return _copy_from_iter(addr, bytes, i);
}

size_t dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
		size_t bytes, struct iov_iter *i)
{
	if (!dax_alive(dax_dev))
		return 0;

	/*
	 * The userspace address for the memory copy has already been validated
	 * via access_ok() in vfs_red, so use the 'no check' version to bypass
	 * the HARDENED_USERCOPY overhead.
	 */
	if (test_bit(DAXDEV_NOMC, &dax_dev->flags))
		return _copy_mc_to_iter(addr, bytes, i);
	return _copy_to_iter(addr, bytes, i);
}

int dax_zero_page_range(struct dax_device *dax_dev, pgoff_t pgoff,
			size_t nr_pages)
{
	int ret;

	if (!dax_alive(dax_dev))
		return -ENXIO;

	if (!dax_dev->ops)
		return -EOPNOTSUPP;

	/*
	 * There are no callers that want to zero more than one page as of now.
	 * Once users are there, this check can be removed after the
	 * device mapper code has been updated to split ranges across targets.
	 */
	if (nr_pages != 1)
		return -EIO;

	ret = dax_dev->ops->zero_page_range(dax_dev, pgoff, nr_pages);
	return dax_mem2blk_err(ret);
}
EXPORT_SYMBOL_GPL(dax_zero_page_range);

size_t dax_recovery_write(struct dax_device *dax_dev, pgoff_t pgoff,
		void *addr, size_t bytes, struct iov_iter *iter)
{
	if (!dax_dev->ops || !dax_dev->ops->recovery_write)
		return 0;
	return dax_dev->ops->recovery_write(dax_dev, pgoff, addr, bytes, iter);
}
EXPORT_SYMBOL_GPL(dax_recovery_write);

int dax_holder_notify_failure(struct dax_device *dax_dev, u64 off,
			      u64 len, int mf_flags)
{
	int rc, id;

	id = dax_read_lock();
	if (!dax_alive(dax_dev)) {
		rc = -ENXIO;
		goto out;
	}

	if (!dax_dev->holder_ops) {
		rc = -EOPNOTSUPP;
		goto out;
	}

	rc = dax_dev->holder_ops->notify_failure(dax_dev, off, len, mf_flags);
out:
	dax_read_unlock(id);
	return rc;
}
EXPORT_SYMBOL_GPL(dax_holder_notify_failure);

#ifdef CONFIG_ARCH_HAS_PMEM_API
void arch_wb_cache_pmem(void *addr, size_t size);
void dax_flush(struct dax_device *dax_dev, void *addr, size_t size)
{
	if (unlikely(!dax_write_cache_enabled(dax_dev)))
		return;

	arch_wb_cache_pmem(addr, size);
}
#else

Annotation

Implementation Notes