diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/file.c | 10 |
1 files changed, 8 insertions, 2 deletions
@@ -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(); |
667 | loop: | ||
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 | ||