md: use sysfs_notify_dirent to notify changes to md/array_state

Now that we have sysfs_notify_dirent, use it to notify changes
to md/array_state.
As sysfs_notify_dirent can be called in atomic context, we can
remove the delayed notify and the MD_NOTIFY_ARRAY_STATE flag.

Signed-off-by: NeilBrown <neilb@suse.de>

NeilBrown b62b7590 0cfd8103

+20 -15
+16 -14
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); ··· 2773 2770 if (err) 2774 2771 return err; 2775 2772 else { 2776 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 2773 + sysfs_notify_dirent(mddev->sysfs_state); 2777 2774 return len; 2778 2775 } 2779 2776 } ··· 3468 3465 if (error) 3469 3466 printk(KERN_WARNING "md: cannot register %s/md - name in use\n", 3470 3467 disk->disk_name); 3471 - else 3468 + else { 3472 3469 kobject_uevent(&mddev->kobj, KOBJ_ADD); 3470 + mddev->sysfs_state = sysfs_get_dirent(mddev->kobj.sd, "array_state"); 3471 + } 3473 3472 return NULL; 3474 3473 } 3475 3474 ··· 3482 3477 if (!atomic_read(&mddev->writes_pending)) { 3483 3478 mddev->safemode = 1; 3484 3479 if (mddev->external) 3485 - set_bit(MD_NOTIFY_ARRAY_STATE, &mddev->flags); 3480 + sysfs_notify_dirent(mddev->sysfs_state); 3486 3481 } 3487 3482 md_wakeup_thread(mddev->thread); 3488 3483 } ··· 3745 3740 3746 3741 mddev->changed = 1; 3747 3742 md_new_event(mddev); 3748 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 3743 + sysfs_notify_dirent(mddev->sysfs_state); 3749 3744 sysfs_notify(&mddev->kobj, NULL, "sync_action"); 3750 3745 sysfs_notify(&mddev->kobj, NULL, "degraded"); 3751 3746 kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); ··· 3772 3767 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 3773 3768 md_wakeup_thread(mddev->thread); 3774 3769 md_wakeup_thread(mddev->sync_thread); 3775 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 3770 + sysfs_notify_dirent(mddev->sysfs_state); 3776 3771 return 0; 3777 3772 } 3778 3773 ··· 3852 3847 module_put(mddev->pers->owner); 3853 3848 mddev->pers = NULL; 3854 3849 /* tell userspace to handle 'inactive' */ 3855 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 3850 + sysfs_notify_dirent(mddev->sysfs_state); 3856 3851 3857 3852 set_capacity(disk, 0); 3858 3853 mddev->changed = 1; ··· 3938 3933 mdname(mddev)); 3939 3934 err = 0; 3940 3935 md_new_event(mddev); 3941 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 3936 + sysfs_notify_dirent(mddev->sysfs_state); 3942 3937 out: 3943 3938 return err; 3944 3939 } ··· 4943 4938 if (_IOC_TYPE(cmd) == MD_MAJOR && mddev->ro && mddev->pers) { 4944 4939 if (mddev->ro == 2) { 4945 4940 mddev->ro = 0; 4946 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 4941 + sysfs_notify_dirent(mddev->sysfs_state); 4947 4942 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 4948 4943 md_wakeup_thread(mddev->thread); 4949 4944 } else { ··· 5617 5612 spin_unlock_irq(&mddev->write_lock); 5618 5613 } 5619 5614 if (did_change) 5620 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 5615 + sysfs_notify_dirent(mddev->sysfs_state); 5621 5616 wait_event(mddev->sb_wait, 5622 5617 !test_bit(MD_CHANGE_CLEAN, &mddev->flags) && 5623 5618 !test_bit(MD_CHANGE_PENDING, &mddev->flags)); ··· 5660 5655 mddev->safemode = 1; 5661 5656 spin_unlock_irq(&mddev->write_lock); 5662 5657 md_update_sb(mddev, 0); 5663 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 5658 + sysfs_notify_dirent(mddev->sysfs_state); 5664 5659 } else 5665 5660 spin_unlock_irq(&mddev->write_lock); 5666 5661 ··· 6053 6048 if (mddev->bitmap) 6054 6049 bitmap_daemon_work(mddev->bitmap); 6055 6050 6056 - if (test_and_clear_bit(MD_NOTIFY_ARRAY_STATE, &mddev->flags)) 6057 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 6058 - 6059 6051 if (mddev->ro) 6060 6052 return; 6061 6053 ··· 6105 6103 mddev->safemode = 0; 6106 6104 spin_unlock_irq(&mddev->write_lock); 6107 6105 if (did_change) 6108 - sysfs_notify(&mddev->kobj, NULL, "array_state"); 6106 + sysfs_notify_dirent(mddev->sysfs_state); 6109 6107 } 6110 6108 6111 6109 if (mddev->flags)
+4 -1
include/linux/raid/md_k.h
··· 128 128 #define MD_CHANGE_DEVS 0 /* Some device status has changed */ 129 129 #define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */ 130 130 #define MD_CHANGE_PENDING 2 /* superblock update in progress */ 131 - #define MD_NOTIFY_ARRAY_STATE 3 /* atomic context wants to notify userspace */ 132 131 133 132 int ro; 134 133 ··· 237 238 * starts here */ 238 239 sector_t resync_max; /* resync should pause 239 240 * when it gets here */ 241 + 242 + struct sysfs_dirent *sysfs_state; /* handle for 'array_state' 243 + * file in sysfs. 244 + */ 240 245 241 246 spinlock_t write_lock; 242 247 wait_queue_head_t sb_wait; /* for waiting on superblock updates */