generic.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:13k
源码类别:

Linux/Unix编程

开发平台:

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 origin)
  122. {
  123. long long retval;
  124. switch (origin) {
  125. case 2:
  126. offset += file->f_dentry->d_inode->i_size;
  127. break;
  128. case 1:
  129. offset += file->f_pos;
  130. }
  131. retval = -EINVAL;
  132. if (offset>=0 && offset<=file->f_dentry->d_inode->i_sb->s_maxbytes) {
  133. if (offset != file->f_pos) {
  134. file->f_pos = offset;
  135. file->f_reada = 0;
  136. }
  137. retval = offset;
  138. }
  139. return retval;
  140. }
  141. /*
  142.  * This function parses a name such as "tty/driver/serial", and
  143.  * returns the struct proc_dir_entry for "/proc/tty/driver", and
  144.  * returns "serial" in residual.
  145.  */
  146. static int xlate_proc_name(const char *name,
  147.    struct proc_dir_entry **ret, const char **residual)
  148. {
  149. const char      *cp = name, *next;
  150. struct proc_dir_entry *de;
  151. int len;
  152. de = &proc_root;
  153. while (1) {
  154. next = strchr(cp, '/');
  155. if (!next)
  156. break;
  157. len = next - cp;
  158. for (de = de->subdir; de ; de = de->next) {
  159. if (proc_match(len, cp, de))
  160. break;
  161. }
  162. if (!de)
  163. return -ENOENT;
  164. cp += len + 1;
  165. }
  166. *residual = cp;
  167. *ret = de;
  168. return 0;
  169. }
  170. static unsigned long proc_alloc_map[(PROC_NDYNAMIC + BITS_PER_LONG - 1) / BITS_PER_LONG];
  171. spinlock_t proc_alloc_map_lock = SPIN_LOCK_UNLOCKED;
  172. static int make_inode_number(void)
  173. {
  174. int i;
  175. spin_lock(&proc_alloc_map_lock);
  176. i = find_first_zero_bit(proc_alloc_map, PROC_NDYNAMIC);
  177. if (i < 0 || i >= PROC_NDYNAMIC) {
  178. i = -1;
  179. goto out;
  180. }
  181. set_bit(i, proc_alloc_map);
  182. i += PROC_DYNAMIC_FIRST;
  183. out:
  184. spin_unlock(&proc_alloc_map_lock);
  185. return i;
  186. }
  187. static int proc_readlink(struct dentry *dentry, char *buffer, int buflen)
  188. {
  189. char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data;
  190. return vfs_readlink(dentry, buffer, buflen, s);
  191. }
  192. static int proc_follow_link(struct dentry *dentry, struct nameidata *nd)
  193. {
  194. char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data;
  195. return vfs_follow_link(nd, s);
  196. }
  197. static struct inode_operations proc_link_inode_operations = {
  198. readlink: proc_readlink,
  199. follow_link: proc_follow_link,
  200. };
  201. /*
  202.  * As some entries in /proc are volatile, we want to 
  203.  * get rid of unused dentries.  This could be made 
  204.  * smarter: we could keep a "volatile" flag in the 
  205.  * inode to indicate which ones to keep.
  206.  */
  207. static int proc_delete_dentry(struct dentry * dentry)
  208. {
  209. return 1;
  210. }
  211. static struct dentry_operations proc_dentry_operations =
  212. {
  213. d_delete: proc_delete_dentry,
  214. };
  215. /*
  216.  * Don't create negative dentries here, return -ENOENT by hand
  217.  * instead.
  218.  */
  219. struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry)
  220. {
  221. struct inode *inode;
  222. struct proc_dir_entry * de;
  223. int error;
  224. error = -ENOENT;
  225. inode = NULL;
  226. de = (struct proc_dir_entry *) dir->u.generic_ip;
  227. if (de) {
  228. for (de = de->subdir; de ; de = de->next) {
  229. if (!de || !de->low_ino)
  230. continue;
  231. if (de->namelen != dentry->d_name.len)
  232. continue;
  233. if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
  234. int ino = de->low_ino;
  235. error = -EINVAL;
  236. inode = proc_get_inode(dir->i_sb, ino, de);
  237. break;
  238. }
  239. }
  240. }
  241. if (inode) {
  242. dentry->d_op = &proc_dentry_operations;
  243. d_add(dentry, inode);
  244. return NULL;
  245. }
  246. return ERR_PTR(error);
  247. }
  248. /*
  249.  * This returns non-zero if at EOF, so that the /proc
  250.  * root directory can use this and check if it should
  251.  * continue with the <pid> entries..
  252.  *
  253.  * Note that the VFS-layer doesn't care about the return
  254.  * value of the readdir() call, as long as it's non-negative
  255.  * for success..
  256.  */
  257. int proc_readdir(struct file * filp,
  258. void * dirent, filldir_t filldir)
  259. {
  260. struct proc_dir_entry * de;
  261. unsigned int ino;
  262. int i;
  263. struct inode *inode = filp->f_dentry->d_inode;
  264. ino = inode->i_ino;
  265. de = (struct proc_dir_entry *) inode->u.generic_ip;
  266. if (!de)
  267. return -EINVAL;
  268. i = filp->f_pos;
  269. switch (i) {
  270. case 0:
  271. if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
  272. return 0;
  273. i++;
  274. filp->f_pos++;
  275. /* fall through */
  276. case 1:
  277. if (filldir(dirent, "..", 2, i,
  278.     filp->f_dentry->d_parent->d_inode->i_ino,
  279.     DT_DIR) < 0)
  280. return 0;
  281. i++;
  282. filp->f_pos++;
  283. /* fall through */
  284. default:
  285. de = de->subdir;
  286. i -= 2;
  287. for (;;) {
  288. if (!de)
  289. return 1;
  290. if (!i)
  291. break;
  292. de = de->next;
  293. i--;
  294. }
  295. do {
  296. if (filldir(dirent, de->name, de->namelen, filp->f_pos,
  297.     de->low_ino, de->mode >> 12) < 0)
  298. return 0;
  299. filp->f_pos++;
  300. de = de->next;
  301. } while (de);
  302. }
  303. return 1;
  304. }
  305. /*
  306.  * These are the generic /proc directory operations. They
  307.  * use the in-memory "struct proc_dir_entry" tree to parse
  308.  * the /proc directory.
  309.  */
  310. static struct file_operations proc_dir_operations = {
  311. read: generic_read_dir,
  312. readdir: proc_readdir,
  313. };
  314. /*
  315.  * proc directories can do almost nothing..
  316.  */
  317. static struct inode_operations proc_dir_inode_operations = {
  318. lookup: proc_lookup,
  319. };
  320. static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
  321. {
  322. int i;
  323. i = make_inode_number();
  324. if (i < 0)
  325. return -EAGAIN;
  326. dp->low_ino = i;
  327. dp->next = dir->subdir;
  328. dp->parent = dir;
  329. dir->subdir = dp;
  330. if (S_ISDIR(dp->mode)) {
  331. if (dp->proc_iops == NULL) {
  332. dp->proc_fops = &proc_dir_operations;
  333. dp->proc_iops = &proc_dir_inode_operations;
  334. }
  335. dir->nlink++;
  336. } else if (S_ISLNK(dp->mode)) {
  337. if (dp->proc_iops == NULL)
  338. dp->proc_iops = &proc_link_inode_operations;
  339. } else if (S_ISREG(dp->mode)) {
  340. if (dp->proc_fops == NULL)
  341. dp->proc_fops = &proc_file_operations;
  342. }
  343. return 0;
  344. }
  345. /*
  346.  * Kill an inode that got unregistered..
  347.  */
  348. static void proc_kill_inodes(struct proc_dir_entry *de)
  349. {
  350. struct list_head *p;
  351. struct super_block *sb = proc_mnt->mnt_sb;
  352. /*
  353.  * Actually it's a partial revoke().
  354.  */
  355. file_list_lock();
  356. for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
  357. struct file * filp = list_entry(p, struct file, f_list);
  358. struct dentry * dentry = filp->f_dentry;
  359. struct inode * inode;
  360. struct file_operations *fops;
  361. if (dentry->d_op != &proc_dentry_operations)
  362. continue;
  363. inode = dentry->d_inode;
  364. if (inode->u.generic_ip != de)
  365. continue;
  366. fops = filp->f_op;
  367. filp->f_op = NULL;
  368. fops_put(fops);
  369. }
  370. file_list_unlock();
  371. }
  372. static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent,
  373.   const char *name,
  374.   mode_t mode,
  375.   nlink_t nlink)
  376. {
  377. struct proc_dir_entry *ent = NULL;
  378. const char *fn = name;
  379. int len;
  380. /* make sure name is valid */
  381. if (!name || !strlen(name)) goto out;
  382. if (!(*parent) && xlate_proc_name(name, parent, &fn) != 0)
  383. goto out;
  384. len = strlen(fn);
  385. ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
  386. if (!ent) goto out;
  387. memset(ent, 0, sizeof(struct proc_dir_entry));
  388. memcpy(((char *) ent) + sizeof(struct proc_dir_entry), fn, len + 1);
  389. ent->name = ((char *) ent) + sizeof(*ent);
  390. ent->namelen = len;
  391. ent->mode = mode;
  392. ent->nlink = nlink;
  393.  out:
  394. return ent;
  395. }
  396. struct proc_dir_entry *proc_symlink(const char *name,
  397. struct proc_dir_entry *parent, const char *dest)
  398. {
  399. struct proc_dir_entry *ent;
  400. ent = proc_create(&parent,name,
  401.   (S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
  402. if (ent) {
  403. ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
  404. if (ent->data) {
  405. strcpy((char*)ent->data,dest);
  406. proc_register(parent, ent);
  407. } else {
  408. kfree(ent);
  409. ent = NULL;
  410. }
  411. }
  412. return ent;
  413. }
  414. struct proc_dir_entry *proc_mknod(const char *name, mode_t mode,
  415. struct proc_dir_entry *parent, kdev_t rdev)
  416. {
  417. struct proc_dir_entry *ent;
  418. ent = proc_create(&parent,name,mode,1);
  419. if (ent) {
  420. ent->rdev = rdev;
  421. proc_register(parent, ent);
  422. }
  423. return ent;
  424. }
  425. struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent)
  426. {
  427. struct proc_dir_entry *ent;
  428. ent = proc_create(&parent,name,
  429.   (S_IFDIR | S_IRUGO | S_IXUGO),2);
  430. if (ent) {
  431. ent->proc_fops = &proc_dir_operations;
  432. ent->proc_iops = &proc_dir_inode_operations;
  433. proc_register(parent, ent);
  434. }
  435. return ent;
  436. }
  437. struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
  438.  struct proc_dir_entry *parent)
  439. {
  440. struct proc_dir_entry *ent;
  441. nlink_t nlink;
  442. if (S_ISDIR(mode)) {
  443. if ((mode & S_IALLUGO) == 0)
  444. mode |= S_IRUGO | S_IXUGO;
  445. nlink = 2;
  446. } else {
  447. if ((mode & S_IFMT) == 0)
  448. mode |= S_IFREG;
  449. if ((mode & S_IALLUGO) == 0)
  450. mode |= S_IRUGO;
  451. nlink = 1;
  452. }
  453. ent = proc_create(&parent,name,mode,nlink);
  454. if (ent) {
  455. if (S_ISDIR(mode)) {
  456. ent->proc_fops = &proc_dir_operations;
  457. ent->proc_iops = &proc_dir_inode_operations;
  458. }
  459. proc_register(parent, ent);
  460. }
  461. return ent;
  462. }
  463. void free_proc_entry(struct proc_dir_entry *de)
  464. {
  465. int ino = de->low_ino;
  466. if (ino < PROC_DYNAMIC_FIRST ||
  467.     ino >= PROC_DYNAMIC_FIRST+PROC_NDYNAMIC)
  468. return;
  469. if (S_ISLNK(de->mode) && de->data)
  470. kfree(de->data);
  471. kfree(de);
  472. }
  473. /*
  474.  * Remove a /proc entry and free it if it's not currently in use.
  475.  * If it is in use, we set the 'deleted' flag.
  476.  */
  477. void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
  478. {
  479. struct proc_dir_entry **p;
  480. struct proc_dir_entry *de;
  481. const char *fn = name;
  482. int len;
  483. if (!parent && xlate_proc_name(name, &parent, &fn) != 0)
  484. goto out;
  485. len = strlen(fn);
  486. for (p = &parent->subdir; *p; p=&(*p)->next ) {
  487. if (!proc_match(len, fn, *p))
  488. continue;
  489. de = *p;
  490. *p = de->next;
  491. de->next = NULL;
  492. if (S_ISDIR(de->mode))
  493. parent->nlink--;
  494. clear_bit(de->low_ino - PROC_DYNAMIC_FIRST,
  495.   proc_alloc_map);
  496. proc_kill_inodes(de);
  497. de->nlink = 0;
  498. if (!atomic_read(&de->count))
  499. free_proc_entry(de);
  500. else {
  501. de->deleted = 1;
  502. printk("remove_proc_entry: %s/%s busy, count=%dn",
  503. parent->name, de->name, atomic_read(&de->count));
  504. }
  505. break;
  506. }
  507. out:
  508. return;
  509. }