1 /* -*- linux-c -*- --------------------------------------------------------- *
3 * linux/fs/devpts/inode.c
5 * Copyright 1998 H. Peter Anvin -- All Rights Reserved
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.
11 * ------------------------------------------------------------------------- */
13 #include <linux/module.h>
14 #include <linux/init.h>
16 #include <linux/sched.h>
17 #include <linux/namei.h>
18 #include <linux/mount.h>
21 #define DEVPTS_SUPER_MAGIC 0x1cd1
23 static struct vfsmount
*devpts_mnt
;
24 static struct dentry
*devpts_root
;
32 } config
= {.mode
= 0600};
34 static int devpts_remount(struct super_block
*sb
, int *flags
, char *data
)
44 while ((this_char
= strsep(&data
, ",")) != NULL
) {
49 if (sscanf(this_char
, "uid=%i%c", &n
, &dummy
) == 1) {
52 } else if (sscanf(this_char
, "gid=%i%c", &n
, &dummy
) == 1) {
55 } else if (sscanf(this_char
, "mode=%o%c", &n
, &dummy
) == 1)
58 printk("devpts: called with bogus options\n");
62 config
.setuid
= setuid
;
63 config
.setgid
= setgid
;
71 static struct super_operations devpts_sops
= {
72 .statfs
= simple_statfs
,
73 .remount_fs
= devpts_remount
,
77 devpts_fill_super(struct super_block
*s
, void *data
, int silent
)
81 s
->s_blocksize
= 1024;
82 s
->s_blocksize_bits
= 10;
83 s
->s_magic
= DEVPTS_SUPER_MAGIC
;
84 s
->s_op
= &devpts_sops
;
90 inode
->i_mtime
= inode
->i_atime
= inode
->i_ctime
= CURRENT_TIME
;
92 inode
->i_blksize
= 1024;
93 inode
->i_uid
= inode
->i_gid
= 0;
94 inode
->i_mode
= S_IFDIR
| S_IRUGO
| S_IXUGO
| S_IWUSR
;
95 inode
->i_op
= &simple_dir_inode_operations
;
96 inode
->i_fop
= &simple_dir_operations
;
99 devpts_root
= s
->s_root
= d_alloc_root(inode
);
103 printk("devpts: get root dentry failed\n");
109 static struct super_block
*devpts_get_sb(struct file_system_type
*fs_type
,
110 int flags
, const char *dev_name
, void *data
)
112 return get_sb_single(fs_type
, flags
, data
, devpts_fill_super
);
115 static struct file_system_type devpts_fs_type
= {
116 .owner
= THIS_MODULE
,
118 .get_sb
= devpts_get_sb
,
119 .kill_sb
= kill_anon_super
,
123 * The normal naming convention is simply /dev/pts/<number>; this conforms
124 * to the System V naming convention
127 static struct dentry
*get_node(int num
)
130 struct dentry
*root
= devpts_root
;
131 down(&root
->d_inode
->i_sem
);
132 return lookup_one_len(s
, root
, sprintf(s
, "%d", num
));
135 static struct inode_operations devpts_file_inode_operations
= {
136 .setxattr
= devpts_setxattr
,
137 .getxattr
= devpts_getxattr
,
138 .listxattr
= devpts_listxattr
,
139 .removexattr
= devpts_removexattr
,
142 void devpts_pty_new(int number
, dev_t device
)
144 struct dentry
*dentry
;
145 struct inode
*inode
= new_inode(devpts_mnt
->mnt_sb
);
148 inode
->i_ino
= number
+2;
149 inode
->i_blksize
= 1024;
150 inode
->i_uid
= config
.setuid
? config
.uid
: current
->fsuid
;
151 inode
->i_gid
= config
.setgid
? config
.gid
: current
->fsgid
;
152 inode
->i_mtime
= inode
->i_atime
= inode
->i_ctime
= CURRENT_TIME
;
153 init_special_inode(inode
, S_IFCHR
|config
.mode
, device
);
154 inode
->i_op
= &devpts_file_inode_operations
;
156 dentry
= get_node(number
);
157 if (!IS_ERR(dentry
) && !dentry
->d_inode
)
158 d_instantiate(dentry
, inode
);
159 up(&devpts_root
->d_inode
->i_sem
);
162 void devpts_pty_kill(int number
)
164 struct dentry
*dentry
= get_node(number
);
166 if (!IS_ERR(dentry
)) {
167 struct inode
*inode
= dentry
->d_inode
;
175 up(&devpts_root
->d_inode
->i_sem
);
178 static int __init
init_devpts_fs(void)
180 int err
= init_devpts_xattr();
183 err
= register_filesystem(&devpts_fs_type
);
185 devpts_mnt
= kern_mount(&devpts_fs_type
);
186 if (IS_ERR(devpts_mnt
))
187 err
= PTR_ERR(devpts_mnt
);
192 static void __exit
exit_devpts_fs(void)
194 unregister_filesystem(&devpts_fs_type
);
199 module_init(init_devpts_fs
)
200 module_exit(exit_devpts_fs
)
201 MODULE_LICENSE("GPL");