dm ioctl: allow message to return data
This patch introduces enhanced message support that allows the device-mapper core to recognise messages that are common to all devices, and for messages to return data to userspace. Core messages are processed by the function "message_for_md". If the device mapper doesn't support the message, it is passed to the target driver. If the message returns data, the kernel sets the flag DM_MESSAGE_OUT_FLAG. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
This commit is contained in:
		
					parent
					
						
							
								02cde50b7e
							
						
					
				
			
			
				commit
				
					
						a26062416e
					
				
			
		
					 2 changed files with 40 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -1414,6 +1414,22 @@ static int table_status(struct dm_ioctl *param, size_t param_size)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool buffer_test_overflow(char *result, unsigned maxlen)
 | 
			
		||||
{
 | 
			
		||||
	return !maxlen || strlen(result) + 1 >= maxlen;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Process device-mapper dependent messages.
 | 
			
		||||
 * Returns a number <= 1 if message was processed by device mapper.
 | 
			
		||||
 * Returns 2 if message should be delivered to the target.
 | 
			
		||||
 */
 | 
			
		||||
static int message_for_md(struct mapped_device *md, unsigned argc, char **argv,
 | 
			
		||||
			  char *result, unsigned maxlen)
 | 
			
		||||
{
 | 
			
		||||
	return 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Pass a message to the target that's at the supplied device offset.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -1425,6 +1441,8 @@ static int target_message(struct dm_ioctl *param, size_t param_size)
 | 
			
		|||
	struct dm_table *table;
 | 
			
		||||
	struct dm_target *ti;
 | 
			
		||||
	struct dm_target_msg *tmsg = (void *) param + param->data_start;
 | 
			
		||||
	size_t maxlen;
 | 
			
		||||
	char *result = get_result_buffer(param, param_size, &maxlen);
 | 
			
		||||
 | 
			
		||||
	md = find_device(param);
 | 
			
		||||
	if (!md)
 | 
			
		||||
| 
						 | 
				
			
			@ -1448,6 +1466,10 @@ static int target_message(struct dm_ioctl *param, size_t param_size)
 | 
			
		|||
		goto out_argv;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r = message_for_md(md, argc, argv, result, maxlen);
 | 
			
		||||
	if (r <= 1)
 | 
			
		||||
		goto out_argv;
 | 
			
		||||
 | 
			
		||||
	table = dm_get_live_table(md);
 | 
			
		||||
	if (!table)
 | 
			
		||||
		goto out_argv;
 | 
			
		||||
| 
						 | 
				
			
			@ -1473,7 +1495,18 @@ static int target_message(struct dm_ioctl *param, size_t param_size)
 | 
			
		|||
 out_argv:
 | 
			
		||||
	kfree(argv);
 | 
			
		||||
 out:
 | 
			
		||||
	param->data_size = 0;
 | 
			
		||||
	if (r >= 0)
 | 
			
		||||
		__dev_status(md, param);
 | 
			
		||||
 | 
			
		||||
	if (r == 1) {
 | 
			
		||||
		param->flags |= DM_DATA_OUT_FLAG;
 | 
			
		||||
		if (buffer_test_overflow(result, maxlen))
 | 
			
		||||
			param->flags |= DM_BUFFER_FULL_FLAG;
 | 
			
		||||
		else
 | 
			
		||||
			param->data_size = param->data_start + strlen(result) + 1;
 | 
			
		||||
		r = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dm_put(md);
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1653,6 +1686,7 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
 | 
			
		|||
	param->flags &= ~DM_BUFFER_FULL_FLAG;
 | 
			
		||||
	param->flags &= ~DM_UEVENT_GENERATED_FLAG;
 | 
			
		||||
	param->flags &= ~DM_SECURE_DATA_FLAG;
 | 
			
		||||
	param->flags &= ~DM_DATA_OUT_FLAG;
 | 
			
		||||
 | 
			
		||||
	/* Ignores parameters */
 | 
			
		||||
	if (cmd == DM_REMOVE_ALL_CMD ||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -336,4 +336,9 @@ enum {
 | 
			
		|||
 */
 | 
			
		||||
#define DM_SECURE_DATA_FLAG		(1 << 15) /* In */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * If set, a message generated output data.
 | 
			
		||||
 */
 | 
			
		||||
#define DM_DATA_OUT_FLAG		(1 << 16) /* Out */
 | 
			
		||||
 | 
			
		||||
#endif				/* _LINUX_DM_IOCTL_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue