arch/um/drivers/ubd_kern.c
Source file repositories/reference/linux-study-clean/arch/um/drivers/ubd_kern.c
File Facts
- System
- Linux kernel
- Corpus path
arch/um/drivers/ubd_kern.c- Extension
.c- Size
- 36109 bytes
- Lines
- 1541
- Domain
- Architecture Layer
- Bucket
- arch/um
- Inferred role
- Architecture Layer: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- 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/module.hlinux/init.hlinux/blkdev.hlinux/blk-mq.hlinux/ata.hlinux/hdreg.hlinux/major.hlinux/cdrom.hlinux/proc_fs.hlinux/seq_file.hlinux/ctype.hlinux/slab.hlinux/vmalloc.hlinux/platform_device.hlinux/scatterlist.hkern_util.hmconsole_kern.hinit.hirq_kern.hubd.hos.hcow.h
Detected Declarations
struct io_descstruct io_thread_reqstruct cowstruct ubdfunction ubd_test_bitfunction ubd_set_bitfunction fake_ide_setupfunction parse_unitfunction ubd_setup_commonfunction ubd_setupfunction udb_setupfunction ubd_end_requestfunction ubd_intrfunction kill_io_threadfunction ubd_file_sizefunction read_cow_bitmapfunction backing_file_mismatchfunction path_requires_switchfunction open_ubd_filefunction create_cow_filefunction ubd_close_devfunction ubd_open_devfunction ubd_device_releasefunction serial_showfunction ubd_attrs_are_visiblefunction ubd_addfunction ubd_configfunction ubd_get_configfunction ubd_idfunction ubd_removefunction ubd_mc_initfunction ubd0_initfunction ubd_initfunction ubd_driver_initfunction cowify_bitmapfunction cowify_reqfunction ubd_map_reqfunction rq_for_each_segmentfunction ubd_submit_requestfunction ubd_queue_rqfunction ubd_getgeofunction ubd_ioctlfunction map_errorfunction update_bitmapfunction do_iomodule init ubd_driver_init
Annotated Snippet
static const struct blk_mq_ops ubd_mq_ops = {
.queue_rq = ubd_queue_rq,
};
static int ubd_add(int n, char **error_out)
{
struct ubd *ubd_dev = &ubd_devs[n];
struct queue_limits lim = {
.max_segments = MAX_SG,
.seg_boundary_mask = PAGE_SIZE - 1,
.features = BLK_FEAT_WRITE_CACHE,
};
struct gendisk *disk;
int err = 0;
if(ubd_dev->file == NULL)
goto out;
if (ubd_dev->cow.file)
lim.max_hw_sectors = 8 * sizeof(long);
if (!ubd_dev->no_trim) {
lim.max_hw_discard_sectors = UBD_MAX_REQUEST;
lim.max_write_zeroes_sectors = UBD_MAX_REQUEST;
}
err = ubd_file_size(ubd_dev, &ubd_dev->size);
if(err < 0){
*error_out = "Couldn't determine size of device's file";
goto out;
}
err = ubd_open_dev(ubd_dev);
if (err) {
pr_err("ubd%c: Can't open \"%s\": errno = %d\n",
'a' + n, ubd_dev->file, -err);
goto out;
}
ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
ubd_dev->tag_set.ops = &ubd_mq_ops;
ubd_dev->tag_set.queue_depth = 64;
ubd_dev->tag_set.numa_node = NUMA_NO_NODE;
ubd_dev->tag_set.driver_data = ubd_dev;
ubd_dev->tag_set.nr_hw_queues = 1;
err = blk_mq_alloc_tag_set(&ubd_dev->tag_set);
if (err)
goto out_close;
disk = blk_mq_alloc_disk(&ubd_dev->tag_set, &lim, ubd_dev);
if (IS_ERR(disk)) {
err = PTR_ERR(disk);
goto out_cleanup_tags;
}
disk->major = UBD_MAJOR;
disk->first_minor = n << UBD_SHIFT;
disk->minors = 1 << UBD_SHIFT;
disk->fops = &ubd_blops;
set_capacity(disk, ubd_dev->size / 512);
sprintf(disk->disk_name, "ubd%c", 'a' + n);
disk->private_data = ubd_dev;
set_disk_ro(disk, !ubd_dev->openflags.w);
ubd_dev->pdev.id = n;
ubd_dev->pdev.name = DRIVER_NAME;
ubd_dev->pdev.dev.release = ubd_device_release;
dev_set_drvdata(&ubd_dev->pdev.dev, ubd_dev);
platform_device_register(&ubd_dev->pdev);
err = device_add_disk(&ubd_dev->pdev.dev, disk, ubd_attr_groups);
if (err)
goto out_cleanup_disk;
ubd_dev->disk = disk;
return 0;
out_cleanup_disk:
put_disk(disk);
out_cleanup_tags:
blk_mq_free_tag_set(&ubd_dev->tag_set);
out_close:
ubd_close_dev(ubd_dev);
out:
return err;
}
static int ubd_config(char *str, char **error_out)
Annotation
- Immediate include surface: `linux/module.h`, `linux/init.h`, `linux/blkdev.h`, `linux/blk-mq.h`, `linux/ata.h`, `linux/hdreg.h`, `linux/major.h`, `linux/cdrom.h`.
- Detected declarations: `struct io_desc`, `struct io_thread_req`, `struct cow`, `struct ubd`, `function ubd_test_bit`, `function ubd_set_bit`, `function fake_ide_setup`, `function parse_unit`, `function ubd_setup_common`, `function ubd_setup`.
- Atlas domain: Architecture Layer / arch/um.
- 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.