block/bsg.c
Source file repositories/reference/linux-study-clean/block/bsg.c
File Facts
- System
- Linux kernel
- Corpus path
block/bsg.c- Extension
.c- Size
- 7273 bytes
- Lines
- 309
- 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/file.hlinux/blkdev.hlinux/cdev.hlinux/jiffies.hlinux/percpu.hlinux/idr.hlinux/bsg.hlinux/slab.hlinux/io_uring/cmd.hscsi/scsi.hscsi/scsi_ioctl.hscsi/sg.h
Detected Declarations
struct bsg_devicefunction bsg_timeoutfunction bsg_sg_iofunction bsg_openfunction bsg_releasefunction bsg_get_command_qfunction bsg_set_command_qfunction bsg_ioctlfunction bsg_check_uring_featuresfunction bsg_uring_cmdfunction bsg_device_releasefunction bsg_unregister_queuefunction bsg_initmodule init bsg_initexport bsg_unregister_queueexport bsg_register_queue
Annotated Snippet
static const struct file_operations bsg_fops = {
.open = bsg_open,
.release = bsg_release,
.unlocked_ioctl = bsg_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.uring_cmd = bsg_uring_cmd,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static void bsg_device_release(struct device *dev)
{
struct bsg_device *bd = container_of(dev, struct bsg_device, device);
ida_free(&bsg_minor_ida, MINOR(bd->device.devt));
kfree(bd);
}
void bsg_unregister_queue(struct bsg_device *bd)
{
struct gendisk *disk = bd->queue->disk;
if (disk && disk->queue_kobj.sd)
sysfs_remove_link(&disk->queue_kobj, "bsg");
cdev_device_del(&bd->cdev, &bd->device);
put_device(&bd->device);
}
EXPORT_SYMBOL_GPL(bsg_unregister_queue);
struct bsg_device *bsg_register_queue(struct request_queue *q,
struct device *parent, const char *name, bsg_sg_io_fn *sg_io_fn,
bsg_uring_cmd_fn *uring_cmd_fn)
{
struct bsg_device *bd;
int ret;
bd = kzalloc_obj(*bd);
if (!bd)
return ERR_PTR(-ENOMEM);
bd->max_queue = BSG_DEFAULT_CMDS;
bd->reserved_size = INT_MAX;
bd->queue = q;
bd->sg_io_fn = sg_io_fn;
bd->uring_cmd_fn = uring_cmd_fn;
ret = ida_alloc_max(&bsg_minor_ida, BSG_MAX_DEVS - 1, GFP_KERNEL);
if (ret < 0) {
if (ret == -ENOSPC)
dev_err(parent, "bsg: too many bsg devices\n");
kfree(bd);
return ERR_PTR(ret);
}
bd->device.devt = MKDEV(bsg_major, ret);
bd->device.class = &bsg_class;
bd->device.parent = parent;
bd->device.release = bsg_device_release;
dev_set_name(&bd->device, "%s", name);
device_initialize(&bd->device);
cdev_init(&bd->cdev, &bsg_fops);
bd->cdev.owner = THIS_MODULE;
ret = cdev_device_add(&bd->cdev, &bd->device);
if (ret)
goto out_put_device;
if (q->disk && q->disk->queue_kobj.sd) {
ret = sysfs_create_link(&q->disk->queue_kobj, &bd->device.kobj,
"bsg");
if (ret)
goto out_device_del;
}
return bd;
out_device_del:
cdev_device_del(&bd->cdev, &bd->device);
out_put_device:
put_device(&bd->device);
return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(bsg_register_queue);
static char *bsg_devnode(const struct device *dev, umode_t *mode)
{
return kasprintf(GFP_KERNEL, "bsg/%s", dev_name(dev));
}
static const struct class bsg_class = {
.name = "bsg",
.devnode = bsg_devnode,
Annotation
- Immediate include surface: `linux/module.h`, `linux/init.h`, `linux/file.h`, `linux/blkdev.h`, `linux/cdev.h`, `linux/jiffies.h`, `linux/percpu.h`, `linux/idr.h`.
- Detected declarations: `struct bsg_device`, `function bsg_timeout`, `function bsg_sg_io`, `function bsg_open`, `function bsg_release`, `function bsg_get_command_q`, `function bsg_set_command_q`, `function bsg_ioctl`, `function bsg_check_uring_features`, `function bsg_uring_cmd`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
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.