author: Eric Dumazet <edumazet@google.com> 2015-06-29 17:10:30 +0200
committer: Al Viro <viro@zeniv.linux.org.uk> 2015-07-01 02:31:08 -0400
commit: 5ba97d2832f87943c43bb69cb1ef86dbc59df5bc
parent: 8a81252b774b53e628a8a0fe18e2b8fc236d92cc
Commit Summary:
Diffstat:
1 file changed, 8 insertions, 2 deletions
diff --git a/fs/file.c b/fs/file.c
index 3d2eb4c542a4..6c672ad329e9 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -664,11 +664,17 @@ static struct file *__fget(unsigned int fd, fmode_t mask)
struct file *file;
rcu_read_lock();
+loop:
file = fcheck_files(files, fd);
if (file) {
- /* File object ref couldn't be taken */
- if ((file->f_mode & mask) || !get_file_rcu(file))
+ /* File object ref couldn't be taken.
+ * dup2() atomicity guarantee is the reason
+ * we loop to catch the new file (or NULL pointer)
+ */
+ if (file->f_mode & mask)
file = NULL;
+ else if (!get_file_rcu(file))
+ goto loop;
}
rcu_read_unlock();