drivers/nvme/host/core.c
Source file repositories/reference/linux-study-clean/drivers/nvme/host/core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/nvme/host/core.c- Extension
.c- Size
- 149601 bytes
- Lines
- 5521
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/async.hlinux/blkdev.hlinux/blk-mq.hlinux/blk-integrity.hlinux/compat.hlinux/delay.hlinux/errno.hlinux/hdreg.hlinux/kernel.hlinux/module.hlinux/backing-dev.hlinux/slab.hlinux/types.hlinux/pr.hlinux/ptrace.hlinux/nvme_ioctl.hlinux/pm_qos.hlinux/ratelimit.hlinux/unaligned.hnvme.hfabrics.hlinux/nvme-auth.htrace.h
Detected Declarations
struct nvme_ns_infostruct nvme_core_quirk_entrystruct async_scan_infoenum nvme_dispositionfunction nvme_queue_scanfunction nvme_try_sched_resetfunction nvme_failfast_workfunction nvme_start_failfast_workfunction nvme_stop_failfast_workfunction nvme_reset_ctrlfunction nvme_reset_ctrl_syncfunction nvme_do_delete_ctrlfunction nvme_delete_ctrl_workfunction nvme_delete_ctrlfunction nvme_delete_ctrl_syncfunction nvme_error_statusfunction nvme_retry_reqfunction nvme_log_errorfunction nvme_log_err_passthrufunction nvme_decide_dispositionfunction nvme_end_req_zonedfunction __nvme_end_reqfunction nvme_end_reqfunction __nvme_complete_rqfunction nvme_complete_rqfunction nvme_complete_batch_reqfunction nvme_host_path_errorfunction nvme_cancel_requestfunction nvme_cancel_tagsetfunction nvme_cancel_admin_tagsetfunction nvme_change_ctrl_statefunction nvme_wait_resetfunction nvme_free_ns_headfunction nvme_tryget_ns_headfunction nvme_put_ns_headfunction nvme_free_nsfunction nvme_get_nsfunction nvme_put_nsfunction nvme_clear_nvme_requestfunction nvme_init_requestfunction nvme_fail_nonready_commandfunction __nvme_check_readyfunction nvme_setup_flushfunction nvme_setup_discardfunction __rq_for_each_biofunction nvme_set_app_tagfunction nvme_set_ref_tagfunction nvme_setup_write_zeroes
Annotated Snippet
static const struct file_operations nvme_dev_fops = {
.owner = THIS_MODULE,
.open = nvme_dev_open,
.release = nvme_dev_release,
.unlocked_ioctl = nvme_dev_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.uring_cmd = nvme_dev_uring_cmd,
};
static struct nvme_ns_head *nvme_find_ns_head(struct nvme_ctrl *ctrl,
unsigned nsid)
{
struct nvme_ns_head *h;
lockdep_assert_held(&ctrl->subsys->lock);
list_for_each_entry(h, &ctrl->subsys->nsheads, entry) {
/*
* Private namespaces can share NSIDs under some conditions.
* In that case we can't use the same ns_head for namespaces
* with the same NSID.
*/
if (h->ns_id != nsid || !nvme_is_unique_nsid(ctrl, h))
continue;
if (nvme_tryget_ns_head(h))
return h;
}
return NULL;
}
static int nvme_subsys_check_duplicate_ids(struct nvme_subsystem *subsys,
struct nvme_ns_ids *ids)
{
bool has_uuid = !uuid_is_null(&ids->uuid);
bool has_nguid = memchr_inv(ids->nguid, 0, sizeof(ids->nguid));
bool has_eui64 = memchr_inv(ids->eui64, 0, sizeof(ids->eui64));
struct nvme_ns_head *h;
lockdep_assert_held(&subsys->lock);
list_for_each_entry(h, &subsys->nsheads, entry) {
if (has_uuid && uuid_equal(&ids->uuid, &h->ids.uuid))
return -EINVAL;
if (has_nguid &&
memcmp(&ids->nguid, &h->ids.nguid, sizeof(ids->nguid)) == 0)
return -EINVAL;
if (has_eui64 &&
memcmp(&ids->eui64, &h->ids.eui64, sizeof(ids->eui64)) == 0)
return -EINVAL;
}
return 0;
}
static void nvme_cdev_rel(struct device *dev)
{
ida_free(&nvme_ns_chr_minor_ida, MINOR(dev->devt));
}
void nvme_cdev_del(struct cdev *cdev, struct device *cdev_device)
{
cdev_device_del(cdev, cdev_device);
put_device(cdev_device);
}
int nvme_cdev_add(struct cdev *cdev, struct device *cdev_device,
const struct file_operations *fops, struct module *owner)
{
int minor, ret;
minor = ida_alloc(&nvme_ns_chr_minor_ida, GFP_KERNEL);
if (minor < 0)
return minor;
cdev_device->devt = MKDEV(MAJOR(nvme_ns_chr_devt), minor);
cdev_device->class = &nvme_ns_chr_class;
cdev_device->release = nvme_cdev_rel;
device_initialize(cdev_device);
cdev_init(cdev, fops);
cdev->owner = owner;
ret = cdev_device_add(cdev, cdev_device);
if (ret)
put_device(cdev_device);
return ret;
}
static int nvme_ns_chr_open(struct inode *inode, struct file *file)
{
return nvme_ns_open(container_of(inode->i_cdev, struct nvme_ns, cdev));
Annotation
- Immediate include surface: `linux/async.h`, `linux/blkdev.h`, `linux/blk-mq.h`, `linux/blk-integrity.h`, `linux/compat.h`, `linux/delay.h`, `linux/errno.h`, `linux/hdreg.h`.
- Detected declarations: `struct nvme_ns_info`, `struct nvme_core_quirk_entry`, `struct async_scan_info`, `enum nvme_disposition`, `function nvme_queue_scan`, `function nvme_try_sched_reset`, `function nvme_failfast_work`, `function nvme_start_failfast_work`, `function nvme_stop_failfast_work`, `function nvme_reset_ctrl`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.