drivers/block/drbd/drbd_receiver.c
Source file repositories/reference/linux-study-clean/drivers/block/drbd/drbd_receiver.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/block/drbd/drbd_receiver.c- Extension
.c- Size
- 175905 bytes
- Lines
- 5933
- 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/uaccess.hnet/sock.hlinux/drbd.hlinux/fs.hlinux/file.hlinux/in.hlinux/mm.hlinux/memcontrol.hlinux/mm_inline.hlinux/slab.huapi/linux/sched/types.hlinux/sched/signal.hlinux/pkt_sched.hlinux/unistd.hlinux/vmalloc.hlinux/random.hlinux/string.hlinux/scatterlist.hlinux/part_stat.hlinux/mempool.hdrbd_int.hdrbd_protocol.hdrbd_req.hdrbd_vli.h
Detected Declarations
struct packet_infostruct accept_wait_datastruct issue_flush_contextstruct one_flush_contextstruct data_cmdstruct meta_sock_cmdenum finish_epochfunction drbd_alloc_pagesfunction drbd_free_pagesfunction page_chain_for_each_safefunction drbd_alloc_peer_reqfunction drbd_free_peer_reqfunction drbd_free_peer_reqsfunction list_for_each_entry_safefunction _req_modfunction _drbd_wait_ee_list_emptyfunction drbd_wait_ee_list_emptyfunction drbd_recv_shortfunction drbd_recvfunction drbd_recv_allfunction drbd_recv_all_warnfunction listenfunction drbd_incoming_connectionfunction prepare_listen_socketfunction unregister_state_changefunction send_first_packetfunction receive_first_packetfunction drbd_socket_okayfunction connection_establishedfunction drbd_connectedfunction conn_connectfunction decode_headerfunction drbd_unplug_all_devicesfunction drbd_recv_headerfunction drbd_recv_header_maybe_unplugfunction one_flush_endiofunction submit_one_flushfunction drbd_flushfunction idr_for_each_entryfunction drbd_may_finish_epochfunction max_allowed_wofunction drbd_bump_write_orderingfunction unalignedfunction can_do_reliable_discardsfunction drbd_issue_peer_discard_or_zero_outfunction peer_request_fault_typefunction drbd_submit_peer_requestfunction blkdev_issue_zeroout
Annotated Snippet
struct packet_info {
enum drbd_packet cmd;
unsigned int size;
unsigned int vnr;
void *data;
};
enum finish_epoch {
FE_STILL_LIVE,
FE_DESTROYED,
FE_RECYCLED,
};
static int drbd_do_features(struct drbd_connection *connection);
static int drbd_do_auth(struct drbd_connection *connection);
static int drbd_disconnected(struct drbd_peer_device *);
static void conn_wait_active_ee_empty(struct drbd_connection *connection);
static enum finish_epoch drbd_may_finish_epoch(struct drbd_connection *, struct drbd_epoch *, enum epoch_event);
static int e_end_block(struct drbd_work *, int);
#define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN)
static struct page *__drbd_alloc_pages(unsigned int number)
{
struct page *page = NULL;
struct page *tmp = NULL;
unsigned int i = 0;
/* GFP_TRY, because we must not cause arbitrary write-out: in a DRBD
* "criss-cross" setup, that might cause write-out on some other DRBD,
* which in turn might block on the other node at this very place. */
for (i = 0; i < number; i++) {
tmp = mempool_alloc(&drbd_buffer_page_pool, GFP_TRY);
if (!tmp)
goto fail;
set_page_private(tmp, (unsigned long)page);
page = tmp;
}
return page;
fail:
page_chain_for_each_safe(page, tmp) {
set_page_private(page, 0);
mempool_free(page, &drbd_buffer_page_pool);
}
return NULL;
}
/**
* drbd_alloc_pages() - Returns @number pages, retries forever (or until signalled)
* @peer_device: DRBD device.
* @number: number of pages requested
* @retry: whether to retry, if not enough pages are available right now
*
* Tries to allocate number pages, first from our own page pool, then from
* the kernel.
* Possibly retry until DRBD frees sufficient pages somewhere else.
*
* If this allocation would exceed the max_buffers setting, we throttle
* allocation (schedule_timeout) to give the system some room to breathe.
*
* We do not use max-buffers as hard limit, because it could lead to
* congestion and further to a distributed deadlock during online-verify or
* (checksum based) resync, if the max-buffers, socket buffer sizes and
* resync-rate settings are mis-configured.
*
* Returns a page chain linked via page->private.
*/
struct page *drbd_alloc_pages(struct drbd_peer_device *peer_device, unsigned int number,
bool retry)
{
struct drbd_device *device = peer_device->device;
struct page *page;
struct net_conf *nc;
unsigned int mxb;
rcu_read_lock();
nc = rcu_dereference(peer_device->connection->net_conf);
mxb = nc ? nc->max_buffers : 1000000;
rcu_read_unlock();
if (atomic_read(&device->pp_in_use) >= mxb)
schedule_timeout_interruptible(HZ / 10);
page = __drbd_alloc_pages(number);
if (page)
atomic_add(number, &device->pp_in_use);
return page;
}
Annotation
- Immediate include surface: `linux/module.h`, `linux/uaccess.h`, `net/sock.h`, `linux/drbd.h`, `linux/fs.h`, `linux/file.h`, `linux/in.h`, `linux/mm.h`.
- Detected declarations: `struct packet_info`, `struct accept_wait_data`, `struct issue_flush_context`, `struct one_flush_context`, `struct data_cmd`, `struct meta_sock_cmd`, `enum finish_epoch`, `function drbd_alloc_pages`, `function drbd_free_pages`, `function page_chain_for_each_safe`.
- 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.