diff options
Diffstat (limited to 'drivers/md/bitmap.c')
| -rw-r--r-- | drivers/md/bitmap.c | 119 |
1 files changed, 53 insertions, 66 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 9462fdd517c0..86b6b037fa44 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
| @@ -261,30 +261,33 @@ char *file_path(struct file *file, char *buf, int count) | |||
| 261 | /* | 261 | /* |
| 262 | * write out a page | 262 | * write out a page |
| 263 | */ | 263 | */ |
| 264 | static int write_page(struct page *page, int wait) | 264 | static int write_page(struct bitmap *bitmap, struct page *page, int wait) |
| 265 | { | 265 | { |
| 266 | int ret = -ENOMEM; | 266 | int ret = -ENOMEM; |
| 267 | 267 | ||
| 268 | lock_page(page); | 268 | lock_page(page); |
| 269 | 269 | ||
| 270 | if (page->mapping == NULL) | ||
| 271 | goto unlock_out; | ||
| 272 | else if (i_size_read(page->mapping->host) < page->index << PAGE_SHIFT) { | ||
| 273 | ret = -ENOENT; | ||
| 274 | goto unlock_out; | ||
| 275 | } | ||
| 276 | |||
| 277 | ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE); | 270 | ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE); |
| 278 | if (!ret) | 271 | if (!ret) |
| 279 | ret = page->mapping->a_ops->commit_write(NULL, page, 0, | 272 | ret = page->mapping->a_ops->commit_write(NULL, page, 0, |
| 280 | PAGE_SIZE); | 273 | PAGE_SIZE); |
| 281 | if (ret) { | 274 | if (ret) { |
| 282 | unlock_out: | ||
| 283 | unlock_page(page); | 275 | unlock_page(page); |
| 284 | return ret; | 276 | return ret; |
| 285 | } | 277 | } |
| 286 | 278 | ||
| 287 | set_page_dirty(page); /* force it to be written out */ | 279 | set_page_dirty(page); /* force it to be written out */ |
| 280 | |||
| 281 | if (!wait) { | ||
| 282 | /* add to list to be waited for by daemon */ | ||
| 283 | struct page_list *item = mempool_alloc(bitmap->write_pool, GFP_NOIO); | ||
| 284 | item->page = page; | ||
| 285 | page_cache_get(page); | ||
| 286 | spin_lock(&bitmap->write_lock); | ||
| 287 | list_add(&item->list, &bitmap->complete_pages); | ||
| 288 | spin_unlock(&bitmap->write_lock); | ||
| 289 | md_wakeup_thread(bitmap->writeback_daemon); | ||
| 290 | } | ||
| 288 | return write_one_page(page, wait); | 291 | return write_one_page(page, wait); |
| 289 | } | 292 | } |
| 290 | 293 | ||
| @@ -343,14 +346,13 @@ int bitmap_update_sb(struct bitmap *bitmap) | |||
| 343 | spin_unlock_irqrestore(&bitmap->lock, flags); | 346 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| 344 | return 0; | 347 | return 0; |
| 345 | } | 348 | } |
| 346 | page_cache_get(bitmap->sb_page); | ||
| 347 | spin_unlock_irqrestore(&bitmap->lock, flags); | 349 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| 348 | sb = (bitmap_super_t *)kmap(bitmap->sb_page); | 350 | sb = (bitmap_super_t *)kmap(bitmap->sb_page); |
| 349 | sb->events = cpu_to_le64(bitmap->mddev->events); | 351 | sb->events = cpu_to_le64(bitmap->mddev->events); |
| 350 | if (!bitmap->mddev->degraded) | 352 | if (!bitmap->mddev->degraded) |
| 351 | sb->events_cleared = cpu_to_le64(bitmap->mddev->events); | 353 | sb->events_cleared = cpu_to_le64(bitmap->mddev->events); |
| 352 | kunmap(bitmap->sb_page); | 354 | kunmap(bitmap->sb_page); |
| 353 | return write_page(bitmap->sb_page, 0); | 355 | return write_page(bitmap, bitmap->sb_page, 0); |
| 354 | } | 356 | } |
| 355 | 357 | ||
| 356 | /* print out the bitmap file superblock */ | 358 | /* print out the bitmap file superblock */ |
| @@ -556,10 +558,10 @@ static void bitmap_file_unmap(struct bitmap *bitmap) | |||
| 556 | static void bitmap_stop_daemons(struct bitmap *bitmap); | 558 | static void bitmap_stop_daemons(struct bitmap *bitmap); |
| 557 | 559 | ||
| 558 | /* dequeue the next item in a page list -- don't call from irq context */ | 560 | /* dequeue the next item in a page list -- don't call from irq context */ |
| 559 | static struct page_list *dequeue_page(struct bitmap *bitmap, | 561 | static struct page_list *dequeue_page(struct bitmap *bitmap) |
| 560 | struct list_head *head) | ||
| 561 | { | 562 | { |
| 562 | struct page_list *item = NULL; | 563 | struct page_list *item = NULL; |
| 564 | struct list_head *head = &bitmap->complete_pages; | ||
| 563 | 565 | ||
| 564 | spin_lock(&bitmap->write_lock); | 566 | spin_lock(&bitmap->write_lock); |
| 565 | if (list_empty(head)) | 567 | if (list_empty(head)) |
| @@ -573,23 +575,15 @@ out: | |||
| 573 | 575 | ||
| 574 | static void drain_write_queues(struct bitmap *bitmap) | 576 | static void drain_write_queues(struct bitmap *bitmap) |
| 575 | { | 577 | { |
| 576 | struct list_head *queues[] = { &bitmap->complete_pages, NULL }; | ||
| 577 | struct list_head *head; | ||
| 578 | struct page_list *item; | 578 | struct page_list *item; |
| 579 | int i; | ||
| 580 | 579 | ||
| 581 | for (i = 0; queues[i]; i++) { | 580 | while ((item = dequeue_page(bitmap))) { |
| 582 | head = queues[i]; | 581 | /* don't bother to wait */ |
| 583 | while ((item = dequeue_page(bitmap, head))) { | 582 | page_cache_release(item->page); |
| 584 | page_cache_release(item->page); | 583 | mempool_free(item, bitmap->write_pool); |
| 585 | mempool_free(item, bitmap->write_pool); | ||
| 586 | } | ||
| 587 | } | 584 | } |
| 588 | 585 | ||
| 589 | spin_lock(&bitmap->write_lock); | ||
| 590 | bitmap->writes_pending = 0; /* make sure waiters continue */ | ||
| 591 | wake_up(&bitmap->write_wait); | 586 | wake_up(&bitmap->write_wait); |
| 592 | spin_unlock(&bitmap->write_lock); | ||
| 593 | } | 587 | } |
| 594 | 588 | ||
| 595 | static void bitmap_file_put(struct bitmap *bitmap) | 589 | static void bitmap_file_put(struct bitmap *bitmap) |
| @@ -734,13 +728,13 @@ int bitmap_unplug(struct bitmap *bitmap) | |||
| 734 | spin_unlock_irqrestore(&bitmap->lock, flags); | 728 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| 735 | 729 | ||
| 736 | if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) | 730 | if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) |
| 737 | if (write_page(page, 0)) | 731 | if (write_page(bitmap, page, 0)) |
| 738 | return 1; | 732 | return 1; |
| 739 | } | 733 | } |
| 740 | if (wait) { /* if any writes were performed, we need to wait on them */ | 734 | if (wait) { /* if any writes were performed, we need to wait on them */ |
| 741 | spin_lock_irq(&bitmap->write_lock); | 735 | spin_lock_irq(&bitmap->write_lock); |
| 742 | wait_event_lock_irq(bitmap->write_wait, | 736 | wait_event_lock_irq(bitmap->write_wait, |
| 743 | bitmap->writes_pending == 0, bitmap->write_lock, | 737 | list_empty(&bitmap->complete_pages), bitmap->write_lock, |
| 744 | wake_up_process(bitmap->writeback_daemon->tsk)); | 738 | wake_up_process(bitmap->writeback_daemon->tsk)); |
| 745 | spin_unlock_irq(&bitmap->write_lock); | 739 | spin_unlock_irq(&bitmap->write_lock); |
| 746 | } | 740 | } |
| @@ -841,7 +835,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) | |||
| 841 | */ | 835 | */ |
| 842 | memset(page_address(page) + offset, 0xff, | 836 | memset(page_address(page) + offset, 0xff, |
| 843 | PAGE_SIZE - offset); | 837 | PAGE_SIZE - offset); |
| 844 | ret = write_page(page, 1); | 838 | ret = write_page(bitmap, page, 1); |
| 845 | if (ret) { | 839 | if (ret) { |
| 846 | kunmap(page); | 840 | kunmap(page); |
| 847 | /* release, page not in filemap yet */ | 841 | /* release, page not in filemap yet */ |
| @@ -934,7 +928,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) | |||
| 934 | } | 928 | } |
| 935 | spin_unlock_irqrestore(&bitmap->lock, flags); | 929 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| 936 | if (attr & BITMAP_PAGE_NEEDWRITE) { | 930 | if (attr & BITMAP_PAGE_NEEDWRITE) { |
| 937 | if (write_page(page, 0)) | 931 | if (write_page(bitmap, page, 0)) |
| 938 | bitmap_file_kick(bitmap); | 932 | bitmap_file_kick(bitmap); |
| 939 | page_cache_release(page); | 933 | page_cache_release(page); |
| 940 | } | 934 | } |
| @@ -950,7 +944,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) | |||
| 950 | if (get_page_attr(bitmap, lastpage) & BITMAP_PAGE_NEEDWRITE) { | 944 | if (get_page_attr(bitmap, lastpage) & BITMAP_PAGE_NEEDWRITE) { |
| 951 | clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); | 945 | clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); |
| 952 | spin_unlock_irqrestore(&bitmap->lock, flags); | 946 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| 953 | err = write_page(lastpage, 0); | 947 | err = write_page(bitmap, lastpage, 0); |
| 954 | } else { | 948 | } else { |
| 955 | set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); | 949 | set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); |
| 956 | spin_unlock_irqrestore(&bitmap->lock, flags); | 950 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| @@ -998,7 +992,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) | |||
| 998 | if (get_page_attr(bitmap, lastpage) &BITMAP_PAGE_NEEDWRITE) { | 992 | if (get_page_attr(bitmap, lastpage) &BITMAP_PAGE_NEEDWRITE) { |
| 999 | clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); | 993 | clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); |
| 1000 | spin_unlock_irqrestore(&bitmap->lock, flags); | 994 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| 1001 | err = write_page(lastpage, 0); | 995 | err = write_page(bitmap, lastpage, 0); |
| 1002 | } else { | 996 | } else { |
| 1003 | set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); | 997 | set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); |
| 1004 | spin_unlock_irqrestore(&bitmap->lock, flags); | 998 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| @@ -1034,46 +1028,40 @@ static void bitmap_writeback_daemon(mddev_t *mddev) | |||
| 1034 | struct page_list *item; | 1028 | struct page_list *item; |
| 1035 | int err = 0; | 1029 | int err = 0; |
| 1036 | 1030 | ||
| 1037 | while (1) { | 1031 | if (signal_pending(current)) { |
| 1038 | PRINTK("%s: bitmap writeback daemon waiting...\n", bmname(bitmap)); | 1032 | printk(KERN_INFO |
| 1039 | down_interruptible(&bitmap->write_done); | 1033 | "%s: bitmap writeback daemon got signal, exiting...\n", |
| 1040 | if (signal_pending(current)) { | 1034 | bmname(bitmap)); |
| 1041 | printk(KERN_INFO | 1035 | err = -EINTR; |
| 1042 | "%s: bitmap writeback daemon got signal, exiting...\n", | 1036 | goto out; |
| 1043 | bmname(bitmap)); | 1037 | } |
| 1044 | break; | ||
| 1045 | } | ||
| 1046 | 1038 | ||
| 1047 | PRINTK("%s: bitmap writeback daemon woke up...\n", bmname(bitmap)); | 1039 | PRINTK("%s: bitmap writeback daemon woke up...\n", bmname(bitmap)); |
| 1048 | /* wait on bitmap page writebacks */ | 1040 | /* wait on bitmap page writebacks */ |
| 1049 | while ((item = dequeue_page(bitmap, &bitmap->complete_pages))) { | 1041 | while ((item = dequeue_page(bitmap))) { |
| 1050 | page = item->page; | 1042 | page = item->page; |
| 1051 | mempool_free(item, bitmap->write_pool); | 1043 | mempool_free(item, bitmap->write_pool); |
| 1052 | PRINTK("wait on page writeback: %p %lu\n", page, bitmap->writes_pending); | 1044 | PRINTK("wait on page writeback: %p\n", page); |
| 1053 | wait_on_page_writeback(page); | 1045 | wait_on_page_writeback(page); |
| 1054 | PRINTK("finished page writeback: %p %lu\n", page, bitmap->writes_pending); | 1046 | PRINTK("finished page writeback: %p\n", page); |
| 1055 | spin_lock(&bitmap->write_lock); | 1047 | |
| 1056 | if (!--bitmap->writes_pending) | 1048 | err = PageError(page); |
| 1057 | wake_up(&bitmap->write_wait); | 1049 | page_cache_release(page); |
| 1058 | spin_unlock(&bitmap->write_lock); | 1050 | if (err) { |
| 1059 | err = PageError(page); | 1051 | printk(KERN_WARNING "%s: bitmap file writeback " |
| 1060 | page_cache_release(page); | 1052 | "failed (page %lu): %d\n", |
| 1061 | if (err) { | 1053 | bmname(bitmap), page->index, err); |
| 1062 | printk(KERN_WARNING "%s: bitmap file writeback " | 1054 | bitmap_file_kick(bitmap); |
| 1063 | "failed (page %lu): %d\n", | 1055 | goto out; |
| 1064 | bmname(bitmap), page->index, err); | ||
| 1065 | bitmap_file_kick(bitmap); | ||
| 1066 | goto out; | ||
| 1067 | } | ||
| 1068 | } | 1056 | } |
| 1069 | } | 1057 | } |
| 1070 | out: | 1058 | out: |
| 1059 | wake_up(&bitmap->write_wait); | ||
| 1071 | if (err) { | 1060 | if (err) { |
| 1072 | printk(KERN_INFO "%s: bitmap writeback daemon exiting (%d)\n", | 1061 | printk(KERN_INFO "%s: bitmap writeback daemon exiting (%d)\n", |
| 1073 | bmname(bitmap), err); | 1062 | bmname(bitmap), err); |
| 1074 | daemon_exit(bitmap, &bitmap->writeback_daemon); | 1063 | daemon_exit(bitmap, &bitmap->writeback_daemon); |
| 1075 | } | 1064 | } |
| 1076 | return; | ||
| 1077 | } | 1065 | } |
| 1078 | 1066 | ||
| 1079 | static int bitmap_start_daemon(struct bitmap *bitmap, mdk_thread_t **ptr, | 1067 | static int bitmap_start_daemon(struct bitmap *bitmap, mdk_thread_t **ptr, |
| @@ -1375,7 +1363,7 @@ int bitmap_setallbits(struct bitmap *bitmap) | |||
| 1375 | spin_unlock_irqrestore(&bitmap->lock, flags); | 1363 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| 1376 | memset(kmap(page), 0xff, PAGE_SIZE); | 1364 | memset(kmap(page), 0xff, PAGE_SIZE); |
| 1377 | kunmap(page); | 1365 | kunmap(page); |
| 1378 | if (write_page(page, 0)) | 1366 | if (write_page(bitmap, page, 0)) |
| 1379 | return 1; | 1367 | return 1; |
| 1380 | } | 1368 | } |
| 1381 | 1369 | ||
| @@ -1443,7 +1431,6 @@ int bitmap_create(mddev_t *mddev) | |||
| 1443 | mddev->bitmap = bitmap; | 1431 | mddev->bitmap = bitmap; |
| 1444 | 1432 | ||
| 1445 | spin_lock_init(&bitmap->write_lock); | 1433 | spin_lock_init(&bitmap->write_lock); |
| 1446 | init_MUTEX_LOCKED(&bitmap->write_done); | ||
| 1447 | INIT_LIST_HEAD(&bitmap->complete_pages); | 1434 | INIT_LIST_HEAD(&bitmap->complete_pages); |
| 1448 | init_waitqueue_head(&bitmap->write_wait); | 1435 | init_waitqueue_head(&bitmap->write_wait); |
| 1449 | bitmap->write_pool = mempool_create(WRITE_POOL_SIZE, write_pool_alloc, | 1436 | bitmap->write_pool = mempool_create(WRITE_POOL_SIZE, write_pool_alloc, |
