diff options
Diffstat (limited to 'fs/userfaultfd.c')
-rw-r--r-- | fs/userfaultfd.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index ccbdbd62f0d8..fe6d804a38dc 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c | |||
@@ -880,6 +880,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file) | |||
880 | /* len == 0 means wake all */ | 880 | /* len == 0 means wake all */ |
881 | struct userfaultfd_wake_range range = { .len = 0, }; | 881 | struct userfaultfd_wake_range range = { .len = 0, }; |
882 | unsigned long new_flags; | 882 | unsigned long new_flags; |
883 | bool still_valid; | ||
883 | 884 | ||
884 | WRITE_ONCE(ctx->released, true); | 885 | WRITE_ONCE(ctx->released, true); |
885 | 886 | ||
@@ -895,8 +896,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file) | |||
895 | * taking the mmap_sem for writing. | 896 | * taking the mmap_sem for writing. |
896 | */ | 897 | */ |
897 | down_write(&mm->mmap_sem); | 898 | down_write(&mm->mmap_sem); |
898 | if (!mmget_still_valid(mm)) | 899 | still_valid = mmget_still_valid(mm); |
899 | goto skip_mm; | ||
900 | prev = NULL; | 900 | prev = NULL; |
901 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | 901 | for (vma = mm->mmap; vma; vma = vma->vm_next) { |
902 | cond_resched(); | 902 | cond_resched(); |
@@ -907,19 +907,20 @@ static int userfaultfd_release(struct inode *inode, struct file *file) | |||
907 | continue; | 907 | continue; |
908 | } | 908 | } |
909 | new_flags = vma->vm_flags & ~(VM_UFFD_MISSING | VM_UFFD_WP); | 909 | new_flags = vma->vm_flags & ~(VM_UFFD_MISSING | VM_UFFD_WP); |
910 | prev = vma_merge(mm, prev, vma->vm_start, vma->vm_end, | 910 | if (still_valid) { |
911 | new_flags, vma->anon_vma, | 911 | prev = vma_merge(mm, prev, vma->vm_start, vma->vm_end, |
912 | vma->vm_file, vma->vm_pgoff, | 912 | new_flags, vma->anon_vma, |
913 | vma_policy(vma), | 913 | vma->vm_file, vma->vm_pgoff, |
914 | NULL_VM_UFFD_CTX); | 914 | vma_policy(vma), |
915 | if (prev) | 915 | NULL_VM_UFFD_CTX); |
916 | vma = prev; | 916 | if (prev) |
917 | else | 917 | vma = prev; |
918 | prev = vma; | 918 | else |
919 | prev = vma; | ||
920 | } | ||
919 | vma->vm_flags = new_flags; | 921 | vma->vm_flags = new_flags; |
920 | vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX; | 922 | vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX; |
921 | } | 923 | } |
922 | skip_mm: | ||
923 | up_write(&mm->mmap_sem); | 924 | up_write(&mm->mmap_sem); |
924 | mmput(mm); | 925 | mmput(mm); |
925 | wakeup: | 926 | wakeup: |