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>
15 #include <linux/string.h>
17 #include <linux/init.h>
18 #include <linux/kdev_t.h>
19 #include <linux/kernel.h>
20 #include <linux/locks.h>
21 #include <linux/major.h>
22 #include <linux/malloc.h>
23 #include <linux/stat.h>
24 #include <linux/tty.h>
25 #include <asm/bitops.h>
26 #include <asm/uaccess.h>
30 static struct super_block
*mounts
= NULL
;
32 static void devpts_put_super(struct super_block
*sb
)
34 struct devpts_sb_info
*sbi
= SBI(sb
);
38 for ( i
= 0 ; i
< sbi
->max_ptys
; i
++ ) {
39 if ( (inode
= sbi
->inodes
[i
]) ) {
40 if ( inode
->i_count
!= 1 )
41 printk("devpts_put_super: badness: entry %d count %d\n",
48 *sbi
->back
= sbi
->next
;
50 SBI(sbi
->next
)->back
= sbi
->back
;
60 static int devpts_statfs(struct super_block
*sb
, struct statfs
*buf
, int bufsiz
);
61 static void devpts_read_inode(struct inode
*inode
);
62 static void devpts_write_inode(struct inode
*inode
);
64 static struct super_operations devpts_sops
= {
68 NULL
, /* delete_inode */
69 NULL
, /* notify_change */
71 NULL
, /* write_super */
73 NULL
, /* remount_fs */
74 NULL
, /* clear_inode */
77 static int devpts_parse_options(char *options
, struct devpts_sb_info
*sbi
)
84 char *this_char
, *value
;
88 this_char
= strtok(options
,",");
89 for ( ; this_char
; this_char
= strtok(NULL
,",")) {
90 if ((value
= strchr(this_char
,'=')) != NULL
)
92 if (!strcmp(this_char
,"uid")) {
93 if (!value
|| !*value
)
95 uid
= simple_strtoul(value
,&value
,0);
100 else if (!strcmp(this_char
,"gid")) {
101 if (!value
|| !*value
)
103 gid
= simple_strtoul(value
,&value
,0);
108 else if (!strcmp(this_char
,"mode")) {
109 if (!value
|| !*value
)
111 mode
= simple_strtoul(value
,&value
,8);
118 sbi
->setuid
= setuid
;
119 sbi
->setgid
= setgid
;
122 sbi
->mode
= mode
& ~S_IFMT
;
127 struct super_block
*devpts_read_super(struct super_block
*s
, void *data
,
130 struct inode
* root_inode
;
131 struct dentry
* root
;
132 struct devpts_sb_info
*sbi
;
137 /* Super block already completed? */
141 sbi
= (struct devpts_sb_info
*) kmalloc(sizeof(struct devpts_sb_info
), GFP_KERNEL
);
145 sbi
->magic
= DEVPTS_SBI_MAGIC
;
146 sbi
->max_ptys
= unix98_max_ptys
;
147 sbi
->inodes
= kmalloc(sizeof(struct inode
*) * sbi
->max_ptys
, GFP_KERNEL
);
148 if ( !sbi
->inodes
) {
152 memset(sbi
->inodes
, 0, sizeof(struct inode
*) * sbi
->max_ptys
);
154 s
->u
.generic_sbp
= (void *) sbi
;
155 s
->s_blocksize
= 1024;
156 s
->s_blocksize_bits
= 10;
157 s
->s_magic
= DEVPTS_SUPER_MAGIC
;
158 s
->s_op
= &devpts_sops
;
160 unlock_super(s
); /* shouldn't we keep it locked a while longer? */
163 * Get the root inode and dentry, but defer checking for errors.
165 root_inode
= iget(s
, 1); /* inode 1 == root directory */
166 root
= d_alloc_root(root_inode
, NULL
);
169 * Check whether somebody else completed the super block.
177 /* Can this call block? (It shouldn't) */
178 if ( devpts_parse_options(data
,sbi
) ) {
179 printk("devpts: called with bogus options\n");
184 * Check whether somebody else completed the super block.
190 * Success! Install the root dentry now to indicate completion.
197 SBI(sbi
->next
)->back
= &(sbi
->next
);
205 * Success ... somebody else completed the super block for us.
220 * Failure ... clear the s_dev slot and clean up.
224 * dput() can block, so we clear the super block first.
230 printk("devpts: get root dentry failed\n");
232 * iput() can block, so we clear the super block first.
247 static int devpts_statfs(struct super_block
*sb
, struct statfs
*buf
, int bufsiz
)
251 tmp
.f_type
= DEVPTS_SUPER_MAGIC
;
258 tmp
.f_namelen
= NAME_MAX
;
259 return copy_to_user(buf
, &tmp
, bufsiz
) ? -EFAULT
: 0;
262 static void devpts_read_inode(struct inode
*inode
)
264 ino_t ino
= inode
->i_ino
;
265 struct devpts_sb_info
*sbi
= SBI(inode
->i_sb
);
271 inode
->i_mtime
= inode
->i_atime
= inode
->i_ctime
= CURRENT_TIME
;
273 inode
->i_blksize
= 1024;
274 inode
->i_uid
= inode
->i_gid
= 0;
277 inode
->i_mode
= S_IFDIR
| S_IRUGO
| S_IXUGO
| S_IWUSR
;
278 inode
->i_op
= &devpts_root_inode_operations
;
284 if ( ino
>= sbi
->max_ptys
)
287 inode
->i_mode
= S_IFCHR
;
288 inode
->i_rdev
= MKDEV(0,0); /* Gets filled in by devpts_pty_new() */
290 inode
->i_op
= &chrdev_inode_operations
;
295 static void devpts_write_inode(struct inode
*inode
)
299 static struct file_system_type devpts_fs_type
= {
306 void devpts_pty_new(int number
, kdev_t device
)
308 struct super_block
*sb
;
309 struct devpts_sb_info
*sbi
;
312 for ( sb
= mounts
; sb
; sb
= sbi
->next
) {
315 if ( sbi
->inodes
[number
] ) {
316 continue; /* Already registered, this does happen */
319 /* Yes, this looks backwards, but it is correct */
320 inode
= iget(sb
, number
+2);
322 inode
->i_uid
= sbi
->setuid
? sbi
->uid
: current
->fsuid
;
323 inode
->i_gid
= sbi
->setgid
? sbi
->gid
: current
->fsgid
;
324 inode
->i_mode
= sbi
->mode
| S_IFCHR
;
325 inode
->i_rdev
= device
;
327 sbi
->inodes
[number
] = inode
;
332 void devpts_pty_kill(int number
)
334 struct super_block
*sb
;
335 struct devpts_sb_info
*sbi
;
338 for ( sb
= mounts
; sb
; sb
= sbi
->next
) {
341 inode
= sbi
->inodes
[number
];
344 sbi
->inodes
[number
] = NULL
;
351 __initfunc(int init_devpts_fs(void))
353 return register_filesystem(&devpts_fs_type
);
359 int init_module(void)
361 int err
= init_devpts_fs();
363 devpts_upcall_new
= devpts_pty_new
;
364 devpts_upcall_kill
= devpts_pty_kill
;
369 void cleanup_module(void)
371 devpts_upcall_new
= NULL
;
372 devpts_upcall_kill
= NULL
;
373 unregister_filesystem(&devpts_fs_type
);