]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branch 'for-chris-4.11-part2' of git://git.kernel.org/pub/scm/linux/kernel...
authorChris Mason <clm@fb.com>
Tue, 28 Feb 2017 22:35:09 +0000 (14:35 -0800)
committerChris Mason <clm@fb.com>
Tue, 28 Feb 2017 22:35:09 +0000 (14:35 -0800)
1  2 
fs/btrfs/ctree.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/file-item.c
fs/btrfs/inode.c
fs/btrfs/tree-log.c

diff --combined fs/btrfs/ctree.c
index 1fb60ee77b4a501bde2401462cc54b51169eb2fa,2c3c943bfcdc8d24b63be190f33d8abf9f800f75..7dc8844037e03b7cfb738d81af6c22b33ee2b31d
@@@ -453,8 -453,6 +453,6 @@@ __tree_mod_log_insert(struct btrfs_fs_i
        struct rb_node *parent = NULL;
        struct tree_mod_elem *cur;
  
-       BUG_ON(!tm);
        tm->seq = btrfs_inc_tree_mod_seq(fs_info);
  
        tm_root = &fs_info->tree_mod_log;
@@@ -4159,9 -4157,6 +4157,9 @@@ static noinline int push_for_double_spl
  
        /* try to push all the items before our slot into the next leaf */
        slot = path->slots[0];
 +      space_needed = data_size;
 +      if (slot > 0)
 +              space_needed -= btrfs_leaf_free_space(fs_info, path->nodes[0]);
        ret = push_leaf_left(trans, root, path, 1, space_needed, 0, slot);
        if (ret < 0)
                return ret;
@@@ -4217,10 -4212,6 +4215,10 @@@ static noinline int split_leaf(struct b
                if (wret < 0)
                        return wret;
                if (wret) {
 +                      space_needed = data_size;
 +                      if (slot > 0)
 +                              space_needed -= btrfs_leaf_free_space(fs_info,
 +                                                                    l);
                        wret = push_leaf_left(trans, root, path, space_needed,
                                              space_needed, 0, (u32)-1);
                        if (wret < 0)
diff --combined fs/btrfs/disk-io.c
index 32a9ec11888d7bd37eb896499cd2cecdfe3fc290,cad47ece2fdfbf4b738c0cb2391bd95bb4411a93..73fdc6bdaea98322d2d8fa602d33e4b8c1f5ecc1
@@@ -219,12 -219,12 +219,12 @@@ void btrfs_set_buffer_lockdep_class(u6
   * extents on the btree inode are pretty simple, there's one extent
   * that covers the entire device
   */
- static struct extent_map *btree_get_extent(struct inode *inode,
+ static struct extent_map *btree_get_extent(struct btrfs_inode *inode,
                struct page *page, size_t pg_offset, u64 start, u64 len,
                int create)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
-       struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
+       struct extent_map_tree *em_tree = &inode->extent_tree;
        struct extent_map *em;
        int ret;
  
@@@ -265,7 -265,7 +265,7 @@@ out
        return em;
  }
  
- u32 btrfs_csum_data(char *data, u32 seed, size_t len)
+ u32 btrfs_csum_data(const char *data, u32 seed, size_t len)
  {
        return btrfs_crc32c(seed, data, len);
  }
@@@ -2205,9 -2205,11 +2205,9 @@@ static void btrfs_stop_all_workers(stru
        btrfs_destroy_workqueue(fs_info->delalloc_workers);
        btrfs_destroy_workqueue(fs_info->workers);
        btrfs_destroy_workqueue(fs_info->endio_workers);
 -      btrfs_destroy_workqueue(fs_info->endio_meta_workers);
        btrfs_destroy_workqueue(fs_info->endio_raid56_workers);
        btrfs_destroy_workqueue(fs_info->endio_repair_workers);
        btrfs_destroy_workqueue(fs_info->rmw_workers);
 -      btrfs_destroy_workqueue(fs_info->endio_meta_write_workers);
        btrfs_destroy_workqueue(fs_info->endio_write_workers);
        btrfs_destroy_workqueue(fs_info->endio_freespace_worker);
        btrfs_destroy_workqueue(fs_info->submit_workers);
        btrfs_destroy_workqueue(fs_info->flush_workers);
        btrfs_destroy_workqueue(fs_info->qgroup_rescan_workers);
        btrfs_destroy_workqueue(fs_info->extent_workers);
 +      /*
 +       * Now that all other work queues are destroyed, we can safely destroy
 +       * the queues used for metadata I/O, since tasks from those other work
 +       * queues can do metadata I/O operations.
 +       */
 +      btrfs_destroy_workqueue(fs_info->endio_meta_workers);
 +      btrfs_destroy_workqueue(fs_info->endio_meta_write_workers);
  }
  
  static void free_root_extent_buffers(struct btrfs_root *root)
@@@ -3266,6 -3261,7 +3266,6 @@@ fail_fsdev_sysfs
  
  fail_block_groups:
        btrfs_put_block_group_cache(fs_info);
 -      btrfs_free_block_groups(fs_info);
  
  fail_tree_roots:
        free_root_pointers(fs_info, 1);
  
  fail_sb_buffer:
        btrfs_stop_all_workers(fs_info);
 +      btrfs_free_block_groups(fs_info);
  fail_alloc:
  fail_iput:
        btrfs_mapping_tree_free(&fs_info->mapping_tree);
@@@ -3453,7 -3448,7 +3453,7 @@@ static int write_dev_supers(struct btrf
                        btrfs_set_super_bytenr(sb, bytenr);
  
                        crc = ~(u32)0;
-                       crc = btrfs_csum_data((char *)sb +
+                       crc = btrfs_csum_data((const char *)sb +
                                              BTRFS_CSUM_SIZE, crc,
                                              BTRFS_SUPER_INFO_SIZE -
                                              BTRFS_CSUM_SIZE);
@@@ -3982,6 -3977,8 +3982,6 @@@ void close_ctree(struct btrfs_fs_info *
  
        btrfs_put_block_group_cache(fs_info);
  
 -      btrfs_free_block_groups(fs_info);
 -
        /*
         * we must make sure there is not any read request to
         * submit after we stopping all workers.
        invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
        btrfs_stop_all_workers(fs_info);
  
 +      btrfs_free_block_groups(fs_info);
 +
        clear_bit(BTRFS_FS_OPEN, &fs_info->flags);
        free_root_pointers(fs_info, 1);
  
@@@ -4658,9 -4653,12 +4658,12 @@@ static int btrfs_cleanup_transaction(st
  }
  
  static const struct extent_io_ops btree_extent_io_ops = {
-       .readpage_end_io_hook = btree_readpage_end_io_hook,
-       .readpage_io_failed_hook = btree_io_failed_hook,
+       /* mandatory callbacks */
        .submit_bio_hook = btree_submit_bio_hook,
+       .readpage_end_io_hook = btree_readpage_end_io_hook,
        /* note we're sharing with inode.c for the merge bio hook */
        .merge_bio_hook = btrfs_merge_bio_hook,
+       .readpage_io_failed_hook = btree_io_failed_hook,
+       /* optional callbacks */
  };
diff --combined fs/btrfs/extent-tree.c
index 438c7312de3381d77c019faf18d85416e8094462,3853fab2f49f5f6a8eb015c37b9afa39bc0f400f..60794658ffd880d32f8921ba1286fa3e717c3be6
@@@ -4135,10 -4135,10 +4135,10 @@@ static u64 btrfs_space_info_used(struc
                (may_use_included ? s_info->bytes_may_use : 0);
  }
  
- int btrfs_alloc_data_chunk_ondemand(struct inode *inode, u64 bytes)
+ int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes)
  {
        struct btrfs_space_info *data_sinfo;
-       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_root *root = inode->root;
        struct btrfs_fs_info *fs_info = root->fs_info;
        u64 used;
        int ret = 0;
@@@ -4281,7 -4281,7 +4281,7 @@@ int btrfs_check_data_free_space(struct 
              round_down(start, fs_info->sectorsize);
        start = round_down(start, fs_info->sectorsize);
  
-       ret = btrfs_alloc_data_chunk_ondemand(inode, len);
+       ret = btrfs_alloc_data_chunk_ondemand(BTRFS_I(inode), len);
        if (ret < 0)
                return ret;
  
@@@ -5742,10 -5742,10 +5742,10 @@@ void btrfs_trans_release_chunk_metadata
  
  /* Can only return 0 or -ENOSPC */
  int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans,
-                                 struct inode *inode)
+                                 struct btrfs_inode *inode)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
-       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
+       struct btrfs_root *root = inode->root;
        /*
         * We always use trans->block_rsv here as we will have reserved space
         * for our orphan when starting the transaction, using get_block_rsv()
         */
        u64 num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
  
-       trace_btrfs_space_reservation(fs_info, "orphan",
-                                     btrfs_ino(BTRFS_I(inode)), num_bytes, 1);
+       trace_btrfs_space_reservation(fs_info, "orphan", btrfs_ino(inode), 
+                       num_bytes, 1);
        return btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1);
  }
  
- void btrfs_orphan_release_metadata(struct inode *inode)
+ void btrfs_orphan_release_metadata(struct btrfs_inode *inode)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
-       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
+       struct btrfs_root *root = inode->root;
        u64 num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
  
-       trace_btrfs_space_reservation(fs_info, "orphan",
-                                     btrfs_ino(BTRFS_I(inode)), num_bytes, 0);
+       trace_btrfs_space_reservation(fs_info, "orphan", btrfs_ino(inode),
+                       num_bytes, 0);
        btrfs_block_rsv_release(fs_info, root->orphan_block_rsv, num_bytes);
  }
  
@@@ -5846,7 -5846,8 +5846,8 @@@ void btrfs_subvolume_release_metadata(s
   * reserved extents that need to be freed.  This must be called with
   * BTRFS_I(inode)->lock held.
   */
- static unsigned drop_outstanding_extent(struct inode *inode, u64 num_bytes)
+ static unsigned drop_outstanding_extent(struct btrfs_inode *inode,
+               u64 num_bytes)
  {
        unsigned drop_inode_space = 0;
        unsigned dropped_extents = 0;
  
        num_extents = count_max_extents(num_bytes);
        ASSERT(num_extents);
-       ASSERT(BTRFS_I(inode)->outstanding_extents >= num_extents);
-       BTRFS_I(inode)->outstanding_extents -= num_extents;
+       ASSERT(inode->outstanding_extents >= num_extents);
+       inode->outstanding_extents -= num_extents;
  
-       if (BTRFS_I(inode)->outstanding_extents == 0 &&
+       if (inode->outstanding_extents == 0 &&
            test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
-                              &BTRFS_I(inode)->runtime_flags))
+                              &inode->runtime_flags))
                drop_inode_space = 1;
  
        /*
         * If we have more or the same amount of outstanding extents than we have
         * reserved then we need to leave the reserved extents count alone.
         */
-       if (BTRFS_I(inode)->outstanding_extents >=
-           BTRFS_I(inode)->reserved_extents)
+       if (inode->outstanding_extents >= inode->reserved_extents)
                return drop_inode_space;
  
-       dropped_extents = BTRFS_I(inode)->reserved_extents -
-               BTRFS_I(inode)->outstanding_extents;
-       BTRFS_I(inode)->reserved_extents -= dropped_extents;
+       dropped_extents = inode->reserved_extents - inode->outstanding_extents;
+       inode->reserved_extents -= dropped_extents;
        return dropped_extents + drop_inode_space;
  }
  
   *
   * This must be called with BTRFS_I(inode)->lock held.
   */
- static u64 calc_csum_metadata_size(struct inode *inode, u64 num_bytes,
+ static u64 calc_csum_metadata_size(struct btrfs_inode *inode, u64 num_bytes,
                                   int reserve)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
        u64 old_csums, num_csums;
  
-       if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM &&
-           BTRFS_I(inode)->csum_bytes == 0)
+       if (inode->flags & BTRFS_INODE_NODATASUM && inode->csum_bytes == 0)
                return 0;
  
-       old_csums = btrfs_csum_bytes_to_leaves(fs_info,
-                                              BTRFS_I(inode)->csum_bytes);
+       old_csums = btrfs_csum_bytes_to_leaves(fs_info, inode->csum_bytes);
        if (reserve)
-               BTRFS_I(inode)->csum_bytes += num_bytes;
+               inode->csum_bytes += num_bytes;
        else
-               BTRFS_I(inode)->csum_bytes -= num_bytes;
-       num_csums = btrfs_csum_bytes_to_leaves(fs_info,
-                                              BTRFS_I(inode)->csum_bytes);
+               inode->csum_bytes -= num_bytes;
+       num_csums = btrfs_csum_bytes_to_leaves(fs_info, inode->csum_bytes);
  
        /* No change, no need to reserve more */
        if (old_csums == num_csums)
        return btrfs_calc_trans_metadata_size(fs_info, old_csums - num_csums);
  }
  
- int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
+ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
-       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
+       struct btrfs_root *root = inode->root;
        struct btrfs_block_rsv *block_rsv = &fs_info->delalloc_block_rsv;
        u64 to_reserve = 0;
        u64 csum_bytes;
                schedule_timeout(1);
  
        if (delalloc_lock)
-               mutex_lock(&BTRFS_I(inode)->delalloc_mutex);
+               mutex_lock(&inode->delalloc_mutex);
  
        num_bytes = ALIGN(num_bytes, fs_info->sectorsize);
  
-       spin_lock(&BTRFS_I(inode)->lock);
+       spin_lock(&inode->lock);
        nr_extents = count_max_extents(num_bytes);
-       BTRFS_I(inode)->outstanding_extents += nr_extents;
+       inode->outstanding_extents += nr_extents;
  
        nr_extents = 0;
-       if (BTRFS_I(inode)->outstanding_extents >
-           BTRFS_I(inode)->reserved_extents)
-               nr_extents += BTRFS_I(inode)->outstanding_extents -
-                       BTRFS_I(inode)->reserved_extents;
+       if (inode->outstanding_extents > inode->reserved_extents)
+               nr_extents += inode->outstanding_extents -
+                       inode->reserved_extents;
  
        /* We always want to reserve a slot for updating the inode. */
        to_reserve = btrfs_calc_trans_metadata_size(fs_info, nr_extents + 1);
        to_reserve += calc_csum_metadata_size(inode, num_bytes, 1);
-       csum_bytes = BTRFS_I(inode)->csum_bytes;
-       spin_unlock(&BTRFS_I(inode)->lock);
+       csum_bytes = inode->csum_bytes;
+       spin_unlock(&inode->lock);
  
        if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) {
                ret = btrfs_qgroup_reserve_meta(root,
                goto out_fail;
        }
  
-       spin_lock(&BTRFS_I(inode)->lock);
+       spin_lock(&inode->lock);
        if (test_and_set_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
-                            &BTRFS_I(inode)->runtime_flags)) {
+                            &inode->runtime_flags)) {
                to_reserve -= btrfs_calc_trans_metadata_size(fs_info, 1);
                release_extra = true;
        }
-       BTRFS_I(inode)->reserved_extents += nr_extents;
-       spin_unlock(&BTRFS_I(inode)->lock);
+       inode->reserved_extents += nr_extents;
+       spin_unlock(&inode->lock);
  
        if (delalloc_lock)
-               mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);
+               mutex_unlock(&inode->delalloc_mutex);
  
        if (to_reserve)
                trace_btrfs_space_reservation(fs_info, "delalloc",
-                                     btrfs_ino(BTRFS_I(inode)), to_reserve, 1);
+                                             btrfs_ino(inode), to_reserve, 1);
        if (release_extra)
                btrfs_block_rsv_release(fs_info, block_rsv,
                                btrfs_calc_trans_metadata_size(fs_info, 1));
        return 0;
  
  out_fail:
-       spin_lock(&BTRFS_I(inode)->lock);
+       spin_lock(&inode->lock);
        dropped = drop_outstanding_extent(inode, num_bytes);
        /*
         * If the inodes csum_bytes is the same as the original
         * csum_bytes then we know we haven't raced with any free()ers
         * so we can just reduce our inodes csum bytes and carry on.
         */
-       if (BTRFS_I(inode)->csum_bytes == csum_bytes) {
+       if (inode->csum_bytes == csum_bytes) {
                calc_csum_metadata_size(inode, num_bytes, 0);
        } else {
-               u64 orig_csum_bytes = BTRFS_I(inode)->csum_bytes;
+               u64 orig_csum_bytes = inode->csum_bytes;
                u64 bytes;
  
                /*
                 * number of bytes that were freed while we were trying our
                 * reservation.
                 */
-               bytes = csum_bytes - BTRFS_I(inode)->csum_bytes;
-               BTRFS_I(inode)->csum_bytes = csum_bytes;
+               bytes = csum_bytes - inode->csum_bytes;
+               inode->csum_bytes = csum_bytes;
                to_free = calc_csum_metadata_size(inode, bytes, 0);
  
  
                 * been making this reservation and our ->csum_bytes were not
                 * artificially inflated.
                 */
-               BTRFS_I(inode)->csum_bytes = csum_bytes - num_bytes;
+               inode->csum_bytes = csum_bytes - num_bytes;
                bytes = csum_bytes - orig_csum_bytes;
                bytes = calc_csum_metadata_size(inode, bytes, 0);
  
                 * need to do anything, the other free-ers did the correct
                 * thing.
                 */
-               BTRFS_I(inode)->csum_bytes = orig_csum_bytes - num_bytes;
+               inode->csum_bytes = orig_csum_bytes - num_bytes;
                if (bytes > to_free)
                        to_free = bytes - to_free;
                else
                        to_free = 0;
        }
-       spin_unlock(&BTRFS_I(inode)->lock);
+       spin_unlock(&inode->lock);
        if (dropped)
                to_free += btrfs_calc_trans_metadata_size(fs_info, dropped);
  
        if (to_free) {
                btrfs_block_rsv_release(fs_info, block_rsv, to_free);
                trace_btrfs_space_reservation(fs_info, "delalloc",
-                                     btrfs_ino(BTRFS_I(inode)), to_free, 0);
+                                             btrfs_ino(inode), to_free, 0);
        }
        if (delalloc_lock)
-               mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);
+               mutex_unlock(&inode->delalloc_mutex);
        return ret;
  }
  
   * once we complete IO for a given set of bytes to release their metadata
   * reservations.
   */
- void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
+ void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
        u64 to_free = 0;
        unsigned dropped;
  
        num_bytes = ALIGN(num_bytes, fs_info->sectorsize);
-       spin_lock(&BTRFS_I(inode)->lock);
+       spin_lock(&inode->lock);
        dropped = drop_outstanding_extent(inode, num_bytes);
  
        if (num_bytes)
                to_free = calc_csum_metadata_size(inode, num_bytes, 0);
-       spin_unlock(&BTRFS_I(inode)->lock);
+       spin_unlock(&inode->lock);
        if (dropped > 0)
                to_free += btrfs_calc_trans_metadata_size(fs_info, dropped);
  
        if (btrfs_is_testing(fs_info))
                return;
  
-       trace_btrfs_space_reservation(fs_info, "delalloc",
-                                     btrfs_ino(BTRFS_I(inode)), to_free, 0);
+       trace_btrfs_space_reservation(fs_info, "delalloc", btrfs_ino(inode),
+                                     to_free, 0);
  
        btrfs_block_rsv_release(fs_info, &fs_info->delalloc_block_rsv, to_free);
  }
@@@ -6141,7 -6136,7 +6136,7 @@@ int btrfs_delalloc_reserve_space(struc
        ret = btrfs_check_data_free_space(inode, start, len);
        if (ret < 0)
                return ret;
-       ret = btrfs_delalloc_reserve_metadata(inode, len);
+       ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), len);
        if (ret < 0)
                btrfs_free_reserved_data_space(inode, start, len);
        return ret;
   */
  void btrfs_delalloc_release_space(struct inode *inode, u64 start, u64 len)
  {
-       btrfs_delalloc_release_metadata(inode, len);
+       btrfs_delalloc_release_metadata(BTRFS_I(inode), len);
        btrfs_free_reserved_data_space(inode, start, len);
  }
  
@@@ -9740,11 -9735,6 +9735,11 @@@ void btrfs_put_block_group_cache(struc
        }
  }
  
 +/*
 + * Must be called only after stopping all workers, since we could have block
 + * group caching kthreads running, and therefore they could race with us if we
 + * freed the block groups before stopping them.
 + */
  int btrfs_free_block_groups(struct btrfs_fs_info *info)
  {
        struct btrfs_block_group_cache *block_group;
                list_del(&block_group->list);
                up_write(&block_group->space_info->groups_sem);
  
 -              if (block_group->cached == BTRFS_CACHE_STARTED)
 -                      wait_block_group_cache_done(block_group);
 -
                /*
                 * We haven't cached this block group, which means we could
                 * possibly have excluded extents on this block group.
                        free_excluded_extents(info, block_group);
  
                btrfs_remove_free_space_cache(block_group);
 +              ASSERT(block_group->cached != BTRFS_CACHE_STARTED);
                ASSERT(list_empty(&block_group->dirty_list));
                ASSERT(list_empty(&block_group->io_list));
                ASSERT(list_empty(&block_group->bg_list));
@@@ -10345,7 -10337,7 +10340,7 @@@ int btrfs_remove_block_group(struct btr
        mutex_unlock(&trans->transaction->cache_write_mutex);
  
        if (!IS_ERR(inode)) {
-               ret = btrfs_orphan_add(trans, inode);
+               ret = btrfs_orphan_add(trans, BTRFS_I(inode));
                if (ret) {
                        btrfs_add_delayed_iput(inode);
                        goto out;
diff --combined fs/btrfs/file-item.c
index e35df48b438387595dbe2ccf1bedd290d9837da7,54ec6d6ef0163fb51aa9ae242a423e8dd3d51474..64fcb31d71633c2731d6241b1236f7c57b1f5b6f
@@@ -214,7 -214,7 +214,7 @@@ static int __btrfs_lookup_bio_sums(stru
         * read from the commit root and sidestep a nasty deadlock
         * between reading the free space cache and updating the csum tree.
         */
-       if (btrfs_is_free_space_inode(inode)) {
+       if (btrfs_is_free_space_inode(BTRFS_I(inode))) {
                path->search_commit_root = 1;
                path->skip_locking = 1;
        }
@@@ -643,33 -643,7 +643,33 @@@ int btrfs_del_csums(struct btrfs_trans_
  
                /* delete the entire item, it is inside our range */
                if (key.offset >= bytenr && csum_end <= end_byte) {
 -                      ret = btrfs_del_item(trans, root, path);
 +                      int del_nr = 1;
 +
 +                      /*
 +                       * Check how many csum items preceding this one in this
 +                       * leaf correspond to our range and then delete them all
 +                       * at once.
 +                       */
 +                      if (key.offset > bytenr && path->slots[0] > 0) {
 +                              int slot = path->slots[0] - 1;
 +
 +                              while (slot >= 0) {
 +                                      struct btrfs_key pk;
 +
 +                                      btrfs_item_key_to_cpu(leaf, &pk, slot);
 +                                      if (pk.offset < bytenr ||
 +                                          pk.type != BTRFS_EXTENT_CSUM_KEY ||
 +                                          pk.objectid !=
 +                                          BTRFS_EXTENT_CSUM_OBJECTID)
 +                                              break;
 +                                      path->slots[0] = slot;
 +                                      del_nr++;
 +                                      key.offset = pk.offset;
 +                                      slot--;
 +                              }
 +                      }
 +                      ret = btrfs_del_items(trans, root, path,
 +                                            path->slots[0], del_nr);
                        if (ret)
                                goto out;
                        if (key.offset == bytenr)
@@@ -930,14 -904,14 +930,14 @@@ fail_unlock
        goto out;
  }
  
- void btrfs_extent_item_to_extent_map(struct inode *inode,
+ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
                                     const struct btrfs_path *path,
                                     struct btrfs_file_extent_item *fi,
                                     const bool new_inline,
                                     struct extent_map *em)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
-       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
+       struct btrfs_root *root = inode->root;
        struct extent_buffer *leaf = path->nodes[0];
        const int slot = path->slots[0];
        struct btrfs_key key;
                }
        } else {
                btrfs_err(fs_info,
-                         "unknown file extent item type %d, inode %llu, offset %llu, root %llu",
-                         type, btrfs_ino(BTRFS_I(inode)), extent_start,
+                         "unknown file extent item type %d, inode %llu, offset %llu, "
+                         "root %llu", type, btrfs_ino(inode), extent_start,
                          root->root_key.objectid);
        }
  }
diff --combined fs/btrfs/inode.c
index 70df45192424068ab8758321af486699d4eea0dc,ca1995cfd8e99631acb97bfa9a4ec51e5e602dd1..b2bc07aad1ae98cac403ed54c839350f8a46b84a
@@@ -316,8 -316,8 +316,8 @@@ static noinline int cow_file_range_inli
        }
  
        set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags);
-       btrfs_delalloc_release_metadata(inode, end + 1 - start);
-       btrfs_drop_extent_cache(inode, start, aligned_end - 1, 0);
+       btrfs_delalloc_release_metadata(BTRFS_I(inode), end + 1 - start);
+       btrfs_drop_extent_cache(BTRFS_I(inode), start, aligned_end - 1, 0);
  out:
        /*
         * Don't forget to free the reserved space, as for inlined extent
@@@ -389,12 -389,12 +389,12 @@@ static inline int inode_need_compress(s
        return 0;
  }
  
- static inline void inode_should_defrag(struct inode *inode,
+ static inline void inode_should_defrag(struct btrfs_inode *inode,
                u64 start, u64 end, u64 num_bytes, u64 small_write)
  {
        /* If this is a small write inside eof, kick off a defrag */
        if (num_bytes < small_write &&
-           (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size))
+           (start > 0 || end + 1 < inode->disk_i_size))
                btrfs_add_inode_defrag(NULL, inode);
  }
  
@@@ -430,23 -430,23 +430,23 @@@ static noinline void compress_file_rang
        int ret = 0;
        struct page **pages = NULL;
        unsigned long nr_pages;
-       unsigned long nr_pages_ret = 0;
        unsigned long total_compressed = 0;
        unsigned long total_in = 0;
-       unsigned long max_compressed = SZ_128K;
-       unsigned long max_uncompressed = SZ_128K;
        int i;
        int will_compress;
        int compress_type = fs_info->compress_type;
        int redirty = 0;
  
-       inode_should_defrag(inode, start, end, end - start + 1, SZ_16K);
+       inode_should_defrag(BTRFS_I(inode), start, end, end - start + 1,
+                       SZ_16K);
  
        actual_end = min_t(u64, isize, end + 1);
  again:
        will_compress = 0;
        nr_pages = (end >> PAGE_SHIFT) - (start >> PAGE_SHIFT) + 1;
-       nr_pages = min_t(unsigned long, nr_pages, SZ_128K / PAGE_SIZE);
+       BUILD_BUG_ON((BTRFS_MAX_COMPRESSED % PAGE_SIZE) != 0);
+       nr_pages = min_t(unsigned long, nr_pages,
+                       BTRFS_MAX_COMPRESSED / PAGE_SIZE);
  
        /*
         * we don't want to send crud past the end of i_size through
           (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size))
                goto cleanup_and_bail_uncompressed;
  
-       /* we want to make sure that amount of ram required to uncompress
-        * an extent is reasonable, so we limit the total size in ram
-        * of a compressed extent to 128k.  This is a crucial number
-        * because it also controls how easily we can spread reads across
-        * cpus for decompression.
-        *
-        * We also want to make sure the amount of IO required to do
-        * a random read is reasonably small, so we limit the size of
-        * a compressed extent to 128k.
-        */
-       total_compressed = min(total_compressed, max_uncompressed);
+       total_compressed = min_t(unsigned long, total_compressed,
+                       BTRFS_MAX_UNCOMPRESSED);
        num_bytes = ALIGN(end - start + 1, blocksize);
        num_bytes = max(blocksize,  num_bytes);
        total_in = 0;
                redirty = 1;
                ret = btrfs_compress_pages(compress_type,
                                           inode->i_mapping, start,
-                                          total_compressed, pages,
-                                          nr_pages, &nr_pages_ret,
+                                          pages,
+                                          &nr_pages,
                                           &total_in,
-                                          &total_compressed,
-                                          max_compressed);
+                                          &total_compressed);
  
                if (!ret) {
                        unsigned long offset = total_compressed &
                                (PAGE_SIZE - 1);
-                       struct page *page = pages[nr_pages_ret - 1];
+                       struct page *page = pages[nr_pages - 1];
                        char *kaddr;
  
                        /* zero the tail end of the last page, we might be
@@@ -606,7 -596,7 +596,7 @@@ cont
                         * will submit them to the elevator.
                         */
                        add_async_extent(async_cow, start, num_bytes,
-                                       total_compressed, pages, nr_pages_ret,
+                                       total_compressed, pages, nr_pages,
                                        compress_type);
  
                        if (start + num_bytes < end) {
                 * the compression code ran but failed to make things smaller,
                 * free any pages it allocated and our page pointer array
                 */
-               for (i = 0; i < nr_pages_ret; i++) {
+               for (i = 0; i < nr_pages; i++) {
                        WARN_ON(pages[i]->mapping);
                        put_page(pages[i]);
                }
                kfree(pages);
                pages = NULL;
                total_compressed = 0;
-               nr_pages_ret = 0;
+               nr_pages = 0;
  
                /* flag the file so we don't compress in the future */
                if (!btrfs_test_opt(fs_info, FORCE_COMPRESS) &&
@@@ -659,7 -649,7 +649,7 @@@ cleanup_and_bail_uncompressed
        return;
  
  free_pages_out:
-       for (i = 0; i < nr_pages_ret; i++) {
+       for (i = 0; i < nr_pages; i++) {
                WARN_ON(pages[i]->mapping);
                put_page(pages[i]);
        }
@@@ -806,7 -796,8 +796,8 @@@ retry
                                                BTRFS_ORDERED_COMPRESSED,
                                                async_extent->compress_type);
                if (ret) {
-                       btrfs_drop_extent_cache(inode, async_extent->start,
+                       btrfs_drop_extent_cache(BTRFS_I(inode),
+                                               async_extent->start,
                                                async_extent->start +
                                                async_extent->ram_size - 1, 0);
                        goto out_free_reserve;
@@@ -933,7 -924,7 +924,7 @@@ static noinline int cow_file_range(stru
        struct extent_map *em;
        int ret = 0;
  
-       if (btrfs_is_free_space_inode(inode)) {
+       if (btrfs_is_free_space_inode(BTRFS_I(inode))) {
                WARN_ON_ONCE(1);
                ret = -EINVAL;
                goto out_unlock;
        num_bytes = max(blocksize,  num_bytes);
        disk_num_bytes = num_bytes;
  
-       inode_should_defrag(inode, start, end, num_bytes, SZ_64K);
+       inode_should_defrag(BTRFS_I(inode), start, end, num_bytes, SZ_64K);
  
        if (start == 0) {
                /* lets try to make an inline extent */
               btrfs_super_total_bytes(fs_info->super_copy));
  
        alloc_hint = get_extent_allocation_hint(inode, start, num_bytes);
-       btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0);
+       btrfs_drop_extent_cache(BTRFS_I(inode), start,
+                       start + num_bytes - 1, 0);
  
        while (disk_num_bytes > 0) {
                unsigned long op;
@@@ -1039,7 -1031,7 +1031,7 @@@ out
        return ret;
  
  out_drop_extent_cache:
-       btrfs_drop_extent_cache(inode, start, start + ram_size - 1, 0);
+       btrfs_drop_extent_cache(BTRFS_I(inode), start, start + ram_size - 1, 0);
  out_reserve:
        btrfs_dec_block_group_reservations(fs_info, ins.objectid);
        btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset, 1);
@@@ -1231,7 -1223,7 +1223,7 @@@ static noinline int run_delalloc_nocow(
                return -ENOMEM;
        }
  
-       nolock = btrfs_is_free_space_inode(inode);
+       nolock = btrfs_is_free_space_inode(BTRFS_I(inode));
  
        cow_start = (u64)-1;
        cur_offset = start;
@@@ -1331,16 -1323,10 +1323,16 @@@ next_slot
                         * either valid or do not exist.
                         */
                        if (csum_exist_in_range(fs_info, disk_bytenr,
 -                                              num_bytes))
 +                                              num_bytes)) {
 +                              if (!nolock)
 +                                      btrfs_end_write_no_snapshoting(root);
                                goto out_check;
 -                      if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr))
 +                      }
 +                      if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) {
 +                              if (!nolock)
 +                                      btrfs_end_write_no_snapshoting(root);
                                goto out_check;
 +                      }
                        nocow = 1;
                } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
                        extent_end = found_key.offset +
@@@ -1635,15 -1621,15 +1627,15 @@@ static void btrfs_add_delalloc_inodes(s
  }
  
  static void btrfs_del_delalloc_inode(struct btrfs_root *root,
-                                    struct inode *inode)
+                                    struct btrfs_inode *inode)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
  
        spin_lock(&root->delalloc_lock);
-       if (!list_empty(&BTRFS_I(inode)->delalloc_inodes)) {
-               list_del_init(&BTRFS_I(inode)->delalloc_inodes);
+       if (!list_empty(&inode->delalloc_inodes)) {
+               list_del_init(&inode->delalloc_inodes);
                clear_bit(BTRFS_INODE_IN_DELALLOC_LIST,
-                         &BTRFS_I(inode)->runtime_flags);
+                         &inode->runtime_flags);
                root->nr_delalloc_inodes--;
                if (!root->nr_delalloc_inodes) {
                        spin_lock(&fs_info->delalloc_root_lock);
@@@ -1676,7 -1662,7 +1668,7 @@@ static void btrfs_set_bit_hook(struct i
        if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
                struct btrfs_root *root = BTRFS_I(inode)->root;
                u64 len = state->end + 1 - state->start;
-               bool do_list = !btrfs_is_free_space_inode(inode);
+               bool do_list = !btrfs_is_free_space_inode(BTRFS_I(inode));
  
                if (*bits & EXTENT_FIRST_DELALLOC) {
                        *bits &= ~EXTENT_FIRST_DELALLOC;
  /*
   * extent_io.c clear_bit_hook, see set_bit_hook for why
   */
- static void btrfs_clear_bit_hook(struct inode *inode,
+ static void btrfs_clear_bit_hook(struct btrfs_inode *inode,
                                 struct extent_state *state,
                                 unsigned *bits)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
        u64 len = state->end + 1 - state->start;
        u32 num_extents = count_max_extents(len);
  
-       spin_lock(&BTRFS_I(inode)->lock);
+       spin_lock(&inode->lock);
        if ((state->state & EXTENT_DEFRAG) && (*bits & EXTENT_DEFRAG))
-               BTRFS_I(inode)->defrag_bytes -= len;
-       spin_unlock(&BTRFS_I(inode)->lock);
+               inode->defrag_bytes -= len;
+       spin_unlock(&inode->lock);
  
        /*
         * set_bit and clear bit hooks normally require _irqsave/restore
         * bit, which is only set or cleared with irqs on
         */
        if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
-               struct btrfs_root *root = BTRFS_I(inode)->root;
+               struct btrfs_root *root = inode->root;
                bool do_list = !btrfs_is_free_space_inode(inode);
  
                if (*bits & EXTENT_FIRST_DELALLOC) {
                        *bits &= ~EXTENT_FIRST_DELALLOC;
                } else if (!(*bits & EXTENT_DO_ACCOUNTING)) {
-                       spin_lock(&BTRFS_I(inode)->lock);
-                       BTRFS_I(inode)->outstanding_extents -= num_extents;
-                       spin_unlock(&BTRFS_I(inode)->lock);
+                       spin_lock(&inode->lock);
+                       inode->outstanding_extents -= num_extents;
+                       spin_unlock(&inode->lock);
                }
  
                /*
                    && do_list && !(state->state & EXTENT_NORESERVE)
                    && (*bits & (EXTENT_DO_ACCOUNTING |
                    EXTENT_CLEAR_DATA_RESV)))
-                       btrfs_free_reserved_data_space_noquota(inode,
+                       btrfs_free_reserved_data_space_noquota(
+                                       &inode->vfs_inode,
                                        state->start, len);
  
                __percpu_counter_add(&fs_info->delalloc_bytes, -len,
                                     fs_info->delalloc_batch);
-               spin_lock(&BTRFS_I(inode)->lock);
-               BTRFS_I(inode)->delalloc_bytes -= len;
-               if (do_list && BTRFS_I(inode)->delalloc_bytes == 0 &&
+               spin_lock(&inode->lock);
+               inode->delalloc_bytes -= len;
+               if (do_list && inode->delalloc_bytes == 0 &&
                    test_bit(BTRFS_INODE_IN_DELALLOC_LIST,
-                            &BTRFS_I(inode)->runtime_flags))
+                                       &inode->runtime_flags))
                        btrfs_del_delalloc_inode(root, inode);
-               spin_unlock(&BTRFS_I(inode)->lock);
+               spin_unlock(&inode->lock);
        }
  }
  
@@@ -1860,7 -1847,7 +1853,7 @@@ static int btrfs_submit_bio_hook(struc
  
        skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
  
-       if (btrfs_is_free_space_inode(inode))
+       if (btrfs_is_free_space_inode(BTRFS_I(inode)))
                metadata = BTRFS_WQ_ENDIO_FREE_SPACE;
  
        if (bio_op(bio) != REQ_OP_WRITE) {
@@@ -1969,7 -1956,7 +1962,7 @@@ again
        if (PagePrivate2(page))
                goto out;
  
-       ordered = btrfs_lookup_ordered_range(inode, page_start,
+       ordered = btrfs_lookup_ordered_range(BTRFS_I(inode), page_start,
                                        PAGE_SIZE);
        if (ordered) {
                unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start,
@@@ -2799,16 -2786,17 +2792,17 @@@ static int btrfs_finish_ordered_io(stru
        bool nolock;
        bool truncated = false;
  
-       nolock = btrfs_is_free_space_inode(inode);
+       nolock = btrfs_is_free_space_inode(BTRFS_I(inode));
  
        if (test_bit(BTRFS_ORDERED_IOERR, &ordered_extent->flags)) {
                ret = -EIO;
                goto out;
        }
  
-       btrfs_free_io_failure_record(inode, ordered_extent->file_offset,
-                                    ordered_extent->file_offset +
-                                    ordered_extent->len - 1);
+       btrfs_free_io_failure_record(BTRFS_I(inode),
+                       ordered_extent->file_offset,
+                       ordered_extent->file_offset +
+                       ordered_extent->len - 1);
  
        if (test_bit(BTRFS_ORDERED_TRUNCATED, &ordered_extent->flags)) {
                truncated = true;
                compress_type = ordered_extent->compress_type;
        if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) {
                BUG_ON(compress_type);
-               ret = btrfs_mark_extent_written(trans, inode,
+               ret = btrfs_mark_extent_written(trans, BTRFS_I(inode),
                                                ordered_extent->file_offset,
                                                ordered_extent->file_offset +
                                                logical_len);
@@@ -2920,7 -2908,8 +2914,8 @@@ out_unlock
                             ordered_extent->len - 1, &cached_state, GFP_NOFS);
  out:
        if (root != fs_info->tree_root)
-               btrfs_delalloc_release_metadata(inode, ordered_extent->len);
+               btrfs_delalloc_release_metadata(BTRFS_I(inode),
+                               ordered_extent->len);
        if (trans)
                btrfs_end_transaction(trans);
  
                clear_extent_uptodate(io_tree, start, end, NULL, GFP_NOFS);
  
                /* Drop the cache for the part of the extent we didn't write. */
-               btrfs_drop_extent_cache(inode, start, end, 0);
+               btrfs_drop_extent_cache(BTRFS_I(inode), start, end, 0);
  
                /*
                 * If the ordered extent had an IOERR or something else went
@@@ -2983,7 -2972,7 +2978,7 @@@ static void finish_ordered_fn(struct bt
        btrfs_finish_ordered_io(ordered_extent);
  }
  
- static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
+ static void btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
                                struct extent_state *state, int uptodate)
  {
        struct inode *inode = page->mapping->host;
        ClearPagePrivate2(page);
        if (!btrfs_dec_test_ordered_pending(inode, &ordered_extent, start,
                                            end - start + 1, uptodate))
-               return 0;
+               return;
  
-       if (btrfs_is_free_space_inode(inode)) {
+       if (btrfs_is_free_space_inode(BTRFS_I(inode))) {
                wq = fs_info->endio_freespace_worker;
                func = btrfs_freespace_write_helper;
        } else {
        btrfs_init_work(&ordered_extent->work, func, finish_ordered_fn, NULL,
                        NULL);
        btrfs_queue_work(wq, &ordered_extent->work);
-       return 0;
  }
  
  static int __readpage_endio_check(struct inode *inode,
        kunmap_atomic(kaddr);
        return 0;
  zeroit:
-       btrfs_print_data_csum_error(inode, start, csum, csum_expected,
+       btrfs_print_data_csum_error(BTRFS_I(inode), start, csum, csum_expected,
                                    io_bio->mirror_num);
        memset(kaddr + pgoff, 1, len);
        flush_dcache_page(page);
@@@ -3173,10 -3160,11 +3166,11 @@@ void btrfs_orphan_commit_root(struct bt
   * NOTE: caller of this function should reserve 5 units of metadata for
   *     this function.
   */
- int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode)
+ int btrfs_orphan_add(struct btrfs_trans_handle *trans,
+               struct btrfs_inode *inode)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
-       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
+       struct btrfs_root *root = inode->root;
        struct btrfs_block_rsv *block_rsv = NULL;
        int reserve = 0;
        int insert = 0;
        }
  
        if (!test_and_set_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
-                             &BTRFS_I(inode)->runtime_flags)) {
+                             &inode->runtime_flags)) {
  #if 0
                /*
                 * For proper ENOSPC handling, we should do orphan
        }
  
        if (!test_and_set_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
-                             &BTRFS_I(inode)->runtime_flags))
+                             &inode->runtime_flags))
                reserve = 1;
        spin_unlock(&root->orphan_lock);
  
                if (ret) {
                        atomic_dec(&root->orphan_inodes);
                        clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
-                                 &BTRFS_I(inode)->runtime_flags);
+                                 &inode->runtime_flags);
                        if (insert)
                                clear_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
-                                         &BTRFS_I(inode)->runtime_flags);
+                                         &inode->runtime_flags);
                        return ret;
                }
        }
  
        /* insert an orphan item to track this unlinked/truncated file */
        if (insert >= 1) {
-               ret = btrfs_insert_orphan_item(trans, root,
-                               btrfs_ino(BTRFS_I(inode)));
+               ret = btrfs_insert_orphan_item(trans, root, btrfs_ino(inode));
                if (ret) {
                        atomic_dec(&root->orphan_inodes);
                        if (reserve) {
                                clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
-                                         &BTRFS_I(inode)->runtime_flags);
+                                         &inode->runtime_flags);
                                btrfs_orphan_release_metadata(inode);
                        }
                        if (ret != -EEXIST) {
                                clear_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
-                                         &BTRFS_I(inode)->runtime_flags);
+                                         &inode->runtime_flags);
                                btrfs_abort_transaction(trans, ret);
                                return ret;
                        }
   * item for this particular inode.
   */
  static int btrfs_orphan_del(struct btrfs_trans_handle *trans,
-                           struct inode *inode)
+                           struct btrfs_inode *inode)
  {
-       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_root *root = inode->root;
        int delete_item = 0;
        int release_rsv = 0;
        int ret = 0;
  
        spin_lock(&root->orphan_lock);
        if (test_and_clear_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
-                              &BTRFS_I(inode)->runtime_flags))
+                              &inode->runtime_flags))
                delete_item = 1;
  
        if (test_and_clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
-                              &BTRFS_I(inode)->runtime_flags))
+                              &inode->runtime_flags))
                release_rsv = 1;
        spin_unlock(&root->orphan_lock);
  
                atomic_dec(&root->orphan_inodes);
                if (trans)
                        ret = btrfs_del_orphan_item(trans, root,
-                                                   btrfs_ino(BTRFS_I(inode)));
+                                                   btrfs_ino(inode));
        }
  
        if (release_rsv)
@@@ -3459,7 -3446,7 +3452,7 @@@ int btrfs_orphan_cleanup(struct btrfs_r
                                ret = PTR_ERR(trans);
                                goto out;
                        }
-                       ret = btrfs_orphan_add(trans, inode);
+                       ret = btrfs_orphan_add(trans, BTRFS_I(inode));
                        btrfs_end_transaction(trans);
                        if (ret) {
                                iput(inode);
  
                        ret = btrfs_truncate(inode);
                        if (ret)
-                               btrfs_orphan_del(NULL, inode);
+                               btrfs_orphan_del(NULL, BTRFS_I(inode));
                } else {
                        nr_unlink++;
                }
@@@ -3623,7 -3610,7 +3616,7 @@@ static int btrfs_read_locked_inode(stru
        set_nlink(inode, btrfs_inode_nlink(leaf, inode_item));
        i_uid_write(inode, btrfs_inode_uid(leaf, inode_item));
        i_gid_write(inode, btrfs_inode_gid(leaf, inode_item));
-       btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
+       btrfs_i_size_write(BTRFS_I(inode), btrfs_inode_size(leaf, inode_item));
  
        inode->i_atime.tv_sec = btrfs_timespec_sec(leaf, &inode_item->atime);
        inode->i_atime.tv_nsec = btrfs_timespec_nsec(leaf, &inode_item->atime);
@@@ -3871,7 -3858,7 +3864,7 @@@ noinline int btrfs_update_inode(struct 
         * The data relocation inode should also be directly updated
         * without delay
         */
-       if (!btrfs_is_free_space_inode(inode)
+       if (!btrfs_is_free_space_inode(BTRFS_I(inode))
            && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID
            && !test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags)) {
                btrfs_update_root_times(trans, root);
@@@ -3994,8 -3981,7 +3987,7 @@@ err
        if (ret)
                goto out;
  
-       btrfs_i_size_write(&dir->vfs_inode,
-                       dir->vfs_inode.i_size - name_len * 2);
+       btrfs_i_size_write(dir, dir->vfs_inode.i_size - name_len * 2);
        inode_inc_iversion(&inode->vfs_inode);
        inode_inc_iversion(&dir->vfs_inode);
        inode->vfs_inode.i_ctime = dir->vfs_inode.i_mtime =
@@@ -4062,7 -4048,7 +4054,7 @@@ static int btrfs_unlink(struct inode *d
                goto out;
  
        if (inode->i_nlink == 0) {
-               ret = btrfs_orphan_add(trans, inode);
+               ret = btrfs_orphan_add(trans, BTRFS_I(inode));
                if (ret)
                        goto out;
        }
@@@ -4143,7 -4129,7 +4135,7 @@@ int btrfs_unlink_subvol(struct btrfs_tr
                goto out;
        }
  
-       btrfs_i_size_write(dir, dir->i_size - name_len * 2);
+       btrfs_i_size_write(BTRFS_I(dir), dir->i_size - name_len * 2);
        inode_inc_iversion(dir);
        dir->i_mtime = dir->i_ctime = current_time(dir);
        ret = btrfs_update_inode_fallback(trans, root, dir);
@@@ -4179,7 -4165,7 +4171,7 @@@ static int btrfs_rmdir(struct inode *di
                goto out;
        }
  
-       err = btrfs_orphan_add(trans, inode);
+       err = btrfs_orphan_add(trans, BTRFS_I(inode));
        if (err)
                goto out;
  
                        BTRFS_I(d_inode(dentry)), dentry->d_name.name,
                        dentry->d_name.len);
        if (!err) {
-               btrfs_i_size_write(inode, 0);
+               btrfs_i_size_write(BTRFS_I(inode), 0);
                /*
                 * Propagate the last_unlink_trans value of the deleted dir to
                 * its parent directory. This is to prevent an unrecoverable
@@@ -4326,7 -4312,7 +4318,7 @@@ int btrfs_truncate_inode_items(struct b
         * for non-free space inodes and ref cows, we want to back off from
         * time to time
         */
-       if (!btrfs_is_free_space_inode(inode) &&
+       if (!btrfs_is_free_space_inode(BTRFS_I(inode)) &&
            test_bit(BTRFS_ROOT_REF_COWS, &root->state))
                be_nice = 1;
  
         */
        if (test_bit(BTRFS_ROOT_REF_COWS, &root->state) ||
            root == fs_info->tree_root)
-               btrfs_drop_extent_cache(inode, ALIGN(new_size,
+               btrfs_drop_extent_cache(BTRFS_I(inode), ALIGN(new_size,
                                        fs_info->sectorsize),
                                        (u64)-1, 0);
  
@@@ -4418,8 -4404,19 +4410,8 @@@ search_again
                if (found_type > min_type) {
                        del_item = 1;
                } else {
 -                      if (item_end < new_size) {
 -                              /*
 -                               * With NO_HOLES mode, for the following mapping
 -                               *
 -                               * [0-4k][hole][8k-12k]
 -                               *
 -                               * if truncating isize down to 6k, it ends up
 -                               * isize being 8k.
 -                               */
 -                              if (btrfs_fs_incompat(root->fs_info, NO_HOLES))
 -                                      last_size = new_size;
 +                      if (item_end < new_size)
                                break;
 -                      }
                        if (found_key.offset >= new_size)
                                del_item = 1;
                        else
                        btrfs_abort_transaction(trans, ret);
        }
  error:
 -      if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
 +      if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
 +              ASSERT(last_size >= new_size);
 +              if (!err && last_size > new_size)
 +                      last_size = new_size;
                btrfs_ordered_update_i_size(inode, last_size, NULL);
 +      }
  
        btrfs_free_path(path);
  
@@@ -4834,7 -4827,7 +4826,7 @@@ int btrfs_cont_expand(struct inode *ino
  
                lock_extent_bits(io_tree, hole_start, block_end - 1,
                                 &cached_state);
-               ordered = btrfs_lookup_ordered_range(inode, hole_start,
+               ordered = btrfs_lookup_ordered_range(BTRFS_I(inode), hole_start,
                                                     block_end - hole_start);
                if (!ordered)
                        break;
  
        cur_offset = hole_start;
        while (1) {
-               em = btrfs_get_extent(inode, NULL, 0, cur_offset,
+               em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, cur_offset,
                                block_end - cur_offset, 0);
                if (IS_ERR(em)) {
                        err = PTR_ERR(em);
                                                hole_size);
                        if (err)
                                break;
-                       btrfs_drop_extent_cache(inode, cur_offset,
+                       btrfs_drop_extent_cache(BTRFS_I(inode), cur_offset,
                                                cur_offset + hole_size - 1, 0);
                        hole_em = alloc_extent_map();
                        if (!hole_em) {
                                write_unlock(&em_tree->lock);
                                if (err != -EEXIST)
                                        break;
-                               btrfs_drop_extent_cache(inode, cur_offset,
+                               btrfs_drop_extent_cache(BTRFS_I(inode),
+                                                       cur_offset,
                                                        cur_offset +
                                                        hole_size - 1, 0);
                        }
@@@ -4986,7 -4980,7 +4979,7 @@@ static int btrfs_setsize(struct inode *
                 * so we need to guarantee from this point on that everything
                 * will be consistent.
                 */
-               ret = btrfs_orphan_add(trans, inode);
+               ret = btrfs_orphan_add(trans, BTRFS_I(inode));
                btrfs_end_transaction(trans);
                if (ret)
                        return ret;
                truncate_setsize(inode, newsize);
  
                /* Disable nonlocked read DIO to avoid the end less truncate */
-               btrfs_inode_block_unlocked_dio(inode);
+               btrfs_inode_block_unlocked_dio(BTRFS_I(inode));
                inode_dio_wait(inode);
-               btrfs_inode_resume_unlocked_dio(inode);
+               btrfs_inode_resume_unlocked_dio(BTRFS_I(inode));
  
                ret = btrfs_truncate(inode);
                if (ret && inode->i_nlink) {
                        /* To get a stable disk_i_size */
                        err = btrfs_wait_ordered_range(inode, 0, (u64)-1);
                        if (err) {
-                               btrfs_orphan_del(NULL, inode);
+                               btrfs_orphan_del(NULL, BTRFS_I(inode));
                                return err;
                        }
  
                         */
                        trans = btrfs_join_transaction(root);
                        if (IS_ERR(trans)) {
-                               btrfs_orphan_del(NULL, inode);
+                               btrfs_orphan_del(NULL, BTRFS_I(inode));
                                return ret;
                        }
                        i_size_write(inode, BTRFS_I(inode)->disk_i_size);
-                       err = btrfs_orphan_del(trans, inode);
+                       err = btrfs_orphan_del(trans, BTRFS_I(inode));
                        if (err)
                                btrfs_abort_transaction(trans, err);
                        btrfs_end_transaction(trans);
@@@ -5180,18 -5174,18 +5173,18 @@@ void btrfs_evict_inode(struct inode *in
        if (inode->i_nlink &&
            ((btrfs_root_refs(&root->root_item) != 0 &&
              root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID) ||
-            btrfs_is_free_space_inode(inode)))
+            btrfs_is_free_space_inode(BTRFS_I(inode))))
                goto no_delete;
  
        if (is_bad_inode(inode)) {
-               btrfs_orphan_del(NULL, inode);
+               btrfs_orphan_del(NULL, BTRFS_I(inode));
                goto no_delete;
        }
        /* do we really want it for ->i_nlink > 0 and zero btrfs_root_refs? */
        if (!special_file(inode->i_mode))
                btrfs_wait_ordered_range(inode, 0, (u64)-1);
  
-       btrfs_free_io_failure_record(inode, 0, (u64)-1);
+       btrfs_free_io_failure_record(BTRFS_I(inode), 0, (u64)-1);
  
        if (test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags)) {
                BUG_ON(test_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
  
        ret = btrfs_commit_inode_delayed_inode(BTRFS_I(inode));
        if (ret) {
-               btrfs_orphan_del(NULL, inode);
+               btrfs_orphan_del(NULL, BTRFS_I(inode));
                goto no_delete;
        }
  
        rsv = btrfs_alloc_block_rsv(fs_info, BTRFS_BLOCK_RSV_TEMP);
        if (!rsv) {
-               btrfs_orphan_del(NULL, inode);
+               btrfs_orphan_del(NULL, BTRFS_I(inode));
                goto no_delete;
        }
        rsv->size = min_size;
        rsv->failfast = 1;
        global_rsv = &fs_info->global_block_rsv;
  
-       btrfs_i_size_write(inode, 0);
+       btrfs_i_size_write(BTRFS_I(inode), 0);
  
        /*
         * This is a bit simpler than btrfs_truncate since we've already
                        btrfs_warn(fs_info,
                                   "Could not get space for a delete, will truncate on mount %d",
                                   ret);
-                       btrfs_orphan_del(NULL, inode);
+                       btrfs_orphan_del(NULL, BTRFS_I(inode));
                        btrfs_free_block_rsv(fs_info, rsv);
                        goto no_delete;
                }
  
                trans = btrfs_join_transaction(root);
                if (IS_ERR(trans)) {
-                       btrfs_orphan_del(NULL, inode);
+                       btrfs_orphan_del(NULL, BTRFS_I(inode));
                        btrfs_free_block_rsv(fs_info, rsv);
                        goto no_delete;
                }
                if (ret) {
                        ret = btrfs_commit_transaction(trans);
                        if (ret) {
-                               btrfs_orphan_del(NULL, inode);
+                               btrfs_orphan_del(NULL, BTRFS_I(inode));
                                btrfs_free_block_rsv(fs_info, rsv);
                                goto no_delete;
                        }
         */
        if (ret == 0) {
                trans->block_rsv = root->orphan_block_rsv;
-               btrfs_orphan_del(trans, inode);
+               btrfs_orphan_del(trans, BTRFS_I(inode));
        } else {
-               btrfs_orphan_del(NULL, inode);
+               btrfs_orphan_del(NULL, BTRFS_I(inode));
        }
  
        trans->block_rsv = &fs_info->trans_block_rsv;
@@@ -5897,7 -5891,8 +5890,8 @@@ int btrfs_write_inode(struct inode *ino
        if (test_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags))
                return 0;
  
-       if (btrfs_fs_closing(root->fs_info) && btrfs_is_free_space_inode(inode))
+       if (btrfs_fs_closing(root->fs_info) &&
+                       btrfs_is_free_space_inode(BTRFS_I(inode)))
                nolock = true;
  
        if (wbc->sync_mode == WB_SYNC_ALL) {
@@@ -5977,15 -5972,15 +5971,15 @@@ static int btrfs_update_time(struct ino
   * and then set the in-memory index_cnt variable to reflect
   * free sequence numbers
   */
- static int btrfs_set_inode_index_count(struct inode *inode)
+ static int btrfs_set_inode_index_count(struct btrfs_inode *inode)
  {
-       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_root *root = inode->root;
        struct btrfs_key key, found_key;
        struct btrfs_path *path;
        struct extent_buffer *leaf;
        int ret;
  
-       key.objectid = btrfs_ino(BTRFS_I(inode));
+       key.objectid = btrfs_ino(inode);
        key.type = BTRFS_DIR_INDEX_KEY;
        key.offset = (u64)-1;
  
         * else has to start at 2
         */
        if (path->slots[0] == 0) {
-               BTRFS_I(inode)->index_cnt = 2;
+               inode->index_cnt = 2;
                goto out;
        }
  
        leaf = path->nodes[0];
        btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
  
-       if (found_key.objectid != btrfs_ino(BTRFS_I(inode)) ||
+       if (found_key.objectid != btrfs_ino(inode) ||
            found_key.type != BTRFS_DIR_INDEX_KEY) {
-               BTRFS_I(inode)->index_cnt = 2;
+               inode->index_cnt = 2;
                goto out;
        }
  
-       BTRFS_I(inode)->index_cnt = found_key.offset + 1;
+       inode->index_cnt = found_key.offset + 1;
  out:
        btrfs_free_path(path);
        return ret;
   * helper to find a free sequence number in a given directory.  This current
   * code is very simple, later versions will do smarter things in the btree
   */
- int btrfs_set_inode_index(struct inode *dir, u64 *index)
+ int btrfs_set_inode_index(struct btrfs_inode *dir, u64 *index)
  {
        int ret = 0;
  
-       if (BTRFS_I(dir)->index_cnt == (u64)-1) {
-               ret = btrfs_inode_delayed_dir_index_count(BTRFS_I(dir));
+       if (dir->index_cnt == (u64)-1) {
+               ret = btrfs_inode_delayed_dir_index_count(dir);
                if (ret) {
                        ret = btrfs_set_inode_index_count(dir);
                        if (ret)
                }
        }
  
-       *index = BTRFS_I(dir)->index_cnt;
-       BTRFS_I(dir)->index_cnt++;
+       *index = dir->index_cnt;
+       dir->index_cnt++;
  
        return ret;
  }
@@@ -6108,7 -6103,7 +6102,7 @@@ static struct inode *btrfs_new_inode(st
        if (dir && name) {
                trace_btrfs_inode_request(dir);
  
-               ret = btrfs_set_inode_index(dir, index);
+               ret = btrfs_set_inode_index(BTRFS_I(dir), index);
                if (ret) {
                        btrfs_free_path(path);
                        iput(inode);
@@@ -6243,18 -6238,18 +6237,18 @@@ static inline u8 btrfs_inode_type(struc
   * inode to the parent directory.
   */
  int btrfs_add_link(struct btrfs_trans_handle *trans,
-                  struct inode *parent_inode, struct inode *inode,
+                  struct btrfs_inode *parent_inode, struct btrfs_inode *inode,
                   const char *name, int name_len, int add_backref, u64 index)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
        int ret = 0;
        struct btrfs_key key;
-       struct btrfs_root *root = BTRFS_I(parent_inode)->root;
-       u64 ino = btrfs_ino(BTRFS_I(inode));
-       u64 parent_ino = btrfs_ino(BTRFS_I(parent_inode));
+       struct btrfs_root *root = parent_inode->root;
+       u64 ino = btrfs_ino(inode);
+       u64 parent_ino = btrfs_ino(parent_inode);
  
        if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) {
-               memcpy(&key, &BTRFS_I(inode)->root->root_key, sizeof(key));
+               memcpy(&key, &inode->root->root_key, sizeof(key));
        } else {
                key.objectid = ino;
                key.type = BTRFS_INODE_ITEM_KEY;
  
        ret = btrfs_insert_dir_item(trans, root, name, name_len,
                                    parent_inode, &key,
-                                   btrfs_inode_type(inode), index);
+                                   btrfs_inode_type(&inode->vfs_inode), index);
        if (ret == -EEXIST || ret == -EOVERFLOW)
                goto fail_dir_item;
        else if (ret) {
                return ret;
        }
  
-       btrfs_i_size_write(parent_inode, parent_inode->i_size +
+       btrfs_i_size_write(parent_inode, parent_inode->vfs_inode.i_size +
                           name_len * 2);
-       inode_inc_iversion(parent_inode);
-       parent_inode->i_mtime = parent_inode->i_ctime =
-               current_time(parent_inode);
-       ret = btrfs_update_inode(trans, root, parent_inode);
+       inode_inc_iversion(&parent_inode->vfs_inode);
+       parent_inode->vfs_inode.i_mtime = parent_inode->vfs_inode.i_ctime =
+               current_time(&parent_inode->vfs_inode);
+       ret = btrfs_update_inode(trans, root, &parent_inode->vfs_inode);
        if (ret)
                btrfs_abort_transaction(trans, ret);
        return ret;
@@@ -6313,8 -6308,8 +6307,8 @@@ fail_dir_item
  }
  
  static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
-                           struct inode *dir, struct dentry *dentry,
-                           struct inode *inode, int backref, u64 index)
+                           struct btrfs_inode *dir, struct dentry *dentry,
+                           struct btrfs_inode *inode, int backref, u64 index)
  {
        int err = btrfs_add_link(trans, dir, inode,
                                 dentry->d_name.name, dentry->d_name.len,
@@@ -6370,7 -6365,8 +6364,8 @@@ static int btrfs_mknod(struct inode *di
        if (err)
                goto out_unlock_inode;
  
-       err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
+       err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode),
+                       0, index);
        if (err) {
                goto out_unlock_inode;
        } else {
@@@ -6447,7 -6443,8 +6442,8 @@@ static int btrfs_create(struct inode *d
        if (err)
                goto out_unlock_inode;
  
-       err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
+       err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode),
+                       0, index);
        if (err)
                goto out_unlock_inode;
  
@@@ -6489,7 -6486,7 +6485,7 @@@ static int btrfs_link(struct dentry *ol
        if (inode->i_nlink >= BTRFS_LINK_MAX)
                return -EMLINK;
  
-       err = btrfs_set_inode_index(dir, &index);
+       err = btrfs_set_inode_index(BTRFS_I(dir), &index);
        if (err)
                goto fail;
  
        ihold(inode);
        set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags);
  
-       err = btrfs_add_nondir(trans, dir, dentry, inode, 1, index);
+       err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode),
+                       1, index);
  
        if (err) {
                drop_inode = 1;
                         * If new hard link count is 1, it's a file created
                         * with open(2) O_TMPFILE flag.
                         */
-                       err = btrfs_orphan_del(trans, inode);
+                       err = btrfs_orphan_del(trans, BTRFS_I(inode));
                        if (err)
                                goto fail;
                }
@@@ -6588,13 -6586,14 +6585,14 @@@ static int btrfs_mkdir(struct inode *di
        if (err)
                goto out_fail_inode;
  
-       btrfs_i_size_write(inode, 0);
+       btrfs_i_size_write(BTRFS_I(inode), 0);
        err = btrfs_update_inode(trans, root, inode);
        if (err)
                goto out_fail_inode;
  
-       err = btrfs_add_link(trans, dir, inode, dentry->d_name.name,
-                            dentry->d_name.len, 0, index);
+       err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode),
+                       dentry->d_name.name,
+                       dentry->d_name.len, 0, index);
        if (err)
                goto out_fail_inode;
  
@@@ -6724,25 -6723,26 +6722,26 @@@ static noinline int uncompress_inline(s
   * This also copies inline extents directly into the page.
   */
  
- struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
-                                   size_t pg_offset, u64 start, u64 len,
-                                   int create)
+ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
+               struct page *page,
+           size_t pg_offset, u64 start, u64 len,
+               int create)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
        int ret;
        int err = 0;
        u64 extent_start = 0;
        u64 extent_end = 0;
-       u64 objectid = btrfs_ino(BTRFS_I(inode));
+       u64 objectid = btrfs_ino(inode);
        u32 found_type;
        struct btrfs_path *path = NULL;
-       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_root *root = inode->root;
        struct btrfs_file_extent_item *item;
        struct extent_buffer *leaf;
        struct btrfs_key found_key;
        struct extent_map *em = NULL;
-       struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
-       struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
+       struct extent_map_tree *em_tree = &inode->extent_tree;
+       struct extent_io_tree *io_tree = &inode->io_tree;
        struct btrfs_trans_handle *trans = NULL;
        const bool new_inline = !page || create;
  
@@@ -6855,7 -6855,8 +6854,8 @@@ next
                goto not_found_em;
        }
  
-       btrfs_extent_item_to_extent_map(inode, path, item, new_inline, em);
+       btrfs_extent_item_to_extent_map(inode, path, item,
+                       new_inline, em);
  
        if (found_type == BTRFS_FILE_EXTENT_REG ||
            found_type == BTRFS_FILE_EXTENT_PREALLOC) {
@@@ -6991,7 -6992,7 +6991,7 @@@ insert
        write_unlock(&em_tree->lock);
  out:
  
-       trace_btrfs_get_extent(root, BTRFS_I(inode), em);
+       trace_btrfs_get_extent(root, inode, em);
  
        btrfs_free_path(path);
        if (trans) {
        return em;
  }
  
- struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *page,
-                                          size_t pg_offset, u64 start, u64 len,
-                                          int create)
+ struct extent_map *btrfs_get_extent_fiemap(struct btrfs_inode *inode,
+               struct page *page,
+               size_t pg_offset, u64 start, u64 len,
+               int create)
  {
        struct extent_map *em;
        struct extent_map *hole_em = NULL;
        em = NULL;
  
        /* ok, we didn't find anything, lets look for delalloc */
-       found = count_range_bits(&BTRFS_I(inode)->io_tree, &range_start,
+       found = count_range_bits(&inode->io_tree, &range_start,
                                 end, len, EXTENT_DELALLOC, 1);
        found_end = range_start + found;
        if (found_end < range_start)
@@@ -7161,7 -7163,7 +7162,7 @@@ static struct extent_map *btrfs_create_
        if (ret) {
                if (em) {
                        free_extent_map(em);
-                       btrfs_drop_extent_cache(inode, start,
+                       btrfs_drop_extent_cache(BTRFS_I(inode), start,
                                                start + len - 1, 0);
                }
                em = ERR_PTR(ret);
@@@ -7422,7 -7424,7 +7423,7 @@@ static int lock_extent_direct(struct in
                 * doing DIO to, so we need to make sure there's no ordered
                 * extents in this range.
                 */
-               ordered = btrfs_lookup_ordered_range(inode, lockstart,
+               ordered = btrfs_lookup_ordered_range(BTRFS_I(inode), lockstart,
                                                     lockend - lockstart + 1);
  
                /*
@@@ -7528,7 -7530,7 +7529,7 @@@ static struct extent_map *create_io_em(
        }
  
        do {
-               btrfs_drop_extent_cache(inode, em->start,
+               btrfs_drop_extent_cache(BTRFS_I(inode), em->start,
                                em->start + em->len - 1, 0);
                write_lock(&em_tree->lock);
                ret = add_extent_mapping(em_tree, em, 1);
@@@ -7616,7 -7618,7 +7617,7 @@@ static int btrfs_get_blocks_direct(stru
                goto err;
        }
  
-       em = btrfs_get_extent(inode, NULL, 0, start, len, 0);
+       em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, start, len, 0);
        if (IS_ERR(em)) {
                ret = PTR_ERR(em);
                goto unlock_err;
@@@ -7853,7 -7855,7 +7854,7 @@@ static int dio_read_error(struct inode 
        ret = btrfs_check_dio_repairable(inode, failed_bio, failrec,
                                         failed_mirror);
        if (!ret) {
-               free_io_failure(inode, failrec);
+               free_io_failure(BTRFS_I(inode), failrec);
                return -EIO;
        }
  
        bio = btrfs_create_repair_bio(inode, failed_bio, failrec, page,
                                pgoff, isector, repair_endio, repair_arg);
        if (!bio) {
-               free_io_failure(inode, failrec);
+               free_io_failure(BTRFS_I(inode), failrec);
                return -EIO;
        }
        bio_set_op_attrs(bio, REQ_OP_READ, read_mode);
  
        ret = submit_dio_repair_bio(inode, bio, failrec->this_mirror);
        if (ret) {
-               free_io_failure(inode, failrec);
+               free_io_failure(BTRFS_I(inode), failrec);
                bio_put(bio);
        }
  
@@@ -7908,7 -7910,7 +7909,7 @@@ static void btrfs_retry_endio_nocsum(st
  
        done->uptodate = 1;
        bio_for_each_segment_all(bvec, bio, i)
-               clean_io_failure(done->inode, done->start, bvec->bv_page, 0);
+       clean_io_failure(BTRFS_I(done->inode), done->start, bvec->bv_page, 0);
  end:
        complete(&done->done);
        bio_put(bio);
@@@ -7994,7 -7996,7 +7995,7 @@@ static void btrfs_retry_endio(struct bi
                                        bvec->bv_page, bvec->bv_offset,
                                        done->start, bvec->bv_len);
                if (!ret)
-                       clean_io_failure(done->inode, done->start,
+                       clean_io_failure(BTRFS_I(done->inode), done->start,
                                        bvec->bv_page, bvec->bv_offset);
                else
                        uptodate = 0;
@@@ -8795,7 -8797,7 +8796,7 @@@ static void btrfs_invalidatepage(struc
                lock_extent_bits(tree, page_start, page_end, &cached_state);
  again:
        start = page_start;
-       ordered = btrfs_lookup_ordered_range(inode, start,
+       ordered = btrfs_lookup_ordered_range(BTRFS_I(inode), start,
                                        page_end - start + 1);
        if (ordered) {
                end = min(page_end, ordered->file_offset + ordered->len - 1);
@@@ -8961,7 -8963,8 +8962,8 @@@ again
         * we can't set the delalloc bits if there are pending ordered
         * extents.  Drop our locks and wait for them to finish
         */
-       ordered = btrfs_lookup_ordered_range(inode, page_start, PAGE_SIZE);
+       ordered = btrfs_lookup_ordered_range(BTRFS_I(inode), page_start,
+                       PAGE_SIZE);
        if (ordered) {
                unlock_extent_cached(io_tree, page_start, page_end,
                                     &cached_state, GFP_NOFS);
@@@ -9159,7 -9162,7 +9161,7 @@@ static int btrfs_truncate(struct inode 
  
        if (ret == 0 && inode->i_nlink > 0) {
                trans->block_rsv = root->orphan_block_rsv;
-               ret = btrfs_orphan_del(trans, inode);
+               ret = btrfs_orphan_del(trans, BTRFS_I(inode));
                if (ret)
                        err = ret;
        }
@@@ -9204,7 -9207,7 +9206,7 @@@ int btrfs_create_subvol_root(struct btr
        inode->i_fop = &btrfs_dir_file_operations;
  
        set_nlink(inode, 1);
-       btrfs_i_size_write(inode, 0);
+       btrfs_i_size_write(BTRFS_I(inode), 0);
        unlock_new_inode(inode);
  
        err = btrfs_subvol_inherit_props(trans, new_root, parent_root);
@@@ -9277,7 -9280,7 +9279,7 @@@ struct inode *btrfs_alloc_inode(struct 
  #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
  void btrfs_test_destroy_inode(struct inode *inode)
  {
-       btrfs_drop_extent_cache(inode, 0, (u64)-1, 0);
+       btrfs_drop_extent_cache(BTRFS_I(inode), 0, (u64)-1, 0);
        kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
  }
  #endif
@@@ -9332,7 -9335,7 +9334,7 @@@ void btrfs_destroy_inode(struct inode *
        }
        btrfs_qgroup_check_reserved_leak(inode);
        inode_tree_del(inode);
-       btrfs_drop_extent_cache(inode, 0, (u64)-1, 0);
+       btrfs_drop_extent_cache(BTRFS_I(inode), 0, (u64)-1, 0);
  free:
        call_rcu(&inode->i_rcu, btrfs_i_callback);
  }
@@@ -9479,10 -9482,10 +9481,10 @@@ static int btrfs_rename_exchange(struc
         * We need to find a free sequence number both in the source and
         * in the destination directory for the exchange.
         */
-       ret = btrfs_set_inode_index(new_dir, &old_idx);
+       ret = btrfs_set_inode_index(BTRFS_I(new_dir), &old_idx);
        if (ret)
                goto out_fail;
-       ret = btrfs_set_inode_index(old_dir, &new_idx);
+       ret = btrfs_set_inode_index(BTRFS_I(old_dir), &new_idx);
        if (ret)
                goto out_fail;
  
                goto out_fail;
        }
  
-       ret = btrfs_add_link(trans, new_dir, old_inode,
+       ret = btrfs_add_link(trans, BTRFS_I(new_dir), BTRFS_I(old_inode),
                             new_dentry->d_name.name,
                             new_dentry->d_name.len, 0, old_idx);
        if (ret) {
                goto out_fail;
        }
  
-       ret = btrfs_add_link(trans, old_dir, new_inode,
+       ret = btrfs_add_link(trans, BTRFS_I(old_dir), BTRFS_I(new_inode),
                             old_dentry->d_name.name,
                             old_dentry->d_name.len, 0, new_idx);
        if (ret) {
@@@ -9690,8 -9693,8 +9692,8 @@@ static int btrfs_whiteout_for_rename(st
        if (ret)
                goto out;
  
-       ret = btrfs_add_nondir(trans, dir, dentry,
-                               inode, 0, index);
+       ret = btrfs_add_nondir(trans, BTRFS_I(dir), dentry,
+                               BTRFS_I(inode), 0, index);
        if (ret)
                goto out;
  
@@@ -9790,7 -9793,7 +9792,7 @@@ static int btrfs_rename(struct inode *o
        if (dest != root)
                btrfs_record_root_in_trans(trans, dest);
  
-       ret = btrfs_set_inode_index(new_dir, &index);
+       ret = btrfs_set_inode_index(BTRFS_I(new_dir), &index);
        if (ret)
                goto out_fail;
  
                                                 new_dentry->d_name.len);
                }
                if (!ret && new_inode->i_nlink == 0)
-                       ret = btrfs_orphan_add(trans, d_inode(new_dentry));
+                       ret = btrfs_orphan_add(trans,
+                                       BTRFS_I(d_inode(new_dentry)));
                if (ret) {
                        btrfs_abort_transaction(trans, ret);
                        goto out_fail;
                }
        }
  
-       ret = btrfs_add_link(trans, new_dir, old_inode,
+       ret = btrfs_add_link(trans, BTRFS_I(new_dir), BTRFS_I(old_inode),
                             new_dentry->d_name.name,
                             new_dentry->d_name.len, 0, index);
        if (ret) {
@@@ -10231,7 -10235,7 +10234,7 @@@ static int btrfs_symlink(struct inode *
        inode_nohighmem(inode);
        inode->i_mapping->a_ops = &btrfs_symlink_aops;
        inode_set_bytes(inode, name_len);
-       btrfs_i_size_write(inode, name_len);
+       btrfs_i_size_write(BTRFS_I(inode), name_len);
        err = btrfs_update_inode(trans, root, inode);
        /*
         * Last step, add directory indexes for our symlink inode. This is the
         * elsewhere above.
         */
        if (!err)
-               err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
+               err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry,
+                               BTRFS_I(inode), 0, index);
        if (err) {
                drop_inode = 1;
                goto out_unlock_inode;
@@@ -10325,7 -10330,7 +10329,7 @@@ static int __btrfs_prealloc_file_range(
                        break;
                }
  
-               btrfs_drop_extent_cache(inode, cur_offset,
+               btrfs_drop_extent_cache(BTRFS_I(inode), cur_offset,
                                        cur_offset + ins.offset -1, 0);
  
                em = alloc_extent_map();
                        write_unlock(&em_tree->lock);
                        if (ret != -EEXIST)
                                break;
-                       btrfs_drop_extent_cache(inode, cur_offset,
+                       btrfs_drop_extent_cache(BTRFS_I(inode), cur_offset,
                                                cur_offset + ins.offset - 1,
                                                0);
                }
@@@ -10474,7 -10479,7 +10478,7 @@@ static int btrfs_tmpfile(struct inode *
        ret = btrfs_update_inode(trans, root, inode);
        if (ret)
                goto out_inode;
-       ret = btrfs_orphan_add(trans, inode);
+       ret = btrfs_orphan_add(trans, BTRFS_I(inode));
        if (ret)
                goto out_inode;
  
@@@ -10504,6 -10509,12 +10508,12 @@@ out_inode
  
  }
  
+ __attribute__((const))
+ static int dummy_readpage_io_failed_hook(struct page *page, int failed_mirror)
+ {
+       return 0;
+ }
  static const struct inode_operations btrfs_dir_inode_operations = {
        .getattr        = btrfs_getattr,
        .lookup         = btrfs_lookup,
@@@ -10542,10 -10553,14 +10552,14 @@@ static const struct file_operations btr
  };
  
  static const struct extent_io_ops btrfs_extent_io_ops = {
-       .fill_delalloc = run_delalloc_range,
+       /* mandatory callbacks */
        .submit_bio_hook = btrfs_submit_bio_hook,
-       .merge_bio_hook = btrfs_merge_bio_hook,
        .readpage_end_io_hook = btrfs_readpage_end_io_hook,
+       .merge_bio_hook = btrfs_merge_bio_hook,
+       .readpage_io_failed_hook = dummy_readpage_io_failed_hook,
+       /* optional callbacks */
+       .fill_delalloc = run_delalloc_range,
        .writepage_end_io_hook = btrfs_writepage_end_io_hook,
        .writepage_start_hook = btrfs_writepage_start_hook,
        .set_bit_hook = btrfs_set_bit_hook,
diff --combined fs/btrfs/tree-log.c
index 3cc972330ab34a6409abc67633fa9ec78b782b14,c9ada4b90004125615238dd0de6845fee37c4954..a59674c3e69efb76d27d6705b41ca76d94e82e15
@@@ -673,10 -673,6 +673,10 @@@ static noinline int replay_one_extent(s
                unsigned long dest_offset;
                struct btrfs_key ins;
  
 +              if (btrfs_file_extent_disk_bytenr(eb, item) == 0 &&
 +                  btrfs_fs_incompat(fs_info, NO_HOLES))
 +                      goto update_inode;
 +
                ret = btrfs_insert_empty_item(trans, root, path, key,
                                              sizeof(*item));
                if (ret)
        }
  
        inode_add_bytes(inode, nbytes);
 +update_inode:
        ret = btrfs_update_inode(trans, root, inode);
  out:
        if (inode)
@@@ -1327,8 -1322,9 +1327,9 @@@ static noinline int add_inode_ref(struc
                        }
  
                        /* insert our name */
-                       ret = btrfs_add_link(trans, dir, inode, name, namelen,
-                                            0, ref_index);
+                       ret = btrfs_add_link(trans, BTRFS_I(dir),
+                                       BTRFS_I(inode),
+                                       name, namelen, 0, ref_index);
                        if (ret)
                                goto out;
  
@@@ -1646,7 -1642,8 +1647,8 @@@ static noinline int insert_one_name(str
                return -EIO;
        }
  
-       ret = btrfs_add_link(trans, dir, inode, name, name_len, 1, index);
+       ret = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), name,
+                       name_len, 1, index);
  
        /* FIXME, put inode into FIXUP list */
  
@@@ -1785,7 -1782,7 +1787,7 @@@ static noinline int replay_one_name(str
  out:
        btrfs_release_path(path);
        if (!ret && update_size) {
-               btrfs_i_size_write(dir, dir->i_size + name_len * 2);
+               btrfs_i_size_write(BTRFS_I(dir), dir->i_size + name_len * 2);
                ret = btrfs_update_inode(trans, root, dir);
        }
        kfree(name);
@@@ -5050,14 -5047,14 +5052,14 @@@ static bool btrfs_must_commit_transacti
   * a full commit is required.
   */
  static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,
-                                              struct inode *inode,
+                                              struct btrfs_inode *inode,
                                               struct dentry *parent,
                                               struct super_block *sb,
                                               u64 last_committed)
  {
        int ret = 0;
        struct dentry *old_parent = NULL;
-       struct inode *orig_inode = inode;
+       struct btrfs_inode *orig_inode = inode;
  
        /*
         * for regular files, if its inode is already on disk, we don't
         * we can use the last_unlink_trans field to record renames
         * and other fun in this file.
         */
-       if (S_ISREG(inode->i_mode) &&
-           BTRFS_I(inode)->generation <= last_committed &&
-           BTRFS_I(inode)->last_unlink_trans <= last_committed)
-                       goto out;
+       if (S_ISREG(inode->vfs_inode.i_mode) &&
+           inode->generation <= last_committed &&
+           inode->last_unlink_trans <= last_committed)
+               goto out;
  
-       if (!S_ISDIR(inode->i_mode)) {
+       if (!S_ISDIR(inode->vfs_inode.i_mode)) {
                if (!parent || d_really_is_negative(parent) || sb != parent->d_sb)
                        goto out;
-               inode = d_inode(parent);
+               inode = BTRFS_I(d_inode(parent));
        }
  
        while (1) {
                 * think this inode has already been logged.
                 */
                if (inode != orig_inode)
-                       BTRFS_I(inode)->logged_trans = trans->transid;
+                       inode->logged_trans = trans->transid;
                smp_mb();
  
-               if (btrfs_must_commit_transaction(trans, BTRFS_I(inode))) {
+               if (btrfs_must_commit_transaction(trans, inode)) {
                        ret = 1;
                        break;
                }
                        break;
  
                if (IS_ROOT(parent)) {
-                       inode = d_inode(parent);
-                       if (btrfs_must_commit_transaction(trans, BTRFS_I(inode)))
+                       inode = BTRFS_I(d_inode(parent));
+                       if (btrfs_must_commit_transaction(trans, inode))
                                ret = 1;
                        break;
                }
                parent = dget_parent(parent);
                dput(old_parent);
                old_parent = parent;
-               inode = d_inode(parent);
+               inode = BTRFS_I(d_inode(parent));
  
        }
        dput(old_parent);
@@@ -5292,15 -5289,15 +5294,15 @@@ next_dir_inode
  }
  
  static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
-                                struct inode *inode,
+                                struct btrfs_inode *inode,
                                 struct btrfs_log_ctx *ctx)
  {
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
        int ret;
        struct btrfs_path *path;
        struct btrfs_key key;
-       struct btrfs_root *root = BTRFS_I(inode)->root;
-       const u64 ino = btrfs_ino(BTRFS_I(inode));
+       struct btrfs_root *root = inode->root;
+       const u64 ino = btrfs_ino(inode);
  
        path = btrfs_alloc_path();
        if (!path)
@@@ -5395,7 -5392,8 +5397,8 @@@ out
   * the last committed transaction
   */
  static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
-                                 struct btrfs_root *root, struct inode *inode,
+                                 struct btrfs_root *root,
+                                 struct btrfs_inode *inode,
                                  struct dentry *parent,
                                  const loff_t start,
                                  const loff_t end,
        int ret = 0;
        u64 last_committed = fs_info->last_trans_committed;
        bool log_dentries = false;
-       struct inode *orig_inode = inode;
+       struct btrfs_inode *orig_inode = inode;
  
-       sb = inode->i_sb;
+       sb = inode->vfs_inode.i_sb;
  
        if (btrfs_test_opt(fs_info, NOTREELOG)) {
                ret = 1;
                goto end_no_trans;
        }
  
-       if (root != BTRFS_I(inode)->root ||
-           btrfs_root_refs(&root->root_item) == 0) {
+       if (root != inode->root || btrfs_root_refs(&root->root_item) == 0) {
                ret = 1;
                goto end_no_trans;
        }
  
-       ret = check_parent_dirs_for_sync(trans, inode, parent,
-                                        sb, last_committed);
+       ret = check_parent_dirs_for_sync(trans, inode, parent, sb,
+                       last_committed);
        if (ret)
                goto end_no_trans;
  
-       if (btrfs_inode_in_log(BTRFS_I(inode), trans->transid)) {
+       if (btrfs_inode_in_log(inode, trans->transid)) {
                ret = BTRFS_NO_LOG_SYNC;
                goto end_no_trans;
        }
        if (ret)
                goto end_no_trans;
  
-       ret = btrfs_log_inode(trans, root, BTRFS_I(inode), inode_only,
-                       start, end, ctx);
+       ret = btrfs_log_inode(trans, root, inode, inode_only, start, end, ctx);
        if (ret)
                goto end_trans;
  
         * we can use the last_unlink_trans field to record renames
         * and other fun in this file.
         */
-       if (S_ISREG(inode->i_mode) &&
-           BTRFS_I(inode)->generation <= last_committed &&
-           BTRFS_I(inode)->last_unlink_trans <= last_committed) {
+       if (S_ISREG(inode->vfs_inode.i_mode) &&
+           inode->generation <= last_committed &&
+           inode->last_unlink_trans <= last_committed) {
                ret = 0;
                goto end_trans;
        }
  
-       if (S_ISDIR(inode->i_mode) && ctx && ctx->log_new_dentries)
+       if (S_ISDIR(inode->vfs_inode.i_mode) && ctx && ctx->log_new_dentries)
                log_dentries = true;
  
        /*
         * but the file inode does not have a matching BTRFS_INODE_REF_KEY item
         * and has a link count of 2.
         */
-       if (BTRFS_I(inode)->last_unlink_trans > last_committed) {
+       if (inode->last_unlink_trans > last_committed) {
                ret = btrfs_log_all_parents(trans, orig_inode, ctx);
                if (ret)
                        goto end_trans;
                if (!parent || d_really_is_negative(parent) || sb != parent->d_sb)
                        break;
  
-               inode = d_inode(parent);
-               if (root != BTRFS_I(inode)->root)
+               inode = BTRFS_I(d_inode(parent));
+               if (root != inode->root)
                        break;
  
-               if (BTRFS_I(inode)->generation > last_committed) {
-                       ret = btrfs_log_inode(trans, root, BTRFS_I(inode),
-                                             LOG_INODE_EXISTS,
-                                             0, LLONG_MAX, ctx);
+               if (inode->generation > last_committed) {
+                       ret = btrfs_log_inode(trans, root, inode,
+                                       LOG_INODE_EXISTS, 0, LLONG_MAX, ctx);
                        if (ret)
                                goto end_trans;
                }
                old_parent = parent;
        }
        if (log_dentries)
-               ret = log_new_dir_dentries(trans, root, BTRFS_I(orig_inode), ctx);
+               ret = log_new_dir_dentries(trans, root, orig_inode, ctx);
        else
                ret = 0;
  end_trans:
@@@ -5571,8 -5566,8 +5571,8 @@@ int btrfs_log_dentry_safe(struct btrfs_
        struct dentry *parent = dget_parent(dentry);
        int ret;
  
-       ret = btrfs_log_inode_parent(trans, root, d_inode(dentry), parent,
-                                    start, end, 0, ctx);
+       ret = btrfs_log_inode_parent(trans, root, BTRFS_I(d_inode(dentry)),
+                       parent, start, end, 0, ctx);
        dput(parent);
  
        return ret;
@@@ -5834,7 -5829,7 +5834,7 @@@ int btrfs_log_new_name(struct btrfs_tra
            (!old_dir || old_dir->logged_trans <= fs_info->last_trans_committed))
                return 0;
  
-       return btrfs_log_inode_parent(trans, root, &inode->vfs_inode, parent, 0,
+       return btrfs_log_inode_parent(trans, root, inode, parent, 0,
                                      LLONG_MAX, 1, NULL);
  }