drivers/block/drbd/drbd_actlog.c
Source file repositories/reference/linux-study-clean/drivers/block/drbd/drbd_actlog.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/block/drbd/drbd_actlog.c- Extension
.c- Size
- 37198 bytes
- Lines
- 1237
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/slab.hlinux/crc32c.hlinux/drbd.hlinux/drbd_limits.hdrbd_int.h
Detected Declarations
enum al_transaction_typesfunction drbd_md_put_bufferfunction wait_until_done_or_force_detachedfunction _drbd_md_sync_page_iofunction drbd_md_sync_page_iofunction drbd_al_begin_io_fastpathfunction drbd_al_begin_io_preparefunction al_extent_to_bm_pagefunction al_tr_number_to_on_disk_sectorfunction __al_write_transactionfunction al_write_transactionfunction drbd_al_begin_io_commitfunction drbd_al_begin_iofunction drbd_al_begin_io_nonblockfunction drbd_al_complete_iofunction BUG_ONfunction _try_lc_delfunction drbd_al_shrinkfunction drbd_al_initializefunction get_ldevfunction drbd_advance_rs_marksfunction lazy_bitmap_update_duefunction maybe_schedule_on_disk_bitmap_updatefunction update_sync_bitsfunction plausible_request_sizefunction __drbd_change_syncfunction _is_in_alfunction drbd_rs_begin_iofunction drbd_try_rs_begin_iofunction drbd_rs_complete_iofunction drbd_rs_cancel_allfunction drbd_rs_del_all
Annotated Snippet
else if (!get_ldev_if_state(device, D_ATTACHING)) {
/* Corresponding put_ldev in drbd_md_endio() */
drbd_err(device, "ASSERT FAILED: get_ldev_if_state() == 1 in _drbd_md_sync_page_io()\n");
err = -ENODEV;
goto out;
}
bio_get(bio); /* one bio_put() is in the completion handler */
atomic_inc(&device->md_io.in_use); /* drbd_md_put_buffer() is in the completion handler */
device->md_io.submit_jif = jiffies;
if (drbd_insert_fault(device, (op == REQ_OP_WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD))
bio_io_error(bio);
else
submit_bio(bio);
wait_until_done_or_force_detached(device, bdev, &device->md_io.done);
if (!bio->bi_status)
err = device->md_io.error;
out:
bio_put(bio);
return err;
}
int drbd_md_sync_page_io(struct drbd_device *device, struct drbd_backing_dev *bdev,
sector_t sector, enum req_op op)
{
int err;
D_ASSERT(device, atomic_read(&device->md_io.in_use) == 1);
BUG_ON(!bdev->md_bdev);
dynamic_drbd_dbg(device, "meta_data io: %s [%d]:%s(,%llus,%s) %pS\n",
current->comm, current->pid, __func__,
(unsigned long long)sector, (op == REQ_OP_WRITE) ? "WRITE" : "READ",
(void*)_RET_IP_ );
if (sector < drbd_md_first_sector(bdev) ||
sector + 7 > drbd_md_last_sector(bdev))
drbd_alert(device, "%s [%d]:%s(,%llus,%s) out of range md access!\n",
current->comm, current->pid, __func__,
(unsigned long long)sector,
(op == REQ_OP_WRITE) ? "WRITE" : "READ");
err = _drbd_md_sync_page_io(device, bdev, sector, op);
if (err) {
drbd_err(device, "drbd_md_sync_page_io(,%llus,%s) failed with error %d\n",
(unsigned long long)sector,
(op == REQ_OP_WRITE) ? "WRITE" : "READ", err);
}
return err;
}
static struct bm_extent *find_active_resync_extent(struct drbd_device *device, unsigned int enr)
{
struct lc_element *tmp;
tmp = lc_find(device->resync, enr/AL_EXT_PER_BM_SECT);
if (unlikely(tmp != NULL)) {
struct bm_extent *bm_ext = lc_entry(tmp, struct bm_extent, lce);
if (test_bit(BME_NO_WRITES, &bm_ext->flags))
return bm_ext;
}
return NULL;
}
static struct lc_element *_al_get(struct drbd_device *device, unsigned int enr, bool nonblock)
{
struct lc_element *al_ext;
struct bm_extent *bm_ext;
int wake;
spin_lock_irq(&device->al_lock);
bm_ext = find_active_resync_extent(device, enr);
if (bm_ext) {
wake = !test_and_set_bit(BME_PRIORITY, &bm_ext->flags);
spin_unlock_irq(&device->al_lock);
if (wake)
wake_up(&device->al_wait);
return NULL;
}
if (nonblock)
al_ext = lc_try_get(device->act_log, enr);
else
al_ext = lc_get(device->act_log, enr);
spin_unlock_irq(&device->al_lock);
return al_ext;
}
bool drbd_al_begin_io_fastpath(struct drbd_device *device, struct drbd_interval *i)
{
/* for bios crossing activity log extent boundaries,
Annotation
- Immediate include surface: `linux/slab.h`, `linux/crc32c.h`, `linux/drbd.h`, `linux/drbd_limits.h`, `drbd_int.h`.
- Detected declarations: `enum al_transaction_types`, `function drbd_md_put_buffer`, `function wait_until_done_or_force_detached`, `function _drbd_md_sync_page_io`, `function drbd_md_sync_page_io`, `function drbd_al_begin_io_fastpath`, `function drbd_al_begin_io_prepare`, `function al_extent_to_bm_page`, `function al_tr_number_to_on_disk_sector`, `function __al_write_transaction`.
- 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.