/* * When you add any new common ioctls to the switches above and below * please update compat_sys_ioctl() too. * * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. * It's just a simple helper for sys_ioctl and compat_sys_ioctl. */ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg) { int error = 0; int __user *argp = (int __user *)arg; struct inode *inode = file_inode(filp); switch (cmd) { case FIOCLEX: set_close_on_exec(fd, 1); break; case FIONCLEX: set_close_on_exec(fd, 0); break; case FIONBIO: error = ioctl_fionbio(filp, argp); break; case FIOASYNC: error = ioctl_fioasync(fd, filp, argp); break; case FIOQSIZE: if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) || S_ISLNK(inode->i_mode)) { loff_t res = inode_get_bytes(inode); error = copy_to_user(argp, &res, sizeof(res)) ? -EFAULT : 0; } else error = -ENOTTY; break; case FIFREEZE: error = ioctl_fsfreeze(filp); break; case FITHAW: error = ioctl_fsthaw(filp); break; case FS_IOC_FIEMAP: return ioctl_fiemap(filp, arg); case FIGETBSZ: return put_user(inode->i_sb->s_blocksize, argp); case FICLONE: return ioctl_file_clone(filp, arg, 0, 0, 0); case FICLONERANGE: return ioctl_file_clone_range(filp, argp); case FIDEDUPERANGE: return ioctl_file_dedupe_range(filp, argp); default: if (S_ISREG(inode->i_mode)) error = file_ioctl(filp, cmd, arg); else error = vfs_ioctl(filp, cmd, arg); break; } return error; }
/* * When you add any new common ioctls to the switches above and below * please update compat_sys_ioctl() too. * * vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. * It's just a simple helper for sys_ioctl and compat_sys_ioctl. */ int vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg) { unsigned int flag; int on, error = 0; umode_t mode; struct _file *_filp = tx_cache_get_file(filp); /* Patch up ioctl for bad tx cases*/ if((!_filp) || !_filp->f_dentry ){ #ifdef CONFIG_TX_KSTM_WARNINGS printk(KERN_ERR "Fixing up ioctl\n"); #endif return 0; } mode = d_get_inode_ro(f_get_dentry(_filp))->i_mode; switch (cmd) { case FIOCLEX: set_close_on_exec(fd, 1); break; case FIONCLEX: set_close_on_exec(fd, 0); break; case FIONBIO: if ((error = get_user(on, (int __user *)arg)) != 0) break; flag = O_NONBLOCK; #ifdef __sparc__ /* SunOS compatibility item. */ if(O_NONBLOCK != O_NDELAY) flag |= O_NDELAY; #endif if (on) _filp->f_flags |= flag; else _filp->f_flags &= ~flag; break; case FIOASYNC: if ((error = get_user(on, (int __user *)arg)) != 0) break; flag = on ? FASYNC : 0; /* Did FASYNC state change ? */ if ((flag ^ _filp->f_flags) & FASYNC) { if (filp->f_op && filp->f_op->fasync) { lock_kernel(); error = filp->f_op->fasync(fd, filp, on); unlock_kernel(); } else error = -ENOTTY; } if (error != 0) break; if (on) _filp->f_flags |= FASYNC; else _filp->f_flags &= ~FASYNC; break; case FIOQSIZE: if (S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode)) { loff_t res = inode_get_bytes(f_get_dentry(_filp)->d_inode); error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0; } else error = -ENOTTY; break; default: if(live_transaction()){ /* Short circuit this stupid ioctl */ if(cmd == TIOCGWINSZ){ #ifdef CONFIG_TX_KSTM_WARNINGS printk(KERN_ERR "Warning: some bozo wants to know the terminal width in a transaction.\n"); #endif error = -EINVAL; break; } else if(cmd != TCGETS) BUG(); } if (S_ISREG(mode)) error = file_ioctl(filp, cmd, arg); else error = do_ioctl(filp, cmd, arg); break; } return error; }
/* * When you add any new common ioctls to the switches above and below * please update compat_sys_ioctl() too. * * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. * It's just a simple helper for sys_ioctl and compat_sys_ioctl. */ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg) { int error = 0; int __user *argp = (int __user *)arg; switch (cmd) { case FIOCLEX: set_close_on_exec(fd, 1); break; case FIONCLEX: set_close_on_exec(fd, 0); break; case FIONBIO: error = ioctl_fionbio(filp, argp); break; case FIOASYNC: error = ioctl_fioasync(fd, filp, argp); break; case FIOQSIZE: if (S_ISDIR(filp->f_path.dentry->d_inode->i_mode) || S_ISREG(filp->f_path.dentry->d_inode->i_mode) || S_ISLNK(filp->f_path.dentry->d_inode->i_mode)) { loff_t res = inode_get_bytes(filp->f_path.dentry->d_inode); error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0; } else error = -ENOTTY; break; case FIFREEZE: error = ioctl_fsfreeze(filp); break; case FITHAW: error = ioctl_fsthaw(filp); break; case FS_IOC_FIEMAP: return ioctl_fiemap(filp, arg); case FIGETBSZ: { struct super_block *sb = filp->f_path.dentry->d_inode->i_sb; int __user *p = (int __user *)arg; if (sb->s_blocksize == 1ul << sb->s_blocksize_bits) return put_user(sb->s_blocksize, p); /* fail through */ } default: if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) error = file_ioctl(filp, cmd, arg); else error = vfs_ioctl(filp, cmd, arg); break; } return error; }
asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { struct file * filp; unsigned int flag; int on, error = -EBADF; filp = fget(fd); if (!filp) goto out; error = security_file_ioctl(filp, cmd, arg); if (error) { fput(filp); goto out; } lock_kernel(); switch (cmd) { case FIOCLEX: set_close_on_exec(fd, 1); break; case FIONCLEX: set_close_on_exec(fd, 0); break; case FIONBIO: if ((error = get_user(on, (int __user *)arg)) != 0) break; flag = O_NONBLOCK; #ifdef __sparc__ /* SunOS compatibility item. */ if(O_NONBLOCK != O_NDELAY) flag |= O_NDELAY; #endif if (on) filp->f_flags |= flag; else filp->f_flags &= ~flag; break; case FIOASYNC: if ((error = get_user(on, (int __user *)arg)) != 0) break; flag = on ? FASYNC : 0; /* Did FASYNC state change ? */ if ((flag ^ filp->f_flags) & FASYNC) { if (filp->f_op && filp->f_op->fasync) error = filp->f_op->fasync(fd, filp, on); else error = -ENOTTY; } if (error != 0) break; if (on) filp->f_flags |= FASYNC; else filp->f_flags &= ~FASYNC; break; case FIOQSIZE: if (S_ISDIR(filp->f_dentry->d_inode->i_mode) || S_ISREG(filp->f_dentry->d_inode->i_mode) || S_ISLNK(filp->f_dentry->d_inode->i_mode)) { loff_t res = inode_get_bytes(filp->f_dentry->d_inode); error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0; } else error = -ENOTTY; break; default: error = -ENOTTY; if (S_ISREG(filp->f_dentry->d_inode->i_mode)) error = file_ioctl(filp, cmd, arg); else if (filp->f_op && filp->f_op->ioctl) error = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg); } unlock_kernel(); fput(filp); out: return error; }
/* * When you add any new common ioctls to the switches above and below * please update compat_sys_ioctl() too. * * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. * It's just a simple helper for sys_ioctl and compat_sys_ioctl. */ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg) { int error = 0; int __user *argp = (int __user *)arg; #ifdef CONFIG_LTT_LITE char ltt_string[LTT_LITE_MAX_LOG_STRING_SIZE]; sprintf(ltt_string, "fd=%X/cmd=%X/arg=%X/pid=%d\n", fd, cmd, (int)arg, current->pid); ltt_lite_syscall_param(LTT_EV_FILE_SYSTEM_IOCTL, ltt_string, strlen(ltt_string)); sprintf(ltt_string, "f_op=%X/pid=%d\n", (int)filp->f_op, current->pid); ltt_lite_syscall_param(LTT_EV_FILE_SYSTEM_IOCTL, ltt_string, strlen(ltt_string)); #endif switch (cmd) { case FIOCLEX: set_close_on_exec(fd, 1); break; case FIONCLEX: set_close_on_exec(fd, 0); break; case FIONBIO: /* BKL needed to avoid races tweaking f_flags */ lock_kernel(); error = ioctl_fionbio(filp, argp); unlock_kernel(); break; case FIOASYNC: /* BKL needed to avoid races tweaking f_flags */ lock_kernel(); error = ioctl_fioasync(fd, filp, argp); unlock_kernel(); break; case FIOQSIZE: if (S_ISDIR(filp->f_path.dentry->d_inode->i_mode) || S_ISREG(filp->f_path.dentry->d_inode->i_mode) || S_ISLNK(filp->f_path.dentry->d_inode->i_mode)) { loff_t res = inode_get_bytes(filp->f_path.dentry->d_inode); error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0; } else error = -ENOTTY; break; case FIFREEZE: error = ioctl_fsfreeze(filp); break; case FITHAW: error = ioctl_fsthaw(filp); break; default: if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) error = file_ioctl(filp, cmd, arg); else error = vfs_ioctl(filp, cmd, arg); break; } return error; }