Branch data Line data Source code
1 : : /*
2 : : * proc/fs/generic.c --- generic routines for the proc-fs
3 : : *
4 : : * This file contains generic proc-fs routines for handling
5 : : * directories and files.
6 : : *
7 : : * Copyright (C) 1991, 1992 Linus Torvalds.
8 : : * Copyright (C) 1997 Theodore Ts'o
9 : : */
10 : :
11 : : #include <linux/errno.h>
12 : : #include <linux/time.h>
13 : : #include <linux/proc_fs.h>
14 : : #include <linux/stat.h>
15 : : #include <linux/mm.h>
16 : : #include <linux/module.h>
17 : : #include <linux/slab.h>
18 : : #include <linux/printk.h>
19 : : #include <linux/mount.h>
20 : : #include <linux/init.h>
21 : : #include <linux/idr.h>
22 : : #include <linux/namei.h>
23 : : #include <linux/bitops.h>
24 : : #include <linux/spinlock.h>
25 : : #include <linux/completion.h>
26 : : #include <asm/uaccess.h>
27 : :
28 : : #include "internal.h"
29 : :
30 : : DEFINE_SPINLOCK(proc_subdir_lock);
31 : :
32 : : static int proc_match(unsigned int len, const char *name, struct proc_dir_entry *de)
33 : : {
34 [ # # ][ # # ]: 0 : if (de->namelen != len)
[ # # ]
35 : : return 0;
36 : 0 : return !memcmp(name, de->name, len);
37 : : }
38 : :
39 : 0 : static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
40 : : {
41 : 0 : struct inode *inode = dentry->d_inode;
42 : : struct proc_dir_entry *de = PDE(inode);
43 : : int error;
44 : :
45 : 0 : error = inode_change_ok(inode, iattr);
46 [ # # ]: 0 : if (error)
47 : : return error;
48 : :
49 : 0 : setattr_copy(inode, iattr);
50 : : mark_inode_dirty(inode);
51 : :
52 : 0 : de->uid = inode->i_uid;
53 : 0 : de->gid = inode->i_gid;
54 : 0 : de->mode = inode->i_mode;
55 : 0 : return 0;
56 : : }
57 : :
58 : 0 : static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry,
59 : : struct kstat *stat)
60 : : {
61 : 132 : struct inode *inode = dentry->d_inode;
62 : 132 : struct proc_dir_entry *de = PROC_I(inode)->pde;
63 [ + - ][ + - ]: 132 : if (de && de->nlink)
64 : 132 : set_nlink(inode, de->nlink);
65 : :
66 : 132 : generic_fillattr(inode, stat);
67 : 132 : return 0;
68 : : }
69 : :
70 : : static const struct inode_operations proc_file_inode_operations = {
71 : : .setattr = proc_notify_change,
72 : : };
73 : :
74 : : /*
75 : : * This function parses a name such as "tty/driver/serial", and
76 : : * returns the struct proc_dir_entry for "/proc/tty/driver", and
77 : : * returns "serial" in residual.
78 : : */
79 : 0 : static int __xlate_proc_name(const char *name, struct proc_dir_entry **ret,
80 : : const char **residual)
81 : : {
82 : : const char *cp = name, *next;
83 : : struct proc_dir_entry *de;
84 : : unsigned int len;
85 : :
86 : 0 : de = *ret;
87 [ # # ]: 0 : if (!de)
88 : : de = &proc_root;
89 : :
90 : : while (1) {
91 : 0 : next = strchr(cp, '/');
92 [ # # ]: 0 : if (!next)
93 : : break;
94 : :
95 : 0 : len = next - cp;
96 [ # # ]: 0 : for (de = de->subdir; de ; de = de->next) {
97 [ # # ]: 0 : if (proc_match(len, cp, de))
98 : : break;
99 : : }
100 [ # # ]: 0 : if (!de) {
101 : 0 : WARN(1, "name '%s'\n", name);
102 : 0 : return -ENOENT;
103 : : }
104 : 0 : cp += len + 1;
105 : 0 : }
106 : 0 : *residual = cp;
107 : 0 : *ret = de;
108 : 0 : return 0;
109 : : }
110 : :
111 : 0 : static int xlate_proc_name(const char *name, struct proc_dir_entry **ret,
112 : : const char **residual)
113 : : {
114 : : int rv;
115 : :
116 : : spin_lock(&proc_subdir_lock);
117 : 0 : rv = __xlate_proc_name(name, ret, residual);
118 : : spin_unlock(&proc_subdir_lock);
119 : 0 : return rv;
120 : : }
121 : :
122 : : static DEFINE_IDA(proc_inum_ida);
123 : : static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */
124 : :
125 : : #define PROC_DYNAMIC_FIRST 0xF0000000U
126 : :
127 : : /*
128 : : * Return an inode number between PROC_DYNAMIC_FIRST and
129 : : * 0xffffffff, or zero on failure.
130 : : */
131 : 1 : int proc_alloc_inum(unsigned int *inum)
132 : : {
133 : : unsigned int i;
134 : : int error;
135 : :
136 : : retry:
137 [ + - ]: 1 : if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL))
138 : : return -ENOMEM;
139 : :
140 : : spin_lock_irq(&proc_inum_lock);
141 : : error = ida_get_new(&proc_inum_ida, &i);
142 : : spin_unlock_irq(&proc_inum_lock);
143 [ - + ]: 1 : if (error == -EAGAIN)
144 : : goto retry;
145 [ + - ]: 1 : else if (error)
146 : : return error;
147 : :
148 [ - + ]: 1 : if (i > UINT_MAX - PROC_DYNAMIC_FIRST) {
149 : : spin_lock_irq(&proc_inum_lock);
150 : 0 : ida_remove(&proc_inum_ida, i);
151 : : spin_unlock_irq(&proc_inum_lock);
152 : 0 : return -ENOSPC;
153 : : }
154 : 1 : *inum = PROC_DYNAMIC_FIRST + i;
155 : 1 : return 0;
156 : : }
157 : :
158 : 0 : void proc_free_inum(unsigned int inum)
159 : : {
160 : : unsigned long flags;
161 : 1 : spin_lock_irqsave(&proc_inum_lock, flags);
162 : 1 : ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST);
163 : : spin_unlock_irqrestore(&proc_inum_lock, flags);
164 : 1 : }
165 : :
166 : 0 : static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd)
167 : : {
168 : 183 : nd_set_link(nd, __PDE_DATA(dentry->d_inode));
169 : 183 : return NULL;
170 : : }
171 : :
172 : : static const struct inode_operations proc_link_inode_operations = {
173 : : .readlink = generic_readlink,
174 : : .follow_link = proc_follow_link,
175 : : };
176 : :
177 : : /*
178 : : * Don't create negative dentries here, return -ENOENT by hand
179 : : * instead.
180 : : */
181 : 0 : struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
182 : : struct dentry *dentry)
183 : : {
184 : : struct inode *inode;
185 : :
186 : : spin_lock(&proc_subdir_lock);
187 [ + + ]: 695205 : for (de = de->subdir; de ; de = de->next) {
188 [ + + ]: 693306 : if (de->namelen != dentry->d_name.len)
189 : 642626 : continue;
190 [ + + ]: 50680 : if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
191 : : pde_get(de);
192 : : spin_unlock(&proc_subdir_lock);
193 : 31214 : inode = proc_get_inode(dir->i_sb, de);
194 [ + - ]: 31214 : if (!inode)
195 : : return ERR_PTR(-ENOMEM);
196 : 31214 : d_set_d_op(dentry, &simple_dentry_operations);
197 : : d_add(dentry, inode);
198 : 31214 : return NULL;
199 : : }
200 : : }
201 : : spin_unlock(&proc_subdir_lock);
202 : 1899 : return ERR_PTR(-ENOENT);
203 : : }
204 : :
205 : 0 : struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
206 : : unsigned int flags)
207 : : {
208 : 33023 : return proc_lookup_de(PDE(dir), dir, dentry);
209 : : }
210 : :
211 : : /*
212 : : * This returns non-zero if at EOF, so that the /proc
213 : : * root directory can use this and check if it should
214 : : * continue with the <pid> entries..
215 : : *
216 : : * Note that the VFS-layer doesn't care about the return
217 : : * value of the readdir() call, as long as it's non-negative
218 : : * for success..
219 : : */
220 : 0 : int proc_readdir_de(struct proc_dir_entry *de, struct file *file,
221 : : struct dir_context *ctx)
222 : : {
223 : : int i;
224 : :
225 [ + - ]: 413 : if (!dir_emit_dots(file, ctx))
226 : : return 0;
227 : :
228 : : spin_lock(&proc_subdir_lock);
229 : 413 : de = de->subdir;
230 : 826 : i = ctx->pos - 2;
231 : : for (;;) {
232 [ + + ]: 1185 : if (!de) {
233 : : spin_unlock(&proc_subdir_lock);
234 : 134 : return 0;
235 : : }
236 [ + + ]: 1051 : if (!i)
237 : : break;
238 : 772 : de = de->next;
239 : 772 : i--;
240 : 1051 : }
241 : :
242 : : do {
243 : : struct proc_dir_entry *next;
244 : : pde_get(de);
245 : : spin_unlock(&proc_subdir_lock);
246 [ - + ]: 8967 : if (!dir_emit(ctx, de->name, de->namelen,
247 : 17934 : de->low_ino, de->mode >> 12)) {
248 : 0 : pde_put(de);
249 : 0 : return 0;
250 : : }
251 : : spin_lock(&proc_subdir_lock);
252 : 8967 : ctx->pos++;
253 : 8967 : next = de->next;
254 : 8967 : pde_put(de);
255 : : de = next;
256 [ + + ]: 8967 : } while (de);
257 : : spin_unlock(&proc_subdir_lock);
258 : 279 : return 1;
259 : : }
260 : :
261 : 0 : int proc_readdir(struct file *file, struct dir_context *ctx)
262 : : {
263 : : struct inode *inode = file_inode(file);
264 : :
265 : 411 : return proc_readdir_de(PDE(inode), file, ctx);
266 : : }
267 : :
268 : : /*
269 : : * These are the generic /proc directory operations. They
270 : : * use the in-memory "struct proc_dir_entry" tree to parse
271 : : * the /proc directory.
272 : : */
273 : : static const struct file_operations proc_dir_operations = {
274 : : .llseek = generic_file_llseek,
275 : : .read = generic_read_dir,
276 : : .iterate = proc_readdir,
277 : : };
278 : :
279 : : /*
280 : : * proc directories can do almost nothing..
281 : : */
282 : : static const struct inode_operations proc_dir_inode_operations = {
283 : : .lookup = proc_lookup,
284 : : .getattr = proc_getattr,
285 : : .setattr = proc_notify_change,
286 : : };
287 : :
288 : 0 : static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
289 : : {
290 : : struct proc_dir_entry *tmp;
291 : : int ret;
292 : :
293 : 0 : ret = proc_alloc_inum(&dp->low_ino);
294 [ # # ]: 0 : if (ret)
295 : : return ret;
296 : :
297 [ # # ]: 0 : if (S_ISDIR(dp->mode)) {
298 : 0 : dp->proc_fops = &proc_dir_operations;
299 : 0 : dp->proc_iops = &proc_dir_inode_operations;
300 : 0 : dir->nlink++;
301 [ # # ]: 0 : } else if (S_ISLNK(dp->mode)) {
302 : 0 : dp->proc_iops = &proc_link_inode_operations;
303 [ # # ]: 0 : } else if (S_ISREG(dp->mode)) {
304 [ # # ]: 0 : BUG_ON(dp->proc_fops == NULL);
305 : 0 : dp->proc_iops = &proc_file_inode_operations;
306 : : } else {
307 : 0 : WARN_ON(1);
308 : 0 : return -EINVAL;
309 : : }
310 : :
311 : : spin_lock(&proc_subdir_lock);
312 : :
313 [ # # ]: 0 : for (tmp = dir->subdir; tmp; tmp = tmp->next)
314 [ # # ]: 0 : if (strcmp(tmp->name, dp->name) == 0) {
315 : 0 : WARN(1, "proc_dir_entry '%s/%s' already registered\n",
316 : : dir->name, dp->name);
317 : 0 : break;
318 : : }
319 : :
320 : 0 : dp->next = dir->subdir;
321 : 0 : dp->parent = dir;
322 : 0 : dir->subdir = dp;
323 : : spin_unlock(&proc_subdir_lock);
324 : :
325 : 0 : return 0;
326 : : }
327 : :
328 : 0 : static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
329 : : const char *name,
330 : : umode_t mode,
331 : : nlink_t nlink)
332 : : {
333 : : struct proc_dir_entry *ent = NULL;
334 : 0 : const char *fn = name;
335 : : unsigned int len;
336 : :
337 : : /* make sure name is valid */
338 [ # # ][ # # ]: 0 : if (!name || !strlen(name))
339 : : goto out;
340 : :
341 [ # # ]: 0 : if (xlate_proc_name(name, parent, &fn) != 0)
342 : : goto out;
343 : :
344 : : /* At this point there must not be any '/' characters beyond *fn */
345 [ # # ]: 0 : if (strchr(fn, '/'))
346 : : goto out;
347 : :
348 : 0 : len = strlen(fn);
349 : :
350 : 0 : ent = kzalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
351 [ # # ]: 0 : if (!ent)
352 : : goto out;
353 : :
354 : 0 : memcpy(ent->name, fn, len + 1);
355 : 0 : ent->namelen = len;
356 : 0 : ent->mode = mode;
357 : 0 : ent->nlink = nlink;
358 : 0 : atomic_set(&ent->count, 1);
359 : 0 : spin_lock_init(&ent->pde_unload_lock);
360 : 0 : INIT_LIST_HEAD(&ent->pde_openers);
361 : : out:
362 : 0 : return ent;
363 : : }
364 : :
365 : 0 : struct proc_dir_entry *proc_symlink(const char *name,
366 : : struct proc_dir_entry *parent, const char *dest)
367 : : {
368 : : struct proc_dir_entry *ent;
369 : :
370 : 0 : ent = __proc_create(&parent, name,
371 : : (S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
372 : :
373 [ # # ]: 0 : if (ent) {
374 : 0 : ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
375 [ # # ]: 0 : if (ent->data) {
376 : 0 : strcpy((char*)ent->data,dest);
377 [ # # ]: 0 : if (proc_register(parent, ent) < 0) {
378 : 0 : kfree(ent->data);
379 : 0 : kfree(ent);
380 : : ent = NULL;
381 : : }
382 : : } else {
383 : 0 : kfree(ent);
384 : : ent = NULL;
385 : : }
386 : : }
387 : 0 : return ent;
388 : : }
389 : : EXPORT_SYMBOL(proc_symlink);
390 : :
391 : 0 : struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode,
392 : : struct proc_dir_entry *parent, void *data)
393 : : {
394 : : struct proc_dir_entry *ent;
395 : :
396 [ # # ]: 0 : if (mode == 0)
397 : : mode = S_IRUGO | S_IXUGO;
398 : :
399 : 0 : ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
400 [ # # ]: 0 : if (ent) {
401 : 0 : ent->data = data;
402 [ # # ]: 0 : if (proc_register(parent, ent) < 0) {
403 : 0 : kfree(ent);
404 : : ent = NULL;
405 : : }
406 : : }
407 : 0 : return ent;
408 : : }
409 : : EXPORT_SYMBOL_GPL(proc_mkdir_data);
410 : :
411 : 0 : struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode,
412 : : struct proc_dir_entry *parent)
413 : : {
414 : 0 : return proc_mkdir_data(name, mode, parent, NULL);
415 : : }
416 : : EXPORT_SYMBOL(proc_mkdir_mode);
417 : :
418 : 0 : struct proc_dir_entry *proc_mkdir(const char *name,
419 : : struct proc_dir_entry *parent)
420 : : {
421 : 0 : return proc_mkdir_data(name, 0, parent, NULL);
422 : : }
423 : : EXPORT_SYMBOL(proc_mkdir);
424 : :
425 : 0 : struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
426 : : struct proc_dir_entry *parent,
427 : : const struct file_operations *proc_fops,
428 : : void *data)
429 : : {
430 : : struct proc_dir_entry *pde;
431 [ # # ]: 0 : if ((mode & S_IFMT) == 0)
432 : 0 : mode |= S_IFREG;
433 : :
434 [ # # ]: 0 : if (!S_ISREG(mode)) {
435 : 0 : WARN_ON(1); /* use proc_mkdir() */
436 : 0 : return NULL;
437 : : }
438 : :
439 [ # # ]: 0 : if ((mode & S_IALLUGO) == 0)
440 : 0 : mode |= S_IRUGO;
441 : 0 : pde = __proc_create(&parent, name, mode, 1);
442 [ # # ]: 0 : if (!pde)
443 : : goto out;
444 : 0 : pde->proc_fops = proc_fops;
445 : 0 : pde->data = data;
446 [ # # ]: 0 : if (proc_register(parent, pde) < 0)
447 : : goto out_free;
448 : : return pde;
449 : : out_free:
450 : 0 : kfree(pde);
451 : : out:
452 : : return NULL;
453 : : }
454 : : EXPORT_SYMBOL(proc_create_data);
455 : :
456 : 0 : void proc_set_size(struct proc_dir_entry *de, loff_t size)
457 : : {
458 : 0 : de->size = size;
459 : 0 : }
460 : : EXPORT_SYMBOL(proc_set_size);
461 : :
462 : 0 : void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid)
463 : : {
464 : 0 : de->uid = uid;
465 : 0 : de->gid = gid;
466 : 0 : }
467 : : EXPORT_SYMBOL(proc_set_user);
468 : :
469 : 0 : static void free_proc_entry(struct proc_dir_entry *de)
470 : : {
471 : 0 : proc_free_inum(de->low_ino);
472 : :
473 [ # # ]: 0 : if (S_ISLNK(de->mode))
474 : 0 : kfree(de->data);
475 : 0 : kfree(de);
476 : 0 : }
477 : :
478 : 0 : void pde_put(struct proc_dir_entry *pde)
479 : : {
480 [ - + ]: 40180 : if (atomic_dec_and_test(&pde->count))
481 : 0 : free_proc_entry(pde);
482 : 0 : }
483 : :
484 : : /*
485 : : * Remove a /proc entry and free it if it's not currently in use.
486 : : */
487 : 0 : void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
488 : : {
489 : : struct proc_dir_entry **p;
490 : : struct proc_dir_entry *de = NULL;
491 : 0 : const char *fn = name;
492 : : unsigned int len;
493 : :
494 : : spin_lock(&proc_subdir_lock);
495 [ # # ]: 0 : if (__xlate_proc_name(name, &parent, &fn) != 0) {
496 : : spin_unlock(&proc_subdir_lock);
497 : 0 : return;
498 : : }
499 : 0 : len = strlen(fn);
500 : :
501 [ # # ]: 0 : for (p = &parent->subdir; *p; p=&(*p)->next ) {
502 [ # # ]: 0 : if (proc_match(len, fn, *p)) {
503 : : de = *p;
504 : 0 : *p = de->next;
505 : 0 : de->next = NULL;
506 : 0 : break;
507 : : }
508 : : }
509 : : spin_unlock(&proc_subdir_lock);
510 [ # # ]: 0 : if (!de) {
511 : 0 : WARN(1, "name '%s'\n", name);
512 : 0 : return;
513 : : }
514 : :
515 : 0 : proc_entry_rundown(de);
516 : :
517 [ # # ]: 0 : if (S_ISDIR(de->mode))
518 : 0 : parent->nlink--;
519 : 0 : de->nlink = 0;
520 [ # # ]: 0 : WARN(de->subdir, "%s: removing non-empty directory "
521 : : "'%s/%s', leaking at least '%s'\n", __func__,
522 : : de->parent->name, de->name, de->subdir->name);
523 : 0 : pde_put(de);
524 : : }
525 : : EXPORT_SYMBOL(remove_proc_entry);
526 : :
527 : 0 : int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
528 : : {
529 : : struct proc_dir_entry **p;
530 : : struct proc_dir_entry *root = NULL, *de, *next;
531 : 0 : const char *fn = name;
532 : : unsigned int len;
533 : :
534 : : spin_lock(&proc_subdir_lock);
535 [ # # ]: 0 : if (__xlate_proc_name(name, &parent, &fn) != 0) {
536 : : spin_unlock(&proc_subdir_lock);
537 : 0 : return -ENOENT;
538 : : }
539 : 0 : len = strlen(fn);
540 : :
541 [ # # ]: 0 : for (p = &parent->subdir; *p; p=&(*p)->next ) {
542 [ # # ]: 0 : if (proc_match(len, fn, *p)) {
543 : : root = *p;
544 : 0 : *p = root->next;
545 : 0 : root->next = NULL;
546 : 0 : break;
547 : : }
548 : : }
549 [ # # ]: 0 : if (!root) {
550 : : spin_unlock(&proc_subdir_lock);
551 : 0 : return -ENOENT;
552 : : }
553 : : de = root;
554 : : while (1) {
555 : 0 : next = de->subdir;
556 [ # # ]: 0 : if (next) {
557 : 0 : de->subdir = next->next;
558 : 0 : next->next = NULL;
559 : : de = next;
560 : 0 : continue;
561 : : }
562 : : spin_unlock(&proc_subdir_lock);
563 : :
564 : 0 : proc_entry_rundown(de);
565 : 0 : next = de->parent;
566 [ # # ]: 0 : if (S_ISDIR(de->mode))
567 : 0 : next->nlink--;
568 : 0 : de->nlink = 0;
569 [ # # ]: 0 : if (de == root)
570 : : break;
571 : 0 : pde_put(de);
572 : :
573 : : spin_lock(&proc_subdir_lock);
574 : : de = next;
575 : : }
576 : 0 : pde_put(root);
577 : 0 : return 0;
578 : : }
579 : : EXPORT_SYMBOL(remove_proc_subtree);
580 : :
581 : 0 : void *proc_get_parent_data(const struct inode *inode)
582 : : {
583 : : struct proc_dir_entry *de = PDE(inode);
584 : 0 : return de->parent->data;
585 : : }
586 : : EXPORT_SYMBOL_GPL(proc_get_parent_data);
587 : :
588 : 0 : void proc_remove(struct proc_dir_entry *de)
589 : : {
590 [ # # ]: 0 : if (de)
591 : 0 : remove_proc_subtree(de->name, de->parent);
592 : 0 : }
593 : : EXPORT_SYMBOL(proc_remove);
594 : :
595 : 0 : void *PDE_DATA(const struct inode *inode)
596 : : {
597 : 79 : return __PDE_DATA(inode);
598 : : }
599 : : EXPORT_SYMBOL(PDE_DATA);
|