drivers/block/null_blk/main.c
Source file repositories/reference/linux-study-clean/drivers/block/null_blk/main.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/block/null_blk/main.c- Extension
.c- Size
- 57744 bytes
- Lines
- 2224
- 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.
- 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/module.hlinux/moduleparam.hlinux/sched.hlinux/fs.hlinux/init.hnull_blk.h
Detected Declarations
struct nullb_pageenum nullb_device_flagsfunction mb_per_tickfunction null_param_store_valfunction null_set_queue_modefunction null_set_irqmodefunction nullb_device_uint_attr_showfunction nullb_device_ulong_attr_showfunction nullb_device_bool_attr_showfunction nullb_device_uint_attr_storefunction nullb_device_ulong_attr_storefunction nullb_device_bool_attr_storefunction nullb_update_nr_hw_queuesfunction nullb_apply_submit_queuesfunction nullb_apply_poll_queuesfunction nullb_device_power_showfunction nullb_device_power_storefunction nullb_device_badblocks_showfunction nullb_device_badblocks_storefunction nullb_device_zone_readonly_storefunction nullb_device_zone_offline_storefunction nullb_device_releasefunction nullb_add_fault_configfunction nullb_del_fault_configfunction nullb_add_fault_configfunction nullb_group_drop_itemfunction memb_group_features_showfunction null_cache_activefunction null_free_devfunction null_cmd_timer_expiredfunction null_cmd_end_timerfunction null_complete_rqfunction null_free_pagefunction null_page_emptyfunction null_free_sectorfunction null_free_device_storagefunction null_flush_cache_pagefunction null_make_cache_spacefunction copy_to_nullbfunction copy_from_nullbfunction null_handle_discardfunction null_handle_flushfunction null_transferfunction null_handle_data_transferfunction null_handle_throttledfunction null_handle_badblocksfunction null_handle_memory_backedfunction nullb_zero_read_cmd_buffer
Annotated Snippet
static const struct blk_mq_ops null_mq_ops = {
.queue_rq = null_queue_rq,
.queue_rqs = null_queue_rqs,
.complete = null_complete_rq,
.timeout = null_timeout_rq,
.poll = null_poll,
.map_queues = null_map_queues,
.init_hctx = null_init_hctx,
};
static void null_del_dev(struct nullb *nullb)
{
struct nullb_device *dev;
if (!nullb)
return;
dev = nullb->dev;
ida_free(&nullb_indexes, nullb->index);
list_del_init(&nullb->list);
del_gendisk(nullb->disk);
if (test_bit(NULLB_DEV_FL_THROTTLED, &nullb->dev->flags)) {
hrtimer_cancel(&nullb->bw_timer);
atomic_long_set(&nullb->cur_bytes, LONG_MAX);
blk_mq_start_stopped_hw_queues(nullb->q, true);
}
put_disk(nullb->disk);
if (nullb->tag_set == &nullb->__tag_set)
blk_mq_free_tag_set(nullb->tag_set);
kfree(nullb->queues);
if (null_cache_active(nullb))
null_free_device_storage(nullb->dev, true);
kfree(nullb);
dev->nullb = NULL;
}
static void null_config_discard(struct nullb *nullb, struct queue_limits *lim)
{
if (nullb->dev->discard == false)
return;
if (!nullb->dev->memory_backed) {
nullb->dev->discard = false;
pr_info("discard option is ignored without memory backing\n");
return;
}
if (nullb->dev->zoned) {
nullb->dev->discard = false;
pr_info("discard option is ignored in zoned mode\n");
return;
}
lim->max_hw_discard_sectors = UINT_MAX >> 9;
}
static const struct block_device_operations null_ops = {
.owner = THIS_MODULE,
.report_zones = null_report_zones,
};
static int setup_queues(struct nullb *nullb)
{
int nqueues = nr_cpu_ids;
if (g_poll_queues)
nqueues += g_poll_queues;
nullb->queues = kzalloc_objs(struct nullb_queue, nqueues);
if (!nullb->queues)
return -ENOMEM;
return 0;
}
static int null_init_tag_set(struct blk_mq_tag_set *set, int poll_queues)
{
set->ops = &null_mq_ops;
set->cmd_size = sizeof(struct nullb_cmd);
set->timeout = 5 * HZ;
set->nr_maps = 1;
if (poll_queues) {
set->nr_hw_queues += poll_queues;
set->nr_maps += 2;
}
Annotation
- Immediate include surface: `linux/module.h`, `linux/moduleparam.h`, `linux/sched.h`, `linux/fs.h`, `linux/init.h`, `null_blk.h`.
- Detected declarations: `struct nullb_page`, `enum nullb_device_flags`, `function mb_per_tick`, `function null_param_store_val`, `function null_set_queue_mode`, `function null_set_irqmode`, `function nullb_device_uint_attr_show`, `function nullb_device_ulong_attr_show`, `function nullb_device_bool_attr_show`, `function nullb_device_uint_attr_store`.
- Atlas domain: Driver Families / drivers/block.
- 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.