summaryrefslogtreecommitdiffstats
path: root/fs/file.c
diff options
context:
space:
mode:
authorChristian Brauner <christian.brauner@ubuntu.com>2021-04-02 10:38:09 +0200
committerChristian Brauner <christian.brauner@ubuntu.com>2021-04-02 14:11:10 +0200
commit03ba0fe4d09f2eb0a91888caaa057ed67462ae2d (patch)
tree6df62d8ad78bb35a18d6361ffbc0d183f687da28 /fs/file.c
parentfile: let pick_file() tell caller it's done (diff)
downloadlinux-03ba0fe4d09f2eb0a91888caaa057ed67462ae2d.tar.xz
linux-03ba0fe4d09f2eb0a91888caaa057ed67462ae2d.zip
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: Christian Brauner <christian.brauner@ubuntu.com>
Diffstat (limited to 'fs/file.c')
-rw-r--r--fs/file.c31
1 files changed, 14 insertions, 17 deletions
diff --git a/fs/file.c b/fs/file.c
index 740040346a98..ed46cd3ae225 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -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) && (max_fd >= cur_max))
- max_unshare_fds = fd;
+ 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.
+ */
+ 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