xref: /linux/fs/fcntl.c (revision 3ab04d5cf9736b7a4e9dfcf28285d8663b01aa0e)
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