X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fdevpts%2Finode.c;h=5fa3655975153cf482e930efccbdea6a230ca808;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=db40284e77229dce8ad504d4defd15924ff857bc;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index db40284e7..5fa365597 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -18,8 +18,21 @@ #include #include #include -#include -#include "xattr.h" +#include + + +static int devpts_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + int ret = -EACCES; + + if (vx_check(inode->i_xid, VX_IDENT)) + ret = generic_permission(inode, mask, NULL); + return ret; +} + +static struct inode_operations devpts_file_inode_operations = { + .permission = devpts_permission, +}; static struct vfsmount *devpts_mnt; static struct dentry *devpts_root; @@ -32,95 +45,72 @@ static struct { umode_t mode; } config = {.mode = 0600}; +enum { + Opt_uid, Opt_gid, Opt_mode, + Opt_err +}; + +static match_table_t tokens = { + {Opt_uid, "uid=%u"}, + {Opt_gid, "gid=%u"}, + {Opt_mode, "mode=%o"}, + {Opt_err, NULL} +}; + static int devpts_remount(struct super_block *sb, int *flags, char *data) { - int setuid = 0; - int setgid = 0; - uid_t uid = 0; - gid_t gid = 0; - umode_t mode = 0600; - char *this_char; - - this_char = NULL; - while ((this_char = strsep(&data, ",")) != NULL) { - int n; - char dummy; - if (!*this_char) + char *p; + + config.setuid = 0; + config.setgid = 0; + config.uid = 0; + config.gid = 0; + config.mode = 0600; + + while ((p = strsep(&data, ",")) != NULL) { + substring_t args[MAX_OPT_ARGS]; + int token; + int option; + + if (!*p) continue; - if (sscanf(this_char, "uid=%i%c", &n, &dummy) == 1) { - setuid = 1; - uid = n; - } else if (sscanf(this_char, "gid=%i%c", &n, &dummy) == 1) { - setgid = 1; - gid = n; - } else if (sscanf(this_char, "mode=%o%c", &n, &dummy) == 1) - mode = n & ~S_IFMT; - else { - printk("devpts: called with bogus options\n"); + + token = match_token(p, tokens, args); + switch (token) { + case Opt_uid: + if (match_int(&args[0], &option)) + return -EINVAL; + config.uid = option; + config.setuid = 1; + break; + case Opt_gid: + if (match_int(&args[0], &option)) + return -EINVAL; + config.gid = option; + config.setgid = 1; + break; + case Opt_mode: + if (match_octal(&args[0], &option)) + return -EINVAL; + config.mode = option & ~S_IFMT; + break; + default: + printk(KERN_ERR "devpts: called with bogus options\n"); return -EINVAL; } } - config.setuid = setuid; - config.setgid = setgid; - config.uid = uid; - config.gid = gid; - config.mode = mode; return 0; } +static int devpts_filter(struct dentry *de) +{ + return vx_check(de->d_inode->i_xid, VX_IDENT); +} + static int devpts_readdir(struct file * filp, void * dirent, filldir_t filldir) { - struct dentry *dentry = filp->f_dentry; - struct dentry *cursor = filp->private_data; - struct list_head *p, *q = &cursor->d_child; - ino_t ino; - int i = filp->f_pos; - - switch (i) { - case 0: - ino = dentry->d_inode->i_ino; - if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) - break; - filp->f_pos++; - i++; - /* fallthrough */ - case 1: - ino = parent_ino(dentry); - if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) - break; - filp->f_pos++; - i++; - /* fallthrough */ - default: - spin_lock(&dcache_lock); - if (filp->f_pos == 2) { - list_del(q); - list_add(q, &dentry->d_subdirs); - } - for (p=q->next; p != &dentry->d_subdirs; p=p->next) { - struct dentry *next; - next = list_entry(p, struct dentry, d_child); - if (d_unhashed(next) || !next->d_inode) - continue; - if (!vx_check(next->d_inode->i_xid, VX_IDENT)) - continue; - - spin_unlock(&dcache_lock); - if (filldir(dirent, next->d_name.name, - next->d_name.len, filp->f_pos, - next->d_inode->i_ino, DT_CHR) < 0) - return 0; - spin_lock(&dcache_lock); - /* next is still alive */ - list_del(q); - list_add(q, p); - p = q; - filp->f_pos++; - } - spin_unlock(&dcache_lock); - } - return 0; + return dcache_readdir_filter(filp, dirent, filldir, devpts_filter); } static struct file_operations devpts_dir_operations = { @@ -145,6 +135,7 @@ devpts_fill_super(struct super_block *s, void *data, int silent) s->s_blocksize_bits = 10; s->s_magic = DEVPTS_SUPER_MAGIC; s->s_op = &devpts_sops; + s->s_time_gran = 1; inode = new_inode(s); if (!inode) @@ -192,27 +183,10 @@ static struct dentry *get_node(int num) { char s[12]; struct dentry *root = devpts_root; - down(&root->d_inode->i_sem); + mutex_lock(&root->d_inode->i_mutex); return lookup_one_len(s, root, sprintf(s, "%d", num)); } -static int devpts_permission(struct inode *inode, int mask, struct nameidata *nd) -{ - int ret = -EACCES; - - if (vx_check(inode->i_xid, VX_IDENT)) - ret = vfs_permission(inode, mask); - return ret; -} - -static struct inode_operations devpts_file_inode_operations = { - .setxattr = devpts_setxattr, - .getxattr = devpts_getxattr, - .listxattr = devpts_listxattr, - .removexattr = devpts_removexattr, - .permission = devpts_permission, -}; - int devpts_pty_new(struct tty_struct *tty) { int number = tty->index; @@ -242,7 +216,7 @@ int devpts_pty_new(struct tty_struct *tty) if (!IS_ERR(dentry) && !dentry->d_inode) d_instantiate(dentry, inode); - up(&devpts_root->d_inode->i_sem); + mutex_unlock(&devpts_root->d_inode->i_mutex); return 0; } @@ -259,7 +233,7 @@ struct tty_struct *devpts_get_tty(int number) dput(dentry); } - up(&devpts_root->d_inode->i_sem); + mutex_unlock(&devpts_root->d_inode->i_mutex); return tty; } @@ -277,15 +251,12 @@ void devpts_pty_kill(int number) } dput(dentry); } - up(&devpts_root->d_inode->i_sem); + mutex_unlock(&devpts_root->d_inode->i_mutex); } static int __init init_devpts_fs(void) { - int err = init_devpts_xattr(); - if (err) - return err; - err = register_filesystem(&devpts_fs_type); + int err = register_filesystem(&devpts_fs_type); if (!err) { devpts_mnt = kern_mount(&devpts_fs_type); if (IS_ERR(devpts_mnt)) @@ -298,7 +269,6 @@ static void __exit exit_devpts_fs(void) { unregister_filesystem(&devpts_fs_type); mntput(devpts_mnt); - exit_devpts_xattr(); } module_init(init_devpts_fs)