diff options
Diffstat (limited to 'fs/debugfs/file.c')
| -rw-r--r-- | fs/debugfs/file.c | 74 | 
1 files changed, 26 insertions, 48 deletions
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 2340f6978d6..c5ca6ae5a30 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -526,73 +526,51 @@ struct array_data {  	u32 elements;  }; -static int u32_array_open(struct inode *inode, struct file *file) -{ -	file->private_data = NULL; -	return nonseekable_open(inode, file); -} - -static size_t format_array(char *buf, size_t bufsize, const char *fmt, -			   u32 *array, u32 array_size) +static size_t u32_format_array(char *buf, size_t bufsize, +			       u32 *array, int array_size)  {  	size_t ret = 0; -	u32 i; -	for (i = 0; i < array_size; i++) { +	while (--array_size >= 0) {  		size_t len; +		char term = array_size ? ' ' : '\n'; -		len = snprintf(buf, bufsize, fmt, array[i]); -		len++;	/* ' ' or '\n' */ +		len = snprintf(buf, bufsize, "%u%c", *array++, term);  		ret += len; -		if (buf) { -			buf += len; -			bufsize -= len; -			buf[-1] = (i == array_size-1) ? '\n' : ' '; -		} +		buf += len; +		bufsize -= len;  	} - -	ret++;		/* \0 */ -	if (buf) -		*buf = '\0'; -  	return ret;  } -static char *format_array_alloc(const char *fmt, u32 *array, -						u32 array_size) +static int u32_array_open(struct inode *inode, struct file *file)  { -	size_t len = format_array(NULL, 0, fmt, array, array_size); -	char *ret; +	struct array_data *data = inode->i_private; +	int size, elements = data->elements; +	char *buf; -	ret = kmalloc(len, GFP_KERNEL); -	if (ret == NULL) -		return NULL; +	/* +	 * Max size: +	 *  - 10 digits + ' '/'\n' = 11 bytes per number +	 *  - terminating NUL character +	 */ +	size = elements*11; +	buf = kmalloc(size+1, GFP_KERNEL); +	if (!buf) +		return -ENOMEM; +	buf[size] = 0; -	format_array(ret, len, fmt, array, array_size); -	return ret; +	file->private_data = buf; +	u32_format_array(buf, size, data->array, data->elements); + +	return nonseekable_open(inode, file);  }  static ssize_t u32_array_read(struct file *file, char __user *buf, size_t len,  			      loff_t *ppos)  { -	struct inode *inode = file->f_path.dentry->d_inode; -	struct array_data *data = inode->i_private; -	size_t size; - -	if (*ppos == 0) { -		if (file->private_data) { -			kfree(file->private_data); -			file->private_data = NULL; -		} - -		file->private_data = format_array_alloc("%u", data->array, -							      data->elements); -	} - -	size = 0; -	if (file->private_data) -		size = strlen(file->private_data); +	size_t size = strlen(file->private_data);  	return simple_read_from_buffer(buf, len, ppos,  					file->private_data, size);  |