Commit 048c9374a749a27f16493cea033fa4a8ff492356
Committed by
Jens Axboe
1 parent
a1b49cb7e2
Exists in
master
and in
7 other branches
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: NeilBrown <neilb@suse.de> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Showing 2 changed files with 26 additions and 1 deletions Side-by-side Diff
block/blk-core.c
... | ... | @@ -2638,6 +2638,7 @@ |
2638 | 2638 | |
2639 | 2639 | plug->magic = PLUG_MAGIC; |
2640 | 2640 | INIT_LIST_HEAD(&plug->list); |
2641 | + INIT_LIST_HEAD(&plug->cb_list); | |
2641 | 2642 | plug->should_sort = 0; |
2642 | 2643 | |
2643 | 2644 | /* |
... | ... | @@ -2678,6 +2679,24 @@ |
2678 | 2679 | q->unplugged_fn(q); |
2679 | 2680 | } |
2680 | 2681 | |
2682 | +static void flush_plug_callbacks(struct blk_plug *plug) | |
2683 | +{ | |
2684 | + LIST_HEAD(callbacks); | |
2685 | + | |
2686 | + if (list_empty(&plug->cb_list)) | |
2687 | + return; | |
2688 | + | |
2689 | + list_splice_init(&plug->cb_list, &callbacks); | |
2690 | + | |
2691 | + while (!list_empty(&callbacks)) { | |
2692 | + struct blk_plug_cb *cb = list_first_entry(&callbacks, | |
2693 | + struct blk_plug_cb, | |
2694 | + list); | |
2695 | + list_del(&cb->list); | |
2696 | + cb->callback(cb); | |
2697 | + } | |
2698 | +} | |
2699 | + | |
2681 | 2700 | void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) |
2682 | 2701 | { |
2683 | 2702 | struct request_queue *q; |
... | ... | @@ -2688,6 +2707,7 @@ |
2688 | 2707 | |
2689 | 2708 | BUG_ON(plug->magic != PLUG_MAGIC); |
2690 | 2709 | |
2710 | + flush_plug_callbacks(plug); | |
2691 | 2711 | if (list_empty(&plug->list)) |
2692 | 2712 | return; |
2693 | 2713 |
include/linux/blkdev.h
... | ... | @@ -860,8 +860,13 @@ |
860 | 860 | struct blk_plug { |
861 | 861 | unsigned long magic; |
862 | 862 | struct list_head list; |
863 | + struct list_head cb_list; | |
863 | 864 | unsigned int should_sort; |
864 | 865 | }; |
866 | +struct blk_plug_cb { | |
867 | + struct list_head list; | |
868 | + void (*callback)(struct blk_plug_cb *); | |
869 | +}; | |
865 | 870 | |
866 | 871 | extern void blk_start_plug(struct blk_plug *); |
867 | 872 | extern void blk_finish_plug(struct blk_plug *); |
... | ... | @@ -887,7 +892,7 @@ |
887 | 892 | { |
888 | 893 | struct blk_plug *plug = tsk->plug; |
889 | 894 | |
890 | - return plug && !list_empty(&plug->list); | |
895 | + return plug && (!list_empty(&plug->list) || !list_empty(&plug->cb_list)); | |
891 | 896 | } |
892 | 897 | |
893 | 898 | /* |