Commit c9243f5bdd6637b2bb7dc254b54d9edf957ef17e
Committed by
Frederic Weisbecker
1 parent
86a5ef7d77
Exists in
master
and in
39 other branches
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
fs/autofs/root.c
... | ... | @@ -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 |
fs/autofs4/root.c
... | ... | @@ -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 |
fs/compat_ioctl.c
... | ... | @@ -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 |