diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 86 |
1 files changed, 85 insertions, 1 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 9ecf51ee596f..a68ad8547325 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -181,7 +181,7 @@ static void mddev_put(mddev_t *mddev) | |||
181 | if (!mddev->raid_disks && list_empty(&mddev->disks)) { | 181 | if (!mddev->raid_disks && list_empty(&mddev->disks)) { |
182 | list_del(&mddev->all_mddevs); | 182 | list_del(&mddev->all_mddevs); |
183 | blk_put_queue(mddev->queue); | 183 | blk_put_queue(mddev->queue); |
184 | kfree(mddev); | 184 | kobject_unregister(&mddev->kobj); |
185 | } | 185 | } |
186 | spin_unlock(&all_mddevs_lock); | 186 | spin_unlock(&all_mddevs_lock); |
187 | } | 187 | } |
@@ -1551,6 +1551,85 @@ static void analyze_sbs(mddev_t * mddev) | |||
1551 | 1551 | ||
1552 | } | 1552 | } |
1553 | 1553 | ||
1554 | struct md_sysfs_entry { | ||
1555 | struct attribute attr; | ||
1556 | ssize_t (*show)(mddev_t *, char *); | ||
1557 | ssize_t (*store)(mddev_t *, const char *, size_t); | ||
1558 | }; | ||
1559 | |||
1560 | static ssize_t | ||
1561 | md_show_level(mddev_t *mddev, char *page) | ||
1562 | { | ||
1563 | mdk_personality_t *p = mddev->pers; | ||
1564 | if (p == NULL) | ||
1565 | return 0; | ||
1566 | if (mddev->level >= 0) | ||
1567 | return sprintf(page, "RAID-%d\n", mddev->level); | ||
1568 | else | ||
1569 | return sprintf(page, "%s\n", p->name); | ||
1570 | } | ||
1571 | |||
1572 | static struct md_sysfs_entry md_level = { | ||
1573 | .attr = {.name = "level", .mode = S_IRUGO }, | ||
1574 | .show = md_show_level, | ||
1575 | }; | ||
1576 | |||
1577 | static ssize_t | ||
1578 | md_show_rdisks(mddev_t *mddev, char *page) | ||
1579 | { | ||
1580 | return sprintf(page, "%d\n", mddev->raid_disks); | ||
1581 | } | ||
1582 | |||
1583 | static struct md_sysfs_entry md_raid_disks = { | ||
1584 | .attr = {.name = "raid_disks", .mode = S_IRUGO }, | ||
1585 | .show = md_show_rdisks, | ||
1586 | }; | ||
1587 | |||
1588 | static struct attribute *md_default_attrs[] = { | ||
1589 | &md_level.attr, | ||
1590 | &md_raid_disks.attr, | ||
1591 | NULL, | ||
1592 | }; | ||
1593 | |||
1594 | static ssize_t | ||
1595 | md_attr_show(struct kobject *kobj, struct attribute *attr, char *page) | ||
1596 | { | ||
1597 | struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr); | ||
1598 | mddev_t *mddev = container_of(kobj, struct mddev_s, kobj); | ||
1599 | |||
1600 | if (!entry->show) | ||
1601 | return -EIO; | ||
1602 | return entry->show(mddev, page); | ||
1603 | } | ||
1604 | |||
1605 | static ssize_t | ||
1606 | md_attr_store(struct kobject *kobj, struct attribute *attr, | ||
1607 | const char *page, size_t length) | ||
1608 | { | ||
1609 | struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr); | ||
1610 | mddev_t *mddev = container_of(kobj, struct mddev_s, kobj); | ||
1611 | |||
1612 | if (!entry->store) | ||
1613 | return -EIO; | ||
1614 | return entry->store(mddev, page, length); | ||
1615 | } | ||
1616 | |||
1617 | static void md_free(struct kobject *ko) | ||
1618 | { | ||
1619 | mddev_t *mddev = container_of(ko, mddev_t, kobj); | ||
1620 | kfree(mddev); | ||
1621 | } | ||
1622 | |||
1623 | static struct sysfs_ops md_sysfs_ops = { | ||
1624 | .show = md_attr_show, | ||
1625 | .store = md_attr_store, | ||
1626 | }; | ||
1627 | static struct kobj_type md_ktype = { | ||
1628 | .release = md_free, | ||
1629 | .sysfs_ops = &md_sysfs_ops, | ||
1630 | .default_attrs = md_default_attrs, | ||
1631 | }; | ||
1632 | |||
1554 | int mdp_major = 0; | 1633 | int mdp_major = 0; |
1555 | 1634 | ||
1556 | static struct kobject *md_probe(dev_t dev, int *part, void *data) | 1635 | static struct kobject *md_probe(dev_t dev, int *part, void *data) |
@@ -1592,6 +1671,11 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) | |||
1592 | add_disk(disk); | 1671 | add_disk(disk); |
1593 | mddev->gendisk = disk; | 1672 | mddev->gendisk = disk; |
1594 | up(&disks_sem); | 1673 | up(&disks_sem); |
1674 | mddev->kobj.parent = kobject_get(&disk->kobj); | ||
1675 | mddev->kobj.k_name = NULL; | ||
1676 | snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md"); | ||
1677 | mddev->kobj.ktype = &md_ktype; | ||
1678 | kobject_register(&mddev->kobj); | ||
1595 | return NULL; | 1679 | return NULL; |
1596 | } | 1680 | } |
1597 | 1681 | ||