aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-06-21 20:17:29 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 22:07:47 -0400
commit8a5e9cf1d6626586ff08e49f400a006a9f0c3275 (patch)
tree3a3135209c0dcb5dd2899b8afcc1701e2fdcf732 /drivers/md
parent39730960d94306d7be414e8d54f4e5c071af1278 (diff)
[PATCH] md: make sure md/bitmap doesn't try to write a page with active writeback
Due to the use of write-behind, it is possible for md to write a page to the bitmap file that is still completing writeback. This is not allowed. With this patch, we detect those cases and either force a sync write, or back off and try later, as appropriate. Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> 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.c68
1 files changed, 38 insertions, 30 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 030d6861051a..95980ad6b27b 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -313,7 +313,16 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait)
313 if (bitmap->file == NULL) 313 if (bitmap->file == NULL)
314 return write_sb_page(bitmap->mddev, bitmap->offset, page, wait); 314 return write_sb_page(bitmap->mddev, bitmap->offset, page, wait);
315 315
316 lock_page(page); 316 if (wait)
317 lock_page(page);
318 else {
319 if (TestSetPageLocked(page))
320 return -EAGAIN; /* already locked */
321 if (PageWriteback(page)) {
322 unlock_page(page);
323 return -EAGAIN;
324 }
325 }
317 326
318 ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE); 327 ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE);
319 if (!ret) 328 if (!ret)
@@ -400,7 +409,7 @@ int bitmap_update_sb(struct bitmap *bitmap)
400 if (!bitmap->mddev->degraded) 409 if (!bitmap->mddev->degraded)
401 sb->events_cleared = cpu_to_le64(bitmap->mddev->events); 410 sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
402 kunmap(bitmap->sb_page); 411 kunmap(bitmap->sb_page);
403 return write_page(bitmap, bitmap->sb_page, 0); 412 return write_page(bitmap, bitmap->sb_page, 1);
404} 413}
405 414
406/* print out the bitmap file superblock */ 415/* print out the bitmap file superblock */
@@ -762,6 +771,7 @@ int bitmap_unplug(struct bitmap *bitmap)
762 unsigned long i, attr, flags; 771 unsigned long i, attr, flags;
763 struct page *page; 772 struct page *page;
764 int wait = 0; 773 int wait = 0;
774 int err;
765 775
766 if (!bitmap) 776 if (!bitmap)
767 return 0; 777 return 0;
@@ -782,9 +792,17 @@ int bitmap_unplug(struct bitmap *bitmap)
782 wait = 1; 792 wait = 1;
783 spin_unlock_irqrestore(&bitmap->lock, flags); 793 spin_unlock_irqrestore(&bitmap->lock, flags);
784 794
785 if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) 795 if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) {
786 if (write_page(bitmap, page, 0)) 796 err = write_page(bitmap, page, 0);
797 if (err == -EAGAIN) {
798 if (attr & BITMAP_PAGE_DIRTY)
799 err = write_page(bitmap, page, 1);
800 else
801 err = 0;
802 }
803 if (err)
787 return 1; 804 return 1;
805 }
788 } 806 }
789 if (wait) { /* if any writes were performed, we need to wait on them */ 807 if (wait) { /* if any writes were performed, we need to wait on them */
790 if (bitmap->file) { 808 if (bitmap->file) {
@@ -1006,8 +1024,15 @@ int bitmap_daemon_work(struct bitmap *bitmap)
1006 } 1024 }
1007 spin_unlock_irqrestore(&bitmap->lock, flags); 1025 spin_unlock_irqrestore(&bitmap->lock, flags);
1008 if (attr & BITMAP_PAGE_NEEDWRITE) { 1026 if (attr & BITMAP_PAGE_NEEDWRITE) {
1009 if (write_page(bitmap, page, 0)) 1027 switch (write_page(bitmap, page, 0)) {
1028 case -EAGAIN:
1029 set_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
1030 break;
1031 case 0:
1032 break;
1033 default:
1010 bitmap_file_kick(bitmap); 1034 bitmap_file_kick(bitmap);
1035 }
1011 page_cache_release(page); 1036 page_cache_release(page);
1012 } 1037 }
1013 continue; 1038 continue;
@@ -1020,6 +1045,10 @@ int bitmap_daemon_work(struct bitmap *bitmap)
1020 clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); 1045 clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
1021 spin_unlock_irqrestore(&bitmap->lock, flags); 1046 spin_unlock_irqrestore(&bitmap->lock, flags);
1022 err = write_page(bitmap, lastpage, 0); 1047 err = write_page(bitmap, lastpage, 0);
1048 if (err == -EAGAIN) {
1049 err = 0;
1050 set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
1051 }
1023 } else { 1052 } else {
1024 set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); 1053 set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
1025 spin_unlock_irqrestore(&bitmap->lock, flags); 1054 spin_unlock_irqrestore(&bitmap->lock, flags);
@@ -1068,6 +1097,10 @@ int bitmap_daemon_work(struct bitmap *bitmap)
1068 clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); 1097 clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
1069 spin_unlock_irqrestore(&bitmap->lock, flags); 1098 spin_unlock_irqrestore(&bitmap->lock, flags);
1070 err = write_page(bitmap, lastpage, 0); 1099 err = write_page(bitmap, lastpage, 0);
1100 if (err == -EAGAIN) {
1101 set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
1102 err = 0;
1103 }
1071 } else { 1104 } else {
1072 set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); 1105 set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
1073 spin_unlock_irqrestore(&bitmap->lock, flags); 1106 spin_unlock_irqrestore(&bitmap->lock, flags);
@@ -1421,31 +1454,6 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset,
1421 } 1454 }
1422} 1455}
1423 1456
1424/* dirty the entire bitmap */
1425int bitmap_setallbits(struct bitmap *bitmap)
1426{
1427 unsigned long flags;
1428 unsigned long j;
1429
1430 /* dirty the in-memory bitmap */
1431 bitmap_set_memory_bits(bitmap, 0, bitmap->chunks << CHUNK_BLOCK_SHIFT(bitmap), 1);
1432
1433 /* dirty the bitmap file */
1434 for (j = 0; j < bitmap->file_pages; j++) {
1435 struct page *page = bitmap->filemap[j];
1436
1437 spin_lock_irqsave(&bitmap->lock, flags);
1438 page_cache_get(page);
1439 spin_unlock_irqrestore(&bitmap->lock, flags);
1440 memset(kmap(page), 0xff, PAGE_SIZE);
1441 kunmap(page);
1442 if (write_page(bitmap, page, 0))
1443 return 1;
1444 }
1445
1446 return 0;
1447}
1448
1449/* 1457/*
1450 * free memory that was allocated 1458 * free memory that was allocated
1451 */ 1459 */