summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/file.c10
1 files 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)
664 struct file *file; 664 struct file *file;
665 665
666 rcu_read_lock(); 666 rcu_read_lock();
667loop:
667 file = fcheck_files(files, fd); 668 file = fcheck_files(files, fd);
668 if (file) { 669 if (file) {
669 /* File object ref couldn't be taken */ 670 /* File object ref couldn't be taken.
670 if ((file->f_mode & mask) || !get_file_rcu(file)) 671 * dup2() atomicity guarantee is the reason
672 * we loop to catch the new file (or NULL pointer)
673 */
674 if (file->f_mode & mask)
671 file = NULL; 675 file = NULL;
676 else if (!get_file_rcu(file))
677 goto loop;
672 } 678 }
673 rcu_read_unlock(); 679 rcu_read_unlock();
674 680