diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-10 13:58:28 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-10 13:58:28 -0700 | 
| commit | 7233e392760b3493095d3d5885cb15e44493d74a (patch) | |
| tree | e2095425fe34c635ee2cf77f9ef6022f7cddfbb1 /fs/autofs/root.c | |
| parent | 4c619407b0439c59c20398b9459020c0d297f424 (diff) | |
| parent | 5ef06839f50c7e5e479d3595257131edf1f84f36 (diff) | |
Merge branch 'bkl/ioctl' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing
* 'bkl/ioctl' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing:
  staging: Pushdown bkl to easycap ioctl handlers
  autofs/autofs4: Move compat_ioctl handling into fs
  v4l: Convert v4l2-dev to unlocked_ioctl
  ia64/perfmon: Convert to unlocked_ioctl
  sunrpc: Remove duplicated #include
  ncpfs: Remove duplicated #include
Diffstat (limited to 'fs/autofs/root.c')
| -rw-r--r-- | fs/autofs/root.c | 67 | 
1 files changed, 64 insertions, 3 deletions
| diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 9a0520b5066..11b1ea786d0 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c @@ -16,6 +16,7 @@  #include <linux/slab.h>  #include <linux/param.h>  #include <linux/time.h> +#include <linux/compat.h>  #include <linux/smp_lock.h>  #include "autofs_i.h" @@ -25,13 +26,17 @@ static int autofs_root_symlink(struct inode *,struct dentry *,const char *);  static int autofs_root_unlink(struct inode *,struct dentry *);  static int autofs_root_rmdir(struct inode *,struct dentry *);  static int autofs_root_mkdir(struct inode *,struct dentry *,int); -static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long); +static long autofs_root_ioctl(struct file *,unsigned int,unsigned long); +static long autofs_root_compat_ioctl(struct file *,unsigned int,unsigned long);  const struct file_operations autofs_root_operations = {  	.llseek		= generic_file_llseek,  	.read		= generic_read_dir,  	.readdir	= autofs_root_readdir, -	.ioctl		= autofs_root_ioctl, +	.unlocked_ioctl	= autofs_root_ioctl, +#ifdef CONFIG_COMPAT +	.compat_ioctl	= autofs_root_compat_ioctl, +#endif  };  const struct inode_operations autofs_root_inode_operations = { @@ -492,6 +497,25 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)  }  /* Get/set timeout ioctl() operation */ +#ifdef CONFIG_COMPAT +static inline int autofs_compat_get_set_timeout(struct autofs_sb_info *sbi, +					 unsigned int __user *p) +{ +	unsigned long ntimeout; + +	if (get_user(ntimeout, p) || +	    put_user(sbi->exp_timeout / HZ, p)) +		return -EFAULT; + +	if (ntimeout > UINT_MAX/HZ) +		sbi->exp_timeout = 0; +	else +		sbi->exp_timeout = ntimeout * HZ; + +	return 0; +} +#endif +  static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi,  					 unsigned long __user *p)  { @@ -546,7 +570,7 @@ static inline int autofs_expire_run(struct super_block *sb,   * ioctl()'s on the root directory is the chief method for the daemon to   * generate kernel reactions   */ -static int autofs_root_ioctl(struct inode *inode, struct file *filp, +static int autofs_do_root_ioctl(struct inode *inode, struct file *filp,  			     unsigned int cmd, unsigned long arg)  {  	struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb); @@ -571,6 +595,10 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp,  		return 0;  	case AUTOFS_IOC_PROTOVER: /* Get protocol version */  		return autofs_get_protover(argp); +#ifdef CONFIG_COMPAT +	case AUTOFS_IOC_SETTIMEOUT32: +		return autofs_compat_get_set_timeout(sbi, argp); +#endif  	case AUTOFS_IOC_SETTIMEOUT:  		return autofs_get_set_timeout(sbi, argp);  	case AUTOFS_IOC_EXPIRE: @@ -579,4 +607,37 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp,  	default:  		return -ENOSYS;  	} + +} + +static long autofs_root_ioctl(struct file *filp, +			     unsigned int cmd, unsigned long arg) +{ +	int ret; + +	lock_kernel(); +	ret = autofs_do_root_ioctl(filp->f_path.dentry->d_inode, +				   filp, cmd, arg); +	unlock_kernel(); + +	return ret; +} + +#ifdef CONFIG_COMPAT +static long autofs_root_compat_ioctl(struct file *filp, +			     unsigned int cmd, unsigned long arg) +{ +	struct inode *inode = filp->f_path.dentry->d_inode; +	int ret; + +	lock_kernel(); +	if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL) +		ret = autofs_do_root_ioctl(inode, filp, cmd, arg); +	else +		ret = autofs_do_root_ioctl(inode, filp, cmd, +			(unsigned long)compat_ptr(arg)); +	unlock_kernel(); + +	return ret;  } +#endif | 
