diff options
author | NeilBrown <neilb@suse.de> | 2006-06-26 03:27:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 12:58:38 -0400 |
commit | 0b79ccf0cdd9f59e5f99017e1a5d23da336544b2 (patch) | |
tree | 8688d9810fcba1e24abce726eaf35ff32f6b58d9 /drivers/md | |
parent | d7375ab324971e7acbea9f02a0269ae7348f4147 (diff) |
[PATCH] md/bitmap: remove bitmap writeback daemon
md/bitmap currently has a separate thread to wait for writes to the bitmap
file to complete (as we cannot get a callback on that action).
However this isn't needed as bitmap_unplug is called from process context and
waits for the writeback thread to do it's work. The same result can be
achieved by doing the waiting directly in bitmap_unplug.
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bitmap.c | 115 |
1 files changed, 8 insertions, 107 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index f8ffaee20ff8..814f412a410c 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -7,7 +7,6 @@ | |||
7 | * additions, Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc.: | 7 | * additions, Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc.: |
8 | * - added disk storage for bitmap | 8 | * - added disk storage for bitmap |
9 | * - changes to allow various bitmap chunk sizes | 9 | * - changes to allow various bitmap chunk sizes |
10 | * - added bitmap daemon (to asynchronously clear bitmap bits from disk) | ||
11 | */ | 10 | */ |
12 | 11 | ||
13 | /* | 12 | /* |
@@ -330,14 +329,13 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait) | |||
330 | set_page_dirty(page); /* force it to be written out */ | 329 | set_page_dirty(page); /* force it to be written out */ |
331 | 330 | ||
332 | if (!wait) { | 331 | if (!wait) { |
333 | /* add to list to be waited for by daemon */ | 332 | /* add to list to be waited for */ |
334 | struct page_list *item = mempool_alloc(bitmap->write_pool, GFP_NOIO); | 333 | struct page_list *item = mempool_alloc(bitmap->write_pool, GFP_NOIO); |
335 | item->page = page; | 334 | item->page = page; |
336 | get_page(page); | 335 | get_page(page); |
337 | spin_lock(&bitmap->write_lock); | 336 | spin_lock(&bitmap->write_lock); |
338 | list_add(&item->list, &bitmap->complete_pages); | 337 | list_add(&item->list, &bitmap->complete_pages); |
339 | spin_unlock(&bitmap->write_lock); | 338 | spin_unlock(&bitmap->write_lock); |
340 | md_wakeup_thread(bitmap->writeback_daemon); | ||
341 | } | 339 | } |
342 | return write_one_page(page, wait); | 340 | return write_one_page(page, wait); |
343 | } | 341 | } |
@@ -621,8 +619,6 @@ static void bitmap_file_unmap(struct bitmap *bitmap) | |||
621 | safe_put_page(sb_page); | 619 | safe_put_page(sb_page); |
622 | } | 620 | } |
623 | 621 | ||
624 | static void bitmap_stop_daemon(struct bitmap *bitmap); | ||
625 | |||
626 | /* dequeue the next item in a page list -- don't call from irq context */ | 622 | /* dequeue the next item in a page list -- don't call from irq context */ |
627 | static struct page_list *dequeue_page(struct bitmap *bitmap) | 623 | static struct page_list *dequeue_page(struct bitmap *bitmap) |
628 | { | 624 | { |
@@ -648,8 +644,6 @@ static void drain_write_queues(struct bitmap *bitmap) | |||
648 | put_page(item->page); | 644 | put_page(item->page); |
649 | mempool_free(item, bitmap->write_pool); | 645 | mempool_free(item, bitmap->write_pool); |
650 | } | 646 | } |
651 | |||
652 | wake_up(&bitmap->write_wait); | ||
653 | } | 647 | } |
654 | 648 | ||
655 | static void bitmap_file_put(struct bitmap *bitmap) | 649 | static void bitmap_file_put(struct bitmap *bitmap) |
@@ -663,8 +657,6 @@ static void bitmap_file_put(struct bitmap *bitmap) | |||
663 | bitmap->file = NULL; | 657 | bitmap->file = NULL; |
664 | spin_unlock_irqrestore(&bitmap->lock, flags); | 658 | spin_unlock_irqrestore(&bitmap->lock, flags); |
665 | 659 | ||
666 | bitmap_stop_daemon(bitmap); | ||
667 | |||
668 | drain_write_queues(bitmap); | 660 | drain_write_queues(bitmap); |
669 | 661 | ||
670 | bitmap_file_unmap(bitmap); | 662 | bitmap_file_unmap(bitmap); |
@@ -770,6 +762,8 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block) | |||
770 | 762 | ||
771 | } | 763 | } |
772 | 764 | ||
765 | static void bitmap_writeback(struct bitmap *bitmap); | ||
766 | |||
773 | /* this gets called when the md device is ready to unplug its underlying | 767 | /* this gets called when the md device is ready to unplug its underlying |
774 | * (slave) device queues -- before we let any writes go down, we need to | 768 | * (slave) device queues -- before we let any writes go down, we need to |
775 | * sync the dirty pages of the bitmap file to disk */ | 769 | * sync the dirty pages of the bitmap file to disk */ |
@@ -812,13 +806,9 @@ int bitmap_unplug(struct bitmap *bitmap) | |||
812 | } | 806 | } |
813 | } | 807 | } |
814 | if (wait) { /* if any writes were performed, we need to wait on them */ | 808 | if (wait) { /* if any writes were performed, we need to wait on them */ |
815 | if (bitmap->file) { | 809 | if (bitmap->file) |
816 | spin_lock_irq(&bitmap->write_lock); | 810 | bitmap_writeback(bitmap); |
817 | wait_event_lock_irq(bitmap->write_wait, | 811 | else |
818 | list_empty(&bitmap->complete_pages), bitmap->write_lock, | ||
819 | wake_up_process(bitmap->writeback_daemon->tsk)); | ||
820 | spin_unlock_irq(&bitmap->write_lock); | ||
821 | } else | ||
822 | md_super_wait(bitmap->mddev); | 812 | md_super_wait(bitmap->mddev); |
823 | } | 813 | } |
824 | return 0; | 814 | return 0; |
@@ -1126,41 +1116,12 @@ int bitmap_daemon_work(struct bitmap *bitmap) | |||
1126 | return err; | 1116 | return err; |
1127 | } | 1117 | } |
1128 | 1118 | ||
1129 | static void daemon_exit(struct bitmap *bitmap, mdk_thread_t **daemon) | 1119 | static void bitmap_writeback(struct bitmap *bitmap) |
1130 | { | 1120 | { |
1131 | mdk_thread_t *dmn; | ||
1132 | unsigned long flags; | ||
1133 | |||
1134 | /* if no one is waiting on us, we'll free the md thread struct | ||
1135 | * and exit, otherwise we let the waiter clean things up */ | ||
1136 | spin_lock_irqsave(&bitmap->lock, flags); | ||
1137 | if ((dmn = *daemon)) { /* no one is waiting, cleanup and exit */ | ||
1138 | *daemon = NULL; | ||
1139 | spin_unlock_irqrestore(&bitmap->lock, flags); | ||
1140 | kfree(dmn); | ||
1141 | complete_and_exit(NULL, 0); /* do_exit not exported */ | ||
1142 | } | ||
1143 | spin_unlock_irqrestore(&bitmap->lock, flags); | ||
1144 | } | ||
1145 | |||
1146 | static void bitmap_writeback_daemon(mddev_t *mddev) | ||
1147 | { | ||
1148 | struct bitmap *bitmap = mddev->bitmap; | ||
1149 | struct page *page; | 1121 | struct page *page; |
1150 | struct page_list *item; | 1122 | struct page_list *item; |
1151 | int err = 0; | 1123 | int err = 0; |
1152 | 1124 | ||
1153 | if (signal_pending(current)) { | ||
1154 | printk(KERN_INFO | ||
1155 | "%s: bitmap writeback daemon got signal, exiting...\n", | ||
1156 | bmname(bitmap)); | ||
1157 | err = -EINTR; | ||
1158 | goto out; | ||
1159 | } | ||
1160 | if (bitmap == NULL) | ||
1161 | /* about to be stopped. */ | ||
1162 | return; | ||
1163 | |||
1164 | PRINTK("%s: bitmap writeback daemon woke up...\n", bmname(bitmap)); | 1125 | PRINTK("%s: bitmap writeback daemon woke up...\n", bmname(bitmap)); |
1165 | /* wait on bitmap page writebacks */ | 1126 | /* wait on bitmap page writebacks */ |
1166 | while ((item = dequeue_page(bitmap))) { | 1127 | while ((item = dequeue_page(bitmap))) { |
@@ -1177,59 +1138,9 @@ static void bitmap_writeback_daemon(mddev_t *mddev) | |||
1177 | "failed (page %lu): %d\n", | 1138 | "failed (page %lu): %d\n", |
1178 | bmname(bitmap), page->index, err); | 1139 | bmname(bitmap), page->index, err); |
1179 | bitmap_file_kick(bitmap); | 1140 | bitmap_file_kick(bitmap); |
1180 | goto out; | 1141 | break; |
1181 | } | 1142 | } |
1182 | } | 1143 | } |
1183 | out: | ||
1184 | wake_up(&bitmap->write_wait); | ||
1185 | if (err) { | ||
1186 | printk(KERN_INFO "%s: bitmap writeback daemon exiting (%d)\n", | ||
1187 | bmname(bitmap), err); | ||
1188 | daemon_exit(bitmap, &bitmap->writeback_daemon); | ||
1189 | } | ||
1190 | } | ||
1191 | |||
1192 | static mdk_thread_t *bitmap_start_daemon(struct bitmap *bitmap, | ||
1193 | void (*func)(mddev_t *), char *name) | ||
1194 | { | ||
1195 | mdk_thread_t *daemon; | ||
1196 | char namebuf[32]; | ||
1197 | |||
1198 | #ifdef INJECT_FATAL_FAULT_2 | ||
1199 | daemon = NULL; | ||
1200 | #else | ||
1201 | sprintf(namebuf, "%%s_%s", name); | ||
1202 | daemon = md_register_thread(func, bitmap->mddev, namebuf); | ||
1203 | #endif | ||
1204 | if (!daemon) { | ||
1205 | printk(KERN_ERR "%s: failed to start bitmap daemon\n", | ||
1206 | bmname(bitmap)); | ||
1207 | return ERR_PTR(-ECHILD); | ||
1208 | } | ||
1209 | |||
1210 | md_wakeup_thread(daemon); /* start it running */ | ||
1211 | |||
1212 | PRINTK("%s: %s daemon (pid %d) started...\n", | ||
1213 | bmname(bitmap), name, daemon->tsk->pid); | ||
1214 | |||
1215 | return daemon; | ||
1216 | } | ||
1217 | |||
1218 | static void bitmap_stop_daemon(struct bitmap *bitmap) | ||
1219 | { | ||
1220 | /* the daemon can't stop itself... it'll just exit instead... */ | ||
1221 | if (bitmap->writeback_daemon && ! IS_ERR(bitmap->writeback_daemon) && | ||
1222 | current->pid != bitmap->writeback_daemon->tsk->pid) { | ||
1223 | mdk_thread_t *daemon; | ||
1224 | unsigned long flags; | ||
1225 | |||
1226 | spin_lock_irqsave(&bitmap->lock, flags); | ||
1227 | daemon = bitmap->writeback_daemon; | ||
1228 | bitmap->writeback_daemon = NULL; | ||
1229 | spin_unlock_irqrestore(&bitmap->lock, flags); | ||
1230 | if (daemon && ! IS_ERR(daemon)) | ||
1231 | md_unregister_thread(daemon); /* destroy the thread */ | ||
1232 | } | ||
1233 | } | 1144 | } |
1234 | 1145 | ||
1235 | static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, | 1146 | static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, |
@@ -1553,7 +1464,6 @@ int bitmap_create(mddev_t *mddev) | |||
1553 | 1464 | ||
1554 | spin_lock_init(&bitmap->write_lock); | 1465 | spin_lock_init(&bitmap->write_lock); |
1555 | INIT_LIST_HEAD(&bitmap->complete_pages); | 1466 | INIT_LIST_HEAD(&bitmap->complete_pages); |
1556 | init_waitqueue_head(&bitmap->write_wait); | ||
1557 | bitmap->write_pool = mempool_create_kmalloc_pool(WRITE_POOL_SIZE, | 1467 | bitmap->write_pool = mempool_create_kmalloc_pool(WRITE_POOL_SIZE, |
1558 | sizeof(struct page_list)); | 1468 | sizeof(struct page_list)); |
1559 | err = -ENOMEM; | 1469 | err = -ENOMEM; |
@@ -1613,15 +1523,6 @@ int bitmap_create(mddev_t *mddev) | |||
1613 | 1523 | ||
1614 | mddev->bitmap = bitmap; | 1524 | mddev->bitmap = bitmap; |
1615 | 1525 | ||
1616 | if (file) | ||
1617 | /* kick off the bitmap writeback daemon */ | ||
1618 | bitmap->writeback_daemon = | ||
1619 | bitmap_start_daemon(bitmap, | ||
1620 | bitmap_writeback_daemon, | ||
1621 | "bitmap_wb"); | ||
1622 | |||
1623 | if (IS_ERR(bitmap->writeback_daemon)) | ||
1624 | return PTR_ERR(bitmap->writeback_daemon); | ||
1625 | mddev->thread->timeout = bitmap->daemon_sleep * HZ; | 1526 | mddev->thread->timeout = bitmap->daemon_sleep * HZ; |
1626 | 1527 | ||
1627 | return bitmap_update_sb(bitmap); | 1528 | return bitmap_update_sb(bitmap); |