drivers/block/drbd/drbd_req.c
Source file repositories/reference/linux-study-clean/drivers/block/drbd/drbd_req.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/block/drbd/drbd_req.c- Extension
.c- Size
- 56990 bytes
- Lines
- 1792
- Domain
- Driver Families
- Bucket
- drivers/block
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- 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/slab.hlinux/drbd.hdrbd_int.hdrbd_req.h
Detected Declarations
struct drbd_plug_cbfunction drbd_remove_request_intervalfunction drbd_req_destroyfunction bitfunction wake_all_sendersfunction start_new_tl_epochfunction complete_master_biofunction alonefunction _drbd_send_zc_biofunction drbd_req_put_completion_reffunction set_if_null_req_nextfunction advance_conn_req_nextfunction set_if_null_req_ack_pendingfunction advance_conn_req_ack_pendingfunction set_if_null_req_not_net_donefunction advance_conn_req_not_net_donefunction mod_rq_statefunction drbd_report_io_errorfunction writefunction __req_modfunction drbd_may_do_local_readfunction remote_due_to_read_balancingfunction complete_conflicting_writesfunction drbd_for_each_overlapfunction maybe_pull_aheadfunction do_remote_readfunction drbd_should_do_remotefunction drbd_should_send_out_of_syncfunction drbd_process_write_requestfunction drbd_process_discard_or_zeroes_reqfunction drbd_submit_req_private_biofunction drbd_queue_writefunction drbd_send_and_submitfunction may_do_writesfunction drbd_unplugfunction drbd_check_pluggedfunction drbd_update_plugfunction drbd_send_and_submitfunction __drbd_make_requestfunction submit_fast_pathfunction prepare_al_transaction_nonblockfunction send_and_submit_pendingfunction do_submitfunction drbd_submit_biofunction net_timeout_reachedfunction requestsfunction twice
Annotated Snippet
struct drbd_plug_cb {
struct blk_plug_cb cb;
struct drbd_request *most_recent_req;
/* do we need more? */
};
static void drbd_unplug(struct blk_plug_cb *cb, bool from_schedule)
{
struct drbd_plug_cb *plug = container_of(cb, struct drbd_plug_cb, cb);
struct drbd_resource *resource = plug->cb.data;
struct drbd_request *req = plug->most_recent_req;
kfree(cb);
if (!req)
return;
spin_lock_irq(&resource->req_lock);
/* In case the sender did not process it yet, raise the flag to
* have it followed with P_UNPLUG_REMOTE just after. */
req->rq_state |= RQ_UNPLUG;
/* but also queue a generic unplug */
drbd_queue_unplug(req->device);
kref_put(&req->kref, drbd_req_destroy);
spin_unlock_irq(&resource->req_lock);
}
static struct drbd_plug_cb* drbd_check_plugged(struct drbd_resource *resource)
{
/* A lot of text to say
* return (struct drbd_plug_cb*)blk_check_plugged(); */
struct drbd_plug_cb *plug;
struct blk_plug_cb *cb = blk_check_plugged(drbd_unplug, resource, sizeof(*plug));
if (cb)
plug = container_of(cb, struct drbd_plug_cb, cb);
else
plug = NULL;
return plug;
}
static void drbd_update_plug(struct drbd_plug_cb *plug, struct drbd_request *req)
{
struct drbd_request *tmp = plug->most_recent_req;
/* Will be sent to some peer.
* Remember to tag it with UNPLUG_REMOTE on unplug */
kref_get(&req->kref);
plug->most_recent_req = req;
if (tmp)
kref_put(&tmp->kref, drbd_req_destroy);
}
static void drbd_send_and_submit(struct drbd_device *device, struct drbd_request *req)
{
struct drbd_resource *resource = device->resource;
struct drbd_peer_device *peer_device = first_peer_device(device);
const int rw = bio_data_dir(req->master_bio);
struct bio_and_error m = { NULL, };
bool no_remote = false;
bool submit_private_bio = false;
spin_lock_irq(&resource->req_lock);
if (rw == WRITE) {
/* This may temporarily give up the req_lock,
* but will re-aquire it before it returns here.
* Needs to be before the check on drbd_suspended() */
complete_conflicting_writes(req);
/* no more giving up req_lock from now on! */
/* check for congestion, and potentially stop sending
* full data updates, but start sending "dirty bits" only. */
maybe_pull_ahead(device);
}
if (drbd_suspended(device)) {
/* push back and retry: */
req->rq_state |= RQ_POSTPONED;
if (req->private_bio) {
bio_put(req->private_bio);
req->private_bio = NULL;
put_ldev(device);
}
goto out;
}
/* We fail READ early, if we can not serve it.
* We must do this before req is registered on any lists.
* Otherwise, drbd_req_complete() will queue failed READ for retry. */
if (rw != WRITE) {
if (!do_remote_read(req) && !req->private_bio)
Annotation
- Immediate include surface: `linux/module.h`, `linux/slab.h`, `linux/drbd.h`, `drbd_int.h`, `drbd_req.h`.
- Detected declarations: `struct drbd_plug_cb`, `function drbd_remove_request_interval`, `function drbd_req_destroy`, `function bit`, `function wake_all_senders`, `function start_new_tl_epoch`, `function complete_master_bio`, `function alone`, `function _drbd_send_zc_bio`, `function drbd_req_put_completion_ref`.
- Atlas domain: Driver Families / drivers/block.
- Implementation status: source 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.