/*
         * Keep track of where the inode has extent items mapped in order to
-        * make sure the i_size adjustments are accurate
+        * make sure the i_size adjustments are accurate. Not required when the
+        * filesystem is NO_HOLES, the status can't be set while mounted as
+        * it's a mkfs-time feature.
         */
-       struct extent_io_tree file_extent_tree;
+       struct extent_io_tree *file_extent_tree;
 
        /* held while logging the inode in tree-log.c */
        struct mutex log_mutex;
 
                goto out_unlock;
        }
 
-       ret = find_contiguous_extent_bit(&inode->file_extent_tree, 0, &start,
+       ret = find_contiguous_extent_bit(inode->file_extent_tree, 0, &start,
                                         &end, EXTENT_DIRTY);
        if (!ret && start == 0)
                i_size = min(i_size, end + 1);
 
        if (btrfs_fs_incompat(inode->root->fs_info, NO_HOLES))
                return 0;
-       return set_extent_bit(&inode->file_extent_tree, start, start + len - 1,
+       return set_extent_bit(inode->file_extent_tree, start, start + len - 1,
                              EXTENT_DIRTY, NULL);
 }
 
 
        if (btrfs_fs_incompat(inode->root->fs_info, NO_HOLES))
                return 0;
-       return clear_extent_bit(&inode->file_extent_tree, start,
+       return clear_extent_bit(inode->file_extent_tree, start,
                                start + len - 1, EXTENT_DIRTY, NULL);
 }
 
 
        struct btrfs_fs_info *fs_info = btrfs_sb(sb);
        struct btrfs_inode *ei;
        struct inode *inode;
+       struct extent_io_tree *file_extent_tree = NULL;
+
+       /* Self tests may pass a NULL fs_info. */
+       if (fs_info && !btrfs_fs_incompat(fs_info, NO_HOLES)) {
+               file_extent_tree = kmalloc(sizeof(struct extent_io_tree), GFP_KERNEL);
+               if (!file_extent_tree)
+                       return NULL;
+       }
 
        ei = alloc_inode_sb(sb, btrfs_inode_cachep, GFP_KERNEL);
-       if (!ei)
+       if (!ei) {
+               kfree(file_extent_tree);
                return NULL;
+       }
 
        ei->root = NULL;
        ei->generation = 0;
        extent_io_tree_init(fs_info, &ei->io_tree, IO_TREE_INODE_IO);
        ei->io_tree.inode = ei;
 
-       extent_io_tree_init(fs_info, &ei->file_extent_tree,
-                           IO_TREE_INODE_FILE_EXTENT);
-       /* Lockdep class is set only for the file extent tree. */
-       lockdep_set_class(&ei->file_extent_tree.lock, &file_extent_tree_class);
+       ei->file_extent_tree = file_extent_tree;
+       if (file_extent_tree) {
+               extent_io_tree_init(fs_info, ei->file_extent_tree,
+                                   IO_TREE_INODE_FILE_EXTENT);
+               /* Lockdep class is set only for the file extent tree. */
+               lockdep_set_class(&ei->file_extent_tree->lock, &file_extent_tree_class);
+       }
        mutex_init(&ei->log_mutex);
        spin_lock_init(&ei->ordered_tree_lock);
        ei->ordered_tree = RB_ROOT;
 void btrfs_test_destroy_inode(struct inode *inode)
 {
        btrfs_drop_extent_map_range(BTRFS_I(inode), 0, (u64)-1, false);
+       kfree(BTRFS_I(inode)->file_extent_tree);
        kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
 }
 #endif
 
 void btrfs_free_inode(struct inode *inode)
 {
+       kfree(BTRFS_I(inode)->file_extent_tree);
        kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
 }