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 | |
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.
-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 | ||||
-rw-r--r-- | fs/block_dev.c | 14 | ||||
-rw-r--r-- | include/linux/raid/md_k.h | 20 | ||||
-rw-r--r-- | include/linux/raid/md_p.h | 2 | ||||
-rw-r--r-- | include/linux/raid/raid0.h | 10 |
13 files changed, 435 insertions, 247 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) { |
diff --git a/fs/block_dev.c b/fs/block_dev.c index b957717e25ab..8ebbfdf708c2 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -1005,6 +1005,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1005 | } | 1005 | } |
1006 | 1006 | ||
1007 | lock_kernel(); | 1007 | lock_kernel(); |
1008 | restart: | ||
1008 | 1009 | ||
1009 | ret = -ENXIO; | 1010 | ret = -ENXIO; |
1010 | disk = get_gendisk(bdev->bd_dev, &partno); | 1011 | disk = get_gendisk(bdev->bd_dev, &partno); |
@@ -1025,6 +1026,19 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
1025 | 1026 | ||
1026 | if (disk->fops->open) { | 1027 | if (disk->fops->open) { |
1027 | ret = disk->fops->open(bdev, mode); | 1028 | ret = disk->fops->open(bdev, mode); |
1029 | if (ret == -ERESTARTSYS) { | ||
1030 | /* Lost a race with 'disk' being | ||
1031 | * deleted, try again. | ||
1032 | * See md.c | ||
1033 | */ | ||
1034 | disk_put_part(bdev->bd_part); | ||
1035 | bdev->bd_part = NULL; | ||
1036 | module_put(disk->fops->owner); | ||
1037 | put_disk(disk); | ||
1038 | bdev->bd_disk = NULL; | ||
1039 | mutex_unlock(&bdev->bd_mutex); | ||
1040 | goto restart; | ||
1041 | } | ||
1028 | if (ret) | 1042 | if (ret) |
1029 | goto out_clear; | 1043 | goto out_clear; |
1030 | } | 1044 | } |
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 8fc909ef6787..9743e4dbc918 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h | |||
@@ -137,6 +137,9 @@ struct mddev_s | |||
137 | struct gendisk *gendisk; | 137 | struct gendisk *gendisk; |
138 | 138 | ||
139 | struct kobject kobj; | 139 | struct kobject kobj; |
140 | int hold_active; | ||
141 | #define UNTIL_IOCTL 1 | ||
142 | #define UNTIL_STOP 2 | ||
140 | 143 | ||
141 | /* Superblock information */ | 144 | /* Superblock information */ |
142 | int major_version, | 145 | int major_version, |
@@ -215,6 +218,9 @@ struct mddev_s | |||
215 | #define MD_RECOVERY_FROZEN 9 | 218 | #define MD_RECOVERY_FROZEN 9 |
216 | 219 | ||
217 | unsigned long recovery; | 220 | unsigned long recovery; |
221 | int recovery_disabled; /* if we detect that recovery | ||
222 | * will always fail, set this | ||
223 | * so we don't loop trying */ | ||
218 | 224 | ||
219 | int in_sync; /* know to not need resync */ | 225 | int in_sync; /* know to not need resync */ |
220 | struct mutex reconfig_mutex; | 226 | struct mutex reconfig_mutex; |
@@ -244,6 +250,9 @@ struct mddev_s | |||
244 | struct sysfs_dirent *sysfs_state; /* handle for 'array_state' | 250 | struct sysfs_dirent *sysfs_state; /* handle for 'array_state' |
245 | * file in sysfs. | 251 | * file in sysfs. |
246 | */ | 252 | */ |
253 | struct sysfs_dirent *sysfs_action; /* handle for 'sync_action' */ | ||
254 | |||
255 | struct work_struct del_work; /* used for delayed sysfs removal */ | ||
247 | 256 | ||
248 | spinlock_t write_lock; | 257 | spinlock_t write_lock; |
249 | wait_queue_head_t sb_wait; /* for waiting on superblock updates */ | 258 | wait_queue_head_t sb_wait; /* for waiting on superblock updates */ |
@@ -334,17 +343,14 @@ static inline char * mdname (mddev_t * mddev) | |||
334 | * iterates through some rdev ringlist. It's safe to remove the | 343 | * iterates through some rdev ringlist. It's safe to remove the |
335 | * current 'rdev'. Dont touch 'tmp' though. | 344 | * current 'rdev'. Dont touch 'tmp' though. |
336 | */ | 345 | */ |
337 | #define rdev_for_each_list(rdev, tmp, list) \ | 346 | #define rdev_for_each_list(rdev, tmp, head) \ |
338 | \ | 347 | list_for_each_entry_safe(rdev, tmp, head, same_set) |
339 | for ((tmp) = (list).next; \ | 348 | |
340 | (rdev) = (list_entry((tmp), mdk_rdev_t, same_set)), \ | ||
341 | (tmp) = (tmp)->next, (tmp)->prev != &(list) \ | ||
342 | ; ) | ||
343 | /* | 349 | /* |
344 | * iterates through the 'same array disks' ringlist | 350 | * iterates through the 'same array disks' ringlist |
345 | */ | 351 | */ |
346 | #define rdev_for_each(rdev, tmp, mddev) \ | 352 | #define rdev_for_each(rdev, tmp, mddev) \ |
347 | rdev_for_each_list(rdev, tmp, (mddev)->disks) | 353 | list_for_each_entry_safe(rdev, tmp, &((mddev)->disks), same_set) |
348 | 354 | ||
349 | #define rdev_for_each_rcu(rdev, mddev) \ | 355 | #define rdev_for_each_rcu(rdev, mddev) \ |
350 | list_for_each_entry_rcu(rdev, &((mddev)->disks), same_set) | 356 | list_for_each_entry_rcu(rdev, &((mddev)->disks), same_set) |
diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h index 8b4de4a41ff1..9491026afe66 100644 --- a/include/linux/raid/md_p.h +++ b/include/linux/raid/md_p.h | |||
@@ -194,6 +194,8 @@ static inline __u64 md_event(mdp_super_t *sb) { | |||
194 | return (ev<<32)| sb->events_lo; | 194 | return (ev<<32)| sb->events_lo; |
195 | } | 195 | } |
196 | 196 | ||
197 | #define MD_SUPERBLOCK_1_TIME_SEC_MASK ((1ULL<<40) - 1) | ||
198 | |||
197 | /* | 199 | /* |
198 | * The version-1 superblock : | 200 | * The version-1 superblock : |
199 | * All numeric fields are little-endian. | 201 | * All numeric fields are little-endian. |
diff --git a/include/linux/raid/raid0.h b/include/linux/raid/raid0.h index 1b2dda035f8e..fd42aa87c391 100644 --- a/include/linux/raid/raid0.h +++ b/include/linux/raid/raid0.h | |||
@@ -5,9 +5,9 @@ | |||
5 | 5 | ||
6 | struct strip_zone | 6 | struct strip_zone |
7 | { | 7 | { |
8 | sector_t zone_offset; /* Zone offset in md_dev */ | 8 | sector_t zone_start; /* Zone offset in md_dev (in sectors) */ |
9 | sector_t dev_offset; /* Zone offset in real dev */ | 9 | sector_t dev_start; /* Zone offset in real dev (in sectors) */ |
10 | sector_t size; /* Zone size */ | 10 | sector_t sectors; /* Zone size in sectors */ |
11 | int nb_dev; /* # of devices attached to the zone */ | 11 | int nb_dev; /* # of devices attached to the zone */ |
12 | mdk_rdev_t **dev; /* Devices attached to the zone */ | 12 | mdk_rdev_t **dev; /* Devices attached to the zone */ |
13 | }; | 13 | }; |
@@ -19,8 +19,8 @@ struct raid0_private_data | |||
19 | mdk_rdev_t **devlist; /* lists of rdevs, pointed to by strip_zone->dev */ | 19 | mdk_rdev_t **devlist; /* lists of rdevs, pointed to by strip_zone->dev */ |
20 | int nr_strip_zones; | 20 | int nr_strip_zones; |
21 | 21 | ||
22 | sector_t hash_spacing; | 22 | sector_t spacing; |
23 | int preshift; /* shift this before divide by hash_spacing */ | 23 | int sector_shift; /* shift this before divide by spacing */ |
24 | }; | 24 | }; |
25 | 25 | ||
26 | typedef struct raid0_private_data raid0_conf_t; | 26 | typedef struct raid0_private_data raid0_conf_t; |