Merge branch 'for-linus' of git://neil.brown.name/md

* 'for-linus' of git://neil.brown.name/md:
md: allow extended partitions on md devices.
md: use sysfs_notify_dirent to notify changes to md/dev-xxx/state
md: use sysfs_notify_dirent to notify changes to md/array_state

+40 -24
+33 -23
drivers/md/md.c
··· 222 222 list_del(&mddev->all_mddevs); 223 223 spin_unlock(&all_mddevs_lock); 224 224 blk_cleanup_queue(mddev->queue); 225 + if (mddev->sysfs_state) 226 + sysfs_put(mddev->sysfs_state); 227 + mddev->sysfs_state = NULL; 225 228 kobject_put(&mddev->kobj); 226 229 } else 227 230 spin_unlock(&all_mddevs_lock); ··· 1462 1459 kobject_del(&rdev->kobj); 1463 1460 goto fail; 1464 1461 } 1462 + rdev->sysfs_state = sysfs_get_dirent(rdev->kobj.sd, "state"); 1463 + 1465 1464 list_add_rcu(&rdev->same_set, &mddev->disks); 1466 1465 bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); 1467 1466 return 0; ··· 1493 1488 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); 1494 1489 rdev->mddev = NULL; 1495 1490 sysfs_remove_link(&rdev->kobj, "block"); 1496 - 1491 + sysfs_put(rdev->sysfs_state); 1492 + rdev->sysfs_state = NULL; 1497 1493 /* We need to delay this, otherwise we can deadlock when 1498 1494 * writing to 'remove' to "dev/state". We also need 1499 1495 * to delay it due to rcu usage. ··· 1929 1923 1930 1924 err = 0; 1931 1925 } 1932 - if (!err) 1933 - sysfs_notify(&rdev->kobj, NULL, "state"); 1926 + if (!err && rdev->sysfs_state) 1927 + sysfs_notify_dirent(rdev->sysfs_state); 1934 1928 return err ? err : len; 1935 1929 } 1936 1930 static struct rdev_sysfs_entry rdev_state = ··· 2025 2019 rdev->raid_disk = -1; 2026 2020 return err; 2027 2021 } else 2028 - sysfs_notify(&rdev->kobj, NULL, "state"); 2022 + sysfs_notify_dirent(rdev->sysfs_state); 2029 2023 sprintf(nm, "rd%d", rdev->raid_disk); 2030 2024 if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm)) 2031 2025 printk(KERN_WARNING ··· 2042 2036 clear_bit(Faulty, &rdev->flags); 2043 2037 clear_bit(WriteMostly, &rdev->flags); 2044 2038 set_bit(In_sync, &rdev->flags); 2045 - sysfs_notify(&rdev->kobj, NULL, "state"); 2039 + sysfs_notify_dirent(rdev->sysfs_state); 2046 2040 } 2047 2041 return len; 2048 2042 } ··· 2776 2770 if (err) 2777 2771 return err; 2778 2772 else { 2779 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 2773 + sysfs_notify_dirent(mddev->sysfs_state); 2780 2774 return len; 2781 2775 } 2782 2776 } ··· 3463 3457 disk->fops = &md_fops; 3464 3458 disk->private_data = mddev; 3465 3459 disk->queue = mddev->queue; 3460 + /* Allow extended partitions. This makes the 3461 + * 'mdp' device redundant, but we can really 3462 + * remove it now. 3463 + */ 3464 + disk->flags |= GENHD_FL_EXT_DEVT; 3466 3465 add_disk(disk); 3467 3466 mddev->gendisk = disk; 3468 3467 error = kobject_init_and_add(&mddev->kobj, &md_ktype, ··· 3476 3465 if (error) 3477 3466 printk(KERN_WARNING "md: cannot register %s/md - name in use\n", 3478 3467 disk->disk_name); 3479 - else 3468 + else { 3480 3469 kobject_uevent(&mddev->kobj, KOBJ_ADD); 3470 + mddev->sysfs_state = sysfs_get_dirent(mddev->kobj.sd, "array_state"); 3471 + } 3481 3472 return NULL; 3482 3473 } 3483 3474 ··· 3490 3477 if (!atomic_read(&mddev->writes_pending)) { 3491 3478 mddev->safemode = 1; 3492 3479 if (mddev->external) 3493 - set_bit(MD_NOTIFY_ARRAY_STATE, &mddev->flags); 3480 + sysfs_notify_dirent(mddev->sysfs_state); 3494 3481 } 3495 3482 md_wakeup_thread(mddev->thread); 3496 3483 } ··· 3591 3578 return -EINVAL; 3592 3579 } 3593 3580 } 3594 - sysfs_notify(&rdev->kobj, NULL, "state"); 3581 + sysfs_notify_dirent(rdev->sysfs_state); 3595 3582 } 3596 3583 3597 3584 md_probe(mddev->unit, NULL, NULL); ··· 3753 3740 3754 3741 mddev->changed = 1; 3755 3742 md_new_event(mddev); 3756 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 3743 + sysfs_notify_dirent(mddev->sysfs_state); 3757 3744 sysfs_notify(&mddev->kobj, NULL, "sync_action"); 3758 3745 sysfs_notify(&mddev->kobj, NULL, "degraded"); 3759 3746 kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); ··· 3780 3767 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 3781 3768 md_wakeup_thread(mddev->thread); 3782 3769 md_wakeup_thread(mddev->sync_thread); 3783 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 3770 + sysfs_notify_dirent(mddev->sysfs_state); 3784 3771 return 0; 3785 3772 } 3786 3773 ··· 3860 3847 module_put(mddev->pers->owner); 3861 3848 mddev->pers = NULL; 3862 3849 /* tell userspace to handle 'inactive' */ 3863 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 3850 + sysfs_notify_dirent(mddev->sysfs_state); 3864 3851 3865 3852 set_capacity(disk, 0); 3866 3853 mddev->changed = 1; ··· 3946 3933 mdname(mddev)); 3947 3934 err = 0; 3948 3935 md_new_event(mddev); 3949 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 3936 + sysfs_notify_dirent(mddev->sysfs_state); 3950 3937 out: 3951 3938 return err; 3952 3939 } ··· 4310 4297 if (err) 4311 4298 export_rdev(rdev); 4312 4299 else 4313 - sysfs_notify(&rdev->kobj, NULL, "state"); 4300 + sysfs_notify_dirent(rdev->sysfs_state); 4314 4301 4315 4302 md_update_sb(mddev, 1); 4316 4303 if (mddev->degraded) ··· 4951 4938 if (_IOC_TYPE(cmd) == MD_MAJOR && mddev->ro && mddev->pers) { 4952 4939 if (mddev->ro == 2) { 4953 4940 mddev->ro = 0; 4954 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 4941 + sysfs_notify_dirent(mddev->sysfs_state); 4955 4942 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 4956 4943 md_wakeup_thread(mddev->thread); 4957 4944 } else { ··· 5625 5612 spin_unlock_irq(&mddev->write_lock); 5626 5613 } 5627 5614 if (did_change) 5628 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 5615 + sysfs_notify_dirent(mddev->sysfs_state); 5629 5616 wait_event(mddev->sb_wait, 5630 5617 !test_bit(MD_CHANGE_CLEAN, &mddev->flags) && 5631 5618 !test_bit(MD_CHANGE_PENDING, &mddev->flags)); ··· 5668 5655 mddev->safemode = 1; 5669 5656 spin_unlock_irq(&mddev->write_lock); 5670 5657 md_update_sb(mddev, 0); 5671 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 5658 + sysfs_notify_dirent(mddev->sysfs_state); 5672 5659 } else 5673 5660 spin_unlock_irq(&mddev->write_lock); 5674 5661 ··· 6061 6048 if (mddev->bitmap) 6062 6049 bitmap_daemon_work(mddev->bitmap); 6063 6050 6064 - if (test_and_clear_bit(MD_NOTIFY_ARRAY_STATE, &mddev->flags)) 6065 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 6066 - 6067 6051 if (mddev->ro) 6068 6052 return; 6069 6053 ··· 6113 6103 mddev->safemode = 0; 6114 6104 spin_unlock_irq(&mddev->write_lock); 6115 6105 if (did_change) 6116 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 6106 + sysfs_notify_dirent(mddev->sysfs_state); 6117 6107 } 6118 6108 6119 6109 if (mddev->flags) ··· 6121 6111 6122 6112 rdev_for_each(rdev, rtmp, mddev) 6123 6113 if (test_and_clear_bit(StateChanged, &rdev->flags)) 6124 - sysfs_notify(&rdev->kobj, NULL, "state"); 6114 + sysfs_notify_dirent(rdev->sysfs_state); 6125 6115 6126 6116 6127 6117 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && ··· 6231 6221 6232 6222 void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev) 6233 6223 { 6234 - sysfs_notify(&rdev->kobj, NULL, "state"); 6224 + sysfs_notify_dirent(rdev->sysfs_state); 6235 6225 wait_event_timeout(rdev->blocked_wait, 6236 6226 !test_bit(Blocked, &rdev->flags), 6237 6227 msecs_to_jiffies(5000));
+7 -1
include/linux/raid/md_k.h
··· 115 115 * in superblock. 116 116 */ 117 117 struct work_struct del_work; /* used for delayed sysfs removal */ 118 + 119 + struct sysfs_dirent *sysfs_state; /* handle for 'state' 120 + * sysfs entry */ 118 121 }; 119 122 120 123 struct mddev_s ··· 131 128 #define MD_CHANGE_DEVS 0 /* Some device status has changed */ 132 129 #define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */ 133 130 #define MD_CHANGE_PENDING 2 /* superblock update in progress */ 134 - #define MD_NOTIFY_ARRAY_STATE 3 /* atomic context wants to notify userspace */ 135 131 136 132 int ro; 137 133 ··· 240 238 * starts here */ 241 239 sector_t resync_max; /* resync should pause 242 240 * when it gets here */ 241 + 242 + struct sysfs_dirent *sysfs_state; /* handle for 'array_state' 243 + * file in sysfs. 244 + */ 243 245 244 246 spinlock_t write_lock; 245 247 wait_queue_head_t sb_wait; /* for waiting on superblock updates */