drivers/block/xen-blkfront.c
Source file repositories/reference/linux-study-clean/drivers/block/xen-blkfront.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/block/xen-blkfront.c- Extension
.c- Size
- 72981 bytes
- Lines
- 2643
- Domain
- Driver Families
- Bucket
- drivers/block
- 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/interrupt.hlinux/blkdev.hlinux/blk-mq.hlinux/hdreg.hlinux/cdrom.hlinux/module.hlinux/slab.hlinux/major.hlinux/mutex.hlinux/scatterlist.hlinux/bitmap.hlinux/list.hlinux/workqueue.hlinux/sched/mm.hxen/xen.hxen/xenbus.hxen/grant_table.hxen/events.hxen/page.hxen/platform_pci.hxen/interface/grant_table.hxen/interface/io/blkif.hxen/interface/io/protocols.hasm/xen/hypervisor.h
Detected Declarations
struct grantstruct blk_shadowstruct blkif_reqstruct blkfront_ring_infostruct blkfront_infostruct setup_rw_reqstruct copy_from_grantenum blkif_stateenum blk_req_statusfunction get_rinfofunction get_id_from_freelistfunction add_id_to_freelistfunction fill_grant_bufferfunction grant_foreign_accessfunction xlbd_reserve_minorsfunction xlbd_release_minorsfunction blkif_restart_queue_callbackfunction blkif_getgeofunction blkif_ioctlfunction blkif_ring_get_requestfunction blkif_queue_discard_reqfunction blkif_setup_rw_req_grantfunction blkif_setup_extra_reqfunction blkif_queue_rw_reqfunction likelyfunction for_each_sgfunction blkif_queue_requestfunction flush_requestsfunction blkif_queue_rqfunction blkif_complete_rqfunction blkif_set_queue_limitsfunction xlvbd_flushfunction xen_translate_vdevfunction xlvbd_alloc_gendiskfunction kick_pending_request_queues_lockedfunction kick_pending_request_queuesfunction blkif_restart_queuefunction blkif_free_ringfunction list_for_each_entry_safefunction list_for_each_entry_safefunction blkif_freefunction blkif_copy_from_grantfunction blkif_rsp_to_req_statusfunction blkif_get_final_statusfunction blkif_completionfunction blkif_interruptfunction itfunction setup_blkring
Annotated Snippet
static const struct blk_mq_ops blkfront_mq_ops = {
.queue_rq = blkif_queue_rq,
.complete = blkif_complete_rq,
};
static void blkif_set_queue_limits(const struct blkfront_info *info,
struct queue_limits *lim)
{
unsigned int segments = info->max_indirect_segments ? :
BLKIF_MAX_SEGMENTS_PER_REQUEST;
if (info->feature_discard) {
lim->max_hw_discard_sectors = UINT_MAX;
if (info->discard_granularity)
lim->discard_granularity = info->discard_granularity;
lim->discard_alignment = info->discard_alignment;
if (info->feature_secdiscard)
lim->max_secure_erase_sectors = UINT_MAX;
}
if (info->feature_flush) {
lim->features |= BLK_FEAT_WRITE_CACHE;
if (info->feature_fua)
lim->features |= BLK_FEAT_FUA;
}
/* Hard sector size and max sectors impersonate the equiv. hardware. */
lim->logical_block_size = info->sector_size;
lim->physical_block_size = info->physical_sector_size;
lim->max_hw_sectors = (segments * XEN_PAGE_SIZE) / 512;
/* Each segment in a request is up to an aligned page in size. */
lim->seg_boundary_mask = PAGE_SIZE - 1;
lim->max_segment_size = PAGE_SIZE;
/* Ensure a merged request will fit in a single I/O ring slot. */
lim->max_segments = segments / GRANTS_PER_PSEG;
/* Make sure buffer addresses are sector-aligned. */
lim->dma_alignment = 511;
}
static const char *flush_info(struct blkfront_info *info)
{
if (info->feature_flush && info->feature_fua)
return "barrier: enabled;";
else if (info->feature_flush)
return "flush diskcache: enabled;";
else
return "barrier or flush: disabled;";
}
static void xlvbd_flush(struct blkfront_info *info)
{
pr_info("blkfront: %s: %s %s %s %s %s %s %s\n",
info->gd->disk_name, flush_info(info),
"persistent grants:", info->feature_persistent ?
"enabled;" : "disabled;", "indirect descriptors:",
info->max_indirect_segments ? "enabled;" : "disabled;",
"bounce buffer:", info->bounce ? "enabled" : "disabled;");
}
static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset)
{
int major;
major = BLKIF_MAJOR(vdevice);
*minor = BLKIF_MINOR(vdevice);
switch (major) {
case XEN_IDE0_MAJOR:
*offset = (*minor / 64) + EMULATED_HD_DISK_NAME_OFFSET;
*minor = ((*minor / 64) * PARTS_PER_DISK) +
EMULATED_HD_DISK_MINOR_OFFSET;
break;
case XEN_IDE1_MAJOR:
*offset = (*minor / 64) + 2 + EMULATED_HD_DISK_NAME_OFFSET;
*minor = (((*minor / 64) + 2) * PARTS_PER_DISK) +
EMULATED_HD_DISK_MINOR_OFFSET;
break;
case XEN_SCSI_DISK0_MAJOR:
*offset = (*minor / PARTS_PER_DISK) + EMULATED_SD_DISK_NAME_OFFSET;
*minor = *minor + EMULATED_SD_DISK_MINOR_OFFSET;
break;
case XEN_SCSI_DISK1_MAJOR:
case XEN_SCSI_DISK2_MAJOR:
case XEN_SCSI_DISK3_MAJOR:
case XEN_SCSI_DISK4_MAJOR:
case XEN_SCSI_DISK5_MAJOR:
case XEN_SCSI_DISK6_MAJOR:
case XEN_SCSI_DISK7_MAJOR:
*offset = (*minor / PARTS_PER_DISK) +
Annotation
- Immediate include surface: `linux/interrupt.h`, `linux/blkdev.h`, `linux/blk-mq.h`, `linux/hdreg.h`, `linux/cdrom.h`, `linux/module.h`, `linux/slab.h`, `linux/major.h`.
- Detected declarations: `struct grant`, `struct blk_shadow`, `struct blkif_req`, `struct blkfront_ring_info`, `struct blkfront_info`, `struct setup_rw_req`, `struct copy_from_grant`, `enum blkif_state`, `enum blk_req_status`, `function get_rinfo`.
- Atlas domain: Driver Families / drivers/block.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.