diff options
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r-- | drivers/md/bitmap.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 01654fcabc52..51315302a85e 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -21,7 +21,6 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/version.h> | ||
25 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
26 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
27 | #include <linux/init.h> | 26 | #include <linux/init.h> |
@@ -272,7 +271,8 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde | |||
272 | return ERR_PTR(-ENOMEM); | 271 | return ERR_PTR(-ENOMEM); |
273 | 272 | ||
274 | ITERATE_RDEV(mddev, rdev, tmp) { | 273 | ITERATE_RDEV(mddev, rdev, tmp) { |
275 | if (! rdev->in_sync || rdev->faulty) | 274 | if (! test_bit(In_sync, &rdev->flags) |
275 | || test_bit(Faulty, &rdev->flags)) | ||
276 | continue; | 276 | continue; |
277 | 277 | ||
278 | target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512); | 278 | target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512); |
@@ -292,7 +292,8 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai | |||
292 | struct list_head *tmp; | 292 | struct list_head *tmp; |
293 | 293 | ||
294 | ITERATE_RDEV(mddev, rdev, tmp) | 294 | ITERATE_RDEV(mddev, rdev, tmp) |
295 | if (rdev->in_sync && !rdev->faulty) | 295 | if (test_bit(In_sync, &rdev->flags) |
296 | && !test_bit(Faulty, &rdev->flags)) | ||
296 | md_super_write(mddev, rdev, | 297 | md_super_write(mddev, rdev, |
297 | (rdev->sb_offset<<1) + offset | 298 | (rdev->sb_offset<<1) + offset |
298 | + page->index * (PAGE_SIZE/512), | 299 | + page->index * (PAGE_SIZE/512), |
@@ -300,7 +301,7 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai | |||
300 | page); | 301 | page); |
301 | 302 | ||
302 | if (wait) | 303 | if (wait) |
303 | wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); | 304 | md_super_wait(mddev); |
304 | return 0; | 305 | return 0; |
305 | } | 306 | } |
306 | 307 | ||
@@ -481,7 +482,8 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
481 | /* verify that the bitmap-specific fields are valid */ | 482 | /* verify that the bitmap-specific fields are valid */ |
482 | if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) | 483 | if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) |
483 | reason = "bad magic"; | 484 | reason = "bad magic"; |
484 | else if (sb->version != cpu_to_le32(BITMAP_MAJOR)) | 485 | else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO || |
486 | le32_to_cpu(sb->version) > BITMAP_MAJOR_HI) | ||
485 | reason = "unrecognized superblock version"; | 487 | reason = "unrecognized superblock version"; |
486 | else if (chunksize < 512 || chunksize > (1024 * 1024 * 4)) | 488 | else if (chunksize < 512 || chunksize > (1024 * 1024 * 4)) |
487 | reason = "bitmap chunksize out of range (512B - 4MB)"; | 489 | reason = "bitmap chunksize out of range (512B - 4MB)"; |
@@ -526,6 +528,8 @@ success: | |||
526 | bitmap->daemon_lastrun = jiffies; | 528 | bitmap->daemon_lastrun = jiffies; |
527 | bitmap->max_write_behind = write_behind; | 529 | bitmap->max_write_behind = write_behind; |
528 | bitmap->flags |= sb->state; | 530 | bitmap->flags |= sb->state; |
531 | if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN) | ||
532 | bitmap->flags |= BITMAP_HOSTENDIAN; | ||
529 | bitmap->events_cleared = le64_to_cpu(sb->events_cleared); | 533 | bitmap->events_cleared = le64_to_cpu(sb->events_cleared); |
530 | if (sb->state & BITMAP_STALE) | 534 | if (sb->state & BITMAP_STALE) |
531 | bitmap->events_cleared = bitmap->mddev->events; | 535 | bitmap->events_cleared = bitmap->mddev->events; |
@@ -763,7 +767,10 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block) | |||
763 | 767 | ||
764 | /* set the bit */ | 768 | /* set the bit */ |
765 | kaddr = kmap_atomic(page, KM_USER0); | 769 | kaddr = kmap_atomic(page, KM_USER0); |
766 | set_bit(bit, kaddr); | 770 | if (bitmap->flags & BITMAP_HOSTENDIAN) |
771 | set_bit(bit, kaddr); | ||
772 | else | ||
773 | ext2_set_bit(bit, kaddr); | ||
767 | kunmap_atomic(kaddr, KM_USER0); | 774 | kunmap_atomic(kaddr, KM_USER0); |
768 | PRINTK("set file bit %lu page %lu\n", bit, page->index); | 775 | PRINTK("set file bit %lu page %lu\n", bit, page->index); |
769 | 776 | ||
@@ -821,8 +828,7 @@ int bitmap_unplug(struct bitmap *bitmap) | |||
821 | wake_up_process(bitmap->writeback_daemon->tsk)); | 828 | wake_up_process(bitmap->writeback_daemon->tsk)); |
822 | spin_unlock_irq(&bitmap->write_lock); | 829 | spin_unlock_irq(&bitmap->write_lock); |
823 | } else | 830 | } else |
824 | wait_event(bitmap->mddev->sb_wait, | 831 | md_super_wait(bitmap->mddev); |
825 | atomic_read(&bitmap->mddev->pending_writes)==0); | ||
826 | } | 832 | } |
827 | return 0; | 833 | return 0; |
828 | } | 834 | } |
@@ -890,6 +896,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | |||
890 | oldindex = ~0L; | 896 | oldindex = ~0L; |
891 | 897 | ||
892 | for (i = 0; i < chunks; i++) { | 898 | for (i = 0; i < chunks; i++) { |
899 | int b; | ||
893 | index = file_page_index(i); | 900 | index = file_page_index(i); |
894 | bit = file_page_offset(i); | 901 | bit = file_page_offset(i); |
895 | if (index != oldindex) { /* this is a new page, read it in */ | 902 | if (index != oldindex) { /* this is a new page, read it in */ |
@@ -938,7 +945,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | |||
938 | 945 | ||
939 | bitmap->filemap[bitmap->file_pages++] = page; | 946 | bitmap->filemap[bitmap->file_pages++] = page; |
940 | } | 947 | } |
941 | if (test_bit(bit, page_address(page))) { | 948 | if (bitmap->flags & BITMAP_HOSTENDIAN) |
949 | b = test_bit(bit, page_address(page)); | ||
950 | else | ||
951 | b = ext2_test_bit(bit, page_address(page)); | ||
952 | if (b) { | ||
942 | /* if the disk bit is set, set the memory bit */ | 953 | /* if the disk bit is set, set the memory bit */ |
943 | bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap), | 954 | bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap), |
944 | ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start) | 955 | ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start) |
@@ -1096,7 +1107,10 @@ int bitmap_daemon_work(struct bitmap *bitmap) | |||
1096 | -1); | 1107 | -1); |
1097 | 1108 | ||
1098 | /* clear the bit */ | 1109 | /* clear the bit */ |
1099 | clear_bit(file_page_offset(j), page_address(page)); | 1110 | if (bitmap->flags & BITMAP_HOSTENDIAN) |
1111 | clear_bit(file_page_offset(j), page_address(page)); | ||
1112 | else | ||
1113 | ext2_clear_bit(file_page_offset(j), page_address(page)); | ||
1100 | } | 1114 | } |
1101 | } | 1115 | } |
1102 | spin_unlock_irqrestore(&bitmap->lock, flags); | 1116 | spin_unlock_irqrestore(&bitmap->lock, flags); |