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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* -*- linux-c -*- --------------------------------------------------------- *
  2.  *
  3.  * linux/fs/devpts/inode.c
  4.  *
  5.  *  Copyright 1998 H. Peter Anvin -- All Rights Reserved
  6.  *
  7.  * This file is part of the Linux kernel and is made available under
  8.  * the terms of the GNU General Public License, version 2, or at your
  9.  * option, any later version, incorporated herein by reference.
  10.  *
  11.  * ------------------------------------------------------------------------- */
  12. #include <linux/module.h>
  13. #include <linux/string.h>
  14. #include <linux/fs.h>
  15. #include <linux/init.h>
  16. #include <linux/kdev_t.h>
  17. #include <linux/kernel.h>
  18. #include <linux/locks.h>
  19. #include <linux/major.h>
  20. #include <linux/slab.h>
  21. #include <linux/stat.h>
  22. #include <linux/tty.h>
  23. #include <asm/bitops.h>
  24. #include <asm/uaccess.h>
  25. #include "devpts_i.h"
  26. static struct vfsmount *devpts_mnt;
  27. static void devpts_put_super(struct super_block *sb)
  28. {
  29. struct devpts_sb_info *sbi = SBI(sb);
  30. struct inode *inode;
  31. int i;
  32. for ( i = 0 ; i < sbi->max_ptys ; i++ ) {
  33. if ( (inode = sbi->inodes[i]) ) {
  34. if ( atomic_read(&inode->i_count) != 1 )
  35. printk("devpts_put_super: badness: entry %d count %dn",
  36.        i, atomic_read(&inode->i_count));
  37. inode->i_nlink--;
  38. iput(inode);
  39. }
  40. }
  41. kfree(sbi->inodes);
  42. kfree(sbi);
  43. }
  44. static int devpts_statfs(struct super_block *sb, struct statfs *buf);
  45. static int devpts_remount (struct super_block * sb, int * flags, char * data);
  46. static struct super_operations devpts_sops = {
  47. put_super: devpts_put_super,
  48. statfs: devpts_statfs,
  49. remount_fs: devpts_remount,
  50. };
  51. static int devpts_parse_options(char *options, struct devpts_sb_info *sbi)
  52. {
  53. int setuid = 0;
  54. int setgid = 0;
  55. uid_t uid = 0;
  56. gid_t gid = 0;
  57. umode_t mode = 0600;
  58. char *this_char, *value;
  59. this_char = NULL;
  60. if ( options )
  61. this_char = strtok(options,",");
  62. for ( ; this_char; this_char = strtok(NULL,",")) {
  63. if ((value = strchr(this_char,'=')) != NULL)
  64. *value++ = 0;
  65. if (!strcmp(this_char,"uid")) {
  66. if (!value || !*value)
  67. return 1;
  68. uid = simple_strtoul(value,&value,0);
  69. if (*value)
  70. return 1;
  71. setuid = 1;
  72. }
  73. else if (!strcmp(this_char,"gid")) {
  74. if (!value || !*value)
  75. return 1;
  76. gid = simple_strtoul(value,&value,0);
  77. if (*value)
  78. return 1;
  79. setgid = 1;
  80. }
  81. else if (!strcmp(this_char,"mode")) {
  82. if (!value || !*value)
  83. return 1;
  84. mode = simple_strtoul(value,&value,8);
  85. if (*value)
  86. return 1;
  87. }
  88. else
  89. return 1;
  90. }
  91. sbi->setuid  = setuid;
  92. sbi->setgid  = setgid;
  93. sbi->uid     = uid;
  94. sbi->gid     = gid;
  95. sbi->mode    = mode & ~S_IFMT;
  96. return 0;
  97. }
  98. static int devpts_remount(struct super_block * sb, int * flags, char * data)
  99. {
  100. struct devpts_sb_info *sbi = sb->u.generic_sbp;
  101. int res = devpts_parse_options(data,sbi);
  102. if (res) {
  103. printk("devpts: called with bogus optionsn");
  104. return -EINVAL;
  105. }
  106. return 0;
  107. }
  108. struct super_block *devpts_read_super(struct super_block *s, void *data,
  109.       int silent)
  110. {
  111. struct inode * inode;
  112. struct devpts_sb_info *sbi;
  113. sbi = (struct devpts_sb_info *) kmalloc(sizeof(struct devpts_sb_info), GFP_KERNEL);
  114. if ( !sbi )
  115. goto fail;
  116. sbi->magic  = DEVPTS_SBI_MAGIC;
  117. sbi->max_ptys = unix98_max_ptys;
  118. sbi->inodes = kmalloc(sizeof(struct inode *) * sbi->max_ptys, GFP_KERNEL);
  119. if ( !sbi->inodes )
  120. goto fail_free;
  121. memset(sbi->inodes, 0, sizeof(struct inode *) * sbi->max_ptys);
  122. if ( devpts_parse_options(data,sbi) && !silent) {
  123. printk("devpts: called with bogus optionsn");
  124. goto fail_free;
  125. }
  126. inode = new_inode(s);
  127. if (!inode)
  128. goto fail_free;
  129. inode->i_ino = 1;
  130. inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
  131. inode->i_blocks = 0;
  132. inode->i_blksize = 1024;
  133. inode->i_uid = inode->i_gid = 0;
  134. inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
  135. inode->i_op = &devpts_root_inode_operations;
  136. inode->i_fop = &devpts_root_operations;
  137. inode->i_nlink = 2;
  138. s->u.generic_sbp = (void *) sbi;
  139. s->s_blocksize = 1024;
  140. s->s_blocksize_bits = 10;
  141. s->s_magic = DEVPTS_SUPER_MAGIC;
  142. s->s_op = &devpts_sops;
  143. s->s_root = d_alloc_root(inode);
  144. if (s->s_root)
  145. return s;
  146. printk("devpts: get root dentry failedn");
  147. iput(inode);
  148. fail_free:
  149. kfree(sbi);
  150. fail:
  151. return NULL;
  152. }
  153. static int devpts_statfs(struct super_block *sb, struct statfs *buf)
  154. {
  155. buf->f_type = DEVPTS_SUPER_MAGIC;
  156. buf->f_bsize = 1024;
  157. buf->f_namelen = NAME_MAX;
  158. return 0;
  159. }
  160. static DECLARE_FSTYPE(devpts_fs_type, "devpts", devpts_read_super, FS_SINGLE);
  161. void devpts_pty_new(int number, kdev_t device)
  162. {
  163. struct super_block *sb = devpts_mnt->mnt_sb;
  164. struct devpts_sb_info *sbi = SBI(sb);
  165. struct inode *inode;
  166. if ( sbi->inodes[number] )
  167. return; /* Already registered, this does happen */
  168. inode = new_inode(sb);
  169. if (!inode)
  170. return;
  171. inode->i_ino = number+2;
  172. inode->i_blocks = 0;
  173. inode->i_blksize = 1024;
  174. inode->i_uid = sbi->setuid ? sbi->uid : current->fsuid;
  175. inode->i_gid = sbi->setgid ? sbi->gid : current->fsgid;
  176. inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
  177. init_special_inode(inode, S_IFCHR|sbi->mode, kdev_t_to_nr(device));
  178. if ( sbi->inodes[number] ) {
  179. iput(inode);
  180. return;
  181. }
  182. sbi->inodes[number] = inode;
  183. }
  184. void devpts_pty_kill(int number)
  185. {
  186. struct super_block *sb = devpts_mnt->mnt_sb;
  187. struct devpts_sb_info *sbi = SBI(sb);
  188. struct inode *inode = sbi->inodes[number];
  189. if ( inode ) {
  190. sbi->inodes[number] = NULL;
  191. inode->i_nlink--;
  192. iput(inode);
  193. }
  194. }
  195. static int __init init_devpts_fs(void)
  196. {
  197. int err = register_filesystem(&devpts_fs_type);
  198. if (!err) {
  199. devpts_mnt = kern_mount(&devpts_fs_type);
  200. err = PTR_ERR(devpts_mnt);
  201. if (!IS_ERR(devpts_mnt))
  202. err = 0;
  203. #ifdef MODULE
  204. if ( !err ) {
  205. devpts_upcall_new  = devpts_pty_new;
  206. devpts_upcall_kill = devpts_pty_kill;
  207. }
  208. #endif
  209. }
  210. return err;
  211. }
  212. static void __exit exit_devpts_fs(void)
  213. {
  214. #ifdef MODULE
  215. devpts_upcall_new  = NULL;
  216. devpts_upcall_kill = NULL;
  217. #endif
  218. unregister_filesystem(&devpts_fs_type);
  219. kern_umount(devpts_mnt);
  220. }
  221. module_init(init_devpts_fs)
  222. module_exit(exit_devpts_fs)
  223. MODULE_LICENSE("GPL");