From 6272e2667965dfb5b59199f462cd0f001fb304a6 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 8 May 2007 00:29:21 -0700 Subject: cleanup compat ioctl handling Merge all compat ioctl handling into compat_ioctl.c instead of splitting it over compat.c and compat_ioctl.c. This also allows to get rid of ioctl32.h Signed-off-by: Christoph Hellwig Looks-good-to: Andi Kleen Acked-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/compat.c | 162 +----------------------------------------------------------- 1 file changed, 1 insertion(+), 161 deletions(-) (limited to 'fs/compat.c') diff --git a/fs/compat.c b/fs/compat.c index a32e2ae737f..9f6248dfd9d 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -25,10 +25,8 @@ #include #include #include -#include #include #include -#include /* for SIOCDEVPRIVATE */ #include #include #include @@ -46,13 +44,12 @@ #include #include #include +#include #include #include #include #include -#include /* siocdevprivate_ioctl */ - #include #include #include @@ -313,163 +310,6 @@ out: return error; } -/* ioctl32 stuff, used by sparc64, parisc, s390x, ppc64, x86_64, MIPS */ - -#define IOCTL_HASHSIZE 256 -static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE]; - -static inline unsigned long ioctl32_hash(unsigned long cmd) -{ - return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE; -} - -static void ioctl32_insert_translation(struct ioctl_trans *trans) -{ - unsigned long hash; - struct ioctl_trans *t; - - hash = ioctl32_hash (trans->cmd); - if (!ioctl32_hash_table[hash]) - ioctl32_hash_table[hash] = trans; - else { - t = ioctl32_hash_table[hash]; - while (t->next) - t = t->next; - trans->next = NULL; - t->next = trans; - } -} - -static int __init init_sys32_ioctl(void) -{ - int i; - - for (i = 0; i < ioctl_table_size; i++) { - if (ioctl_start[i].next != 0) { - printk("ioctl translation %d bad\n",i); - return -1; - } - - ioctl32_insert_translation(&ioctl_start[i]); - } - return 0; -} - -__initcall(init_sys32_ioctl); - -static void compat_ioctl_error(struct file *filp, unsigned int fd, - unsigned int cmd, unsigned long arg) -{ - char buf[10]; - char *fn = "?"; - char *path; - - /* find the name of the device. */ - path = (char *)__get_free_page(GFP_KERNEL); - if (path) { - fn = d_path(filp->f_path.dentry, filp->f_path.mnt, path, PAGE_SIZE); - if (IS_ERR(fn)) - fn = "?"; - } - - sprintf(buf,"'%c'", (cmd>>_IOC_TYPESHIFT) & _IOC_TYPEMASK); - if (!isprint(buf[1])) - sprintf(buf, "%02x", buf[1]); - compat_printk("ioctl32(%s:%d): Unknown cmd fd(%d) " - "cmd(%08x){t:%s;sz:%u} arg(%08x) on %s\n", - current->comm, current->pid, - (int)fd, (unsigned int)cmd, buf, - (cmd >> _IOC_SIZESHIFT) & _IOC_SIZEMASK, - (unsigned int)arg, fn); - - if (path) - free_page((unsigned long)path); -} - -asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, - unsigned long arg) -{ - struct file *filp; - int error = -EBADF; - struct ioctl_trans *t; - int fput_needed; - - filp = fget_light(fd, &fput_needed); - if (!filp) - goto out; - - /* RED-PEN how should LSM module know it's handling 32bit? */ - error = security_file_ioctl(filp, cmd, arg); - if (error) - goto out_fput; - - /* - * To allow the compat_ioctl handlers to be self contained - * we need to check the common ioctls here first. - * Just handle them with the standard handlers below. - */ - switch (cmd) { - case FIOCLEX: - case FIONCLEX: - case FIONBIO: - case FIOASYNC: - case FIOQSIZE: - break; - - case FIBMAP: - case FIGETBSZ: - case FIONREAD: - if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) - break; - /*FALL THROUGH*/ - - default: - if (filp->f_op && filp->f_op->compat_ioctl) { - error = filp->f_op->compat_ioctl(filp, cmd, arg); - if (error != -ENOIOCTLCMD) - goto out_fput; - } - - if (!filp->f_op || - (!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl)) - goto do_ioctl; - break; - } - - for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) { - if (t->cmd == cmd) - goto found_handler; - } - - if (S_ISSOCK(filp->f_path.dentry->d_inode->i_mode) && - cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { - error = siocdevprivate_ioctl(fd, cmd, arg); - } else { - static int count; - - if (++count <= 50) - compat_ioctl_error(filp, fd, cmd, arg); - error = -EINVAL; - } - - goto out_fput; - - found_handler: - if (t->handler) { - lock_kernel(); - error = t->handler(fd, cmd, arg, filp); - unlock_kernel(); - goto out_fput; - } - - do_ioctl: - error = vfs_ioctl(filp, fd, cmd, arg); - out_fput: - fput_light(filp, fput_needed); - out: - return error; -} - static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) { if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || -- cgit v1.2.3