/* Inode locking type flags, by default the exclusive lock is taken */
 #define BTRFS_ILOCK_SHARED     (1U << 0)
 #define BTRFS_ILOCK_TRY        (1U << 1)
+#define BTRFS_ILOCK_MMAP       (1U << 2)
 
 int btrfs_inode_lock(struct inode *inode, unsigned int ilock_flags);
 void btrfs_inode_unlock(struct inode *inode, unsigned int ilock_flags);
 
  * BTRFS_ILOCK_SHARED - acquire a shared lock on the inode
  * BTRFS_ILOCK_TRY - try to acquire the lock, if fails on first attempt
  *                  return -EAGAIN
+ * BTRFS_ILOCK_MMAP - acquire a write lock on the i_mmap_lock
  */
 int btrfs_inode_lock(struct inode *inode, unsigned int ilock_flags)
 {
                }
                inode_lock(inode);
        }
+       if (ilock_flags & BTRFS_ILOCK_MMAP)
+               down_write(&BTRFS_I(inode)->i_mmap_lock);
        return 0;
 }
 
  */
 void btrfs_inode_unlock(struct inode *inode, unsigned int ilock_flags)
 {
+       if (ilock_flags & BTRFS_ILOCK_MMAP)
+               up_write(&BTRFS_I(inode)->i_mmap_lock);
        if (ilock_flags & BTRFS_ILOCK_SHARED)
                inode_unlock_shared(inode);
        else
 
        ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */
 again:
+       down_read(&BTRFS_I(inode)->i_mmap_lock);
        lock_page(page);
        size = i_size_read(inode);
 
                unlock_extent_cached(io_tree, page_start, page_end,
                                     &cached_state);
                unlock_page(page);
+               up_read(&BTRFS_I(inode)->i_mmap_lock);
                btrfs_start_ordered_extent(ordered, 1);
                btrfs_put_ordered_extent(ordered);
                goto again;
        BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->root->last_log_commit;
 
        unlock_extent_cached(io_tree, page_start, page_end, &cached_state);
+       up_read(&BTRFS_I(inode)->i_mmap_lock);
 
        btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
        sb_end_pagefault(inode->i_sb);
 
 out_unlock:
        unlock_page(page);
+       up_read(&BTRFS_I(inode)->i_mmap_lock);
 out:
        btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
        btrfs_delalloc_release_space(BTRFS_I(inode), data_reserved, page_start,
        INIT_LIST_HEAD(&ei->delalloc_inodes);
        INIT_LIST_HEAD(&ei->delayed_iput);
        RB_CLEAR_NODE(&ei->rb_node);
+       init_rwsem(&ei->i_mmap_lock);
 
        return inode;
 }