Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 048c9374 authored by NeilBrown's avatar NeilBrown Committed by Jens Axboe
Browse files

block: Enhance new plugging support to support general callbacks



md/raid requires an unplug callback, but as it does not uses
requests the current code cannot provide one.

So allow arbitrary callbacks to be attached to the blk_plug.

Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Signed-off-by: default avatarJens Axboe <jaxboe@fusionio.com>
parent a1b49cb7
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -2638,6 +2638,7 @@ void blk_start_plug(struct blk_plug *plug)

	plug->magic = PLUG_MAGIC;
	INIT_LIST_HEAD(&plug->list);
	INIT_LIST_HEAD(&plug->cb_list);
	plug->should_sort = 0;

	/*
@@ -2678,6 +2679,24 @@ static void queue_unplugged(struct request_queue *q, unsigned int depth,
		q->unplugged_fn(q);
}

static void flush_plug_callbacks(struct blk_plug *plug)
{
	LIST_HEAD(callbacks);

	if (list_empty(&plug->cb_list))
		return;

	list_splice_init(&plug->cb_list, &callbacks);

	while (!list_empty(&callbacks)) {
		struct blk_plug_cb *cb = list_first_entry(&callbacks,
							  struct blk_plug_cb,
							  list);
		list_del(&cb->list);
		cb->callback(cb);
	}
}

void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule)
{
	struct request_queue *q;
@@ -2688,6 +2707,7 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule)

	BUG_ON(plug->magic != PLUG_MAGIC);

	flush_plug_callbacks(plug);
	if (list_empty(&plug->list))
		return;

+6 −1
Original line number Diff line number Diff line
@@ -860,8 +860,13 @@ extern void blk_put_queue(struct request_queue *);
struct blk_plug {
	unsigned long magic;
	struct list_head list;
	struct list_head cb_list;
	unsigned int should_sort;
};
struct blk_plug_cb {
	struct list_head list;
	void (*callback)(struct blk_plug_cb *);
};

extern void blk_start_plug(struct blk_plug *);
extern void blk_finish_plug(struct blk_plug *);
@@ -887,7 +892,7 @@ static inline bool blk_needs_flush_plug(struct task_struct *tsk)
{
	struct blk_plug *plug = tsk->plug;

	return plug && !list_empty(&plug->list);
	return plug && (!list_empty(&plug->list) || !list_empty(&plug->cb_list));
}

/*