* Expansion is handled above, merging is handled below.
                 * Drivers should not alter the address of the VMA.
                 */
-               if (WARN_ON((addr != vma->vm_start))) {
-                       error = -EINVAL;
+               error = -EINVAL;
+               if (WARN_ON((addr != vma->vm_start)))
                        goto close_and_free_vma;
-               }
-               vma_iter_set(&vmi, addr);
 
+               vma_iter_set(&vmi, addr);
                /*
                 * If vm_flags changed after call_mmap(), we should try merge
                 * vma again as we may succeed this time.
        }
 
        /* Allow architectures to sanity-check the vm_flags */
-       if (!arch_validate_flags(vma->vm_flags)) {
-               error = -EINVAL;
-               if (file)
-                       goto close_and_free_vma;
-               else if (vma->vm_file)
-                       goto unmap_and_free_vma;
-               else
-                       goto free_vma;
-       }
+       error = -EINVAL;
+       if (!arch_validate_flags(vma->vm_flags))
+               goto close_and_free_vma;
 
-       if (vma_iter_prealloc(&vmi)) {
-               error = -ENOMEM;
-               if (file)
-                       goto close_and_free_vma;
-               else if (vma->vm_file)
-                       goto unmap_and_free_vma;
-               else
-                       goto free_vma;
-       }
+       error = -ENOMEM;
+       if (vma_iter_prealloc(&vmi))
+               goto close_and_free_vma;
 
        if (vma->vm_file)
                i_mmap_lock_write(vma->vm_file->f_mapping);
        return addr;
 
 close_and_free_vma:
-       if (vma->vm_ops && vma->vm_ops->close)
+       if (file && vma->vm_ops && vma->vm_ops->close)
                vma->vm_ops->close(vma);
+
+       if (file || vma->vm_file) {
 unmap_and_free_vma:
-       fput(vma->vm_file);
-       vma->vm_file = NULL;
+               fput(vma->vm_file);
+               vma->vm_file = NULL;
 
-       /* Undo any partial mapping done by a device driver. */
-       unmap_region(mm, &mm->mm_mt, vma, prev, next, vma->vm_start, vma->vm_end);
+               /* Undo any partial mapping done by a device driver. */
+               unmap_region(mm, &mm->mm_mt, vma, prev, next, vma->vm_start,
+                            vma->vm_end);
+       }
        if (file && (vm_flags & VM_SHARED))
                mapping_unmap_writable(file->f_mapping);
 free_vma: