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/md.c | |
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/md.c')
-rw-r--r-- | drivers/md/md.c | 416 |
1 files changed, 293 insertions, 123 deletions
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); |