diff --git a/fs/file.c b/fs/file.c index 34d8d09756e5..07bdf5bb93a6 100644 --- a/fs/file.c +++ b/fs/file.c @@ -944,6 +944,27 @@ struct file *fget_task(struct task_struct *task, unsigned int fd) return file; } +struct file *task_lookup_next_fd_rcu(struct task_struct *task, unsigned int *ret_fd) +{ + /* Must be called with rcu_read_lock held */ + struct files_struct *files; + unsigned int fd = *ret_fd; + struct file *file = NULL; + + task_lock(task); + files = task->files; + if (files) { + for (; fd < files_fdtable(files)->max_fds; fd++) { + file = files_lookup_fd_rcu(files, fd); + if (file) + break; + } + } + task_unlock(task); + *ret_fd = fd; + return file; +} + /* * Lightweight file lookup - no refcnt increment if fd table isn't shared. * diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index 54d3df973c34..6627a5350ae9 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -101,6 +101,7 @@ static inline struct file *files_lookup_fd_rcu(struct files_struct *files, unsig * Check whether the specified fd has an open file. */ #define fcheck(fd) files_lookup_fd_rcu(current->files, fd) +struct file *task_lookup_next_fd_rcu(struct task_struct *task, unsigned int *fd); struct task_struct;