diff options
-rw-r--r-- | block/blk-core.c | 20 | ||||
-rw-r--r-- | include/linux/blkdev.h | 7 |
2 files changed, 26 insertions, 1 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 78b7b0cb7216..77edf0512338 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -2638,6 +2638,7 @@ void blk_start_plug(struct blk_plug *plug) | |||
2638 | 2638 | ||
2639 | plug->magic = PLUG_MAGIC; | 2639 | plug->magic = PLUG_MAGIC; |
2640 | INIT_LIST_HEAD(&plug->list); | 2640 | INIT_LIST_HEAD(&plug->list); |
2641 | INIT_LIST_HEAD(&plug->cb_list); | ||
2641 | plug->should_sort = 0; | 2642 | plug->should_sort = 0; |
2642 | 2643 | ||
2643 | /* | 2644 | /* |
@@ -2678,6 +2679,24 @@ static void queue_unplugged(struct request_queue *q, unsigned int depth, | |||
2678 | q->unplugged_fn(q); | 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 | void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) | 2700 | void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) |
2682 | { | 2701 | { |
2683 | struct request_queue *q; | 2702 | struct request_queue *q; |
@@ -2688,6 +2707,7 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) | |||
2688 | 2707 | ||
2689 | BUG_ON(plug->magic != PLUG_MAGIC); | 2708 | BUG_ON(plug->magic != PLUG_MAGIC); |
2690 | 2709 | ||
2710 | flush_plug_callbacks(plug); | ||
2691 | if (list_empty(&plug->list)) | 2711 | if (list_empty(&plug->list)) |
2692 | return; | 2712 | return; |
2693 | 2713 | ||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index ec0357d8c4a5..f3f7879391a7 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -860,8 +860,13 @@ extern void blk_put_queue(struct request_queue *); | |||
860 | struct blk_plug { | 860 | struct blk_plug { |
861 | unsigned long magic; | 861 | unsigned long magic; |
862 | struct list_head list; | 862 | struct list_head list; |
863 | struct list_head cb_list; | ||
863 | unsigned int should_sort; | 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 | extern void blk_start_plug(struct blk_plug *); | 871 | extern void blk_start_plug(struct blk_plug *); |
867 | extern void blk_finish_plug(struct blk_plug *); | 872 | extern void blk_finish_plug(struct blk_plug *); |
@@ -887,7 +892,7 @@ static inline bool blk_needs_flush_plug(struct task_struct *tsk) | |||
887 | { | 892 | { |
888 | struct blk_plug *plug = tsk->plug; | 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 | /* |