diff options
Diffstat (limited to 'drivers/md')
| -rw-r--r-- | drivers/md/dm-log-userspace-base.c | 35 | 
1 files changed, 32 insertions, 3 deletions
diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c index 3c27978890b..8db3862dade 100644 --- a/drivers/md/dm-log-userspace-base.c +++ b/drivers/md/dm-log-userspace-base.c @@ -30,6 +30,7 @@ struct flush_entry {  struct log_c {  	struct dm_target *ti; +	struct dm_dev *log_dev;  	uint32_t region_size;  	region_t region_count;  	uint64_t luid; @@ -161,13 +162,15 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,  	struct log_c *lc = NULL;  	uint64_t rdata;  	size_t rdata_size = sizeof(rdata); +	char *devices_rdata = NULL; +	size_t devices_rdata_size = DM_NAME_LEN;  	if (argc < 3) {  		DMWARN("Too few arguments to userspace dirty log");  		return -EINVAL;  	} -	lc = kmalloc(sizeof(*lc), GFP_KERNEL); +	lc = kzalloc(sizeof(*lc), GFP_KERNEL);  	if (!lc) {  		DMWARN("Unable to allocate userspace log context.");  		return -ENOMEM; @@ -195,9 +198,19 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,  		return str_size;  	} -	/* Send table string */ +	devices_rdata = kzalloc(devices_rdata_size, GFP_KERNEL); +	if (!devices_rdata) { +		DMERR("Failed to allocate memory for device information"); +		r = -ENOMEM; +		goto out; +	} + +	/* +	 * Send table string and get back any opened device. +	 */  	r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_CTR, -				 ctr_str, str_size, NULL, NULL); +				 ctr_str, str_size, +				 devices_rdata, &devices_rdata_size);  	if (r < 0) {  		if (r == -ESRCH) @@ -220,7 +233,20 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,  	lc->region_size = (uint32_t)rdata;  	lc->region_count = dm_sector_div_up(ti->len, lc->region_size); +	if (devices_rdata_size) { +		if (devices_rdata[devices_rdata_size - 1] != '\0') { +			DMERR("DM_ULOG_CTR device return string not properly terminated"); +			r = -EINVAL; +			goto out; +		} +		r = dm_get_device(ti, devices_rdata, +				  dm_table_get_mode(ti->table), &lc->log_dev); +		if (r) +			DMERR("Failed to register %s with device-mapper", +			      devices_rdata); +	}  out: +	kfree(devices_rdata);  	if (r) {  		kfree(lc);  		kfree(ctr_str); @@ -241,6 +267,9 @@ static void userspace_dtr(struct dm_dirty_log *log)  				 NULL, 0,  				 NULL, NULL); +	if (lc->log_dev) +		dm_put_device(lc->ti, lc->log_dev); +  	kfree(lc->usr_argv_str);  	kfree(lc);  |