diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-06 15:59:59 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-06 15:59:59 -0500 |
commit | ccf18968b1bbc2fb117190a1984ac2a826dac228 (patch) | |
tree | 7bc8fbf5722aecf1e84fa50c31c657864cba1daa /drivers/md/raid5.c | |
parent | e91c021c487110386a07facd0396e6c3b7cf9c1f (diff) | |
parent | d99cf9d679a520d67f81d805b7cb91c68e1847f0 (diff) |
Merge ../torvalds-2.6/
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 174 |
1 files changed, 95 insertions, 79 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index fafc4bc045f7..54f4a9847e38 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -35,12 +35,10 @@ | |||
35 | #define STRIPE_SHIFT (PAGE_SHIFT - 9) | 35 | #define STRIPE_SHIFT (PAGE_SHIFT - 9) |
36 | #define STRIPE_SECTORS (STRIPE_SIZE>>9) | 36 | #define STRIPE_SECTORS (STRIPE_SIZE>>9) |
37 | #define IO_THRESHOLD 1 | 37 | #define IO_THRESHOLD 1 |
38 | #define HASH_PAGES 1 | 38 | #define NR_HASH (PAGE_SIZE / sizeof(struct hlist_head)) |
39 | #define HASH_PAGES_ORDER 0 | ||
40 | #define NR_HASH (HASH_PAGES * PAGE_SIZE / sizeof(struct stripe_head *)) | ||
41 | #define HASH_MASK (NR_HASH - 1) | 39 | #define HASH_MASK (NR_HASH - 1) |
42 | 40 | ||
43 | #define stripe_hash(conf, sect) ((conf)->stripe_hashtbl[((sect) >> STRIPE_SHIFT) & HASH_MASK]) | 41 | #define stripe_hash(conf, sect) (&((conf)->stripe_hashtbl[((sect) >> STRIPE_SHIFT) & HASH_MASK])) |
44 | 42 | ||
45 | /* bio's attached to a stripe+device for I/O are linked together in bi_sector | 43 | /* bio's attached to a stripe+device for I/O are linked together in bi_sector |
46 | * order without overlap. There may be several bio's per stripe+device, and | 44 | * order without overlap. There may be several bio's per stripe+device, and |
@@ -113,29 +111,21 @@ static void release_stripe(struct stripe_head *sh) | |||
113 | spin_unlock_irqrestore(&conf->device_lock, flags); | 111 | spin_unlock_irqrestore(&conf->device_lock, flags); |
114 | } | 112 | } |
115 | 113 | ||
116 | static void remove_hash(struct stripe_head *sh) | 114 | static inline void remove_hash(struct stripe_head *sh) |
117 | { | 115 | { |
118 | PRINTK("remove_hash(), stripe %llu\n", (unsigned long long)sh->sector); | 116 | PRINTK("remove_hash(), stripe %llu\n", (unsigned long long)sh->sector); |
119 | 117 | ||
120 | if (sh->hash_pprev) { | 118 | hlist_del_init(&sh->hash); |
121 | if (sh->hash_next) | ||
122 | sh->hash_next->hash_pprev = sh->hash_pprev; | ||
123 | *sh->hash_pprev = sh->hash_next; | ||
124 | sh->hash_pprev = NULL; | ||
125 | } | ||
126 | } | 119 | } |
127 | 120 | ||
128 | static __inline__ void insert_hash(raid5_conf_t *conf, struct stripe_head *sh) | 121 | static inline void insert_hash(raid5_conf_t *conf, struct stripe_head *sh) |
129 | { | 122 | { |
130 | struct stripe_head **shp = &stripe_hash(conf, sh->sector); | 123 | struct hlist_head *hp = stripe_hash(conf, sh->sector); |
131 | 124 | ||
132 | PRINTK("insert_hash(), stripe %llu\n", (unsigned long long)sh->sector); | 125 | PRINTK("insert_hash(), stripe %llu\n", (unsigned long long)sh->sector); |
133 | 126 | ||
134 | CHECK_DEVLOCK(); | 127 | CHECK_DEVLOCK(); |
135 | if ((sh->hash_next = *shp) != NULL) | 128 | hlist_add_head(&sh->hash, hp); |
136 | (*shp)->hash_pprev = &sh->hash_next; | ||
137 | *shp = sh; | ||
138 | sh->hash_pprev = shp; | ||
139 | } | 129 | } |
140 | 130 | ||
141 | 131 | ||
@@ -167,7 +157,7 @@ static void shrink_buffers(struct stripe_head *sh, int num) | |||
167 | if (!p) | 157 | if (!p) |
168 | continue; | 158 | continue; |
169 | sh->dev[i].page = NULL; | 159 | sh->dev[i].page = NULL; |
170 | page_cache_release(p); | 160 | put_page(p); |
171 | } | 161 | } |
172 | } | 162 | } |
173 | 163 | ||
@@ -228,10 +218,11 @@ static inline void init_stripe(struct stripe_head *sh, sector_t sector, int pd_i | |||
228 | static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector) | 218 | static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector) |
229 | { | 219 | { |
230 | struct stripe_head *sh; | 220 | struct stripe_head *sh; |
221 | struct hlist_node *hn; | ||
231 | 222 | ||
232 | CHECK_DEVLOCK(); | 223 | CHECK_DEVLOCK(); |
233 | PRINTK("__find_stripe, sector %llu\n", (unsigned long long)sector); | 224 | PRINTK("__find_stripe, sector %llu\n", (unsigned long long)sector); |
234 | for (sh = stripe_hash(conf, sector); sh; sh = sh->hash_next) | 225 | hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash) |
235 | if (sh->sector == sector) | 226 | if (sh->sector == sector) |
236 | return sh; | 227 | return sh; |
237 | PRINTK("__stripe %llu not in cache\n", (unsigned long long)sector); | 228 | PRINTK("__stripe %llu not in cache\n", (unsigned long long)sector); |
@@ -417,7 +408,7 @@ static int raid5_end_read_request(struct bio * bi, unsigned int bytes_done, | |||
417 | set_bit(R5_UPTODATE, &sh->dev[i].flags); | 408 | set_bit(R5_UPTODATE, &sh->dev[i].flags); |
418 | #endif | 409 | #endif |
419 | if (test_bit(R5_ReadError, &sh->dev[i].flags)) { | 410 | if (test_bit(R5_ReadError, &sh->dev[i].flags)) { |
420 | printk("R5: read error corrected!!\n"); | 411 | printk(KERN_INFO "raid5: read error corrected!!\n"); |
421 | clear_bit(R5_ReadError, &sh->dev[i].flags); | 412 | clear_bit(R5_ReadError, &sh->dev[i].flags); |
422 | clear_bit(R5_ReWrite, &sh->dev[i].flags); | 413 | clear_bit(R5_ReWrite, &sh->dev[i].flags); |
423 | } | 414 | } |
@@ -428,13 +419,14 @@ static int raid5_end_read_request(struct bio * bi, unsigned int bytes_done, | |||
428 | clear_bit(R5_UPTODATE, &sh->dev[i].flags); | 419 | clear_bit(R5_UPTODATE, &sh->dev[i].flags); |
429 | atomic_inc(&conf->disks[i].rdev->read_errors); | 420 | atomic_inc(&conf->disks[i].rdev->read_errors); |
430 | if (conf->mddev->degraded) | 421 | if (conf->mddev->degraded) |
431 | printk("R5: read error not correctable.\n"); | 422 | printk(KERN_WARNING "raid5: read error not correctable.\n"); |
432 | else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) | 423 | else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) |
433 | /* Oh, no!!! */ | 424 | /* Oh, no!!! */ |
434 | printk("R5: read error NOT corrected!!\n"); | 425 | printk(KERN_WARNING "raid5: read error NOT corrected!!\n"); |
435 | else if (atomic_read(&conf->disks[i].rdev->read_errors) | 426 | else if (atomic_read(&conf->disks[i].rdev->read_errors) |
436 | > conf->max_nr_stripes) | 427 | > conf->max_nr_stripes) |
437 | printk("raid5: Too many read errors, failing device.\n"); | 428 | printk(KERN_WARNING |
429 | "raid5: Too many read errors, failing device.\n"); | ||
438 | else | 430 | else |
439 | retry = 1; | 431 | retry = 1; |
440 | if (retry) | 432 | if (retry) |
@@ -604,7 +596,7 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks, | |||
604 | *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks; | 596 | *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks; |
605 | break; | 597 | break; |
606 | default: | 598 | default: |
607 | printk("raid5: unsupported algorithm %d\n", | 599 | printk(KERN_ERR "raid5: unsupported algorithm %d\n", |
608 | conf->algorithm); | 600 | conf->algorithm); |
609 | } | 601 | } |
610 | 602 | ||
@@ -645,7 +637,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) | |||
645 | i -= (sh->pd_idx + 1); | 637 | i -= (sh->pd_idx + 1); |
646 | break; | 638 | break; |
647 | default: | 639 | default: |
648 | printk("raid5: unsupported algorithm %d\n", | 640 | printk(KERN_ERR "raid5: unsupported algorithm %d\n", |
649 | conf->algorithm); | 641 | conf->algorithm); |
650 | } | 642 | } |
651 | 643 | ||
@@ -654,7 +646,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) | |||
654 | 646 | ||
655 | check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf); | 647 | check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf); |
656 | if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) { | 648 | if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) { |
657 | printk("compute_blocknr: map not correct\n"); | 649 | printk(KERN_ERR "compute_blocknr: map not correct\n"); |
658 | return 0; | 650 | return 0; |
659 | } | 651 | } |
660 | return r_sector; | 652 | return r_sector; |
@@ -737,7 +729,7 @@ static void compute_block(struct stripe_head *sh, int dd_idx) | |||
737 | if (test_bit(R5_UPTODATE, &sh->dev[i].flags)) | 729 | if (test_bit(R5_UPTODATE, &sh->dev[i].flags)) |
738 | ptr[count++] = p; | 730 | ptr[count++] = p; |
739 | else | 731 | else |
740 | printk("compute_block() %d, stripe %llu, %d" | 732 | printk(KERN_ERR "compute_block() %d, stripe %llu, %d" |
741 | " not present\n", dd_idx, | 733 | " not present\n", dd_idx, |
742 | (unsigned long long)sh->sector, i); | 734 | (unsigned long long)sh->sector, i); |
743 | 735 | ||
@@ -960,11 +952,11 @@ static void handle_stripe(struct stripe_head *sh) | |||
960 | syncing = test_bit(STRIPE_SYNCING, &sh->state); | 952 | syncing = test_bit(STRIPE_SYNCING, &sh->state); |
961 | /* Now to look around and see what can be done */ | 953 | /* Now to look around and see what can be done */ |
962 | 954 | ||
955 | rcu_read_lock(); | ||
963 | for (i=disks; i--; ) { | 956 | for (i=disks; i--; ) { |
964 | mdk_rdev_t *rdev; | 957 | mdk_rdev_t *rdev; |
965 | dev = &sh->dev[i]; | 958 | dev = &sh->dev[i]; |
966 | clear_bit(R5_Insync, &dev->flags); | 959 | clear_bit(R5_Insync, &dev->flags); |
967 | clear_bit(R5_Syncio, &dev->flags); | ||
968 | 960 | ||
969 | PRINTK("check %d: state 0x%lx read %p write %p written %p\n", | 961 | PRINTK("check %d: state 0x%lx read %p write %p written %p\n", |
970 | i, dev->flags, dev->toread, dev->towrite, dev->written); | 962 | i, dev->flags, dev->toread, dev->towrite, dev->written); |
@@ -1003,9 +995,9 @@ static void handle_stripe(struct stripe_head *sh) | |||
1003 | non_overwrite++; | 995 | non_overwrite++; |
1004 | } | 996 | } |
1005 | if (dev->written) written++; | 997 | if (dev->written) written++; |
1006 | rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */ | 998 | rdev = rcu_dereference(conf->disks[i].rdev); |
1007 | if (!rdev || !test_bit(In_sync, &rdev->flags)) { | 999 | if (!rdev || !test_bit(In_sync, &rdev->flags)) { |
1008 | /* The ReadError flag wil just be confusing now */ | 1000 | /* The ReadError flag will just be confusing now */ |
1009 | clear_bit(R5_ReadError, &dev->flags); | 1001 | clear_bit(R5_ReadError, &dev->flags); |
1010 | clear_bit(R5_ReWrite, &dev->flags); | 1002 | clear_bit(R5_ReWrite, &dev->flags); |
1011 | } | 1003 | } |
@@ -1016,6 +1008,7 @@ static void handle_stripe(struct stripe_head *sh) | |||
1016 | } else | 1008 | } else |
1017 | set_bit(R5_Insync, &dev->flags); | 1009 | set_bit(R5_Insync, &dev->flags); |
1018 | } | 1010 | } |
1011 | rcu_read_unlock(); | ||
1019 | PRINTK("locked=%d uptodate=%d to_read=%d" | 1012 | PRINTK("locked=%d uptodate=%d to_read=%d" |
1020 | " to_write=%d failed=%d failed_num=%d\n", | 1013 | " to_write=%d failed=%d failed_num=%d\n", |
1021 | locked, uptodate, to_read, to_write, failed, failed_num); | 1014 | locked, uptodate, to_read, to_write, failed, failed_num); |
@@ -1027,10 +1020,13 @@ static void handle_stripe(struct stripe_head *sh) | |||
1027 | int bitmap_end = 0; | 1020 | int bitmap_end = 0; |
1028 | 1021 | ||
1029 | if (test_bit(R5_ReadError, &sh->dev[i].flags)) { | 1022 | if (test_bit(R5_ReadError, &sh->dev[i].flags)) { |
1030 | mdk_rdev_t *rdev = conf->disks[i].rdev; | 1023 | mdk_rdev_t *rdev; |
1024 | rcu_read_lock(); | ||
1025 | rdev = rcu_dereference(conf->disks[i].rdev); | ||
1031 | if (rdev && test_bit(In_sync, &rdev->flags)) | 1026 | if (rdev && test_bit(In_sync, &rdev->flags)) |
1032 | /* multiple read failures in one stripe */ | 1027 | /* multiple read failures in one stripe */ |
1033 | md_error(conf->mddev, rdev); | 1028 | md_error(conf->mddev, rdev); |
1029 | rcu_read_unlock(); | ||
1034 | } | 1030 | } |
1035 | 1031 | ||
1036 | spin_lock_irq(&conf->device_lock); | 1032 | spin_lock_irq(&conf->device_lock); |
@@ -1179,9 +1175,6 @@ static void handle_stripe(struct stripe_head *sh) | |||
1179 | locked++; | 1175 | locked++; |
1180 | PRINTK("Reading block %d (sync=%d)\n", | 1176 | PRINTK("Reading block %d (sync=%d)\n", |
1181 | i, syncing); | 1177 | i, syncing); |
1182 | if (syncing) | ||
1183 | md_sync_acct(conf->disks[i].rdev->bdev, | ||
1184 | STRIPE_SECTORS); | ||
1185 | } | 1178 | } |
1186 | } | 1179 | } |
1187 | } | 1180 | } |
@@ -1288,7 +1281,7 @@ static void handle_stripe(struct stripe_head *sh) | |||
1288 | * is available | 1281 | * is available |
1289 | */ | 1282 | */ |
1290 | if (syncing && locked == 0 && | 1283 | if (syncing && locked == 0 && |
1291 | !test_bit(STRIPE_INSYNC, &sh->state) && failed <= 1) { | 1284 | !test_bit(STRIPE_INSYNC, &sh->state)) { |
1292 | set_bit(STRIPE_HANDLE, &sh->state); | 1285 | set_bit(STRIPE_HANDLE, &sh->state); |
1293 | if (failed == 0) { | 1286 | if (failed == 0) { |
1294 | char *pagea; | 1287 | char *pagea; |
@@ -1306,27 +1299,25 @@ static void handle_stripe(struct stripe_head *sh) | |||
1306 | if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery)) | 1299 | if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery)) |
1307 | /* don't try to repair!! */ | 1300 | /* don't try to repair!! */ |
1308 | set_bit(STRIPE_INSYNC, &sh->state); | 1301 | set_bit(STRIPE_INSYNC, &sh->state); |
1302 | else { | ||
1303 | compute_block(sh, sh->pd_idx); | ||
1304 | uptodate++; | ||
1305 | } | ||
1309 | } | 1306 | } |
1310 | } | 1307 | } |
1311 | if (!test_bit(STRIPE_INSYNC, &sh->state)) { | 1308 | if (!test_bit(STRIPE_INSYNC, &sh->state)) { |
1309 | /* either failed parity check, or recovery is happening */ | ||
1312 | if (failed==0) | 1310 | if (failed==0) |
1313 | failed_num = sh->pd_idx; | 1311 | failed_num = sh->pd_idx; |
1314 | /* should be able to compute the missing block and write it to spare */ | ||
1315 | if (!test_bit(R5_UPTODATE, &sh->dev[failed_num].flags)) { | ||
1316 | if (uptodate+1 != disks) | ||
1317 | BUG(); | ||
1318 | compute_block(sh, failed_num); | ||
1319 | uptodate++; | ||
1320 | } | ||
1321 | if (uptodate != disks) | ||
1322 | BUG(); | ||
1323 | dev = &sh->dev[failed_num]; | 1312 | dev = &sh->dev[failed_num]; |
1313 | BUG_ON(!test_bit(R5_UPTODATE, &dev->flags)); | ||
1314 | BUG_ON(uptodate != disks); | ||
1315 | |||
1324 | set_bit(R5_LOCKED, &dev->flags); | 1316 | set_bit(R5_LOCKED, &dev->flags); |
1325 | set_bit(R5_Wantwrite, &dev->flags); | 1317 | set_bit(R5_Wantwrite, &dev->flags); |
1326 | clear_bit(STRIPE_DEGRADED, &sh->state); | 1318 | clear_bit(STRIPE_DEGRADED, &sh->state); |
1327 | locked++; | 1319 | locked++; |
1328 | set_bit(STRIPE_INSYNC, &sh->state); | 1320 | set_bit(STRIPE_INSYNC, &sh->state); |
1329 | set_bit(R5_Syncio, &dev->flags); | ||
1330 | } | 1321 | } |
1331 | } | 1322 | } |
1332 | if (syncing && locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) { | 1323 | if (syncing && locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) { |
@@ -1392,7 +1383,7 @@ static void handle_stripe(struct stripe_head *sh) | |||
1392 | rcu_read_unlock(); | 1383 | rcu_read_unlock(); |
1393 | 1384 | ||
1394 | if (rdev) { | 1385 | if (rdev) { |
1395 | if (test_bit(R5_Syncio, &sh->dev[i].flags)) | 1386 | if (syncing) |
1396 | md_sync_acct(rdev->bdev, STRIPE_SECTORS); | 1387 | md_sync_acct(rdev->bdev, STRIPE_SECTORS); |
1397 | 1388 | ||
1398 | bi->bi_bdev = rdev->bdev; | 1389 | bi->bi_bdev = rdev->bdev; |
@@ -1409,6 +1400,9 @@ static void handle_stripe(struct stripe_head *sh) | |||
1409 | bi->bi_io_vec[0].bv_offset = 0; | 1400 | bi->bi_io_vec[0].bv_offset = 0; |
1410 | bi->bi_size = STRIPE_SIZE; | 1401 | bi->bi_size = STRIPE_SIZE; |
1411 | bi->bi_next = NULL; | 1402 | bi->bi_next = NULL; |
1403 | if (rw == WRITE && | ||
1404 | test_bit(R5_ReWrite, &sh->dev[i].flags)) | ||
1405 | atomic_add(STRIPE_SECTORS, &rdev->corrected_errors); | ||
1412 | generic_make_request(bi); | 1406 | generic_make_request(bi); |
1413 | } else { | 1407 | } else { |
1414 | if (rw == 1) | 1408 | if (rw == 1) |
@@ -1822,21 +1816,21 @@ static int run(mddev_t *mddev) | |||
1822 | struct list_head *tmp; | 1816 | struct list_head *tmp; |
1823 | 1817 | ||
1824 | if (mddev->level != 5 && mddev->level != 4) { | 1818 | if (mddev->level != 5 && mddev->level != 4) { |
1825 | printk("raid5: %s: raid level not set to 4/5 (%d)\n", mdname(mddev), mddev->level); | 1819 | printk(KERN_ERR "raid5: %s: raid level not set to 4/5 (%d)\n", |
1820 | mdname(mddev), mddev->level); | ||
1826 | return -EIO; | 1821 | return -EIO; |
1827 | } | 1822 | } |
1828 | 1823 | ||
1829 | mddev->private = kmalloc (sizeof (raid5_conf_t) | 1824 | mddev->private = kzalloc(sizeof (raid5_conf_t) |
1830 | + mddev->raid_disks * sizeof(struct disk_info), | 1825 | + mddev->raid_disks * sizeof(struct disk_info), |
1831 | GFP_KERNEL); | 1826 | GFP_KERNEL); |
1832 | if ((conf = mddev->private) == NULL) | 1827 | if ((conf = mddev->private) == NULL) |
1833 | goto abort; | 1828 | goto abort; |
1834 | memset (conf, 0, sizeof (*conf) + mddev->raid_disks * sizeof(struct disk_info) ); | 1829 | |
1835 | conf->mddev = mddev; | 1830 | conf->mddev = mddev; |
1836 | 1831 | ||
1837 | if ((conf->stripe_hashtbl = (struct stripe_head **) __get_free_pages(GFP_ATOMIC, HASH_PAGES_ORDER)) == NULL) | 1832 | if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL) |
1838 | goto abort; | 1833 | goto abort; |
1839 | memset(conf->stripe_hashtbl, 0, HASH_PAGES * PAGE_SIZE); | ||
1840 | 1834 | ||
1841 | spin_lock_init(&conf->device_lock); | 1835 | spin_lock_init(&conf->device_lock); |
1842 | init_waitqueue_head(&conf->wait_for_stripe); | 1836 | init_waitqueue_head(&conf->wait_for_stripe); |
@@ -1903,10 +1897,17 @@ static int run(mddev_t *mddev) | |||
1903 | 1897 | ||
1904 | if (mddev->degraded == 1 && | 1898 | if (mddev->degraded == 1 && |
1905 | mddev->recovery_cp != MaxSector) { | 1899 | mddev->recovery_cp != MaxSector) { |
1906 | printk(KERN_ERR | 1900 | if (mddev->ok_start_degraded) |
1907 | "raid5: cannot start dirty degraded array for %s\n", | 1901 | printk(KERN_WARNING |
1908 | mdname(mddev)); | 1902 | "raid5: starting dirty degraded array: %s" |
1909 | goto abort; | 1903 | "- data corruption possible.\n", |
1904 | mdname(mddev)); | ||
1905 | else { | ||
1906 | printk(KERN_ERR | ||
1907 | "raid5: cannot start dirty degraded array for %s\n", | ||
1908 | mdname(mddev)); | ||
1909 | goto abort; | ||
1910 | } | ||
1910 | } | 1911 | } |
1911 | 1912 | ||
1912 | { | 1913 | { |
@@ -1948,7 +1949,7 @@ static int run(mddev_t *mddev) | |||
1948 | */ | 1949 | */ |
1949 | { | 1950 | { |
1950 | int stripe = (mddev->raid_disks-1) * mddev->chunk_size | 1951 | int stripe = (mddev->raid_disks-1) * mddev->chunk_size |
1951 | / PAGE_CACHE_SIZE; | 1952 | / PAGE_SIZE; |
1952 | if (mddev->queue->backing_dev_info.ra_pages < 2 * stripe) | 1953 | if (mddev->queue->backing_dev_info.ra_pages < 2 * stripe) |
1953 | mddev->queue->backing_dev_info.ra_pages = 2 * stripe; | 1954 | mddev->queue->backing_dev_info.ra_pages = 2 * stripe; |
1954 | } | 1955 | } |
@@ -1956,9 +1957,6 @@ static int run(mddev_t *mddev) | |||
1956 | /* Ok, everything is just fine now */ | 1957 | /* Ok, everything is just fine now */ |
1957 | sysfs_create_group(&mddev->kobj, &raid5_attrs_group); | 1958 | sysfs_create_group(&mddev->kobj, &raid5_attrs_group); |
1958 | 1959 | ||
1959 | if (mddev->bitmap) | ||
1960 | mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ; | ||
1961 | |||
1962 | mddev->queue->unplug_fn = raid5_unplug_device; | 1960 | mddev->queue->unplug_fn = raid5_unplug_device; |
1963 | mddev->queue->issue_flush_fn = raid5_issue_flush; | 1961 | mddev->queue->issue_flush_fn = raid5_issue_flush; |
1964 | 1962 | ||
@@ -1967,9 +1965,7 @@ static int run(mddev_t *mddev) | |||
1967 | abort: | 1965 | abort: |
1968 | if (conf) { | 1966 | if (conf) { |
1969 | print_raid5_conf(conf); | 1967 | print_raid5_conf(conf); |
1970 | if (conf->stripe_hashtbl) | 1968 | kfree(conf->stripe_hashtbl); |
1971 | free_pages((unsigned long) conf->stripe_hashtbl, | ||
1972 | HASH_PAGES_ORDER); | ||
1973 | kfree(conf); | 1969 | kfree(conf); |
1974 | } | 1970 | } |
1975 | mddev->private = NULL; | 1971 | mddev->private = NULL; |
@@ -1986,7 +1982,7 @@ static int stop(mddev_t *mddev) | |||
1986 | md_unregister_thread(mddev->thread); | 1982 | md_unregister_thread(mddev->thread); |
1987 | mddev->thread = NULL; | 1983 | mddev->thread = NULL; |
1988 | shrink_stripes(conf); | 1984 | shrink_stripes(conf); |
1989 | free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER); | 1985 | kfree(conf->stripe_hashtbl); |
1990 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ | 1986 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ |
1991 | sysfs_remove_group(&mddev->kobj, &raid5_attrs_group); | 1987 | sysfs_remove_group(&mddev->kobj, &raid5_attrs_group); |
1992 | kfree(conf); | 1988 | kfree(conf); |
@@ -2014,12 +2010,12 @@ static void print_sh (struct stripe_head *sh) | |||
2014 | static void printall (raid5_conf_t *conf) | 2010 | static void printall (raid5_conf_t *conf) |
2015 | { | 2011 | { |
2016 | struct stripe_head *sh; | 2012 | struct stripe_head *sh; |
2013 | struct hlist_node *hn; | ||
2017 | int i; | 2014 | int i; |
2018 | 2015 | ||
2019 | spin_lock_irq(&conf->device_lock); | 2016 | spin_lock_irq(&conf->device_lock); |
2020 | for (i = 0; i < NR_HASH; i++) { | 2017 | for (i = 0; i < NR_HASH; i++) { |
2021 | sh = conf->stripe_hashtbl[i]; | 2018 | hlist_for_each_entry(sh, hn, &conf->stripe_hashtbl[i], hash) { |
2022 | for (; sh; sh = sh->hash_next) { | ||
2023 | if (sh->raid_conf != conf) | 2019 | if (sh->raid_conf != conf) |
2024 | continue; | 2020 | continue; |
2025 | print_sh(sh); | 2021 | print_sh(sh); |
@@ -2192,17 +2188,12 @@ static void raid5_quiesce(mddev_t *mddev, int state) | |||
2192 | spin_unlock_irq(&conf->device_lock); | 2188 | spin_unlock_irq(&conf->device_lock); |
2193 | break; | 2189 | break; |
2194 | } | 2190 | } |
2195 | if (mddev->thread) { | ||
2196 | if (mddev->bitmap) | ||
2197 | mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ; | ||
2198 | else | ||
2199 | mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT; | ||
2200 | md_wakeup_thread(mddev->thread); | ||
2201 | } | ||
2202 | } | 2191 | } |
2203 | static mdk_personality_t raid5_personality= | 2192 | |
2193 | static struct mdk_personality raid5_personality = | ||
2204 | { | 2194 | { |
2205 | .name = "raid5", | 2195 | .name = "raid5", |
2196 | .level = 5, | ||
2206 | .owner = THIS_MODULE, | 2197 | .owner = THIS_MODULE, |
2207 | .make_request = make_request, | 2198 | .make_request = make_request, |
2208 | .run = run, | 2199 | .run = run, |
@@ -2217,17 +2208,42 @@ static mdk_personality_t raid5_personality= | |||
2217 | .quiesce = raid5_quiesce, | 2208 | .quiesce = raid5_quiesce, |
2218 | }; | 2209 | }; |
2219 | 2210 | ||
2220 | static int __init raid5_init (void) | 2211 | static struct mdk_personality raid4_personality = |
2221 | { | 2212 | { |
2222 | return register_md_personality (RAID5, &raid5_personality); | 2213 | .name = "raid4", |
2214 | .level = 4, | ||
2215 | .owner = THIS_MODULE, | ||
2216 | .make_request = make_request, | ||
2217 | .run = run, | ||
2218 | .stop = stop, | ||
2219 | .status = status, | ||
2220 | .error_handler = error, | ||
2221 | .hot_add_disk = raid5_add_disk, | ||
2222 | .hot_remove_disk= raid5_remove_disk, | ||
2223 | .spare_active = raid5_spare_active, | ||
2224 | .sync_request = sync_request, | ||
2225 | .resize = raid5_resize, | ||
2226 | .quiesce = raid5_quiesce, | ||
2227 | }; | ||
2228 | |||
2229 | static int __init raid5_init(void) | ||
2230 | { | ||
2231 | register_md_personality(&raid5_personality); | ||
2232 | register_md_personality(&raid4_personality); | ||
2233 | return 0; | ||
2223 | } | 2234 | } |
2224 | 2235 | ||
2225 | static void raid5_exit (void) | 2236 | static void raid5_exit(void) |
2226 | { | 2237 | { |
2227 | unregister_md_personality (RAID5); | 2238 | unregister_md_personality(&raid5_personality); |
2239 | unregister_md_personality(&raid4_personality); | ||
2228 | } | 2240 | } |
2229 | 2241 | ||
2230 | module_init(raid5_init); | 2242 | module_init(raid5_init); |
2231 | module_exit(raid5_exit); | 2243 | module_exit(raid5_exit); |
2232 | MODULE_LICENSE("GPL"); | 2244 | MODULE_LICENSE("GPL"); |
2233 | MODULE_ALIAS("md-personality-4"); /* RAID5 */ | 2245 | MODULE_ALIAS("md-personality-4"); /* RAID5 */ |
2246 | MODULE_ALIAS("md-raid5"); | ||
2247 | MODULE_ALIAS("md-raid4"); | ||
2248 | MODULE_ALIAS("md-level-5"); | ||
2249 | MODULE_ALIAS("md-level-4"); | ||