Unverified Commit 03ba0fe4 authored by Christian Brauner's avatar Christian Brauner
Browse files

file: simplify logic in __close_range()



It never looked too pleasant and it doesn't really buy us anything
anymore now that CLOSE_RANGE_CLOEXEC exists and we need to retake the
current maximum under the lock for it anyway. This also makes the logic
easier to follow.

Cc: Christoph Hellwig <hch@lst.de>
Cc: Giuseppe Scrivano <gscrivan@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: default avatarChristian Brauner <christian.brauner@ubuntu.com>
parent f49fd6d3
Loading
Loading
Loading
Loading
+14 −17
Original line number Diff line number Diff line
@@ -701,7 +701,6 @@ static inline void __range_close(struct files_struct *cur_fds, unsigned int fd,
 */
int __close_range(unsigned fd, unsigned max_fd, unsigned int flags)
{
	unsigned int cur_max;
	struct task_struct *me = current;
	struct files_struct *cur_fds = me->files, *fds = NULL;

@@ -711,26 +710,26 @@ int __close_range(unsigned fd, unsigned max_fd, unsigned int flags)
	if (fd > max_fd)
		return -EINVAL;

	rcu_read_lock();
	cur_max = files_fdtable(cur_fds)->max_fds;
	rcu_read_unlock();

	/* cap to last valid index into fdtable */
	cur_max--;

	if (flags & CLOSE_RANGE_UNSHARE) {
		int ret;
		unsigned int max_unshare_fds = NR_OPEN_MAX;

		/*
		 * If the requested range is greater than the current maximum,
		 * we're closing everything so only copy all file descriptors
		 * beneath the lowest file descriptor.
		 * If the caller requested all fds to be made cloexec copy all
		 * of the file descriptors since they still want to use them.
		 * If the caller requested all fds to be made cloexec we always
		 * copy all of the file descriptors since they still want to
		 * use them.
		 */
		if (!(flags & CLOSE_RANGE_CLOEXEC)) {
			/*
			 * If the requested range is greater than the current
			 * maximum, we're closing everything so only copy all
			 * file descriptors beneath the lowest file descriptor.
			 */
		if (!(flags & CLOSE_RANGE_CLOEXEC) && (max_fd >= cur_max))
			rcu_read_lock();
			if (max_fd >= last_fd(files_fdtable(cur_fds)))
				max_unshare_fds = fd;
			rcu_read_unlock();
		}

		ret = unshare_fd(CLONE_FILES, max_unshare_fds, &fds);
		if (ret)
@@ -744,8 +743,6 @@ int __close_range(unsigned fd, unsigned max_fd, unsigned int flags)
			swap(cur_fds, fds);
	}

	max_fd = min(max_fd, cur_max);

	if (flags & CLOSE_RANGE_CLOEXEC)
		__range_cloexec(cur_fds, fd, max_fd);
	else