1 /* -*- linux-c -*- --------------------------------------------------------- *
3 * linux/fs/devpts/root.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/errno.h>
14 #include <linux/stat.h>
15 #include <linux/param.h>
16 #include <linux/string.h>
19 static int devpts_root_readdir(struct file
*,void *,filldir_t
);
20 static struct dentry
*devpts_root_lookup(struct inode
*,struct dentry
*);
21 static int devpts_revalidate(struct dentry
*, int);
23 struct file_operations devpts_root_operations
= {
24 read
: generic_read_dir
,
25 readdir
: devpts_root_readdir
,
28 struct inode_operations devpts_root_inode_operations
= {
29 lookup
: devpts_root_lookup
,
32 static struct dentry_operations devpts_dentry_operations
= {
33 d_revalidate
: devpts_revalidate
,
37 * The normal naming convention is simply /dev/pts/<number>; this conforms
38 * to the System V naming convention
41 #define genptsname(buf,num) sprintf(buf, "%d", num)
43 static int devpts_root_readdir(struct file
*filp
, void *dirent
, filldir_t filldir
)
45 struct inode
* inode
= filp
->f_dentry
->d_inode
;
46 struct devpts_sb_info
* sbi
= SBI(filp
->f_dentry
->d_inode
->i_sb
);
55 if (filldir(dirent
, ".", 1, nr
, inode
->i_ino
) < 0)
60 if (filldir(dirent
, "..", 2, nr
, inode
->i_ino
) < 0)
65 while ( nr
- 2 < sbi
->max_ptys
) {
67 if ( sbi
->inodes
[ptynr
] ) {
68 genptsname(numbuf
, ptynr
);
69 if ( filldir(dirent
, numbuf
, strlen(numbuf
), nr
, nr
) < 0 )
81 * Revalidate is called on every cache lookup. We use it to check that
82 * the pty really does still exist. Never revalidate negative dentries;
83 * for simplicity (fix later?)
85 static int devpts_revalidate(struct dentry
* dentry
, int flags
)
87 struct devpts_sb_info
*sbi
;
89 if ( !dentry
->d_inode
)
92 sbi
= SBI(dentry
->d_inode
->i_sb
);
94 return ( sbi
->inodes
[dentry
->d_inode
->i_ino
- 2] == dentry
->d_inode
);
97 static struct dentry
*devpts_root_lookup(struct inode
* dir
, struct dentry
* dentry
)
99 struct devpts_sb_info
*sbi
= SBI(dir
->i_sb
);
104 dentry
->d_inode
= NULL
; /* Assume failure */
105 dentry
->d_op
= &devpts_dentry_operations
;
107 if ( dentry
->d_name
.len
== 1 && dentry
->d_name
.name
[0] == '0' ) {
109 } else if ( dentry
->d_name
.len
< 1 ) {
112 p
= dentry
->d_name
.name
;
113 if ( *p
< '1' || *p
> '9' )
117 for ( i
= dentry
->d_name
.len
-1 ; i
; i
-- ) {
118 unsigned int nentry
= *p
++ - '0';
121 if ( entry
>= ~0U/10 )
123 entry
= nentry
+ entry
* 10;
127 if ( entry
>= sbi
->max_ptys
)
130 dentry
->d_inode
= sbi
->inodes
[entry
];
131 if ( dentry
->d_inode
)
132 atomic_inc(&dentry
->d_inode
->i_count
);
134 d_add(dentry
, dentry
->d_inode
);