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>
16 #include <linux/init.h>
17 #include <linux/kdev_t.h>
18 #include <linux/kernel.h>
19 #include <linux/locks.h>
20 #include <linux/major.h>
21 #include <linux/malloc.h>
22 #include <linux/stat.h>
23 #include <linux/tty.h>
24 #include <asm/bitops.h>
25 #include <asm/uaccess.h>
29 static struct super_block
*mounts
= NULL
;
31 static void devpts_put_super(struct super_block
*sb
)
33 struct devpts_sb_info
*sbi
= SBI(sb
);
37 for ( i
= 0 ; i
< sbi
->max_ptys
; i
++ ) {
38 if ( (inode
= sbi
->inodes
[i
]) ) {
39 if ( inode
->i_count
!= 1 )
40 printk("devpts_put_super: badness: entry %d count %d\n",
47 *sbi
->back
= sbi
->next
;
49 SBI(sbi
->next
)->back
= sbi
->back
;
59 static int devpts_statfs(struct super_block
*sb
, struct statfs
*buf
, int bufsiz
);
60 static void devpts_read_inode(struct inode
*inode
);
61 static void devpts_write_inode(struct inode
*inode
);
63 static struct super_operations devpts_sops
= {
67 NULL
, /* delete_inode */
68 NULL
, /* notify_change */
70 NULL
, /* write_super */
72 NULL
, /* remount_fs */
73 NULL
, /* clear_inode */
76 static int devpts_parse_options(char *options
, struct devpts_sb_info
*sbi
)
83 char *this_char
, *value
;
87 this_char
= strtok(options
,",");
88 for ( ; this_char
; this_char
= strtok(NULL
,",")) {
89 if ((value
= strchr(this_char
,'=')) != NULL
)
91 if (!strcmp(this_char
,"uid")) {
92 if (!value
|| !*value
)
94 uid
= simple_strtoul(value
,&value
,0);
99 else if (!strcmp(this_char
,"gid")) {
100 if (!value
|| !*value
)
102 gid
= simple_strtoul(value
,&value
,0);
107 else if (!strcmp(this_char
,"mode")) {
108 if (!value
|| !*value
)
110 mode
= simple_strtoul(value
,&value
,8);
117 sbi
->setuid
= setuid
;
118 sbi
->setgid
= setgid
;
121 sbi
->mode
= mode
& ~S_IFMT
;
126 struct super_block
*devpts_read_super(struct super_block
*s
, void *data
,
129 struct inode
* root_inode
;
130 struct dentry
* root
;
131 struct devpts_sb_info
*sbi
;
136 /* Super block already completed? */
140 sbi
= (struct devpts_sb_info
*) kmalloc(sizeof(struct devpts_sb_info
), GFP_KERNEL
);
144 sbi
->magic
= DEVPTS_SBI_MAGIC
;
145 sbi
->max_ptys
= unix98_max_ptys
;
146 sbi
->inodes
= kmalloc(sizeof(struct inode
*) * sbi
->max_ptys
, GFP_KERNEL
);
147 if ( !sbi
->inodes
) {
151 memset(sbi
->inodes
, 0, sizeof(struct inode
*) * sbi
->max_ptys
);
153 s
->u
.generic_sbp
= (void *) sbi
;
154 s
->s_blocksize
= 1024;
155 s
->s_blocksize_bits
= 10;
156 s
->s_magic
= DEVPTS_SUPER_MAGIC
;
157 s
->s_op
= &devpts_sops
;
159 unlock_super(s
); /* shouldn't we keep it locked a while longer? */
162 * Get the root inode and dentry, but defer checking for errors.
164 root_inode
= iget(s
, 1); /* inode 1 == root directory */
165 root
= d_alloc_root(root_inode
, NULL
);
168 * Check whether somebody else completed the super block.
176 /* Can this call block? (It shouldn't) */
177 if ( devpts_parse_options(data
,sbi
) ) {
178 printk("devpts: called with bogus options\n");
183 * Check whether somebody else completed the super block.
189 * Success! Install the root dentry now to indicate completion.
196 SBI(sbi
->next
)->back
= &(sbi
->next
);
204 * Success ... somebody else completed the super block for us.
219 * Failure ... clear the s_dev slot and clean up.
223 * dput() can block, so we clear the super block first.
229 printk("devpts: get root dentry failed\n");
231 * iput() can block, so we clear the super block first.
246 static int devpts_statfs(struct super_block
*sb
, struct statfs
*buf
, int bufsiz
)
250 tmp
.f_type
= DEVPTS_SUPER_MAGIC
;
257 tmp
.f_namelen
= NAME_MAX
;
258 return copy_to_user(buf
, &tmp
, bufsiz
) ? -EFAULT
: 0;
261 static void devpts_read_inode(struct inode
*inode
)
263 ino_t ino
= inode
->i_ino
;
264 struct devpts_sb_info
*sbi
= SBI(inode
->i_sb
);
270 inode
->i_mtime
= inode
->i_atime
= inode
->i_ctime
= CURRENT_TIME
;
272 inode
->i_blksize
= 1024;
273 inode
->i_uid
= inode
->i_gid
= 0;
276 inode
->i_mode
= S_IFDIR
| S_IRUGO
| S_IXUGO
| S_IWUSR
;
277 inode
->i_op
= &devpts_root_inode_operations
;
283 if ( ino
>= sbi
->max_ptys
)
286 inode
->i_mode
= S_IFCHR
;
287 inode
->i_rdev
= MKDEV(0,0); /* Gets filled in by devpts_pty_new() */
289 inode
->i_op
= &chrdev_inode_operations
;
294 static void devpts_write_inode(struct inode
*inode
)
298 static struct file_system_type devpts_fs_type
= {
305 void devpts_pty_new(int number
, kdev_t device
)
307 struct super_block
*sb
;
308 struct devpts_sb_info
*sbi
;
311 for ( sb
= mounts
; sb
; sb
= sbi
->next
) {
314 if ( sbi
->inodes
[number
] ) {
315 continue; /* Already registered, this does happen */
318 /* Yes, this looks backwards, but it is correct */
319 inode
= iget(sb
, number
+2);
321 inode
->i_uid
= sbi
->setuid
? sbi
->uid
: current
->fsuid
;
322 inode
->i_gid
= sbi
->setgid
? sbi
->gid
: current
->fsgid
;
323 inode
->i_mode
= sbi
->mode
| S_IFCHR
;
324 inode
->i_rdev
= device
;
326 sbi
->inodes
[number
] = inode
;
331 void devpts_pty_kill(int number
)
333 struct super_block
*sb
;
334 struct devpts_sb_info
*sbi
;
337 for ( sb
= mounts
; sb
; sb
= sbi
->next
) {
340 inode
= sbi
->inodes
[number
];
343 sbi
->inodes
[number
] = NULL
;
350 __initfunc(int init_devpts_fs(void))
352 return register_filesystem(&devpts_fs_type
);
358 int init_module(void)
360 int err
= init_devpts_fs();
362 devpts_upcall_new
= devpts_pty_new
;
363 devpts_upcall_kill
= devpts_pty_kill
;
368 void cleanup_module(void)
370 devpts_upcall_new
= NULL
;
371 devpts_upcall_kill
= NULL
;
372 unregister_filesystem(&devpts_fs_type
);