diff options
author | Arnd Bergmann <arnd@arndb.de> | 2010-07-03 18:15:07 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2010-08-08 18:13:34 -0400 |
commit | c9243f5bdd6637b2bb7dc254b54d9edf957ef17e (patch) | |
tree | 254c0733f9d547651f467ed6502c7335804eaaf8 /fs | |
parent | 86a5ef7d777cdd61dfe82379d559dbea069aea3d (diff) |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/autofs/root.c | 67 | ||||
-rw-r--r-- | fs/autofs4/root.c | 49 | ||||
-rw-r--r-- | fs/compat_ioctl.c | 36 |
3 files changed, 113 insertions, 39 deletions
diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 9a0520b50663..11b1ea786d00 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/param.h> | 17 | #include <linux/param.h> |
18 | #include <linux/time.h> | 18 | #include <linux/time.h> |
19 | #include <linux/compat.h> | ||
19 | #include <linux/smp_lock.h> | 20 | #include <linux/smp_lock.h> |
20 | #include "autofs_i.h" | 21 | #include "autofs_i.h" |
21 | 22 | ||
@@ -25,13 +26,17 @@ static int autofs_root_symlink(struct inode *,struct dentry *,const char *); | |||
25 | static int autofs_root_unlink(struct inode *,struct dentry *); | 26 | static int autofs_root_unlink(struct inode *,struct dentry *); |
26 | static int autofs_root_rmdir(struct inode *,struct dentry *); | 27 | static int autofs_root_rmdir(struct inode *,struct dentry *); |
27 | static int autofs_root_mkdir(struct inode *,struct dentry *,int); | 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 | const struct file_operations autofs_root_operations = { | 32 | const struct file_operations autofs_root_operations = { |
31 | .llseek = generic_file_llseek, | 33 | .llseek = generic_file_llseek, |
32 | .read = generic_read_dir, | 34 | .read = generic_read_dir, |
33 | .readdir = autofs_root_readdir, | 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 | const struct inode_operations autofs_root_inode_operations = { | 42 | 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) | |||
492 | } | 497 | } |
493 | 498 | ||
494 | /* Get/set timeout ioctl() operation */ | 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 | static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi, | 519 | static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi, |
496 | unsigned long __user *p) | 520 | unsigned long __user *p) |
497 | { | 521 | { |
@@ -546,7 +570,7 @@ static inline int autofs_expire_run(struct super_block *sb, | |||
546 | * ioctl()'s on the root directory is the chief method for the daemon to | 570 | * ioctl()'s on the root directory is the chief method for the daemon to |
547 | * generate kernel reactions | 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 | unsigned int cmd, unsigned long arg) | 574 | unsigned int cmd, unsigned long arg) |
551 | { | 575 | { |
552 | struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb); | 576 | 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, | |||
571 | return 0; | 595 | return 0; |
572 | case AUTOFS_IOC_PROTOVER: /* Get protocol version */ | 596 | case AUTOFS_IOC_PROTOVER: /* Get protocol version */ |
573 | return autofs_get_protover(argp); | 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 | case AUTOFS_IOC_SETTIMEOUT: | 602 | case AUTOFS_IOC_SETTIMEOUT: |
575 | return autofs_get_set_timeout(sbi, argp); | 603 | return autofs_get_set_timeout(sbi, argp); |
576 | case AUTOFS_IOC_EXPIRE: | 604 | case AUTOFS_IOC_EXPIRE: |
@@ -579,4 +607,37 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp, | |||
579 | default: | 607 | default: |
580 | return -ENOSYS; | 608 | return -ENOSYS; |
581 | } | 609 | } |
610 | |||
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; | ||
582 | } | 642 | } |
643 | #endif | ||
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index db4117ed7803..48e056e70fd6 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -18,7 +18,9 @@ | |||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/param.h> | 19 | #include <linux/param.h> |
20 | #include <linux/time.h> | 20 | #include <linux/time.h> |
21 | #include <linux/compat.h> | ||
21 | #include <linux/smp_lock.h> | 22 | #include <linux/smp_lock.h> |
23 | |||
22 | #include "autofs_i.h" | 24 | #include "autofs_i.h" |
23 | 25 | ||
24 | static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); | 26 | static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); |
@@ -26,6 +28,7 @@ static int autofs4_dir_unlink(struct inode *,struct dentry *); | |||
26 | static int autofs4_dir_rmdir(struct inode *,struct dentry *); | 28 | static int autofs4_dir_rmdir(struct inode *,struct dentry *); |
27 | static int autofs4_dir_mkdir(struct inode *,struct dentry *,int); | 29 | static int autofs4_dir_mkdir(struct inode *,struct dentry *,int); |
28 | static long autofs4_root_ioctl(struct file *,unsigned int,unsigned long); | 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 | static int autofs4_dir_open(struct inode *inode, struct file *file); | 32 | static int autofs4_dir_open(struct inode *inode, struct file *file); |
30 | static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); | 33 | static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); |
31 | static void *autofs4_follow_link(struct dentry *, struct nameidata *); | 34 | static void *autofs4_follow_link(struct dentry *, struct nameidata *); |
@@ -40,6 +43,9 @@ const struct file_operations autofs4_root_operations = { | |||
40 | .readdir = dcache_readdir, | 43 | .readdir = dcache_readdir, |
41 | .llseek = dcache_dir_lseek, | 44 | .llseek = dcache_dir_lseek, |
42 | .unlocked_ioctl = autofs4_root_ioctl, | 45 | .unlocked_ioctl = autofs4_root_ioctl, |
46 | #ifdef CONFIG_COMPAT | ||
47 | .compat_ioctl = autofs4_root_compat_ioctl, | ||
48 | #endif | ||
43 | }; | 49 | }; |
44 | 50 | ||
45 | const struct file_operations autofs4_dir_operations = { | 51 | const struct file_operations autofs4_dir_operations = { |
@@ -840,6 +846,26 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
840 | } | 846 | } |
841 | 847 | ||
842 | /* Get/set timeout ioctl() operation */ | 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 | static inline int autofs4_get_set_timeout(struct autofs_sb_info *sbi, | 869 | static inline int autofs4_get_set_timeout(struct autofs_sb_info *sbi, |
844 | unsigned long __user *p) | 870 | unsigned long __user *p) |
845 | { | 871 | { |
@@ -933,6 +959,10 @@ static int autofs4_root_ioctl_unlocked(struct inode *inode, struct file *filp, | |||
933 | return autofs4_get_protosubver(sbi, p); | 959 | return autofs4_get_protosubver(sbi, p); |
934 | case AUTOFS_IOC_SETTIMEOUT: | 960 | case AUTOFS_IOC_SETTIMEOUT: |
935 | return autofs4_get_set_timeout(sbi, p); | 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 | case AUTOFS_IOC_ASKUMOUNT: | 967 | case AUTOFS_IOC_ASKUMOUNT: |
938 | return autofs4_ask_umount(filp->f_path.mnt, p); | 968 | return autofs4_ask_umount(filp->f_path.mnt, p); |
@@ -961,3 +991,22 @@ static long autofs4_root_ioctl(struct file *filp, | |||
961 | 991 | ||
962 | return ret; | 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 | ||
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 641640dc7ae5..618f38136304 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -131,23 +131,6 @@ static int w_long(unsigned int fd, unsigned int cmd, | |||
131 | return err; | 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 | struct compat_video_event { | 134 | struct compat_video_event { |
152 | int32_t type; | 135 | int32_t type; |
153 | compat_time_t timestamp; | 136 | compat_time_t timestamp; |
@@ -594,12 +577,6 @@ static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, | |||
594 | return err; | 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 | /* Bluetooth ioctls */ | 580 | /* Bluetooth ioctls */ |
604 | #define HCIUARTSETPROTO _IOW('U', 200, int) | 581 | #define HCIUARTSETPROTO _IOW('U', 200, int) |
605 | #define HCIUARTGETPROTO _IOR('U', 201, int) | 582 | #define HCIUARTGETPROTO _IOR('U', 201, int) |
@@ -1281,13 +1258,6 @@ COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5) | |||
1281 | COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS) | 1258 | COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS) |
1282 | COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) | 1259 | COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) |
1283 | COMPATIBLE_IOCTL(OSS_GETVERSION) | 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 | /* Raw devices */ | 1261 | /* Raw devices */ |
1292 | COMPATIBLE_IOCTL(RAW_SETBIND) | 1262 | COMPATIBLE_IOCTL(RAW_SETBIND) |
1293 | COMPATIBLE_IOCTL(RAW_GETBIND) | 1263 | COMPATIBLE_IOCTL(RAW_GETBIND) |
@@ -1552,9 +1522,6 @@ static long do_ioctl_trans(int fd, unsigned int cmd, | |||
1552 | case RAW_GETBIND: | 1522 | case RAW_GETBIND: |
1553 | return raw_ioctl(fd, cmd, argp); | 1523 | return raw_ioctl(fd, cmd, argp); |
1554 | #endif | 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 | /* One SMB ioctl needs translations. */ | 1525 | /* One SMB ioctl needs translations. */ |
1559 | #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) | 1526 | #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) |
1560 | case SMB_IOC_GETMOUNTUID_32: | 1527 | case SMB_IOC_GETMOUNTUID_32: |
@@ -1609,9 +1576,6 @@ static long do_ioctl_trans(int fd, unsigned int cmd, | |||
1609 | case KDSKBMETA: | 1576 | case KDSKBMETA: |
1610 | case KDSKBLED: | 1577 | case KDSKBLED: |
1611 | case KDSETLED: | 1578 | case KDSETLED: |
1612 | /* AUTOFS */ | ||
1613 | case AUTOFS_IOC_READY: | ||
1614 | case AUTOFS_IOC_FAIL: | ||
1615 | /* NBD */ | 1579 | /* NBD */ |
1616 | case NBD_SET_SOCK: | 1580 | case NBD_SET_SOCK: |
1617 | case NBD_SET_BLKSIZE: | 1581 | case NBD_SET_BLKSIZE: |