Use the IDR iteration functionality instead of the open_fds bitmap to call filp_close() for each open file. Also make close_files() return void, because it no longer uses the fdtable. Signed-off-by: Sandhya Bankar <bankarsandhya512@xxxxxxxxx> Signed-off-by: Matthew Wilcox <mawilcox@xxxxxxxxxxxxx> --- fs/file.c | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/fs/file.c b/fs/file.c index 8d67968..8cd77c5 100644 --- a/fs/file.c +++ b/fs/file.c @@ -373,37 +373,21 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) return NULL; } -static struct fdtable *close_files(struct files_struct * files) +static void close_files(struct files_struct * files) { /* - * It is safe to dereference the fd table without RCU or - * ->file_lock because this is the last reference to the - * files structure. + * No need for RCU or ->file_lock protection because + * this is the last reference to the files structure. */ - struct fdtable *fdt = rcu_dereference_raw(files->fdt); - unsigned int i, j = 0; + struct file *file; + int fd; - for (;;) { - unsigned long set; - i = j * BITS_PER_LONG; - if (i >= fdt->max_fds) - break; - set = fdt->open_fds[j++]; - while (set) { - if (set & 1) { - struct file *file; - file = idr_remove(&files->fd_idr, i); - if (file) { - filp_close(file, files); - cond_resched_rcu_qs(); - } - } - i++; - set >>= 1; - } + idr_for_each_entry(&files->fd_idr, file, fd) { + filp_close(file, files); + cond_resched_rcu_qs(); } - return fdt; + idr_destroy(&files->fd_idr); } struct files_struct *get_files_struct(struct task_struct *task) @@ -422,7 +406,8 @@ struct files_struct *get_files_struct(struct task_struct *task) void put_files_struct(struct files_struct *files) { if (atomic_dec_and_test(&files->count)) { - struct fdtable *fdt = close_files(files); + struct fdtable *fdt = rcu_dereference_raw(files->fdt); + close_files(files); /* free the arrays if they are not embedded */ if (fdt != &files->fdtab) -- 1.8.3.1