u64 isize;
        u64 start;
 
+       /*
+        * Acquire the inode's mmap lock to prevent races with memory mapped
+        * writes, as they could happen after we flush delalloc below and before
+        * we lock the extent range further below. The inode was already locked
+        * up in the call chain.
+        */
+       btrfs_assert_inode_locked(BTRFS_I(inode));
+       down_write(&BTRFS_I(inode)->i_mmap_lock);
+
        /*
         * If the swap file was just created, make sure delalloc is done. If the
         * file changes again after this, the user is doing something stupid and
         */
        ret = btrfs_wait_ordered_range(BTRFS_I(inode), 0, (u64)-1);
        if (ret)
-               return ret;
+               goto out_unlock_mmap;
 
        /*
         * The inode is locked, so these flags won't change after we check them.
         */
        if (BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS) {
                btrfs_warn(fs_info, "swapfile must not be compressed");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_unlock_mmap;
        }
        if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW)) {
                btrfs_warn(fs_info, "swapfile must not be copy-on-write");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_unlock_mmap;
        }
        if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) {
                btrfs_warn(fs_info, "swapfile must not be checksummed");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_unlock_mmap;
        }
 
        /*
        if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_SWAP_ACTIVATE)) {
                btrfs_warn(fs_info,
           "cannot activate swapfile while exclusive operation is running");
-               return -EBUSY;
+               ret = -EBUSY;
+               goto out_unlock_mmap;
        }
 
        /*
                btrfs_exclop_finish(fs_info);
                btrfs_warn(fs_info,
           "cannot activate swapfile because snapshot creation is in progress");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_unlock_mmap;
        }
        /*
         * Snapshots can create extents which require COW even if NODATACOW is
                btrfs_warn(fs_info,
                "cannot activate swapfile because subvolume %llu is being deleted",
                        btrfs_root_id(root));
-               return -EPERM;
+               ret = -EPERM;
+               goto out_unlock_mmap;
        }
        atomic_inc(&root->nr_swapfiles);
        spin_unlock(&root->root_item_lock);
 
        btrfs_exclop_finish(fs_info);
 
+out_unlock_mmap:
+       up_write(&BTRFS_I(inode)->i_mmap_lock);
        if (ret)
                return ret;