drivers/md/bcache/movinggc.c

Source file repositories/reference/linux-study-clean/drivers/md/bcache/movinggc.c

File Facts

System
Linux kernel
Corpus path
drivers/md/bcache/movinggc.c
Extension
.c
Size
5378 bytes
Lines
253
Domain
Driver Families
Bucket
drivers/md
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

struct moving_io {
	struct closure		cl;
	struct keybuf_key	*w;
	struct data_insert_op	op;
	struct bbio		bio;
};

static bool moving_pred(struct keybuf *buf, struct bkey *k)
{
	struct cache_set *c = container_of(buf, struct cache_set,
					   moving_gc_keys);
	unsigned int i;

	for (i = 0; i < KEY_PTRS(k); i++)
		if (ptr_available(c, k, i) &&
		    GC_MOVE(PTR_BUCKET(c, k, i)))
			return true;

	return false;
}

/* Moving GC - IO loop */

static CLOSURE_CALLBACK(moving_io_destructor)
{
	closure_type(io, struct moving_io, cl);

	kfree(io);
}

static CLOSURE_CALLBACK(write_moving_finish)
{
	closure_type(io, struct moving_io, cl);
	struct bio *bio = &io->bio.bio;

	bio_free_pages(bio);

	if (io->op.replace_collision)
		trace_bcache_gc_copy_collision(&io->w->key);

	bch_keybuf_del(&io->op.c->moving_gc_keys, io->w);

	up(&io->op.c->moving_in_flight);

	closure_return_with_destructor(cl, moving_io_destructor);
}

static void read_moving_endio(struct bio *bio)
{
	struct bbio *b = container_of(bio, struct bbio, bio);
	struct moving_io *io = container_of(bio->bi_private,
					    struct moving_io, cl);

	if (bio->bi_status)
		io->op.status = bio->bi_status;
	else if (!KEY_DIRTY(&b->key) &&
		 ptr_stale(io->op.c, &b->key, 0)) {
		io->op.status = BLK_STS_IOERR;
	}

	bch_bbio_endio(io->op.c, bio, bio->bi_status, "reading data to move");
}

static void moving_init(struct moving_io *io)
{
	struct bio *bio = &io->bio.bio;

	bio_init_inline(bio, NULL,
		 DIV_ROUND_UP(KEY_SIZE(&io->w->key), PAGE_SECTORS), 0);
	bio_get(bio);
	bio->bi_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0);

	bio->bi_iter.bi_size	= KEY_SIZE(&io->w->key) << 9;
	bio->bi_private		= &io->cl;
	bch_bio_map(bio, NULL);
}

static CLOSURE_CALLBACK(write_moving)
{
	closure_type(io, struct moving_io, cl);
	struct data_insert_op *op = &io->op;

	if (!op->status) {
		moving_init(io);

		io->bio.bio.bi_iter.bi_sector = KEY_START(&io->w->key);
		op->write_prio		= 1;
		op->bio			= &io->bio.bio;

		op->writeback		= KEY_DIRTY(&io->w->key);

Annotation

Implementation Notes