diff options
Diffstat (limited to 'drivers/md/md.c')
| -rw-r--r-- | drivers/md/md.c | 63 | 
1 files changed, 23 insertions, 40 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 927a43db5dfb..8e344b4b3444 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -78,7 +78,7 @@  static LIST_HEAD(pers_list);  static DEFINE_SPINLOCK(pers_lock); -static struct kobj_type md_ktype; +static const struct kobj_type md_ktype;  struct md_cluster_operations *md_cluster_ops;  EXPORT_SYMBOL(md_cluster_ops); @@ -322,26 +322,6 @@ static struct ctl_table raid_table[] = {  	{ }  }; -static struct ctl_table raid_dir_table[] = { -	{ -		.procname	= "raid", -		.maxlen		= 0, -		.mode		= S_IRUGO|S_IXUGO, -		.child		= raid_table, -	}, -	{ } -}; - -static struct ctl_table raid_root_table[] = { -	{ -		.procname	= "dev", -		.maxlen		= 0, -		.mode		= 0555, -		.child		= raid_dir_table, -	}, -	{  } -}; -  static int start_readonly;  /* @@ -3128,6 +3108,9 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len)  		err = kstrtouint(buf, 10, (unsigned int *)&slot);  		if (err < 0)  			return err; +		if (slot < 0) +			/* overflow */ +			return -ENOSPC;  	}  	if (rdev->mddev->pers && slot == -1) {  		/* Setting 'slot' on an active array requires also @@ -3597,7 +3580,7 @@ static const struct sysfs_ops rdev_sysfs_ops = {  	.show		= rdev_attr_show,  	.store		= rdev_attr_store,  }; -static struct kobj_type rdev_ktype = { +static const struct kobj_type rdev_ktype = {  	.release	= rdev_free,  	.sysfs_ops	= &rdev_sysfs_ops,  	.default_groups	= rdev_default_groups, @@ -5555,7 +5538,7 @@ static const struct sysfs_ops md_sysfs_ops = {  	.show	= md_attr_show,  	.store	= md_attr_store,  }; -static struct kobj_type md_ktype = { +static const struct kobj_type md_ktype = {  	.release	= md_kobj_release,  	.sysfs_ops	= &md_sysfs_ops,  	.default_groups	= md_attr_groups, @@ -6256,6 +6239,10 @@ static void __md_stop(struct mddev *mddev)  		mddev->to_remove = &md_redundancy_group;  	module_put(pers->owner);  	clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); + +	percpu_ref_exit(&mddev->active_io); +	bioset_exit(&mddev->bio_set); +	bioset_exit(&mddev->sync_set);  }  void md_stop(struct mddev *mddev) @@ -6266,9 +6253,6 @@ void md_stop(struct mddev *mddev)  	__md_stop_writes(mddev);  	__md_stop(mddev);  	percpu_ref_exit(&mddev->writes_pending); -	percpu_ref_exit(&mddev->active_io); -	bioset_exit(&mddev->bio_set); -	bioset_exit(&mddev->sync_set);  }  EXPORT_SYMBOL_GPL(md_stop); @@ -7840,10 +7824,6 @@ static void md_free_disk(struct gendisk *disk)  	struct mddev *mddev = disk->private_data;  	percpu_ref_exit(&mddev->writes_pending); -	percpu_ref_exit(&mddev->active_io); -	bioset_exit(&mddev->bio_set); -	bioset_exit(&mddev->sync_set); -  	mddev_free(mddev);  } @@ -7974,6 +7954,9 @@ void md_error(struct mddev *mddev, struct md_rdev *rdev)  		return;  	mddev->pers->error_handler(mddev, rdev); +	if (mddev->pers->level == 0 || mddev->pers->level == LEVEL_LINEAR) +		return; +  	if (mddev->degraded && !test_bit(MD_BROKEN, &mddev->flags))  		set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);  	sysfs_notify_dirent_safe(rdev->sysfs_state); @@ -8029,16 +8012,16 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev)  	} else if (resync > max_sectors) {  		resync = max_sectors;  	} else { -		resync -= atomic_read(&mddev->recovery_active); -		if (resync < MD_RESYNC_ACTIVE) { -			/* -			 * Resync has started, but the subtraction has -			 * yielded one of the special values. Force it -			 * to active to ensure the status reports an -			 * active resync. -			 */ +		res = atomic_read(&mddev->recovery_active); +		/* +		 * Resync has started, but the subtraction has overflowed or +		 * yielded one of the special values. Force it to active to +		 * ensure the status reports an active resync. +		 */ +		if (resync < res || resync - res < MD_RESYNC_ACTIVE)  			resync = MD_RESYNC_ACTIVE; -		} +		else +			resync -= res;  	}  	if (resync == MD_RESYNC_NONE) { @@ -9650,7 +9633,7 @@ static int __init md_init(void)  	mdp_major = ret;  	register_reboot_notifier(&md_notifier); -	raid_table_header = register_sysctl_table(raid_root_table); +	raid_table_header = register_sysctl("dev/raid", raid_table);  	md_geninit();  	return 0;  |