diff options
author | NeilBrown <neilb@suse.de> | 2012-05-21 23:55:15 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-05-21 23:55:15 -0400 |
commit | b405fe91e50c60c80e72d798025aea4917096421 (patch) | |
tree | bc0b8dc67e7bc7897c6299d4bc80e42a7842e7fe /drivers/md | |
parent | 84e923453e19d6427c6aa884d9561f01e1425d09 (diff) |
md/bitmap: use set_bit, test_bit, etc for operation on bitmap->flags.
We currently use '&' and '|' which isn't the norm in the kernel
and doesn't allow easy atomicity.
So change to bit numbers and {set,clear,test}_bit.
This allows us to remove a spinlock/unlock (which was dubious anyway)
and some other simplifications.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bitmap.c | 46 | ||||
-rw-r--r-- | drivers/md/bitmap.h | 6 |
2 files changed, 24 insertions, 28 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 09d360ff77dc..f3a9dffc3fc8 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -271,7 +271,7 @@ static void write_page(struct bitmap *bitmap, struct page *page, int wait) | |||
271 | if (bitmap->storage.file == NULL) { | 271 | if (bitmap->storage.file == NULL) { |
272 | switch (write_sb_page(bitmap, page, wait)) { | 272 | switch (write_sb_page(bitmap, page, wait)) { |
273 | case -EINVAL: | 273 | case -EINVAL: |
274 | bitmap->flags |= BITMAP_WRITE_ERROR; | 274 | set_bit(BITMAP_WRITE_ERROR, &bitmap->flags); |
275 | } | 275 | } |
276 | } else { | 276 | } else { |
277 | 277 | ||
@@ -289,20 +289,16 @@ static void write_page(struct bitmap *bitmap, struct page *page, int wait) | |||
289 | wait_event(bitmap->write_wait, | 289 | wait_event(bitmap->write_wait, |
290 | atomic_read(&bitmap->pending_writes)==0); | 290 | atomic_read(&bitmap->pending_writes)==0); |
291 | } | 291 | } |
292 | if (bitmap->flags & BITMAP_WRITE_ERROR) | 292 | if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags)) |
293 | bitmap_file_kick(bitmap); | 293 | bitmap_file_kick(bitmap); |
294 | } | 294 | } |
295 | 295 | ||
296 | static void end_bitmap_write(struct buffer_head *bh, int uptodate) | 296 | static void end_bitmap_write(struct buffer_head *bh, int uptodate) |
297 | { | 297 | { |
298 | struct bitmap *bitmap = bh->b_private; | 298 | struct bitmap *bitmap = bh->b_private; |
299 | unsigned long flags; | ||
300 | 299 | ||
301 | if (!uptodate) { | 300 | if (!uptodate) |
302 | spin_lock_irqsave(&bitmap->lock, flags); | 301 | set_bit(BITMAP_WRITE_ERROR, &bitmap->flags); |
303 | bitmap->flags |= BITMAP_WRITE_ERROR; | ||
304 | spin_unlock_irqrestore(&bitmap->lock, flags); | ||
305 | } | ||
306 | if (atomic_dec_and_test(&bitmap->pending_writes)) | 302 | if (atomic_dec_and_test(&bitmap->pending_writes)) |
307 | wake_up(&bitmap->write_wait); | 303 | wake_up(&bitmap->write_wait); |
308 | } | 304 | } |
@@ -389,7 +385,7 @@ static int read_page(struct file *file, unsigned long index, | |||
389 | 385 | ||
390 | wait_event(bitmap->write_wait, | 386 | wait_event(bitmap->write_wait, |
391 | atomic_read(&bitmap->pending_writes)==0); | 387 | atomic_read(&bitmap->pending_writes)==0); |
392 | if (bitmap->flags & BITMAP_WRITE_ERROR) | 388 | if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags)) |
393 | ret = -EIO; | 389 | ret = -EIO; |
394 | out: | 390 | out: |
395 | if (ret) | 391 | if (ret) |
@@ -521,7 +517,7 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap) | |||
521 | 517 | ||
522 | memcpy(sb->uuid, bitmap->mddev->uuid, 16); | 518 | memcpy(sb->uuid, bitmap->mddev->uuid, 16); |
523 | 519 | ||
524 | bitmap->flags |= BITMAP_STALE; | 520 | set_bit(BITMAP_STALE, &bitmap->flags); |
525 | sb->state = cpu_to_le32(bitmap->flags); | 521 | sb->state = cpu_to_le32(bitmap->flags); |
526 | bitmap->events_cleared = bitmap->mddev->events; | 522 | bitmap->events_cleared = bitmap->mddev->events; |
527 | sb->events_cleared = cpu_to_le64(bitmap->mddev->events); | 523 | sb->events_cleared = cpu_to_le64(bitmap->mddev->events); |
@@ -545,7 +541,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
545 | chunksize = 128 * 1024 * 1024; | 541 | chunksize = 128 * 1024 * 1024; |
546 | daemon_sleep = 5 * HZ; | 542 | daemon_sleep = 5 * HZ; |
547 | write_behind = 0; | 543 | write_behind = 0; |
548 | bitmap->flags = BITMAP_STALE; | 544 | set_bit(BITMAP_STALE, &bitmap->flags); |
549 | err = 0; | 545 | err = 0; |
550 | goto out_no_sb; | 546 | goto out_no_sb; |
551 | } | 547 | } |
@@ -617,20 +613,20 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
617 | "-- forcing full recovery\n", | 613 | "-- forcing full recovery\n", |
618 | bmname(bitmap), events, | 614 | bmname(bitmap), events, |
619 | (unsigned long long) bitmap->mddev->events); | 615 | (unsigned long long) bitmap->mddev->events); |
620 | bitmap->flags |= BITMAP_STALE; | 616 | set_bit(BITMAP_STALE, &bitmap->flags); |
621 | } | 617 | } |
622 | } | 618 | } |
623 | 619 | ||
624 | /* assign fields using values from superblock */ | 620 | /* assign fields using values from superblock */ |
625 | bitmap->flags |= le32_to_cpu(sb->state); | 621 | bitmap->flags |= le32_to_cpu(sb->state); |
626 | if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN) | 622 | if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN) |
627 | bitmap->flags |= BITMAP_HOSTENDIAN; | 623 | set_bit(BITMAP_HOSTENDIAN, &bitmap->flags); |
628 | bitmap->events_cleared = le64_to_cpu(sb->events_cleared); | 624 | bitmap->events_cleared = le64_to_cpu(sb->events_cleared); |
629 | err = 0; | 625 | err = 0; |
630 | out: | 626 | out: |
631 | kunmap_atomic(sb); | 627 | kunmap_atomic(sb); |
632 | out_no_sb: | 628 | out_no_sb: |
633 | if (bitmap->flags & BITMAP_STALE) | 629 | if (test_bit(BITMAP_STALE, &bitmap->flags)) |
634 | bitmap->events_cleared = bitmap->mddev->events; | 630 | bitmap->events_cleared = bitmap->mddev->events; |
635 | bitmap->mddev->bitmap_info.chunksize = chunksize; | 631 | bitmap->mddev->bitmap_info.chunksize = chunksize; |
636 | bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep; | 632 | bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep; |
@@ -796,8 +792,7 @@ static void bitmap_file_kick(struct bitmap *bitmap) | |||
796 | { | 792 | { |
797 | char *path, *ptr = NULL; | 793 | char *path, *ptr = NULL; |
798 | 794 | ||
799 | if (!(bitmap->flags & BITMAP_STALE)) { | 795 | if (!test_and_set_bit(BITMAP_STALE, &bitmap->flags)) { |
800 | bitmap->flags |= BITMAP_STALE; | ||
801 | bitmap_update_sb(bitmap); | 796 | bitmap_update_sb(bitmap); |
802 | 797 | ||
803 | if (bitmap->storage.file) { | 798 | if (bitmap->storage.file) { |
@@ -868,7 +863,7 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block) | |||
868 | 863 | ||
869 | /* set the bit */ | 864 | /* set the bit */ |
870 | kaddr = kmap_atomic(page); | 865 | kaddr = kmap_atomic(page); |
871 | if (bitmap->flags & BITMAP_HOSTENDIAN) | 866 | if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags)) |
872 | set_bit(bit, kaddr); | 867 | set_bit(bit, kaddr); |
873 | else | 868 | else |
874 | __set_bit_le(bit, kaddr); | 869 | __set_bit_le(bit, kaddr); |
@@ -890,7 +885,7 @@ static void bitmap_file_clear_bit(struct bitmap *bitmap, sector_t block) | |||
890 | return; | 885 | return; |
891 | bit = file_page_offset(&bitmap->storage, chunk); | 886 | bit = file_page_offset(&bitmap->storage, chunk); |
892 | paddr = kmap_atomic(page); | 887 | paddr = kmap_atomic(page); |
893 | if (bitmap->flags & BITMAP_HOSTENDIAN) | 888 | if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags)) |
894 | clear_bit(bit, paddr); | 889 | clear_bit(bit, paddr); |
895 | else | 890 | else |
896 | __clear_bit_le(bit, paddr); | 891 | __clear_bit_le(bit, paddr); |
@@ -941,7 +936,7 @@ void bitmap_unplug(struct bitmap *bitmap) | |||
941 | else | 936 | else |
942 | md_super_wait(bitmap->mddev); | 937 | md_super_wait(bitmap->mddev); |
943 | } | 938 | } |
944 | if (bitmap->flags & BITMAP_WRITE_ERROR) | 939 | if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags)) |
945 | bitmap_file_kick(bitmap); | 940 | bitmap_file_kick(bitmap); |
946 | } | 941 | } |
947 | EXPORT_SYMBOL(bitmap_unplug); | 942 | EXPORT_SYMBOL(bitmap_unplug); |
@@ -988,7 +983,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | |||
988 | return 0; | 983 | return 0; |
989 | } | 984 | } |
990 | 985 | ||
991 | outofdate = bitmap->flags & BITMAP_STALE; | 986 | outofdate = test_bit(BITMAP_STALE, &bitmap->flags); |
992 | if (outofdate) | 987 | if (outofdate) |
993 | printk(KERN_INFO "%s: bitmap file is out of date, doing full " | 988 | printk(KERN_INFO "%s: bitmap file is out of date, doing full " |
994 | "recovery\n", bmname(bitmap)); | 989 | "recovery\n", bmname(bitmap)); |
@@ -1045,12 +1040,13 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | |||
1045 | write_page(bitmap, page, 1); | 1040 | write_page(bitmap, page, 1); |
1046 | 1041 | ||
1047 | ret = -EIO; | 1042 | ret = -EIO; |
1048 | if (bitmap->flags & BITMAP_WRITE_ERROR) | 1043 | if (test_bit(BITMAP_WRITE_ERROR, |
1044 | &bitmap->flags)) | ||
1049 | goto err; | 1045 | goto err; |
1050 | } | 1046 | } |
1051 | } | 1047 | } |
1052 | paddr = kmap_atomic(page); | 1048 | paddr = kmap_atomic(page); |
1053 | if (bitmap->flags & BITMAP_HOSTENDIAN) | 1049 | if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags)) |
1054 | b = test_bit(bit, paddr); | 1050 | b = test_bit(bit, paddr); |
1055 | else | 1051 | else |
1056 | b = test_bit_le(bit, paddr); | 1052 | b = test_bit_le(bit, paddr); |
@@ -1758,7 +1754,7 @@ int bitmap_create(struct mddev *mddev) | |||
1758 | mddev->bitmap = bitmap; | 1754 | mddev->bitmap = bitmap; |
1759 | 1755 | ||
1760 | 1756 | ||
1761 | return (bitmap->flags & BITMAP_WRITE_ERROR) ? -EIO : 0; | 1757 | return test_bit(BITMAP_WRITE_ERROR, &bitmap->flags) ? -EIO : 0; |
1762 | 1758 | ||
1763 | error: | 1759 | error: |
1764 | bitmap_free(bitmap); | 1760 | bitmap_free(bitmap); |
@@ -1799,7 +1795,7 @@ int bitmap_load(struct mddev *mddev) | |||
1799 | 1795 | ||
1800 | if (err) | 1796 | if (err) |
1801 | goto out; | 1797 | goto out; |
1802 | bitmap->flags &= ~BITMAP_STALE; | 1798 | clear_bit(BITMAP_STALE, &bitmap->flags); |
1803 | 1799 | ||
1804 | /* Kick recovery in case any bits were set */ | 1800 | /* Kick recovery in case any bits were set */ |
1805 | set_bit(MD_RECOVERY_NEEDED, &bitmap->mddev->recovery); | 1801 | set_bit(MD_RECOVERY_NEEDED, &bitmap->mddev->recovery); |
@@ -1809,7 +1805,7 @@ int bitmap_load(struct mddev *mddev) | |||
1809 | 1805 | ||
1810 | bitmap_update_sb(bitmap); | 1806 | bitmap_update_sb(bitmap); |
1811 | 1807 | ||
1812 | if (bitmap->flags & BITMAP_WRITE_ERROR) | 1808 | if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags)) |
1813 | err = -EIO; | 1809 | err = -EIO; |
1814 | out: | 1810 | out: |
1815 | return err; | 1811 | return err; |
diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h index 26689260e179..e2d999a62ba9 100644 --- a/drivers/md/bitmap.h +++ b/drivers/md/bitmap.h | |||
@@ -111,9 +111,9 @@ typedef __u16 bitmap_counter_t; | |||
111 | 111 | ||
112 | /* use these for bitmap->flags and bitmap->sb->state bit-fields */ | 112 | /* use these for bitmap->flags and bitmap->sb->state bit-fields */ |
113 | enum bitmap_state { | 113 | enum bitmap_state { |
114 | BITMAP_STALE = 0x002, /* the bitmap file is out of date or had -EIO */ | 114 | BITMAP_STALE = 1, /* the bitmap file is out of date or had -EIO */ |
115 | BITMAP_WRITE_ERROR = 0x004, /* A write error has occurred */ | 115 | BITMAP_WRITE_ERROR = 2, /* A write error has occurred */ |
116 | BITMAP_HOSTENDIAN = 0x8000, | 116 | BITMAP_HOSTENDIAN =15, |
117 | }; | 117 | }; |
118 | 118 | ||
119 | /* the superblock at the front of the bitmap file -- little endian */ | 119 | /* the superblock at the front of the bitmap file -- little endian */ |