diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-08 17:03:34 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-08 17:03:34 -0500 |
| commit | 894bcdfb1a40a7c5032242c380b956aab106e05d (patch) | |
| tree | cb5d34da6a7f524bb3188be539422896f2427405 /drivers/md | |
| parent | a419df8a0ff01b6694cebc8885778f854165d17d (diff) | |
| parent | 4044ba58dd15cb01797c4fd034f39ef4a75f7cc3 (diff) | |
Merge branch 'for-linus' of git://neil.brown.name/md
* 'for-linus' of git://neil.brown.name/md:
md: don't retry recovery of raid1 that fails due to error on source drive.
md: Allow md devices to be created by name.
md: make devices disappear when they are no longer needed.
md: centralise all freeing of an 'mddev' in 'md_free'
md: move allocation of ->queue from mddev_find to md_probe
md: need another print_sb for mdp_superblock_1
md: use list_for_each_entry macro directly
md: raid0: make hash_spacing and preshift sector-based.
md: raid0: Represent the size of strip zones in sectors.
md: raid0 create_strip_zones(): Add KERN_INFO/KERN_ERR to printk's.
md: raid0 create_strip_zones(): Make two local variables sector-based.
md: raid0: Represent zone->zone_offset in sectors.
md: raid0: Represent device offset in sectors.
md: raid0_make_request(): Replace local variable block by sector.
md: raid0_make_request(): Remove local variable chunk_size.
md: raid0_make_request(): Replace chunksize_bits by chunksect_bits.
md: use sysfs_notify_dirent to notify changes to md/sync_action.
md: fix bitmap-on-external-file bug.
Diffstat (limited to 'drivers/md')
| -rw-r--r-- | drivers/md/bitmap.c | 11 | ||||
| -rw-r--r-- | drivers/md/faulty.c | 3 | ||||
| -rw-r--r-- | drivers/md/linear.c | 3 | ||||
| -rw-r--r-- | drivers/md/md.c | 416 | ||||
| -rw-r--r-- | drivers/md/multipath.c | 3 | ||||
| -rw-r--r-- | drivers/md/raid0.c | 178 | ||||
| -rw-r--r-- | drivers/md/raid1.c | 11 | ||||
| -rw-r--r-- | drivers/md/raid10.c | 3 | ||||
| -rw-r--r-- | drivers/md/raid5.c | 8 |
9 files changed, 401 insertions, 235 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index ab7c8e4a61f9..719943763391 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
| @@ -215,7 +215,6 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, | |||
| 215 | /* choose a good rdev and read the page from there */ | 215 | /* choose a good rdev and read the page from there */ |
| 216 | 216 | ||
| 217 | mdk_rdev_t *rdev; | 217 | mdk_rdev_t *rdev; |
| 218 | struct list_head *tmp; | ||
| 219 | sector_t target; | 218 | sector_t target; |
| 220 | 219 | ||
| 221 | if (!page) | 220 | if (!page) |
| @@ -223,7 +222,7 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, | |||
| 223 | if (!page) | 222 | if (!page) |
| 224 | return ERR_PTR(-ENOMEM); | 223 | return ERR_PTR(-ENOMEM); |
| 225 | 224 | ||
| 226 | rdev_for_each(rdev, tmp, mddev) { | 225 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 227 | if (! test_bit(In_sync, &rdev->flags) | 226 | if (! test_bit(In_sync, &rdev->flags) |
| 228 | || test_bit(Faulty, &rdev->flags)) | 227 | || test_bit(Faulty, &rdev->flags)) |
| 229 | continue; | 228 | continue; |
| @@ -964,9 +963,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | |||
| 964 | */ | 963 | */ |
| 965 | page = bitmap->sb_page; | 964 | page = bitmap->sb_page; |
| 966 | offset = sizeof(bitmap_super_t); | 965 | offset = sizeof(bitmap_super_t); |
| 967 | read_sb_page(bitmap->mddev, bitmap->offset, | 966 | if (!file) |
| 968 | page, | 967 | read_sb_page(bitmap->mddev, |
| 969 | index, count); | 968 | bitmap->offset, |
| 969 | page, | ||
| 970 | index, count); | ||
| 970 | } else if (file) { | 971 | } else if (file) { |
| 971 | page = read_page(file, index, bitmap, count); | 972 | page = read_page(file, index, bitmap, count); |
| 972 | offset = 0; | 973 | offset = 0; |
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index f26c1f9a475b..86d9adf90e79 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c | |||
| @@ -283,7 +283,6 @@ static int reconfig(mddev_t *mddev, int layout, int chunk_size) | |||
| 283 | static int run(mddev_t *mddev) | 283 | static int run(mddev_t *mddev) |
| 284 | { | 284 | { |
| 285 | mdk_rdev_t *rdev; | 285 | mdk_rdev_t *rdev; |
| 286 | struct list_head *tmp; | ||
| 287 | int i; | 286 | int i; |
| 288 | 287 | ||
| 289 | conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL); | 288 | conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL); |
| @@ -296,7 +295,7 @@ static int run(mddev_t *mddev) | |||
| 296 | } | 295 | } |
| 297 | conf->nfaults = 0; | 296 | conf->nfaults = 0; |
| 298 | 297 | ||
| 299 | rdev_for_each(rdev, tmp, mddev) | 298 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 300 | conf->rdev = rdev; | 299 | conf->rdev = rdev; |
| 301 | 300 | ||
| 302 | mddev->array_sectors = mddev->size * 2; | 301 | mddev->array_sectors = mddev->size * 2; |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 3b90c5c924ec..1e3aea9eecf1 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
| @@ -105,7 +105,6 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
| 105 | int i, nb_zone, cnt; | 105 | int i, nb_zone, cnt; |
| 106 | sector_t min_sectors; | 106 | sector_t min_sectors; |
| 107 | sector_t curr_sector; | 107 | sector_t curr_sector; |
| 108 | struct list_head *tmp; | ||
| 109 | 108 | ||
| 110 | conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t), | 109 | conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t), |
| 111 | GFP_KERNEL); | 110 | GFP_KERNEL); |
| @@ -115,7 +114,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
| 115 | cnt = 0; | 114 | cnt = 0; |
| 116 | conf->array_sectors = 0; | 115 | conf->array_sectors = 0; |
| 117 | 116 | ||
| 118 | rdev_for_each(rdev, tmp, mddev) { | 117 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 119 | int j = rdev->raid_disk; | 118 | int j = rdev->raid_disk; |
| 120 | dev_info_t *disk = conf->disks + j; | 119 | dev_info_t *disk = conf->disks + j; |
| 121 | 120 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index 1b1d32694f6f..41e2509bf896 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -214,20 +214,33 @@ static inline mddev_t *mddev_get(mddev_t *mddev) | |||
| 214 | return mddev; | 214 | return mddev; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | static void mddev_delayed_delete(struct work_struct *ws) | ||
| 218 | { | ||
| 219 | mddev_t *mddev = container_of(ws, mddev_t, del_work); | ||
| 220 | kobject_del(&mddev->kobj); | ||
| 221 | kobject_put(&mddev->kobj); | ||
| 222 | } | ||
| 223 | |||
| 217 | static void mddev_put(mddev_t *mddev) | 224 | static void mddev_put(mddev_t *mddev) |
| 218 | { | 225 | { |
| 219 | if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock)) | 226 | if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock)) |
| 220 | return; | 227 | return; |
| 221 | if (!mddev->raid_disks && list_empty(&mddev->disks)) { | 228 | if (!mddev->raid_disks && list_empty(&mddev->disks) && |
| 229 | !mddev->hold_active) { | ||
| 222 | list_del(&mddev->all_mddevs); | 230 | list_del(&mddev->all_mddevs); |
| 223 | spin_unlock(&all_mddevs_lock); | 231 | if (mddev->gendisk) { |
| 224 | blk_cleanup_queue(mddev->queue); | 232 | /* we did a probe so need to clean up. |
| 225 | if (mddev->sysfs_state) | 233 | * Call schedule_work inside the spinlock |
| 226 | sysfs_put(mddev->sysfs_state); | 234 | * so that flush_scheduled_work() after |
| 227 | mddev->sysfs_state = NULL; | 235 | * mddev_find will succeed in waiting for the |
| 228 | kobject_put(&mddev->kobj); | 236 | * work to be done. |
| 229 | } else | 237 | */ |
| 230 | spin_unlock(&all_mddevs_lock); | 238 | INIT_WORK(&mddev->del_work, mddev_delayed_delete); |
| 239 | schedule_work(&mddev->del_work); | ||
| 240 | } else | ||
| 241 | kfree(mddev); | ||
| 242 | } | ||
| 243 | spin_unlock(&all_mddevs_lock); | ||
| 231 | } | 244 | } |
| 232 | 245 | ||
| 233 | static mddev_t * mddev_find(dev_t unit) | 246 | static mddev_t * mddev_find(dev_t unit) |
| @@ -236,15 +249,50 @@ static mddev_t * mddev_find(dev_t unit) | |||
| 236 | 249 | ||
| 237 | retry: | 250 | retry: |
| 238 | spin_lock(&all_mddevs_lock); | 251 | spin_lock(&all_mddevs_lock); |
| 239 | list_for_each_entry(mddev, &all_mddevs, all_mddevs) | 252 | |
| 240 | if (mddev->unit == unit) { | 253 | if (unit) { |
| 241 | mddev_get(mddev); | 254 | list_for_each_entry(mddev, &all_mddevs, all_mddevs) |
| 255 | if (mddev->unit == unit) { | ||
| 256 | mddev_get(mddev); | ||
| 257 | spin_unlock(&all_mddevs_lock); | ||
| 258 | kfree(new); | ||
| 259 | return mddev; | ||
| 260 | } | ||
| 261 | |||
| 262 | if (new) { | ||
| 263 | list_add(&new->all_mddevs, &all_mddevs); | ||
| 242 | spin_unlock(&all_mddevs_lock); | 264 | spin_unlock(&all_mddevs_lock); |
| 243 | kfree(new); | 265 | new->hold_active = UNTIL_IOCTL; |
| 244 | return mddev; | 266 | return new; |
| 245 | } | 267 | } |
| 246 | 268 | } else if (new) { | |
| 247 | if (new) { | 269 | /* find an unused unit number */ |
| 270 | static int next_minor = 512; | ||
| 271 | int start = next_minor; | ||
| 272 | int is_free = 0; | ||
| 273 | int dev = 0; | ||
| 274 | while (!is_free) { | ||
| 275 | dev = MKDEV(MD_MAJOR, next_minor); | ||
| 276 | next_minor++; | ||
| 277 | if (next_minor > MINORMASK) | ||
| 278 | next_minor = 0; | ||
| 279 | if (next_minor == start) { | ||
| 280 | /* Oh dear, all in use. */ | ||
| 281 | spin_unlock(&all_mddevs_lock); | ||
| 282 | kfree(new); | ||
| 283 | return NULL; | ||
| 284 | } | ||
| 285 | |||
| 286 | is_free = 1; | ||
| 287 | list_for_each_entry(mddev, &all_mddevs, all_mddevs) | ||
| 288 | if (mddev->unit == dev) { | ||
| 289 | is_free = 0; | ||
| 290 | break; | ||
| 291 | } | ||
| 292 | } | ||
| 293 | new->unit = dev; | ||
| 294 | new->md_minor = MINOR(dev); | ||
| 295 | new->hold_active = UNTIL_STOP; | ||
| 248 | list_add(&new->all_mddevs, &all_mddevs); | 296 | list_add(&new->all_mddevs, &all_mddevs); |
| 249 | spin_unlock(&all_mddevs_lock); | 297 | spin_unlock(&all_mddevs_lock); |
| 250 | return new; | 298 | return new; |
| @@ -275,16 +323,6 @@ static mddev_t * mddev_find(dev_t unit) | |||
| 275 | new->resync_max = MaxSector; | 323 | new->resync_max = MaxSector; |
| 276 | new->level = LEVEL_NONE; | 324 | new->level = LEVEL_NONE; |
| 277 | 325 | ||
| 278 | new->queue = blk_alloc_queue(GFP_KERNEL); | ||
| 279 | if (!new->queue) { | ||
| 280 | kfree(new); | ||
| 281 | return NULL; | ||
| 282 | } | ||
| 283 | /* Can be unlocked because the queue is new: no concurrency */ | ||
| 284 | queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, new->queue); | ||
| 285 | |||
| 286 | blk_queue_make_request(new->queue, md_fail_request); | ||
| 287 | |||
| 288 | goto retry; | 326 | goto retry; |
| 289 | } | 327 | } |
| 290 | 328 | ||
| @@ -307,25 +345,23 @@ static inline void mddev_unlock(mddev_t * mddev) | |||
| 307 | 345 | ||
| 308 | static mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr) | 346 | static mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr) |
| 309 | { | 347 | { |
| 310 | mdk_rdev_t * rdev; | 348 | mdk_rdev_t *rdev; |
| 311 | struct list_head *tmp; | ||
| 312 | 349 | ||
| 313 | rdev_for_each(rdev, tmp, mddev) { | 350 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 314 | if (rdev->desc_nr == nr) | 351 | if (rdev->desc_nr == nr) |
| 315 | return rdev; | 352 | return rdev; |
| 316 | } | 353 | |
| 317 | return NULL; | 354 | return NULL; |
| 318 | } | 355 | } |
| 319 | 356 | ||
| 320 | static mdk_rdev_t * find_rdev(mddev_t * mddev, dev_t dev) | 357 | static mdk_rdev_t * find_rdev(mddev_t * mddev, dev_t dev) |
| 321 | { | 358 | { |
| 322 | struct list_head *tmp; | ||
| 323 | mdk_rdev_t *rdev; | 359 | mdk_rdev_t *rdev; |
| 324 | 360 | ||
| 325 | rdev_for_each(rdev, tmp, mddev) { | 361 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 326 | if (rdev->bdev->bd_dev == dev) | 362 | if (rdev->bdev->bd_dev == dev) |
| 327 | return rdev; | 363 | return rdev; |
| 328 | } | 364 | |
| 329 | return NULL; | 365 | return NULL; |
| 330 | } | 366 | } |
| 331 | 367 | ||
| @@ -861,7 +897,6 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 861 | static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) | 897 | static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) |
| 862 | { | 898 | { |
| 863 | mdp_super_t *sb; | 899 | mdp_super_t *sb; |
| 864 | struct list_head *tmp; | ||
| 865 | mdk_rdev_t *rdev2; | 900 | mdk_rdev_t *rdev2; |
| 866 | int next_spare = mddev->raid_disks; | 901 | int next_spare = mddev->raid_disks; |
| 867 | 902 | ||
| @@ -933,7 +968,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 933 | sb->state |= (1<<MD_SB_BITMAP_PRESENT); | 968 | sb->state |= (1<<MD_SB_BITMAP_PRESENT); |
| 934 | 969 | ||
| 935 | sb->disks[0].state = (1<<MD_DISK_REMOVED); | 970 | sb->disks[0].state = (1<<MD_DISK_REMOVED); |
| 936 | rdev_for_each(rdev2, tmp, mddev) { | 971 | list_for_each_entry(rdev2, &mddev->disks, same_set) { |
| 937 | mdp_disk_t *d; | 972 | mdp_disk_t *d; |
| 938 | int desc_nr; | 973 | int desc_nr; |
| 939 | if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags) | 974 | if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags) |
| @@ -1259,7 +1294,6 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1259 | static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | 1294 | static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) |
| 1260 | { | 1295 | { |
| 1261 | struct mdp_superblock_1 *sb; | 1296 | struct mdp_superblock_1 *sb; |
| 1262 | struct list_head *tmp; | ||
| 1263 | mdk_rdev_t *rdev2; | 1297 | mdk_rdev_t *rdev2; |
| 1264 | int max_dev, i; | 1298 | int max_dev, i; |
| 1265 | /* make rdev->sb match mddev and rdev data. */ | 1299 | /* make rdev->sb match mddev and rdev data. */ |
| @@ -1307,7 +1341,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1307 | } | 1341 | } |
| 1308 | 1342 | ||
| 1309 | max_dev = 0; | 1343 | max_dev = 0; |
| 1310 | rdev_for_each(rdev2, tmp, mddev) | 1344 | list_for_each_entry(rdev2, &mddev->disks, same_set) |
| 1311 | if (rdev2->desc_nr+1 > max_dev) | 1345 | if (rdev2->desc_nr+1 > max_dev) |
| 1312 | max_dev = rdev2->desc_nr+1; | 1346 | max_dev = rdev2->desc_nr+1; |
| 1313 | 1347 | ||
| @@ -1316,7 +1350,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1316 | for (i=0; i<max_dev;i++) | 1350 | for (i=0; i<max_dev;i++) |
| 1317 | sb->dev_roles[i] = cpu_to_le16(0xfffe); | 1351 | sb->dev_roles[i] = cpu_to_le16(0xfffe); |
| 1318 | 1352 | ||
| 1319 | rdev_for_each(rdev2, tmp, mddev) { | 1353 | list_for_each_entry(rdev2, &mddev->disks, same_set) { |
| 1320 | i = rdev2->desc_nr; | 1354 | i = rdev2->desc_nr; |
| 1321 | if (test_bit(Faulty, &rdev2->flags)) | 1355 | if (test_bit(Faulty, &rdev2->flags)) |
| 1322 | sb->dev_roles[i] = cpu_to_le16(0xfffe); | 1356 | sb->dev_roles[i] = cpu_to_le16(0xfffe); |
| @@ -1466,6 +1500,9 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
| 1466 | 1500 | ||
| 1467 | list_add_rcu(&rdev->same_set, &mddev->disks); | 1501 | list_add_rcu(&rdev->same_set, &mddev->disks); |
| 1468 | bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); | 1502 | bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); |
| 1503 | |||
| 1504 | /* May as well allow recovery to be retried once */ | ||
| 1505 | mddev->recovery_disabled = 0; | ||
| 1469 | return 0; | 1506 | return 0; |
| 1470 | 1507 | ||
| 1471 | fail: | 1508 | fail: |
| @@ -1571,8 +1608,7 @@ static void kick_rdev_from_array(mdk_rdev_t * rdev) | |||
| 1571 | 1608 | ||
| 1572 | static void export_array(mddev_t *mddev) | 1609 | static void export_array(mddev_t *mddev) |
| 1573 | { | 1610 | { |
| 1574 | struct list_head *tmp; | 1611 | mdk_rdev_t *rdev, *tmp; |
| 1575 | mdk_rdev_t *rdev; | ||
| 1576 | 1612 | ||
| 1577 | rdev_for_each(rdev, tmp, mddev) { | 1613 | rdev_for_each(rdev, tmp, mddev) { |
| 1578 | if (!rdev->mddev) { | 1614 | if (!rdev->mddev) { |
| @@ -1593,7 +1629,7 @@ static void print_desc(mdp_disk_t *desc) | |||
| 1593 | desc->major,desc->minor,desc->raid_disk,desc->state); | 1629 | desc->major,desc->minor,desc->raid_disk,desc->state); |
| 1594 | } | 1630 | } |
| 1595 | 1631 | ||
| 1596 | static void print_sb(mdp_super_t *sb) | 1632 | static void print_sb_90(mdp_super_t *sb) |
| 1597 | { | 1633 | { |
| 1598 | int i; | 1634 | int i; |
| 1599 | 1635 | ||
| @@ -1624,10 +1660,57 @@ static void print_sb(mdp_super_t *sb) | |||
| 1624 | } | 1660 | } |
| 1625 | printk(KERN_INFO "md: THIS: "); | 1661 | printk(KERN_INFO "md: THIS: "); |
| 1626 | print_desc(&sb->this_disk); | 1662 | print_desc(&sb->this_disk); |
| 1627 | |||
| 1628 | } | 1663 | } |
| 1629 | 1664 | ||
| 1630 | static void print_rdev(mdk_rdev_t *rdev) | 1665 | static void print_sb_1(struct mdp_superblock_1 *sb) |
| 1666 | { | ||
| 1667 | __u8 *uuid; | ||
| 1668 | |||
| 1669 | uuid = sb->set_uuid; | ||
| 1670 | printk(KERN_INFO "md: SB: (V:%u) (F:0x%08x) Array-ID:<%02x%02x%02x%02x" | ||
| 1671 | ":%02x%02x:%02x%02x:%02x%02x:%02x%02x%02x%02x%02x%02x>\n" | ||
| 1672 | KERN_INFO "md: Name: \"%s\" CT:%llu\n", | ||
| 1673 | le32_to_cpu(sb->major_version), | ||
| 1674 | le32_to_cpu(sb->feature_map), | ||
| 1675 | uuid[0], uuid[1], uuid[2], uuid[3], | ||
| 1676 | uuid[4], uuid[5], uuid[6], uuid[7], | ||
| 1677 | uuid[8], uuid[9], uuid[10], uuid[11], | ||
| 1678 | uuid[12], uuid[13], uuid[14], uuid[15], | ||
| 1679 | sb->set_name, | ||
| 1680 | (unsigned long long)le64_to_cpu(sb->ctime) | ||
| 1681 | & MD_SUPERBLOCK_1_TIME_SEC_MASK); | ||
| 1682 | |||
| 1683 | uuid = sb->device_uuid; | ||
| 1684 | printk(KERN_INFO "md: L%u SZ%llu RD:%u LO:%u CS:%u DO:%llu DS:%llu SO:%llu" | ||
| 1685 | " RO:%llu\n" | ||
| 1686 | KERN_INFO "md: Dev:%08x UUID: %02x%02x%02x%02x:%02x%02x:%02x%02x:%02x%02x" | ||
| 1687 | ":%02x%02x%02x%02x%02x%02x\n" | ||
| 1688 | KERN_INFO "md: (F:0x%08x) UT:%llu Events:%llu ResyncOffset:%llu CSUM:0x%08x\n" | ||
| 1689 | KERN_INFO "md: (MaxDev:%u) \n", | ||
| 1690 | le32_to_cpu(sb->level), | ||
| 1691 | (unsigned long long)le64_to_cpu(sb->size), | ||
| 1692 | le32_to_cpu(sb->raid_disks), | ||
| 1693 | le32_to_cpu(sb->layout), | ||
| 1694 | le32_to_cpu(sb->chunksize), | ||
| 1695 | (unsigned long long)le64_to_cpu(sb->data_offset), | ||
| 1696 | (unsigned long long)le64_to_cpu(sb->data_size), | ||
| 1697 | (unsigned long long)le64_to_cpu(sb->super_offset), | ||
| 1698 | (unsigned long long)le64_to_cpu(sb->recovery_offset), | ||
| 1699 | le32_to_cpu(sb->dev_number), | ||
| 1700 | uuid[0], uuid[1], uuid[2], uuid[3], | ||
| 1701 | uuid[4], uuid[5], uuid[6], uuid[7], | ||
| 1702 | uuid[8], uuid[9], uuid[10], uuid[11], | ||
| 1703 | uuid[12], uuid[13], uuid[14], uuid[15], | ||
| 1704 | sb->devflags, | ||
| 1705 | (unsigned long long)le64_to_cpu(sb->utime) & MD_SUPERBLOCK_1_TIME_SEC_MASK, | ||
| 1706 | (unsigned long long)le64_to_cpu(sb->events), | ||
| 1707 | (unsigned long long)le64_to_cpu(sb->resync_offset), | ||
| 1708 | le32_to_cpu(sb->sb_csum), | ||
| 1709 | le32_to_cpu(sb->max_dev) | ||
| 1710 | ); | ||
| 1711 | } | ||
| 1712 | |||
| 1713 | static void print_rdev(mdk_rdev_t *rdev, int major_version) | ||
| 1631 | { | 1714 | { |
| 1632 | char b[BDEVNAME_SIZE]; | 1715 | char b[BDEVNAME_SIZE]; |
| 1633 | printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n", | 1716 | printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n", |
| @@ -1635,15 +1718,22 @@ static void print_rdev(mdk_rdev_t *rdev) | |||
| 1635 | test_bit(Faulty, &rdev->flags), test_bit(In_sync, &rdev->flags), | 1718 | test_bit(Faulty, &rdev->flags), test_bit(In_sync, &rdev->flags), |
| 1636 | rdev->desc_nr); | 1719 | rdev->desc_nr); |
| 1637 | if (rdev->sb_loaded) { | 1720 | if (rdev->sb_loaded) { |
| 1638 | printk(KERN_INFO "md: rdev superblock:\n"); | 1721 | printk(KERN_INFO "md: rdev superblock (MJ:%d):\n", major_version); |
| 1639 | print_sb((mdp_super_t*)page_address(rdev->sb_page)); | 1722 | switch (major_version) { |
| 1723 | case 0: | ||
| 1724 | print_sb_90((mdp_super_t*)page_address(rdev->sb_page)); | ||
| 1725 | break; | ||
| 1726 | case 1: | ||
| 1727 | print_sb_1((struct mdp_superblock_1 *)page_address(rdev->sb_page)); | ||
| 1728 | break; | ||
| 1729 | } | ||
| 1640 | } else | 1730 | } else |
| 1641 | printk(KERN_INFO "md: no rdev superblock!\n"); | 1731 | printk(KERN_INFO "md: no rdev superblock!\n"); |
| 1642 | } | 1732 | } |
| 1643 | 1733 | ||
| 1644 | static void md_print_devices(void) | 1734 | static void md_print_devices(void) |
| 1645 | { | 1735 | { |
| 1646 | struct list_head *tmp, *tmp2; | 1736 | struct list_head *tmp; |
| 1647 | mdk_rdev_t *rdev; | 1737 | mdk_rdev_t *rdev; |
| 1648 | mddev_t *mddev; | 1738 | mddev_t *mddev; |
| 1649 | char b[BDEVNAME_SIZE]; | 1739 | char b[BDEVNAME_SIZE]; |
| @@ -1658,12 +1748,12 @@ static void md_print_devices(void) | |||
| 1658 | bitmap_print_sb(mddev->bitmap); | 1748 | bitmap_print_sb(mddev->bitmap); |
| 1659 | else | 1749 | else |
| 1660 | printk("%s: ", mdname(mddev)); | 1750 | printk("%s: ", mdname(mddev)); |
| 1661 | rdev_for_each(rdev, tmp2, mddev) | 1751 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 1662 | printk("<%s>", bdevname(rdev->bdev,b)); | 1752 | printk("<%s>", bdevname(rdev->bdev,b)); |
| 1663 | printk("\n"); | 1753 | printk("\n"); |
| 1664 | 1754 | ||
| 1665 | rdev_for_each(rdev, tmp2, mddev) | 1755 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 1666 | print_rdev(rdev); | 1756 | print_rdev(rdev, mddev->major_version); |
| 1667 | } | 1757 | } |
| 1668 | printk("md: **********************************\n"); | 1758 | printk("md: **********************************\n"); |
| 1669 | printk("\n"); | 1759 | printk("\n"); |
| @@ -1679,9 +1769,8 @@ static void sync_sbs(mddev_t * mddev, int nospares) | |||
| 1679 | * with the rest of the array) | 1769 | * with the rest of the array) |
| 1680 | */ | 1770 | */ |
| 1681 | mdk_rdev_t *rdev; | 1771 | mdk_rdev_t *rdev; |
| 1682 | struct list_head *tmp; | ||
| 1683 | 1772 | ||
| 1684 | rdev_for_each(rdev, tmp, mddev) { | 1773 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 1685 | if (rdev->sb_events == mddev->events || | 1774 | if (rdev->sb_events == mddev->events || |
| 1686 | (nospares && | 1775 | (nospares && |
| 1687 | rdev->raid_disk < 0 && | 1776 | rdev->raid_disk < 0 && |
| @@ -1699,7 +1788,6 @@ static void sync_sbs(mddev_t * mddev, int nospares) | |||
| 1699 | 1788 | ||
| 1700 | static void md_update_sb(mddev_t * mddev, int force_change) | 1789 | static void md_update_sb(mddev_t * mddev, int force_change) |
| 1701 | { | 1790 | { |
| 1702 | struct list_head *tmp; | ||
| 1703 | mdk_rdev_t *rdev; | 1791 | mdk_rdev_t *rdev; |
| 1704 | int sync_req; | 1792 | int sync_req; |
| 1705 | int nospares = 0; | 1793 | int nospares = 0; |
| @@ -1790,7 +1878,7 @@ repeat: | |||
| 1790 | mdname(mddev),mddev->in_sync); | 1878 | mdname(mddev),mddev->in_sync); |
| 1791 | 1879 | ||
| 1792 | bitmap_update_sb(mddev->bitmap); | 1880 | bitmap_update_sb(mddev->bitmap); |
| 1793 | rdev_for_each(rdev, tmp, mddev) { | 1881 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 1794 | char b[BDEVNAME_SIZE]; | 1882 | char b[BDEVNAME_SIZE]; |
| 1795 | dprintk(KERN_INFO "md: "); | 1883 | dprintk(KERN_INFO "md: "); |
| 1796 | if (rdev->sb_loaded != 1) | 1884 | if (rdev->sb_loaded != 1) |
| @@ -1999,7 +2087,6 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 1999 | md_wakeup_thread(rdev->mddev->thread); | 2087 | md_wakeup_thread(rdev->mddev->thread); |
| 2000 | } else if (rdev->mddev->pers) { | 2088 | } else if (rdev->mddev->pers) { |
| 2001 | mdk_rdev_t *rdev2; | 2089 | mdk_rdev_t *rdev2; |
| 2002 | struct list_head *tmp; | ||
| 2003 | /* Activating a spare .. or possibly reactivating | 2090 | /* Activating a spare .. or possibly reactivating |
| 2004 | * if we every get bitmaps working here. | 2091 | * if we every get bitmaps working here. |
| 2005 | */ | 2092 | */ |
| @@ -2010,7 +2097,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2010 | if (rdev->mddev->pers->hot_add_disk == NULL) | 2097 | if (rdev->mddev->pers->hot_add_disk == NULL) |
| 2011 | return -EINVAL; | 2098 | return -EINVAL; |
| 2012 | 2099 | ||
| 2013 | rdev_for_each(rdev2, tmp, rdev->mddev) | 2100 | list_for_each_entry(rdev2, &rdev->mddev->disks, same_set) |
| 2014 | if (rdev2->raid_disk == slot) | 2101 | if (rdev2->raid_disk == slot) |
| 2015 | return -EEXIST; | 2102 | return -EEXIST; |
| 2016 | 2103 | ||
| @@ -2125,14 +2212,14 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2125 | */ | 2212 | */ |
| 2126 | mddev_t *mddev; | 2213 | mddev_t *mddev; |
| 2127 | int overlap = 0; | 2214 | int overlap = 0; |
| 2128 | struct list_head *tmp, *tmp2; | 2215 | struct list_head *tmp; |
| 2129 | 2216 | ||
| 2130 | mddev_unlock(my_mddev); | 2217 | mddev_unlock(my_mddev); |
| 2131 | for_each_mddev(mddev, tmp) { | 2218 | for_each_mddev(mddev, tmp) { |
| 2132 | mdk_rdev_t *rdev2; | 2219 | mdk_rdev_t *rdev2; |
| 2133 | 2220 | ||
| 2134 | mddev_lock(mddev); | 2221 | mddev_lock(mddev); |
| 2135 | rdev_for_each(rdev2, tmp2, mddev) | 2222 | list_for_each_entry(rdev2, &mddev->disks, same_set) |
| 2136 | if (test_bit(AllReserved, &rdev2->flags) || | 2223 | if (test_bit(AllReserved, &rdev2->flags) || |
| 2137 | (rdev->bdev == rdev2->bdev && | 2224 | (rdev->bdev == rdev2->bdev && |
| 2138 | rdev != rdev2 && | 2225 | rdev != rdev2 && |
| @@ -2328,8 +2415,7 @@ abort_free: | |||
| 2328 | static void analyze_sbs(mddev_t * mddev) | 2415 | static void analyze_sbs(mddev_t * mddev) |
| 2329 | { | 2416 | { |
| 2330 | int i; | 2417 | int i; |
| 2331 | struct list_head *tmp; | 2418 | mdk_rdev_t *rdev, *freshest, *tmp; |
| 2332 | mdk_rdev_t *rdev, *freshest; | ||
| 2333 | char b[BDEVNAME_SIZE]; | 2419 | char b[BDEVNAME_SIZE]; |
| 2334 | 2420 | ||
| 2335 | freshest = NULL; | 2421 | freshest = NULL; |
| @@ -3046,7 +3132,7 @@ action_store(mddev_t *mddev, const char *page, size_t len) | |||
| 3046 | } | 3132 | } |
| 3047 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 3133 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
| 3048 | md_wakeup_thread(mddev->thread); | 3134 | md_wakeup_thread(mddev->thread); |
| 3049 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | 3135 | sysfs_notify_dirent(mddev->sysfs_action); |
| 3050 | return len; | 3136 | return len; |
| 3051 | } | 3137 | } |
| 3052 | 3138 | ||
| @@ -3404,6 +3490,8 @@ md_attr_store(struct kobject *kobj, struct attribute *attr, | |||
| 3404 | if (!capable(CAP_SYS_ADMIN)) | 3490 | if (!capable(CAP_SYS_ADMIN)) |
| 3405 | return -EACCES; | 3491 | return -EACCES; |
| 3406 | rv = mddev_lock(mddev); | 3492 | rv = mddev_lock(mddev); |
| 3493 | if (mddev->hold_active == UNTIL_IOCTL) | ||
| 3494 | mddev->hold_active = 0; | ||
| 3407 | if (!rv) { | 3495 | if (!rv) { |
| 3408 | rv = entry->store(mddev, page, length); | 3496 | rv = entry->store(mddev, page, length); |
| 3409 | mddev_unlock(mddev); | 3497 | mddev_unlock(mddev); |
| @@ -3414,6 +3502,17 @@ md_attr_store(struct kobject *kobj, struct attribute *attr, | |||
| 3414 | static void md_free(struct kobject *ko) | 3502 | static void md_free(struct kobject *ko) |
| 3415 | { | 3503 | { |
| 3416 | mddev_t *mddev = container_of(ko, mddev_t, kobj); | 3504 | mddev_t *mddev = container_of(ko, mddev_t, kobj); |
| 3505 | |||
| 3506 | if (mddev->sysfs_state) | ||
| 3507 | sysfs_put(mddev->sysfs_state); | ||
| 3508 | |||
| 3509 | if (mddev->gendisk) { | ||
| 3510 | del_gendisk(mddev->gendisk); | ||
| 3511 | put_disk(mddev->gendisk); | ||
| 3512 | } | ||
| 3513 | if (mddev->queue) | ||
| 3514 | blk_cleanup_queue(mddev->queue); | ||
| 3515 | |||
| 3417 | kfree(mddev); | 3516 | kfree(mddev); |
| 3418 | } | 3517 | } |
| 3419 | 3518 | ||
| @@ -3429,34 +3528,74 @@ static struct kobj_type md_ktype = { | |||
| 3429 | 3528 | ||
| 3430 | int mdp_major = 0; | 3529 | int mdp_major = 0; |
| 3431 | 3530 | ||
| 3432 | static struct kobject *md_probe(dev_t dev, int *part, void *data) | 3531 | static int md_alloc(dev_t dev, char *name) |
| 3433 | { | 3532 | { |
| 3434 | static DEFINE_MUTEX(disks_mutex); | 3533 | static DEFINE_MUTEX(disks_mutex); |
| 3435 | mddev_t *mddev = mddev_find(dev); | 3534 | mddev_t *mddev = mddev_find(dev); |
| 3436 | struct gendisk *disk; | 3535 | struct gendisk *disk; |
| 3437 | int partitioned = (MAJOR(dev) != MD_MAJOR); | 3536 | int partitioned; |
| 3438 | int shift = partitioned ? MdpMinorShift : 0; | 3537 | int shift; |
| 3439 | int unit = MINOR(dev) >> shift; | 3538 | int unit; |
| 3440 | int error; | 3539 | int error; |
| 3441 | 3540 | ||
| 3442 | if (!mddev) | 3541 | if (!mddev) |
| 3443 | return NULL; | 3542 | return -ENODEV; |
| 3543 | |||
| 3544 | partitioned = (MAJOR(mddev->unit) != MD_MAJOR); | ||
| 3545 | shift = partitioned ? MdpMinorShift : 0; | ||
| 3546 | unit = MINOR(mddev->unit) >> shift; | ||
| 3547 | |||
| 3548 | /* wait for any previous instance if this device | ||
| 3549 | * to be completed removed (mddev_delayed_delete). | ||
| 3550 | */ | ||
| 3551 | flush_scheduled_work(); | ||
| 3444 | 3552 | ||
| 3445 | mutex_lock(&disks_mutex); | 3553 | mutex_lock(&disks_mutex); |
| 3446 | if (mddev->gendisk) { | 3554 | if (mddev->gendisk) { |
| 3447 | mutex_unlock(&disks_mutex); | 3555 | mutex_unlock(&disks_mutex); |
| 3448 | mddev_put(mddev); | 3556 | mddev_put(mddev); |
| 3449 | return NULL; | 3557 | return -EEXIST; |
| 3558 | } | ||
| 3559 | |||
| 3560 | if (name) { | ||
| 3561 | /* Need to ensure that 'name' is not a duplicate. | ||
| 3562 | */ | ||
| 3563 | mddev_t *mddev2; | ||
| 3564 | spin_lock(&all_mddevs_lock); | ||
| 3565 | |||
| 3566 | list_for_each_entry(mddev2, &all_mddevs, all_mddevs) | ||
| 3567 | if (mddev2->gendisk && | ||
| 3568 | strcmp(mddev2->gendisk->disk_name, name) == 0) { | ||
| 3569 | spin_unlock(&all_mddevs_lock); | ||
| 3570 | return -EEXIST; | ||
| 3571 | } | ||
| 3572 | spin_unlock(&all_mddevs_lock); | ||
| 3573 | } | ||
| 3574 | |||
| 3575 | mddev->queue = blk_alloc_queue(GFP_KERNEL); | ||
| 3576 | if (!mddev->queue) { | ||
| 3577 | mutex_unlock(&disks_mutex); | ||
| 3578 | mddev_put(mddev); | ||
| 3579 | return -ENOMEM; | ||
| 3450 | } | 3580 | } |
| 3581 | /* Can be unlocked because the queue is new: no concurrency */ | ||
| 3582 | queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue); | ||
| 3583 | |||
| 3584 | blk_queue_make_request(mddev->queue, md_fail_request); | ||
| 3585 | |||
| 3451 | disk = alloc_disk(1 << shift); | 3586 | disk = alloc_disk(1 << shift); |
| 3452 | if (!disk) { | 3587 | if (!disk) { |
| 3453 | mutex_unlock(&disks_mutex); | 3588 | mutex_unlock(&disks_mutex); |
| 3589 | blk_cleanup_queue(mddev->queue); | ||
| 3590 | mddev->queue = NULL; | ||
| 3454 | mddev_put(mddev); | 3591 | mddev_put(mddev); |
| 3455 | return NULL; | 3592 | return -ENOMEM; |
| 3456 | } | 3593 | } |
| 3457 | disk->major = MAJOR(dev); | 3594 | disk->major = MAJOR(mddev->unit); |
| 3458 | disk->first_minor = unit << shift; | 3595 | disk->first_minor = unit << shift; |
| 3459 | if (partitioned) | 3596 | if (name) |
| 3597 | strcpy(disk->disk_name, name); | ||
| 3598 | else if (partitioned) | ||
| 3460 | sprintf(disk->disk_name, "md_d%d", unit); | 3599 | sprintf(disk->disk_name, "md_d%d", unit); |
| 3461 | else | 3600 | else |
| 3462 | sprintf(disk->disk_name, "md%d", unit); | 3601 | sprintf(disk->disk_name, "md%d", unit); |
| @@ -3464,7 +3603,7 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) | |||
| 3464 | disk->private_data = mddev; | 3603 | disk->private_data = mddev; |
| 3465 | disk->queue = mddev->queue; | 3604 | disk->queue = mddev->queue; |
| 3466 | /* Allow extended partitions. This makes the | 3605 | /* Allow extended partitions. This makes the |
| 3467 | * 'mdp' device redundant, but we can really | 3606 | * 'mdp' device redundant, but we can't really |
| 3468 | * remove it now. | 3607 | * remove it now. |
| 3469 | */ | 3608 | */ |
| 3470 | disk->flags |= GENHD_FL_EXT_DEVT; | 3609 | disk->flags |= GENHD_FL_EXT_DEVT; |
| @@ -3480,9 +3619,35 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) | |||
| 3480 | kobject_uevent(&mddev->kobj, KOBJ_ADD); | 3619 | kobject_uevent(&mddev->kobj, KOBJ_ADD); |
| 3481 | mddev->sysfs_state = sysfs_get_dirent(mddev->kobj.sd, "array_state"); | 3620 | mddev->sysfs_state = sysfs_get_dirent(mddev->kobj.sd, "array_state"); |
| 3482 | } | 3621 | } |
| 3622 | mddev_put(mddev); | ||
| 3623 | return 0; | ||
| 3624 | } | ||
| 3625 | |||
| 3626 | static struct kobject *md_probe(dev_t dev, int *part, void *data) | ||
| 3627 | { | ||
| 3628 | md_alloc(dev, NULL); | ||
| 3483 | return NULL; | 3629 | return NULL; |
| 3484 | } | 3630 | } |
| 3485 | 3631 | ||
| 3632 | static int add_named_array(const char *val, struct kernel_param *kp) | ||
| 3633 | { | ||
| 3634 | /* val must be "md_*" where * is not all digits. | ||
| 3635 | * We allocate an array with a large free minor number, and | ||
| 3636 | * set the name to val. val must not already be an active name. | ||
| 3637 | */ | ||
| 3638 | int len = strlen(val); | ||
| 3639 | char buf[DISK_NAME_LEN]; | ||
| 3640 | |||
| 3641 | while (len && val[len-1] == '\n') | ||
| 3642 | len--; | ||
| 3643 | if (len >= DISK_NAME_LEN) | ||
| 3644 | return -E2BIG; | ||
| 3645 | strlcpy(buf, val, len+1); | ||
| 3646 | if (strncmp(buf, "md_", 3) != 0) | ||
| 3647 | return -EINVAL; | ||
| 3648 | return md_alloc(0, buf); | ||
| 3649 | } | ||
| 3650 | |||
| 3486 | static void md_safemode_timeout(unsigned long data) | 3651 | static void md_safemode_timeout(unsigned long data) |
| 3487 | { | 3652 | { |
| 3488 | mddev_t *mddev = (mddev_t *) data; | 3653 | mddev_t *mddev = (mddev_t *) data; |
| @@ -3501,7 +3666,6 @@ static int do_md_run(mddev_t * mddev) | |||
| 3501 | { | 3666 | { |
| 3502 | int err; | 3667 | int err; |
| 3503 | int chunk_size; | 3668 | int chunk_size; |
| 3504 | struct list_head *tmp; | ||
| 3505 | mdk_rdev_t *rdev; | 3669 | mdk_rdev_t *rdev; |
| 3506 | struct gendisk *disk; | 3670 | struct gendisk *disk; |
| 3507 | struct mdk_personality *pers; | 3671 | struct mdk_personality *pers; |
| @@ -3540,7 +3704,7 @@ static int do_md_run(mddev_t * mddev) | |||
| 3540 | } | 3704 | } |
| 3541 | 3705 | ||
| 3542 | /* devices must have minimum size of one chunk */ | 3706 | /* devices must have minimum size of one chunk */ |
| 3543 | rdev_for_each(rdev, tmp, mddev) { | 3707 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 3544 | if (test_bit(Faulty, &rdev->flags)) | 3708 | if (test_bit(Faulty, &rdev->flags)) |
| 3545 | continue; | 3709 | continue; |
| 3546 | if (rdev->size < chunk_size / 1024) { | 3710 | if (rdev->size < chunk_size / 1024) { |
| @@ -3565,7 +3729,7 @@ static int do_md_run(mddev_t * mddev) | |||
| 3565 | * the only valid external interface is through the md | 3729 | * the only valid external interface is through the md |
| 3566 | * device. | 3730 | * device. |
| 3567 | */ | 3731 | */ |
| 3568 | rdev_for_each(rdev, tmp, mddev) { | 3732 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 3569 | if (test_bit(Faulty, &rdev->flags)) | 3733 | if (test_bit(Faulty, &rdev->flags)) |
| 3570 | continue; | 3734 | continue; |
| 3571 | sync_blockdev(rdev->bdev); | 3735 | sync_blockdev(rdev->bdev); |
| @@ -3630,10 +3794,10 @@ static int do_md_run(mddev_t * mddev) | |||
| 3630 | */ | 3794 | */ |
| 3631 | char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; | 3795 | char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; |
| 3632 | mdk_rdev_t *rdev2; | 3796 | mdk_rdev_t *rdev2; |
| 3633 | struct list_head *tmp2; | ||
| 3634 | int warned = 0; | 3797 | int warned = 0; |
| 3635 | rdev_for_each(rdev, tmp, mddev) { | 3798 | |
| 3636 | rdev_for_each(rdev2, tmp2, mddev) { | 3799 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 3800 | list_for_each_entry(rdev2, &mddev->disks, same_set) { | ||
| 3637 | if (rdev < rdev2 && | 3801 | if (rdev < rdev2 && |
| 3638 | rdev->bdev->bd_contains == | 3802 | rdev->bdev->bd_contains == |
| 3639 | rdev2->bdev->bd_contains) { | 3803 | rdev2->bdev->bd_contains) { |
| @@ -3647,7 +3811,7 @@ static int do_md_run(mddev_t * mddev) | |||
| 3647 | warned = 1; | 3811 | warned = 1; |
| 3648 | } | 3812 | } |
| 3649 | } | 3813 | } |
| 3650 | } | 3814 | |
| 3651 | if (warned) | 3815 | if (warned) |
| 3652 | printk(KERN_WARNING | 3816 | printk(KERN_WARNING |
| 3653 | "True protection against single-disk" | 3817 | "True protection against single-disk" |
| @@ -3684,6 +3848,7 @@ static int do_md_run(mddev_t * mddev) | |||
| 3684 | printk(KERN_WARNING | 3848 | printk(KERN_WARNING |
| 3685 | "md: cannot register extra attributes for %s\n", | 3849 | "md: cannot register extra attributes for %s\n", |
| 3686 | mdname(mddev)); | 3850 | mdname(mddev)); |
| 3851 | mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, "sync_action"); | ||
| 3687 | } else if (mddev->ro == 2) /* auto-readonly not meaningful */ | 3852 | } else if (mddev->ro == 2) /* auto-readonly not meaningful */ |
| 3688 | mddev->ro = 0; | 3853 | mddev->ro = 0; |
| 3689 | 3854 | ||
| @@ -3694,7 +3859,7 @@ static int do_md_run(mddev_t * mddev) | |||
| 3694 | mddev->safemode_delay = (200 * HZ)/1000 +1; /* 200 msec delay */ | 3859 | mddev->safemode_delay = (200 * HZ)/1000 +1; /* 200 msec delay */ |
| 3695 | mddev->in_sync = 1; | 3860 | mddev->in_sync = 1; |
| 3696 | 3861 | ||
| 3697 | rdev_for_each(rdev, tmp, mddev) | 3862 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 3698 | if (rdev->raid_disk >= 0) { | 3863 | if (rdev->raid_disk >= 0) { |
| 3699 | char nm[20]; | 3864 | char nm[20]; |
| 3700 | sprintf(nm, "rd%d", rdev->raid_disk); | 3865 | sprintf(nm, "rd%d", rdev->raid_disk); |
| @@ -3725,9 +3890,8 @@ static int do_md_run(mddev_t * mddev) | |||
| 3725 | * it will remove the drives and not do the right thing | 3890 | * it will remove the drives and not do the right thing |
| 3726 | */ | 3891 | */ |
| 3727 | if (mddev->degraded && !mddev->sync_thread) { | 3892 | if (mddev->degraded && !mddev->sync_thread) { |
| 3728 | struct list_head *rtmp; | ||
| 3729 | int spares = 0; | 3893 | int spares = 0; |
| 3730 | rdev_for_each(rdev, rtmp, mddev) | 3894 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 3731 | if (rdev->raid_disk >= 0 && | 3895 | if (rdev->raid_disk >= 0 && |
| 3732 | !test_bit(In_sync, &rdev->flags) && | 3896 | !test_bit(In_sync, &rdev->flags) && |
| 3733 | !test_bit(Faulty, &rdev->flags)) | 3897 | !test_bit(Faulty, &rdev->flags)) |
| @@ -3754,7 +3918,8 @@ static int do_md_run(mddev_t * mddev) | |||
| 3754 | mddev->changed = 1; | 3918 | mddev->changed = 1; |
| 3755 | md_new_event(mddev); | 3919 | md_new_event(mddev); |
| 3756 | sysfs_notify_dirent(mddev->sysfs_state); | 3920 | sysfs_notify_dirent(mddev->sysfs_state); |
| 3757 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | 3921 | if (mddev->sysfs_action) |
| 3922 | sysfs_notify_dirent(mddev->sysfs_action); | ||
| 3758 | sysfs_notify(&mddev->kobj, NULL, "degraded"); | 3923 | sysfs_notify(&mddev->kobj, NULL, "degraded"); |
| 3759 | kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); | 3924 | kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); |
| 3760 | return 0; | 3925 | return 0; |
| @@ -3854,9 +4019,12 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
| 3854 | mddev->queue->merge_bvec_fn = NULL; | 4019 | mddev->queue->merge_bvec_fn = NULL; |
| 3855 | mddev->queue->unplug_fn = NULL; | 4020 | mddev->queue->unplug_fn = NULL; |
| 3856 | mddev->queue->backing_dev_info.congested_fn = NULL; | 4021 | mddev->queue->backing_dev_info.congested_fn = NULL; |
| 3857 | if (mddev->pers->sync_request) | 4022 | if (mddev->pers->sync_request) { |
| 3858 | sysfs_remove_group(&mddev->kobj, &md_redundancy_group); | 4023 | sysfs_remove_group(&mddev->kobj, &md_redundancy_group); |
| 3859 | 4024 | if (mddev->sysfs_action) | |
| 4025 | sysfs_put(mddev->sysfs_action); | ||
| 4026 | mddev->sysfs_action = NULL; | ||
| 4027 | } | ||
| 3860 | module_put(mddev->pers->owner); | 4028 | module_put(mddev->pers->owner); |
| 3861 | mddev->pers = NULL; | 4029 | mddev->pers = NULL; |
| 3862 | /* tell userspace to handle 'inactive' */ | 4030 | /* tell userspace to handle 'inactive' */ |
| @@ -3883,7 +4051,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
| 3883 | */ | 4051 | */ |
| 3884 | if (mode == 0) { | 4052 | if (mode == 0) { |
| 3885 | mdk_rdev_t *rdev; | 4053 | mdk_rdev_t *rdev; |
| 3886 | struct list_head *tmp; | ||
| 3887 | 4054 | ||
| 3888 | printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); | 4055 | printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); |
| 3889 | 4056 | ||
| @@ -3895,7 +4062,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
| 3895 | } | 4062 | } |
| 3896 | mddev->bitmap_offset = 0; | 4063 | mddev->bitmap_offset = 0; |
| 3897 | 4064 | ||
| 3898 | rdev_for_each(rdev, tmp, mddev) | 4065 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 3899 | if (rdev->raid_disk >= 0) { | 4066 | if (rdev->raid_disk >= 0) { |
| 3900 | char nm[20]; | 4067 | char nm[20]; |
| 3901 | sprintf(nm, "rd%d", rdev->raid_disk); | 4068 | sprintf(nm, "rd%d", rdev->raid_disk); |
| @@ -3941,6 +4108,8 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
| 3941 | mddev->barriers_work = 0; | 4108 | mddev->barriers_work = 0; |
| 3942 | mddev->safemode = 0; | 4109 | mddev->safemode = 0; |
| 3943 | kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); | 4110 | kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); |
| 4111 | if (mddev->hold_active == UNTIL_STOP) | ||
| 4112 | mddev->hold_active = 0; | ||
| 3944 | 4113 | ||
| 3945 | } else if (mddev->pers) | 4114 | } else if (mddev->pers) |
| 3946 | printk(KERN_INFO "md: %s switched to read-only mode.\n", | 4115 | printk(KERN_INFO "md: %s switched to read-only mode.\n", |
| @@ -3956,7 +4125,6 @@ out: | |||
| 3956 | static void autorun_array(mddev_t *mddev) | 4125 | static void autorun_array(mddev_t *mddev) |
| 3957 | { | 4126 | { |
| 3958 | mdk_rdev_t *rdev; | 4127 | mdk_rdev_t *rdev; |
| 3959 | struct list_head *tmp; | ||
| 3960 | int err; | 4128 | int err; |
| 3961 | 4129 | ||
| 3962 | if (list_empty(&mddev->disks)) | 4130 | if (list_empty(&mddev->disks)) |
| @@ -3964,7 +4132,7 @@ static void autorun_array(mddev_t *mddev) | |||
| 3964 | 4132 | ||
| 3965 | printk(KERN_INFO "md: running: "); | 4133 | printk(KERN_INFO "md: running: "); |
| 3966 | 4134 | ||
| 3967 | rdev_for_each(rdev, tmp, mddev) { | 4135 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 3968 | char b[BDEVNAME_SIZE]; | 4136 | char b[BDEVNAME_SIZE]; |
| 3969 | printk("<%s>", bdevname(rdev->bdev,b)); | 4137 | printk("<%s>", bdevname(rdev->bdev,b)); |
| 3970 | } | 4138 | } |
| @@ -3991,8 +4159,7 @@ static void autorun_array(mddev_t *mddev) | |||
| 3991 | */ | 4159 | */ |
| 3992 | static void autorun_devices(int part) | 4160 | static void autorun_devices(int part) |
| 3993 | { | 4161 | { |
| 3994 | struct list_head *tmp; | 4162 | mdk_rdev_t *rdev0, *rdev, *tmp; |
| 3995 | mdk_rdev_t *rdev0, *rdev; | ||
| 3996 | mddev_t *mddev; | 4163 | mddev_t *mddev; |
| 3997 | char b[BDEVNAME_SIZE]; | 4164 | char b[BDEVNAME_SIZE]; |
| 3998 | 4165 | ||
| @@ -4007,7 +4174,7 @@ static void autorun_devices(int part) | |||
| 4007 | printk(KERN_INFO "md: considering %s ...\n", | 4174 | printk(KERN_INFO "md: considering %s ...\n", |
| 4008 | bdevname(rdev0->bdev,b)); | 4175 | bdevname(rdev0->bdev,b)); |
| 4009 | INIT_LIST_HEAD(&candidates); | 4176 | INIT_LIST_HEAD(&candidates); |
| 4010 | rdev_for_each_list(rdev, tmp, pending_raid_disks) | 4177 | rdev_for_each_list(rdev, tmp, &pending_raid_disks) |
| 4011 | if (super_90_load(rdev, rdev0, 0) >= 0) { | 4178 | if (super_90_load(rdev, rdev0, 0) >= 0) { |
| 4012 | printk(KERN_INFO "md: adding %s ...\n", | 4179 | printk(KERN_INFO "md: adding %s ...\n", |
| 4013 | bdevname(rdev->bdev,b)); | 4180 | bdevname(rdev->bdev,b)); |
| @@ -4053,7 +4220,7 @@ static void autorun_devices(int part) | |||
| 4053 | } else { | 4220 | } else { |
| 4054 | printk(KERN_INFO "md: created %s\n", mdname(mddev)); | 4221 | printk(KERN_INFO "md: created %s\n", mdname(mddev)); |
| 4055 | mddev->persistent = 1; | 4222 | mddev->persistent = 1; |
| 4056 | rdev_for_each_list(rdev, tmp, candidates) { | 4223 | rdev_for_each_list(rdev, tmp, &candidates) { |
| 4057 | list_del_init(&rdev->same_set); | 4224 | list_del_init(&rdev->same_set); |
| 4058 | if (bind_rdev_to_array(rdev, mddev)) | 4225 | if (bind_rdev_to_array(rdev, mddev)) |
| 4059 | export_rdev(rdev); | 4226 | export_rdev(rdev); |
| @@ -4064,7 +4231,7 @@ static void autorun_devices(int part) | |||
| 4064 | /* on success, candidates will be empty, on error | 4231 | /* on success, candidates will be empty, on error |
| 4065 | * it won't... | 4232 | * it won't... |
| 4066 | */ | 4233 | */ |
| 4067 | rdev_for_each_list(rdev, tmp, candidates) { | 4234 | rdev_for_each_list(rdev, tmp, &candidates) { |
| 4068 | list_del_init(&rdev->same_set); | 4235 | list_del_init(&rdev->same_set); |
| 4069 | export_rdev(rdev); | 4236 | export_rdev(rdev); |
| 4070 | } | 4237 | } |
| @@ -4093,10 +4260,9 @@ static int get_array_info(mddev_t * mddev, void __user * arg) | |||
| 4093 | mdu_array_info_t info; | 4260 | mdu_array_info_t info; |
| 4094 | int nr,working,active,failed,spare; | 4261 | int nr,working,active,failed,spare; |
| 4095 | mdk_rdev_t *rdev; | 4262 | mdk_rdev_t *rdev; |
| 4096 | struct list_head *tmp; | ||
| 4097 | 4263 | ||
| 4098 | nr=working=active=failed=spare=0; | 4264 | nr=working=active=failed=spare=0; |
| 4099 | rdev_for_each(rdev, tmp, mddev) { | 4265 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 4100 | nr++; | 4266 | nr++; |
| 4101 | if (test_bit(Faulty, &rdev->flags)) | 4267 | if (test_bit(Faulty, &rdev->flags)) |
| 4102 | failed++; | 4268 | failed++; |
| @@ -4614,9 +4780,8 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) | |||
| 4614 | 4780 | ||
| 4615 | static int update_size(mddev_t *mddev, sector_t num_sectors) | 4781 | static int update_size(mddev_t *mddev, sector_t num_sectors) |
| 4616 | { | 4782 | { |
| 4617 | mdk_rdev_t * rdev; | 4783 | mdk_rdev_t *rdev; |
| 4618 | int rv; | 4784 | int rv; |
| 4619 | struct list_head *tmp; | ||
| 4620 | int fit = (num_sectors == 0); | 4785 | int fit = (num_sectors == 0); |
| 4621 | 4786 | ||
| 4622 | if (mddev->pers->resize == NULL) | 4787 | if (mddev->pers->resize == NULL) |
| @@ -4638,7 +4803,7 @@ static int update_size(mddev_t *mddev, sector_t num_sectors) | |||
| 4638 | * grow, and re-add. | 4803 | * grow, and re-add. |
| 4639 | */ | 4804 | */ |
| 4640 | return -EBUSY; | 4805 | return -EBUSY; |
| 4641 | rdev_for_each(rdev, tmp, mddev) { | 4806 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 4642 | sector_t avail; | 4807 | sector_t avail; |
| 4643 | avail = rdev->size * 2; | 4808 | avail = rdev->size * 2; |
| 4644 | 4809 | ||
| @@ -5000,6 +5165,9 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, | |||
| 5000 | 5165 | ||
| 5001 | done_unlock: | 5166 | done_unlock: |
| 5002 | abort_unlock: | 5167 | abort_unlock: |
| 5168 | if (mddev->hold_active == UNTIL_IOCTL && | ||
| 5169 | err != -EINVAL) | ||
| 5170 | mddev->hold_active = 0; | ||
| 5003 | mddev_unlock(mddev); | 5171 | mddev_unlock(mddev); |
| 5004 | 5172 | ||
| 5005 | return err; | 5173 | return err; |
| @@ -5016,14 +5184,25 @@ static int md_open(struct block_device *bdev, fmode_t mode) | |||
| 5016 | * Succeed if we can lock the mddev, which confirms that | 5184 | * Succeed if we can lock the mddev, which confirms that |
| 5017 | * it isn't being stopped right now. | 5185 | * it isn't being stopped right now. |
| 5018 | */ | 5186 | */ |
| 5019 | mddev_t *mddev = bdev->bd_disk->private_data; | 5187 | mddev_t *mddev = mddev_find(bdev->bd_dev); |
| 5020 | int err; | 5188 | int err; |
| 5021 | 5189 | ||
| 5190 | if (mddev->gendisk != bdev->bd_disk) { | ||
| 5191 | /* we are racing with mddev_put which is discarding this | ||
| 5192 | * bd_disk. | ||
| 5193 | */ | ||
| 5194 | mddev_put(mddev); | ||
| 5195 | /* Wait until bdev->bd_disk is definitely gone */ | ||
| 5196 | flush_scheduled_work(); | ||
| 5197 | /* Then retry the open from the top */ | ||
| 5198 | return -ERESTARTSYS; | ||
| 5199 | } | ||
| 5200 | BUG_ON(mddev != bdev->bd_disk->private_data); | ||
| 5201 | |||
| 5022 | if ((err = mutex_lock_interruptible_nested(&mddev->reconfig_mutex, 1))) | 5202 | if ((err = mutex_lock_interruptible_nested(&mddev->reconfig_mutex, 1))) |
| 5023 | goto out; | 5203 | goto out; |
| 5024 | 5204 | ||
| 5025 | err = 0; | 5205 | err = 0; |
| 5026 | mddev_get(mddev); | ||
| 5027 | atomic_inc(&mddev->openers); | 5206 | atomic_inc(&mddev->openers); |
| 5028 | mddev_unlock(mddev); | 5207 | mddev_unlock(mddev); |
| 5029 | 5208 | ||
| @@ -5187,11 +5366,10 @@ static void status_unused(struct seq_file *seq) | |||
| 5187 | { | 5366 | { |
| 5188 | int i = 0; | 5367 | int i = 0; |
| 5189 | mdk_rdev_t *rdev; | 5368 | mdk_rdev_t *rdev; |
| 5190 | struct list_head *tmp; | ||
| 5191 | 5369 | ||
| 5192 | seq_printf(seq, "unused devices: "); | 5370 | seq_printf(seq, "unused devices: "); |
| 5193 | 5371 | ||
| 5194 | rdev_for_each_list(rdev, tmp, pending_raid_disks) { | 5372 | list_for_each_entry(rdev, &pending_raid_disks, same_set) { |
| 5195 | char b[BDEVNAME_SIZE]; | 5373 | char b[BDEVNAME_SIZE]; |
| 5196 | i++; | 5374 | i++; |
| 5197 | seq_printf(seq, "%s ", | 5375 | seq_printf(seq, "%s ", |
| @@ -5350,7 +5528,6 @@ static int md_seq_show(struct seq_file *seq, void *v) | |||
| 5350 | { | 5528 | { |
| 5351 | mddev_t *mddev = v; | 5529 | mddev_t *mddev = v; |
| 5352 | sector_t size; | 5530 | sector_t size; |
| 5353 | struct list_head *tmp2; | ||
| 5354 | mdk_rdev_t *rdev; | 5531 | mdk_rdev_t *rdev; |
| 5355 | struct mdstat_info *mi = seq->private; | 5532 | struct mdstat_info *mi = seq->private; |
| 5356 | struct bitmap *bitmap; | 5533 | struct bitmap *bitmap; |
| @@ -5387,7 +5564,7 @@ static int md_seq_show(struct seq_file *seq, void *v) | |||
| 5387 | } | 5564 | } |
| 5388 | 5565 | ||
| 5389 | size = 0; | 5566 | size = 0; |
| 5390 | rdev_for_each(rdev, tmp2, mddev) { | 5567 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 5391 | char b[BDEVNAME_SIZE]; | 5568 | char b[BDEVNAME_SIZE]; |
| 5392 | seq_printf(seq, " %s[%d]", | 5569 | seq_printf(seq, " %s[%d]", |
| 5393 | bdevname(rdev->bdev,b), rdev->desc_nr); | 5570 | bdevname(rdev->bdev,b), rdev->desc_nr); |
| @@ -5694,7 +5871,6 @@ void md_do_sync(mddev_t *mddev) | |||
| 5694 | struct list_head *tmp; | 5871 | struct list_head *tmp; |
| 5695 | sector_t last_check; | 5872 | sector_t last_check; |
| 5696 | int skipped = 0; | 5873 | int skipped = 0; |
| 5697 | struct list_head *rtmp; | ||
| 5698 | mdk_rdev_t *rdev; | 5874 | mdk_rdev_t *rdev; |
| 5699 | char *desc; | 5875 | char *desc; |
| 5700 | 5876 | ||
| @@ -5799,7 +5975,7 @@ void md_do_sync(mddev_t *mddev) | |||
| 5799 | /* recovery follows the physical size of devices */ | 5975 | /* recovery follows the physical size of devices */ |
| 5800 | max_sectors = mddev->size << 1; | 5976 | max_sectors = mddev->size << 1; |
| 5801 | j = MaxSector; | 5977 | j = MaxSector; |
| 5802 | rdev_for_each(rdev, rtmp, mddev) | 5978 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 5803 | if (rdev->raid_disk >= 0 && | 5979 | if (rdev->raid_disk >= 0 && |
| 5804 | !test_bit(Faulty, &rdev->flags) && | 5980 | !test_bit(Faulty, &rdev->flags) && |
| 5805 | !test_bit(In_sync, &rdev->flags) && | 5981 | !test_bit(In_sync, &rdev->flags) && |
| @@ -5949,7 +6125,7 @@ void md_do_sync(mddev_t *mddev) | |||
| 5949 | } else { | 6125 | } else { |
| 5950 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) | 6126 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) |
| 5951 | mddev->curr_resync = MaxSector; | 6127 | mddev->curr_resync = MaxSector; |
| 5952 | rdev_for_each(rdev, rtmp, mddev) | 6128 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 5953 | if (rdev->raid_disk >= 0 && | 6129 | if (rdev->raid_disk >= 0 && |
| 5954 | !test_bit(Faulty, &rdev->flags) && | 6130 | !test_bit(Faulty, &rdev->flags) && |
| 5955 | !test_bit(In_sync, &rdev->flags) && | 6131 | !test_bit(In_sync, &rdev->flags) && |
| @@ -5985,10 +6161,9 @@ EXPORT_SYMBOL_GPL(md_do_sync); | |||
| 5985 | static int remove_and_add_spares(mddev_t *mddev) | 6161 | static int remove_and_add_spares(mddev_t *mddev) |
| 5986 | { | 6162 | { |
| 5987 | mdk_rdev_t *rdev; | 6163 | mdk_rdev_t *rdev; |
| 5988 | struct list_head *rtmp; | ||
| 5989 | int spares = 0; | 6164 | int spares = 0; |
| 5990 | 6165 | ||
| 5991 | rdev_for_each(rdev, rtmp, mddev) | 6166 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 5992 | if (rdev->raid_disk >= 0 && | 6167 | if (rdev->raid_disk >= 0 && |
| 5993 | !test_bit(Blocked, &rdev->flags) && | 6168 | !test_bit(Blocked, &rdev->flags) && |
| 5994 | (test_bit(Faulty, &rdev->flags) || | 6169 | (test_bit(Faulty, &rdev->flags) || |
| @@ -6003,8 +6178,8 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
| 6003 | } | 6178 | } |
| 6004 | } | 6179 | } |
| 6005 | 6180 | ||
| 6006 | if (mddev->degraded && ! mddev->ro) { | 6181 | if (mddev->degraded && ! mddev->ro && !mddev->recovery_disabled) { |
| 6007 | rdev_for_each(rdev, rtmp, mddev) { | 6182 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 6008 | if (rdev->raid_disk >= 0 && | 6183 | if (rdev->raid_disk >= 0 && |
| 6009 | !test_bit(In_sync, &rdev->flags) && | 6184 | !test_bit(In_sync, &rdev->flags) && |
| 6010 | !test_bit(Blocked, &rdev->flags)) | 6185 | !test_bit(Blocked, &rdev->flags)) |
| @@ -6056,7 +6231,6 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
| 6056 | void md_check_recovery(mddev_t *mddev) | 6231 | void md_check_recovery(mddev_t *mddev) |
| 6057 | { | 6232 | { |
| 6058 | mdk_rdev_t *rdev; | 6233 | mdk_rdev_t *rdev; |
| 6059 | struct list_head *rtmp; | ||
| 6060 | 6234 | ||
| 6061 | 6235 | ||
| 6062 | if (mddev->bitmap) | 6236 | if (mddev->bitmap) |
| @@ -6120,7 +6294,7 @@ void md_check_recovery(mddev_t *mddev) | |||
| 6120 | if (mddev->flags) | 6294 | if (mddev->flags) |
| 6121 | md_update_sb(mddev, 0); | 6295 | md_update_sb(mddev, 0); |
| 6122 | 6296 | ||
| 6123 | rdev_for_each(rdev, rtmp, mddev) | 6297 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 6124 | if (test_and_clear_bit(StateChanged, &rdev->flags)) | 6298 | if (test_and_clear_bit(StateChanged, &rdev->flags)) |
| 6125 | sysfs_notify_dirent(rdev->sysfs_state); | 6299 | sysfs_notify_dirent(rdev->sysfs_state); |
| 6126 | 6300 | ||
| @@ -6149,13 +6323,13 @@ void md_check_recovery(mddev_t *mddev) | |||
| 6149 | * information must be scrapped | 6323 | * information must be scrapped |
| 6150 | */ | 6324 | */ |
| 6151 | if (!mddev->degraded) | 6325 | if (!mddev->degraded) |
| 6152 | rdev_for_each(rdev, rtmp, mddev) | 6326 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 6153 | rdev->saved_raid_disk = -1; | 6327 | rdev->saved_raid_disk = -1; |
| 6154 | 6328 | ||
| 6155 | mddev->recovery = 0; | 6329 | mddev->recovery = 0; |
| 6156 | /* flag recovery needed just to double check */ | 6330 | /* flag recovery needed just to double check */ |
| 6157 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 6331 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
| 6158 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | 6332 | sysfs_notify_dirent(mddev->sysfs_action); |
| 6159 | md_new_event(mddev); | 6333 | md_new_event(mddev); |
| 6160 | goto unlock; | 6334 | goto unlock; |
| 6161 | } | 6335 | } |
| @@ -6216,7 +6390,7 @@ void md_check_recovery(mddev_t *mddev) | |||
| 6216 | mddev->recovery = 0; | 6390 | mddev->recovery = 0; |
| 6217 | } else | 6391 | } else |
| 6218 | md_wakeup_thread(mddev->sync_thread); | 6392 | md_wakeup_thread(mddev->sync_thread); |
| 6219 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | 6393 | sysfs_notify_dirent(mddev->sysfs_action); |
| 6220 | md_new_event(mddev); | 6394 | md_new_event(mddev); |
| 6221 | } | 6395 | } |
| 6222 | unlock: | 6396 | unlock: |
| @@ -6224,7 +6398,8 @@ void md_check_recovery(mddev_t *mddev) | |||
| 6224 | clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | 6398 | clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery); |
| 6225 | if (test_and_clear_bit(MD_RECOVERY_RECOVER, | 6399 | if (test_and_clear_bit(MD_RECOVERY_RECOVER, |
| 6226 | &mddev->recovery)) | 6400 | &mddev->recovery)) |
| 6227 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | 6401 | if (mddev->sysfs_action) |
| 6402 | sysfs_notify_dirent(mddev->sysfs_action); | ||
| 6228 | } | 6403 | } |
| 6229 | mddev_unlock(mddev); | 6404 | mddev_unlock(mddev); |
| 6230 | } | 6405 | } |
| @@ -6386,14 +6561,8 @@ static __exit void md_exit(void) | |||
| 6386 | unregister_sysctl_table(raid_table_header); | 6561 | unregister_sysctl_table(raid_table_header); |
| 6387 | remove_proc_entry("mdstat", NULL); | 6562 | remove_proc_entry("mdstat", NULL); |
| 6388 | for_each_mddev(mddev, tmp) { | 6563 | for_each_mddev(mddev, tmp) { |
| 6389 | struct gendisk *disk = mddev->gendisk; | ||
| 6390 | if (!disk) | ||
| 6391 | continue; | ||
| 6392 | export_array(mddev); | 6564 | export_array(mddev); |
| 6393 | del_gendisk(disk); | 6565 | mddev->hold_active = 0; |
| 6394 | put_disk(disk); | ||
| 6395 | mddev->gendisk = NULL; | ||
| 6396 | mddev_put(mddev); | ||
| 6397 | } | 6566 | } |
| 6398 | } | 6567 | } |
| 6399 | 6568 | ||
| @@ -6418,6 +6587,7 @@ static int set_ro(const char *val, struct kernel_param *kp) | |||
| 6418 | module_param_call(start_ro, set_ro, get_ro, NULL, S_IRUSR|S_IWUSR); | 6587 | module_param_call(start_ro, set_ro, get_ro, NULL, S_IRUSR|S_IWUSR); |
| 6419 | module_param(start_dirty_degraded, int, S_IRUGO|S_IWUSR); | 6588 | module_param(start_dirty_degraded, int, S_IRUGO|S_IWUSR); |
| 6420 | 6589 | ||
| 6590 | module_param_call(new_array, add_named_array, NULL, NULL, S_IWUSR); | ||
| 6421 | 6591 | ||
| 6422 | EXPORT_SYMBOL(register_md_personality); | 6592 | EXPORT_SYMBOL(register_md_personality); |
| 6423 | EXPORT_SYMBOL(unregister_md_personality); | 6593 | EXPORT_SYMBOL(unregister_md_personality); |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index d4ac47d11279..f6d08f241671 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
| @@ -408,7 +408,6 @@ static int multipath_run (mddev_t *mddev) | |||
| 408 | int disk_idx; | 408 | int disk_idx; |
| 409 | struct multipath_info *disk; | 409 | struct multipath_info *disk; |
| 410 | mdk_rdev_t *rdev; | 410 | mdk_rdev_t *rdev; |
| 411 | struct list_head *tmp; | ||
| 412 | 411 | ||
| 413 | if (mddev->level != LEVEL_MULTIPATH) { | 412 | if (mddev->level != LEVEL_MULTIPATH) { |
| 414 | printk("multipath: %s: raid level not set to multipath IO (%d)\n", | 413 | printk("multipath: %s: raid level not set to multipath IO (%d)\n", |
| @@ -441,7 +440,7 @@ static int multipath_run (mddev_t *mddev) | |||
| 441 | } | 440 | } |
| 442 | 441 | ||
| 443 | conf->working_disks = 0; | 442 | conf->working_disks = 0; |
| 444 | rdev_for_each(rdev, tmp, mddev) { | 443 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 445 | disk_idx = rdev->raid_disk; | 444 | disk_idx = rdev->raid_disk; |
| 446 | if (disk_idx < 0 || | 445 | if (disk_idx < 0 || |
| 447 | disk_idx >= mddev->raid_disks) | 446 | disk_idx >= mddev->raid_disks) |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 8ac6488ad0dc..c605ba805586 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
| @@ -53,11 +53,10 @@ static int raid0_congested(void *data, int bits) | |||
| 53 | static int create_strip_zones (mddev_t *mddev) | 53 | static int create_strip_zones (mddev_t *mddev) |
| 54 | { | 54 | { |
| 55 | int i, c, j; | 55 | int i, c, j; |
| 56 | sector_t current_offset, curr_zone_offset; | 56 | sector_t current_start, curr_zone_start; |
| 57 | sector_t min_spacing; | 57 | sector_t min_spacing; |
| 58 | raid0_conf_t *conf = mddev_to_conf(mddev); | 58 | raid0_conf_t *conf = mddev_to_conf(mddev); |
| 59 | mdk_rdev_t *smallest, *rdev1, *rdev2, *rdev; | 59 | mdk_rdev_t *smallest, *rdev1, *rdev2, *rdev; |
| 60 | struct list_head *tmp1, *tmp2; | ||
| 61 | struct strip_zone *zone; | 60 | struct strip_zone *zone; |
| 62 | int cnt; | 61 | int cnt; |
| 63 | char b[BDEVNAME_SIZE]; | 62 | char b[BDEVNAME_SIZE]; |
| @@ -67,19 +66,19 @@ static int create_strip_zones (mddev_t *mddev) | |||
| 67 | */ | 66 | */ |
| 68 | conf->nr_strip_zones = 0; | 67 | conf->nr_strip_zones = 0; |
| 69 | 68 | ||
| 70 | rdev_for_each(rdev1, tmp1, mddev) { | 69 | list_for_each_entry(rdev1, &mddev->disks, same_set) { |
| 71 | printk("raid0: looking at %s\n", | 70 | printk(KERN_INFO "raid0: looking at %s\n", |
| 72 | bdevname(rdev1->bdev,b)); | 71 | bdevname(rdev1->bdev,b)); |
| 73 | c = 0; | 72 | c = 0; |
| 74 | rdev_for_each(rdev2, tmp2, mddev) { | 73 | list_for_each_entry(rdev2, &mddev->disks, same_set) { |
| 75 | printk("raid0: comparing %s(%llu)", | 74 | printk(KERN_INFO "raid0: comparing %s(%llu)", |
| 76 | bdevname(rdev1->bdev,b), | 75 | bdevname(rdev1->bdev,b), |
| 77 | (unsigned long long)rdev1->size); | 76 | (unsigned long long)rdev1->size); |
| 78 | printk(" with %s(%llu)\n", | 77 | printk(KERN_INFO " with %s(%llu)\n", |
| 79 | bdevname(rdev2->bdev,b), | 78 | bdevname(rdev2->bdev,b), |
| 80 | (unsigned long long)rdev2->size); | 79 | (unsigned long long)rdev2->size); |
| 81 | if (rdev2 == rdev1) { | 80 | if (rdev2 == rdev1) { |
| 82 | printk("raid0: END\n"); | 81 | printk(KERN_INFO "raid0: END\n"); |
| 83 | break; | 82 | break; |
| 84 | } | 83 | } |
| 85 | if (rdev2->size == rdev1->size) | 84 | if (rdev2->size == rdev1->size) |
| @@ -88,19 +87,20 @@ static int create_strip_zones (mddev_t *mddev) | |||
| 88 | * Not unique, don't count it as a new | 87 | * Not unique, don't count it as a new |
| 89 | * group | 88 | * group |
| 90 | */ | 89 | */ |
| 91 | printk("raid0: EQUAL\n"); | 90 | printk(KERN_INFO "raid0: EQUAL\n"); |
| 92 | c = 1; | 91 | c = 1; |
| 93 | break; | 92 | break; |
| 94 | } | 93 | } |
| 95 | printk("raid0: NOT EQUAL\n"); | 94 | printk(KERN_INFO "raid0: NOT EQUAL\n"); |
| 96 | } | 95 | } |
| 97 | if (!c) { | 96 | if (!c) { |
| 98 | printk("raid0: ==> UNIQUE\n"); | 97 | printk(KERN_INFO "raid0: ==> UNIQUE\n"); |
| 99 | conf->nr_strip_zones++; | 98 | conf->nr_strip_zones++; |
| 100 | printk("raid0: %d zones\n", conf->nr_strip_zones); | 99 | printk(KERN_INFO "raid0: %d zones\n", |
| 100 | conf->nr_strip_zones); | ||
| 101 | } | 101 | } |
| 102 | } | 102 | } |
| 103 | printk("raid0: FINAL %d zones\n", conf->nr_strip_zones); | 103 | printk(KERN_INFO "raid0: FINAL %d zones\n", conf->nr_strip_zones); |
| 104 | 104 | ||
| 105 | conf->strip_zone = kzalloc(sizeof(struct strip_zone)* | 105 | conf->strip_zone = kzalloc(sizeof(struct strip_zone)* |
| 106 | conf->nr_strip_zones, GFP_KERNEL); | 106 | conf->nr_strip_zones, GFP_KERNEL); |
| @@ -119,16 +119,17 @@ static int create_strip_zones (mddev_t *mddev) | |||
| 119 | cnt = 0; | 119 | cnt = 0; |
| 120 | smallest = NULL; | 120 | smallest = NULL; |
| 121 | zone->dev = conf->devlist; | 121 | zone->dev = conf->devlist; |
| 122 | rdev_for_each(rdev1, tmp1, mddev) { | 122 | list_for_each_entry(rdev1, &mddev->disks, same_set) { |
| 123 | int j = rdev1->raid_disk; | 123 | int j = rdev1->raid_disk; |
| 124 | 124 | ||
| 125 | if (j < 0 || j >= mddev->raid_disks) { | 125 | if (j < 0 || j >= mddev->raid_disks) { |
| 126 | printk("raid0: bad disk number %d - aborting!\n", j); | 126 | printk(KERN_ERR "raid0: bad disk number %d - " |
| 127 | "aborting!\n", j); | ||
| 127 | goto abort; | 128 | goto abort; |
| 128 | } | 129 | } |
| 129 | if (zone->dev[j]) { | 130 | if (zone->dev[j]) { |
| 130 | printk("raid0: multiple devices for %d - aborting!\n", | 131 | printk(KERN_ERR "raid0: multiple devices for %d - " |
| 131 | j); | 132 | "aborting!\n", j); |
| 132 | goto abort; | 133 | goto abort; |
| 133 | } | 134 | } |
| 134 | zone->dev[j] = rdev1; | 135 | zone->dev[j] = rdev1; |
| @@ -149,16 +150,16 @@ static int create_strip_zones (mddev_t *mddev) | |||
| 149 | cnt++; | 150 | cnt++; |
| 150 | } | 151 | } |
| 151 | if (cnt != mddev->raid_disks) { | 152 | if (cnt != mddev->raid_disks) { |
| 152 | printk("raid0: too few disks (%d of %d) - aborting!\n", | 153 | printk(KERN_ERR "raid0: too few disks (%d of %d) - " |
| 153 | cnt, mddev->raid_disks); | 154 | "aborting!\n", cnt, mddev->raid_disks); |
| 154 | goto abort; | 155 | goto abort; |
| 155 | } | 156 | } |
| 156 | zone->nb_dev = cnt; | 157 | zone->nb_dev = cnt; |
| 157 | zone->size = smallest->size * cnt; | 158 | zone->sectors = smallest->size * cnt * 2; |
| 158 | zone->zone_offset = 0; | 159 | zone->zone_start = 0; |
| 159 | 160 | ||
| 160 | current_offset = smallest->size; | 161 | current_start = smallest->size * 2; |
| 161 | curr_zone_offset = zone->size; | 162 | curr_zone_start = zone->sectors; |
| 162 | 163 | ||
| 163 | /* now do the other zones */ | 164 | /* now do the other zones */ |
| 164 | for (i = 1; i < conf->nr_strip_zones; i++) | 165 | for (i = 1; i < conf->nr_strip_zones; i++) |
| @@ -166,40 +167,41 @@ static int create_strip_zones (mddev_t *mddev) | |||
| 166 | zone = conf->strip_zone + i; | 167 | zone = conf->strip_zone + i; |
| 167 | zone->dev = conf->strip_zone[i-1].dev + mddev->raid_disks; | 168 | zone->dev = conf->strip_zone[i-1].dev + mddev->raid_disks; |
| 168 | 169 | ||
| 169 | printk("raid0: zone %d\n", i); | 170 | printk(KERN_INFO "raid0: zone %d\n", i); |
| 170 | zone->dev_offset = current_offset; | 171 | zone->dev_start = current_start; |
| 171 | smallest = NULL; | 172 | smallest = NULL; |
| 172 | c = 0; | 173 | c = 0; |
| 173 | 174 | ||
| 174 | for (j=0; j<cnt; j++) { | 175 | for (j=0; j<cnt; j++) { |
| 175 | char b[BDEVNAME_SIZE]; | 176 | char b[BDEVNAME_SIZE]; |
| 176 | rdev = conf->strip_zone[0].dev[j]; | 177 | rdev = conf->strip_zone[0].dev[j]; |
| 177 | printk("raid0: checking %s ...", bdevname(rdev->bdev,b)); | 178 | printk(KERN_INFO "raid0: checking %s ...", |
| 178 | if (rdev->size > current_offset) | 179 | bdevname(rdev->bdev, b)); |
| 179 | { | 180 | if (rdev->size > current_start / 2) { |
| 180 | printk(" contained as device %d\n", c); | 181 | printk(KERN_INFO " contained as device %d\n", |
| 182 | c); | ||
| 181 | zone->dev[c] = rdev; | 183 | zone->dev[c] = rdev; |
| 182 | c++; | 184 | c++; |
| 183 | if (!smallest || (rdev->size <smallest->size)) { | 185 | if (!smallest || (rdev->size <smallest->size)) { |
| 184 | smallest = rdev; | 186 | smallest = rdev; |
| 185 | printk(" (%llu) is smallest!.\n", | 187 | printk(KERN_INFO " (%llu) is smallest!.\n", |
| 186 | (unsigned long long)rdev->size); | 188 | (unsigned long long)rdev->size); |
| 187 | } | 189 | } |
| 188 | } else | 190 | } else |
| 189 | printk(" nope.\n"); | 191 | printk(KERN_INFO " nope.\n"); |
| 190 | } | 192 | } |
| 191 | 193 | ||
| 192 | zone->nb_dev = c; | 194 | zone->nb_dev = c; |
| 193 | zone->size = (smallest->size - current_offset) * c; | 195 | zone->sectors = (smallest->size * 2 - current_start) * c; |
| 194 | printk("raid0: zone->nb_dev: %d, size: %llu\n", | 196 | printk(KERN_INFO "raid0: zone->nb_dev: %d, sectors: %llu\n", |
| 195 | zone->nb_dev, (unsigned long long)zone->size); | 197 | zone->nb_dev, (unsigned long long)zone->sectors); |
| 196 | 198 | ||
| 197 | zone->zone_offset = curr_zone_offset; | 199 | zone->zone_start = curr_zone_start; |
| 198 | curr_zone_offset += zone->size; | 200 | curr_zone_start += zone->sectors; |
| 199 | 201 | ||
| 200 | current_offset = smallest->size; | 202 | current_start = smallest->size * 2; |
| 201 | printk("raid0: current zone offset: %llu\n", | 203 | printk(KERN_INFO "raid0: current zone start: %llu\n", |
| 202 | (unsigned long long)current_offset); | 204 | (unsigned long long)current_start); |
| 203 | } | 205 | } |
| 204 | 206 | ||
| 205 | /* Now find appropriate hash spacing. | 207 | /* Now find appropriate hash spacing. |
| @@ -210,16 +212,16 @@ static int create_strip_zones (mddev_t *mddev) | |||
| 210 | * strip though as it's size has no bearing on the efficacy of the hash | 212 | * strip though as it's size has no bearing on the efficacy of the hash |
| 211 | * table. | 213 | * table. |
| 212 | */ | 214 | */ |
| 213 | conf->hash_spacing = curr_zone_offset; | 215 | conf->spacing = curr_zone_start; |
| 214 | min_spacing = curr_zone_offset; | 216 | min_spacing = curr_zone_start; |
| 215 | sector_div(min_spacing, PAGE_SIZE/sizeof(struct strip_zone*)); | 217 | sector_div(min_spacing, PAGE_SIZE/sizeof(struct strip_zone*)); |
| 216 | for (i=0; i < conf->nr_strip_zones-1; i++) { | 218 | for (i=0; i < conf->nr_strip_zones-1; i++) { |
| 217 | sector_t sz = 0; | 219 | sector_t s = 0; |
| 218 | for (j=i; j<conf->nr_strip_zones-1 && | 220 | for (j = i; j < conf->nr_strip_zones - 1 && |
| 219 | sz < min_spacing ; j++) | 221 | s < min_spacing; j++) |
| 220 | sz += conf->strip_zone[j].size; | 222 | s += conf->strip_zone[j].sectors; |
| 221 | if (sz >= min_spacing && sz < conf->hash_spacing) | 223 | if (s >= min_spacing && s < conf->spacing) |
| 222 | conf->hash_spacing = sz; | 224 | conf->spacing = s; |
| 223 | } | 225 | } |
| 224 | 226 | ||
| 225 | mddev->queue->unplug_fn = raid0_unplug; | 227 | mddev->queue->unplug_fn = raid0_unplug; |
| @@ -227,7 +229,7 @@ static int create_strip_zones (mddev_t *mddev) | |||
| 227 | mddev->queue->backing_dev_info.congested_fn = raid0_congested; | 229 | mddev->queue->backing_dev_info.congested_fn = raid0_congested; |
| 228 | mddev->queue->backing_dev_info.congested_data = mddev; | 230 | mddev->queue->backing_dev_info.congested_data = mddev; |
| 229 | 231 | ||
| 230 | printk("raid0: done.\n"); | 232 | printk(KERN_INFO "raid0: done.\n"); |
| 231 | return 0; | 233 | return 0; |
| 232 | abort: | 234 | abort: |
| 233 | return 1; | 235 | return 1; |
| @@ -262,10 +264,9 @@ static int raid0_mergeable_bvec(struct request_queue *q, | |||
| 262 | static int raid0_run (mddev_t *mddev) | 264 | static int raid0_run (mddev_t *mddev) |
| 263 | { | 265 | { |
| 264 | unsigned cur=0, i=0, nb_zone; | 266 | unsigned cur=0, i=0, nb_zone; |
| 265 | s64 size; | 267 | s64 sectors; |
| 266 | raid0_conf_t *conf; | 268 | raid0_conf_t *conf; |
| 267 | mdk_rdev_t *rdev; | 269 | mdk_rdev_t *rdev; |
| 268 | struct list_head *tmp; | ||
| 269 | 270 | ||
| 270 | if (mddev->chunk_size == 0) { | 271 | if (mddev->chunk_size == 0) { |
| 271 | printk(KERN_ERR "md/raid0: non-zero chunk size required.\n"); | 272 | printk(KERN_ERR "md/raid0: non-zero chunk size required.\n"); |
| @@ -291,54 +292,54 @@ static int raid0_run (mddev_t *mddev) | |||
| 291 | 292 | ||
| 292 | /* calculate array device size */ | 293 | /* calculate array device size */ |
| 293 | mddev->array_sectors = 0; | 294 | mddev->array_sectors = 0; |
| 294 | rdev_for_each(rdev, tmp, mddev) | 295 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 295 | mddev->array_sectors += rdev->size * 2; | 296 | mddev->array_sectors += rdev->size * 2; |
| 296 | 297 | ||
| 297 | printk("raid0 : md_size is %llu blocks.\n", | 298 | printk(KERN_INFO "raid0 : md_size is %llu sectors.\n", |
| 298 | (unsigned long long)mddev->array_sectors / 2); | 299 | (unsigned long long)mddev->array_sectors); |
| 299 | printk("raid0 : conf->hash_spacing is %llu blocks.\n", | 300 | printk(KERN_INFO "raid0 : conf->spacing is %llu sectors.\n", |
| 300 | (unsigned long long)conf->hash_spacing); | 301 | (unsigned long long)conf->spacing); |
| 301 | { | 302 | { |
| 302 | sector_t s = mddev->array_sectors / 2; | 303 | sector_t s = mddev->array_sectors; |
| 303 | sector_t space = conf->hash_spacing; | 304 | sector_t space = conf->spacing; |
| 304 | int round; | 305 | int round; |
| 305 | conf->preshift = 0; | 306 | conf->sector_shift = 0; |
| 306 | if (sizeof(sector_t) > sizeof(u32)) { | 307 | if (sizeof(sector_t) > sizeof(u32)) { |
| 307 | /*shift down space and s so that sector_div will work */ | 308 | /*shift down space and s so that sector_div will work */ |
| 308 | while (space > (sector_t) (~(u32)0)) { | 309 | while (space > (sector_t) (~(u32)0)) { |
| 309 | s >>= 1; | 310 | s >>= 1; |
| 310 | space >>= 1; | 311 | space >>= 1; |
| 311 | s += 1; /* force round-up */ | 312 | s += 1; /* force round-up */ |
| 312 | conf->preshift++; | 313 | conf->sector_shift++; |
| 313 | } | 314 | } |
| 314 | } | 315 | } |
| 315 | round = sector_div(s, (u32)space) ? 1 : 0; | 316 | round = sector_div(s, (u32)space) ? 1 : 0; |
| 316 | nb_zone = s + round; | 317 | nb_zone = s + round; |
| 317 | } | 318 | } |
| 318 | printk("raid0 : nb_zone is %d.\n", nb_zone); | 319 | printk(KERN_INFO "raid0 : nb_zone is %d.\n", nb_zone); |
| 319 | 320 | ||
| 320 | printk("raid0 : Allocating %Zd bytes for hash.\n", | 321 | printk(KERN_INFO "raid0 : Allocating %zu bytes for hash.\n", |
| 321 | nb_zone*sizeof(struct strip_zone*)); | 322 | nb_zone*sizeof(struct strip_zone*)); |
| 322 | conf->hash_table = kmalloc (sizeof (struct strip_zone *)*nb_zone, GFP_KERNEL); | 323 | conf->hash_table = kmalloc (sizeof (struct strip_zone *)*nb_zone, GFP_KERNEL); |
| 323 | if (!conf->hash_table) | 324 | if (!conf->hash_table) |
| 324 | goto out_free_conf; | 325 | goto out_free_conf; |
| 325 | size = conf->strip_zone[cur].size; | 326 | sectors = conf->strip_zone[cur].sectors; |
| 326 | 327 | ||
| 327 | conf->hash_table[0] = conf->strip_zone + cur; | 328 | conf->hash_table[0] = conf->strip_zone + cur; |
| 328 | for (i=1; i< nb_zone; i++) { | 329 | for (i=1; i< nb_zone; i++) { |
| 329 | while (size <= conf->hash_spacing) { | 330 | while (sectors <= conf->spacing) { |
| 330 | cur++; | 331 | cur++; |
| 331 | size += conf->strip_zone[cur].size; | 332 | sectors += conf->strip_zone[cur].sectors; |
| 332 | } | 333 | } |
| 333 | size -= conf->hash_spacing; | 334 | sectors -= conf->spacing; |
| 334 | conf->hash_table[i] = conf->strip_zone + cur; | 335 | conf->hash_table[i] = conf->strip_zone + cur; |
| 335 | } | 336 | } |
| 336 | if (conf->preshift) { | 337 | if (conf->sector_shift) { |
| 337 | conf->hash_spacing >>= conf->preshift; | 338 | conf->spacing >>= conf->sector_shift; |
| 338 | /* round hash_spacing up so when we divide by it, we | 339 | /* round spacing up so when we divide by it, we |
| 339 | * err on the side of too-low, which is safest | 340 | * err on the side of too-low, which is safest |
| 340 | */ | 341 | */ |
| 341 | conf->hash_spacing++; | 342 | conf->spacing++; |
| 342 | } | 343 | } |
| 343 | 344 | ||
| 344 | /* calculate the max read-ahead size. | 345 | /* calculate the max read-ahead size. |
| @@ -387,12 +388,12 @@ static int raid0_stop (mddev_t *mddev) | |||
| 387 | static int raid0_make_request (struct request_queue *q, struct bio *bio) | 388 | static int raid0_make_request (struct request_queue *q, struct bio *bio) |
| 388 | { | 389 | { |
| 389 | mddev_t *mddev = q->queuedata; | 390 | mddev_t *mddev = q->queuedata; |
| 390 | unsigned int sect_in_chunk, chunksize_bits, chunk_size, chunk_sects; | 391 | unsigned int sect_in_chunk, chunksect_bits, chunk_sects; |
| 391 | raid0_conf_t *conf = mddev_to_conf(mddev); | 392 | raid0_conf_t *conf = mddev_to_conf(mddev); |
| 392 | struct strip_zone *zone; | 393 | struct strip_zone *zone; |
| 393 | mdk_rdev_t *tmp_dev; | 394 | mdk_rdev_t *tmp_dev; |
| 394 | sector_t chunk; | 395 | sector_t chunk; |
| 395 | sector_t block, rsect; | 396 | sector_t sector, rsect; |
| 396 | const int rw = bio_data_dir(bio); | 397 | const int rw = bio_data_dir(bio); |
| 397 | int cpu; | 398 | int cpu; |
| 398 | 399 | ||
| @@ -407,11 +408,9 @@ static int raid0_make_request (struct request_queue *q, struct bio *bio) | |||
| 407 | bio_sectors(bio)); | 408 | bio_sectors(bio)); |
| 408 | part_stat_unlock(); | 409 | part_stat_unlock(); |
| 409 | 410 | ||
| 410 | chunk_size = mddev->chunk_size >> 10; | ||
| 411 | chunk_sects = mddev->chunk_size >> 9; | 411 | chunk_sects = mddev->chunk_size >> 9; |
| 412 | chunksize_bits = ffz(~chunk_size); | 412 | chunksect_bits = ffz(~chunk_sects); |
| 413 | block = bio->bi_sector >> 1; | 413 | sector = bio->bi_sector; |
| 414 | |||
| 415 | 414 | ||
| 416 | if (unlikely(chunk_sects < (bio->bi_sector & (chunk_sects - 1)) + (bio->bi_size >> 9))) { | 415 | if (unlikely(chunk_sects < (bio->bi_sector & (chunk_sects - 1)) + (bio->bi_size >> 9))) { |
| 417 | struct bio_pair *bp; | 416 | struct bio_pair *bp; |
| @@ -434,28 +433,27 @@ static int raid0_make_request (struct request_queue *q, struct bio *bio) | |||
| 434 | 433 | ||
| 435 | 434 | ||
| 436 | { | 435 | { |
| 437 | sector_t x = block >> conf->preshift; | 436 | sector_t x = sector >> conf->sector_shift; |
| 438 | sector_div(x, (u32)conf->hash_spacing); | 437 | sector_div(x, (u32)conf->spacing); |
| 439 | zone = conf->hash_table[x]; | 438 | zone = conf->hash_table[x]; |
| 440 | } | 439 | } |
| 441 | 440 | ||
| 442 | while (block >= (zone->zone_offset + zone->size)) | 441 | while (sector >= zone->zone_start + zone->sectors) |
| 443 | zone++; | 442 | zone++; |
| 444 | 443 | ||
| 445 | sect_in_chunk = bio->bi_sector & ((chunk_size<<1) -1); | 444 | sect_in_chunk = bio->bi_sector & (chunk_sects - 1); |
| 446 | 445 | ||
| 447 | 446 | ||
| 448 | { | 447 | { |
| 449 | sector_t x = (block - zone->zone_offset) >> chunksize_bits; | 448 | sector_t x = (sector - zone->zone_start) >> chunksect_bits; |
| 450 | 449 | ||
| 451 | sector_div(x, zone->nb_dev); | 450 | sector_div(x, zone->nb_dev); |
| 452 | chunk = x; | 451 | chunk = x; |
| 453 | 452 | ||
| 454 | x = block >> chunksize_bits; | 453 | x = sector >> chunksect_bits; |
| 455 | tmp_dev = zone->dev[sector_div(x, zone->nb_dev)]; | 454 | tmp_dev = zone->dev[sector_div(x, zone->nb_dev)]; |
| 456 | } | 455 | } |
| 457 | rsect = (((chunk << chunksize_bits) + zone->dev_offset)<<1) | 456 | rsect = (chunk << chunksect_bits) + zone->dev_start + sect_in_chunk; |
| 458 | + sect_in_chunk; | ||
| 459 | 457 | ||
| 460 | bio->bi_bdev = tmp_dev->bdev; | 458 | bio->bi_bdev = tmp_dev->bdev; |
| 461 | bio->bi_sector = rsect + tmp_dev->data_offset; | 459 | bio->bi_sector = rsect + tmp_dev->data_offset; |
| @@ -467,7 +465,7 @@ static int raid0_make_request (struct request_queue *q, struct bio *bio) | |||
| 467 | 465 | ||
| 468 | bad_map: | 466 | bad_map: |
| 469 | printk("raid0_make_request bug: can't convert block across chunks" | 467 | printk("raid0_make_request bug: can't convert block across chunks" |
| 470 | " or bigger than %dk %llu %d\n", chunk_size, | 468 | " or bigger than %dk %llu %d\n", chunk_sects / 2, |
| 471 | (unsigned long long)bio->bi_sector, bio->bi_size >> 10); | 469 | (unsigned long long)bio->bi_sector, bio->bi_size >> 10); |
| 472 | 470 | ||
| 473 | bio_io_error(bio); | 471 | bio_io_error(bio); |
| @@ -492,10 +490,10 @@ static void raid0_status (struct seq_file *seq, mddev_t *mddev) | |||
| 492 | seq_printf(seq, "%s/", bdevname( | 490 | seq_printf(seq, "%s/", bdevname( |
| 493 | conf->strip_zone[j].dev[k]->bdev,b)); | 491 | conf->strip_zone[j].dev[k]->bdev,b)); |
| 494 | 492 | ||
| 495 | seq_printf(seq, "] zo=%d do=%d s=%d\n", | 493 | seq_printf(seq, "] zs=%d ds=%d s=%d\n", |
| 496 | conf->strip_zone[j].zone_offset, | 494 | conf->strip_zone[j].zone_start, |
| 497 | conf->strip_zone[j].dev_offset, | 495 | conf->strip_zone[j].dev_start, |
| 498 | conf->strip_zone[j].size); | 496 | conf->strip_zone[j].sectors); |
| 499 | } | 497 | } |
| 500 | #endif | 498 | #endif |
| 501 | seq_printf(seq, " %dk chunks", mddev->chunk_size/1024); | 499 | seq_printf(seq, " %dk chunks", mddev->chunk_size/1024); |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 9c788e2489b1..7b4f5f7155d8 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -1016,12 +1016,16 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1016 | * else mark the drive as failed | 1016 | * else mark the drive as failed |
| 1017 | */ | 1017 | */ |
| 1018 | if (test_bit(In_sync, &rdev->flags) | 1018 | if (test_bit(In_sync, &rdev->flags) |
| 1019 | && (conf->raid_disks - mddev->degraded) == 1) | 1019 | && (conf->raid_disks - mddev->degraded) == 1) { |
| 1020 | /* | 1020 | /* |
| 1021 | * Don't fail the drive, act as though we were just a | 1021 | * Don't fail the drive, act as though we were just a |
| 1022 | * normal single drive | 1022 | * normal single drive. |
| 1023 | * However don't try a recovery from this drive as | ||
| 1024 | * it is very likely to fail. | ||
| 1023 | */ | 1025 | */ |
| 1026 | mddev->recovery_disabled = 1; | ||
| 1024 | return; | 1027 | return; |
| 1028 | } | ||
| 1025 | if (test_and_clear_bit(In_sync, &rdev->flags)) { | 1029 | if (test_and_clear_bit(In_sync, &rdev->flags)) { |
| 1026 | unsigned long flags; | 1030 | unsigned long flags; |
| 1027 | spin_lock_irqsave(&conf->device_lock, flags); | 1031 | spin_lock_irqsave(&conf->device_lock, flags); |
| @@ -1919,7 +1923,6 @@ static int run(mddev_t *mddev) | |||
| 1919 | int i, j, disk_idx; | 1923 | int i, j, disk_idx; |
| 1920 | mirror_info_t *disk; | 1924 | mirror_info_t *disk; |
| 1921 | mdk_rdev_t *rdev; | 1925 | mdk_rdev_t *rdev; |
| 1922 | struct list_head *tmp; | ||
| 1923 | 1926 | ||
| 1924 | if (mddev->level != 1) { | 1927 | if (mddev->level != 1) { |
| 1925 | printk("raid1: %s: raid level not set to mirroring (%d)\n", | 1928 | printk("raid1: %s: raid level not set to mirroring (%d)\n", |
| @@ -1964,7 +1967,7 @@ static int run(mddev_t *mddev) | |||
| 1964 | spin_lock_init(&conf->device_lock); | 1967 | spin_lock_init(&conf->device_lock); |
| 1965 | mddev->queue->queue_lock = &conf->device_lock; | 1968 | mddev->queue->queue_lock = &conf->device_lock; |
| 1966 | 1969 | ||
| 1967 | rdev_for_each(rdev, tmp, mddev) { | 1970 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 1968 | disk_idx = rdev->raid_disk; | 1971 | disk_idx = rdev->raid_disk; |
| 1969 | if (disk_idx >= mddev->raid_disks | 1972 | if (disk_idx >= mddev->raid_disks |
| 1970 | || disk_idx < 0) | 1973 | || disk_idx < 0) |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 970a96ef9b18..6736d6dff981 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -2025,7 +2025,6 @@ static int run(mddev_t *mddev) | |||
| 2025 | int i, disk_idx; | 2025 | int i, disk_idx; |
| 2026 | mirror_info_t *disk; | 2026 | mirror_info_t *disk; |
| 2027 | mdk_rdev_t *rdev; | 2027 | mdk_rdev_t *rdev; |
| 2028 | struct list_head *tmp; | ||
| 2029 | int nc, fc, fo; | 2028 | int nc, fc, fo; |
| 2030 | sector_t stride, size; | 2029 | sector_t stride, size; |
| 2031 | 2030 | ||
| @@ -2108,7 +2107,7 @@ static int run(mddev_t *mddev) | |||
| 2108 | spin_lock_init(&conf->device_lock); | 2107 | spin_lock_init(&conf->device_lock); |
| 2109 | mddev->queue->queue_lock = &conf->device_lock; | 2108 | mddev->queue->queue_lock = &conf->device_lock; |
| 2110 | 2109 | ||
| 2111 | rdev_for_each(rdev, tmp, mddev) { | 2110 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 2112 | disk_idx = rdev->raid_disk; | 2111 | disk_idx = rdev->raid_disk; |
| 2113 | if (disk_idx >= mddev->raid_disks | 2112 | if (disk_idx >= mddev->raid_disks |
| 2114 | || disk_idx < 0) | 2113 | || disk_idx < 0) |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index a36a7435edf5..a5ba080d303b 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -3998,7 +3998,6 @@ static int run(mddev_t *mddev) | |||
| 3998 | int raid_disk, memory; | 3998 | int raid_disk, memory; |
| 3999 | mdk_rdev_t *rdev; | 3999 | mdk_rdev_t *rdev; |
| 4000 | struct disk_info *disk; | 4000 | struct disk_info *disk; |
| 4001 | struct list_head *tmp; | ||
| 4002 | int working_disks = 0; | 4001 | int working_disks = 0; |
| 4003 | 4002 | ||
| 4004 | if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) { | 4003 | if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) { |
| @@ -4108,7 +4107,7 @@ static int run(mddev_t *mddev) | |||
| 4108 | 4107 | ||
| 4109 | pr_debug("raid5: run(%s) called.\n", mdname(mddev)); | 4108 | pr_debug("raid5: run(%s) called.\n", mdname(mddev)); |
| 4110 | 4109 | ||
| 4111 | rdev_for_each(rdev, tmp, mddev) { | 4110 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 4112 | raid_disk = rdev->raid_disk; | 4111 | raid_disk = rdev->raid_disk; |
| 4113 | if (raid_disk >= conf->raid_disks | 4112 | if (raid_disk >= conf->raid_disks |
| 4114 | || raid_disk < 0) | 4113 | || raid_disk < 0) |
| @@ -4533,7 +4532,6 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
| 4533 | { | 4532 | { |
| 4534 | raid5_conf_t *conf = mddev_to_conf(mddev); | 4533 | raid5_conf_t *conf = mddev_to_conf(mddev); |
| 4535 | mdk_rdev_t *rdev; | 4534 | mdk_rdev_t *rdev; |
| 4536 | struct list_head *rtmp; | ||
| 4537 | int spares = 0; | 4535 | int spares = 0; |
| 4538 | int added_devices = 0; | 4536 | int added_devices = 0; |
| 4539 | unsigned long flags; | 4537 | unsigned long flags; |
| @@ -4541,7 +4539,7 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
| 4541 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | 4539 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
| 4542 | return -EBUSY; | 4540 | return -EBUSY; |
| 4543 | 4541 | ||
| 4544 | rdev_for_each(rdev, rtmp, mddev) | 4542 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 4545 | if (rdev->raid_disk < 0 && | 4543 | if (rdev->raid_disk < 0 && |
| 4546 | !test_bit(Faulty, &rdev->flags)) | 4544 | !test_bit(Faulty, &rdev->flags)) |
| 4547 | spares++; | 4545 | spares++; |
| @@ -4563,7 +4561,7 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
| 4563 | /* Add some new drives, as many as will fit. | 4561 | /* Add some new drives, as many as will fit. |
| 4564 | * We know there are enough to make the newly sized array work. | 4562 | * We know there are enough to make the newly sized array work. |
| 4565 | */ | 4563 | */ |
| 4566 | rdev_for_each(rdev, rtmp, mddev) | 4564 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 4567 | if (rdev->raid_disk < 0 && | 4565 | if (rdev->raid_disk < 0 && |
| 4568 | !test_bit(Faulty, &rdev->flags)) { | 4566 | !test_bit(Faulty, &rdev->flags)) { |
| 4569 | if (raid5_add_disk(mddev, rdev) == 0) { | 4567 | if (raid5_add_disk(mddev, rdev) == 0) { |
