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>
This commit is contained in:
parent
f49fd6d3c0
commit
03ba0fe4d0
31
fs/file.c
31
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)
|
int __close_range(unsigned fd, unsigned max_fd, unsigned int flags)
|
||||||
{
|
{
|
||||||
unsigned int cur_max;
|
|
||||||
struct task_struct *me = current;
|
struct task_struct *me = current;
|
||||||
struct files_struct *cur_fds = me->files, *fds = NULL;
|
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)
|
if (fd > max_fd)
|
||||||
return -EINVAL;
|
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) {
|
if (flags & CLOSE_RANGE_UNSHARE) {
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int max_unshare_fds = NR_OPEN_MAX;
|
unsigned int max_unshare_fds = NR_OPEN_MAX;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the requested range is greater than the current maximum,
|
* If the caller requested all fds to be made cloexec we always
|
||||||
* we're closing everything so only copy all file descriptors
|
* copy all of the file descriptors since they still want to
|
||||||
* beneath the lowest file descriptor.
|
* use them.
|
||||||
* If the caller requested all fds to be made cloexec copy all
|
|
||||||
* of the file descriptors since they still want to use them.
|
|
||||||
*/
|
*/
|
||||||
if (!(flags & CLOSE_RANGE_CLOEXEC) && (max_fd >= cur_max))
|
if (!(flags & CLOSE_RANGE_CLOEXEC)) {
|
||||||
max_unshare_fds = fd;
|
/*
|
||||||
|
* 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);
|
ret = unshare_fd(CLONE_FILES, max_unshare_fds, &fds);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -744,8 +743,6 @@ int __close_range(unsigned fd, unsigned max_fd, unsigned int flags)
|
|||||||
swap(cur_fds, fds);
|
swap(cur_fds, fds);
|
||||||
}
|
}
|
||||||
|
|
||||||
max_fd = min(max_fd, cur_max);
|
|
||||||
|
|
||||||
if (flags & CLOSE_RANGE_CLOEXEC)
|
if (flags & CLOSE_RANGE_CLOEXEC)
|
||||||
__range_cloexec(cur_fds, fd, max_fd);
|
__range_cloexec(cur_fds, fd, max_fd);
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user