ia64/linux-2.6.18-xen.hg

annotate fs/ioctl.c @ 524:7f8b544237bf

netfront: Allow netfront in domain 0.

This is useful if your physical network device is in a utility domain.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Apr 15 15:18:58 2008 +0100 (2008-04-15)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 * linux/fs/ioctl.c
ian@0 3 *
ian@0 4 * Copyright (C) 1991, 1992 Linus Torvalds
ian@0 5 */
ian@0 6
ian@0 7 #include <linux/syscalls.h>
ian@0 8 #include <linux/mm.h>
ian@0 9 #include <linux/smp_lock.h>
ian@0 10 #include <linux/capability.h>
ian@0 11 #include <linux/file.h>
ian@0 12 #include <linux/fs.h>
ian@0 13 #include <linux/security.h>
ian@0 14 #include <linux/module.h>
ian@0 15
ian@0 16 #include <asm/uaccess.h>
ian@0 17 #include <asm/ioctls.h>
ian@0 18
ian@0 19 static long do_ioctl(struct file *filp, unsigned int cmd,
ian@0 20 unsigned long arg)
ian@0 21 {
ian@0 22 int error = -ENOTTY;
ian@0 23
ian@0 24 if (!filp->f_op)
ian@0 25 goto out;
ian@0 26
ian@0 27 if (filp->f_op->unlocked_ioctl) {
ian@0 28 error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
ian@0 29 if (error == -ENOIOCTLCMD)
ian@0 30 error = -EINVAL;
ian@0 31 goto out;
ian@0 32 } else if (filp->f_op->ioctl) {
ian@0 33 lock_kernel();
ian@0 34 error = filp->f_op->ioctl(filp->f_dentry->d_inode,
ian@0 35 filp, cmd, arg);
ian@0 36 unlock_kernel();
ian@0 37 }
ian@0 38
ian@0 39 out:
ian@0 40 return error;
ian@0 41 }
ian@0 42
ian@0 43 static int file_ioctl(struct file *filp, unsigned int cmd,
ian@0 44 unsigned long arg)
ian@0 45 {
ian@0 46 int error;
ian@0 47 int block;
ian@0 48 struct inode * inode = filp->f_dentry->d_inode;
ian@0 49 int __user *p = (int __user *)arg;
ian@0 50
ian@0 51 switch (cmd) {
ian@0 52 case FIBMAP:
ian@0 53 {
ian@0 54 struct address_space *mapping = filp->f_mapping;
ian@0 55 int res;
ian@0 56 /* do we support this mess? */
ian@0 57 if (!mapping->a_ops->bmap)
ian@0 58 return -EINVAL;
ian@0 59 if (!capable(CAP_SYS_RAWIO))
ian@0 60 return -EPERM;
ian@0 61 if ((error = get_user(block, p)) != 0)
ian@0 62 return error;
ian@0 63
ian@0 64 lock_kernel();
ian@0 65 res = mapping->a_ops->bmap(mapping, block);
ian@0 66 unlock_kernel();
ian@0 67 return put_user(res, p);
ian@0 68 }
ian@0 69 case FIGETBSZ:
ian@0 70 if (inode->i_sb == NULL)
ian@0 71 return -EBADF;
ian@0 72 return put_user(inode->i_sb->s_blocksize, p);
ian@0 73 case FIONREAD:
ian@0 74 return put_user(i_size_read(inode) - filp->f_pos, p);
ian@0 75 }
ian@0 76
ian@0 77 return do_ioctl(filp, cmd, arg);
ian@0 78 }
ian@0 79
ian@0 80 /*
ian@0 81 * When you add any new common ioctls to the switches above and below
ian@0 82 * please update compat_sys_ioctl() too.
ian@0 83 *
ian@0 84 * vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
ian@0 85 * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
ian@0 86 */
ian@0 87 int vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg)
ian@0 88 {
ian@0 89 unsigned int flag;
ian@0 90 int on, error = 0;
ian@0 91
ian@0 92 switch (cmd) {
ian@0 93 case FIOCLEX:
ian@0 94 set_close_on_exec(fd, 1);
ian@0 95 break;
ian@0 96
ian@0 97 case FIONCLEX:
ian@0 98 set_close_on_exec(fd, 0);
ian@0 99 break;
ian@0 100
ian@0 101 case FIONBIO:
ian@0 102 if ((error = get_user(on, (int __user *)arg)) != 0)
ian@0 103 break;
ian@0 104 flag = O_NONBLOCK;
ian@0 105 #ifdef __sparc__
ian@0 106 /* SunOS compatibility item. */
ian@0 107 if(O_NONBLOCK != O_NDELAY)
ian@0 108 flag |= O_NDELAY;
ian@0 109 #endif
ian@0 110 if (on)
ian@0 111 filp->f_flags |= flag;
ian@0 112 else
ian@0 113 filp->f_flags &= ~flag;
ian@0 114 break;
ian@0 115
ian@0 116 case FIOASYNC:
ian@0 117 if ((error = get_user(on, (int __user *)arg)) != 0)
ian@0 118 break;
ian@0 119 flag = on ? FASYNC : 0;
ian@0 120
ian@0 121 /* Did FASYNC state change ? */
ian@0 122 if ((flag ^ filp->f_flags) & FASYNC) {
ian@0 123 if (filp->f_op && filp->f_op->fasync) {
ian@0 124 lock_kernel();
ian@0 125 error = filp->f_op->fasync(fd, filp, on);
ian@0 126 unlock_kernel();
ian@0 127 }
ian@0 128 else error = -ENOTTY;
ian@0 129 }
ian@0 130 if (error != 0)
ian@0 131 break;
ian@0 132
ian@0 133 if (on)
ian@0 134 filp->f_flags |= FASYNC;
ian@0 135 else
ian@0 136 filp->f_flags &= ~FASYNC;
ian@0 137 break;
ian@0 138
ian@0 139 case FIOQSIZE:
ian@0 140 if (S_ISDIR(filp->f_dentry->d_inode->i_mode) ||
ian@0 141 S_ISREG(filp->f_dentry->d_inode->i_mode) ||
ian@0 142 S_ISLNK(filp->f_dentry->d_inode->i_mode)) {
ian@0 143 loff_t res = inode_get_bytes(filp->f_dentry->d_inode);
ian@0 144 error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0;
ian@0 145 }
ian@0 146 else
ian@0 147 error = -ENOTTY;
ian@0 148 break;
ian@0 149 default:
ian@0 150 if (S_ISREG(filp->f_dentry->d_inode->i_mode))
ian@0 151 error = file_ioctl(filp, cmd, arg);
ian@0 152 else
ian@0 153 error = do_ioctl(filp, cmd, arg);
ian@0 154 break;
ian@0 155 }
ian@0 156 return error;
ian@0 157 }
ian@0 158
ian@0 159 asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
ian@0 160 {
ian@0 161 struct file * filp;
ian@0 162 int error = -EBADF;
ian@0 163 int fput_needed;
ian@0 164
ian@0 165 filp = fget_light(fd, &fput_needed);
ian@0 166 if (!filp)
ian@0 167 goto out;
ian@0 168
ian@0 169 error = security_file_ioctl(filp, cmd, arg);
ian@0 170 if (error)
ian@0 171 goto out_fput;
ian@0 172
ian@0 173 error = vfs_ioctl(filp, fd, cmd, arg);
ian@0 174 out_fput:
ian@0 175 fput_light(filp, fput_needed);
ian@0 176 out:
ian@0 177 return error;
ian@0 178 }
ian@0 179
ian@0 180 /*
ian@0 181 * Platforms implementing 32 bit compatibility ioctl handlers in
ian@0 182 * modules need this exported
ian@0 183 */
ian@0 184 #ifdef CONFIG_COMPAT
ian@0 185 EXPORT_SYMBOL(sys_ioctl);
ian@0 186 #endif