spin_lock(&em_tree->lock);
        em = lookup_extent_mapping(em_tree, offset, PAGE_CACHE_SIZE);
        spin_unlock(&em_tree->lock);
-       if (!em)
+       if (!em) {
+               __unplug_io_fn(bdi, page);
                return;
+       }
 
+       if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
+               free_extent_map(em);
+               __unplug_io_fn(bdi, page);
+               return;
+       }
        offset = offset - em->start;
        btrfs_unplug_page(&BTRFS_I(inode)->root->fs_info->mapping_tree,
                          em->block_start + offset, page);
 
                                                          cur + iosize - 1);
                }
                if (!ret) {
-                       unsigned long nr = (last_byte >> PAGE_CACHE_SHIFT) + 1;
-                       nr -= page->index;
+                       unsigned long pnr = (last_byte >> PAGE_CACHE_SHIFT) + 1;
+                       pnr -= page->index;
                        ret = submit_extent_page(READ, tree, page,
                                         sector, iosize, page_offset,
-                                        bdev, bio, nr,
+                                        bdev, bio, pnr,
                                         end_bio_extent_readpage, mirror_num);
+                       nr++;
                }
                if (ret)
                        SetPageError(page);
                cur = cur + iosize;
                page_offset += iosize;
-               nr++;
        }
        if (!nr) {
                if (!PageError(page))
 
            btrfs_test_flag(inode, NODATASUM))
                return 0;
 
+       /*
+        * It is possible there is an ordered extent that has
+        * not yet finished for this range in the file.  If so,
+        * that extent will have a csum cached, and it will insert
+        * the sum after all the blocks in the extent are fully
+        * on disk.  So, look for an ordered extent and use the
+        * sum if found.  We have to do this before looking in the
+        * btree because csum items are pre-inserted based on
+        * the file size.  btrfs_lookup_csum might find an item
+        * that still hasn't been fully filled.
+        */
+       ret = btrfs_find_ordered_sum(inode, start, &csum);
+       if (ret == 0)
+               goto found;
+
+       ret = 0;
        path = btrfs_alloc_path();
-       mutex_lock(&BTRFS_I(inode)->csum_mutex);
        item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0);
        if (IS_ERR(item)) {
-               /*
-                * It is possible there is an ordered extent that has
-                * not yet finished for this range in the file.  If so,
-                * that extent will have a csum cached, and it will insert
-                * the sum after all the blocks in the extent are fully
-                * on disk.  So, look for an ordered extent and use the
-                * sum if found.
-                */
-               ret = btrfs_find_ordered_sum(inode, start, &csum);
-               if (ret == 0)
-                       goto found;
-
                ret = PTR_ERR(item);
                /* a csum that isn't present is a preallocated region. */
                if (ret == -ENOENT || ret == -EFBIG)
 found:
        set_state_private(io_tree, start, csum);
 out:
-       mutex_unlock(&BTRFS_I(inode)->csum_mutex);
        if (path)
                btrfs_free_path(path);
        return ret;
                }
                if (!PageUptodate(page)) {
                        ret = -EIO;
-                       goto out;
+                       goto out_unlock;
                }
        }
        wait_on_page_writeback(page);
        set_page_dirty(page);
        unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
 
+out_unlock:
        unlock_page(page);
        page_cache_release(page);
 out: