diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bitmap.c | 83 | ||||
-rw-r--r-- | drivers/md/dm-raid1.c | 2 | ||||
-rw-r--r-- | drivers/md/dm-table.c | 6 | ||||
-rw-r--r-- | drivers/md/dm.c | 196 | ||||
-rw-r--r-- | drivers/md/md.c | 6 | ||||
-rw-r--r-- | drivers/md/raid1.c | 30 | ||||
-rw-r--r-- | drivers/md/raid5.c | 2 | ||||
-rw-r--r-- | drivers/md/raid6main.c | 2 |
8 files changed, 170 insertions, 157 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 0c2ed99a3832..41df4cda66e2 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -108,7 +108,7 @@ static unsigned char *bitmap_alloc_page(struct bitmap *bitmap) | |||
108 | { | 108 | { |
109 | unsigned char *page; | 109 | unsigned char *page; |
110 | 110 | ||
111 | #if INJECT_FAULTS_1 | 111 | #ifdef INJECT_FAULTS_1 |
112 | page = NULL; | 112 | page = NULL; |
113 | #else | 113 | #else |
114 | page = kmalloc(PAGE_SIZE, GFP_NOIO); | 114 | page = kmalloc(PAGE_SIZE, GFP_NOIO); |
@@ -818,8 +818,7 @@ int bitmap_unplug(struct bitmap *bitmap) | |||
818 | return 0; | 818 | return 0; |
819 | } | 819 | } |
820 | 820 | ||
821 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, | 821 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset); |
822 | unsigned long sectors, int in_sync); | ||
823 | /* * bitmap_init_from_disk -- called at bitmap_create time to initialize | 822 | /* * bitmap_init_from_disk -- called at bitmap_create time to initialize |
824 | * the in-memory bitmap from the on-disk bitmap -- also, sets up the | 823 | * the in-memory bitmap from the on-disk bitmap -- also, sets up the |
825 | * memory mapping of the bitmap file | 824 | * memory mapping of the bitmap file |
@@ -828,7 +827,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, | |||
828 | * previously kicked from the array, we mark all the bits as | 827 | * previously kicked from the array, we mark all the bits as |
829 | * 1's in order to cause a full resync. | 828 | * 1's in order to cause a full resync. |
830 | */ | 829 | */ |
831 | static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) | 830 | static int bitmap_init_from_disk(struct bitmap *bitmap) |
832 | { | 831 | { |
833 | unsigned long i, chunks, index, oldindex, bit; | 832 | unsigned long i, chunks, index, oldindex, bit; |
834 | struct page *page = NULL, *oldpage = NULL; | 833 | struct page *page = NULL, *oldpage = NULL; |
@@ -843,7 +842,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) | |||
843 | 842 | ||
844 | BUG_ON(!file && !bitmap->offset); | 843 | BUG_ON(!file && !bitmap->offset); |
845 | 844 | ||
846 | #if INJECT_FAULTS_3 | 845 | #ifdef INJECT_FAULTS_3 |
847 | outofdate = 1; | 846 | outofdate = 1; |
848 | #else | 847 | #else |
849 | outofdate = bitmap->flags & BITMAP_STALE; | 848 | outofdate = bitmap->flags & BITMAP_STALE; |
@@ -929,8 +928,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) | |||
929 | } | 928 | } |
930 | if (test_bit(bit, page_address(page))) { | 929 | if (test_bit(bit, page_address(page))) { |
931 | /* if the disk bit is set, set the memory bit */ | 930 | /* if the disk bit is set, set the memory bit */ |
932 | bitmap_set_memory_bits(bitmap, | 931 | bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap)); |
933 | i << CHUNK_BLOCK_SHIFT(bitmap), 1, in_sync); | ||
934 | bit_cnt++; | 932 | bit_cnt++; |
935 | } | 933 | } |
936 | } | 934 | } |
@@ -1187,7 +1185,7 @@ static int bitmap_start_daemon(struct bitmap *bitmap, mdk_thread_t **ptr, | |||
1187 | 1185 | ||
1188 | spin_unlock_irqrestore(&bitmap->lock, flags); | 1186 | spin_unlock_irqrestore(&bitmap->lock, flags); |
1189 | 1187 | ||
1190 | #if INJECT_FATAL_FAULT_2 | 1188 | #ifdef INJECT_FATAL_FAULT_2 |
1191 | daemon = NULL; | 1189 | daemon = NULL; |
1192 | #else | 1190 | #else |
1193 | sprintf(namebuf, "%%s_%s", name); | 1191 | sprintf(namebuf, "%%s_%s", name); |
@@ -1426,35 +1424,53 @@ void bitmap_close_sync(struct bitmap *bitmap) | |||
1426 | } | 1424 | } |
1427 | } | 1425 | } |
1428 | 1426 | ||
1429 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, | 1427 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset) |
1430 | unsigned long sectors, int in_sync) | ||
1431 | { | 1428 | { |
1432 | /* For each chunk covered by any of these sectors, set the | 1429 | /* For each chunk covered by any of these sectors, set the |
1433 | * counter to 1 and set resync_needed unless in_sync. They should all | 1430 | * counter to 1 and set resync_needed. They should all |
1434 | * be 0 at this point | 1431 | * be 0 at this point |
1435 | */ | 1432 | */ |
1436 | while (sectors) { | 1433 | |
1437 | int secs; | 1434 | int secs; |
1438 | bitmap_counter_t *bmc; | 1435 | bitmap_counter_t *bmc; |
1439 | spin_lock_irq(&bitmap->lock); | 1436 | spin_lock_irq(&bitmap->lock); |
1440 | bmc = bitmap_get_counter(bitmap, offset, &secs, 1); | 1437 | bmc = bitmap_get_counter(bitmap, offset, &secs, 1); |
1441 | if (!bmc) { | 1438 | if (!bmc) { |
1442 | spin_unlock_irq(&bitmap->lock); | ||
1443 | return; | ||
1444 | } | ||
1445 | if (! *bmc) { | ||
1446 | struct page *page; | ||
1447 | *bmc = 1 | (in_sync? 0 : NEEDED_MASK); | ||
1448 | bitmap_count_page(bitmap, offset, 1); | ||
1449 | page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)); | ||
1450 | set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); | ||
1451 | } | ||
1452 | spin_unlock_irq(&bitmap->lock); | 1439 | spin_unlock_irq(&bitmap->lock); |
1453 | if (sectors > secs) | 1440 | return; |
1454 | sectors -= secs; | 1441 | } |
1455 | else | 1442 | if (! *bmc) { |
1456 | sectors = 0; | 1443 | struct page *page; |
1444 | *bmc = 1 | NEEDED_MASK; | ||
1445 | bitmap_count_page(bitmap, offset, 1); | ||
1446 | page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)); | ||
1447 | set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); | ||
1457 | } | 1448 | } |
1449 | spin_unlock_irq(&bitmap->lock); | ||
1450 | |||
1451 | } | ||
1452 | |||
1453 | /* | ||
1454 | * flush out any pending updates | ||
1455 | */ | ||
1456 | void bitmap_flush(mddev_t *mddev) | ||
1457 | { | ||
1458 | struct bitmap *bitmap = mddev->bitmap; | ||
1459 | int sleep; | ||
1460 | |||
1461 | if (!bitmap) /* there was no bitmap */ | ||
1462 | return; | ||
1463 | |||
1464 | /* run the daemon_work three time to ensure everything is flushed | ||
1465 | * that can be | ||
1466 | */ | ||
1467 | sleep = bitmap->daemon_sleep; | ||
1468 | bitmap->daemon_sleep = 0; | ||
1469 | bitmap_daemon_work(bitmap); | ||
1470 | bitmap_daemon_work(bitmap); | ||
1471 | bitmap_daemon_work(bitmap); | ||
1472 | bitmap->daemon_sleep = sleep; | ||
1473 | bitmap_update_sb(bitmap); | ||
1458 | } | 1474 | } |
1459 | 1475 | ||
1460 | /* | 1476 | /* |
@@ -1552,7 +1568,7 @@ int bitmap_create(mddev_t *mddev) | |||
1552 | 1568 | ||
1553 | bitmap->syncchunk = ~0UL; | 1569 | bitmap->syncchunk = ~0UL; |
1554 | 1570 | ||
1555 | #if INJECT_FATAL_FAULT_1 | 1571 | #ifdef INJECT_FATAL_FAULT_1 |
1556 | bitmap->bp = NULL; | 1572 | bitmap->bp = NULL; |
1557 | #else | 1573 | #else |
1558 | bitmap->bp = kmalloc(pages * sizeof(*bitmap->bp), GFP_KERNEL); | 1574 | bitmap->bp = kmalloc(pages * sizeof(*bitmap->bp), GFP_KERNEL); |
@@ -1565,7 +1581,8 @@ int bitmap_create(mddev_t *mddev) | |||
1565 | 1581 | ||
1566 | /* now that we have some pages available, initialize the in-memory | 1582 | /* now that we have some pages available, initialize the in-memory |
1567 | * bitmap from the on-disk bitmap */ | 1583 | * bitmap from the on-disk bitmap */ |
1568 | err = bitmap_init_from_disk(bitmap, mddev->recovery_cp == MaxSector); | 1584 | err = bitmap_init_from_disk(bitmap); |
1585 | |||
1569 | if (err) | 1586 | if (err) |
1570 | return err; | 1587 | return err; |
1571 | 1588 | ||
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 12031c9d3f1e..b08df8b9b2ca 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -1230,7 +1230,7 @@ static int __init dm_mirror_init(void) | |||
1230 | if (r) | 1230 | if (r) |
1231 | return r; | 1231 | return r; |
1232 | 1232 | ||
1233 | _kmirrord_wq = create_workqueue("kmirrord"); | 1233 | _kmirrord_wq = create_singlethread_workqueue("kmirrord"); |
1234 | if (!_kmirrord_wq) { | 1234 | if (!_kmirrord_wq) { |
1235 | DMERR("couldn't start kmirrord"); | 1235 | DMERR("couldn't start kmirrord"); |
1236 | dm_dirty_log_exit(); | 1236 | dm_dirty_log_exit(); |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index a5a4c0ed8a14..a6d3baa46f61 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -869,11 +869,17 @@ static void suspend_targets(struct dm_table *t, unsigned postsuspend) | |||
869 | 869 | ||
870 | void dm_table_presuspend_targets(struct dm_table *t) | 870 | void dm_table_presuspend_targets(struct dm_table *t) |
871 | { | 871 | { |
872 | if (!t) | ||
873 | return; | ||
874 | |||
872 | return suspend_targets(t, 0); | 875 | return suspend_targets(t, 0); |
873 | } | 876 | } |
874 | 877 | ||
875 | void dm_table_postsuspend_targets(struct dm_table *t) | 878 | void dm_table_postsuspend_targets(struct dm_table *t) |
876 | { | 879 | { |
880 | if (!t) | ||
881 | return; | ||
882 | |||
877 | return suspend_targets(t, 1); | 883 | return suspend_targets(t, 1); |
878 | } | 884 | } |
879 | 885 | ||
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 54fabbf06678..d487d9deb98e 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -55,10 +55,10 @@ union map_info *dm_get_mapinfo(struct bio *bio) | |||
55 | */ | 55 | */ |
56 | #define DMF_BLOCK_IO 0 | 56 | #define DMF_BLOCK_IO 0 |
57 | #define DMF_SUSPENDED 1 | 57 | #define DMF_SUSPENDED 1 |
58 | #define DMF_FS_LOCKED 2 | ||
59 | 58 | ||
60 | struct mapped_device { | 59 | struct mapped_device { |
61 | struct rw_semaphore lock; | 60 | struct rw_semaphore io_lock; |
61 | struct semaphore suspend_lock; | ||
62 | rwlock_t map_lock; | 62 | rwlock_t map_lock; |
63 | atomic_t holders; | 63 | atomic_t holders; |
64 | 64 | ||
@@ -248,16 +248,16 @@ static inline void free_tio(struct mapped_device *md, struct target_io *tio) | |||
248 | */ | 248 | */ |
249 | static int queue_io(struct mapped_device *md, struct bio *bio) | 249 | static int queue_io(struct mapped_device *md, struct bio *bio) |
250 | { | 250 | { |
251 | down_write(&md->lock); | 251 | down_write(&md->io_lock); |
252 | 252 | ||
253 | if (!test_bit(DMF_BLOCK_IO, &md->flags)) { | 253 | if (!test_bit(DMF_BLOCK_IO, &md->flags)) { |
254 | up_write(&md->lock); | 254 | up_write(&md->io_lock); |
255 | return 1; | 255 | return 1; |
256 | } | 256 | } |
257 | 257 | ||
258 | bio_list_add(&md->deferred, bio); | 258 | bio_list_add(&md->deferred, bio); |
259 | 259 | ||
260 | up_write(&md->lock); | 260 | up_write(&md->io_lock); |
261 | return 0; /* deferred successfully */ | 261 | return 0; /* deferred successfully */ |
262 | } | 262 | } |
263 | 263 | ||
@@ -568,14 +568,14 @@ static int dm_request(request_queue_t *q, struct bio *bio) | |||
568 | int r; | 568 | int r; |
569 | struct mapped_device *md = q->queuedata; | 569 | struct mapped_device *md = q->queuedata; |
570 | 570 | ||
571 | down_read(&md->lock); | 571 | down_read(&md->io_lock); |
572 | 572 | ||
573 | /* | 573 | /* |
574 | * If we're suspended we have to queue | 574 | * If we're suspended we have to queue |
575 | * this io for later. | 575 | * this io for later. |
576 | */ | 576 | */ |
577 | while (test_bit(DMF_BLOCK_IO, &md->flags)) { | 577 | while (test_bit(DMF_BLOCK_IO, &md->flags)) { |
578 | up_read(&md->lock); | 578 | up_read(&md->io_lock); |
579 | 579 | ||
580 | if (bio_rw(bio) == READA) { | 580 | if (bio_rw(bio) == READA) { |
581 | bio_io_error(bio, bio->bi_size); | 581 | bio_io_error(bio, bio->bi_size); |
@@ -594,11 +594,11 @@ static int dm_request(request_queue_t *q, struct bio *bio) | |||
594 | * We're in a while loop, because someone could suspend | 594 | * We're in a while loop, because someone could suspend |
595 | * before we get to the following read lock. | 595 | * before we get to the following read lock. |
596 | */ | 596 | */ |
597 | down_read(&md->lock); | 597 | down_read(&md->io_lock); |
598 | } | 598 | } |
599 | 599 | ||
600 | __split_bio(md, bio); | 600 | __split_bio(md, bio); |
601 | up_read(&md->lock); | 601 | up_read(&md->io_lock); |
602 | return 0; | 602 | return 0; |
603 | } | 603 | } |
604 | 604 | ||
@@ -610,7 +610,7 @@ static int dm_flush_all(request_queue_t *q, struct gendisk *disk, | |||
610 | int ret = -ENXIO; | 610 | int ret = -ENXIO; |
611 | 611 | ||
612 | if (map) { | 612 | if (map) { |
613 | ret = dm_table_flush_all(md->map); | 613 | ret = dm_table_flush_all(map); |
614 | dm_table_put(map); | 614 | dm_table_put(map); |
615 | } | 615 | } |
616 | 616 | ||
@@ -747,7 +747,8 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) | |||
747 | goto bad1; | 747 | goto bad1; |
748 | 748 | ||
749 | memset(md, 0, sizeof(*md)); | 749 | memset(md, 0, sizeof(*md)); |
750 | init_rwsem(&md->lock); | 750 | init_rwsem(&md->io_lock); |
751 | init_MUTEX(&md->suspend_lock); | ||
751 | rwlock_init(&md->map_lock); | 752 | rwlock_init(&md->map_lock); |
752 | atomic_set(&md->holders, 1); | 753 | atomic_set(&md->holders, 1); |
753 | atomic_set(&md->event_nr, 0); | 754 | atomic_set(&md->event_nr, 0); |
@@ -825,18 +826,13 @@ static void event_callback(void *context) | |||
825 | wake_up(&md->eventq); | 826 | wake_up(&md->eventq); |
826 | } | 827 | } |
827 | 828 | ||
828 | static void __set_size(struct gendisk *disk, sector_t size) | 829 | static void __set_size(struct mapped_device *md, sector_t size) |
829 | { | 830 | { |
830 | struct block_device *bdev; | 831 | set_capacity(md->disk, size); |
831 | 832 | ||
832 | set_capacity(disk, size); | 833 | down(&md->frozen_bdev->bd_inode->i_sem); |
833 | bdev = bdget_disk(disk, 0); | 834 | i_size_write(md->frozen_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); |
834 | if (bdev) { | 835 | up(&md->frozen_bdev->bd_inode->i_sem); |
835 | down(&bdev->bd_inode->i_sem); | ||
836 | i_size_write(bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); | ||
837 | up(&bdev->bd_inode->i_sem); | ||
838 | bdput(bdev); | ||
839 | } | ||
840 | } | 836 | } |
841 | 837 | ||
842 | static int __bind(struct mapped_device *md, struct dm_table *t) | 838 | static int __bind(struct mapped_device *md, struct dm_table *t) |
@@ -845,17 +841,18 @@ static int __bind(struct mapped_device *md, struct dm_table *t) | |||
845 | sector_t size; | 841 | sector_t size; |
846 | 842 | ||
847 | size = dm_table_get_size(t); | 843 | size = dm_table_get_size(t); |
848 | __set_size(md->disk, size); | 844 | __set_size(md, size); |
849 | if (size == 0) | 845 | if (size == 0) |
850 | return 0; | 846 | return 0; |
851 | 847 | ||
848 | dm_table_get(t); | ||
849 | dm_table_event_callback(t, event_callback, md); | ||
850 | |||
852 | write_lock(&md->map_lock); | 851 | write_lock(&md->map_lock); |
853 | md->map = t; | 852 | md->map = t; |
853 | dm_table_set_restrictions(t, q); | ||
854 | write_unlock(&md->map_lock); | 854 | write_unlock(&md->map_lock); |
855 | 855 | ||
856 | dm_table_get(t); | ||
857 | dm_table_event_callback(md->map, event_callback, md); | ||
858 | dm_table_set_restrictions(t, q); | ||
859 | return 0; | 856 | return 0; |
860 | } | 857 | } |
861 | 858 | ||
@@ -935,7 +932,7 @@ void dm_put(struct mapped_device *md) | |||
935 | struct dm_table *map = dm_get_table(md); | 932 | struct dm_table *map = dm_get_table(md); |
936 | 933 | ||
937 | if (atomic_dec_and_test(&md->holders)) { | 934 | if (atomic_dec_and_test(&md->holders)) { |
938 | if (!test_bit(DMF_SUSPENDED, &md->flags) && map) { | 935 | if (!dm_suspended(md)) { |
939 | dm_table_presuspend_targets(map); | 936 | dm_table_presuspend_targets(map); |
940 | dm_table_postsuspend_targets(map); | 937 | dm_table_postsuspend_targets(map); |
941 | } | 938 | } |
@@ -968,17 +965,17 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) | |||
968 | { | 965 | { |
969 | int r = -EINVAL; | 966 | int r = -EINVAL; |
970 | 967 | ||
971 | down_write(&md->lock); | 968 | down(&md->suspend_lock); |
972 | 969 | ||
973 | /* device must be suspended */ | 970 | /* device must be suspended */ |
974 | if (!test_bit(DMF_SUSPENDED, &md->flags)) | 971 | if (!dm_suspended(md)) |
975 | goto out; | 972 | goto out; |
976 | 973 | ||
977 | __unbind(md); | 974 | __unbind(md); |
978 | r = __bind(md, table); | 975 | r = __bind(md, table); |
979 | 976 | ||
980 | out: | 977 | out: |
981 | up_write(&md->lock); | 978 | up(&md->suspend_lock); |
982 | return r; | 979 | return r; |
983 | } | 980 | } |
984 | 981 | ||
@@ -986,16 +983,13 @@ out: | |||
986 | * Functions to lock and unlock any filesystem running on the | 983 | * Functions to lock and unlock any filesystem running on the |
987 | * device. | 984 | * device. |
988 | */ | 985 | */ |
989 | static int __lock_fs(struct mapped_device *md) | 986 | static int lock_fs(struct mapped_device *md) |
990 | { | 987 | { |
991 | int error = -ENOMEM; | 988 | int r = -ENOMEM; |
992 | |||
993 | if (test_and_set_bit(DMF_FS_LOCKED, &md->flags)) | ||
994 | return 0; | ||
995 | 989 | ||
996 | md->frozen_bdev = bdget_disk(md->disk, 0); | 990 | md->frozen_bdev = bdget_disk(md->disk, 0); |
997 | if (!md->frozen_bdev) { | 991 | if (!md->frozen_bdev) { |
998 | DMWARN("bdget failed in __lock_fs"); | 992 | DMWARN("bdget failed in lock_fs"); |
999 | goto out; | 993 | goto out; |
1000 | } | 994 | } |
1001 | 995 | ||
@@ -1003,13 +997,13 @@ static int __lock_fs(struct mapped_device *md) | |||
1003 | 997 | ||
1004 | md->frozen_sb = freeze_bdev(md->frozen_bdev); | 998 | md->frozen_sb = freeze_bdev(md->frozen_bdev); |
1005 | if (IS_ERR(md->frozen_sb)) { | 999 | if (IS_ERR(md->frozen_sb)) { |
1006 | error = PTR_ERR(md->frozen_sb); | 1000 | r = PTR_ERR(md->frozen_sb); |
1007 | goto out_bdput; | 1001 | goto out_bdput; |
1008 | } | 1002 | } |
1009 | 1003 | ||
1010 | /* don't bdput right now, we don't want the bdev | 1004 | /* don't bdput right now, we don't want the bdev |
1011 | * to go away while it is locked. We'll bdput | 1005 | * to go away while it is locked. We'll bdput |
1012 | * in __unlock_fs | 1006 | * in unlock_fs |
1013 | */ | 1007 | */ |
1014 | return 0; | 1008 | return 0; |
1015 | 1009 | ||
@@ -1018,15 +1012,11 @@ out_bdput: | |||
1018 | md->frozen_sb = NULL; | 1012 | md->frozen_sb = NULL; |
1019 | md->frozen_bdev = NULL; | 1013 | md->frozen_bdev = NULL; |
1020 | out: | 1014 | out: |
1021 | clear_bit(DMF_FS_LOCKED, &md->flags); | 1015 | return r; |
1022 | return error; | ||
1023 | } | 1016 | } |
1024 | 1017 | ||
1025 | static void __unlock_fs(struct mapped_device *md) | 1018 | static void unlock_fs(struct mapped_device *md) |
1026 | { | 1019 | { |
1027 | if (!test_and_clear_bit(DMF_FS_LOCKED, &md->flags)) | ||
1028 | return; | ||
1029 | |||
1030 | thaw_bdev(md->frozen_bdev, md->frozen_sb); | 1020 | thaw_bdev(md->frozen_bdev, md->frozen_sb); |
1031 | bdput(md->frozen_bdev); | 1021 | bdput(md->frozen_bdev); |
1032 | 1022 | ||
@@ -1043,50 +1033,37 @@ static void __unlock_fs(struct mapped_device *md) | |||
1043 | */ | 1033 | */ |
1044 | int dm_suspend(struct mapped_device *md) | 1034 | int dm_suspend(struct mapped_device *md) |
1045 | { | 1035 | { |
1046 | struct dm_table *map; | 1036 | struct dm_table *map = NULL; |
1047 | DECLARE_WAITQUEUE(wait, current); | 1037 | DECLARE_WAITQUEUE(wait, current); |
1048 | int error = -EINVAL; | 1038 | int r = -EINVAL; |
1049 | 1039 | ||
1050 | /* Flush I/O to the device. */ | 1040 | down(&md->suspend_lock); |
1051 | down_read(&md->lock); | 1041 | |
1052 | if (test_bit(DMF_BLOCK_IO, &md->flags)) | 1042 | if (dm_suspended(md)) |
1053 | goto out_read_unlock; | 1043 | goto out; |
1054 | 1044 | ||
1055 | map = dm_get_table(md); | 1045 | map = dm_get_table(md); |
1056 | if (map) | ||
1057 | /* This does not get reverted if there's an error later. */ | ||
1058 | dm_table_presuspend_targets(map); | ||
1059 | 1046 | ||
1060 | error = __lock_fs(md); | 1047 | /* This does not get reverted if there's an error later. */ |
1061 | if (error) { | 1048 | dm_table_presuspend_targets(map); |
1062 | dm_table_put(map); | ||
1063 | goto out_read_unlock; | ||
1064 | } | ||
1065 | 1049 | ||
1066 | up_read(&md->lock); | 1050 | /* Flush I/O to the device. */ |
1051 | r = lock_fs(md); | ||
1052 | if (r) | ||
1053 | goto out; | ||
1067 | 1054 | ||
1068 | /* | 1055 | /* |
1069 | * First we set the BLOCK_IO flag so no more ios will be mapped. | 1056 | * First we set the BLOCK_IO flag so no more ios will be mapped. |
1070 | * | ||
1071 | * If the flag is already set we know another thread is trying to | ||
1072 | * suspend as well, so we leave the fs locked for this thread. | ||
1073 | */ | 1057 | */ |
1074 | error = -EINVAL; | 1058 | down_write(&md->io_lock); |
1075 | down_write(&md->lock); | 1059 | set_bit(DMF_BLOCK_IO, &md->flags); |
1076 | if (test_and_set_bit(DMF_BLOCK_IO, &md->flags)) { | ||
1077 | if (map) | ||
1078 | dm_table_put(map); | ||
1079 | goto out_write_unlock; | ||
1080 | } | ||
1081 | 1060 | ||
1082 | add_wait_queue(&md->wait, &wait); | 1061 | add_wait_queue(&md->wait, &wait); |
1083 | up_write(&md->lock); | 1062 | up_write(&md->io_lock); |
1084 | 1063 | ||
1085 | /* unplug */ | 1064 | /* unplug */ |
1086 | if (map) { | 1065 | if (map) |
1087 | dm_table_unplug_all(map); | 1066 | dm_table_unplug_all(map); |
1088 | dm_table_put(map); | ||
1089 | } | ||
1090 | 1067 | ||
1091 | /* | 1068 | /* |
1092 | * Then we wait for the already mapped ios to | 1069 | * Then we wait for the already mapped ios to |
@@ -1102,62 +1079,67 @@ int dm_suspend(struct mapped_device *md) | |||
1102 | } | 1079 | } |
1103 | set_current_state(TASK_RUNNING); | 1080 | set_current_state(TASK_RUNNING); |
1104 | 1081 | ||
1105 | down_write(&md->lock); | 1082 | down_write(&md->io_lock); |
1106 | remove_wait_queue(&md->wait, &wait); | 1083 | remove_wait_queue(&md->wait, &wait); |
1107 | 1084 | ||
1108 | /* were we interrupted ? */ | 1085 | /* were we interrupted ? */ |
1109 | error = -EINTR; | 1086 | r = -EINTR; |
1110 | if (atomic_read(&md->pending)) | 1087 | if (atomic_read(&md->pending)) { |
1111 | goto out_unfreeze; | 1088 | up_write(&md->io_lock); |
1112 | 1089 | unlock_fs(md); | |
1113 | set_bit(DMF_SUSPENDED, &md->flags); | 1090 | clear_bit(DMF_BLOCK_IO, &md->flags); |
1091 | goto out; | ||
1092 | } | ||
1093 | up_write(&md->io_lock); | ||
1114 | 1094 | ||
1115 | map = dm_get_table(md); | 1095 | dm_table_postsuspend_targets(map); |
1116 | if (map) | ||
1117 | dm_table_postsuspend_targets(map); | ||
1118 | dm_table_put(map); | ||
1119 | up_write(&md->lock); | ||
1120 | 1096 | ||
1121 | return 0; | 1097 | set_bit(DMF_SUSPENDED, &md->flags); |
1122 | 1098 | ||
1123 | out_unfreeze: | 1099 | r = 0; |
1124 | __unlock_fs(md); | ||
1125 | clear_bit(DMF_BLOCK_IO, &md->flags); | ||
1126 | out_write_unlock: | ||
1127 | up_write(&md->lock); | ||
1128 | return error; | ||
1129 | 1100 | ||
1130 | out_read_unlock: | 1101 | out: |
1131 | up_read(&md->lock); | 1102 | dm_table_put(map); |
1132 | return error; | 1103 | up(&md->suspend_lock); |
1104 | return r; | ||
1133 | } | 1105 | } |
1134 | 1106 | ||
1135 | int dm_resume(struct mapped_device *md) | 1107 | int dm_resume(struct mapped_device *md) |
1136 | { | 1108 | { |
1109 | int r = -EINVAL; | ||
1137 | struct bio *def; | 1110 | struct bio *def; |
1138 | struct dm_table *map = dm_get_table(md); | 1111 | struct dm_table *map = NULL; |
1139 | 1112 | ||
1140 | down_write(&md->lock); | 1113 | down(&md->suspend_lock); |
1141 | if (!map || | 1114 | if (!dm_suspended(md)) |
1142 | !test_bit(DMF_SUSPENDED, &md->flags) || | 1115 | goto out; |
1143 | !dm_table_get_size(map)) { | 1116 | |
1144 | up_write(&md->lock); | 1117 | map = dm_get_table(md); |
1145 | dm_table_put(map); | 1118 | if (!map || !dm_table_get_size(map)) |
1146 | return -EINVAL; | 1119 | goto out; |
1147 | } | ||
1148 | 1120 | ||
1149 | dm_table_resume_targets(map); | 1121 | dm_table_resume_targets(map); |
1150 | clear_bit(DMF_SUSPENDED, &md->flags); | 1122 | |
1123 | down_write(&md->io_lock); | ||
1151 | clear_bit(DMF_BLOCK_IO, &md->flags); | 1124 | clear_bit(DMF_BLOCK_IO, &md->flags); |
1152 | 1125 | ||
1153 | def = bio_list_get(&md->deferred); | 1126 | def = bio_list_get(&md->deferred); |
1154 | __flush_deferred_io(md, def); | 1127 | __flush_deferred_io(md, def); |
1155 | up_write(&md->lock); | 1128 | up_write(&md->io_lock); |
1156 | __unlock_fs(md); | 1129 | |
1130 | unlock_fs(md); | ||
1131 | |||
1132 | clear_bit(DMF_SUSPENDED, &md->flags); | ||
1133 | |||
1157 | dm_table_unplug_all(map); | 1134 | dm_table_unplug_all(map); |
1135 | |||
1136 | r = 0; | ||
1137 | |||
1138 | out: | ||
1158 | dm_table_put(map); | 1139 | dm_table_put(map); |
1140 | up(&md->suspend_lock); | ||
1159 | 1141 | ||
1160 | return 0; | 1142 | return r; |
1161 | } | 1143 | } |
1162 | 1144 | ||
1163 | /*----------------------------------------------------------------- | 1145 | /*----------------------------------------------------------------- |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 4a0c57db2b67..480f658db6f2 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -284,7 +284,7 @@ static mdk_rdev_t * find_rdev(mddev_t * mddev, dev_t dev) | |||
284 | return NULL; | 284 | return NULL; |
285 | } | 285 | } |
286 | 286 | ||
287 | inline static sector_t calc_dev_sboffset(struct block_device *bdev) | 287 | static inline sector_t calc_dev_sboffset(struct block_device *bdev) |
288 | { | 288 | { |
289 | sector_t size = bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; | 289 | sector_t size = bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; |
290 | return MD_NEW_SIZE_BLOCKS(size); | 290 | return MD_NEW_SIZE_BLOCKS(size); |
@@ -1798,6 +1798,8 @@ static int do_md_stop(mddev_t * mddev, int ro) | |||
1798 | goto out; | 1798 | goto out; |
1799 | mddev->ro = 1; | 1799 | mddev->ro = 1; |
1800 | } else { | 1800 | } else { |
1801 | bitmap_flush(mddev); | ||
1802 | wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); | ||
1801 | if (mddev->ro) | 1803 | if (mddev->ro) |
1802 | set_disk_ro(disk, 0); | 1804 | set_disk_ro(disk, 0); |
1803 | blk_queue_make_request(mddev->queue, md_fail_request); | 1805 | blk_queue_make_request(mddev->queue, md_fail_request); |
@@ -3484,7 +3486,6 @@ static void md_do_sync(mddev_t *mddev) | |||
3484 | goto skip; | 3486 | goto skip; |
3485 | } | 3487 | } |
3486 | ITERATE_MDDEV(mddev2,tmp) { | 3488 | ITERATE_MDDEV(mddev2,tmp) { |
3487 | printk("."); | ||
3488 | if (mddev2 == mddev) | 3489 | if (mddev2 == mddev) |
3489 | continue; | 3490 | continue; |
3490 | if (mddev2->curr_resync && | 3491 | if (mddev2->curr_resync && |
@@ -4007,3 +4008,4 @@ EXPORT_SYMBOL(md_wakeup_thread); | |||
4007 | EXPORT_SYMBOL(md_print_devices); | 4008 | EXPORT_SYMBOL(md_print_devices); |
4008 | EXPORT_SYMBOL(md_check_recovery); | 4009 | EXPORT_SYMBOL(md_check_recovery); |
4009 | MODULE_LICENSE("GPL"); | 4010 | MODULE_LICENSE("GPL"); |
4011 | MODULE_ALIAS("md"); | ||
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 5f253ee536bb..51d9645ed09c 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -893,7 +893,6 @@ static int end_sync_read(struct bio *bio, unsigned int bytes_done, int error) | |||
893 | if (!uptodate) { | 893 | if (!uptodate) { |
894 | md_error(r1_bio->mddev, | 894 | md_error(r1_bio->mddev, |
895 | conf->mirrors[r1_bio->read_disk].rdev); | 895 | conf->mirrors[r1_bio->read_disk].rdev); |
896 | set_bit(R1BIO_Degraded, &r1_bio->state); | ||
897 | } else | 896 | } else |
898 | set_bit(R1BIO_Uptodate, &r1_bio->state); | 897 | set_bit(R1BIO_Uptodate, &r1_bio->state); |
899 | rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev); | 898 | rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev); |
@@ -918,10 +917,9 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error) | |||
918 | mirror = i; | 917 | mirror = i; |
919 | break; | 918 | break; |
920 | } | 919 | } |
921 | if (!uptodate) { | 920 | if (!uptodate) |
922 | md_error(mddev, conf->mirrors[mirror].rdev); | 921 | md_error(mddev, conf->mirrors[mirror].rdev); |
923 | set_bit(R1BIO_Degraded, &r1_bio->state); | 922 | |
924 | } | ||
925 | update_head_pos(mirror, r1_bio); | 923 | update_head_pos(mirror, r1_bio); |
926 | 924 | ||
927 | if (atomic_dec_and_test(&r1_bio->remaining)) { | 925 | if (atomic_dec_and_test(&r1_bio->remaining)) { |
@@ -1109,6 +1107,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1109 | int i; | 1107 | int i; |
1110 | int write_targets = 0; | 1108 | int write_targets = 0; |
1111 | int sync_blocks; | 1109 | int sync_blocks; |
1110 | int still_degraded = 0; | ||
1112 | 1111 | ||
1113 | if (!conf->r1buf_pool) | 1112 | if (!conf->r1buf_pool) |
1114 | { | 1113 | { |
@@ -1137,7 +1136,10 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1137 | return 0; | 1136 | return 0; |
1138 | } | 1137 | } |
1139 | 1138 | ||
1140 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, mddev->degraded) && | 1139 | /* before building a request, check if we can skip these blocks.. |
1140 | * This call the bitmap_start_sync doesn't actually record anything | ||
1141 | */ | ||
1142 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && | ||
1141 | !conf->fullsync) { | 1143 | !conf->fullsync) { |
1142 | /* We can skip this block, and probably several more */ | 1144 | /* We can skip this block, and probably several more */ |
1143 | *skipped = 1; | 1145 | *skipped = 1; |
@@ -1203,24 +1205,23 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1203 | if (i == disk) { | 1205 | if (i == disk) { |
1204 | bio->bi_rw = READ; | 1206 | bio->bi_rw = READ; |
1205 | bio->bi_end_io = end_sync_read; | 1207 | bio->bi_end_io = end_sync_read; |
1206 | } else if (conf->mirrors[i].rdev && | 1208 | } else if (conf->mirrors[i].rdev == NULL || |
1207 | !conf->mirrors[i].rdev->faulty && | 1209 | conf->mirrors[i].rdev->faulty) { |
1208 | (!conf->mirrors[i].rdev->in_sync || | 1210 | still_degraded = 1; |
1209 | sector_nr + RESYNC_SECTORS > mddev->recovery_cp)) { | 1211 | continue; |
1212 | } else if (!conf->mirrors[i].rdev->in_sync || | ||
1213 | sector_nr + RESYNC_SECTORS > mddev->recovery_cp) { | ||
1210 | bio->bi_rw = WRITE; | 1214 | bio->bi_rw = WRITE; |
1211 | bio->bi_end_io = end_sync_write; | 1215 | bio->bi_end_io = end_sync_write; |
1212 | write_targets ++; | 1216 | write_targets ++; |
1213 | } else | 1217 | } else |
1218 | /* no need to read or write here */ | ||
1214 | continue; | 1219 | continue; |
1215 | bio->bi_sector = sector_nr + conf->mirrors[i].rdev->data_offset; | 1220 | bio->bi_sector = sector_nr + conf->mirrors[i].rdev->data_offset; |
1216 | bio->bi_bdev = conf->mirrors[i].rdev->bdev; | 1221 | bio->bi_bdev = conf->mirrors[i].rdev->bdev; |
1217 | bio->bi_private = r1_bio; | 1222 | bio->bi_private = r1_bio; |
1218 | } | 1223 | } |
1219 | 1224 | ||
1220 | if (write_targets + 1 < conf->raid_disks) | ||
1221 | /* array degraded, can't clear bitmap */ | ||
1222 | set_bit(R1BIO_Degraded, &r1_bio->state); | ||
1223 | |||
1224 | if (write_targets == 0) { | 1225 | if (write_targets == 0) { |
1225 | /* There is nowhere to write, so all non-sync | 1226 | /* There is nowhere to write, so all non-sync |
1226 | * drives must be failed - so we are finished | 1227 | * drives must be failed - so we are finished |
@@ -1243,7 +1244,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1243 | break; | 1244 | break; |
1244 | if (sync_blocks == 0) { | 1245 | if (sync_blocks == 0) { |
1245 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, | 1246 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, |
1246 | &sync_blocks, mddev->degraded) && | 1247 | &sync_blocks, still_degraded) && |
1247 | !conf->fullsync) | 1248 | !conf->fullsync) |
1248 | break; | 1249 | break; |
1249 | if (sync_blocks < (PAGE_SIZE>>9)) | 1250 | if (sync_blocks < (PAGE_SIZE>>9)) |
@@ -1468,6 +1469,7 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors) | |||
1468 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 1469 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
1469 | } | 1470 | } |
1470 | mddev->size = mddev->array_size; | 1471 | mddev->size = mddev->array_size; |
1472 | mddev->resync_max_sectors = sectors; | ||
1471 | return 0; | 1473 | return 0; |
1472 | } | 1474 | } |
1473 | 1475 | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 93a9726cc2d6..43f231a467d5 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1653,6 +1653,7 @@ static int run (mddev_t *mddev) | |||
1653 | 1653 | ||
1654 | /* device size must be a multiple of chunk size */ | 1654 | /* device size must be a multiple of chunk size */ |
1655 | mddev->size &= ~(mddev->chunk_size/1024 -1); | 1655 | mddev->size &= ~(mddev->chunk_size/1024 -1); |
1656 | mddev->resync_max_sectors = mddev->size << 1; | ||
1656 | 1657 | ||
1657 | if (!conf->chunk_size || conf->chunk_size % 4) { | 1658 | if (!conf->chunk_size || conf->chunk_size % 4) { |
1658 | printk(KERN_ERR "raid5: invalid chunk size %d for %s\n", | 1659 | printk(KERN_ERR "raid5: invalid chunk size %d for %s\n", |
@@ -1931,6 +1932,7 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors) | |||
1931 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 1932 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
1932 | } | 1933 | } |
1933 | mddev->size = sectors /2; | 1934 | mddev->size = sectors /2; |
1935 | mddev->resync_max_sectors = sectors; | ||
1934 | return 0; | 1936 | return 0; |
1935 | } | 1937 | } |
1936 | 1938 | ||
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index f62ea1a73d0d..495dee1d1e83 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c | |||
@@ -1813,6 +1813,7 @@ static int run (mddev_t *mddev) | |||
1813 | 1813 | ||
1814 | /* device size must be a multiple of chunk size */ | 1814 | /* device size must be a multiple of chunk size */ |
1815 | mddev->size &= ~(mddev->chunk_size/1024 -1); | 1815 | mddev->size &= ~(mddev->chunk_size/1024 -1); |
1816 | mddev->resync_max_sectors = mddev->size << 1; | ||
1816 | 1817 | ||
1817 | if (conf->raid_disks < 4) { | 1818 | if (conf->raid_disks < 4) { |
1818 | printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n", | 1819 | printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n", |
@@ -2095,6 +2096,7 @@ static int raid6_resize(mddev_t *mddev, sector_t sectors) | |||
2095 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 2096 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
2096 | } | 2097 | } |
2097 | mddev->size = sectors /2; | 2098 | mddev->size = sectors /2; |
2099 | mddev->resync_max_sectors = sectors; | ||
2098 | return 0; | 2100 | return 0; |
2099 | } | 2101 | } |
2100 | 2102 | ||