xref: /linux/fs/configfs/file.c (revision 762f99f4f3cb41a775b5157dd761217beba65873)
1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /*
3   * file.c - operations for regular (text) files.
4   *
5   * Based on sysfs:
6   * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
7   *
8   * configfs Copyright (C) 2005 Oracle.  All rights reserved.
9   */
10  
11  #include <linux/fs.h>
12  #include <linux/module.h>
13  #include <linux/slab.h>
14  #include <linux/mutex.h>
15  #include <linux/vmalloc.h>
16  #include <linux/uaccess.h>
17  #include <linux/uio.h>
18  #include <linux/configfs.h>
19  #include "configfs_internal.h"
20  
21  /*
22   * A simple attribute can only be 4096 characters.  Why 4k?  Because the
23   * original code limited it to PAGE_SIZE.  That's a bad idea, though,
24   * because an attribute of 16k on ia64 won't work on x86.  So we limit to
25   * 4k, our minimum common page size.
26   */
27  #define SIMPLE_ATTR_SIZE 4096
28  
29  struct configfs_buffer {
30  	size_t			count;
31  	loff_t			pos;
32  	char			* page;
33  	struct configfs_item_operations	* ops;
34  	struct mutex		mutex;
35  	int			needs_read_fill;
36  	bool			read_in_progress;
37  	bool			write_in_progress;
38  	char			*bin_buffer;
39  	int			bin_buffer_size;
40  	int			cb_max_size;
41  	struct config_item	*item;
42  	struct module		*owner;
43  	union {
44  		struct configfs_attribute	*attr;
45  		struct configfs_bin_attribute	*bin_attr;
46  	};
47  };
48  
to_frag(struct file * file)49  static inline struct configfs_fragment *to_frag(struct file *file)
50  {
51  	struct configfs_dirent *sd = file->f_path.dentry->d_fsdata;
52  
53  	return sd->s_frag;
54  }
55  
fill_read_buffer(struct file * file,struct configfs_buffer * buffer)56  static int fill_read_buffer(struct file *file, struct configfs_buffer *buffer)
57  {
58  	struct configfs_fragment *frag = to_frag(file);
59  	ssize_t count = -ENOENT;
60  
61  	if (!buffer->page)
62  		buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
63  	if (!buffer->page)
64  		return -ENOMEM;
65  
66  	down_read(&frag->frag_sem);
67  	if (!frag->frag_dead)
68  		count = buffer->attr->show(buffer->item, buffer->page);
69  	up_read(&frag->frag_sem);
70  
71  	if (count < 0)
72  		return count;
73  	if (WARN_ON_ONCE(count > (ssize_t)SIMPLE_ATTR_SIZE))
74  		return -EIO;
75  	buffer->needs_read_fill = 0;
76  	buffer->count = count;
77  	return 0;
78  }
79  
configfs_read_iter(struct kiocb * iocb,struct iov_iter * to)80  static ssize_t configfs_read_iter(struct kiocb *iocb, struct iov_iter *to)
81  {
82  	struct file *file = iocb->ki_filp;
83  	struct configfs_buffer *buffer = file->private_data;
84  	ssize_t retval = 0;
85  
86  	mutex_lock(&buffer->mutex);
87  	if (buffer->needs_read_fill) {
88  		retval = fill_read_buffer(file, buffer);
89  		if (retval)
90  			goto out;
91  	}
92  	pr_debug("%s: count = %zd, pos = %lld, buf = %s\n",
93  		 __func__, iov_iter_count(to), iocb->ki_pos, buffer->page);
94  	if (iocb->ki_pos >= buffer->count)
95  		goto out;
96  	retval = copy_to_iter(buffer->page + iocb->ki_pos,
97  			      buffer->count - iocb->ki_pos, to);
98  	iocb->ki_pos += retval;
99  	if (retval == 0)
100  		retval = -EFAULT;
101  out:
102  	mutex_unlock(&buffer->mutex);
103  	return retval;
104  }
105  
configfs_bin_read_iter(struct kiocb * iocb,struct iov_iter * to)106  static ssize_t configfs_bin_read_iter(struct kiocb *iocb, struct iov_iter *to)
107  {
108  	struct file *file = iocb->ki_filp;
109  	struct configfs_fragment *frag = to_frag(file);
110  	struct configfs_buffer *buffer = file->private_data;
111  	ssize_t retval = 0;
112  	ssize_t len;
113  
114  	mutex_lock(&buffer->mutex);
115  
116  	/* we don't support switching read/write modes */
117  	if (buffer->write_in_progress) {
118  		retval = -ETXTBSY;
119  		goto out;
120  	}
121  	buffer->read_in_progress = true;
122  
123  	if (buffer->needs_read_fill) {
124  		/* perform first read with buf == NULL to get extent */
125  		down_read(&frag->frag_sem);
126  		if (!frag->frag_dead)
127  			len = buffer->bin_attr->read(buffer->item, NULL, 0);
128  		else
129  			len = -ENOENT;
130  		up_read(&frag->frag_sem);
131  		if (len <= 0) {
132  			retval = len;
133  			goto out;
134  		}
135  
136  		/* do not exceed the maximum value */
137  		if (buffer->cb_max_size && len > buffer->cb_max_size) {
138  			retval = -EFBIG;
139  			goto out;
140  		}
141  
142  		buffer->bin_buffer = vmalloc(len);
143  		if (buffer->bin_buffer == NULL) {
144  			retval = -ENOMEM;
145  			goto out;
146  		}
147  		buffer->bin_buffer_size = len;
148  
149  		/* perform second read to fill buffer */
150  		down_read(&frag->frag_sem);
151  		if (!frag->frag_dead)
152  			len = buffer->bin_attr->read(buffer->item,
153  						     buffer->bin_buffer, len);
154  		else
155  			len = -ENOENT;
156  		up_read(&frag->frag_sem);
157  		if (len < 0) {
158  			retval = len;
159  			vfree(buffer->bin_buffer);
160  			buffer->bin_buffer_size = 0;
161  			buffer->bin_buffer = NULL;
162  			goto out;
163  		}
164  
165  		buffer->needs_read_fill = 0;
166  	}
167  
168  	if (iocb->ki_pos >= buffer->bin_buffer_size)
169  		goto out;
170  	retval = copy_to_iter(buffer->bin_buffer + iocb->ki_pos,
171  			      buffer->bin_buffer_size - iocb->ki_pos, to);
172  	iocb->ki_pos += retval;
173  	if (retval == 0)
174  		retval = -EFAULT;
175  out:
176  	mutex_unlock(&buffer->mutex);
177  	return retval;
178  }
179  
180  /* Fill @buffer with data coming from @from. */
fill_write_buffer(struct configfs_buffer * buffer,struct iov_iter * from)181  static int fill_write_buffer(struct configfs_buffer *buffer,
182  			     struct iov_iter *from)
183  {
184  	int copied;
185  
186  	if (!buffer->page)
187  		buffer->page = (char *)__get_free_pages(GFP_KERNEL, 0);
188  	if (!buffer->page)
189  		return -ENOMEM;
190  
191  	copied = copy_from_iter(buffer->page, SIMPLE_ATTR_SIZE - 1, from);
192  	buffer->needs_read_fill = 1;
193  	/* if buf is assumed to contain a string, terminate it by \0,
194  	 * so e.g. sscanf() can scan the string easily */
195  	buffer->page[copied] = 0;
196  	return copied ? : -EFAULT;
197  }
198  
199  static int
flush_write_buffer(struct file * file,struct configfs_buffer * buffer,size_t count)200  flush_write_buffer(struct file *file, struct configfs_buffer *buffer, size_t count)
201  {
202  	struct configfs_fragment *frag = to_frag(file);
203  	int res = -ENOENT;
204  
205  	down_read(&frag->frag_sem);
206  	if (!frag->frag_dead)
207  		res = buffer->attr->store(buffer->item, buffer->page, count);
208  	up_read(&frag->frag_sem);
209  	return res;
210  }
211  
212  
213  /*
214   * There is no easy way for us to know if userspace is only doing a partial
215   * write, so we don't support them. We expect the entire buffer to come on the
216   * first write.
217   * Hint: if you're writing a value, first read the file, modify only the value
218   * you're changing, then write entire buffer back.
219   */
configfs_write_iter(struct kiocb * iocb,struct iov_iter * from)220  static ssize_t configfs_write_iter(struct kiocb *iocb, struct iov_iter *from)
221  {
222  	struct file *file = iocb->ki_filp;
223  	struct configfs_buffer *buffer = file->private_data;
224  	int len;
225  
226  	mutex_lock(&buffer->mutex);
227  	len = fill_write_buffer(buffer, from);
228  	if (len > 0)
229  		len = flush_write_buffer(file, buffer, len);
230  	if (len > 0)
231  		iocb->ki_pos += len;
232  	mutex_unlock(&buffer->mutex);
233  	return len;
234  }
235  
configfs_bin_write_iter(struct kiocb * iocb,struct iov_iter * from)236  static ssize_t configfs_bin_write_iter(struct kiocb *iocb,
237  				       struct iov_iter *from)
238  {
239  	struct file *file = iocb->ki_filp;
240  	struct configfs_buffer *buffer = file->private_data;
241  	void *tbuf = NULL;
242  	size_t end_offset;
243  	ssize_t len;
244  
245  	mutex_lock(&buffer->mutex);
246  
247  	/* we don't support switching read/write modes */
248  	if (buffer->read_in_progress) {
249  		len = -ETXTBSY;
250  		goto out;
251  	}
252  	buffer->write_in_progress = true;
253  
254  	/* buffer grows? */
255  	end_offset = iocb->ki_pos + iov_iter_count(from);
256  	if (end_offset > buffer->bin_buffer_size) {
257  		if (buffer->cb_max_size && end_offset > buffer->cb_max_size) {
258  			len = -EFBIG;
259  			goto out;
260  		}
261  
262  		tbuf = vmalloc(end_offset);
263  		if (tbuf == NULL) {
264  			len = -ENOMEM;
265  			goto out;
266  		}
267  
268  		/* copy old contents */
269  		if (buffer->bin_buffer) {
270  			memcpy(tbuf, buffer->bin_buffer,
271  				buffer->bin_buffer_size);
272  			vfree(buffer->bin_buffer);
273  		}
274  
275  		/* clear the new area */
276  		memset(tbuf + buffer->bin_buffer_size, 0,
277  			end_offset - buffer->bin_buffer_size);
278  		buffer->bin_buffer = tbuf;
279  		buffer->bin_buffer_size = end_offset;
280  	}
281  
282  	len = copy_from_iter(buffer->bin_buffer + iocb->ki_pos,
283  			     buffer->bin_buffer_size - iocb->ki_pos, from);
284  	iocb->ki_pos += len;
285  out:
286  	mutex_unlock(&buffer->mutex);
287  	return len ? : -EFAULT;
288  }
289  
__configfs_open_file(struct inode * inode,struct file * file,int type)290  static int __configfs_open_file(struct inode *inode, struct file *file, int type)
291  {
292  	struct dentry *dentry = file->f_path.dentry;
293  	struct configfs_fragment *frag = to_frag(file);
294  	struct configfs_attribute *attr;
295  	struct configfs_buffer *buffer;
296  	int error;
297  
298  	error = -ENOMEM;
299  	buffer = kzalloc(sizeof(struct configfs_buffer), GFP_KERNEL);
300  	if (!buffer)
301  		goto out;
302  
303  	error = -ENOENT;
304  	down_read(&frag->frag_sem);
305  	if (unlikely(frag->frag_dead))
306  		goto out_free_buffer;
307  
308  	error = -EINVAL;
309  	buffer->item = to_item(dentry->d_parent);
310  	if (!buffer->item)
311  		goto out_free_buffer;
312  
313  	attr = to_attr(dentry);
314  	if (!attr)
315  		goto out_free_buffer;
316  
317  	if (type & CONFIGFS_ITEM_BIN_ATTR) {
318  		buffer->bin_attr = to_bin_attr(dentry);
319  		buffer->cb_max_size = buffer->bin_attr->cb_max_size;
320  	} else {
321  		buffer->attr = attr;
322  	}
323  
324  	buffer->owner = attr->ca_owner;
325  	/* Grab the module reference for this attribute if we have one */
326  	error = -ENODEV;
327  	if (!try_module_get(buffer->owner))
328  		goto out_free_buffer;
329  
330  	error = -EACCES;
331  	if (!buffer->item->ci_type)
332  		goto out_put_module;
333  
334  	buffer->ops = buffer->item->ci_type->ct_item_ops;
335  
336  	/* File needs write support.
337  	 * The inode's perms must say it's ok,
338  	 * and we must have a store method.
339  	 */
340  	if (file->f_mode & FMODE_WRITE) {
341  		if (!(inode->i_mode & S_IWUGO))
342  			goto out_put_module;
343  		if ((type & CONFIGFS_ITEM_ATTR) && !attr->store)
344  			goto out_put_module;
345  		if ((type & CONFIGFS_ITEM_BIN_ATTR) && !buffer->bin_attr->write)
346  			goto out_put_module;
347  	}
348  
349  	/* File needs read support.
350  	 * The inode's perms must say it's ok, and we there
351  	 * must be a show method for it.
352  	 */
353  	if (file->f_mode & FMODE_READ) {
354  		if (!(inode->i_mode & S_IRUGO))
355  			goto out_put_module;
356  		if ((type & CONFIGFS_ITEM_ATTR) && !attr->show)
357  			goto out_put_module;
358  		if ((type & CONFIGFS_ITEM_BIN_ATTR) && !buffer->bin_attr->read)
359  			goto out_put_module;
360  	}
361  
362  	mutex_init(&buffer->mutex);
363  	buffer->needs_read_fill = 1;
364  	buffer->read_in_progress = false;
365  	buffer->write_in_progress = false;
366  	file->private_data = buffer;
367  	up_read(&frag->frag_sem);
368  	return 0;
369  
370  out_put_module:
371  	module_put(buffer->owner);
372  out_free_buffer:
373  	up_read(&frag->frag_sem);
374  	kfree(buffer);
375  out:
376  	return error;
377  }
378  
configfs_release(struct inode * inode,struct file * filp)379  static int configfs_release(struct inode *inode, struct file *filp)
380  {
381  	struct configfs_buffer *buffer = filp->private_data;
382  
383  	module_put(buffer->owner);
384  	if (buffer->page)
385  		free_page((unsigned long)buffer->page);
386  	mutex_destroy(&buffer->mutex);
387  	kfree(buffer);
388  	return 0;
389  }
390  
configfs_open_file(struct inode * inode,struct file * filp)391  static int configfs_open_file(struct inode *inode, struct file *filp)
392  {
393  	return __configfs_open_file(inode, filp, CONFIGFS_ITEM_ATTR);
394  }
395  
configfs_open_bin_file(struct inode * inode,struct file * filp)396  static int configfs_open_bin_file(struct inode *inode, struct file *filp)
397  {
398  	return __configfs_open_file(inode, filp, CONFIGFS_ITEM_BIN_ATTR);
399  }
400  
configfs_release_bin_file(struct inode * inode,struct file * file)401  static int configfs_release_bin_file(struct inode *inode, struct file *file)
402  {
403  	struct configfs_buffer *buffer = file->private_data;
404  
405  	if (buffer->write_in_progress) {
406  		struct configfs_fragment *frag = to_frag(file);
407  
408  		down_read(&frag->frag_sem);
409  		if (!frag->frag_dead) {
410  			/* result of ->release() is ignored */
411  			buffer->bin_attr->write(buffer->item,
412  					buffer->bin_buffer,
413  					buffer->bin_buffer_size);
414  		}
415  		up_read(&frag->frag_sem);
416  	}
417  
418  	vfree(buffer->bin_buffer);
419  
420  	configfs_release(inode, file);
421  	return 0;
422  }
423  
424  
425  const struct file_operations configfs_file_operations = {
426  	.read_iter	= configfs_read_iter,
427  	.write_iter	= configfs_write_iter,
428  	.llseek		= generic_file_llseek,
429  	.open		= configfs_open_file,
430  	.release	= configfs_release,
431  };
432  
433  const struct file_operations configfs_bin_file_operations = {
434  	.read_iter	= configfs_bin_read_iter,
435  	.write_iter	= configfs_bin_write_iter,
436  	.llseek		= NULL,		/* bin file is not seekable */
437  	.open		= configfs_open_bin_file,
438  	.release	= configfs_release_bin_file,
439  };
440  
441  /**
442   *	configfs_create_file - create an attribute file for an item.
443   *	@item:	item we're creating for.
444   *	@attr:	atrribute descriptor.
445   */
446  
configfs_create_file(struct config_item * item,const struct configfs_attribute * attr)447  int configfs_create_file(struct config_item * item, const struct configfs_attribute * attr)
448  {
449  	struct dentry *dir = item->ci_dentry;
450  	struct configfs_dirent *parent_sd = dir->d_fsdata;
451  	umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG;
452  	int error = 0;
453  
454  	inode_lock_nested(d_inode(dir), I_MUTEX_NORMAL);
455  	error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode,
456  				     CONFIGFS_ITEM_ATTR, parent_sd->s_frag);
457  	inode_unlock(d_inode(dir));
458  
459  	return error;
460  }
461  
462  /**
463   *	configfs_create_bin_file - create a binary attribute file for an item.
464   *	@item:	item we're creating for.
465   *	@bin_attr: atrribute descriptor.
466   */
467  
configfs_create_bin_file(struct config_item * item,const struct configfs_bin_attribute * bin_attr)468  int configfs_create_bin_file(struct config_item *item,
469  		const struct configfs_bin_attribute *bin_attr)
470  {
471  	struct dentry *dir = item->ci_dentry;
472  	struct configfs_dirent *parent_sd = dir->d_fsdata;
473  	umode_t mode = (bin_attr->cb_attr.ca_mode & S_IALLUGO) | S_IFREG;
474  	int error = 0;
475  
476  	inode_lock_nested(dir->d_inode, I_MUTEX_NORMAL);
477  	error = configfs_make_dirent(parent_sd, NULL, (void *) bin_attr, mode,
478  				     CONFIGFS_ITEM_BIN_ATTR, parent_sd->s_frag);
479  	inode_unlock(dir->d_inode);
480  
481  	return error;
482  }
483