Commit c9243f5bdd6637b2bb7dc254b54d9edf957ef17e

Authored by Arnd Bergmann
Committed by Frederic Weisbecker
1 parent 86a5ef7d77

autofs/autofs4: Move compat_ioctl handling into fs

Handling of autofs ioctl numbers does not need to be generic
and can easily be done directly in autofs itself.

This also pushes the BKL into autofs and autofs4 ioctl
methods.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Ian Kent <raven@themaw.net>
Cc: Autofs <autofs@linux.kernel.org>
Cc: John Kacur <jkacur@redhat.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>

Showing 4 changed files with 114 additions and 39 deletions Side-by-side Diff

... ... @@ -16,6 +16,7 @@
16 16 #include <linux/slab.h>
17 17 #include <linux/param.h>
18 18 #include <linux/time.h>
  19 +#include <linux/compat.h>
19 20 #include <linux/smp_lock.h>
20 21 #include "autofs_i.h"
21 22  
22 23  
... ... @@ -25,13 +26,17 @@
25 26 static int autofs_root_unlink(struct inode *,struct dentry *);
26 27 static int autofs_root_rmdir(struct inode *,struct dentry *);
27 28 static int autofs_root_mkdir(struct inode *,struct dentry *,int);
28   -static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long);
  29 +static long autofs_root_ioctl(struct file *,unsigned int,unsigned long);
  30 +static long autofs_root_compat_ioctl(struct file *,unsigned int,unsigned long);
29 31  
30 32 const struct file_operations autofs_root_operations = {
31 33 .llseek = generic_file_llseek,
32 34 .read = generic_read_dir,
33 35 .readdir = autofs_root_readdir,
34   - .ioctl = autofs_root_ioctl,
  36 + .unlocked_ioctl = autofs_root_ioctl,
  37 +#ifdef CONFIG_COMPAT
  38 + .compat_ioctl = autofs_root_compat_ioctl,
  39 +#endif
35 40 };
36 41  
37 42 const struct inode_operations autofs_root_inode_operations = {
... ... @@ -492,6 +497,25 @@
492 497 }
493 498  
494 499 /* Get/set timeout ioctl() operation */
  500 +#ifdef CONFIG_COMPAT
  501 +static inline int autofs_compat_get_set_timeout(struct autofs_sb_info *sbi,
  502 + unsigned int __user *p)
  503 +{
  504 + unsigned long ntimeout;
  505 +
  506 + if (get_user(ntimeout, p) ||
  507 + put_user(sbi->exp_timeout / HZ, p))
  508 + return -EFAULT;
  509 +
  510 + if (ntimeout > UINT_MAX/HZ)
  511 + sbi->exp_timeout = 0;
  512 + else
  513 + sbi->exp_timeout = ntimeout * HZ;
  514 +
  515 + return 0;
  516 +}
  517 +#endif
  518 +
495 519 static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi,
496 520 unsigned long __user *p)
497 521 {
... ... @@ -546,7 +570,7 @@
546 570 * ioctl()'s on the root directory is the chief method for the daemon to
547 571 * generate kernel reactions
548 572 */
549   -static int autofs_root_ioctl(struct inode *inode, struct file *filp,
  573 +static int autofs_do_root_ioctl(struct inode *inode, struct file *filp,
550 574 unsigned int cmd, unsigned long arg)
551 575 {
552 576 struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
... ... @@ -571,6 +595,10 @@
571 595 return 0;
572 596 case AUTOFS_IOC_PROTOVER: /* Get protocol version */
573 597 return autofs_get_protover(argp);
  598 +#ifdef CONFIG_COMPAT
  599 + case AUTOFS_IOC_SETTIMEOUT32:
  600 + return autofs_compat_get_set_timeout(sbi, argp);
  601 +#endif
574 602 case AUTOFS_IOC_SETTIMEOUT:
575 603 return autofs_get_set_timeout(sbi, argp);
576 604 case AUTOFS_IOC_EXPIRE:
577 605  
... ... @@ -579,5 +607,38 @@
579 607 default:
580 608 return -ENOSYS;
581 609 }
  610 +
582 611 }
  612 +
  613 +static long autofs_root_ioctl(struct file *filp,
  614 + unsigned int cmd, unsigned long arg)
  615 +{
  616 + int ret;
  617 +
  618 + lock_kernel();
  619 + ret = autofs_do_root_ioctl(filp->f_path.dentry->d_inode,
  620 + filp, cmd, arg);
  621 + unlock_kernel();
  622 +
  623 + return ret;
  624 +}
  625 +
  626 +#ifdef CONFIG_COMPAT
  627 +static long autofs_root_compat_ioctl(struct file *filp,
  628 + unsigned int cmd, unsigned long arg)
  629 +{
  630 + struct inode *inode = filp->f_path.dentry->d_inode;
  631 + int ret;
  632 +
  633 + lock_kernel();
  634 + if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL)
  635 + ret = autofs_do_root_ioctl(inode, filp, cmd, arg);
  636 + else
  637 + ret = autofs_do_root_ioctl(inode, filp, cmd,
  638 + (unsigned long)compat_ptr(arg));
  639 + unlock_kernel();
  640 +
  641 + return ret;
  642 +}
  643 +#endif
... ... @@ -18,7 +18,9 @@
18 18 #include <linux/slab.h>
19 19 #include <linux/param.h>
20 20 #include <linux/time.h>
  21 +#include <linux/compat.h>
21 22 #include <linux/smp_lock.h>
  23 +
22 24 #include "autofs_i.h"
23 25  
24 26 static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *);
... ... @@ -26,6 +28,7 @@
26 28 static int autofs4_dir_rmdir(struct inode *,struct dentry *);
27 29 static int autofs4_dir_mkdir(struct inode *,struct dentry *,int);
28 30 static long autofs4_root_ioctl(struct file *,unsigned int,unsigned long);
  31 +static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long);
29 32 static int autofs4_dir_open(struct inode *inode, struct file *file);
30 33 static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *);
31 34 static void *autofs4_follow_link(struct dentry *, struct nameidata *);
... ... @@ -40,6 +43,9 @@
40 43 .readdir = dcache_readdir,
41 44 .llseek = dcache_dir_lseek,
42 45 .unlocked_ioctl = autofs4_root_ioctl,
  46 +#ifdef CONFIG_COMPAT
  47 + .compat_ioctl = autofs4_root_compat_ioctl,
  48 +#endif
43 49 };
44 50  
45 51 const struct file_operations autofs4_dir_operations = {
... ... @@ -840,6 +846,26 @@
840 846 }
841 847  
842 848 /* Get/set timeout ioctl() operation */
  849 +#ifdef CONFIG_COMPAT
  850 +static inline int autofs4_compat_get_set_timeout(struct autofs_sb_info *sbi,
  851 + compat_ulong_t __user *p)
  852 +{
  853 + int rv;
  854 + unsigned long ntimeout;
  855 +
  856 + if ((rv = get_user(ntimeout, p)) ||
  857 + (rv = put_user(sbi->exp_timeout/HZ, p)))
  858 + return rv;
  859 +
  860 + if (ntimeout > UINT_MAX/HZ)
  861 + sbi->exp_timeout = 0;
  862 + else
  863 + sbi->exp_timeout = ntimeout * HZ;
  864 +
  865 + return 0;
  866 +}
  867 +#endif
  868 +
843 869 static inline int autofs4_get_set_timeout(struct autofs_sb_info *sbi,
844 870 unsigned long __user *p)
845 871 {
... ... @@ -933,6 +959,10 @@
933 959 return autofs4_get_protosubver(sbi, p);
934 960 case AUTOFS_IOC_SETTIMEOUT:
935 961 return autofs4_get_set_timeout(sbi, p);
  962 +#ifdef CONFIG_COMPAT
  963 + case AUTOFS_IOC_SETTIMEOUT32:
  964 + return autofs4_compat_get_set_timeout(sbi, p);
  965 +#endif
936 966  
937 967 case AUTOFS_IOC_ASKUMOUNT:
938 968 return autofs4_ask_umount(filp->f_path.mnt, p);
... ... @@ -961,4 +991,23 @@
961 991  
962 992 return ret;
963 993 }
  994 +
  995 +#ifdef CONFIG_COMPAT
  996 +static long autofs4_root_compat_ioctl(struct file *filp,
  997 + unsigned int cmd, unsigned long arg)
  998 +{
  999 + struct inode *inode = filp->f_path.dentry->d_inode;
  1000 + int ret;
  1001 +
  1002 + lock_kernel();
  1003 + if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL)
  1004 + ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
  1005 + else
  1006 + ret = autofs4_root_ioctl_unlocked(inode, filp, cmd,
  1007 + (unsigned long)compat_ptr(arg));
  1008 + unlock_kernel();
  1009 +
  1010 + return ret;
  1011 +}
  1012 +#endif
... ... @@ -131,23 +131,6 @@
131 131 return err;
132 132 }
133 133  
134   -static int rw_long(unsigned int fd, unsigned int cmd,
135   - compat_ulong_t __user *argp)
136   -{
137   - mm_segment_t old_fs = get_fs();
138   - int err;
139   - unsigned long val;
140   -
141   - if(get_user(val, argp))
142   - return -EFAULT;
143   - set_fs (KERNEL_DS);
144   - err = sys_ioctl(fd, cmd, (unsigned long)&val);
145   - set_fs (old_fs);
146   - if (!err && put_user(val, argp))
147   - return -EFAULT;
148   - return err;
149   -}
150   -
151 134 struct compat_video_event {
152 135 int32_t type;
153 136 compat_time_t timestamp;
... ... @@ -594,12 +577,6 @@
594 577 return err;
595 578 }
596 579  
597   -static int ioc_settimeout(unsigned int fd, unsigned int cmd,
598   - compat_ulong_t __user *argp)
599   -{
600   - return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, argp);
601   -}
602   -
603 580 /* Bluetooth ioctls */
604 581 #define HCIUARTSETPROTO _IOW('U', 200, int)
605 582 #define HCIUARTGETPROTO _IOR('U', 201, int)
... ... @@ -1281,13 +1258,6 @@
1281 1258 COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS)
1282 1259 COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS)
1283 1260 COMPATIBLE_IOCTL(OSS_GETVERSION)
1284   -/* AUTOFS */
1285   -COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
1286   -COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
1287   -COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
1288   -COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI)
1289   -COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER)
1290   -COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT)
1291 1261 /* Raw devices */
1292 1262 COMPATIBLE_IOCTL(RAW_SETBIND)
1293 1263 COMPATIBLE_IOCTL(RAW_GETBIND)
... ... @@ -1552,9 +1522,6 @@
1552 1522 case RAW_GETBIND:
1553 1523 return raw_ioctl(fd, cmd, argp);
1554 1524 #endif
1555   -#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
1556   - case AUTOFS_IOC_SETTIMEOUT32:
1557   - return ioc_settimeout(fd, cmd, argp);
1558 1525 /* One SMB ioctl needs translations. */
1559 1526 #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
1560 1527 case SMB_IOC_GETMOUNTUID_32:
... ... @@ -1609,9 +1576,6 @@
1609 1576 case KDSKBMETA:
1610 1577 case KDSKBLED:
1611 1578 case KDSETLED:
1612   - /* AUTOFS */
1613   - case AUTOFS_IOC_READY:
1614   - case AUTOFS_IOC_FAIL:
1615 1579 /* NBD */
1616 1580 case NBD_SET_SOCK:
1617 1581 case NBD_SET_BLKSIZE:
include/linux/auto_fs.h
... ... @@ -79,6 +79,7 @@
79 79 #define AUTOFS_IOC_FAIL _IO(0x93,0x61)
80 80 #define AUTOFS_IOC_CATATONIC _IO(0x93,0x62)
81 81 #define AUTOFS_IOC_PROTOVER _IOR(0x93,0x63,int)
  82 +#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,compat_ulong_t)
82 83 #define AUTOFS_IOC_SETTIMEOUT _IOWR(0x93,0x64,unsigned long)
83 84 #define AUTOFS_IOC_EXPIRE _IOR(0x93,0x65,struct autofs_packet_expire)
84 85