diff options
| author | Junxiao Bi <junxiao.bi@oracle.com> | 2020-08-04 17:27:18 -0700 | 
|---|---|---|
| committer | Song Liu <songliubraving@fb.com> | 2020-08-05 16:07:39 -0700 | 
| commit | e8efa9b88e3c20a20ff34bb33e2e94bf6896016a (patch) | |
| tree | 0e5e30b21f188bbe322080f7fa266b91b4a9ebad | |
| parent | f59589fc89665102923725e80e12f782d5f74f67 (diff) | |
md: get sysfs entry after redundancy attr group create
"sync_completed" and "degraded" belongs to redundancy attr group,
it was not exist yet when md device was created.
Reported-by: kernel test robot <rong.a.chen@intel.com>
Fixes: e1a86dbbbd6a ("md: fix deadlock causing by sysfs_notify")
Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com>
Signed-off-by: Song Liu <songliubraving@fb.com>
| -rw-r--r-- | drivers/md/md.c | 17 | 
1 files changed, 10 insertions, 7 deletions
| diff --git a/drivers/md/md.c b/drivers/md/md.c index 9c69084cae73..6b511c9007d3 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -876,7 +876,13 @@ void mddev_unlock(struct mddev *mddev)  				sysfs_remove_group(&mddev->kobj, &md_redundancy_group);  				if (mddev->sysfs_action)  					sysfs_put(mddev->sysfs_action); +				if (mddev->sysfs_completed) +					sysfs_put(mddev->sysfs_completed); +				if (mddev->sysfs_degraded) +					sysfs_put(mddev->sysfs_degraded);  				mddev->sysfs_action = NULL; +				mddev->sysfs_completed = NULL; +				mddev->sysfs_degraded = NULL;  			}  		}  		mddev->sysfs_active = 0; @@ -4094,6 +4100,8 @@ level_store(struct mddev *mddev, const char *buf, size_t len)  			pr_warn("md: cannot register extra attributes for %s\n",  				mdname(mddev));  		mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, "sync_action"); +		mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed"); +		mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded");  	}  	if (oldpers->sync_request != NULL &&  	    pers->sync_request == NULL) { @@ -5609,14 +5617,9 @@ static void md_free(struct kobject *ko)  	if (mddev->sysfs_state)  		sysfs_put(mddev->sysfs_state); -	if (mddev->sysfs_completed) -		sysfs_put(mddev->sysfs_completed); -	if (mddev->sysfs_degraded) -		sysfs_put(mddev->sysfs_degraded);  	if (mddev->sysfs_level)  		sysfs_put(mddev->sysfs_level); -  	if (mddev->gendisk)  		del_gendisk(mddev->gendisk);  	if (mddev->queue) @@ -5783,8 +5786,6 @@ static int md_alloc(dev_t dev, char *name)  	if (!error && mddev->kobj.sd) {  		kobject_uevent(&mddev->kobj, KOBJ_ADD);  		mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state"); -		mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed"); -		mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded");  		mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level");  	}  	mddev_put(mddev); @@ -6064,6 +6065,8 @@ int md_run(struct mddev *mddev)  			pr_warn("md: cannot register extra attributes for %s\n",  				mdname(mddev));  		mddev->sysfs_action = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_action"); +		mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed"); +		mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded");  	} else if (mddev->ro == 2) /* auto-readonly not meaningful */  		mddev->ro = 0; | 
