generic.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:12k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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