Skip to content

Commit f49fd6d

Browse files
author
Christian Brauner
committed
file: let pick_file() tell caller it's done
Let pick_file() report back that the fd it was passed exceeded the maximum fd in that fdtable. This allows us to simplify the caller of this helper because it doesn't need to care anymore whether the passed in max_fd is excessive. It can rely on pick_file() telling it that it's past the last valid fd. Cc: Christoph Hellwig <[email protected]> Cc: Giuseppe Scrivano <[email protected]> Cc: Al Viro <[email protected]> Cc: [email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent 9b5b872 commit f49fd6d

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

fs/file.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -596,18 +596,32 @@ void fd_install(unsigned int fd, struct file *file)
596596

597597
EXPORT_SYMBOL(fd_install);
598598

599+
/**
600+
* pick_file - return file associatd with fd
601+
* @files: file struct to retrieve file from
602+
* @fd: file descriptor to retrieve file for
603+
*
604+
* If this functions returns an EINVAL error pointer the fd was beyond the
605+
* current maximum number of file descriptors for that fdtable.
606+
*
607+
* Returns: The file associated with @fd, on error returns an error pointer.
608+
*/
599609
static struct file *pick_file(struct files_struct *files, unsigned fd)
600610
{
601-
struct file *file = NULL;
611+
struct file *file;
602612
struct fdtable *fdt;
603613

604614
spin_lock(&files->file_lock);
605615
fdt = files_fdtable(files);
606-
if (fd >= fdt->max_fds)
616+
if (fd >= fdt->max_fds) {
617+
file = ERR_PTR(-EINVAL);
607618
goto out_unlock;
619+
}
608620
file = fdt->fd[fd];
609-
if (!file)
621+
if (!file) {
622+
file = ERR_PTR(-EBADF);
610623
goto out_unlock;
624+
}
611625
rcu_assign_pointer(fdt->fd[fd], NULL);
612626
__put_unused_fd(files, fd);
613627

@@ -622,7 +636,7 @@ int close_fd(unsigned fd)
622636
struct file *file;
623637

624638
file = pick_file(files, fd);
625-
if (!file)
639+
if (IS_ERR(file))
626640
return -EBADF;
627641

628642
return filp_close(file, files);
@@ -663,11 +677,16 @@ static inline void __range_close(struct files_struct *cur_fds, unsigned int fd,
663677
struct file *file;
664678

665679
file = pick_file(cur_fds, fd++);
666-
if (!file)
680+
if (!IS_ERR(file)) {
681+
/* found a valid file to close */
682+
filp_close(file, cur_fds);
683+
cond_resched();
667684
continue;
685+
}
668686

669-
filp_close(file, cur_fds);
670-
cond_resched();
687+
/* beyond the last fd in that table */
688+
if (PTR_ERR(file) == -EINVAL)
689+
return;
671690
}
672691
}
673692

0 commit comments

Comments
 (0)