aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r--drivers/md/bitmap.c34
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);