block/blk-merge.c
Source file repositories/reference/linux-study-clean/block/blk-merge.c
File Facts
- System
- Linux kernel
- Corpus path
block/blk-merge.c- Extension
.c- Size
- 32317 bytes
- Lines
- 1169
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/bio.hlinux/blkdev.hlinux/blk-integrity.hlinux/part_stat.hlinux/blk-cgroup.htrace/events/block.hblk.hblk-mq-sched.hblk-rq-qos.hblk-throttle.h
Detected Declarations
function bio_get_first_bvecfunction bio_get_last_bvecfunction bio_will_gapfunction req_gap_back_mergefunction req_gap_front_mergefunction bio_allowed_max_sectorsfunction blk_boundary_sectorsfunction get_max_io_sizefunction bvec_split_segsfunction bio_split_alignmentfunction bvec_seg_gapfunction bio_split_io_atfunction bio_for_each_bvecfunction blk_recalc_rq_segmentsfunction blk_rq_get_max_sectorsfunction ll_new_hw_segmentfunction ll_back_merge_fnfunction blk_rq_get_max_sectorsfunction ll_front_merge_fnfunction blk_rq_get_max_sectorsfunction req_attempt_discard_mergefunction ll_merge_requests_fnfunction blk_rq_set_mixed_mergefunction bio_failfastfunction blk_update_mixed_mergefunction blk_account_io_merge_requestfunction blk_try_req_mergefunction blk_atomic_write_mergeable_rq_biofunction blk_atomic_write_mergeable_rqsfunction bio_seg_gapfunction blk_attempt_req_mergefunction blk_rq_merge_okfunction blk_try_mergefunction blk_account_io_merge_biofunction bio_attempt_back_mergefunction bio_attempt_front_mergefunction bio_attempt_discard_mergefunction blk_attempt_bio_mergefunction blk_attempt_plug_mergefunction rq_list_for_eachfunction blk_bio_list_mergefunction list_for_each_entry_reversefunction blk_mq_sched_try_mergeexport bio_submit_split_biosetexport bio_split_io_atexport bio_split_to_limitsexport blk_bio_list_mergeexport blk_mq_sched_try_merge
Annotated Snippet
if (bvprvp) {
if (bvec_gap_to_prev(lim, bvprvp, bv.bv_offset))
goto split;
gaps |= bvec_seg_gap(bvprvp, &bv);
}
if (nsegs < lim->max_segments &&
bytes + bv.bv_len <= max_bytes &&
bv.bv_offset + bv.bv_len <= lim->max_fast_segment_size) {
nsegs++;
bytes += bv.bv_len;
} else {
if (bvec_split_segs(lim, &bv, &nsegs, &bytes,
lim->max_segments, max_bytes))
goto split;
}
bvprv = bv;
bvprvp = &bvprv;
}
*segs = nsegs;
bio->bi_bvec_gap_bit = ffs(gaps);
return 0;
split:
if (bio->bi_opf & REQ_ATOMIC)
return -EINVAL;
/*
* We can't sanely support splitting for a REQ_NOWAIT bio. End it
* with EAGAIN if splitting is required and return an error pointer.
*/
if (bio->bi_opf & REQ_NOWAIT)
return -EAGAIN;
*segs = nsegs;
/*
* Individual bvecs might not be logical block aligned. Round down the
* split size so that each bio is properly block size aligned, even if
* we do not use the full hardware limits.
*
* It is possible to submit a bio that can't be split into a valid io:
* there may either be too many discontiguous vectors for the max
* segments limit, or contain virtual boundary gaps without having a
* valid block sized split. A zero byte result means one of those
* conditions occured.
*/
bytes = ALIGN_DOWN(bytes, bio_split_alignment(bio, lim));
if (!bytes)
return -EINVAL;
/*
* Bio splitting may cause subtle trouble such as hang when doing sync
* iopoll in direct IO routine. Given performance gain of iopoll for
* big IO can be trival, disable iopoll when split needed.
*/
bio_clear_polled(bio);
bio->bi_bvec_gap_bit = ffs(gaps);
return bytes >> SECTOR_SHIFT;
}
EXPORT_SYMBOL_GPL(bio_split_io_at);
struct bio *bio_split_rw(struct bio *bio, const struct queue_limits *lim,
unsigned *nr_segs)
{
return bio_submit_split(bio,
bio_split_rw_at(bio, lim, nr_segs,
get_max_io_size(bio, lim) << SECTOR_SHIFT));
}
/*
* REQ_OP_ZONE_APPEND bios must never be split by the block layer.
*
* But we want the nr_segs calculation provided by bio_split_rw_at, and having
* a good sanity check that the submitter built the bio correctly is nice to
* have as well.
*/
struct bio *bio_split_zone_append(struct bio *bio,
const struct queue_limits *lim, unsigned *nr_segs)
{
int split_sectors;
split_sectors = bio_split_rw_at(bio, lim, nr_segs,
lim->max_zone_append_sectors << SECTOR_SHIFT);
if (WARN_ON_ONCE(split_sectors > 0))
split_sectors = -EINVAL;
return bio_submit_split(bio, split_sectors);
}
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/bio.h`, `linux/blkdev.h`, `linux/blk-integrity.h`, `linux/part_stat.h`, `linux/blk-cgroup.h`, `trace/events/block.h`.
- Detected declarations: `function bio_get_first_bvec`, `function bio_get_last_bvec`, `function bio_will_gap`, `function req_gap_back_merge`, `function req_gap_front_merge`, `function bio_allowed_max_sectors`, `function blk_boundary_sectors`, `function get_max_io_size`, `function bvec_split_segs`, `function bio_split_alignment`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: integration 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.