Al Viro viro@zeniv.linux.org.uk wrote:
Umm... That's going to be very painful if you dup2() something to MAX_INT and then run that; roughly 2G iterations of bouncing ->file_lock up and down, without anything that would yield CPU in process.
If anything, I would suggest something like
fd = *start_fd; grab the lock fdt = files_fdtable(files); more: look for the next eviction candidate in ->open_fds, starting at fd if there's none up to max_fd drop the lock return NULL *start_fd = fd + 1; if the fscker is really opened and not just reserved rcu_assign_pointer(fdt->fd[fd], NULL); __put_unused_fd(files, fd); drop the lock return the file we'd got if (unlikely(need_resched())) drop lock cond_resched(); grab lock fdt = files_fdtable(files); goto more;
with the main loop being basically while ((file = pick_next(files, &start_fd, max_fd)) != NULL) filp_close(file, files);
If we can live with close_from(int first) rather than close_range(), then this can perhaps be done a lot more efficiently by:
new = alloc_fdtable(first); spin_lock(&files->file_lock); old = files_fdtable(files); copy_fds(new, old, 0, first - 1); rcu_assign_pointer(files->fdt, new); spin_unlock(&files->file_lock); clear_fds(old, 0, first - 1); close_fdt_from(old, first); kfree_rcu(old);
David