drivers/block/drbd/drbd_worker.c

Source file repositories/reference/linux-study-clean/drivers/block/drbd/drbd_worker.c

File Facts

System
Linux kernel
Corpus path
drivers/block/drbd/drbd_worker.c
Extension
.c
Size
65438 bytes
Lines
2224
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.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (bio_op(bio)) {
		case REQ_OP_WRITE_ZEROES:
		case REQ_OP_DISCARD:
			if (bio->bi_status == BLK_STS_NOTSUPP)
				what = DISCARD_COMPLETED_NOTSUPP;
			else
				what = DISCARD_COMPLETED_WITH_ERROR;
			break;
		case REQ_OP_READ:
			if (bio->bi_opf & REQ_RAHEAD)
				what = READ_AHEAD_COMPLETED_WITH_ERROR;
			else
				what = READ_COMPLETED_WITH_ERROR;
			break;
		default:
			what = WRITE_COMPLETED_WITH_ERROR;
			break;
		}
	} else {
		what = COMPLETED_OK;
	}

	req->private_bio = ERR_PTR(blk_status_to_errno(bio->bi_status));
	bio_put(bio);

	/* not req_mod(), we need irqsave here! */
	spin_lock_irqsave(&device->resource->req_lock, flags);
	__req_mod(req, what, NULL, &m);
	spin_unlock_irqrestore(&device->resource->req_lock, flags);
	put_ldev(device);

	if (m.bio)
		complete_master_bio(device, &m);
}

void drbd_csum_ee(struct crypto_shash *tfm, struct drbd_peer_request *peer_req, void *digest)
{
	SHASH_DESC_ON_STACK(desc, tfm);
	struct page *page = peer_req->pages;
	struct page *tmp;
	unsigned len;
	void *src;

	desc->tfm = tfm;

	crypto_shash_init(desc);

	src = kmap_atomic(page);
	while ((tmp = page_chain_next(page))) {
		/* all but the last page will be fully used */
		crypto_shash_update(desc, src, PAGE_SIZE);
		kunmap_atomic(src);
		page = tmp;
		src = kmap_atomic(page);
	}
	/* and now the last, possibly only partially used page */
	len = peer_req->i.size & (PAGE_SIZE - 1);
	crypto_shash_update(desc, src, len ?: PAGE_SIZE);
	kunmap_atomic(src);

	crypto_shash_final(desc, digest);
	shash_desc_zero(desc);
}

void drbd_csum_bio(struct crypto_shash *tfm, struct bio *bio, void *digest)
{
	SHASH_DESC_ON_STACK(desc, tfm);
	struct bio_vec bvec;
	struct bvec_iter iter;

	desc->tfm = tfm;

	crypto_shash_init(desc);

	bio_for_each_segment(bvec, bio, iter) {
		u8 *src;

		src = bvec_kmap_local(&bvec);
		crypto_shash_update(desc, src, bvec.bv_len);
		kunmap_local(src);
	}
	crypto_shash_final(desc, digest);
	shash_desc_zero(desc);
}

/* MAYBE merge common code with w_e_end_ov_req */
static int w_e_send_csum(struct drbd_work *w, int cancel)
{
	struct drbd_peer_request *peer_req = container_of(w, struct drbd_peer_request, w);
	struct drbd_peer_device *peer_device = peer_req->peer_device;

Annotation

Implementation Notes