1 /* -*- linux-c -*- --------------------------------------------------------- * 2 * 3 * linux/fs/devpts/inode.c 4 * 5 * Copyright 1998-2004 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 13 #include <linux/module.h> 14 #include <linux/init.h> 15 #include <linux/fs.h> 16 #include <linux/sched.h> 17 #include <linux/namei.h> 18 #include <linux/mount.h> 19 #include <linux/tty.h> 20 #include <linux/mutex.h> 21 #include <linux/idr.h> 22 #include <linux/devpts_fs.h> 23 #include <linux/parser.h> 24 #include <linux/fsnotify.h> 25 #include <linux/seq_file.h> 26 27 #define DEVPTS_SUPER_MAGIC 0x1cd1 28 29 #define DEVPTS_DEFAULT_MODE 0600 30 #define PTMX_MINOR 2 31 32 extern int pty_limit; /* Config limit on Unix98 ptys */ 33 static DEFINE_MUTEX(allocated_ptys_lock); 34 35 static struct vfsmount *devpts_mnt; 36 37 struct pts_mount_opts { 38 int setuid; 39 int setgid; 40 uid_t uid; 41 gid_t gid; 42 umode_t mode; 43 }; 44 45 enum { 46 Opt_uid, Opt_gid, Opt_mode, 47 Opt_err 48 }; 49 50 static const match_table_t tokens = { 51 {Opt_uid, "uid=%u"}, 52 {Opt_gid, "gid=%u"}, 53 {Opt_mode, "mode=%o"}, 54 {Opt_err, NULL} 55 }; 56 57 struct pts_fs_info { 58 struct ida allocated_ptys; 59 struct pts_mount_opts mount_opts; 60 }; 61 62 static inline struct pts_fs_info *DEVPTS_SB(struct super_block *sb) 63 { 64 return sb->s_fs_info; 65 } 66 67 static inline struct super_block *pts_sb_from_inode(struct inode *inode) 68 { 69 if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) 70 return inode->i_sb; 71 72 return devpts_mnt->mnt_sb; 73 } 74 75 static int parse_mount_options(char *data, struct pts_mount_opts *opts) 76 { 77 char *p; 78 79 opts->setuid = 0; 80 opts->setgid = 0; 81 opts->uid = 0; 82 opts->gid = 0; 83 opts->mode = DEVPTS_DEFAULT_MODE; 84 85 while ((p = strsep(&data, ",")) != NULL) { 86 substring_t args[MAX_OPT_ARGS]; 87 int token; 88 int option; 89 90 if (!*p) 91 continue; 92 93 token = match_token(p, tokens, args); 94 switch (token) { 95 case Opt_uid: 96 if (match_int(&args[0], &option)) 97 return -EINVAL; 98 opts->uid = option; 99 opts->setuid = 1; 100 break; 101 case Opt_gid: 102 if (match_int(&args[0], &option)) 103 return -EINVAL; 104 opts->gid = option; 105 opts->setgid = 1; 106 break; 107 case Opt_mode: 108 if (match_octal(&args[0], &option)) 109 return -EINVAL; 110 opts->mode = option & S_IALLUGO; 111 break; 112 default: 113 printk(KERN_ERR "devpts: called with bogus options\n"); 114 return -EINVAL; 115 } 116 } 117 118 return 0; 119 } 120 121 static int devpts_remount(struct super_block *sb, int *flags, char *data) 122 { 123 struct pts_fs_info *fsi = DEVPTS_SB(sb); 124 struct pts_mount_opts *opts = &fsi->mount_opts; 125 126 return parse_mount_options(data, opts); 127 } 128 129 static int devpts_show_options(struct seq_file *seq, struct vfsmount *vfs) 130 { 131 struct pts_fs_info *fsi = DEVPTS_SB(vfs->mnt_sb); 132 struct pts_mount_opts *opts = &fsi->mount_opts; 133 134 if (opts->setuid) 135 seq_printf(seq, ",uid=%u", opts->uid); 136 if (opts->setgid) 137 seq_printf(seq, ",gid=%u", opts->gid); 138 seq_printf(seq, ",mode=%03o", opts->mode); 139 140 return 0; 141 } 142 143 static const struct super_operations devpts_sops = { 144 .statfs = simple_statfs, 145 .remount_fs = devpts_remount, 146 .show_options = devpts_show_options, 147 }; 148 149 static void *new_pts_fs_info(void) 150 { 151 struct pts_fs_info *fsi; 152 153 fsi = kzalloc(sizeof(struct pts_fs_info), GFP_KERNEL); 154 if (!fsi) 155 return NULL; 156 157 ida_init(&fsi->allocated_ptys); 158 fsi->mount_opts.mode = DEVPTS_DEFAULT_MODE; 159 160 return fsi; 161 } 162 163 static int 164 devpts_fill_super(struct super_block *s, void *data, int silent) 165 { 166 struct inode * inode; 167 168 s->s_blocksize = 1024; 169 s->s_blocksize_bits = 10; 170 s->s_magic = DEVPTS_SUPER_MAGIC; 171 s->s_op = &devpts_sops; 172 s->s_time_gran = 1; 173 174 s->s_fs_info = new_pts_fs_info(); 175 if (!s->s_fs_info) 176 goto fail; 177 178 inode = new_inode(s); 179 if (!inode) 180 goto free_fsi; 181 inode->i_ino = 1; 182 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 183 inode->i_blocks = 0; 184 inode->i_uid = inode->i_gid = 0; 185 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR; 186 inode->i_op = &simple_dir_inode_operations; 187 inode->i_fop = &simple_dir_operations; 188 inode->i_nlink = 2; 189 190 s->s_root = d_alloc_root(inode); 191 if (s->s_root) 192 return 0; 193 194 printk("devpts: get root dentry failed\n"); 195 iput(inode); 196 197 free_fsi: 198 kfree(s->s_fs_info); 199 fail: 200 return -ENOMEM; 201 } 202 203 static int devpts_get_sb(struct file_system_type *fs_type, 204 int flags, const char *dev_name, void *data, struct vfsmount *mnt) 205 { 206 return get_sb_single(fs_type, flags, data, devpts_fill_super, mnt); 207 } 208 209 static void devpts_kill_sb(struct super_block *sb) 210 { 211 struct pts_fs_info *fsi = DEVPTS_SB(sb); 212 213 kfree(fsi); 214 kill_anon_super(sb); 215 } 216 217 static struct file_system_type devpts_fs_type = { 218 .owner = THIS_MODULE, 219 .name = "devpts", 220 .get_sb = devpts_get_sb, 221 .kill_sb = devpts_kill_sb, 222 }; 223 224 /* 225 * The normal naming convention is simply /dev/pts/<number>; this conforms 226 * to the System V naming convention 227 */ 228 229 int devpts_new_index(struct inode *ptmx_inode) 230 { 231 struct super_block *sb = pts_sb_from_inode(ptmx_inode); 232 struct pts_fs_info *fsi = DEVPTS_SB(sb); 233 int index; 234 int ida_ret; 235 236 retry: 237 if (!ida_pre_get(&fsi->allocated_ptys, GFP_KERNEL)) { 238 return -ENOMEM; 239 } 240 241 mutex_lock(&allocated_ptys_lock); 242 ida_ret = ida_get_new(&fsi->allocated_ptys, &index); 243 if (ida_ret < 0) { 244 mutex_unlock(&allocated_ptys_lock); 245 if (ida_ret == -EAGAIN) 246 goto retry; 247 return -EIO; 248 } 249 250 if (index >= pty_limit) { 251 ida_remove(&fsi->allocated_ptys, index); 252 mutex_unlock(&allocated_ptys_lock); 253 return -EIO; 254 } 255 mutex_unlock(&allocated_ptys_lock); 256 return index; 257 } 258 259 void devpts_kill_index(struct inode *ptmx_inode, int idx) 260 { 261 struct super_block *sb = pts_sb_from_inode(ptmx_inode); 262 struct pts_fs_info *fsi = DEVPTS_SB(sb); 263 264 mutex_lock(&allocated_ptys_lock); 265 ida_remove(&fsi->allocated_ptys, idx); 266 mutex_unlock(&allocated_ptys_lock); 267 } 268 269 int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) 270 { 271 int number = tty->index; /* tty layer puts index from devpts_new_index() in here */ 272 struct tty_driver *driver = tty->driver; 273 dev_t device = MKDEV(driver->major, driver->minor_start+number); 274 struct dentry *dentry; 275 struct super_block *sb = pts_sb_from_inode(ptmx_inode); 276 struct inode *inode = new_inode(sb); 277 struct dentry *root = sb->s_root; 278 struct pts_fs_info *fsi = DEVPTS_SB(sb); 279 struct pts_mount_opts *opts = &fsi->mount_opts; 280 char s[12]; 281 282 /* We're supposed to be given the slave end of a pty */ 283 BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY); 284 BUG_ON(driver->subtype != PTY_TYPE_SLAVE); 285 286 if (!inode) 287 return -ENOMEM; 288 289 inode->i_ino = number+2; 290 inode->i_uid = config.setuid ? config.uid : current_fsuid(); 291 inode->i_gid = config.setgid ? config.gid : current_fsgid(); 292 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 293 init_special_inode(inode, S_IFCHR|opts->mode, device); 294 inode->i_private = tty; 295 tty->driver_data = inode; 296 297 sprintf(s, "%d", number); 298 299 mutex_lock(&root->d_inode->i_mutex); 300 301 dentry = d_alloc_name(root, s); 302 if (!IS_ERR(dentry)) { 303 d_add(dentry, inode); 304 fsnotify_create(root->d_inode, dentry); 305 } 306 307 mutex_unlock(&root->d_inode->i_mutex); 308 309 return 0; 310 } 311 312 struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number) 313 { 314 BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); 315 316 if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) 317 return (struct tty_struct *)pts_inode->i_private; 318 return NULL; 319 } 320 321 void devpts_pty_kill(struct tty_struct *tty) 322 { 323 struct inode *inode = tty->driver_data; 324 struct super_block *sb = pts_sb_from_inode(inode); 325 struct dentry *root = sb->s_root; 326 struct dentry *dentry; 327 328 BUG_ON(inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); 329 330 mutex_lock(&root->d_inode->i_mutex); 331 332 dentry = d_find_alias(inode); 333 if (dentry && !IS_ERR(dentry)) { 334 inode->i_nlink--; 335 d_delete(dentry); 336 dput(dentry); 337 } 338 339 mutex_unlock(&root->d_inode->i_mutex); 340 } 341 342 static int __init init_devpts_fs(void) 343 { 344 int err = register_filesystem(&devpts_fs_type); 345 if (!err) { 346 devpts_mnt = kern_mount(&devpts_fs_type); 347 if (IS_ERR(devpts_mnt)) 348 err = PTR_ERR(devpts_mnt); 349 } 350 return err; 351 } 352 353 static void __exit exit_devpts_fs(void) 354 { 355 unregister_filesystem(&devpts_fs_type); 356 mntput(devpts_mnt); 357 } 358 359 module_init(init_devpts_fs) 360 module_exit(exit_devpts_fs) 361 MODULE_LICENSE("GPL"); 362