blob: a6a1cb5d589d4aa38d131b94cead51dbf7721c28 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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>
Christoph Hellwig10257742010-06-04 11:30:02 +020015#include <linux/mm.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include <linux/module.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090017#include <linux/slab.h>
Andrew Morton87ebdc02013-02-27 17:03:16 -080018#include <linux/printk.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070019#include <linux/mount.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <linux/init.h>
21#include <linux/idr.h>
22#include <linux/namei.h>
23#include <linux/bitops.h>
Steven Rostedt64a07bd2006-03-26 01:36:55 -080024#include <linux/spinlock.h>
Alexey Dobriyan786d7e12007-07-15 23:39:00 -070025#include <linux/completion.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <asm/uaccess.h>
27
Adrian Bunkfee781e2006-01-08 01:04:16 -080028#include "internal.h"
29
Steven Rostedt64a07bd2006-03-26 01:36:55 -080030DEFINE_SPINLOCK(proc_subdir_lock);
31
Alexey Dobriyan312ec7e2011-03-23 16:42:52 -070032static int proc_match(unsigned int len, const char *name, struct proc_dir_entry *de)
Linus Torvalds1da177e2005-04-16 15:20:36 -070033{
34 if (de->namelen != len)
35 return 0;
36 return !memcmp(name, de->name, len);
37}
38
Linus Torvalds1da177e2005-04-16 15:20:36 -070039/* buffer size is one page but our output routines use some slack for overruns */
40#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
41
42static ssize_t
Alexey Dobriyan3dec7f52009-02-20 17:04:33 +030043__proc_file_read(struct file *file, char __user *buf, size_t nbytes,
Linus Torvalds1da177e2005-04-16 15:20:36 -070044 loff_t *ppos)
45{
Al Viro496ad9a2013-01-23 17:07:38 -050046 struct inode * inode = file_inode(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -070047 char *page;
48 ssize_t retval=0;
49 int eof=0;
50 ssize_t n, count;
51 char *start;
52 struct proc_dir_entry * dp;
Linus Torvalds8b90db02005-12-30 08:39:10 -080053 unsigned long long pos;
54
55 /*
56 * Gaah, please just use "seq_file" instead. The legacy /proc
57 * interfaces cut loff_t down to off_t for reads, and ignore
58 * the offset entirely for writes..
59 */
60 pos = *ppos;
61 if (pos > MAX_NON_LFS)
62 return 0;
63 if (nbytes > MAX_NON_LFS - pos)
64 nbytes = MAX_NON_LFS - pos;
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
66 dp = PDE(inode);
Mel Gormane12ba742007-10-16 01:25:52 -070067 if (!(page = (char*) __get_free_page(GFP_TEMPORARY)))
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 return -ENOMEM;
69
70 while ((nbytes > 0) && !eof) {
71 count = min_t(size_t, PROC_BLOCK_SIZE, nbytes);
72
73 start = NULL;
David Howellsad147d02013-04-04 16:32:28 +010074 if (!dp->read_proc)
Linus Torvalds1da177e2005-04-16 15:20:36 -070075 break;
76
David Howellsad147d02013-04-04 16:32:28 +010077 /* How to be a proc read function
78 * ------------------------------
79 * Prototype:
80 * int f(char *buffer, char **start, off_t offset,
81 * int count, int *peof, void *dat)
82 *
83 * Assume that the buffer is "count" bytes in size.
84 *
85 * If you know you have supplied all the data you have, set
86 * *peof.
87 *
88 * You have three ways to return data:
89 *
90 * 0) Leave *start = NULL. (This is the default.) Put the
91 * data of the requested offset at that offset within the
92 * buffer. Return the number (n) of bytes there are from
93 * the beginning of the buffer up to the last byte of data.
94 * If the number of supplied bytes (= n - offset) is greater
95 * than zero and you didn't signal eof and the reader is
96 * prepared to take more data you will be called again with
97 * the requested offset advanced by the number of bytes
98 * absorbed. This interface is useful for files no larger
99 * than the buffer.
100 *
101 * 1) Set *start = an unsigned long value less than the buffer
102 * address but greater than zero. Put the data of the
103 * requested offset at the beginning of the buffer. Return
104 * the number of bytes of data placed there. If this number
105 * is greater than zero and you didn't signal eof and the
106 * reader is prepared to take more data you will be called
107 * again with the requested offset advanced by *start. This
108 * interface is useful when you have a large file consisting
109 * of a series of blocks which you want to count and return
110 * as wholes.
111 * (Hack by Paul.Russell@rustcorp.com.au)
112 *
113 * 2) Set *start = an address within the buffer. Put the data
114 * of the requested offset at *start. Return the number of
115 * bytes of data placed there. If this number is greater
116 * than zero and you didn't signal eof and the reader is
117 * prepared to take more data you will be called again with
118 * the requested offset advanced by the number of bytes
119 * absorbed.
120 */
121 n = dp->read_proc(page, &start, *ppos, count, &eof, dp->data);
122
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 if (n == 0) /* end of file */
124 break;
125 if (n < 0) { /* error */
126 if (retval == 0)
127 retval = n;
128 break;
129 }
130
131 if (start == NULL) {
Andrew Morton87ebdc02013-02-27 17:03:16 -0800132 if (n > PAGE_SIZE) /* Apparent buffer overflow */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 n = PAGE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 n -= *ppos;
135 if (n <= 0)
136 break;
137 if (n > count)
138 n = count;
139 start = page + *ppos;
140 } else if (start < page) {
Andrew Morton87ebdc02013-02-27 17:03:16 -0800141 if (n > PAGE_SIZE) /* Apparent buffer overflow */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 n = PAGE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143 if (n > count) {
144 /*
145 * Don't reduce n because doing so might
146 * cut off part of a data block.
147 */
Andrew Morton87ebdc02013-02-27 17:03:16 -0800148 pr_warn("proc_file_read: count exceeded\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 }
150 } else /* start >= page */ {
151 unsigned long startoff = (unsigned long)(start - page);
Andrew Morton87ebdc02013-02-27 17:03:16 -0800152 if (n > (PAGE_SIZE - startoff)) /* buffer overflow? */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 n = PAGE_SIZE - startoff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 if (n > count)
155 n = count;
156 }
157
158 n -= copy_to_user(buf, start < page ? page : start, n);
159 if (n == 0) {
160 if (retval == 0)
161 retval = -EFAULT;
162 break;
163 }
164
165 *ppos += start < page ? (unsigned long)start : n;
166 nbytes -= n;
167 buf += n;
168 retval += n;
169 }
170 free_page((unsigned long) page);
171 return retval;
172}
173
174static ssize_t
Alexey Dobriyan3dec7f52009-02-20 17:04:33 +0300175proc_file_read(struct file *file, char __user *buf, size_t nbytes,
176 loff_t *ppos)
177{
Al Viro496ad9a2013-01-23 17:07:38 -0500178 struct proc_dir_entry *pde = PDE(file_inode(file));
Alexey Dobriyan3dec7f52009-02-20 17:04:33 +0300179 ssize_t rv = -EIO;
180
181 spin_lock(&pde->pde_unload_lock);
182 if (!pde->proc_fops) {
183 spin_unlock(&pde->pde_unload_lock);
184 return rv;
185 }
186 pde->pde_users++;
187 spin_unlock(&pde->pde_unload_lock);
188
189 rv = __proc_file_read(file, buf, nbytes, ppos);
190
191 pde_users_dec(pde);
192 return rv;
193}
194
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195static loff_t
196proc_file_lseek(struct file *file, loff_t offset, int orig)
197{
Linus Torvalds8b90db02005-12-30 08:39:10 -0800198 loff_t retval = -EINVAL;
199 switch (orig) {
200 case 1:
201 offset += file->f_pos;
202 /* fallthrough */
203 case 0:
204 if (offset < 0 || offset > MAX_NON_LFS)
205 break;
206 file->f_pos = retval = offset;
207 }
208 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209}
210
Alexey Dobriyan76df0c22008-02-08 04:18:27 -0800211static const struct file_operations proc_file_operations = {
212 .llseek = proc_file_lseek,
213 .read = proc_file_read,
Alexey Dobriyan76df0c22008-02-08 04:18:27 -0800214};
215
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
217{
218 struct inode *inode = dentry->d_inode;
219 struct proc_dir_entry *de = PDE(inode);
220 int error;
221
222 error = inode_change_ok(inode, iattr);
223 if (error)
Christoph Hellwig10257742010-06-04 11:30:02 +0200224 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225
Christoph Hellwig10257742010-06-04 11:30:02 +0200226 setattr_copy(inode, iattr);
227 mark_inode_dirty(inode);
Marco Stornelli46f69552012-12-15 11:48:48 +0100228
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 de->uid = inode->i_uid;
230 de->gid = inode->i_gid;
231 de->mode = inode->i_mode;
Christoph Hellwig10257742010-06-04 11:30:02 +0200232 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233}
234
Miklos Szeredi2b579be2005-09-06 15:17:18 -0700235static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry,
236 struct kstat *stat)
237{
238 struct inode *inode = dentry->d_inode;
239 struct proc_dir_entry *de = PROC_I(inode)->pde;
240 if (de && de->nlink)
Miklos Szeredibfe86842011-10-28 14:13:29 +0200241 set_nlink(inode, de->nlink);
Miklos Szeredi2b579be2005-09-06 15:17:18 -0700242
243 generic_fillattr(inode, stat);
244 return 0;
245}
246
Arjan van de Venc5ef1c42007-02-12 00:55:40 -0800247static const struct inode_operations proc_file_inode_operations = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 .setattr = proc_notify_change,
249};
250
251/*
252 * This function parses a name such as "tty/driver/serial", and
253 * returns the struct proc_dir_entry for "/proc/tty/driver", and
254 * returns "serial" in residual.
255 */
Alexey Dobriyane17a5762010-03-05 13:43:59 -0800256static int __xlate_proc_name(const char *name, struct proc_dir_entry **ret,
257 const char **residual)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258{
259 const char *cp = name, *next;
260 struct proc_dir_entry *de;
Alexey Dobriyan312ec7e2011-03-23 16:42:52 -0700261 unsigned int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262
Alexey Dobriyan7cee4e02008-04-29 01:01:40 -0700263 de = *ret;
264 if (!de)
265 de = &proc_root;
266
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 while (1) {
268 next = strchr(cp, '/');
269 if (!next)
270 break;
271
272 len = next - cp;
273 for (de = de->subdir; de ; de = de->next) {
274 if (proc_match(len, cp, de))
275 break;
276 }
Alexey Dobriyan12bac0d2010-03-05 13:44:00 -0800277 if (!de) {
278 WARN(1, "name '%s'\n", name);
Alexey Dobriyane17a5762010-03-05 13:43:59 -0800279 return -ENOENT;
Alexey Dobriyan12bac0d2010-03-05 13:44:00 -0800280 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 cp += len + 1;
282 }
283 *residual = cp;
284 *ret = de;
Alexey Dobriyane17a5762010-03-05 13:43:59 -0800285 return 0;
286}
287
288static int xlate_proc_name(const char *name, struct proc_dir_entry **ret,
289 const char **residual)
290{
291 int rv;
292
293 spin_lock(&proc_subdir_lock);
294 rv = __xlate_proc_name(name, ret, residual);
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800295 spin_unlock(&proc_subdir_lock);
Alexey Dobriyane17a5762010-03-05 13:43:59 -0800296 return rv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297}
298
Alexey Dobriyan9a185402008-07-26 11:21:37 +0400299static DEFINE_IDA(proc_inum_ida);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */
301
Alexey Dobriyan67935df2008-07-26 11:18:28 +0400302#define PROC_DYNAMIC_FIRST 0xF0000000U
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303
304/*
305 * Return an inode number between PROC_DYNAMIC_FIRST and
306 * 0xffffffff, or zero on failure.
307 */
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700308int proc_alloc_inum(unsigned int *inum)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309{
Alexey Dobriyan67935df2008-07-26 11:18:28 +0400310 unsigned int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311 int error;
312
313retry:
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700314 if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL))
315 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316
Eric W. Biedermandfb2ea42012-12-21 20:38:00 -0800317 spin_lock_irq(&proc_inum_lock);
Alexey Dobriyan9a185402008-07-26 11:21:37 +0400318 error = ida_get_new(&proc_inum_ida, &i);
Eric W. Biedermandfb2ea42012-12-21 20:38:00 -0800319 spin_unlock_irq(&proc_inum_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 if (error == -EAGAIN)
321 goto retry;
322 else if (error)
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700323 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
Alexey Dobriyan67935df2008-07-26 11:18:28 +0400325 if (i > UINT_MAX - PROC_DYNAMIC_FIRST) {
Eric W. Biedermandfb2ea42012-12-21 20:38:00 -0800326 spin_lock_irq(&proc_inum_lock);
Alexey Dobriyan9a185402008-07-26 11:21:37 +0400327 ida_remove(&proc_inum_ida, i);
Eric W. Biedermandfb2ea42012-12-21 20:38:00 -0800328 spin_unlock_irq(&proc_inum_lock);
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700329 return -ENOSPC;
Alexey Dobriyan67935df2008-07-26 11:18:28 +0400330 }
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700331 *inum = PROC_DYNAMIC_FIRST + i;
332 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333}
334
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700335void proc_free_inum(unsigned int inum)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336{
Eric W. Biedermandfb2ea42012-12-21 20:38:00 -0800337 unsigned long flags;
338 spin_lock_irqsave(&proc_inum_lock, flags);
Alexey Dobriyan9a185402008-07-26 11:21:37 +0400339 ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST);
Eric W. Biedermandfb2ea42012-12-21 20:38:00 -0800340 spin_unlock_irqrestore(&proc_inum_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341}
342
Al Viro008b1502005-08-20 00:17:39 +0100343static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344{
Al Virod9dda782013-03-31 18:16:14 -0400345 nd_set_link(nd, PDE_DATA(dentry->d_inode));
Al Viro008b1502005-08-20 00:17:39 +0100346 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347}
348
Arjan van de Venc5ef1c42007-02-12 00:55:40 -0800349static const struct inode_operations proc_link_inode_operations = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 .readlink = generic_readlink,
351 .follow_link = proc_follow_link,
352};
353
354/*
355 * As some entries in /proc are volatile, we want to
356 * get rid of unused dentries. This could be made
357 * smarter: we could keep a "volatile" flag in the
358 * inode to indicate which ones to keep.
359 */
Nick Pigginfe15ce42011-01-07 17:49:23 +1100360static int proc_delete_dentry(const struct dentry * dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361{
362 return 1;
363}
364
Al Virod72f71e2009-02-20 05:58:47 +0000365static const struct dentry_operations proc_dentry_operations =
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366{
367 .d_delete = proc_delete_dentry,
368};
369
370/*
371 * Don't create negative dentries here, return -ENOENT by hand
372 * instead.
373 */
Pavel Emelyanove9720ac2008-03-07 11:08:40 -0800374struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
375 struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376{
Al Virod3d009c2013-01-25 20:11:22 -0500377 struct inode *inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800379 spin_lock(&proc_subdir_lock);
Alexey Dobriyan5e971dc2008-04-29 01:01:41 -0700380 for (de = de->subdir; de ; de = de->next) {
381 if (de->namelen != dentry->d_name.len)
382 continue;
383 if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800384 pde_get(de);
Alexey Dobriyan5e971dc2008-04-29 01:01:41 -0700385 spin_unlock(&proc_subdir_lock);
Alexey Dobriyan6d1b6e42011-01-12 17:00:33 -0800386 inode = proc_get_inode(dir->i_sb, de);
Al Virod3d009c2013-01-25 20:11:22 -0500387 if (!inode)
388 return ERR_PTR(-ENOMEM);
389 d_set_d_op(dentry, &proc_dentry_operations);
390 d_add(dentry, inode);
391 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 }
393 }
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800394 spin_unlock(&proc_subdir_lock);
Al Virod3d009c2013-01-25 20:11:22 -0500395 return ERR_PTR(-ENOENT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396}
397
Pavel Emelyanove9720ac2008-03-07 11:08:40 -0800398struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
Al Viro00cd8dd2012-06-10 17:13:09 -0400399 unsigned int flags)
Pavel Emelyanove9720ac2008-03-07 11:08:40 -0800400{
401 return proc_lookup_de(PDE(dir), dir, dentry);
402}
403
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404/*
405 * This returns non-zero if at EOF, so that the /proc
406 * root directory can use this and check if it should
407 * continue with the <pid> entries..
408 *
409 * Note that the VFS-layer doesn't care about the return
410 * value of the readdir() call, as long as it's non-negative
411 * for success..
412 */
Pavel Emelyanove9720ac2008-03-07 11:08:40 -0800413int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,
414 filldir_t filldir)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 unsigned int ino;
417 int i;
Al Viro496ad9a2013-01-23 17:07:38 -0500418 struct inode *inode = file_inode(filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 int ret = 0;
420
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 ino = inode->i_ino;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 i = filp->f_pos;
423 switch (i) {
424 case 0:
425 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
426 goto out;
427 i++;
428 filp->f_pos++;
429 /* fall through */
430 case 1:
431 if (filldir(dirent, "..", 2, i,
Josef "Jeff" Sipek2fddfee2006-12-08 02:36:36 -0800432 parent_ino(filp->f_path.dentry),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 DT_DIR) < 0)
434 goto out;
435 i++;
436 filp->f_pos++;
437 /* fall through */
438 default:
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800439 spin_lock(&proc_subdir_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 de = de->subdir;
441 i -= 2;
442 for (;;) {
443 if (!de) {
444 ret = 1;
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800445 spin_unlock(&proc_subdir_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 goto out;
447 }
448 if (!i)
449 break;
450 de = de->next;
451 i--;
452 }
453
454 do {
Darrick J. Wong59cd0cb2007-05-08 00:25:47 -0700455 struct proc_dir_entry *next;
456
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800457 /* filldir passes info to user space */
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800458 pde_get(de);
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800459 spin_unlock(&proc_subdir_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460 if (filldir(dirent, de->name, de->namelen, filp->f_pos,
Darrick J. Wong59cd0cb2007-05-08 00:25:47 -0700461 de->low_ino, de->mode >> 12) < 0) {
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800462 pde_put(de);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 goto out;
Darrick J. Wong59cd0cb2007-05-08 00:25:47 -0700464 }
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800465 spin_lock(&proc_subdir_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 filp->f_pos++;
Darrick J. Wong59cd0cb2007-05-08 00:25:47 -0700467 next = de->next;
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800468 pde_put(de);
Darrick J. Wong59cd0cb2007-05-08 00:25:47 -0700469 de = next;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 } while (de);
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800471 spin_unlock(&proc_subdir_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 }
473 ret = 1;
Alexey Dobriyanb4df2b92008-10-27 22:48:36 +0300474out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 return ret;
476}
477
Pavel Emelyanove9720ac2008-03-07 11:08:40 -0800478int proc_readdir(struct file *filp, void *dirent, filldir_t filldir)
479{
Al Viro496ad9a2013-01-23 17:07:38 -0500480 struct inode *inode = file_inode(filp);
Pavel Emelyanove9720ac2008-03-07 11:08:40 -0800481
482 return proc_readdir_de(PDE(inode), filp, dirent, filldir);
483}
484
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485/*
486 * These are the generic /proc directory operations. They
487 * use the in-memory "struct proc_dir_entry" tree to parse
488 * the /proc directory.
489 */
Arjan van de Ven00977a52007-02-12 00:55:34 -0800490static const struct file_operations proc_dir_operations = {
Alexey Dobriyanb4df2b92008-10-27 22:48:36 +0300491 .llseek = generic_file_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 .read = generic_read_dir,
493 .readdir = proc_readdir,
494};
495
496/*
497 * proc directories can do almost nothing..
498 */
Arjan van de Venc5ef1c42007-02-12 00:55:40 -0800499static const struct inode_operations proc_dir_inode_operations = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 .lookup = proc_lookup,
Miklos Szeredi2b579be2005-09-06 15:17:18 -0700501 .getattr = proc_getattr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 .setattr = proc_notify_change,
503};
504
505static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
506{
Zhang Rui94413d82008-02-08 04:18:29 -0800507 struct proc_dir_entry *tmp;
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700508 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700510 ret = proc_alloc_inum(&dp->low_ino);
511 if (ret)
512 return ret;
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800513
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 if (S_ISDIR(dp->mode)) {
Al Virob6cdc732013-03-30 21:20:14 -0400515 dp->proc_fops = &proc_dir_operations;
516 dp->proc_iops = &proc_dir_inode_operations;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 dir->nlink++;
518 } else if (S_ISLNK(dp->mode)) {
Al Virob6cdc732013-03-30 21:20:14 -0400519 dp->proc_iops = &proc_link_inode_operations;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 } else if (S_ISREG(dp->mode)) {
521 if (dp->proc_fops == NULL)
522 dp->proc_fops = &proc_file_operations;
Al Virob6cdc732013-03-30 21:20:14 -0400523 dp->proc_iops = &proc_file_inode_operations;
524 } else {
525 WARN_ON(1);
526 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 }
Changli Gao99fc06d2007-07-15 23:40:09 -0700528
529 spin_lock(&proc_subdir_lock);
Zhang Rui94413d82008-02-08 04:18:29 -0800530
531 for (tmp = dir->subdir; tmp; tmp = tmp->next)
532 if (strcmp(tmp->name, dp->name) == 0) {
Andrew Morton87ebdc02013-02-27 17:03:16 -0800533 WARN(1, "proc_dir_entry '%s/%s' already registered\n",
Alexey Dobriyan665020c2008-09-13 02:33:06 -0700534 dir->name, dp->name);
Zhang Rui94413d82008-02-08 04:18:29 -0800535 break;
536 }
537
Changli Gao99fc06d2007-07-15 23:40:09 -0700538 dp->next = dir->subdir;
539 dp->parent = dir;
540 dir->subdir = dp;
541 spin_unlock(&proc_subdir_lock);
542
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 return 0;
544}
545
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800546static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 const char *name,
Al Virod161a132011-07-24 03:36:29 -0400548 umode_t mode,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 nlink_t nlink)
550{
551 struct proc_dir_entry *ent = NULL;
552 const char *fn = name;
Alexey Dobriyan312ec7e2011-03-23 16:42:52 -0700553 unsigned int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554
555 /* make sure name is valid */
yan17baa2a2012-10-04 17:15:43 -0700556 if (!name || !strlen(name))
557 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
Alexey Dobriyan7cee4e02008-04-29 01:01:40 -0700559 if (xlate_proc_name(name, parent, &fn) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 goto out;
561
562 /* At this point there must not be any '/' characters beyond *fn */
563 if (strchr(fn, '/'))
564 goto out;
565
566 len = strlen(fn);
567
yan17baa2a2012-10-04 17:15:43 -0700568 ent = kzalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
569 if (!ent)
570 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571
David Howells09570f92011-07-27 21:47:03 +0300572 memcpy(ent->name, fn, len + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 ent->namelen = len;
574 ent->mode = mode;
575 ent->nlink = nlink;
Alexey Dobriyan5a622f22007-12-04 23:45:28 -0800576 atomic_set(&ent->count, 1);
Alexey Dobriyan786d7e12007-07-15 23:39:00 -0700577 spin_lock_init(&ent->pde_unload_lock);
Alexey Dobriyan881adb82008-07-25 01:48:29 -0700578 INIT_LIST_HEAD(&ent->pde_openers);
yan17baa2a2012-10-04 17:15:43 -0700579out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 return ent;
581}
582
583struct proc_dir_entry *proc_symlink(const char *name,
584 struct proc_dir_entry *parent, const char *dest)
585{
586 struct proc_dir_entry *ent;
587
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800588 ent = __proc_create(&parent, name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 (S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
590
591 if (ent) {
592 ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
593 if (ent->data) {
594 strcpy((char*)ent->data,dest);
595 if (proc_register(parent, ent) < 0) {
596 kfree(ent->data);
597 kfree(ent);
598 ent = NULL;
599 }
600 } else {
601 kfree(ent);
602 ent = NULL;
603 }
604 }
605 return ent;
606}
Helight.Xu587d4a12009-12-30 13:24:41 +0800607EXPORT_SYMBOL(proc_symlink);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Al Virod161a132011-07-24 03:36:29 -0400609struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 struct proc_dir_entry *parent)
611{
612 struct proc_dir_entry *ent;
613
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800614 ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 if (ent) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 if (proc_register(parent, ent) < 0) {
617 kfree(ent);
618 ent = NULL;
619 }
620 }
621 return ent;
622}
Alexey Dobriyan011159a2011-05-14 00:12:48 +0300623EXPORT_SYMBOL(proc_mkdir_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624
Denis V. Lunev78e92b92008-05-02 04:12:41 -0700625struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
626 struct proc_dir_entry *parent)
627{
628 struct proc_dir_entry *ent;
629
630 ent = __proc_create(&parent, name, S_IFDIR | S_IRUGO | S_IXUGO, 2);
631 if (ent) {
632 ent->data = net;
633 if (proc_register(parent, ent) < 0) {
634 kfree(ent);
635 ent = NULL;
636 }
637 }
638 return ent;
639}
640EXPORT_SYMBOL_GPL(proc_net_mkdir);
641
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642struct proc_dir_entry *proc_mkdir(const char *name,
643 struct proc_dir_entry *parent)
644{
645 return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
646}
Helight.Xu587d4a12009-12-30 13:24:41 +0800647EXPORT_SYMBOL(proc_mkdir);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648
David Howells80e928f2013-04-04 17:02:03 +0100649struct proc_dir_entry *create_proc_read_entry(
650 const char *name, umode_t mode, struct proc_dir_entry *parent,
651 read_proc_t *read_proc, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652{
653 struct proc_dir_entry *ent;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654
Al Virob6cdc732013-03-30 21:20:14 -0400655 if ((mode & S_IFMT) == 0)
656 mode |= S_IFREG;
657
658 if (!S_ISREG(mode)) {
659 WARN_ON(1); /* use proc_mkdir(), damnit */
660 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 }
662
Al Virob6cdc732013-03-30 21:20:14 -0400663 if ((mode & S_IALLUGO) == 0)
664 mode |= S_IRUGO;
665
666 ent = __proc_create(&parent, name, mode, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 if (ent) {
David Howells80e928f2013-04-04 17:02:03 +0100668 ent->read_proc = read_proc;
669 ent->data = data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 if (proc_register(parent, ent) < 0) {
671 kfree(ent);
672 ent = NULL;
673 }
674 }
675 return ent;
676}
David Howells80e928f2013-04-04 17:02:03 +0100677EXPORT_SYMBOL(create_proc_read_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678
Al Virod161a132011-07-24 03:36:29 -0400679struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
Denis V. Lunev59b74352008-04-29 01:02:00 -0700680 struct proc_dir_entry *parent,
681 const struct file_operations *proc_fops,
682 void *data)
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800683{
684 struct proc_dir_entry *pde;
Al Virob6cdc732013-03-30 21:20:14 -0400685 if ((mode & S_IFMT) == 0)
686 mode |= S_IFREG;
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800687
Al Virob6cdc732013-03-30 21:20:14 -0400688 if (!S_ISREG(mode)) {
689 WARN_ON(1); /* use proc_mkdir() */
690 return NULL;
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800691 }
692
Al Virob6cdc732013-03-30 21:20:14 -0400693 if ((mode & S_IALLUGO) == 0)
694 mode |= S_IRUGO;
695 pde = __proc_create(&parent, name, mode, 1);
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800696 if (!pde)
697 goto out;
698 pde->proc_fops = proc_fops;
Denis V. Lunev59b74352008-04-29 01:02:00 -0700699 pde->data = data;
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800700 if (proc_register(parent, pde) < 0)
701 goto out_free;
702 return pde;
703out_free:
704 kfree(pde);
705out:
706 return NULL;
707}
Helight.Xu587d4a12009-12-30 13:24:41 +0800708EXPORT_SYMBOL(proc_create_data);
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800709
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800710static void free_proc_entry(struct proc_dir_entry *de)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711{
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700712 proc_free_inum(de->low_ino);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713
Alexey Dobriyanfd2cbe42008-02-08 04:18:28 -0800714 if (S_ISLNK(de->mode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 kfree(de->data);
716 kfree(de);
717}
718
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800719void pde_put(struct proc_dir_entry *pde)
720{
721 if (atomic_dec_and_test(&pde->count))
722 free_proc_entry(pde);
723}
724
Al Viro8ce584c2013-03-30 20:13:46 -0400725static void entry_rundown(struct proc_dir_entry *de)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726{
Alexey Dobriyanf649d6d2008-04-29 01:01:39 -0700727 spin_lock(&de->pde_unload_lock);
728 /*
729 * Stop accepting new callers into module. If you're
730 * dynamically allocating ->proc_fops, save a pointer somewhere.
731 */
732 de->proc_fops = NULL;
733 /* Wait until all existing callers into module are done. */
734 if (de->pde_users > 0) {
735 DECLARE_COMPLETION_ONSTACK(c);
736
737 if (!de->pde_unload_completion)
738 de->pde_unload_completion = &c;
739
740 spin_unlock(&de->pde_unload_lock);
741
742 wait_for_completion(de->pde_unload_completion);
743
Alexey Dobriyan3740a202011-01-12 17:00:35 -0800744 spin_lock(&de->pde_unload_lock);
Alexey Dobriyanf649d6d2008-04-29 01:01:39 -0700745 }
Alexey Dobriyanf649d6d2008-04-29 01:01:39 -0700746
Alexey Dobriyan881adb82008-07-25 01:48:29 -0700747 while (!list_empty(&de->pde_openers)) {
748 struct pde_opener *pdeo;
749
750 pdeo = list_first_entry(&de->pde_openers, struct pde_opener, lh);
751 list_del(&pdeo->lh);
752 spin_unlock(&de->pde_unload_lock);
753 pdeo->release(pdeo->inode, pdeo->file);
754 kfree(pdeo);
755 spin_lock(&de->pde_unload_lock);
756 }
757 spin_unlock(&de->pde_unload_lock);
Al Viro8ce584c2013-03-30 20:13:46 -0400758}
759
760/*
761 * Remove a /proc entry and free it if it's not currently in use.
762 */
763void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
764{
765 struct proc_dir_entry **p;
766 struct proc_dir_entry *de = NULL;
767 const char *fn = name;
768 unsigned int len;
769
770 spin_lock(&proc_subdir_lock);
771 if (__xlate_proc_name(name, &parent, &fn) != 0) {
772 spin_unlock(&proc_subdir_lock);
773 return;
774 }
775 len = strlen(fn);
776
777 for (p = &parent->subdir; *p; p=&(*p)->next ) {
778 if (proc_match(len, fn, *p)) {
779 de = *p;
780 *p = de->next;
781 de->next = NULL;
782 break;
783 }
784 }
785 spin_unlock(&proc_subdir_lock);
786 if (!de) {
787 WARN(1, "name '%s'\n", name);
788 return;
789 }
790
791 entry_rundown(de);
Alexey Dobriyan881adb82008-07-25 01:48:29 -0700792
Alexey Dobriyanf649d6d2008-04-29 01:01:39 -0700793 if (S_ISDIR(de->mode))
794 parent->nlink--;
795 de->nlink = 0;
Andrew Morton87ebdc02013-02-27 17:03:16 -0800796 WARN(de->subdir, "%s: removing non-empty directory "
797 "'%s/%s', leaking at least '%s'\n", __func__,
798 de->parent->name, de->name, de->subdir->name);
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800799 pde_put(de);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800}
Helight.Xu587d4a12009-12-30 13:24:41 +0800801EXPORT_SYMBOL(remove_proc_entry);
Al Viro8ce584c2013-03-30 20:13:46 -0400802
803int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
804{
805 struct proc_dir_entry **p;
806 struct proc_dir_entry *root = NULL, *de, *next;
807 const char *fn = name;
808 unsigned int len;
809
810 spin_lock(&proc_subdir_lock);
811 if (__xlate_proc_name(name, &parent, &fn) != 0) {
812 spin_unlock(&proc_subdir_lock);
813 return -ENOENT;
814 }
815 len = strlen(fn);
816
817 for (p = &parent->subdir; *p; p=&(*p)->next ) {
818 if (proc_match(len, fn, *p)) {
819 root = *p;
820 *p = root->next;
821 root->next = NULL;
822 break;
823 }
824 }
825 if (!root) {
826 spin_unlock(&proc_subdir_lock);
827 return -ENOENT;
828 }
829 de = root;
830 while (1) {
831 next = de->subdir;
832 if (next) {
833 de->subdir = next->next;
834 next->next = NULL;
835 de = next;
836 continue;
837 }
838 spin_unlock(&proc_subdir_lock);
839
840 entry_rundown(de);
841 next = de->parent;
842 if (S_ISDIR(de->mode))
843 next->nlink--;
844 de->nlink = 0;
845 if (de == root)
846 break;
847 pde_put(de);
848
849 spin_lock(&proc_subdir_lock);
850 de = next;
851 }
852 pde_put(root);
853 return 0;
854}
855EXPORT_SYMBOL(remove_proc_subtree);