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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/fs/proc/inode.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6. #include <linux/sched.h>
  7. #include <linux/proc_fs.h>
  8. #include <linux/kernel.h>
  9. #include <linux/mm.h>
  10. #include <linux/string.h>
  11. #include <linux/stat.h>
  12. #include <linux/file.h>
  13. #include <linux/locks.h>
  14. #include <linux/limits.h>
  15. #define __NO_VERSION__
  16. #include <linux/module.h>
  17. #include <linux/smp_lock.h>
  18. #include <asm/system.h>
  19. #include <asm/uaccess.h>
  20. extern void free_proc_entry(struct proc_dir_entry *);
  21. struct proc_dir_entry * de_get(struct proc_dir_entry *de)
  22. {
  23. if (de)
  24. atomic_inc(&de->count);
  25. return de;
  26. }
  27. /*
  28.  * Decrements the use count and checks for deferred deletion.
  29.  */
  30. void de_put(struct proc_dir_entry *de)
  31. {
  32. if (de) {
  33. lock_kernel();
  34. if (!atomic_read(&de->count)) {
  35. printk("de_put: entry %s already free!n", de->name);
  36. unlock_kernel();
  37. return;
  38. }
  39. if (atomic_dec_and_test(&de->count)) {
  40. if (de->deleted) {
  41. printk("de_put: deferred delete of %sn",
  42. de->name);
  43. free_proc_entry(de);
  44. }
  45. }
  46. unlock_kernel();
  47. }
  48. }
  49. /*
  50.  * Decrement the use count of the proc_dir_entry.
  51.  */
  52. static void proc_delete_inode(struct inode *inode)
  53. {
  54. struct proc_dir_entry *de = inode->u.generic_ip;
  55. inode->i_state = I_CLEAR;
  56. if (PROC_INODE_PROPER(inode)) {
  57. proc_pid_delete_inode(inode);
  58. return;
  59. }
  60. if (de) {
  61. if (de->owner)
  62. __MOD_DEC_USE_COUNT(de->owner);
  63. de_put(de);
  64. }
  65. }
  66. struct vfsmount *proc_mnt;
  67. static void proc_read_inode(struct inode * inode)
  68. {
  69. inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
  70. }
  71. static int proc_statfs(struct super_block *sb, struct statfs *buf)
  72. {
  73. buf->f_type = PROC_SUPER_MAGIC;
  74. buf->f_bsize = PAGE_SIZE/sizeof(long);
  75. buf->f_bfree = 0;
  76. buf->f_bavail = 0;
  77. buf->f_ffree = 0;
  78. buf->f_namelen = NAME_MAX;
  79. return 0;
  80. }
  81. static struct super_operations proc_sops = { 
  82. read_inode: proc_read_inode,
  83. put_inode: force_delete,
  84. delete_inode: proc_delete_inode,
  85. statfs: proc_statfs,
  86. };
  87. static int parse_options(char *options,uid_t *uid,gid_t *gid)
  88. {
  89. char *this_char,*value;
  90. *uid = current->uid;
  91. *gid = current->gid;
  92. if (!options) return 1;
  93. for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
  94. if ((value = strchr(this_char,'=')) != NULL)
  95. *value++ = 0;
  96. if (!strcmp(this_char,"uid")) {
  97. if (!value || !*value)
  98. return 0;
  99. *uid = simple_strtoul(value,&value,0);
  100. if (*value)
  101. return 0;
  102. }
  103. else if (!strcmp(this_char,"gid")) {
  104. if (!value || !*value)
  105. return 0;
  106. *gid = simple_strtoul(value,&value,0);
  107. if (*value)
  108. return 0;
  109. }
  110. else return 1;
  111. }
  112. return 1;
  113. }
  114. struct inode * proc_get_inode(struct super_block * sb, int ino,
  115. struct proc_dir_entry * de)
  116. {
  117. struct inode * inode;
  118. /*
  119.  * Increment the use count so the dir entry can't disappear.
  120.  */
  121. de_get(de);
  122. #if 1
  123. /* shouldn't ever happen */
  124. if (de && de->deleted)
  125. printk("proc_iget: using deleted entry %s, count=%dn", de->name, atomic_read(&de->count));
  126. #endif
  127. inode = iget(sb, ino);
  128. if (!inode)
  129. goto out_fail;
  130. inode->u.generic_ip = (void *) de;
  131. if (de) {
  132. if (de->mode) {
  133. inode->i_mode = de->mode;
  134. inode->i_uid = de->uid;
  135. inode->i_gid = de->gid;
  136. }
  137. if (de->size)
  138. inode->i_size = de->size;
  139. if (de->nlink)
  140. inode->i_nlink = de->nlink;
  141. if (de->owner)
  142. __MOD_INC_USE_COUNT(de->owner);
  143. if (de->proc_iops)
  144. inode->i_op = de->proc_iops;
  145. if (de->proc_fops)
  146. inode->i_fop = de->proc_fops;
  147. else if (S_ISBLK(de->mode)||S_ISCHR(de->mode)||S_ISFIFO(de->mode))
  148. init_special_inode(inode,de->mode,kdev_t_to_nr(de->rdev));
  149. }
  150. out:
  151. return inode;
  152. out_fail:
  153. de_put(de);
  154. goto out;
  155. }
  156. struct super_block *proc_read_super(struct super_block *s,void *data, 
  157.     int silent)
  158. {
  159. struct inode * root_inode;
  160. struct task_struct *p;
  161. s->s_blocksize = 1024;
  162. s->s_blocksize_bits = 10;
  163. s->s_magic = PROC_SUPER_MAGIC;
  164. s->s_op = &proc_sops;
  165. root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root);
  166. if (!root_inode)
  167. goto out_no_root;
  168. /*
  169.  * Fixup the root inode's nlink value
  170.  */
  171. read_lock(&tasklist_lock);
  172. for_each_task(p) if (p->pid) root_inode->i_nlink++;
  173. read_unlock(&tasklist_lock);
  174. s->s_root = d_alloc_root(root_inode);
  175. if (!s->s_root)
  176. goto out_no_root;
  177. parse_options(data, &root_inode->i_uid, &root_inode->i_gid);
  178. return s;
  179. out_no_root:
  180. printk("proc_read_super: get root inode failedn");
  181. iput(root_inode);
  182. return NULL;
  183. }
  184. MODULE_LICENSE("GPL");