Line data Source code
1 : /* -*- mode: c; c-basic-offset: 8; -*-
2 : * vim: noexpandtab sw=8 ts=8 sts=0:
3 : *
4 : * file.c - operations for regular (text) files.
5 : *
6 : * This program is free software; you can redistribute it and/or
7 : * modify it under the terms of the GNU General Public
8 : * License as published by the Free Software Foundation; either
9 : * version 2 of the License, or (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public
17 : * License along with this program; if not, write to the
18 : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 : * Boston, MA 021110-1307, USA.
20 : *
21 : * Based on sysfs:
22 : * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
23 : *
24 : * configfs Copyright (C) 2005 Oracle. All rights reserved.
25 : */
26 :
27 : #include <linux/fs.h>
28 : #include <linux/module.h>
29 : #include <linux/slab.h>
30 : #include <linux/mutex.h>
31 : #include <asm/uaccess.h>
32 :
33 : #include <linux/configfs.h>
34 : #include "configfs_internal.h"
35 :
36 : /*
37 : * A simple attribute can only be 4096 characters. Why 4k? Because the
38 : * original code limited it to PAGE_SIZE. That's a bad idea, though,
39 : * because an attribute of 16k on ia64 won't work on x86. So we limit to
40 : * 4k, our minimum common page size.
41 : */
42 : #define SIMPLE_ATTR_SIZE 4096
43 :
44 : struct configfs_buffer {
45 : size_t count;
46 : loff_t pos;
47 : char * page;
48 : struct configfs_item_operations * ops;
49 : struct mutex mutex;
50 : int needs_read_fill;
51 : };
52 :
53 :
54 : /**
55 : * fill_read_buffer - allocate and fill buffer from item.
56 : * @dentry: dentry pointer.
57 : * @buffer: data buffer for file.
58 : *
59 : * Allocate @buffer->page, if it hasn't been already, then call the
60 : * config_item's show() method to fill the buffer with this attribute's
61 : * data.
62 : * This is called only once, on the file's first read.
63 : */
64 : static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buffer)
65 : {
66 4 : struct configfs_attribute * attr = to_attr(dentry);
67 4 : struct config_item * item = to_item(dentry->d_parent);
68 2 : struct configfs_item_operations * ops = buffer->ops;
69 2 : int ret = 0;
70 1 : ssize_t count;
71 1 :
72 4 : if (!buffer->page)
73 3 : buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
74 4 : if (!buffer->page)
75 1 : return -ENOMEM;
76 :
77 1 : count = ops->show_attribute(item,attr,buffer->page);
78 1 : buffer->needs_read_fill = 0;
79 6 : BUG_ON(count > (ssize_t)SIMPLE_ATTR_SIZE);
80 2 : if (count >= 0)
81 1 : buffer->count = count;
82 : else
83 1 : ret = count;
84 1 : return ret;
85 : }
86 :
87 : /**
88 : * configfs_read_file - read an attribute.
89 : * @file: file pointer.
90 : * @buf: buffer to fill.
91 : * @count: number of bytes to read.
92 : * @ppos: starting offset in file.
93 : *
94 : * Userspace wants to read an attribute file. The attribute descriptor
95 : * is in the file's ->d_fsdata. The target item is in the directory's
96 : * ->d_fsdata.
97 : *
98 : * We call fill_read_buffer() to allocate and fill the buffer from the
99 : * item's show() method exactly once (if the read is happening from
100 : * the beginning of the file). That should fill the entire buffer with
101 : * all the data the item has to offer for that attribute.
102 : * We then call flush_read_buffer() to copy the buffer to userspace
103 : * in the increments specified.
104 : */
105 :
106 : static ssize_t
107 : configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
108 : {
109 3 : struct configfs_buffer * buffer = file->private_data;
110 2 : ssize_t retval = 0;
111 1 :
112 1 : mutex_lock(&buffer->mutex);
113 2 : if (buffer->needs_read_fill) {
114 6 : if ((retval = fill_read_buffer(file->f_path.dentry,buffer)))
115 1 : goto out;
116 : }
117 : pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
118 : __func__, count, *ppos, buffer->page);
119 4 : retval = simple_read_from_buffer(buf, count, ppos, buffer->page,
120 : buffer->count);
121 : out:
122 4 : mutex_unlock(&buffer->mutex);
123 2 : return retval;
124 : }
125 :
126 :
127 : /**
128 : * fill_write_buffer - copy buffer from userspace.
129 : * @buffer: data buffer for file.
130 : * @buf: data from user.
131 : * @count: number of bytes in @userbuf.
132 : *
133 : * Allocate @buffer->page if it hasn't been already, then
134 : * copy the user-supplied buffer into it.
135 : */
136 :
137 : static int
138 : fill_write_buffer(struct configfs_buffer * buffer, const char __user * buf, size_t count)
139 : {
140 : int error;
141 1 :
142 4 : if (!buffer->page)
143 3 : buffer->page = (char *)__get_free_pages(GFP_KERNEL, 0);
144 3 : if (!buffer->page)
145 1 : return -ENOMEM;
146 :
147 2 : if (count >= SIMPLE_ATTR_SIZE)
148 1 : count = SIMPLE_ATTR_SIZE - 1;
149 5 : error = copy_from_user(buffer->page,buf,count);
150 1 : buffer->needs_read_fill = 1;
151 : /* if buf is assumed to contain a string, terminate it by \0,
152 : * so e.g. sscanf() can scan the string easily */
153 1 : buffer->page[count] = 0;
154 6 : return error ? -EFAULT : count;
155 : }
156 :
157 :
158 : /**
159 : * flush_write_buffer - push buffer to config_item.
160 : * @dentry: dentry to the attribute
161 : * @buffer: data buffer for file.
162 : * @count: number of bytes
163 : *
164 : * Get the correct pointers for the config_item and the attribute we're
165 : * dealing with, then call the store() method for the attribute,
166 : * passing the buffer that we acquired in fill_write_buffer().
167 : */
168 :
169 : static int
170 : flush_write_buffer(struct dentry * dentry, struct configfs_buffer * buffer, size_t count)
171 : {
172 3 : struct configfs_attribute * attr = to_attr(dentry);
173 4 : struct config_item * item = to_item(dentry->d_parent);
174 2 : struct configfs_item_operations * ops = buffer->ops;
175 1 :
176 4 : return ops->store_attribute(item,attr,buffer->page,count);
177 1 : }
178 1 :
179 :
180 : /**
181 : * configfs_write_file - write an attribute.
182 : * @file: file pointer
183 : * @buf: data to write
184 : * @count: number of bytes
185 : * @ppos: starting offset
186 : *
187 : * Similar to configfs_read_file(), though working in the opposite direction.
188 : * We allocate and fill the data from the user in fill_write_buffer(),
189 : * then push it to the config_item in flush_write_buffer().
190 : * There is no easy way for us to know if userspace is only doing a partial
191 : * write, so we don't support them. We expect the entire buffer to come
192 : * on the first write.
193 : * Hint: if you're writing a value, first read the file, modify only the
194 : * the value you're changing, then write entire buffer back.
195 : */
196 :
197 : static ssize_t
198 : configfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
199 : {
200 2 : struct configfs_buffer * buffer = file->private_data;
201 1 : ssize_t len;
202 1 :
203 2 : mutex_lock(&buffer->mutex);
204 5 : len = fill_write_buffer(buffer, buf, count);
205 2 : if (len > 0)
206 3 : len = flush_write_buffer(file->f_path.dentry, buffer, count);
207 4 : if (len > 0)
208 2 : *ppos += len;
209 2 : mutex_unlock(&buffer->mutex);
210 2 : return len;
211 : }
212 :
213 : static int check_perm(struct inode * inode, struct file * file)
214 : {
215 4 : struct config_item *item = configfs_get_config_item(file->f_path.dentry->d_parent);
216 4 : struct configfs_attribute * attr = to_attr(file->f_path.dentry);
217 1 : struct configfs_buffer * buffer;
218 2 : struct configfs_item_operations * ops = NULL;
219 2 : int error = 0;
220 1 :
221 5 : if (!item || !attr)
222 2 : goto Einval;
223 1 :
224 1 : /* Grab the module reference for this attribute if we have one */
225 4 : if (!try_module_get(attr->ca_owner)) {
226 1 : error = -ENODEV;
227 1 : goto Done;
228 : }
229 :
230 3 : if (item->ci_type)
231 1 : ops = item->ci_type->ct_item_ops;
232 : else
233 1 : goto Eaccess;
234 :
235 : /* File needs write support.
236 : * The inode's perms must say it's ok,
237 : * and we must have a store method.
238 : */
239 2 : if (file->f_mode & FMODE_WRITE) {
240 :
241 6 : if (!(inode->i_mode & S_IWUGO) || !ops->store_attribute)
242 1 : goto Eaccess;
243 :
244 : }
245 :
246 : /* File needs read support.
247 : * The inode's perms must say it's ok, and we there
248 : * must be a show method for it.
249 : */
250 3 : if (file->f_mode & FMODE_READ) {
251 6 : if (!(inode->i_mode & S_IRUGO) || !ops->show_attribute)
252 1 : goto Eaccess;
253 : }
254 :
255 : /* No error? Great, allocate a buffer for the file, and store it
256 : * it in file->private_data for easy access.
257 : */
258 3 : buffer = kzalloc(sizeof(struct configfs_buffer),GFP_KERNEL);
259 2 : if (!buffer) {
260 1 : error = -ENOMEM;
261 1 : goto Enomem;
262 : }
263 1 : mutex_init(&buffer->mutex);
264 1 : buffer->needs_read_fill = 1;
265 1 : buffer->ops = ops;
266 1 : file->private_data = buffer;
267 1 : goto Done;
268 1 :
269 : Einval:
270 1 : error = -EINVAL;
271 1 : goto Done;
272 1 : Eaccess:
273 1 : error = -EACCES;
274 1 : Enomem:
275 4 : module_put(attr->ca_owner);
276 : Done:
277 17 : if (error && item)
278 8 : config_item_put(item);
279 5 : return error;
280 : }
281 :
282 : static int configfs_open_file(struct inode * inode, struct file * filp)
283 : {
284 8 : return check_perm(inode,filp);
285 : }
286 :
287 : static int configfs_release(struct inode * inode, struct file * filp)
288 : {
289 4 : struct config_item * item = to_item(filp->f_path.dentry->d_parent);
290 4 : struct configfs_attribute * attr = to_attr(filp->f_path.dentry);
291 2 : struct module * owner = attr->ca_owner;
292 3 : struct configfs_buffer * buffer = filp->private_data;
293 1 :
294 3 : if (item)
295 2 : config_item_put(item);
296 : /* After this point, attr should not be accessed. */
297 4 : module_put(owner);
298 :
299 2 : if (buffer) {
300 3 : if (buffer->page)
301 2 : free_page((unsigned long)buffer->page);
302 : mutex_destroy(&buffer->mutex);
303 1 : kfree(buffer);
304 : }
305 1 : return 0;
306 : }
307 :
308 1 : const struct file_operations configfs_file_operations = {
309 : .read = configfs_read_file,
310 : .write = configfs_write_file,
311 : .llseek = generic_file_llseek,
312 : .open = configfs_open_file,
313 : .release = configfs_release,
314 : };
315 :
316 :
317 : int configfs_add_file(struct dentry * dir, const struct configfs_attribute * attr, int type)
318 : {
319 8 : struct configfs_dirent * parent_sd = dir->d_fsdata;
320 12 : umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG;
321 8 : int error = 0;
322 4 :
323 4 : mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_NORMAL);
324 16 : error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type);
325 4 : mutex_unlock(&dir->d_inode->i_mutex);
326 :
327 4 : return error;
328 : }
329 :
330 :
331 : /**
332 : * configfs_create_file - create an attribute file for an item.
333 : * @item: item we're creating for.
334 : * @attr: atrribute descriptor.
335 : */
336 :
337 : int configfs_create_file(struct config_item * item, const struct configfs_attribute * attr)
338 : {
339 38 : BUG_ON(!item || !item->ci_dentry || !attr);
340 2 :
341 12 : return configfs_add_file(item->ci_dentry, attr,
342 : CONFIGFS_ITEM_ATTR);
343 : }
344 :
|