md: use sysfs_notify_dirent to notify changes to md/dev-xxx/state

The 'state' file for a device reports, for example, when the device
has failed. Changes should be reported to userspace ASAP without
the possibility of blocking on low-memory. sysfs_notify does
have that possibility (as it takes a mutex which can be held
across a kmalloc) so use sysfs_notify_dirent instead.

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

NeilBrown 3c0ee63a b62b7590

+15 -9
+12 -9
drivers/md/md.c
··· 1462 1462 kobject_del(&rdev->kobj); 1463 1463 goto fail; 1464 1464 } 1465 + rdev->sysfs_state = sysfs_get_dirent(rdev->kobj.sd, "state"); 1466 + 1465 1467 list_add_rcu(&rdev->same_set, &mddev->disks); 1466 1468 bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); 1467 1469 return 0; ··· 1493 1491 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); 1494 1492 rdev->mddev = NULL; 1495 1493 sysfs_remove_link(&rdev->kobj, "block"); 1496 - 1494 + sysfs_put(rdev->sysfs_state); 1495 + rdev->sysfs_state = NULL; 1497 1496 /* We need to delay this, otherwise we can deadlock when 1498 1497 * writing to 'remove' to "dev/state". We also need 1499 1498 * to delay it due to rcu usage. ··· 1929 1926 1930 1927 err = 0; 1931 1928 } 1932 - if (!err) 1933 - sysfs_notify(&rdev->kobj, NULL, "state"); 1929 + if (!err && rdev->sysfs_state) 1930 + sysfs_notify_dirent(rdev->sysfs_state); 1934 1931 return err ? err : len; 1935 1932 } 1936 1933 static struct rdev_sysfs_entry rdev_state = ··· 2025 2022 rdev->raid_disk = -1; 2026 2023 return err; 2027 2024 } else 2028 - sysfs_notify(&rdev->kobj, NULL, "state"); 2025 + sysfs_notify_dirent(rdev->sysfs_state); 2029 2026 sprintf(nm, "rd%d", rdev->raid_disk); 2030 2027 if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm)) 2031 2028 printk(KERN_WARNING ··· 2042 2039 clear_bit(Faulty, &rdev->flags); 2043 2040 clear_bit(WriteMostly, &rdev->flags); 2044 2041 set_bit(In_sync, &rdev->flags); 2045 - sysfs_notify(&rdev->kobj, NULL, "state"); 2042 + sysfs_notify_dirent(rdev->sysfs_state); 2046 2043 } 2047 2044 return len; 2048 2045 } ··· 3586 3583 return -EINVAL; 3587 3584 } 3588 3585 } 3589 - sysfs_notify(&rdev->kobj, NULL, "state"); 3586 + sysfs_notify_dirent(rdev->sysfs_state); 3590 3587 } 3591 3588 3592 3589 md_probe(mddev->unit, NULL, NULL); ··· 4305 4302 if (err) 4306 4303 export_rdev(rdev); 4307 4304 else 4308 - sysfs_notify(&rdev->kobj, NULL, "state"); 4305 + sysfs_notify_dirent(rdev->sysfs_state); 4309 4306 4310 4307 md_update_sb(mddev, 1); 4311 4308 if (mddev->degraded) ··· 6116 6113 6117 6114 rdev_for_each(rdev, rtmp, mddev) 6118 6115 if (test_and_clear_bit(StateChanged, &rdev->flags)) 6119 - sysfs_notify(&rdev->kobj, NULL, "state"); 6116 + sysfs_notify_dirent(rdev->sysfs_state); 6120 6117 6121 6118 6122 6119 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && ··· 6226 6223 6227 6224 void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev) 6228 6225 { 6229 - sysfs_notify(&rdev->kobj, NULL, "state"); 6226 + sysfs_notify_dirent(rdev->sysfs_state); 6230 6227 wait_event_timeout(rdev->blocked_wait, 6231 6228 !test_bit(Blocked, &rdev->flags), 6232 6229 msecs_to_jiffies(5000));
+3
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