4 * Copyright (C) 1991, 1992 Linus Torvalds
7 #include <linux/syscalls.h>
9 #include <linux/smp_lock.h>
10 #include <linux/capability.h>
11 #include <linux/file.h>
13 #include <linux/security.h>
14 #include <linux/module.h>
15 #include <linux/uaccess.h>
17 #include <asm/ioctls.h>
20 * vfs_ioctl - call filesystem specific ioctl methods
21 * @filp: [in] open file to invoke ioctl method on
22 * @cmd: [in] ioctl command to execute
23 * @arg: [in/out] command-specific argument for ioctl
25 * Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
26 * invokes * filesystem specific ->ioctl method. If neither method exists,
29 * Returns 0 on success, -errno on error.
31 long vfs_ioctl(struct file
*filp
, unsigned int cmd
,
39 if (filp
->f_op
->unlocked_ioctl
) {
40 error
= filp
->f_op
->unlocked_ioctl(filp
, cmd
, arg
);
41 if (error
== -ENOIOCTLCMD
)
44 } else if (filp
->f_op
->ioctl
) {
46 error
= filp
->f_op
->ioctl(filp
->f_path
.dentry
->d_inode
,
54 EXPORT_SYMBOL_GPL(vfs_ioctl
);
56 static int ioctl_fibmap(struct file
*filp
, int __user
*p
)
58 struct address_space
*mapping
= filp
->f_mapping
;
61 /* do we support this mess? */
62 if (!mapping
->a_ops
->bmap
)
64 if (!capable(CAP_SYS_RAWIO
))
66 res
= get_user(block
, p
);
70 res
= mapping
->a_ops
->bmap(mapping
, block
);
72 return put_user(res
, p
);
75 static int file_ioctl(struct file
*filp
, unsigned int cmd
,
78 struct inode
*inode
= filp
->f_path
.dentry
->d_inode
;
79 int __user
*p
= (int __user
*)arg
;
83 return ioctl_fibmap(filp
, p
);
85 return put_user(inode
->i_sb
->s_blocksize
, p
);
87 return put_user(i_size_read(inode
) - filp
->f_pos
, p
);
90 return vfs_ioctl(filp
, cmd
, arg
);
93 static int ioctl_fionbio(struct file
*filp
, int __user
*argp
)
98 error
= get_user(on
, argp
);
103 /* SunOS compatibility item. */
104 if (O_NONBLOCK
!= O_NDELAY
)
108 filp
->f_flags
|= flag
;
110 filp
->f_flags
&= ~flag
;
114 static int ioctl_fioasync(unsigned int fd
, struct file
*filp
,
120 error
= get_user(on
, argp
);
123 flag
= on
? FASYNC
: 0;
125 /* Did FASYNC state change ? */
126 if ((flag
^ filp
->f_flags
) & FASYNC
) {
127 if (filp
->f_op
&& filp
->f_op
->fasync
) {
129 error
= filp
->f_op
->fasync(fd
, filp
, on
);
138 filp
->f_flags
|= FASYNC
;
140 filp
->f_flags
&= ~FASYNC
;
145 * When you add any new common ioctls to the switches above and below
146 * please update compat_sys_ioctl() too.
148 * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
149 * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
151 int do_vfs_ioctl(struct file
*filp
, unsigned int fd
, unsigned int cmd
,
155 int __user
*argp
= (int __user
*)arg
;
159 set_close_on_exec(fd
, 1);
163 set_close_on_exec(fd
, 0);
167 error
= ioctl_fionbio(filp
, argp
);
171 error
= ioctl_fioasync(fd
, filp
, argp
);
175 if (S_ISDIR(filp
->f_path
.dentry
->d_inode
->i_mode
) ||
176 S_ISREG(filp
->f_path
.dentry
->d_inode
->i_mode
) ||
177 S_ISLNK(filp
->f_path
.dentry
->d_inode
->i_mode
)) {
179 inode_get_bytes(filp
->f_path
.dentry
->d_inode
);
180 error
= copy_to_user((loff_t __user
*)arg
, &res
,
181 sizeof(res
)) ? -EFAULT
: 0;
186 if (S_ISREG(filp
->f_path
.dentry
->d_inode
->i_mode
))
187 error
= file_ioctl(filp
, cmd
, arg
);
189 error
= vfs_ioctl(filp
, cmd
, arg
);
195 asmlinkage
long sys_ioctl(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
201 filp
= fget_light(fd
, &fput_needed
);
205 error
= security_file_ioctl(filp
, cmd
, arg
);
209 error
= do_vfs_ioctl(filp
, fd
, cmd
, arg
);
211 fput_light(filp
, fput_needed
);