blob: 5453f1c0b70c95e3caa9d9744d316225815f8dfb [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;
Alexey Dobriyan8731f142008-04-29 01:01:58 -070074 if (dp->read_proc) {
Linus Torvalds1da177e2005-04-16 15:20:36 -070075 /*
76 * How to be a proc read function
77 * ------------------------------
78 * Prototype:
79 * int f(char *buffer, char **start, off_t offset,
80 * int count, int *peof, void *dat)
81 *
82 * Assume that the buffer is "count" bytes in size.
83 *
84 * If you know you have supplied all the data you
85 * have, set *peof.
86 *
87 * You have three ways to return data:
88 * 0) Leave *start = NULL. (This is the default.)
89 * Put the data of the requested offset at that
90 * offset within the buffer. Return the number (n)
91 * of bytes there are from the beginning of the
92 * buffer up to the last byte of data. If the
93 * number of supplied bytes (= n - offset) is
94 * greater than zero and you didn't signal eof
95 * and the reader is prepared to take more data
96 * you will be called again with the requested
97 * offset advanced by the number of bytes
98 * absorbed. This interface is useful for files
99 * no larger than the buffer.
100 * 1) Set *start = an unsigned long value less than
101 * the buffer address but greater than zero.
102 * Put the data of the requested offset at the
103 * beginning of the buffer. Return the number of
104 * bytes of data placed there. If this number is
105 * greater than zero and you didn't signal eof
106 * and the reader is prepared to take more data
107 * you will be called again with the requested
108 * offset advanced by *start. This interface is
109 * useful when you have a large file consisting
110 * of a series of blocks which you want to count
111 * and return as wholes.
112 * (Hack by Paul.Russell@rustcorp.com.au)
113 * 2) Set *start = an address within the buffer.
114 * Put the data of the requested offset at *start.
115 * Return the number of bytes of data placed there.
116 * If this number is greater than zero and you
117 * didn't signal eof and the reader is prepared to
118 * take more data you will be called again with the
119 * requested offset advanced by the number of bytes
120 * absorbed.
121 */
122 n = dp->read_proc(page, &start, *ppos,
123 count, &eof, dp->data);
124 } else
125 break;
126
127 if (n == 0) /* end of file */
128 break;
129 if (n < 0) { /* error */
130 if (retval == 0)
131 retval = n;
132 break;
133 }
134
135 if (start == NULL) {
Andrew Morton87ebdc02013-02-27 17:03:16 -0800136 if (n > PAGE_SIZE) /* Apparent buffer overflow */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 n = PAGE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 n -= *ppos;
139 if (n <= 0)
140 break;
141 if (n > count)
142 n = count;
143 start = page + *ppos;
144 } else if (start < page) {
Andrew Morton87ebdc02013-02-27 17:03:16 -0800145 if (n > PAGE_SIZE) /* Apparent buffer overflow */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 n = PAGE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147 if (n > count) {
148 /*
149 * Don't reduce n because doing so might
150 * cut off part of a data block.
151 */
Andrew Morton87ebdc02013-02-27 17:03:16 -0800152 pr_warn("proc_file_read: count exceeded\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 }
154 } else /* start >= page */ {
155 unsigned long startoff = (unsigned long)(start - page);
Andrew Morton87ebdc02013-02-27 17:03:16 -0800156 if (n > (PAGE_SIZE - startoff)) /* buffer overflow? */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 n = PAGE_SIZE - startoff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 if (n > count)
159 n = count;
160 }
161
162 n -= copy_to_user(buf, start < page ? page : start, n);
163 if (n == 0) {
164 if (retval == 0)
165 retval = -EFAULT;
166 break;
167 }
168
169 *ppos += start < page ? (unsigned long)start : n;
170 nbytes -= n;
171 buf += n;
172 retval += n;
173 }
174 free_page((unsigned long) page);
175 return retval;
176}
177
178static ssize_t
Alexey Dobriyan3dec7f52009-02-20 17:04:33 +0300179proc_file_read(struct file *file, char __user *buf, size_t nbytes,
180 loff_t *ppos)
181{
Al Viro496ad9a2013-01-23 17:07:38 -0500182 struct proc_dir_entry *pde = PDE(file_inode(file));
Alexey Dobriyan3dec7f52009-02-20 17:04:33 +0300183 ssize_t rv = -EIO;
184
185 spin_lock(&pde->pde_unload_lock);
186 if (!pde->proc_fops) {
187 spin_unlock(&pde->pde_unload_lock);
188 return rv;
189 }
190 pde->pde_users++;
191 spin_unlock(&pde->pde_unload_lock);
192
193 rv = __proc_file_read(file, buf, nbytes, ppos);
194
195 pde_users_dec(pde);
196 return rv;
197}
198
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199static loff_t
200proc_file_lseek(struct file *file, loff_t offset, int orig)
201{
Linus Torvalds8b90db02005-12-30 08:39:10 -0800202 loff_t retval = -EINVAL;
203 switch (orig) {
204 case 1:
205 offset += file->f_pos;
206 /* fallthrough */
207 case 0:
208 if (offset < 0 || offset > MAX_NON_LFS)
209 break;
210 file->f_pos = retval = offset;
211 }
212 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213}
214
Alexey Dobriyan76df0c22008-02-08 04:18:27 -0800215static const struct file_operations proc_file_operations = {
216 .llseek = proc_file_lseek,
217 .read = proc_file_read,
Alexey Dobriyan76df0c22008-02-08 04:18:27 -0800218};
219
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
221{
222 struct inode *inode = dentry->d_inode;
223 struct proc_dir_entry *de = PDE(inode);
224 int error;
225
226 error = inode_change_ok(inode, iattr);
227 if (error)
Christoph Hellwig10257742010-06-04 11:30:02 +0200228 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
Christoph Hellwig10257742010-06-04 11:30:02 +0200230 setattr_copy(inode, iattr);
231 mark_inode_dirty(inode);
Marco Stornelli46f69552012-12-15 11:48:48 +0100232
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233 de->uid = inode->i_uid;
234 de->gid = inode->i_gid;
235 de->mode = inode->i_mode;
Christoph Hellwig10257742010-06-04 11:30:02 +0200236 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237}
238
Miklos Szeredi2b579be2005-09-06 15:17:18 -0700239static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry,
240 struct kstat *stat)
241{
242 struct inode *inode = dentry->d_inode;
243 struct proc_dir_entry *de = PROC_I(inode)->pde;
244 if (de && de->nlink)
Miklos Szeredibfe86842011-10-28 14:13:29 +0200245 set_nlink(inode, de->nlink);
Miklos Szeredi2b579be2005-09-06 15:17:18 -0700246
247 generic_fillattr(inode, stat);
248 return 0;
249}
250
Arjan van de Venc5ef1c42007-02-12 00:55:40 -0800251static const struct inode_operations proc_file_inode_operations = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 .setattr = proc_notify_change,
253};
254
255/*
256 * This function parses a name such as "tty/driver/serial", and
257 * returns the struct proc_dir_entry for "/proc/tty/driver", and
258 * returns "serial" in residual.
259 */
Alexey Dobriyane17a5762010-03-05 13:43:59 -0800260static int __xlate_proc_name(const char *name, struct proc_dir_entry **ret,
261 const char **residual)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262{
263 const char *cp = name, *next;
264 struct proc_dir_entry *de;
Alexey Dobriyan312ec7e2011-03-23 16:42:52 -0700265 unsigned int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266
Alexey Dobriyan7cee4e02008-04-29 01:01:40 -0700267 de = *ret;
268 if (!de)
269 de = &proc_root;
270
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 while (1) {
272 next = strchr(cp, '/');
273 if (!next)
274 break;
275
276 len = next - cp;
277 for (de = de->subdir; de ; de = de->next) {
278 if (proc_match(len, cp, de))
279 break;
280 }
Alexey Dobriyan12bac0d2010-03-05 13:44:00 -0800281 if (!de) {
282 WARN(1, "name '%s'\n", name);
Alexey Dobriyane17a5762010-03-05 13:43:59 -0800283 return -ENOENT;
Alexey Dobriyan12bac0d2010-03-05 13:44:00 -0800284 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 cp += len + 1;
286 }
287 *residual = cp;
288 *ret = de;
Alexey Dobriyane17a5762010-03-05 13:43:59 -0800289 return 0;
290}
291
292static int xlate_proc_name(const char *name, struct proc_dir_entry **ret,
293 const char **residual)
294{
295 int rv;
296
297 spin_lock(&proc_subdir_lock);
298 rv = __xlate_proc_name(name, ret, residual);
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800299 spin_unlock(&proc_subdir_lock);
Alexey Dobriyane17a5762010-03-05 13:43:59 -0800300 return rv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301}
302
Alexey Dobriyan9a185402008-07-26 11:21:37 +0400303static DEFINE_IDA(proc_inum_ida);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */
305
Alexey Dobriyan67935df2008-07-26 11:18:28 +0400306#define PROC_DYNAMIC_FIRST 0xF0000000U
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307
308/*
309 * Return an inode number between PROC_DYNAMIC_FIRST and
310 * 0xffffffff, or zero on failure.
311 */
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700312int proc_alloc_inum(unsigned int *inum)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313{
Alexey Dobriyan67935df2008-07-26 11:18:28 +0400314 unsigned int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 int error;
316
317retry:
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700318 if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL))
319 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320
Eric W. Biedermandfb2ea42012-12-21 20:38:00 -0800321 spin_lock_irq(&proc_inum_lock);
Alexey Dobriyan9a185402008-07-26 11:21:37 +0400322 error = ida_get_new(&proc_inum_ida, &i);
Eric W. Biedermandfb2ea42012-12-21 20:38:00 -0800323 spin_unlock_irq(&proc_inum_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 if (error == -EAGAIN)
325 goto retry;
326 else if (error)
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700327 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328
Alexey Dobriyan67935df2008-07-26 11:18:28 +0400329 if (i > UINT_MAX - PROC_DYNAMIC_FIRST) {
Eric W. Biedermandfb2ea42012-12-21 20:38:00 -0800330 spin_lock_irq(&proc_inum_lock);
Alexey Dobriyan9a185402008-07-26 11:21:37 +0400331 ida_remove(&proc_inum_ida, i);
Eric W. Biedermandfb2ea42012-12-21 20:38:00 -0800332 spin_unlock_irq(&proc_inum_lock);
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700333 return -ENOSPC;
Alexey Dobriyan67935df2008-07-26 11:18:28 +0400334 }
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700335 *inum = PROC_DYNAMIC_FIRST + i;
336 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337}
338
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700339void proc_free_inum(unsigned int inum)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340{
Eric W. Biedermandfb2ea42012-12-21 20:38:00 -0800341 unsigned long flags;
342 spin_lock_irqsave(&proc_inum_lock, flags);
Alexey Dobriyan9a185402008-07-26 11:21:37 +0400343 ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST);
Eric W. Biedermandfb2ea42012-12-21 20:38:00 -0800344 spin_unlock_irqrestore(&proc_inum_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345}
346
Al Viro008b1502005-08-20 00:17:39 +0100347static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348{
Al Virod9dda782013-03-31 18:16:14 -0400349 nd_set_link(nd, PDE_DATA(dentry->d_inode));
Al Viro008b1502005-08-20 00:17:39 +0100350 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351}
352
Arjan van de Venc5ef1c42007-02-12 00:55:40 -0800353static const struct inode_operations proc_link_inode_operations = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 .readlink = generic_readlink,
355 .follow_link = proc_follow_link,
356};
357
358/*
359 * As some entries in /proc are volatile, we want to
360 * get rid of unused dentries. This could be made
361 * smarter: we could keep a "volatile" flag in the
362 * inode to indicate which ones to keep.
363 */
Nick Pigginfe15ce42011-01-07 17:49:23 +1100364static int proc_delete_dentry(const struct dentry * dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365{
366 return 1;
367}
368
Al Virod72f71e2009-02-20 05:58:47 +0000369static const struct dentry_operations proc_dentry_operations =
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370{
371 .d_delete = proc_delete_dentry,
372};
373
374/*
375 * Don't create negative dentries here, return -ENOENT by hand
376 * instead.
377 */
Pavel Emelyanove9720ac2008-03-07 11:08:40 -0800378struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
379 struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380{
Al Virod3d009c2013-01-25 20:11:22 -0500381 struct inode *inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800383 spin_lock(&proc_subdir_lock);
Alexey Dobriyan5e971dc2008-04-29 01:01:41 -0700384 for (de = de->subdir; de ; de = de->next) {
385 if (de->namelen != dentry->d_name.len)
386 continue;
387 if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800388 pde_get(de);
Alexey Dobriyan5e971dc2008-04-29 01:01:41 -0700389 spin_unlock(&proc_subdir_lock);
Alexey Dobriyan6d1b6e42011-01-12 17:00:33 -0800390 inode = proc_get_inode(dir->i_sb, de);
Al Virod3d009c2013-01-25 20:11:22 -0500391 if (!inode)
392 return ERR_PTR(-ENOMEM);
393 d_set_d_op(dentry, &proc_dentry_operations);
394 d_add(dentry, inode);
395 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 }
397 }
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800398 spin_unlock(&proc_subdir_lock);
Al Virod3d009c2013-01-25 20:11:22 -0500399 return ERR_PTR(-ENOENT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400}
401
Pavel Emelyanove9720ac2008-03-07 11:08:40 -0800402struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
Al Viro00cd8dd2012-06-10 17:13:09 -0400403 unsigned int flags)
Pavel Emelyanove9720ac2008-03-07 11:08:40 -0800404{
405 return proc_lookup_de(PDE(dir), dir, dentry);
406}
407
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408/*
409 * This returns non-zero if at EOF, so that the /proc
410 * root directory can use this and check if it should
411 * continue with the <pid> entries..
412 *
413 * Note that the VFS-layer doesn't care about the return
414 * value of the readdir() call, as long as it's non-negative
415 * for success..
416 */
Pavel Emelyanove9720ac2008-03-07 11:08:40 -0800417int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,
418 filldir_t filldir)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 unsigned int ino;
421 int i;
Al Viro496ad9a2013-01-23 17:07:38 -0500422 struct inode *inode = file_inode(filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 int ret = 0;
424
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 ino = inode->i_ino;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 i = filp->f_pos;
427 switch (i) {
428 case 0:
429 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
430 goto out;
431 i++;
432 filp->f_pos++;
433 /* fall through */
434 case 1:
435 if (filldir(dirent, "..", 2, i,
Josef "Jeff" Sipek2fddfee2006-12-08 02:36:36 -0800436 parent_ino(filp->f_path.dentry),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 DT_DIR) < 0)
438 goto out;
439 i++;
440 filp->f_pos++;
441 /* fall through */
442 default:
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800443 spin_lock(&proc_subdir_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 de = de->subdir;
445 i -= 2;
446 for (;;) {
447 if (!de) {
448 ret = 1;
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800449 spin_unlock(&proc_subdir_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 goto out;
451 }
452 if (!i)
453 break;
454 de = de->next;
455 i--;
456 }
457
458 do {
Darrick J. Wong59cd0cb2007-05-08 00:25:47 -0700459 struct proc_dir_entry *next;
460
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800461 /* filldir passes info to user space */
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800462 pde_get(de);
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800463 spin_unlock(&proc_subdir_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 if (filldir(dirent, de->name, de->namelen, filp->f_pos,
Darrick J. Wong59cd0cb2007-05-08 00:25:47 -0700465 de->low_ino, de->mode >> 12) < 0) {
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800466 pde_put(de);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 goto out;
Darrick J. Wong59cd0cb2007-05-08 00:25:47 -0700468 }
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800469 spin_lock(&proc_subdir_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 filp->f_pos++;
Darrick J. Wong59cd0cb2007-05-08 00:25:47 -0700471 next = de->next;
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800472 pde_put(de);
Darrick J. Wong59cd0cb2007-05-08 00:25:47 -0700473 de = next;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 } while (de);
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800475 spin_unlock(&proc_subdir_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 }
477 ret = 1;
Alexey Dobriyanb4df2b92008-10-27 22:48:36 +0300478out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 return ret;
480}
481
Pavel Emelyanove9720ac2008-03-07 11:08:40 -0800482int proc_readdir(struct file *filp, void *dirent, filldir_t filldir)
483{
Al Viro496ad9a2013-01-23 17:07:38 -0500484 struct inode *inode = file_inode(filp);
Pavel Emelyanove9720ac2008-03-07 11:08:40 -0800485
486 return proc_readdir_de(PDE(inode), filp, dirent, filldir);
487}
488
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489/*
490 * These are the generic /proc directory operations. They
491 * use the in-memory "struct proc_dir_entry" tree to parse
492 * the /proc directory.
493 */
Arjan van de Ven00977a52007-02-12 00:55:34 -0800494static const struct file_operations proc_dir_operations = {
Alexey Dobriyanb4df2b92008-10-27 22:48:36 +0300495 .llseek = generic_file_llseek,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 .read = generic_read_dir,
497 .readdir = proc_readdir,
498};
499
500/*
501 * proc directories can do almost nothing..
502 */
Arjan van de Venc5ef1c42007-02-12 00:55:40 -0800503static const struct inode_operations proc_dir_inode_operations = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 .lookup = proc_lookup,
Miklos Szeredi2b579be2005-09-06 15:17:18 -0700505 .getattr = proc_getattr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 .setattr = proc_notify_change,
507};
508
509static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
510{
Zhang Rui94413d82008-02-08 04:18:29 -0800511 struct proc_dir_entry *tmp;
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700512 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700514 ret = proc_alloc_inum(&dp->low_ino);
515 if (ret)
516 return ret;
Steven Rostedt64a07bd2006-03-26 01:36:55 -0800517
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 if (S_ISDIR(dp->mode)) {
Al Virob6cdc732013-03-30 21:20:14 -0400519 dp->proc_fops = &proc_dir_operations;
520 dp->proc_iops = &proc_dir_inode_operations;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 dir->nlink++;
522 } else if (S_ISLNK(dp->mode)) {
Al Virob6cdc732013-03-30 21:20:14 -0400523 dp->proc_iops = &proc_link_inode_operations;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 } else if (S_ISREG(dp->mode)) {
525 if (dp->proc_fops == NULL)
526 dp->proc_fops = &proc_file_operations;
Al Virob6cdc732013-03-30 21:20:14 -0400527 dp->proc_iops = &proc_file_inode_operations;
528 } else {
529 WARN_ON(1);
530 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 }
Changli Gao99fc06d2007-07-15 23:40:09 -0700532
533 spin_lock(&proc_subdir_lock);
Zhang Rui94413d82008-02-08 04:18:29 -0800534
535 for (tmp = dir->subdir; tmp; tmp = tmp->next)
536 if (strcmp(tmp->name, dp->name) == 0) {
Andrew Morton87ebdc02013-02-27 17:03:16 -0800537 WARN(1, "proc_dir_entry '%s/%s' already registered\n",
Alexey Dobriyan665020c2008-09-13 02:33:06 -0700538 dir->name, dp->name);
Zhang Rui94413d82008-02-08 04:18:29 -0800539 break;
540 }
541
Changli Gao99fc06d2007-07-15 23:40:09 -0700542 dp->next = dir->subdir;
543 dp->parent = dir;
544 dir->subdir = dp;
545 spin_unlock(&proc_subdir_lock);
546
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 return 0;
548}
549
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800550static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 const char *name,
Al Virod161a132011-07-24 03:36:29 -0400552 umode_t mode,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 nlink_t nlink)
554{
555 struct proc_dir_entry *ent = NULL;
556 const char *fn = name;
Alexey Dobriyan312ec7e2011-03-23 16:42:52 -0700557 unsigned int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
559 /* make sure name is valid */
yan17baa2a2012-10-04 17:15:43 -0700560 if (!name || !strlen(name))
561 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562
Alexey Dobriyan7cee4e02008-04-29 01:01:40 -0700563 if (xlate_proc_name(name, parent, &fn) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 goto out;
565
566 /* At this point there must not be any '/' characters beyond *fn */
567 if (strchr(fn, '/'))
568 goto out;
569
570 len = strlen(fn);
571
yan17baa2a2012-10-04 17:15:43 -0700572 ent = kzalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
573 if (!ent)
574 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575
David Howells09570f92011-07-27 21:47:03 +0300576 memcpy(ent->name, fn, len + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 ent->namelen = len;
578 ent->mode = mode;
579 ent->nlink = nlink;
Alexey Dobriyan5a622f22007-12-04 23:45:28 -0800580 atomic_set(&ent->count, 1);
Alexey Dobriyan786d7e12007-07-15 23:39:00 -0700581 spin_lock_init(&ent->pde_unload_lock);
Alexey Dobriyan881adb82008-07-25 01:48:29 -0700582 INIT_LIST_HEAD(&ent->pde_openers);
yan17baa2a2012-10-04 17:15:43 -0700583out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 return ent;
585}
586
587struct proc_dir_entry *proc_symlink(const char *name,
588 struct proc_dir_entry *parent, const char *dest)
589{
590 struct proc_dir_entry *ent;
591
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800592 ent = __proc_create(&parent, name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593 (S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
594
595 if (ent) {
596 ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
597 if (ent->data) {
598 strcpy((char*)ent->data,dest);
599 if (proc_register(parent, ent) < 0) {
600 kfree(ent->data);
601 kfree(ent);
602 ent = NULL;
603 }
604 } else {
605 kfree(ent);
606 ent = NULL;
607 }
608 }
609 return ent;
610}
Helight.Xu587d4a12009-12-30 13:24:41 +0800611EXPORT_SYMBOL(proc_symlink);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
Al Virod161a132011-07-24 03:36:29 -0400613struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 struct proc_dir_entry *parent)
615{
616 struct proc_dir_entry *ent;
617
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800618 ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 if (ent) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 if (proc_register(parent, ent) < 0) {
621 kfree(ent);
622 ent = NULL;
623 }
624 }
625 return ent;
626}
Alexey Dobriyan011159a2011-05-14 00:12:48 +0300627EXPORT_SYMBOL(proc_mkdir_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628
Denis V. Lunev78e92b92008-05-02 04:12:41 -0700629struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
630 struct proc_dir_entry *parent)
631{
632 struct proc_dir_entry *ent;
633
634 ent = __proc_create(&parent, name, S_IFDIR | S_IRUGO | S_IXUGO, 2);
635 if (ent) {
636 ent->data = net;
637 if (proc_register(parent, ent) < 0) {
638 kfree(ent);
639 ent = NULL;
640 }
641 }
642 return ent;
643}
644EXPORT_SYMBOL_GPL(proc_net_mkdir);
645
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646struct proc_dir_entry *proc_mkdir(const char *name,
647 struct proc_dir_entry *parent)
648{
649 return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
650}
Helight.Xu587d4a12009-12-30 13:24:41 +0800651EXPORT_SYMBOL(proc_mkdir);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652
David Howells80e928f2013-04-04 17:02:03 +0100653struct proc_dir_entry *create_proc_read_entry(
654 const char *name, umode_t mode, struct proc_dir_entry *parent,
655 read_proc_t *read_proc, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656{
657 struct proc_dir_entry *ent;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658
Al Virob6cdc732013-03-30 21:20:14 -0400659 if ((mode & S_IFMT) == 0)
660 mode |= S_IFREG;
661
662 if (!S_ISREG(mode)) {
663 WARN_ON(1); /* use proc_mkdir(), damnit */
664 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 }
666
Al Virob6cdc732013-03-30 21:20:14 -0400667 if ((mode & S_IALLUGO) == 0)
668 mode |= S_IRUGO;
669
670 ent = __proc_create(&parent, name, mode, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 if (ent) {
David Howells80e928f2013-04-04 17:02:03 +0100672 ent->read_proc = read_proc;
673 ent->data = data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 if (proc_register(parent, ent) < 0) {
675 kfree(ent);
676 ent = NULL;
677 }
678 }
679 return ent;
680}
David Howells80e928f2013-04-04 17:02:03 +0100681EXPORT_SYMBOL(create_proc_read_entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682
Al Virod161a132011-07-24 03:36:29 -0400683struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
Denis V. Lunev59b74352008-04-29 01:02:00 -0700684 struct proc_dir_entry *parent,
685 const struct file_operations *proc_fops,
686 void *data)
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800687{
688 struct proc_dir_entry *pde;
Al Virob6cdc732013-03-30 21:20:14 -0400689 if ((mode & S_IFMT) == 0)
690 mode |= S_IFREG;
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800691
Al Virob6cdc732013-03-30 21:20:14 -0400692 if (!S_ISREG(mode)) {
693 WARN_ON(1); /* use proc_mkdir() */
694 return NULL;
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800695 }
696
Al Virob6cdc732013-03-30 21:20:14 -0400697 if ((mode & S_IALLUGO) == 0)
698 mode |= S_IRUGO;
699 pde = __proc_create(&parent, name, mode, 1);
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800700 if (!pde)
701 goto out;
702 pde->proc_fops = proc_fops;
Denis V. Lunev59b74352008-04-29 01:02:00 -0700703 pde->data = data;
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800704 if (proc_register(parent, pde) < 0)
705 goto out_free;
706 return pde;
707out_free:
708 kfree(pde);
709out:
710 return NULL;
711}
Helight.Xu587d4a12009-12-30 13:24:41 +0800712EXPORT_SYMBOL(proc_create_data);
Alexey Dobriyan2d3a4e32008-02-08 04:18:37 -0800713
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800714static void free_proc_entry(struct proc_dir_entry *de)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715{
Eric W. Biederman33d6dce2011-06-17 13:33:20 -0700716 proc_free_inum(de->low_ino);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717
Alexey Dobriyanfd2cbe42008-02-08 04:18:28 -0800718 if (S_ISLNK(de->mode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 kfree(de->data);
720 kfree(de);
721}
722
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800723void pde_put(struct proc_dir_entry *pde)
724{
725 if (atomic_dec_and_test(&pde->count))
726 free_proc_entry(pde);
727}
728
Al Viro8ce584c2013-03-30 20:13:46 -0400729static void entry_rundown(struct proc_dir_entry *de)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730{
Alexey Dobriyanf649d6d2008-04-29 01:01:39 -0700731 spin_lock(&de->pde_unload_lock);
732 /*
733 * Stop accepting new callers into module. If you're
734 * dynamically allocating ->proc_fops, save a pointer somewhere.
735 */
736 de->proc_fops = NULL;
737 /* Wait until all existing callers into module are done. */
738 if (de->pde_users > 0) {
739 DECLARE_COMPLETION_ONSTACK(c);
740
741 if (!de->pde_unload_completion)
742 de->pde_unload_completion = &c;
743
744 spin_unlock(&de->pde_unload_lock);
745
746 wait_for_completion(de->pde_unload_completion);
747
Alexey Dobriyan3740a202011-01-12 17:00:35 -0800748 spin_lock(&de->pde_unload_lock);
Alexey Dobriyanf649d6d2008-04-29 01:01:39 -0700749 }
Alexey Dobriyanf649d6d2008-04-29 01:01:39 -0700750
Alexey Dobriyan881adb82008-07-25 01:48:29 -0700751 while (!list_empty(&de->pde_openers)) {
752 struct pde_opener *pdeo;
753
754 pdeo = list_first_entry(&de->pde_openers, struct pde_opener, lh);
755 list_del(&pdeo->lh);
756 spin_unlock(&de->pde_unload_lock);
757 pdeo->release(pdeo->inode, pdeo->file);
758 kfree(pdeo);
759 spin_lock(&de->pde_unload_lock);
760 }
761 spin_unlock(&de->pde_unload_lock);
Al Viro8ce584c2013-03-30 20:13:46 -0400762}
763
764/*
765 * Remove a /proc entry and free it if it's not currently in use.
766 */
767void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
768{
769 struct proc_dir_entry **p;
770 struct proc_dir_entry *de = NULL;
771 const char *fn = name;
772 unsigned int len;
773
774 spin_lock(&proc_subdir_lock);
775 if (__xlate_proc_name(name, &parent, &fn) != 0) {
776 spin_unlock(&proc_subdir_lock);
777 return;
778 }
779 len = strlen(fn);
780
781 for (p = &parent->subdir; *p; p=&(*p)->next ) {
782 if (proc_match(len, fn, *p)) {
783 de = *p;
784 *p = de->next;
785 de->next = NULL;
786 break;
787 }
788 }
789 spin_unlock(&proc_subdir_lock);
790 if (!de) {
791 WARN(1, "name '%s'\n", name);
792 return;
793 }
794
795 entry_rundown(de);
Alexey Dobriyan881adb82008-07-25 01:48:29 -0700796
Alexey Dobriyanf649d6d2008-04-29 01:01:39 -0700797 if (S_ISDIR(de->mode))
798 parent->nlink--;
799 de->nlink = 0;
Andrew Morton87ebdc02013-02-27 17:03:16 -0800800 WARN(de->subdir, "%s: removing non-empty directory "
801 "'%s/%s', leaking at least '%s'\n", __func__,
802 de->parent->name, de->name, de->subdir->name);
Alexey Dobriyan135d5652009-12-15 16:45:39 -0800803 pde_put(de);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804}
Helight.Xu587d4a12009-12-30 13:24:41 +0800805EXPORT_SYMBOL(remove_proc_entry);
Al Viro8ce584c2013-03-30 20:13:46 -0400806
807int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
808{
809 struct proc_dir_entry **p;
810 struct proc_dir_entry *root = NULL, *de, *next;
811 const char *fn = name;
812 unsigned int len;
813
814 spin_lock(&proc_subdir_lock);
815 if (__xlate_proc_name(name, &parent, &fn) != 0) {
816 spin_unlock(&proc_subdir_lock);
817 return -ENOENT;
818 }
819 len = strlen(fn);
820
821 for (p = &parent->subdir; *p; p=&(*p)->next ) {
822 if (proc_match(len, fn, *p)) {
823 root = *p;
824 *p = root->next;
825 root->next = NULL;
826 break;
827 }
828 }
829 if (!root) {
830 spin_unlock(&proc_subdir_lock);
831 return -ENOENT;
832 }
833 de = root;
834 while (1) {
835 next = de->subdir;
836 if (next) {
837 de->subdir = next->next;
838 next->next = NULL;
839 de = next;
840 continue;
841 }
842 spin_unlock(&proc_subdir_lock);
843
844 entry_rundown(de);
845 next = de->parent;
846 if (S_ISDIR(de->mode))
847 next->nlink--;
848 de->nlink = 0;
849 if (de == root)
850 break;
851 pde_put(de);
852
853 spin_lock(&proc_subdir_lock);
854 de = next;
855 }
856 pde_put(root);
857 return 0;
858}
859EXPORT_SYMBOL(remove_proc_subtree);