make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / fs / proc / generic.c
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 <asm/uaccess.h>
12
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/proc_fs.h>
16 #include <linux/stat.h>
17 #define __NO_VERSION__
18 #include <linux/module.h>
19 #include <asm/bitops.h>
20
21 static ssize_t proc_file_read(struct file * file, char * buf,
22                               size_t nbytes, loff_t *ppos);
23 static ssize_t proc_file_write(struct file * file, const char * buffer,
24                                size_t count, loff_t *ppos);
25 static loff_t proc_file_lseek(struct file *, loff_t, int);
26
27 int proc_match(int len, const char *name,struct proc_dir_entry * de)
28 {
29         if (!de || !de->low_ino)
30                 return 0;
31         if (de->namelen != len)
32                 return 0;
33         return !memcmp(name, de->name, len);
34 }
35
36 static struct file_operations proc_file_operations = {
37         llseek:         proc_file_lseek,
38         read:           proc_file_read,
39         write:          proc_file_write,
40 };
41
42 #ifndef MIN
43 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
44 #endif
45
46 /* buffer size is one page but our output routines use some slack for overruns */
47 #define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
48
49 static ssize_t
50 proc_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
51 {
52         struct inode * inode = file->f_dentry->d_inode;
53         char    *page;
54         ssize_t retval=0;
55         int     eof=0;
56         ssize_t n, count;
57         char    *start;
58         struct proc_dir_entry * dp;
59
60         dp = (struct proc_dir_entry *) inode->u.generic_ip;
61         if (!(page = (char*) __get_free_page(GFP_KERNEL)))
62                 return -ENOMEM;
63
64         while ((nbytes > 0) && !eof)
65         {
66                 count = MIN(PROC_BLOCK_SIZE, nbytes);
67
68                 start = NULL;
69                 if (dp->get_info) {
70                         /*
71                          * Handle backwards compatibility with the old net
72                          * routines.
73                          */
74                         n = dp->get_info(page, &start, *ppos, count);
75                         if (n < count)
76                                 eof = 1;
77                 } else if (dp->read_proc) {
78                         n = dp->read_proc(page, &start, *ppos,
79                                           count, &eof, dp->data);
80                 } else
81                         break;
82
83                 if (!start) {
84                         /*
85                          * For proc files that are less than 4k
86                          */
87                         start = page + *ppos;
88                         n -= *ppos;
89                         if (n <= 0)
90                                 break;
91                         if (n > count)
92                                 n = count;
93                 }
94                 if (n == 0)
95                         break;  /* End of file */
96                 if (n < 0) {
97                         if (retval == 0)
98                                 retval = n;
99                         break;
100                 }
101                 
102                 /* This is a hack to allow mangling of file pos independent
103                  * of actual bytes read.  Simply place the data at page,
104                  * return the bytes, and set `start' to the desired offset
105                  * as an unsigned int. - Paul.Russell@rustcorp.com.au
106                  */
107                 n -= copy_to_user(buf, start < page ? page : start, n);
108                 if (n == 0) {
109                         if (retval == 0)
110                                 retval = -EFAULT;
111                         break;
112                 }
113
114                 *ppos += start < page ? (long)start : n; /* Move down the file */
115                 nbytes -= n;
116                 buf += n;
117                 retval += n;
118         }
119         free_page((unsigned long) page);
120         return retval;
121 }
122
123 static ssize_t
124 proc_file_write(struct file * file, const char * buffer,
125                 size_t count, loff_t *ppos)
126 {
127         struct inode *inode = file->f_dentry->d_inode;
128         struct proc_dir_entry * dp;
129         
130         dp = (struct proc_dir_entry *) inode->u.generic_ip;
131
132         if (!dp->write_proc)
133                 return -EIO;
134
135         /* FIXME: does this routine need ppos?  probably... */
136         return dp->write_proc(file, buffer, count, dp->data);
137 }
138
139
140 static loff_t
141 proc_file_lseek(struct file * file, loff_t offset, int origin)
142 {
143         long long retval;
144
145         switch (origin) {
146                 case 2:
147                         offset += file->f_dentry->d_inode->i_size;
148                         break;
149                 case 1:
150                         offset += file->f_pos;
151         }
152         retval = -EINVAL;
153         if (offset>=0 && offset<=file->f_dentry->d_inode->i_sb->s_maxbytes) {
154                 if (offset != file->f_pos) {
155                         file->f_pos = offset;
156                         file->f_reada = 0;
157                 }
158                 retval = offset;
159         }
160         return retval;
161 }
162
163 /*
164  * This function parses a name such as "tty/driver/serial", and
165  * returns the struct proc_dir_entry for "/proc/tty/driver", and
166  * returns "serial" in residual.
167  */
168 static int xlate_proc_name(const char *name,
169                            struct proc_dir_entry **ret, const char **residual)
170 {
171         const char              *cp = name, *next;
172         struct proc_dir_entry   *de;
173         int                     len;
174
175         de = &proc_root;
176         while (1) {
177                 next = strchr(cp, '/');
178                 if (!next)
179                         break;
180
181                 len = next - cp;
182                 for (de = de->subdir; de ; de = de->next) {
183                         if (proc_match(len, cp, de))
184                                 break;
185                 }
186                 if (!de)
187                         return -ENOENT;
188                 cp += len + 1;
189         }
190         *residual = cp;
191         *ret = de;
192         return 0;
193 }
194
195 static unsigned long proc_alloc_map[(PROC_NDYNAMIC + BITS_PER_LONG - 1) / BITS_PER_LONG];
196
197 spinlock_t proc_alloc_map_lock = SPIN_LOCK_UNLOCKED;
198
199 static int make_inode_number(void)
200 {
201         int i;
202         spin_lock(&proc_alloc_map_lock);
203         i = find_first_zero_bit(proc_alloc_map, PROC_NDYNAMIC);
204         if (i < 0 || i >= PROC_NDYNAMIC) {
205                 i = -1;
206                 goto out;
207         }
208         set_bit(i, proc_alloc_map);
209         i += PROC_DYNAMIC_FIRST;
210 out:
211         spin_unlock(&proc_alloc_map_lock);
212         return i;
213 }
214
215 static int proc_readlink(struct dentry *dentry, char *buffer, int buflen)
216 {
217         char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data;
218         return vfs_readlink(dentry, buffer, buflen, s);
219 }
220
221 static int proc_follow_link(struct dentry *dentry, struct nameidata *nd)
222 {
223         char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data;
224         return vfs_follow_link(nd, s);
225 }
226
227 static struct inode_operations proc_link_inode_operations = {
228         readlink:       proc_readlink,
229         follow_link:    proc_follow_link,
230 };
231
232 /*
233  * As some entries in /proc are volatile, we want to 
234  * get rid of unused dentries.  This could be made 
235  * smarter: we could keep a "volatile" flag in the 
236  * inode to indicate which ones to keep.
237  */
238 static int proc_delete_dentry(struct dentry * dentry)
239 {
240         return 1;
241 }
242
243 static struct dentry_operations proc_dentry_operations =
244 {
245         d_delete:       proc_delete_dentry,
246 };
247
248 /*
249  * Don't create negative dentries here, return -ENOENT by hand
250  * instead.
251  */
252 struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry)
253 {
254         struct inode *inode;
255         struct proc_dir_entry * de;
256         int error;
257
258         error = -ENOENT;
259         inode = NULL;
260         de = (struct proc_dir_entry *) dir->u.generic_ip;
261         if (de) {
262                 for (de = de->subdir; de ; de = de->next) {
263                         if (!de || !de->low_ino)
264                                 continue;
265                         if (de->namelen != dentry->d_name.len)
266                                 continue;
267                         if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
268                                 int ino = de->low_ino;
269                                 error = -EINVAL;
270                                 inode = proc_get_inode(dir->i_sb, ino, de);
271                                 break;
272                         }
273                 }
274         }
275
276         if (inode) {
277                 dentry->d_op = &proc_dentry_operations;
278                 d_add(dentry, inode);
279                 return NULL;
280         }
281         return ERR_PTR(error);
282 }
283
284 /*
285  * This returns non-zero if at EOF, so that the /proc
286  * root directory can use this and check if it should
287  * continue with the <pid> entries..
288  *
289  * Note that the VFS-layer doesn't care about the return
290  * value of the readdir() call, as long as it's non-negative
291  * for success..
292  */
293 int proc_readdir(struct file * filp,
294         void * dirent, filldir_t filldir)
295 {
296         struct proc_dir_entry * de;
297         unsigned int ino;
298         int i;
299         struct inode *inode = filp->f_dentry->d_inode;
300
301         ino = inode->i_ino;
302         de = (struct proc_dir_entry *) inode->u.generic_ip;
303         if (!de)
304                 return -EINVAL;
305         i = filp->f_pos;
306         switch (i) {
307                 case 0:
308                         if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
309                                 return 0;
310                         i++;
311                         filp->f_pos++;
312                         /* fall through */
313                 case 1:
314                         if (filldir(dirent, "..", 2, i,
315                                     filp->f_dentry->d_parent->d_inode->i_ino,
316                                     DT_DIR) < 0)
317                                 return 0;
318                         i++;
319                         filp->f_pos++;
320                         /* fall through */
321                 default:
322                         de = de->subdir;
323                         i -= 2;
324                         for (;;) {
325                                 if (!de)
326                                         return 1;
327                                 if (!i)
328                                         break;
329                                 de = de->next;
330                                 i--;
331                         }
332
333                         do {
334                                 if (filldir(dirent, de->name, de->namelen, filp->f_pos,
335                                             de->low_ino, de->mode >> 12) < 0)
336                                         return 0;
337                                 filp->f_pos++;
338                                 de = de->next;
339                         } while (de);
340         }
341         return 1;
342 }
343
344 /*
345  * These are the generic /proc directory operations. They
346  * use the in-memory "struct proc_dir_entry" tree to parse
347  * the /proc directory.
348  */
349 static struct file_operations proc_dir_operations = {
350         read:                   generic_read_dir,
351         readdir:                proc_readdir,
352 };
353
354 /*
355  * proc directories can do almost nothing..
356  */
357 static struct inode_operations proc_dir_inode_operations = {
358         lookup:         proc_lookup,
359 };
360
361 static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
362 {
363         int     i;
364         
365         i = make_inode_number();
366         if (i < 0)
367                 return -EAGAIN;
368         dp->low_ino = i;
369         dp->next = dir->subdir;
370         dp->parent = dir;
371         dir->subdir = dp;
372         if (S_ISDIR(dp->mode)) {
373                 if (dp->proc_iops == NULL) {
374                         dp->proc_fops = &proc_dir_operations;
375                         dp->proc_iops = &proc_dir_inode_operations;
376                 }
377                 dir->nlink++;
378         } else if (S_ISLNK(dp->mode)) {
379                 if (dp->proc_iops == NULL)
380                         dp->proc_iops = &proc_link_inode_operations;
381         } else if (S_ISREG(dp->mode)) {
382                 if (dp->proc_fops == NULL)
383                         dp->proc_fops = &proc_file_operations;
384         }
385         return 0;
386 }
387
388 /*
389  * Kill an inode that got unregistered..
390  */
391 static void proc_kill_inodes(struct proc_dir_entry *de)
392 {
393         struct list_head *p;
394         struct super_block *sb = proc_mnt->mnt_sb;
395
396         /*
397          * Actually it's a partial revoke().
398          */
399         file_list_lock();
400         for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
401                 struct file * filp = list_entry(p, struct file, f_list);
402                 struct dentry * dentry = filp->f_dentry;
403                 struct inode * inode;
404                 struct file_operations *fops;
405
406                 if (dentry->d_op != &proc_dentry_operations)
407                         continue;
408                 inode = dentry->d_inode;
409                 if (inode->u.generic_ip != de)
410                         continue;
411                 fops = filp->f_op;
412                 filp->f_op = NULL;
413                 fops_put(fops);
414         }
415         file_list_unlock();
416 }
417
418 static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent,
419                                           const char *name,
420                                           mode_t mode,
421                                           nlink_t nlink)
422 {
423         struct proc_dir_entry *ent = NULL;
424         const char *fn = name;
425         int len;
426
427         /* make sure name is valid */
428         if (!name || !strlen(name)) goto out;
429
430         if (!(*parent) && xlate_proc_name(name, parent, &fn) != 0)
431                 goto out;
432         len = strlen(fn);
433
434         ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
435         if (!ent) goto out;
436
437         memset(ent, 0, sizeof(struct proc_dir_entry));
438         memcpy(((char *) ent) + sizeof(struct proc_dir_entry), fn, len + 1);
439         ent->name = ((char *) ent) + sizeof(*ent);
440         ent->namelen = len;
441         ent->mode = mode;
442         ent->nlink = nlink;
443  out:
444         return ent;
445 }
446
447 struct proc_dir_entry *proc_symlink(const char *name,
448                 struct proc_dir_entry *parent, const char *dest)
449 {
450         struct proc_dir_entry *ent;
451
452         ent = proc_create(&parent,name,
453                           (S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
454
455         if (ent) {
456                 ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
457                 if (ent->data) {
458                         strcpy((char*)ent->data,dest);
459                         if (proc_register(parent, ent) < 0) {
460                                 kfree(ent->data);
461                                 kfree(ent);
462                                 ent = NULL;
463                         }
464                 } else {
465                         kfree(ent);
466                         ent = NULL;
467                 }
468         }
469         return ent;
470 }
471
472 struct proc_dir_entry *proc_mknod(const char *name, mode_t mode,
473                 struct proc_dir_entry *parent, kdev_t rdev)
474 {
475         struct proc_dir_entry *ent;
476
477         ent = proc_create(&parent,name,mode,1);
478         if (ent) {
479                 ent->rdev = rdev;
480                 if (proc_register(parent, ent) < 0) {
481                         kfree(ent);
482                         ent = NULL;
483                 }
484         }
485         return ent;
486 }
487
488 struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent)
489 {
490         struct proc_dir_entry *ent;
491
492         ent = proc_create(&parent,name,
493                           (S_IFDIR | S_IRUGO | S_IXUGO),2);
494         if (ent) {
495                 ent->proc_fops = &proc_dir_operations;
496                 ent->proc_iops = &proc_dir_inode_operations;
497
498                 if (proc_register(parent, ent) < 0) {
499                         kfree(ent);
500                         ent = NULL;
501                 }
502         }
503         return ent;
504 }
505
506 struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
507                                          struct proc_dir_entry *parent)
508 {
509         struct proc_dir_entry *ent;
510         nlink_t nlink;
511
512         if (S_ISDIR(mode)) {
513                 if ((mode & S_IALLUGO) == 0)
514                         mode |= S_IRUGO | S_IXUGO;
515                 nlink = 2;
516         } else {
517                 if ((mode & S_IFMT) == 0)
518                         mode |= S_IFREG;
519                 if ((mode & S_IALLUGO) == 0)
520                         mode |= S_IRUGO;
521                 nlink = 1;
522         }
523
524         ent = proc_create(&parent,name,mode,nlink);
525         if (ent) {
526                 if (S_ISDIR(mode)) {
527                         ent->proc_fops = &proc_dir_operations;
528                         ent->proc_iops = &proc_dir_inode_operations;
529                 }
530                 if (proc_register(parent, ent) < 0) {
531                         kfree(ent);
532                         ent = NULL;
533                 }
534         }
535         return ent;
536 }
537
538 void free_proc_entry(struct proc_dir_entry *de)
539 {
540         int ino = de->low_ino;
541
542         if (ino < PROC_DYNAMIC_FIRST ||
543             ino >= PROC_DYNAMIC_FIRST+PROC_NDYNAMIC)
544                 return;
545         if (S_ISLNK(de->mode) && de->data)
546                 kfree(de->data);
547         kfree(de);
548 }
549
550 /*
551  * Remove a /proc entry and free it if it's not currently in use.
552  * If it is in use, we set the 'deleted' flag.
553  */
554 void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
555 {
556         struct proc_dir_entry **p;
557         struct proc_dir_entry *de;
558         const char *fn = name;
559         int len;
560
561         if (!parent && xlate_proc_name(name, &parent, &fn) != 0)
562                 goto out;
563         len = strlen(fn);
564         for (p = &parent->subdir; *p; p=&(*p)->next ) {
565                 if (!proc_match(len, fn, *p))
566                         continue;
567                 de = *p;
568                 *p = de->next;
569                 de->next = NULL;
570                 if (S_ISDIR(de->mode))
571                         parent->nlink--;
572                 clear_bit(de->low_ino - PROC_DYNAMIC_FIRST,
573                           proc_alloc_map);
574                 proc_kill_inodes(de);
575                 de->nlink = 0;
576                 if (!atomic_read(&de->count))
577                         free_proc_entry(de);
578                 else {
579                         de->deleted = 1;
580                         printk("remove_proc_entry: %s/%s busy, count=%d\n",
581                                 parent->name, de->name, atomic_read(&de->count));
582                 }
583                 break;
584         }
585 out:
586         return;
587 }