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