diff options
Diffstat (limited to 'fs/coda/inode.c')
-rw-r--r-- | fs/coda/inode.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index f1813120d753..4dcc0d81a7aa 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -20,6 +20,7 @@ #include <linux/file.h> #include <linux/vfs.h> #include <linux/slab.h> +#include <linux/pid_namespace.h> #include <asm/uaccess.h> @@ -48,7 +49,7 @@ static struct inode *coda_alloc_inode(struct super_block *sb) return NULL; memset(&ei->c_fid, 0, sizeof(struct CodaFid)); ei->c_flags = 0; - ei->c_uid = 0; + ei->c_uid = GLOBAL_ROOT_UID; ei->c_cached_perm = 0; spin_lock_init(&ei->c_lock); return &ei->vfs_inode; @@ -85,6 +86,11 @@ int coda_init_inodecache(void) void coda_destroy_inodecache(void) { + /* + * Make sure all delayed rcu free inodes are flushed before we + * destroy cache. + */ + rcu_barrier(); kmem_cache_destroy(coda_inode_cachep); } @@ -107,43 +113,41 @@ static const struct super_operations coda_super_operations = static int get_device_index(struct coda_mount_data *data) { - struct file *file; + struct fd f; struct inode *inode; int idx; - if(data == NULL) { + if (data == NULL) { printk("coda_read_super: Bad mount data\n"); return -1; } - if(data->version != CODA_MOUNT_VERSION) { + if (data->version != CODA_MOUNT_VERSION) { printk("coda_read_super: Bad mount version\n"); return -1; } - file = fget(data->fd); - inode = NULL; - if(file) - inode = file->f_path.dentry->d_inode; - - if(!inode || !S_ISCHR(inode->i_mode) || - imajor(inode) != CODA_PSDEV_MAJOR) { - if(file) - fput(file); - - printk("coda_read_super: Bad file\n"); - return -1; + f = fdget(data->fd); + if (!f.file) + goto Ebadf; + inode = file_inode(f.file); + if (!S_ISCHR(inode->i_mode) || imajor(inode) != CODA_PSDEV_MAJOR) { + fdput(f); + goto Ebadf; } idx = iminor(inode); - fput(file); + fdput(f); - if(idx < 0 || idx >= MAX_CODADEVS) { + if (idx < 0 || idx >= MAX_CODADEVS) { printk("coda_read_super: Bad minor number\n"); return -1; } return idx; +Ebadf: + printk("coda_read_super: Bad file\n"); + return -1; } static int coda_fill_super(struct super_block *sb, void *data, int silent) @@ -154,6 +158,9 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) int error; int idx; + if (task_active_pid_ns(current) != &init_pid_ns) + return -EINVAL; + idx = get_device_index((struct coda_mount_data *) data); /* Ignore errors in data, for backward compatibility */ @@ -322,4 +329,5 @@ struct file_system_type coda_fs_type = { .kill_sb = kill_anon_super, .fs_flags = FS_BINARY_MOUNTDATA, }; +MODULE_ALIAS_FS("coda"); |