11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/fs/fcntl.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 1991, 1992 Linus Torvalds 51da177e4SLinus Torvalds */ 61da177e4SLinus Torvalds 71da177e4SLinus Torvalds #include <linux/syscalls.h> 81da177e4SLinus Torvalds #include <linux/init.h> 91da177e4SLinus Torvalds #include <linux/mm.h> 101da177e4SLinus Torvalds #include <linux/fs.h> 111da177e4SLinus Torvalds #include <linux/file.h> 129f3acc31SAl Viro #include <linux/fdtable.h> 1316f7e0feSRandy Dunlap #include <linux/capability.h> 141da177e4SLinus Torvalds #include <linux/dnotify.h> 151da177e4SLinus Torvalds #include <linux/slab.h> 161da177e4SLinus Torvalds #include <linux/module.h> 1735f3d14dSJens Axboe #include <linux/pipe_fs_i.h> 181da177e4SLinus Torvalds #include <linux/security.h> 191da177e4SLinus Torvalds #include <linux/ptrace.h> 207ed20e1aSJesper Juhl #include <linux/signal.h> 21ab2af1f5SDipankar Sarma #include <linux/rcupdate.h> 22b488893aSPavel Emelyanov #include <linux/pid_namespace.h> 231da177e4SLinus Torvalds 241da177e4SLinus Torvalds #include <asm/poll.h> 251da177e4SLinus Torvalds #include <asm/siginfo.h> 261da177e4SLinus Torvalds #include <asm/uaccess.h> 271da177e4SLinus Torvalds 28fc9b52cdSHarvey Harrison void set_close_on_exec(unsigned int fd, int flag) 291da177e4SLinus Torvalds { 301da177e4SLinus Torvalds struct files_struct *files = current->files; 31badf1662SDipankar Sarma struct fdtable *fdt; 321da177e4SLinus Torvalds spin_lock(&files->file_lock); 33badf1662SDipankar Sarma fdt = files_fdtable(files); 341da177e4SLinus Torvalds if (flag) 35badf1662SDipankar Sarma FD_SET(fd, fdt->close_on_exec); 361da177e4SLinus Torvalds else 37badf1662SDipankar Sarma FD_CLR(fd, fdt->close_on_exec); 381da177e4SLinus Torvalds spin_unlock(&files->file_lock); 391da177e4SLinus Torvalds } 401da177e4SLinus Torvalds 41858119e1SArjan van de Ven static int get_close_on_exec(unsigned int fd) 421da177e4SLinus Torvalds { 431da177e4SLinus Torvalds struct files_struct *files = current->files; 44badf1662SDipankar Sarma struct fdtable *fdt; 451da177e4SLinus Torvalds int res; 46b835996fSDipankar Sarma rcu_read_lock(); 47badf1662SDipankar Sarma fdt = files_fdtable(files); 48badf1662SDipankar Sarma res = FD_ISSET(fd, fdt->close_on_exec); 49b835996fSDipankar Sarma rcu_read_unlock(); 501da177e4SLinus Torvalds return res; 511da177e4SLinus Torvalds } 521da177e4SLinus Torvalds 53a26eab24SHeiko Carstens SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags) 541da177e4SLinus Torvalds { 551da177e4SLinus Torvalds int err = -EBADF; 561da177e4SLinus Torvalds struct file * file, *tofree; 571da177e4SLinus Torvalds struct files_struct * files = current->files; 58badf1662SDipankar Sarma struct fdtable *fdt; 591da177e4SLinus Torvalds 60336dd1f7SUlrich Drepper if ((flags & ~O_CLOEXEC) != 0) 61336dd1f7SUlrich Drepper return -EINVAL; 62336dd1f7SUlrich Drepper 636c5d0512SAl Viro if (unlikely(oldfd == newfd)) 646c5d0512SAl Viro return -EINVAL; 656c5d0512SAl Viro 661da177e4SLinus Torvalds spin_lock(&files->file_lock); 671da177e4SLinus Torvalds err = expand_files(files, newfd); 681b7e190bSAl Viro file = fcheck(oldfd); 691b7e190bSAl Viro if (unlikely(!file)) 701b7e190bSAl Viro goto Ebadf; 714e1e018eSAl Viro if (unlikely(err < 0)) { 724e1e018eSAl Viro if (err == -EMFILE) 731b7e190bSAl Viro goto Ebadf; 741b7e190bSAl Viro goto out_unlock; 754e1e018eSAl Viro } 761b7e190bSAl Viro /* 771b7e190bSAl Viro * We need to detect attempts to do dup2() over allocated but still 781b7e190bSAl Viro * not finished descriptor. NB: OpenBSD avoids that at the price of 791b7e190bSAl Viro * extra work in their equivalent of fget() - they insert struct 801b7e190bSAl Viro * file immediately after grabbing descriptor, mark it larval if 811b7e190bSAl Viro * more work (e.g. actual opening) is needed and make sure that 821b7e190bSAl Viro * fget() treats larval files as absent. Potentially interesting, 831b7e190bSAl Viro * but while extra work in fget() is trivial, locking implications 841b7e190bSAl Viro * and amount of surgery on open()-related paths in VFS are not. 851b7e190bSAl Viro * FreeBSD fails with -EBADF in the same situation, NetBSD "solution" 861b7e190bSAl Viro * deadlocks in rather amusing ways, AFAICS. All of that is out of 871b7e190bSAl Viro * scope of POSIX or SUS, since neither considers shared descriptor 881b7e190bSAl Viro * tables and this condition does not arise without those. 891b7e190bSAl Viro */ 901da177e4SLinus Torvalds err = -EBUSY; 91badf1662SDipankar Sarma fdt = files_fdtable(files); 92badf1662SDipankar Sarma tofree = fdt->fd[newfd]; 93badf1662SDipankar Sarma if (!tofree && FD_ISSET(newfd, fdt->open_fds)) 941b7e190bSAl Viro goto out_unlock; 951b7e190bSAl Viro get_file(file); 96ab2af1f5SDipankar Sarma rcu_assign_pointer(fdt->fd[newfd], file); 97badf1662SDipankar Sarma FD_SET(newfd, fdt->open_fds); 98336dd1f7SUlrich Drepper if (flags & O_CLOEXEC) 99336dd1f7SUlrich Drepper FD_SET(newfd, fdt->close_on_exec); 100336dd1f7SUlrich Drepper else 101badf1662SDipankar Sarma FD_CLR(newfd, fdt->close_on_exec); 1021da177e4SLinus Torvalds spin_unlock(&files->file_lock); 1031da177e4SLinus Torvalds 1041da177e4SLinus Torvalds if (tofree) 1051da177e4SLinus Torvalds filp_close(tofree, files); 1061b7e190bSAl Viro 1071b7e190bSAl Viro return newfd; 1081b7e190bSAl Viro 1091b7e190bSAl Viro Ebadf: 1101b7e190bSAl Viro err = -EBADF; 1111da177e4SLinus Torvalds out_unlock: 1121da177e4SLinus Torvalds spin_unlock(&files->file_lock); 1131b7e190bSAl Viro return err; 1141da177e4SLinus Torvalds } 1151da177e4SLinus Torvalds 116a26eab24SHeiko Carstens SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd) 117336dd1f7SUlrich Drepper { 1186c5d0512SAl Viro if (unlikely(newfd == oldfd)) { /* corner case */ 1196c5d0512SAl Viro struct files_struct *files = current->files; 1202b79bc4fSJeff Mahoney int retval = oldfd; 1212b79bc4fSJeff Mahoney 1226c5d0512SAl Viro rcu_read_lock(); 1236c5d0512SAl Viro if (!fcheck_files(files, oldfd)) 1242b79bc4fSJeff Mahoney retval = -EBADF; 1256c5d0512SAl Viro rcu_read_unlock(); 1262b79bc4fSJeff Mahoney return retval; 1276c5d0512SAl Viro } 128336dd1f7SUlrich Drepper return sys_dup3(oldfd, newfd, 0); 129336dd1f7SUlrich Drepper } 130336dd1f7SUlrich Drepper 131a26eab24SHeiko Carstens SYSCALL_DEFINE1(dup, unsigned int, fildes) 1321da177e4SLinus Torvalds { 1331da177e4SLinus Torvalds int ret = -EBADF; 1341da177e4SLinus Torvalds struct file *file = fget(fildes); 1351da177e4SLinus Torvalds 1361027abe8SAl Viro if (file) { 1371027abe8SAl Viro ret = get_unused_fd(); 1381027abe8SAl Viro if (ret >= 0) 1391027abe8SAl Viro fd_install(ret, file); 1401027abe8SAl Viro else 1411027abe8SAl Viro fput(file); 1421027abe8SAl Viro } 1431da177e4SLinus Torvalds return ret; 1441da177e4SLinus Torvalds } 1451da177e4SLinus Torvalds 14676398425SJonathan Corbet #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME) 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds static int setfl(int fd, struct file * filp, unsigned long arg) 1491da177e4SLinus Torvalds { 1500f7fc9e4SJosef "Jeff" Sipek struct inode * inode = filp->f_path.dentry->d_inode; 1511da177e4SLinus Torvalds int error = 0; 1521da177e4SLinus Torvalds 1537d95c8f2Sdean gaudet /* 1547d95c8f2Sdean gaudet * O_APPEND cannot be cleared if the file is marked as append-only 1557d95c8f2Sdean gaudet * and the file is open for write. 1567d95c8f2Sdean gaudet */ 1577d95c8f2Sdean gaudet if (((arg ^ filp->f_flags) & O_APPEND) && IS_APPEND(inode)) 1581da177e4SLinus Torvalds return -EPERM; 1591da177e4SLinus Torvalds 1601da177e4SLinus Torvalds /* O_NOATIME can only be set by the owner or superuser */ 1611da177e4SLinus Torvalds if ((arg & O_NOATIME) && !(filp->f_flags & O_NOATIME)) 1623bd858abSSatyam Sharma if (!is_owner_or_cap(inode)) 1631da177e4SLinus Torvalds return -EPERM; 1641da177e4SLinus Torvalds 1651da177e4SLinus Torvalds /* required for strict SunOS emulation */ 1661da177e4SLinus Torvalds if (O_NONBLOCK != O_NDELAY) 1671da177e4SLinus Torvalds if (arg & O_NDELAY) 1681da177e4SLinus Torvalds arg |= O_NONBLOCK; 1691da177e4SLinus Torvalds 1701da177e4SLinus Torvalds if (arg & O_DIRECT) { 1711da177e4SLinus Torvalds if (!filp->f_mapping || !filp->f_mapping->a_ops || 1721da177e4SLinus Torvalds !filp->f_mapping->a_ops->direct_IO) 1731da177e4SLinus Torvalds return -EINVAL; 1741da177e4SLinus Torvalds } 1751da177e4SLinus Torvalds 1761da177e4SLinus Torvalds if (filp->f_op && filp->f_op->check_flags) 1771da177e4SLinus Torvalds error = filp->f_op->check_flags(arg); 1781da177e4SLinus Torvalds if (error) 1791da177e4SLinus Torvalds return error; 1801da177e4SLinus Torvalds 181218d11a8SJonathan Corbet /* 18276398425SJonathan Corbet * ->fasync() is responsible for setting the FASYNC bit. 183218d11a8SJonathan Corbet */ 18476398425SJonathan Corbet if (((arg ^ filp->f_flags) & FASYNC) && filp->f_op && 18576398425SJonathan Corbet filp->f_op->fasync) { 1861da177e4SLinus Torvalds error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0); 1871da177e4SLinus Torvalds if (error < 0) 1881da177e4SLinus Torvalds goto out; 18960aa4924SJonathan Corbet if (error > 0) 19060aa4924SJonathan Corbet error = 0; 1911da177e4SLinus Torvalds } 192db1dd4d3SJonathan Corbet spin_lock(&filp->f_lock); 1931da177e4SLinus Torvalds filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK); 194db1dd4d3SJonathan Corbet spin_unlock(&filp->f_lock); 19576398425SJonathan Corbet 1961da177e4SLinus Torvalds out: 1971da177e4SLinus Torvalds return error; 1981da177e4SLinus Torvalds } 1991da177e4SLinus Torvalds 200609d7fa9SEric W. Biederman static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, 2012f38d70fSOleg Nesterov int force) 2021da177e4SLinus Torvalds { 20380e1e823SLinus Torvalds write_lock_irq(&filp->f_owner.lock); 2041da177e4SLinus Torvalds if (force || !filp->f_owner.pid) { 205609d7fa9SEric W. Biederman put_pid(filp->f_owner.pid); 206609d7fa9SEric W. Biederman filp->f_owner.pid = get_pid(pid); 207609d7fa9SEric W. Biederman filp->f_owner.pid_type = type; 2082f38d70fSOleg Nesterov 2092f38d70fSOleg Nesterov if (pid) { 2102f38d70fSOleg Nesterov const struct cred *cred = current_cred(); 2112f38d70fSOleg Nesterov filp->f_owner.uid = cred->uid; 2122f38d70fSOleg Nesterov filp->f_owner.euid = cred->euid; 2132f38d70fSOleg Nesterov } 2141da177e4SLinus Torvalds } 21580e1e823SLinus Torvalds write_unlock_irq(&filp->f_owner.lock); 2161da177e4SLinus Torvalds } 2171da177e4SLinus Torvalds 218609d7fa9SEric W. Biederman int __f_setown(struct file *filp, struct pid *pid, enum pid_type type, 219609d7fa9SEric W. Biederman int force) 2201da177e4SLinus Torvalds { 2211da177e4SLinus Torvalds int err; 2221da177e4SLinus Torvalds 2231da177e4SLinus Torvalds err = security_file_set_fowner(filp); 2241da177e4SLinus Torvalds if (err) 2251da177e4SLinus Torvalds return err; 2261da177e4SLinus Torvalds 2272f38d70fSOleg Nesterov f_modown(filp, pid, type, force); 2281da177e4SLinus Torvalds return 0; 2291da177e4SLinus Torvalds } 230609d7fa9SEric W. Biederman EXPORT_SYMBOL(__f_setown); 2311da177e4SLinus Torvalds 232609d7fa9SEric W. Biederman int f_setown(struct file *filp, unsigned long arg, int force) 233609d7fa9SEric W. Biederman { 234609d7fa9SEric W. Biederman enum pid_type type; 235609d7fa9SEric W. Biederman struct pid *pid; 236609d7fa9SEric W. Biederman int who = arg; 237609d7fa9SEric W. Biederman int result; 238609d7fa9SEric W. Biederman type = PIDTYPE_PID; 239609d7fa9SEric W. Biederman if (who < 0) { 240609d7fa9SEric W. Biederman type = PIDTYPE_PGID; 241609d7fa9SEric W. Biederman who = -who; 242609d7fa9SEric W. Biederman } 243609d7fa9SEric W. Biederman rcu_read_lock(); 244b488893aSPavel Emelyanov pid = find_vpid(who); 245609d7fa9SEric W. Biederman result = __f_setown(filp, pid, type, force); 246609d7fa9SEric W. Biederman rcu_read_unlock(); 247609d7fa9SEric W. Biederman return result; 248609d7fa9SEric W. Biederman } 2491da177e4SLinus Torvalds EXPORT_SYMBOL(f_setown); 2501da177e4SLinus Torvalds 2511da177e4SLinus Torvalds void f_delown(struct file *filp) 2521da177e4SLinus Torvalds { 2532f38d70fSOleg Nesterov f_modown(filp, NULL, PIDTYPE_PID, 1); 254609d7fa9SEric W. Biederman } 255609d7fa9SEric W. Biederman 256609d7fa9SEric W. Biederman pid_t f_getown(struct file *filp) 257609d7fa9SEric W. Biederman { 258609d7fa9SEric W. Biederman pid_t pid; 25943fa1adbSEric W. Biederman read_lock(&filp->f_owner.lock); 2606c5f3e7bSPavel Emelyanov pid = pid_vnr(filp->f_owner.pid); 261609d7fa9SEric W. Biederman if (filp->f_owner.pid_type == PIDTYPE_PGID) 262609d7fa9SEric W. Biederman pid = -pid; 26343fa1adbSEric W. Biederman read_unlock(&filp->f_owner.lock); 264609d7fa9SEric W. Biederman return pid; 2651da177e4SLinus Torvalds } 2661da177e4SLinus Torvalds 267ba0a6c9fSPeter Zijlstra static int f_setown_ex(struct file *filp, unsigned long arg) 268ba0a6c9fSPeter Zijlstra { 269ba0a6c9fSPeter Zijlstra struct f_owner_ex * __user owner_p = (void * __user)arg; 270ba0a6c9fSPeter Zijlstra struct f_owner_ex owner; 271ba0a6c9fSPeter Zijlstra struct pid *pid; 272ba0a6c9fSPeter Zijlstra int type; 273ba0a6c9fSPeter Zijlstra int ret; 274ba0a6c9fSPeter Zijlstra 275ba0a6c9fSPeter Zijlstra ret = copy_from_user(&owner, owner_p, sizeof(owner)); 276ba0a6c9fSPeter Zijlstra if (ret) 2775b54470dSDan Carpenter return -EFAULT; 278ba0a6c9fSPeter Zijlstra 279ba0a6c9fSPeter Zijlstra switch (owner.type) { 280ba0a6c9fSPeter Zijlstra case F_OWNER_TID: 281ba0a6c9fSPeter Zijlstra type = PIDTYPE_MAX; 282ba0a6c9fSPeter Zijlstra break; 283ba0a6c9fSPeter Zijlstra 284ba0a6c9fSPeter Zijlstra case F_OWNER_PID: 285ba0a6c9fSPeter Zijlstra type = PIDTYPE_PID; 286ba0a6c9fSPeter Zijlstra break; 287ba0a6c9fSPeter Zijlstra 288978b4053SPeter Zijlstra case F_OWNER_PGRP: 289ba0a6c9fSPeter Zijlstra type = PIDTYPE_PGID; 290ba0a6c9fSPeter Zijlstra break; 291ba0a6c9fSPeter Zijlstra 292ba0a6c9fSPeter Zijlstra default: 293ba0a6c9fSPeter Zijlstra return -EINVAL; 294ba0a6c9fSPeter Zijlstra } 295ba0a6c9fSPeter Zijlstra 296ba0a6c9fSPeter Zijlstra rcu_read_lock(); 297ba0a6c9fSPeter Zijlstra pid = find_vpid(owner.pid); 298ba0a6c9fSPeter Zijlstra if (owner.pid && !pid) 299ba0a6c9fSPeter Zijlstra ret = -ESRCH; 300ba0a6c9fSPeter Zijlstra else 301ba0a6c9fSPeter Zijlstra ret = __f_setown(filp, pid, type, 1); 302ba0a6c9fSPeter Zijlstra rcu_read_unlock(); 303ba0a6c9fSPeter Zijlstra 304ba0a6c9fSPeter Zijlstra return ret; 305ba0a6c9fSPeter Zijlstra } 306ba0a6c9fSPeter Zijlstra 307ba0a6c9fSPeter Zijlstra static int f_getown_ex(struct file *filp, unsigned long arg) 308ba0a6c9fSPeter Zijlstra { 309ba0a6c9fSPeter Zijlstra struct f_owner_ex * __user owner_p = (void * __user)arg; 310ba0a6c9fSPeter Zijlstra struct f_owner_ex owner; 311ba0a6c9fSPeter Zijlstra int ret = 0; 312ba0a6c9fSPeter Zijlstra 313ba0a6c9fSPeter Zijlstra read_lock(&filp->f_owner.lock); 314ba0a6c9fSPeter Zijlstra owner.pid = pid_vnr(filp->f_owner.pid); 315ba0a6c9fSPeter Zijlstra switch (filp->f_owner.pid_type) { 316ba0a6c9fSPeter Zijlstra case PIDTYPE_MAX: 317ba0a6c9fSPeter Zijlstra owner.type = F_OWNER_TID; 318ba0a6c9fSPeter Zijlstra break; 319ba0a6c9fSPeter Zijlstra 320ba0a6c9fSPeter Zijlstra case PIDTYPE_PID: 321ba0a6c9fSPeter Zijlstra owner.type = F_OWNER_PID; 322ba0a6c9fSPeter Zijlstra break; 323ba0a6c9fSPeter Zijlstra 324ba0a6c9fSPeter Zijlstra case PIDTYPE_PGID: 325978b4053SPeter Zijlstra owner.type = F_OWNER_PGRP; 326ba0a6c9fSPeter Zijlstra break; 327ba0a6c9fSPeter Zijlstra 328ba0a6c9fSPeter Zijlstra default: 329ba0a6c9fSPeter Zijlstra WARN_ON(1); 330ba0a6c9fSPeter Zijlstra ret = -EINVAL; 331ba0a6c9fSPeter Zijlstra break; 332ba0a6c9fSPeter Zijlstra } 333ba0a6c9fSPeter Zijlstra read_unlock(&filp->f_owner.lock); 334ba0a6c9fSPeter Zijlstra 3355b54470dSDan Carpenter if (!ret) { 336ba0a6c9fSPeter Zijlstra ret = copy_to_user(owner_p, &owner, sizeof(owner)); 3375b54470dSDan Carpenter if (ret) 3385b54470dSDan Carpenter ret = -EFAULT; 3395b54470dSDan Carpenter } 340ba0a6c9fSPeter Zijlstra return ret; 341ba0a6c9fSPeter Zijlstra } 342ba0a6c9fSPeter Zijlstra 3431da177e4SLinus Torvalds static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, 3441da177e4SLinus Torvalds struct file *filp) 3451da177e4SLinus Torvalds { 3461da177e4SLinus Torvalds long err = -EINVAL; 3471da177e4SLinus Torvalds 3481da177e4SLinus Torvalds switch (cmd) { 3491da177e4SLinus Torvalds case F_DUPFD: 35022d2b35bSUlrich Drepper case F_DUPFD_CLOEXEC: 351d554ed89SJiri Slaby if (arg >= rlimit(RLIMIT_NOFILE)) 3524e1e018eSAl Viro break; 3531027abe8SAl Viro err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0); 3541027abe8SAl Viro if (err >= 0) { 3551da177e4SLinus Torvalds get_file(filp); 3561027abe8SAl Viro fd_install(err, filp); 3571027abe8SAl Viro } 3581da177e4SLinus Torvalds break; 3591da177e4SLinus Torvalds case F_GETFD: 3601da177e4SLinus Torvalds err = get_close_on_exec(fd) ? FD_CLOEXEC : 0; 3611da177e4SLinus Torvalds break; 3621da177e4SLinus Torvalds case F_SETFD: 3631da177e4SLinus Torvalds err = 0; 3641da177e4SLinus Torvalds set_close_on_exec(fd, arg & FD_CLOEXEC); 3651da177e4SLinus Torvalds break; 3661da177e4SLinus Torvalds case F_GETFL: 3671da177e4SLinus Torvalds err = filp->f_flags; 3681da177e4SLinus Torvalds break; 3691da177e4SLinus Torvalds case F_SETFL: 3701da177e4SLinus Torvalds err = setfl(fd, filp, arg); 3711da177e4SLinus Torvalds break; 3721da177e4SLinus Torvalds case F_GETLK: 3731da177e4SLinus Torvalds err = fcntl_getlk(filp, (struct flock __user *) arg); 3741da177e4SLinus Torvalds break; 3751da177e4SLinus Torvalds case F_SETLK: 3761da177e4SLinus Torvalds case F_SETLKW: 377c293621bSPeter Staubach err = fcntl_setlk(fd, filp, cmd, (struct flock __user *) arg); 3781da177e4SLinus Torvalds break; 3791da177e4SLinus Torvalds case F_GETOWN: 3801da177e4SLinus Torvalds /* 3811da177e4SLinus Torvalds * XXX If f_owner is a process group, the 3821da177e4SLinus Torvalds * negative return value will get converted 3831da177e4SLinus Torvalds * into an error. Oops. If we keep the 3841da177e4SLinus Torvalds * current syscall conventions, the only way 3851da177e4SLinus Torvalds * to fix this will be in libc. 3861da177e4SLinus Torvalds */ 387609d7fa9SEric W. Biederman err = f_getown(filp); 3881da177e4SLinus Torvalds force_successful_syscall_return(); 3891da177e4SLinus Torvalds break; 3901da177e4SLinus Torvalds case F_SETOWN: 3911da177e4SLinus Torvalds err = f_setown(filp, arg, 1); 3921da177e4SLinus Torvalds break; 393ba0a6c9fSPeter Zijlstra case F_GETOWN_EX: 394ba0a6c9fSPeter Zijlstra err = f_getown_ex(filp, arg); 395ba0a6c9fSPeter Zijlstra break; 396ba0a6c9fSPeter Zijlstra case F_SETOWN_EX: 397ba0a6c9fSPeter Zijlstra err = f_setown_ex(filp, arg); 398ba0a6c9fSPeter Zijlstra break; 3991da177e4SLinus Torvalds case F_GETSIG: 4001da177e4SLinus Torvalds err = filp->f_owner.signum; 4011da177e4SLinus Torvalds break; 4021da177e4SLinus Torvalds case F_SETSIG: 4031da177e4SLinus Torvalds /* arg == 0 restores default behaviour. */ 4047ed20e1aSJesper Juhl if (!valid_signal(arg)) { 4051da177e4SLinus Torvalds break; 4061da177e4SLinus Torvalds } 4071da177e4SLinus Torvalds err = 0; 4081da177e4SLinus Torvalds filp->f_owner.signum = arg; 4091da177e4SLinus Torvalds break; 4101da177e4SLinus Torvalds case F_GETLEASE: 4111da177e4SLinus Torvalds err = fcntl_getlease(filp); 4121da177e4SLinus Torvalds break; 4131da177e4SLinus Torvalds case F_SETLEASE: 4141da177e4SLinus Torvalds err = fcntl_setlease(fd, filp, arg); 4151da177e4SLinus Torvalds break; 4161da177e4SLinus Torvalds case F_NOTIFY: 4171da177e4SLinus Torvalds err = fcntl_dirnotify(fd, filp, arg); 4181da177e4SLinus Torvalds break; 41935f3d14dSJens Axboe case F_SETPIPE_SZ: 42035f3d14dSJens Axboe case F_GETPIPE_SZ: 42135f3d14dSJens Axboe err = pipe_fcntl(filp, cmd, arg); 42235f3d14dSJens Axboe break; 4231da177e4SLinus Torvalds default: 4241da177e4SLinus Torvalds break; 4251da177e4SLinus Torvalds } 4261da177e4SLinus Torvalds return err; 4271da177e4SLinus Torvalds } 4281da177e4SLinus Torvalds 429a26eab24SHeiko Carstens SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) 4301da177e4SLinus Torvalds { 4311da177e4SLinus Torvalds struct file *filp; 4321da177e4SLinus Torvalds long err = -EBADF; 4331da177e4SLinus Torvalds 4341da177e4SLinus Torvalds filp = fget(fd); 4351da177e4SLinus Torvalds if (!filp) 4361da177e4SLinus Torvalds goto out; 4371da177e4SLinus Torvalds 4381da177e4SLinus Torvalds err = security_file_fcntl(filp, cmd, arg); 4391da177e4SLinus Torvalds if (err) { 4401da177e4SLinus Torvalds fput(filp); 4411da177e4SLinus Torvalds return err; 4421da177e4SLinus Torvalds } 4431da177e4SLinus Torvalds 4441da177e4SLinus Torvalds err = do_fcntl(fd, cmd, arg, filp); 4451da177e4SLinus Torvalds 4461da177e4SLinus Torvalds fput(filp); 4471da177e4SLinus Torvalds out: 4481da177e4SLinus Torvalds return err; 4491da177e4SLinus Torvalds } 4501da177e4SLinus Torvalds 4511da177e4SLinus Torvalds #if BITS_PER_LONG == 32 452a26eab24SHeiko Carstens SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, 453a26eab24SHeiko Carstens unsigned long, arg) 4541da177e4SLinus Torvalds { 4551da177e4SLinus Torvalds struct file * filp; 4561da177e4SLinus Torvalds long err; 4571da177e4SLinus Torvalds 4581da177e4SLinus Torvalds err = -EBADF; 4591da177e4SLinus Torvalds filp = fget(fd); 4601da177e4SLinus Torvalds if (!filp) 4611da177e4SLinus Torvalds goto out; 4621da177e4SLinus Torvalds 4631da177e4SLinus Torvalds err = security_file_fcntl(filp, cmd, arg); 4641da177e4SLinus Torvalds if (err) { 4651da177e4SLinus Torvalds fput(filp); 4661da177e4SLinus Torvalds return err; 4671da177e4SLinus Torvalds } 4681da177e4SLinus Torvalds err = -EBADF; 4691da177e4SLinus Torvalds 4701da177e4SLinus Torvalds switch (cmd) { 4711da177e4SLinus Torvalds case F_GETLK64: 4721da177e4SLinus Torvalds err = fcntl_getlk64(filp, (struct flock64 __user *) arg); 4731da177e4SLinus Torvalds break; 4741da177e4SLinus Torvalds case F_SETLK64: 4751da177e4SLinus Torvalds case F_SETLKW64: 476c293621bSPeter Staubach err = fcntl_setlk64(fd, filp, cmd, 477c293621bSPeter Staubach (struct flock64 __user *) arg); 4781da177e4SLinus Torvalds break; 4791da177e4SLinus Torvalds default: 4801da177e4SLinus Torvalds err = do_fcntl(fd, cmd, arg, filp); 4811da177e4SLinus Torvalds break; 4821da177e4SLinus Torvalds } 4831da177e4SLinus Torvalds fput(filp); 4841da177e4SLinus Torvalds out: 4851da177e4SLinus Torvalds return err; 4861da177e4SLinus Torvalds } 4871da177e4SLinus Torvalds #endif 4881da177e4SLinus Torvalds 4891da177e4SLinus Torvalds /* Table to convert sigio signal codes into poll band bitmaps */ 4901da177e4SLinus Torvalds 491fa3536ccSEric Dumazet static const long band_table[NSIGPOLL] = { 4921da177e4SLinus Torvalds POLLIN | POLLRDNORM, /* POLL_IN */ 4931da177e4SLinus Torvalds POLLOUT | POLLWRNORM | POLLWRBAND, /* POLL_OUT */ 4941da177e4SLinus Torvalds POLLIN | POLLRDNORM | POLLMSG, /* POLL_MSG */ 4951da177e4SLinus Torvalds POLLERR, /* POLL_ERR */ 4961da177e4SLinus Torvalds POLLPRI | POLLRDBAND, /* POLL_PRI */ 4971da177e4SLinus Torvalds POLLHUP | POLLERR /* POLL_HUP */ 4981da177e4SLinus Torvalds }; 4991da177e4SLinus Torvalds 5001da177e4SLinus Torvalds static inline int sigio_perm(struct task_struct *p, 5011da177e4SLinus Torvalds struct fown_struct *fown, int sig) 5021da177e4SLinus Torvalds { 503c69e8d9cSDavid Howells const struct cred *cred; 504c69e8d9cSDavid Howells int ret; 505c69e8d9cSDavid Howells 506c69e8d9cSDavid Howells rcu_read_lock(); 507c69e8d9cSDavid Howells cred = __task_cred(p); 508c69e8d9cSDavid Howells ret = ((fown->euid == 0 || 509c69e8d9cSDavid Howells fown->euid == cred->suid || fown->euid == cred->uid || 510c69e8d9cSDavid Howells fown->uid == cred->suid || fown->uid == cred->uid) && 5111da177e4SLinus Torvalds !security_file_send_sigiotask(p, fown, sig)); 512c69e8d9cSDavid Howells rcu_read_unlock(); 513c69e8d9cSDavid Howells return ret; 5141da177e4SLinus Torvalds } 5151da177e4SLinus Torvalds 5161da177e4SLinus Torvalds static void send_sigio_to_task(struct task_struct *p, 5171da177e4SLinus Torvalds struct fown_struct *fown, 518ba0a6c9fSPeter Zijlstra int fd, int reason, int group) 5191da177e4SLinus Torvalds { 5208eeee4e2SOleg Nesterov /* 5218eeee4e2SOleg Nesterov * F_SETSIG can change ->signum lockless in parallel, make 5228eeee4e2SOleg Nesterov * sure we read it once and use the same value throughout. 5238eeee4e2SOleg Nesterov */ 5248eeee4e2SOleg Nesterov int signum = ACCESS_ONCE(fown->signum); 5258eeee4e2SOleg Nesterov 5268eeee4e2SOleg Nesterov if (!sigio_perm(p, fown, signum)) 5271da177e4SLinus Torvalds return; 5281da177e4SLinus Torvalds 5298eeee4e2SOleg Nesterov switch (signum) { 5301da177e4SLinus Torvalds siginfo_t si; 5311da177e4SLinus Torvalds default: 5321da177e4SLinus Torvalds /* Queue a rt signal with the appropriate fd as its 5331da177e4SLinus Torvalds value. We use SI_SIGIO as the source, not 5341da177e4SLinus Torvalds SI_KERNEL, since kernel signals always get 5351da177e4SLinus Torvalds delivered even if we can't queue. Failure to 5361da177e4SLinus Torvalds queue in this case _should_ be reported; we fall 5371da177e4SLinus Torvalds back to SIGIO in that case. --sct */ 5388eeee4e2SOleg Nesterov si.si_signo = signum; 5391da177e4SLinus Torvalds si.si_errno = 0; 5401da177e4SLinus Torvalds si.si_code = reason; 5411da177e4SLinus Torvalds /* Make sure we are called with one of the POLL_* 5421da177e4SLinus Torvalds reasons, otherwise we could leak kernel stack into 5431da177e4SLinus Torvalds userspace. */ 544f6298aabSEric Sesterhenn BUG_ON((reason & __SI_MASK) != __SI_POLL); 5451da177e4SLinus Torvalds if (reason - POLL_IN >= NSIGPOLL) 5461da177e4SLinus Torvalds si.si_band = ~0L; 5471da177e4SLinus Torvalds else 5481da177e4SLinus Torvalds si.si_band = band_table[reason - POLL_IN]; 5491da177e4SLinus Torvalds si.si_fd = fd; 550ba0a6c9fSPeter Zijlstra if (!do_send_sig_info(signum, &si, p, group)) 5511da177e4SLinus Torvalds break; 5521da177e4SLinus Torvalds /* fall-through: fall back on the old plain SIGIO signal */ 5531da177e4SLinus Torvalds case 0: 554ba0a6c9fSPeter Zijlstra do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, group); 5551da177e4SLinus Torvalds } 5561da177e4SLinus Torvalds } 5571da177e4SLinus Torvalds 5581da177e4SLinus Torvalds void send_sigio(struct fown_struct *fown, int fd, int band) 5591da177e4SLinus Torvalds { 5601da177e4SLinus Torvalds struct task_struct *p; 561609d7fa9SEric W. Biederman enum pid_type type; 562609d7fa9SEric W. Biederman struct pid *pid; 563ba0a6c9fSPeter Zijlstra int group = 1; 5641da177e4SLinus Torvalds 5651da177e4SLinus Torvalds read_lock(&fown->lock); 566ba0a6c9fSPeter Zijlstra 567609d7fa9SEric W. Biederman type = fown->pid_type; 568ba0a6c9fSPeter Zijlstra if (type == PIDTYPE_MAX) { 569ba0a6c9fSPeter Zijlstra group = 0; 570ba0a6c9fSPeter Zijlstra type = PIDTYPE_PID; 571ba0a6c9fSPeter Zijlstra } 572ba0a6c9fSPeter Zijlstra 5731da177e4SLinus Torvalds pid = fown->pid; 5741da177e4SLinus Torvalds if (!pid) 5751da177e4SLinus Torvalds goto out_unlock_fown; 5761da177e4SLinus Torvalds 5771da177e4SLinus Torvalds read_lock(&tasklist_lock); 578609d7fa9SEric W. Biederman do_each_pid_task(pid, type, p) { 579ba0a6c9fSPeter Zijlstra send_sigio_to_task(p, fown, fd, band, group); 580609d7fa9SEric W. Biederman } while_each_pid_task(pid, type, p); 5811da177e4SLinus Torvalds read_unlock(&tasklist_lock); 5821da177e4SLinus Torvalds out_unlock_fown: 5831da177e4SLinus Torvalds read_unlock(&fown->lock); 5841da177e4SLinus Torvalds } 5851da177e4SLinus Torvalds 5861da177e4SLinus Torvalds static void send_sigurg_to_task(struct task_struct *p, 587ba0a6c9fSPeter Zijlstra struct fown_struct *fown, int group) 5881da177e4SLinus Torvalds { 5891da177e4SLinus Torvalds if (sigio_perm(p, fown, SIGURG)) 590ba0a6c9fSPeter Zijlstra do_send_sig_info(SIGURG, SEND_SIG_PRIV, p, group); 5911da177e4SLinus Torvalds } 5921da177e4SLinus Torvalds 5931da177e4SLinus Torvalds int send_sigurg(struct fown_struct *fown) 5941da177e4SLinus Torvalds { 5951da177e4SLinus Torvalds struct task_struct *p; 596609d7fa9SEric W. Biederman enum pid_type type; 597609d7fa9SEric W. Biederman struct pid *pid; 598ba0a6c9fSPeter Zijlstra int group = 1; 599609d7fa9SEric W. Biederman int ret = 0; 6001da177e4SLinus Torvalds 6011da177e4SLinus Torvalds read_lock(&fown->lock); 602ba0a6c9fSPeter Zijlstra 603609d7fa9SEric W. Biederman type = fown->pid_type; 604ba0a6c9fSPeter Zijlstra if (type == PIDTYPE_MAX) { 605ba0a6c9fSPeter Zijlstra group = 0; 606ba0a6c9fSPeter Zijlstra type = PIDTYPE_PID; 607ba0a6c9fSPeter Zijlstra } 608ba0a6c9fSPeter Zijlstra 6091da177e4SLinus Torvalds pid = fown->pid; 6101da177e4SLinus Torvalds if (!pid) 6111da177e4SLinus Torvalds goto out_unlock_fown; 6121da177e4SLinus Torvalds 6131da177e4SLinus Torvalds ret = 1; 6141da177e4SLinus Torvalds 6151da177e4SLinus Torvalds read_lock(&tasklist_lock); 616609d7fa9SEric W. Biederman do_each_pid_task(pid, type, p) { 617ba0a6c9fSPeter Zijlstra send_sigurg_to_task(p, fown, group); 618609d7fa9SEric W. Biederman } while_each_pid_task(pid, type, p); 6191da177e4SLinus Torvalds read_unlock(&tasklist_lock); 6201da177e4SLinus Torvalds out_unlock_fown: 6211da177e4SLinus Torvalds read_unlock(&fown->lock); 6221da177e4SLinus Torvalds return ret; 6231da177e4SLinus Torvalds } 6241da177e4SLinus Torvalds 625989a2979SEric Dumazet static DEFINE_SPINLOCK(fasync_lock); 626e18b890bSChristoph Lameter static struct kmem_cache *fasync_cache __read_mostly; 6271da177e4SLinus Torvalds 628989a2979SEric Dumazet static void fasync_free_rcu(struct rcu_head *head) 629989a2979SEric Dumazet { 630989a2979SEric Dumazet kmem_cache_free(fasync_cache, 631989a2979SEric Dumazet container_of(head, struct fasync_struct, fa_rcu)); 632989a2979SEric Dumazet } 633989a2979SEric Dumazet 6341da177e4SLinus Torvalds /* 63553281b6dSLinus Torvalds * Remove a fasync entry. If successfully removed, return 63653281b6dSLinus Torvalds * positive and clear the FASYNC flag. If no entry exists, 63753281b6dSLinus Torvalds * do nothing and return 0. 63853281b6dSLinus Torvalds * 63953281b6dSLinus Torvalds * NOTE! It is very important that the FASYNC flag always 64053281b6dSLinus Torvalds * match the state "is the filp on a fasync list". 64153281b6dSLinus Torvalds * 6421da177e4SLinus Torvalds */ 64353281b6dSLinus Torvalds static int fasync_remove_entry(struct file *filp, struct fasync_struct **fapp) 6441da177e4SLinus Torvalds { 6451da177e4SLinus Torvalds struct fasync_struct *fa, **fp; 6461da177e4SLinus Torvalds int result = 0; 6471da177e4SLinus Torvalds 6484a6a4499SJonathan Corbet spin_lock(&filp->f_lock); 649989a2979SEric Dumazet spin_lock(&fasync_lock); 6501da177e4SLinus Torvalds for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) { 65153281b6dSLinus Torvalds if (fa->fa_file != filp) 65253281b6dSLinus Torvalds continue; 653989a2979SEric Dumazet 654989a2979SEric Dumazet spin_lock_irq(&fa->fa_lock); 655989a2979SEric Dumazet fa->fa_file = NULL; 656989a2979SEric Dumazet spin_unlock_irq(&fa->fa_lock); 657989a2979SEric Dumazet 6581da177e4SLinus Torvalds *fp = fa->fa_next; 659989a2979SEric Dumazet call_rcu(&fa->fa_rcu, fasync_free_rcu); 66053281b6dSLinus Torvalds filp->f_flags &= ~FASYNC; 6611da177e4SLinus Torvalds result = 1; 66253281b6dSLinus Torvalds break; 6631da177e4SLinus Torvalds } 664989a2979SEric Dumazet spin_unlock(&fasync_lock); 66553281b6dSLinus Torvalds spin_unlock(&filp->f_lock); 66653281b6dSLinus Torvalds return result; 6671da177e4SLinus Torvalds } 6681da177e4SLinus Torvalds 66953281b6dSLinus Torvalds /* 67053281b6dSLinus Torvalds * Add a fasync entry. Return negative on error, positive if 67153281b6dSLinus Torvalds * added, and zero if did nothing but change an existing one. 67253281b6dSLinus Torvalds * 67353281b6dSLinus Torvalds * NOTE! It is very important that the FASYNC flag always 67453281b6dSLinus Torvalds * match the state "is the filp on a fasync list". 67553281b6dSLinus Torvalds */ 67653281b6dSLinus Torvalds static int fasync_add_entry(int fd, struct file *filp, struct fasync_struct **fapp) 67753281b6dSLinus Torvalds { 67853281b6dSLinus Torvalds struct fasync_struct *new, *fa, **fp; 67953281b6dSLinus Torvalds int result = 0; 68053281b6dSLinus Torvalds 68153281b6dSLinus Torvalds new = kmem_cache_alloc(fasync_cache, GFP_KERNEL); 68253281b6dSLinus Torvalds if (!new) 68353281b6dSLinus Torvalds return -ENOMEM; 68453281b6dSLinus Torvalds 68553281b6dSLinus Torvalds spin_lock(&filp->f_lock); 686989a2979SEric Dumazet spin_lock(&fasync_lock); 68753281b6dSLinus Torvalds for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) { 68853281b6dSLinus Torvalds if (fa->fa_file != filp) 68953281b6dSLinus Torvalds continue; 690989a2979SEric Dumazet 691989a2979SEric Dumazet spin_lock_irq(&fa->fa_lock); 69253281b6dSLinus Torvalds fa->fa_fd = fd; 693989a2979SEric Dumazet spin_unlock_irq(&fa->fa_lock); 694989a2979SEric Dumazet 69553281b6dSLinus Torvalds kmem_cache_free(fasync_cache, new); 69653281b6dSLinus Torvalds goto out; 69753281b6dSLinus Torvalds } 69853281b6dSLinus Torvalds 699989a2979SEric Dumazet spin_lock_init(&new->fa_lock); 7001da177e4SLinus Torvalds new->magic = FASYNC_MAGIC; 7011da177e4SLinus Torvalds new->fa_file = filp; 7021da177e4SLinus Torvalds new->fa_fd = fd; 7031da177e4SLinus Torvalds new->fa_next = *fapp; 704989a2979SEric Dumazet rcu_assign_pointer(*fapp, new); 7051da177e4SLinus Torvalds result = 1; 70676398425SJonathan Corbet filp->f_flags |= FASYNC; 70753281b6dSLinus Torvalds 70853281b6dSLinus Torvalds out: 709989a2979SEric Dumazet spin_unlock(&fasync_lock); 7104a6a4499SJonathan Corbet spin_unlock(&filp->f_lock); 7111da177e4SLinus Torvalds return result; 7121da177e4SLinus Torvalds } 7131da177e4SLinus Torvalds 71453281b6dSLinus Torvalds /* 71553281b6dSLinus Torvalds * fasync_helper() is used by almost all character device drivers 71653281b6dSLinus Torvalds * to set up the fasync queue, and for regular files by the file 71753281b6dSLinus Torvalds * lease code. It returns negative on error, 0 if it did no changes 71853281b6dSLinus Torvalds * and positive if it added/deleted the entry. 71953281b6dSLinus Torvalds */ 72053281b6dSLinus Torvalds int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp) 72153281b6dSLinus Torvalds { 72253281b6dSLinus Torvalds if (!on) 72353281b6dSLinus Torvalds return fasync_remove_entry(filp, fapp); 72453281b6dSLinus Torvalds return fasync_add_entry(fd, filp, fapp); 72553281b6dSLinus Torvalds } 72653281b6dSLinus Torvalds 7271da177e4SLinus Torvalds EXPORT_SYMBOL(fasync_helper); 7281da177e4SLinus Torvalds 729989a2979SEric Dumazet /* 730989a2979SEric Dumazet * rcu_read_lock() is held 731989a2979SEric Dumazet */ 732989a2979SEric Dumazet static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band) 7331da177e4SLinus Torvalds { 7341da177e4SLinus Torvalds while (fa) { 7351da177e4SLinus Torvalds struct fown_struct *fown; 736f4985dc7SAndrew Morton unsigned long flags; 737f4985dc7SAndrew Morton 7381da177e4SLinus Torvalds if (fa->magic != FASYNC_MAGIC) { 7391da177e4SLinus Torvalds printk(KERN_ERR "kill_fasync: bad magic number in " 7401da177e4SLinus Torvalds "fasync_struct!\n"); 7411da177e4SLinus Torvalds return; 7421da177e4SLinus Torvalds } 743f4985dc7SAndrew Morton spin_lock_irqsave(&fa->fa_lock, flags); 744989a2979SEric Dumazet if (fa->fa_file) { 7451da177e4SLinus Torvalds fown = &fa->fa_file->f_owner; 7461da177e4SLinus Torvalds /* Don't send SIGURG to processes which have not set a 7471da177e4SLinus Torvalds queued signum: SIGURG has its own default signalling 7481da177e4SLinus Torvalds mechanism. */ 7491da177e4SLinus Torvalds if (!(sig == SIGURG && fown->signum == 0)) 7501da177e4SLinus Torvalds send_sigio(fown, fa->fa_fd, band); 751989a2979SEric Dumazet } 752f4985dc7SAndrew Morton spin_unlock_irqrestore(&fa->fa_lock, flags); 753989a2979SEric Dumazet fa = rcu_dereference(fa->fa_next); 7541da177e4SLinus Torvalds } 7551da177e4SLinus Torvalds } 7561da177e4SLinus Torvalds 7571da177e4SLinus Torvalds void kill_fasync(struct fasync_struct **fp, int sig, int band) 7581da177e4SLinus Torvalds { 7591da177e4SLinus Torvalds /* First a quick test without locking: usually 7601da177e4SLinus Torvalds * the list is empty. 7611da177e4SLinus Torvalds */ 7621da177e4SLinus Torvalds if (*fp) { 763989a2979SEric Dumazet rcu_read_lock(); 764989a2979SEric Dumazet kill_fasync_rcu(rcu_dereference(*fp), sig, band); 765989a2979SEric Dumazet rcu_read_unlock(); 7661da177e4SLinus Torvalds } 7671da177e4SLinus Torvalds } 7681da177e4SLinus Torvalds EXPORT_SYMBOL(kill_fasync); 7691da177e4SLinus Torvalds 770454eedb8SWu Fengguang static int __init fcntl_init(void) 7711da177e4SLinus Torvalds { 772*3ab04d5cSJames Bottomley /* 773*3ab04d5cSJames Bottomley * Please add new bits here to ensure allocation uniqueness. 774*3ab04d5cSJames Bottomley * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY 775*3ab04d5cSJames Bottomley * is defined as O_NONBLOCK on some platforms and not on others. 776*3ab04d5cSJames Bottomley */ 777*3ab04d5cSJames Bottomley BUILD_BUG_ON(18 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( 778454eedb8SWu Fengguang O_RDONLY | O_WRONLY | O_RDWR | 779454eedb8SWu Fengguang O_CREAT | O_EXCL | O_NOCTTY | 780*3ab04d5cSJames Bottomley O_TRUNC | O_APPEND | /* O_NONBLOCK | */ 781454eedb8SWu Fengguang __O_SYNC | O_DSYNC | FASYNC | 782454eedb8SWu Fengguang O_DIRECT | O_LARGEFILE | O_DIRECTORY | 783454eedb8SWu Fengguang O_NOFOLLOW | O_NOATIME | O_CLOEXEC | 784454eedb8SWu Fengguang FMODE_EXEC 785454eedb8SWu Fengguang )); 786454eedb8SWu Fengguang 7871da177e4SLinus Torvalds fasync_cache = kmem_cache_create("fasync_cache", 78820c2df83SPaul Mundt sizeof(struct fasync_struct), 0, SLAB_PANIC, NULL); 7891da177e4SLinus Torvalds return 0; 7901da177e4SLinus Torvalds } 7911da177e4SLinus Torvalds 792454eedb8SWu Fengguang module_init(fcntl_init) 793