diff options
Diffstat (limited to 'fs/coda')
| -rw-r--r-- | fs/coda/Makefile | 2 | ||||
| -rw-r--r-- | fs/coda/cache.c | 23 | ||||
| -rw-r--r-- | fs/coda/cnode.c | 47 | ||||
| -rw-r--r-- | fs/coda/coda_cache.h | 22 | ||||
| -rw-r--r-- | fs/coda/coda_fs_i.h | 58 | ||||
| -rw-r--r-- | fs/coda/coda_int.h | 4 | ||||
| -rw-r--r-- | fs/coda/coda_linux.c | 13 | ||||
| -rw-r--r-- | fs/coda/coda_linux.h | 106 | ||||
| -rw-r--r-- | fs/coda/dir.c | 175 | ||||
| -rw-r--r-- | fs/coda/file.c | 31 | ||||
| -rw-r--r-- | fs/coda/inode.c | 109 | ||||
| -rw-r--r-- | fs/coda/pioctl.c | 6 | ||||
| -rw-r--r-- | fs/coda/psdev.c | 51 | ||||
| -rw-r--r-- | fs/coda/symlink.c | 4 | ||||
| -rw-r--r-- | fs/coda/sysctl.c | 21 | ||||
| -rw-r--r-- | fs/coda/upcall.c | 30 | 
16 files changed, 433 insertions, 269 deletions
diff --git a/fs/coda/Makefile b/fs/coda/Makefile index 6c22e61da39..1bab69a0d34 100644 --- a/fs/coda/Makefile +++ b/fs/coda/Makefile @@ -9,4 +9,4 @@ coda-objs := psdev.o cache.o cnode.o inode.o dir.o file.o upcall.o \  # If you want debugging output, please uncomment the following line. -# EXTRA_CFLAGS += -DDEBUG -DDEBUG_SMB_MALLOC=1 +# ccflags-y := -DDEBUG -DDEBUG_SMB_MALLOC=1 diff --git a/fs/coda/cache.c b/fs/coda/cache.c index 9060f08e70c..1da168c61d3 100644 --- a/fs/coda/cache.c +++ b/fs/coda/cache.c @@ -20,10 +20,9 @@  #include <linux/spinlock.h>  #include <linux/coda.h> -#include <linux/coda_linux.h>  #include <linux/coda_psdev.h> -#include <linux/coda_fs_i.h> -#include <linux/coda_cache.h> +#include "coda_linux.h" +#include "coda_cache.h"  static atomic_t permission_epoch = ATOMIC_INIT(0); @@ -34,7 +33,7 @@ void coda_cache_enter(struct inode *inode, int mask)  	spin_lock(&cii->c_lock);  	cii->c_cached_epoch = atomic_read(&permission_epoch); -	if (cii->c_uid != current_fsuid()) { +	if (!uid_eq(cii->c_uid, current_fsuid())) {  		cii->c_uid = current_fsuid();                  cii->c_cached_perm = mask;          } else @@ -66,7 +65,7 @@ int coda_cache_check(struct inode *inode, int mask)  	spin_lock(&cii->c_lock);  	hit = (mask & cii->c_cached_perm) == mask && -	    cii->c_uid == current_fsuid() && +	    uid_eq(cii->c_uid, current_fsuid()) &&  	    cii->c_cached_epoch == atomic_read(&permission_epoch);  	spin_unlock(&cii->c_lock); @@ -90,19 +89,15 @@ int coda_cache_check(struct inode *inode, int mask)  /* this won't do any harm: just flag all children */  static void coda_flag_children(struct dentry *parent, int flag)  { -	struct list_head *child;  	struct dentry *de; -	spin_lock(&dcache_lock); -	list_for_each(child, &parent->d_subdirs) -	{ -		de = list_entry(child, struct dentry, d_u.d_child); +	spin_lock(&parent->d_lock); +	list_for_each_entry(de, &parent->d_subdirs, d_u.d_child) {  		/* don't know what to do with negative dentries */ -		if ( ! de->d_inode )  -			continue; -		coda_flag_inode(de->d_inode, flag); +		if (de->d_inode )  +			coda_flag_inode(de->d_inode, flag);  	} -	spin_unlock(&dcache_lock); +	spin_unlock(&parent->d_lock);  	return;   } diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c index 602240569c8..7740b1c871c 100644 --- a/fs/coda/cnode.c +++ b/fs/coda/cnode.c @@ -7,9 +7,8 @@  #include <linux/time.h>  #include <linux/coda.h> -#include <linux/coda_linux.h> -#include <linux/coda_fs_i.h>  #include <linux/coda_psdev.h> +#include "coda_linux.h"  static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)  { @@ -89,24 +88,21 @@ struct inode * coda_iget(struct super_block * sb, struct CodaFid * fid,     - link the two up if this is needed     - fill in the attributes  */ -int coda_cnode_make(struct inode **inode, struct CodaFid *fid, struct super_block *sb) +struct inode *coda_cnode_make(struct CodaFid *fid, struct super_block *sb)  {          struct coda_vattr attr; +	struct inode *inode;          int error;  	/* We get inode numbers from Venus -- see venus source */  	error = venus_getattr(sb, fid, &attr); -	if ( error ) { -	    *inode = NULL; -	    return error; -	}  - -	*inode = coda_iget(sb, fid, &attr); -	if ( IS_ERR(*inode) ) { -		printk("coda_cnode_make: coda_iget failed\n"); -                return PTR_ERR(*inode); -        } -	return 0; +	if (error) +		return ERR_PTR(error); + +	inode = coda_iget(sb, fid, &attr); +	if (IS_ERR(inode)) +		pr_warn("%s: coda_iget failed\n", __func__); +	return inode;  } @@ -141,7 +137,7 @@ struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb)  	unsigned long hash = coda_f2i(fid);  	if ( !sb ) { -		printk("coda_fid_to_inode: no sb!\n"); +		pr_warn("%s: no sb!\n", __func__);  		return NULL;  	} @@ -157,19 +153,16 @@ struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb)  }  /* the CONTROL inode is made without asking attributes from Venus */ -int coda_cnode_makectl(struct inode **inode, struct super_block *sb) +struct inode *coda_cnode_makectl(struct super_block *sb)  { -	int error = -ENOMEM; - -	*inode = new_inode(sb); -	if (*inode) { -		(*inode)->i_ino = CTL_INO; -		(*inode)->i_op = &coda_ioctl_inode_operations; -		(*inode)->i_fop = &coda_ioctl_operations; -		(*inode)->i_mode = 0444; -		error = 0; +	struct inode *inode = new_inode(sb); +	if (inode) { +		inode->i_ino = CTL_INO; +		inode->i_op = &coda_ioctl_inode_operations; +		inode->i_fop = &coda_ioctl_operations; +		inode->i_mode = 0444; +		return inode;  	} - -	return error; +	return ERR_PTR(-ENOMEM);  } diff --git a/fs/coda/coda_cache.h b/fs/coda/coda_cache.h new file mode 100644 index 00000000000..c910b5eb1ce --- /dev/null +++ b/fs/coda/coda_cache.h @@ -0,0 +1,22 @@ +/* Coda filesystem -- Linux Minicache + * + * Copyright (C) 1989 - 1997 Carnegie Mellon University + * + * Carnegie Mellon University encourages users of this software to + * contribute improvements to the Coda project. Contact Peter Braam + * <coda@cs.cmu.edu> + */ + +#ifndef _CFSNC_HEADER_ +#define _CFSNC_HEADER_ + +/* credential cache */ +void coda_cache_enter(struct inode *inode, int mask); +void coda_cache_clear_inode(struct inode *); +void coda_cache_clear_all(struct super_block *sb); +int coda_cache_check(struct inode *inode, int mask); + +/* for downcalls and attributes and lookups */ +void coda_flag_inode_children(struct inode *inode, int flag); + +#endif /* _CFSNC_HEADER_ */ diff --git a/fs/coda/coda_fs_i.h b/fs/coda/coda_fs_i.h new file mode 100644 index 00000000000..c6407521321 --- /dev/null +++ b/fs/coda/coda_fs_i.h @@ -0,0 +1,58 @@ +/* + *  coda_fs_i.h + * + *  Copyright (C) 1998 Carnegie Mellon University + * + */ + +#ifndef _LINUX_CODA_FS_I +#define _LINUX_CODA_FS_I + +#include <linux/types.h> +#include <linux/list.h> +#include <linux/spinlock.h> +#include <linux/coda.h> + +/* + * coda fs inode data + * c_lock protects accesses to c_flags, c_mapcount, c_cached_epoch, c_uid and + * c_cached_perm. + * vfs_inode is set only when the inode is created and never changes. + * c_fid is set when the inode is created and should be considered immutable. + */ +struct coda_inode_info { +	struct CodaFid	   c_fid;	/* Coda identifier */ +	u_short	           c_flags;     /* flags (see below) */ +	unsigned int	   c_mapcount;  /* nr of times this inode is mapped */ +	unsigned int	   c_cached_epoch; /* epoch for cached permissions */ +	kuid_t		   c_uid;	/* fsuid for cached permissions */ +	unsigned int       c_cached_perm; /* cached access permissions */ +	spinlock_t	   c_lock; +	struct inode	   vfs_inode; +}; + +/* + * coda fs file private data + */ +#define CODA_MAGIC 0xC0DAC0DA +struct coda_file_info { +	int		   cfi_magic;	  /* magic number */ +	struct file	  *cfi_container; /* container file for this cnode */ +	unsigned int	   cfi_mapcount;  /* nr of times this file is mapped */ +}; + +#define CODA_FTOC(file) ((struct coda_file_info *)((file)->private_data)) + +/* flags */ +#define C_VATTR       0x1   /* Validity of vattr in inode */ +#define C_FLUSH       0x2   /* used after a flush */ +#define C_DYING       0x4   /* from venus (which died) */ +#define C_PURGE       0x8 + +struct inode *coda_cnode_make(struct CodaFid *, struct super_block *); +struct inode *coda_iget(struct super_block *sb, struct CodaFid *fid, struct coda_vattr *attr); +struct inode *coda_cnode_makectl(struct super_block *sb); +struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb); +void coda_replace_fid(struct inode *, struct CodaFid *, struct CodaFid *); + +#endif diff --git a/fs/coda/coda_int.h b/fs/coda/coda_int.h index 6b443ff43a1..381c993b142 100644 --- a/fs/coda/coda_int.h +++ b/fs/coda/coda_int.h @@ -10,8 +10,8 @@ extern int coda_hard;  extern int coda_fake_statfs;  void coda_destroy_inodecache(void); -int coda_init_inodecache(void); -int coda_fsync(struct file *coda_file, int datasync); +int __init coda_init_inodecache(void); +int coda_fsync(struct file *coda_file, loff_t start, loff_t end, int datasync);  void coda_sysctl_init(void);  void coda_sysctl_clean(void); diff --git a/fs/coda/coda_linux.c b/fs/coda/coda_linux.c index bf4a3fd3c8e..2849f41e72a 100644 --- a/fs/coda/coda_linux.c +++ b/fs/coda/coda_linux.c @@ -17,9 +17,8 @@  #include <linux/string.h>  #include <linux/coda.h> -#include <linux/coda_linux.h>  #include <linux/coda_psdev.h> -#include <linux/coda_fs_i.h> +#include "coda_linux.h"  /* initialize the debugging variables */  int coda_fake_statfs; @@ -101,11 +100,11 @@ void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr)  	if (attr->va_mode != (u_short) -1)  	        inode->i_mode = attr->va_mode | inode_type;          if (attr->va_uid != -1)  -	        inode->i_uid = (uid_t) attr->va_uid; +	        inode->i_uid = make_kuid(&init_user_ns, (uid_t) attr->va_uid);          if (attr->va_gid != -1) -	        inode->i_gid = (gid_t) attr->va_gid; +	        inode->i_gid = make_kgid(&init_user_ns, (gid_t) attr->va_gid);  	if (attr->va_nlink != -1) -	        inode->i_nlink = attr->va_nlink; +		set_nlink(inode, attr->va_nlink);  	if (attr->va_size != -1)  	        inode->i_size = attr->va_size;  	if (attr->va_size != -1) @@ -172,10 +171,10 @@ void coda_iattr_to_vattr(struct iattr *iattr, struct coda_vattr *vattr)                  vattr->va_mode = iattr->ia_mode;  	}          if ( valid & ATTR_UID ) { -                vattr->va_uid = (vuid_t) iattr->ia_uid; +                vattr->va_uid = (vuid_t) from_kuid(&init_user_ns, iattr->ia_uid);  	}          if ( valid & ATTR_GID ) { -                vattr->va_gid = (vgid_t) iattr->ia_gid; +                vattr->va_gid = (vgid_t) from_kgid(&init_user_ns, iattr->ia_gid);  	}          if ( valid & ATTR_SIZE ) {                  vattr->va_size = iattr->ia_size; diff --git a/fs/coda/coda_linux.h b/fs/coda/coda_linux.h new file mode 100644 index 00000000000..d42b725b1d2 --- /dev/null +++ b/fs/coda/coda_linux.h @@ -0,0 +1,106 @@ +/*  + * Coda File System, Linux Kernel module + *  + * Original version, adapted from cfs_mach.c, (C) Carnegie Mellon University + * Linux modifications (C) 1996, Peter J. Braam + * Rewritten for Linux 2.1 (C) 1997 Carnegie Mellon University + * + * Carnegie Mellon University encourages users of this software to + * contribute improvements to the Coda project. + */ + +#ifndef _LINUX_CODA_FS +#define _LINUX_CODA_FS + +#ifdef pr_fmt +#undef pr_fmt +#endif + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/kernel.h> +#include <linux/param.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/slab.h> +#include <linux/wait.h>		 +#include <linux/types.h> +#include <linux/fs.h> +#include "coda_fs_i.h" + +/* operations */ +extern const struct inode_operations coda_dir_inode_operations; +extern const struct inode_operations coda_file_inode_operations; +extern const struct inode_operations coda_ioctl_inode_operations; + +extern const struct dentry_operations coda_dentry_operations; + +extern const struct address_space_operations coda_file_aops; +extern const struct address_space_operations coda_symlink_aops; + +extern const struct file_operations coda_dir_operations; +extern const struct file_operations coda_file_operations; +extern const struct file_operations coda_ioctl_operations; + +/* operations shared over more than one file */ +int coda_open(struct inode *i, struct file *f); +int coda_release(struct inode *i, struct file *f); +int coda_permission(struct inode *inode, int mask); +int coda_revalidate_inode(struct inode *); +int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *); +int coda_setattr(struct dentry *, struct iattr *); + +/* this file:  heloers */ +char *coda_f2s(struct CodaFid *f); +int coda_isroot(struct inode *i); +int coda_iscontrol(const char *name, size_t length); + +void coda_vattr_to_iattr(struct inode *, struct coda_vattr *); +void coda_iattr_to_vattr(struct iattr *, struct coda_vattr *); +unsigned short coda_flags_to_cflags(unsigned short); + +/* sysctl.h */ +void coda_sysctl_init(void); +void coda_sysctl_clean(void); + +#define CODA_ALLOC(ptr, cast, size) do { \ +    if (size < PAGE_SIZE) \ +        ptr = kzalloc((unsigned long) size, GFP_KERNEL); \ +    else \ +        ptr = (cast)vzalloc((unsigned long) size); \ +    if (!ptr) \ +	pr_warn("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \ +} while (0) + + +#define CODA_FREE(ptr,size) \ +    do { if (size < PAGE_SIZE) kfree((ptr)); else vfree((ptr)); } while (0) + +/* inode to cnode access functions */ + +static inline struct coda_inode_info *ITOC(struct inode *inode) +{ +	return list_entry(inode, struct coda_inode_info, vfs_inode); +} + +static __inline__ struct CodaFid *coda_i2f(struct inode *inode) +{ +	return &(ITOC(inode)->c_fid); +} + +static __inline__ char *coda_i2s(struct inode *inode) +{ +	return coda_f2s(&(ITOC(inode)->c_fid)); +} + +/* this will not zap the inode away */ +static __inline__ void coda_flag_inode(struct inode *inode, int flag) +{ +	struct coda_inode_info *cii = ITOC(inode); + +	spin_lock(&cii->c_lock); +	cii->c_flags |= flag; +	spin_unlock(&cii->c_lock); +}		 + +#endif diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 5d8b3553960..cd8a63238b1 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -18,40 +18,39 @@  #include <linux/errno.h>  #include <linux/string.h>  #include <linux/spinlock.h> +#include <linux/namei.h>  #include <asm/uaccess.h>  #include <linux/coda.h> -#include <linux/coda_linux.h>  #include <linux/coda_psdev.h> -#include <linux/coda_fs_i.h> -#include <linux/coda_cache.h> +#include "coda_linux.h" +#include "coda_cache.h"  #include "coda_int.h"  /* dir inode-ops */ -static int coda_create(struct inode *dir, struct dentry *new, int mode, struct nameidata *nd); -static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, struct nameidata *nd); +static int coda_create(struct inode *dir, struct dentry *new, umode_t mode, bool excl); +static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, unsigned int flags);  static int coda_link(struct dentry *old_dentry, struct inode *dir_inode,   		     struct dentry *entry);  static int coda_unlink(struct inode *dir_inode, struct dentry *entry);  static int coda_symlink(struct inode *dir_inode, struct dentry *entry,  			const char *symname); -static int coda_mkdir(struct inode *dir_inode, struct dentry *entry, int mode); +static int coda_mkdir(struct inode *dir_inode, struct dentry *entry, umode_t mode);  static int coda_rmdir(struct inode *dir_inode, struct dentry *entry);  static int coda_rename(struct inode *old_inode, struct dentry *old_dentry,                          struct inode *new_inode, struct dentry *new_dentry);  /* dir file-ops */ -static int coda_readdir(struct file *file, void *buf, filldir_t filldir); +static int coda_readdir(struct file *file, struct dir_context *ctx);  /* dentry ops */ -static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd); -static int coda_dentry_delete(struct dentry *); +static int coda_dentry_revalidate(struct dentry *de, unsigned int flags); +static int coda_dentry_delete(const struct dentry *);  /* support routines */ -static int coda_venus_readdir(struct file *coda_file, void *buf, -			      filldir_t filldir); +static int coda_venus_readdir(struct file *, struct dir_context *);  /* same as fs/bad_inode.c */  static int coda_return_EIO(void) @@ -60,7 +59,7 @@ static int coda_return_EIO(void)  }  #define CODA_EIO_ERROR ((void *) (coda_return_EIO)) -static const struct dentry_operations coda_dentry_operations = +const struct dentry_operations coda_dentry_operations =  {  	.d_revalidate	= coda_dentry_revalidate,  	.d_delete	= coda_dentry_delete, @@ -85,7 +84,7 @@ const struct inode_operations coda_dir_inode_operations =  const struct file_operations coda_dir_operations = {  	.llseek		= generic_file_llseek,  	.read		= generic_read_dir, -	.readdir	= coda_readdir, +	.iterate	= coda_readdir,  	.open		= coda_open,  	.release	= coda_release,  	.fsync		= coda_fsync, @@ -94,42 +93,37 @@ const struct file_operations coda_dir_operations = {  /* inode operations for directories */  /* access routines: lookup, readlink, permission */ -static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd) +static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsigned int flags)  { -	struct inode *inode = NULL; -	struct CodaFid resfid = { { 0, } }; -	int type = 0; -	int error = 0; +	struct super_block *sb = dir->i_sb;  	const char *name = entry->d_name.name;  	size_t length = entry->d_name.len; +	struct inode *inode; +	int type = 0;  	if (length > CODA_MAXNAMLEN) { -		printk(KERN_ERR "name too long: lookup, %s (%*s)\n", +		pr_err("name too long: lookup, %s (%*s)\n",  		       coda_i2s(dir), (int)length, name);  		return ERR_PTR(-ENAMETOOLONG);  	}  	/* control object, create inode on the fly */  	if (coda_isroot(dir) && coda_iscontrol(name, length)) { -		error = coda_cnode_makectl(&inode, dir->i_sb); +		inode = coda_cnode_makectl(sb);  		type = CODA_NOCACHE; -		goto exit; +	} else { +		struct CodaFid fid = { { 0, } }; +		int error = venus_lookup(sb, coda_i2f(dir), name, length, +				     &type, &fid); +		inode = !error ? coda_cnode_make(&fid, sb) : ERR_PTR(error);  	} -	error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length, -			     &type, &resfid); -	if (!error) -		error = coda_cnode_make(&inode, &resfid, dir->i_sb); - -	if (error && error != -ENOENT) -		return ERR_PTR(error); - -exit: -	entry->d_op = &coda_dentry_operations; - -	if (inode && (type & CODA_NOCACHE)) +	if (!IS_ERR(inode) && (type & CODA_NOCACHE))  		coda_flag_inode(inode, C_VATTR | C_PURGE); +	if (inode == ERR_PTR(-ENOENT)) +		inode = NULL; +  	return d_splice_alias(inode, entry);  } @@ -138,6 +132,9 @@ int coda_permission(struct inode *inode, int mask)  {  	int error; +	if (mask & MAY_NOT_BLOCK) +		return -ECHILD; +  	mask &= MAY_READ | MAY_WRITE | MAY_EXEC;  	if (!mask) @@ -190,7 +187,7 @@ static inline void coda_dir_drop_nlink(struct inode *dir)  }  /* creation routines: create, mknod, mkdir, link, symlink */ -static int coda_create(struct inode *dir, struct dentry *de, int mode, struct nameidata *nd) +static int coda_create(struct inode *dir, struct dentry *de, umode_t mode, bool excl)  {  	int error;  	const char *name=de->d_name.name; @@ -222,7 +219,7 @@ err_out:  	return error;  } -static int coda_mkdir(struct inode *dir, struct dentry *de, int mode) +static int coda_mkdir(struct inode *dir, struct dentry *de, umode_t mode)  {  	struct inode *inode;  	struct coda_vattr attrs; @@ -339,7 +336,7 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)  	if (!error) {  		/* VFS may delete the child */  		if (de->d_inode) -		    de->d_inode->i_nlink = 0; +			clear_nlink(de->d_inode);  		/* fix the link count of the parent */  		coda_dir_drop_nlink(dir); @@ -380,7 +377,7 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,  /* file operations for directories */ -static int coda_readdir(struct file *coda_file, void *buf, filldir_t filldir) +static int coda_readdir(struct file *coda_file, struct dir_context *ctx)  {  	struct coda_file_info *cfi;  	struct file *host_file; @@ -390,33 +387,19 @@ static int coda_readdir(struct file *coda_file, void *buf, filldir_t filldir)  	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);  	host_file = cfi->cfi_container; -	if (!host_file->f_op) -		return -ENOTDIR; - -	if (host_file->f_op->readdir) -	{ -		/* potemkin case: we were handed a directory inode. -		 * We can't use vfs_readdir because we have to keep the file -		 * position in sync between the coda_file and the host_file. -		 * and as such we need grab the inode mutex. */ -		struct inode *host_inode = host_file->f_path.dentry->d_inode; - +	if (host_file->f_op->iterate) { +		struct inode *host_inode = file_inode(host_file);  		mutex_lock(&host_inode->i_mutex); -		host_file->f_pos = coda_file->f_pos; -  		ret = -ENOENT;  		if (!IS_DEADDIR(host_inode)) { -			ret = host_file->f_op->readdir(host_file, buf, filldir); +			ret = host_file->f_op->iterate(host_file, ctx);  			file_accessed(host_file);  		} - -		coda_file->f_pos = host_file->f_pos;  		mutex_unlock(&host_inode->i_mutex); +		return ret;  	} -	else /* Venus: we must read Venus dirents from a file */ -		ret = coda_venus_readdir(coda_file, buf, filldir); - -	return ret; +	/* Venus: we must read Venus dirents from a file */ +	return coda_venus_readdir(coda_file, ctx);  }  static inline unsigned int CDT2DT(unsigned char cdt) @@ -439,17 +422,14 @@ static inline unsigned int CDT2DT(unsigned char cdt)  }  /* support routines */ -static int coda_venus_readdir(struct file *coda_file, void *buf, -			      filldir_t filldir) +static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx)  { -	int result = 0; /* # of entries returned */  	struct coda_file_info *cfi;  	struct coda_inode_info *cii;  	struct file *host_file;  	struct dentry *de;  	struct venus_dirent *vdir; -	unsigned long vdir_size = -	    (unsigned long)(&((struct venus_dirent *)0)->d_name); +	unsigned long vdir_size = offsetof(struct venus_dirent, d_name);  	unsigned int type;  	struct qstr name;  	ino_t ino; @@ -465,42 +445,31 @@ static int coda_venus_readdir(struct file *coda_file, void *buf,  	vdir = kmalloc(sizeof(*vdir), GFP_KERNEL);  	if (!vdir) return -ENOMEM; -	if (coda_file->f_pos == 0) { -		ret = filldir(buf, ".", 1, 0, de->d_inode->i_ino, DT_DIR); -		if (ret < 0) -			goto out; -		result++; -		coda_file->f_pos++; -	} -	if (coda_file->f_pos == 1) { -		ret = filldir(buf, "..", 2, 1, de->d_parent->d_inode->i_ino, DT_DIR); -		if (ret < 0) -			goto out; -		result++; -		coda_file->f_pos++; -	} +	if (!dir_emit_dots(coda_file, ctx)) +		goto out; +  	while (1) {  		/* read entries from the directory file */ -		ret = kernel_read(host_file, coda_file->f_pos - 2, (char *)vdir, +		ret = kernel_read(host_file, ctx->pos - 2, (char *)vdir,  				  sizeof(*vdir));  		if (ret < 0) { -			printk(KERN_ERR "coda readdir: read dir %s failed %d\n", -			       coda_f2s(&cii->c_fid), ret); +			pr_err("%s: read dir %s failed %d\n", +			       __func__, coda_f2s(&cii->c_fid), ret);  			break;  		}  		if (ret == 0) break; /* end of directory file reached */  		/* catch truncated reads */  		if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) { -			printk(KERN_ERR "coda readdir: short read on %s\n", -			       coda_f2s(&cii->c_fid)); +			pr_err("%s: short read on %s\n", +			       __func__, coda_f2s(&cii->c_fid));  			ret = -EBADF;  			break;  		}  		/* validate whether the directory file actually makes sense */  		if (vdir->d_reclen < vdir_size + vdir->d_namlen) { -			printk(KERN_ERR "coda readdir: invalid dir %s\n", -			       coda_f2s(&cii->c_fid)); +			pr_err("%s: invalid dir %s\n", +			       __func__, coda_f2s(&cii->c_fid));  			ret = -EBADF;  			break;  		} @@ -510,40 +479,35 @@ static int coda_venus_readdir(struct file *coda_file, void *buf,  		/* Make sure we skip '.' and '..', we already got those */  		if (name.name[0] == '.' && (name.len == 1 || -		    (vdir->d_name[1] == '.' && name.len == 2))) +		    (name.name[1] == '.' && name.len == 2)))  			vdir->d_fileno = name.len = 0;  		/* skip null entries */  		if (vdir->d_fileno && name.len) { -			/* try to look up this entry in the dcache, that way -			 * userspace doesn't have to worry about breaking -			 * getcwd by having mismatched inode numbers for -			 * internal volume mountpoints. */ -			ino = find_inode_number(de, &name); -			if (!ino) ino = vdir->d_fileno; - +			ino = vdir->d_fileno;  			type = CDT2DT(vdir->d_type); -			ret = filldir(buf, name.name, name.len, -				      coda_file->f_pos, ino, type); -			/* failure means no space for filling in this round */ -			if (ret < 0) break; -			result++; +			if (!dir_emit(ctx, name.name, name.len, ino, type)) +				break;  		}  		/* we'll always have progress because d_reclen is unsigned and  		 * we've already established it is non-zero. */ -		coda_file->f_pos += vdir->d_reclen; +		ctx->pos += vdir->d_reclen;  	}  out:  	kfree(vdir); -	return result ? result : ret; +	return 0;  }  /* called when a cache lookup succeeds */ -static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd) +static int coda_dentry_revalidate(struct dentry *de, unsigned int flags)  { -	struct inode *inode = de->d_inode; +	struct inode *inode;  	struct coda_inode_info *cii; +	if (flags & LOOKUP_RCU) +		return -ECHILD; + +	inode = de->d_inode;  	if (!inode || coda_isroot(inode))  		goto out;  	if (is_bad_inode(inode)) @@ -559,7 +523,7 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)  	if (cii->c_flags & C_FLUSH)   		coda_flag_inode_children(inode, C_FLUSH); -	if (atomic_read(&de->d_count) > 1) +	if (d_count(de) > 1)  		/* pretend it's valid, but don't change the flags */  		goto out; @@ -577,7 +541,7 @@ out:   * This is the callback from dput() when d_count is going to 0.   * We use this to unhash dentries with bad inodes.   */ -static int coda_dentry_delete(struct dentry * dentry) +static int coda_dentry_delete(const struct dentry * dentry)  {  	int flags; @@ -599,13 +563,12 @@ static int coda_dentry_delete(struct dentry * dentry)   * cache manager Venus issues a downcall to the kernel when this    * happens    */ -int coda_revalidate_inode(struct dentry *dentry) +int coda_revalidate_inode(struct inode *inode)  {  	struct coda_vattr attr;  	int error;  	int old_mode;  	ino_t old_ino; -	struct inode *inode = dentry->d_inode;  	struct coda_inode_info *cii = ITOC(inode);  	if (!cii->c_flags) @@ -626,8 +589,8 @@ int coda_revalidate_inode(struct dentry *dentry)  		coda_vattr_to_iattr(inode, &attr);  		if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) { -			printk("Coda: inode %ld, fid %s changed type!\n", -			       inode->i_ino, coda_f2s(&(cii->c_fid))); +			pr_warn("inode %ld, fid %s changed type!\n", +				inode->i_ino, coda_f2s(&(cii->c_fid)));  		}  		/* the following can happen when a local fid is replaced  diff --git a/fs/coda/file.c b/fs/coda/file.c index c8b50ba4366..9e83b779021 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c @@ -21,10 +21,9 @@  #include <asm/uaccess.h>  #include <linux/coda.h> -#include <linux/coda_linux.h> -#include <linux/coda_fs_i.h>  #include <linux/coda_psdev.h> +#include "coda_linux.h"  #include "coda_int.h"  static ssize_t @@ -37,7 +36,7 @@ coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *p  	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);  	host_file = cfi->cfi_container; -	if (!host_file->f_op || !host_file->f_op->read) +	if (!host_file->f_op->read)  		return -EINVAL;  	return host_file->f_op->read(host_file, buf, count, ppos); @@ -67,7 +66,7 @@ coda_file_splice_read(struct file *coda_file, loff_t *ppos,  static ssize_t  coda_file_write(struct file *coda_file, const char __user *buf, size_t count, loff_t *ppos)  { -	struct inode *host_inode, *coda_inode = coda_file->f_path.dentry->d_inode; +	struct inode *host_inode, *coda_inode = file_inode(coda_file);  	struct coda_file_info *cfi;  	struct file *host_file;  	ssize_t ret; @@ -76,10 +75,11 @@ coda_file_write(struct file *coda_file, const char __user *buf, size_t count, lo  	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);  	host_file = cfi->cfi_container; -	if (!host_file->f_op || !host_file->f_op->write) +	if (!host_file->f_op->write)  		return -EINVAL; -	host_inode = host_file->f_path.dentry->d_inode; +	host_inode = file_inode(host_file); +	file_start_write(host_file);  	mutex_lock(&coda_inode->i_mutex);  	ret = host_file->f_op->write(host_file, buf, count, ppos); @@ -88,6 +88,7 @@ coda_file_write(struct file *coda_file, const char __user *buf, size_t count, lo  	coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;  	coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC;  	mutex_unlock(&coda_inode->i_mutex); +	file_end_write(host_file);  	return ret;  } @@ -104,11 +105,11 @@ coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma)  	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);  	host_file = cfi->cfi_container; -	if (!host_file->f_op || !host_file->f_op->mmap) +	if (!host_file->f_op->mmap)  		return -ENODEV; -	coda_inode = coda_file->f_path.dentry->d_inode; -	host_inode = host_file->f_path.dentry->d_inode; +	coda_inode = file_inode(coda_file); +	host_inode = file_inode(host_file);  	cii = ITOC(coda_inode);  	spin_lock(&cii->c_lock); @@ -179,7 +180,7 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)  	err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode),  			  coda_flags, coda_file->f_cred->fsuid); -	host_inode = cfi->cfi_container->f_path.dentry->d_inode; +	host_inode = file_inode(cfi->cfi_container);  	cii = ITOC(coda_inode);  	/* did we mmap this file? */ @@ -200,10 +201,10 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)  	return 0;  } -int coda_fsync(struct file *coda_file, int datasync) +int coda_fsync(struct file *coda_file, loff_t start, loff_t end, int datasync)  {  	struct file *host_file; -	struct inode *coda_inode = coda_file->f_path.dentry->d_inode; +	struct inode *coda_inode = file_inode(coda_file);  	struct coda_file_info *cfi;  	int err; @@ -211,6 +212,11 @@ int coda_fsync(struct file *coda_file, int datasync)  	      S_ISLNK(coda_inode->i_mode)))  		return -EINVAL; +	err = filemap_write_and_wait_range(coda_inode->i_mapping, start, end); +	if (err) +		return err; +	mutex_lock(&coda_inode->i_mutex); +  	cfi = CODA_FTOC(coda_file);  	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);  	host_file = cfi->cfi_container; @@ -218,6 +224,7 @@ int coda_fsync(struct file *coda_file, int datasync)  	err = vfs_fsync(host_file, datasync);  	if (!err && !datasync)  		err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode)); +	mutex_unlock(&coda_inode->i_mutex);  	return err;  } diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 5ea57c8c7f9..fe3afb2de88 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -20,18 +20,17 @@  #include <linux/file.h>  #include <linux/vfs.h>  #include <linux/slab.h> +#include <linux/pid_namespace.h> -#include <asm/system.h>  #include <asm/uaccess.h>  #include <linux/fs.h>  #include <linux/vmalloc.h>  #include <linux/coda.h> -#include <linux/coda_linux.h>  #include <linux/coda_psdev.h> -#include <linux/coda_fs_i.h> -#include <linux/coda_cache.h> +#include "coda_linux.h" +#include "coda_cache.h"  #include "coda_int.h" @@ -45,22 +44,28 @@ static struct kmem_cache * coda_inode_cachep;  static struct inode *coda_alloc_inode(struct super_block *sb)  {  	struct coda_inode_info *ei; -	ei = (struct coda_inode_info *)kmem_cache_alloc(coda_inode_cachep, GFP_KERNEL); +	ei = kmem_cache_alloc(coda_inode_cachep, GFP_KERNEL);  	if (!ei)  		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;  } -static void coda_destroy_inode(struct inode *inode) +static void coda_i_callback(struct rcu_head *head)  { +	struct inode *inode = container_of(head, struct inode, i_rcu);  	kmem_cache_free(coda_inode_cachep, ITOC(inode));  } +static void coda_destroy_inode(struct inode *inode) +{ +	call_rcu(&inode->i_rcu, coda_i_callback); +} +  static void init_once(void *foo)  {  	struct coda_inode_info *ei = (struct coda_inode_info *) foo; @@ -68,7 +73,7 @@ static void init_once(void *foo)  	inode_init_once(&ei->vfs_inode);  } -int coda_init_inodecache(void) +int __init coda_init_inodecache(void)  {  	coda_inode_cachep = kmem_cache_create("coda_inode_cache",  				sizeof(struct coda_inode_info), @@ -81,11 +86,17 @@ 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);  }  static int coda_remount(struct super_block *sb, int *flags, char *data)  { +	sync_filesystem(sb);  	*flags |= MS_NOATIME;  	return 0;  } @@ -103,43 +114,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) { -		printk("coda_read_super: Bad mount data\n"); +	if (data == NULL) { +		pr_warn("%s: Bad mount data\n", __func__);  		return -1;  	} -	if(data->version != CODA_MOUNT_VERSION) { -		printk("coda_read_super: Bad mount version\n"); +	if (data->version != CODA_MOUNT_VERSION) { +		pr_warn("%s: Bad mount version\n", __func__);  		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) { -		printk("coda_read_super: Bad minor number\n"); +	if (idx < 0 || idx >= MAX_CODADEVS) { +		pr_warn("%s: Bad minor number\n", __func__);  		return -1;  	}  	return idx; +Ebadf: +	pr_warn("%s: Bad file\n", __func__); +	return -1;  }  static int coda_fill_super(struct super_block *sb, void *data, int silent) @@ -150,25 +159,28 @@ 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 */  	if(idx == -1)  		idx = 0; -	printk(KERN_INFO "coda_read_super: device index: %i\n", idx); +	pr_info("%s: device index: %i\n", __func__,  idx);  	vc = &coda_comms[idx];  	mutex_lock(&vc->vc_mutex);  	if (!vc->vc_inuse) { -		printk("coda_read_super: No pseudo device\n"); +		pr_warn("%s: No pseudo device\n", __func__);  		error = -EINVAL;  		goto unlock_out;  	}  	if (vc->vc_sb) { -		printk("coda_read_super: Device already mounted\n"); +		pr_warn("%s: Device already mounted\n", __func__);  		error = -EBUSY;  		goto unlock_out;  	} @@ -186,27 +198,30 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)  	sb->s_blocksize_bits = 12;  	sb->s_magic = CODA_SUPER_MAGIC;  	sb->s_op = &coda_super_operations; +	sb->s_d_op = &coda_dentry_operations;  	sb->s_bdi = &vc->bdi;  	/* get root fid from Venus: this needs the root inode */  	error = venus_rootfid(sb, &fid);  	if ( error ) { -	        printk("coda_read_super: coda_get_rootfid failed with %d\n", -		       error); +		pr_warn("%s: coda_get_rootfid failed with %d\n", +			__func__, error);  		goto error;  	} -	printk("coda_read_super: rootfid is %s\n", coda_f2s(&fid)); +	pr_info("%s: rootfid is %s\n", __func__, coda_f2s(&fid));  	/* make root inode */ -        error = coda_cnode_make(&root, &fid, sb); -        if ( error || !root ) { -	    printk("Failure of coda_cnode_make for root: error %d\n", error); -	    goto error; +        root = coda_cnode_make(&fid, sb); +        if (IS_ERR(root)) { +		error = PTR_ERR(root); +		pr_warn("Failure of coda_cnode_make for root: error %d\n", +			error); +		goto error;  	}  -	printk("coda_read_super: rootinode is %ld dev %s\n",  -	       root->i_ino, root->i_sb->s_id); -	sb->s_root = d_alloc_root(root); +	pr_info("%s: rootinode is %ld dev %s\n", +		__func__, root->i_ino, root->i_sb->s_id); +	sb->s_root = d_make_root(root);  	if (!sb->s_root) {  		error = -EINVAL;  		goto error; @@ -214,9 +229,6 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)  	return 0;  error: -	if (root) -		iput(root); -  	mutex_lock(&vc->vc_mutex);  	bdi_destroy(&vc->bdi);  	vc->vc_sb = NULL; @@ -235,19 +247,19 @@ static void coda_put_super(struct super_block *sb)  	sb->s_fs_info = NULL;  	mutex_unlock(&vcp->vc_mutex); -	printk("Coda: Bye bye.\n"); +	pr_info("Bye bye.\n");  }  static void coda_evict_inode(struct inode *inode)  { -	truncate_inode_pages(&inode->i_data, 0); -	end_writeback(inode); +	truncate_inode_pages_final(&inode->i_data); +	clear_inode(inode);  	coda_cache_clear_inode(inode);  }  int coda_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)  { -	int err = coda_revalidate_inode(dentry); +	int err = coda_revalidate_inode(dentry->d_inode);  	if (!err)  		generic_fillattr(dentry->d_inode, stat);  	return err; @@ -319,4 +331,5 @@ struct file_system_type coda_fs_type = {  	.kill_sb	= kill_anon_super,  	.fs_flags	= FS_BINARY_MOUNTDATA,  }; +MODULE_ALIAS_FS("coda"); diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c index 2fd89b5c5c7..3f5de96bbb5 100644 --- a/fs/coda/pioctl.c +++ b/fs/coda/pioctl.c @@ -19,10 +19,10 @@  #include <asm/uaccess.h>  #include <linux/coda.h> -#include <linux/coda_linux.h> -#include <linux/coda_fs_i.h>  #include <linux/coda_psdev.h> +#include "coda_linux.h" +  /* pioctl ops */  static int coda_ioctl_permission(struct inode *inode, int mask);  static long coda_pioctl(struct file *filp, unsigned int cmd, @@ -52,7 +52,7 @@ static long coda_pioctl(struct file *filp, unsigned int cmd,  	struct path path;  	int error;  	struct PioctlData data; -	struct inode *inode = filp->f_dentry->d_inode; +	struct inode *inode = file_inode(filp);  	struct inode *target_inode = NULL;  	struct coda_inode_info *cnp; diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 62647a8595e..5c1e4242368 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c @@ -37,16 +37,16 @@  #include <linux/list.h>  #include <linux/mutex.h>  #include <linux/device.h> +#include <linux/pid_namespace.h>  #include <asm/io.h> -#include <asm/system.h>  #include <asm/poll.h>  #include <asm/uaccess.h>  #include <linux/coda.h> -#include <linux/coda_linux.h> -#include <linux/coda_fs_i.h>  #include <linux/coda_psdev.h> +#include "coda_linux.h" +  #include "coda_int.h"  /* statistics */ @@ -114,14 +114,14 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,  		int size = sizeof(*dcbuf);  		if  ( nbytes < sizeof(struct coda_out_hdr) ) { -		        printk("coda_downcall opc %d uniq %d, not enough!\n", -			       hdr.opcode, hdr.unique); +			pr_warn("coda_downcall opc %d uniq %d, not enough!\n", +				hdr.opcode, hdr.unique);  			count = nbytes;  			goto out;  		}  		if ( nbytes > size ) { -		        printk("Coda: downcall opc %d, uniq %d, too much!", -			       hdr.opcode, hdr.unique); +			pr_warn("downcall opc %d, uniq %d, too much!", +				hdr.opcode, hdr.unique);  		        nbytes = size;  		}  		CODA_ALLOC(dcbuf, union outputArgs *, nbytes); @@ -136,7 +136,8 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,  		CODA_FREE(dcbuf, nbytes);  		if (error) { -		        printk("psdev_write: coda_downcall error: %d\n", error); +			pr_warn("%s: coda_downcall error: %d\n", +				__func__, error);  			retval = error;  			goto out;  		} @@ -157,16 +158,17 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,  	mutex_unlock(&vcp->vc_mutex);  	if (!req) { -		printk("psdev_write: msg (%d, %d) not found\n",  -			hdr.opcode, hdr.unique); +		pr_warn("%s: msg (%d, %d) not found\n", +			__func__, hdr.opcode, hdr.unique);  		retval = -ESRCH;  		goto out;  	}          /* move data into response buffer. */  	if (req->uc_outSize < nbytes) { -                printk("psdev_write: too much cnt: %d, cnt: %ld, opc: %d, uniq: %d.\n", -		       req->uc_outSize, (long)nbytes, hdr.opcode, hdr.unique); +		pr_warn("%s: too much cnt: %d, cnt: %ld, opc: %d, uniq: %d.\n", +			__func__, req->uc_outSize, (long)nbytes, +			hdr.opcode, hdr.unique);  		nbytes = req->uc_outSize; /* don't have more space! */  	}          if (copy_from_user(req->uc_data, buf, nbytes)) { @@ -240,8 +242,8 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf,  	/* Move the input args into userspace */  	count = req->uc_inSize;  	if (nbytes < req->uc_inSize) { -                printk ("psdev_read: Venus read %ld bytes of %d in message\n", -			(long)nbytes, req->uc_inSize); +		pr_warn("%s: Venus read %ld bytes of %d in message\n", +			__func__, (long)nbytes, req->uc_inSize);  		count = nbytes;          } @@ -267,6 +269,12 @@ static int coda_psdev_open(struct inode * inode, struct file * file)  	struct venus_comm *vcp;  	int idx, err; +	if (task_active_pid_ns(current) != &init_pid_ns) +		return -EINVAL; + +	if (current_user_ns() != &init_user_ns) +		return -EINVAL; +  	idx = iminor(inode);  	if (idx < 0 || idx >= MAX_CODADEVS)  		return -ENODEV; @@ -299,7 +307,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file)  	struct upc_req *req, *tmp;  	if (!vcp || !vcp->vc_inuse ) { -		printk("psdev_release: Not open.\n"); +		pr_warn("%s: Not open.\n", __func__);  		return -1;  	} @@ -348,8 +356,8 @@ static int init_coda_psdev(void)  {  	int i, err = 0;  	if (register_chrdev(CODA_PSDEV_MAJOR, "coda", &coda_psdev_fops)) { -              printk(KERN_ERR "coda_psdev: unable to get major %d\n",  -		     CODA_PSDEV_MAJOR); +		pr_err("%s: unable to get major %d\n", +		       __func__, CODA_PSDEV_MAJOR);                return -EIO;  	}  	coda_psdev_class = class_create(THIS_MODULE, "coda"); @@ -387,13 +395,13 @@ static int __init init_coda(void)  		goto out2;  	status = init_coda_psdev();  	if ( status ) { -		printk("Problem (%d) in init_coda_psdev\n", status); +		pr_warn("Problem (%d) in init_coda_psdev\n", status);  		goto out1;  	}  	status = register_filesystem(&coda_fs_type);  	if (status) { -		printk("coda: failed to register filesystem!\n"); +		pr_warn("failed to register filesystem!\n");  		goto out;  	}  	return 0; @@ -414,9 +422,8 @@ static void __exit exit_coda(void)          int err, i;  	err = unregister_filesystem(&coda_fs_type); -        if ( err != 0 ) { -                printk("coda: failed to unregister filesystem\n"); -        } +	if (err != 0) +		pr_warn("failed to unregister filesystem\n");  	for (i = 0; i < MAX_CODADEVS; i++)  		device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));  	class_destroy(coda_psdev_class); diff --git a/fs/coda/symlink.c b/fs/coda/symlink.c index af78f007a2b..ab94ef63cae 100644 --- a/fs/coda/symlink.c +++ b/fs/coda/symlink.c @@ -16,9 +16,9 @@  #include <linux/pagemap.h>  #include <linux/coda.h> -#include <linux/coda_linux.h>  #include <linux/coda_psdev.h> -#include <linux/coda_fs_i.h> + +#include "coda_linux.h"  static int coda_symlink_filler(struct file *file, struct page *page)  { diff --git a/fs/coda/sysctl.c b/fs/coda/sysctl.c index c6405ce3c50..34218a8a28c 100644 --- a/fs/coda/sysctl.c +++ b/fs/coda/sysctl.c @@ -13,9 +13,8 @@  #ifdef CONFIG_SYSCTL  static struct ctl_table_header *fs_table_header; -#endif -static ctl_table coda_table[] = { +static struct ctl_table coda_table[] = {  	{  		.procname	= "timeout",  		.data		= &coda_timeout, @@ -40,8 +39,7 @@ static ctl_table coda_table[] = {  	{}  }; -#ifdef CONFIG_SYSCTL -static ctl_table fs_table[] = { +static struct ctl_table fs_table[] = {  	{  		.procname	= "coda",  		.mode		= 0555, @@ -49,22 +47,27 @@ static ctl_table fs_table[] = {  	},  	{}  }; -#endif  void coda_sysctl_init(void)  { -#ifdef CONFIG_SYSCTL  	if ( !fs_table_header )  		fs_table_header = register_sysctl_table(fs_table); -#endif  }  void coda_sysctl_clean(void)  { -#ifdef CONFIG_SYSCTL  	if ( fs_table_header ) {  		unregister_sysctl_table(fs_table_header);  		fs_table_header = NULL;  	} -#endif  } + +#else +void coda_sysctl_init(void) +{ +} + +void coda_sysctl_clean(void) +{ +} +#endif diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index c3563cab975..21fcf8dcb9c 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c @@ -14,7 +14,6 @@   * improvements to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.   */ -#include <asm/system.h>  #include <linux/signal.h>  #include <linux/sched.h>  #include <linux/types.h> @@ -33,10 +32,9 @@  #include <linux/vfs.h>  #include <linux/coda.h> -#include <linux/coda_linux.h>  #include <linux/coda_psdev.h> -#include <linux/coda_fs_i.h> -#include <linux/coda_cache.h> +#include "coda_linux.h" +#include "coda_cache.h"  #include "coda_int.h" @@ -52,9 +50,9 @@ static void *alloc_upcall(int opcode, int size)  		return ERR_PTR(-ENOMEM);          inp->ih.opcode = opcode; -	inp->ih.pid = current->pid; -	inp->ih.pgid = task_pgrp_nr(current); -	inp->ih.uid = current_fsuid(); +	inp->ih.pid = task_pid_nr_ns(current, &init_pid_ns); +	inp->ih.pgid = task_pgrp_nr_ns(current, &init_pid_ns); +	inp->ih.uid = from_kuid(&init_user_ns, current_fsuid());  	return (void*)inp;  } @@ -159,7 +157,7 @@ int venus_lookup(struct super_block *sb, struct CodaFid *fid,  }  int venus_close(struct super_block *sb, struct CodaFid *fid, int flags, -		vuid_t uid) +		kuid_t uid)  {  	union inputArgs *inp;  	union outputArgs *outp; @@ -168,7 +166,7 @@ int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,  	insize = SIZE(release);  	UPARG(CODA_CLOSE); -	inp->ih.uid = uid; +	inp->ih.uid = from_kuid(&init_user_ns, uid);          inp->coda_close.VFid = *fid;          inp->coda_close.flags = flags; @@ -510,8 +508,8 @@ int venus_pioctl(struct super_block *sb, struct CodaFid *fid,          inp->coda_ioctl.data = (char *)(INSIZE(ioctl));          /* get the data out of user space */ -        if ( copy_from_user((char*)inp + (long)inp->coda_ioctl.data, -			    data->vi.in, data->vi.in_size) ) { +	if (copy_from_user((char *)inp + (long)inp->coda_ioctl.data, +			   data->vi.in, data->vi.in_size)) {  		error = -EINVAL;  	        goto exit;  	} @@ -520,8 +518,8 @@ int venus_pioctl(struct super_block *sb, struct CodaFid *fid,  			    &outsize, inp);          if (error) { -	        printk("coda_pioctl: Venus returns: %d for %s\n",  -		       error, coda_f2s(fid)); +		pr_warn("%s: Venus returns: %d for %s\n", +			__func__, error, coda_f2s(fid));  		goto exit;   	} @@ -677,7 +675,7 @@ static int coda_upcall(struct venus_comm *vcp,  	mutex_lock(&vcp->vc_mutex);  	if (!vcp->vc_inuse) { -		printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n"); +		pr_notice("Venus dead, not sending upcall\n");  		error = -ENXIO;  		goto exit;  	} @@ -727,7 +725,7 @@ static int coda_upcall(struct venus_comm *vcp,  	error = -EINTR;  	if ((req->uc_flags & CODA_REQ_ABORT) || !signal_pending(current)) { -		printk(KERN_WARNING "coda: Unexpected interruption.\n"); +		pr_warn("Unexpected interruption.\n");  		goto exit;  	} @@ -737,7 +735,7 @@ static int coda_upcall(struct venus_comm *vcp,  	/* Venus saw the upcall, make sure we can send interrupt signal */  	if (!vcp->vc_inuse) { -		printk(KERN_INFO "coda: Venus dead, not sending signal.\n"); +		pr_info("Venus dead, not sending signal.\n");  		goto exit;  	}  | 
