VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
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:
fs/file.c: __fget() and dup2() atomicity rules
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();