blk: centralize non-request unplug handling.
[firefly-linux-kernel-4.4.55.git] / block / blk-core.c
index dd134d834d589468fe1794c71a8325920ee5ac34..177ddcf356e6a2cf3dca8b86d5985c3461addade 100644 (file)
@@ -2927,6 +2927,31 @@ static void flush_plug_callbacks(struct blk_plug *plug)
        }
 }
 
+struct blk_plug_cb *blk_check_plugged(blk_plug_cb_fn unplug, void *data,
+                                     int size)
+{
+       struct blk_plug *plug = current->plug;
+       struct blk_plug_cb *cb;
+
+       if (!plug)
+               return NULL;
+
+       list_for_each_entry(cb, &plug->cb_list, list)
+               if (cb->callback == unplug && cb->data == data)
+                       return cb;
+
+       /* Not currently on the callback list */
+       BUG_ON(size < sizeof(*cb));
+       cb = kzalloc(size, GFP_ATOMIC);
+       if (cb) {
+               cb->data = data;
+               cb->callback = unplug;
+               list_add(&cb->list, &plug->cb_list);
+       }
+       return cb;
+}
+EXPORT_SYMBOL(blk_check_plugged);
+
 void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule)
 {
        struct request_queue *q;