diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index f8775699e15a..eec75f130708 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -386,6 +386,51 @@ void md_barrier_request(mddev_t *mddev, struct bio *bio) | |||
386 | } | 386 | } |
387 | EXPORT_SYMBOL(md_barrier_request); | 387 | EXPORT_SYMBOL(md_barrier_request); |
388 | 388 | ||
389 | /* Support for plugging. | ||
390 | * This mirrors the plugging support in request_queue, but does not | ||
391 | * require having a whole queue | ||
392 | */ | ||
393 | static void plugger_work(struct work_struct *work) | ||
394 | { | ||
395 | struct plug_handle *plug = | ||
396 | container_of(work, struct plug_handle, unplug_work); | ||
397 | plug->unplug_fn(plug); | ||
398 | } | ||
399 | static void plugger_timeout(unsigned long data) | ||
400 | { | ||
401 | struct plug_handle *plug = (void *)data; | ||
402 | kblockd_schedule_work(NULL, &plug->unplug_work); | ||
403 | } | ||
404 | void plugger_init(struct plug_handle *plug, | ||
405 | void (*unplug_fn)(struct plug_handle *)) | ||
406 | { | ||
407 | plug->unplug_flag = 0; | ||
408 | plug->unplug_fn = unplug_fn; | ||
409 | init_timer(&plug->unplug_timer); | ||
410 | plug->unplug_timer.function = plugger_timeout; | ||
411 | plug->unplug_timer.data = (unsigned long)plug; | ||
412 | INIT_WORK(&plug->unplug_work, plugger_work); | ||
413 | } | ||
414 | EXPORT_SYMBOL_GPL(plugger_init); | ||
415 | |||
416 | void plugger_set_plug(struct plug_handle *plug) | ||
417 | { | ||
418 | if (!test_and_set_bit(PLUGGED_FLAG, &plug->unplug_flag)) | ||
419 | mod_timer(&plug->unplug_timer, jiffies + msecs_to_jiffies(3)+1); | ||
420 | } | ||
421 | EXPORT_SYMBOL_GPL(plugger_set_plug); | ||
422 | |||
423 | int plugger_remove_plug(struct plug_handle *plug) | ||
424 | { | ||
425 | if (test_and_clear_bit(PLUGGED_FLAG, &plug->unplug_flag)) { | ||
426 | del_timer(&plug->unplug_timer); | ||
427 | return 1; | ||
428 | } else | ||
429 | return 0; | ||
430 | } | ||
431 | EXPORT_SYMBOL_GPL(plugger_remove_plug); | ||
432 | |||
433 | |||
389 | static inline mddev_t *mddev_get(mddev_t *mddev) | 434 | static inline mddev_t *mddev_get(mddev_t *mddev) |
390 | { | 435 | { |
391 | atomic_inc(&mddev->active); | 436 | atomic_inc(&mddev->active); |