// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2013 Fusion IO. All rights reserved.
*/
#include <linux/types.h>
#include "btrfs-tests.h"
#include "../ctree.h"
#include "../btrfs_inode.h"
#include "../disk-io.h"
#include "../extent_io.h"
#include "../volumes.h"
#include "../compression.h"
static void insert_extent(struct btrfs_root *root, u64 start, u64 len,
u64 ram_bytes, u64 offset, u64 disk_bytenr,
u64 disk_len, u32 type, u8 compression, int slot)
{
struct btrfs_path path;
struct btrfs_file_extent_item *fi;
struct extent_buffer *leaf = root->node;
struct btrfs_key key;
u32 value_len = sizeof(struct btrfs_file_extent_item);
if (type == BTRFS_FILE_EXTENT_INLINE)
value_len += len;
memset(&path, 0, sizeof(path));
path.nodes[0] = leaf;
path.slots[0] = slot;
key.objectid = BTRFS_FIRST_FREE_OBJECTID;
key.type = BTRFS_EXTENT_DATA_KEY;
key.offset = start;
setup_items_for_insert(root, &path, &key, &value_len, 1);
fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
btrfs_set_file_extent_generation(leaf, fi, 1);
btrfs_set_file_extent_type(leaf, fi, type);
btrfs_set_file_extent_disk_bytenr(leaf, fi, disk_bytenr);
btrfs_set_file_extent_disk_num_bytes(leaf, fi, disk_len);
btrfs_set_file_extent_offset(leaf, fi, offset);
btrfs_set_file_extent_num_bytes(leaf, fi, len);
btrfs_set_file_extent_ram_bytes(leaf, fi, ram_bytes);
btrfs_set_file_extent_compression(leaf, fi, compression);
btrfs_set_file_extent_encryption(leaf, fi, 0);
btrfs_set_file_extent_other_encoding(leaf, fi, 0);
}
static void insert_inode_item_key(struct btrfs_root *root)
{
struct btrfs_path path;
struct extent_buffer *leaf = root->node;
struct btrfs_key key;
u32 value_len = 0;
memset(&path, 0, sizeof(path));
path.nodes[0] = leaf;
path.slots[0] = 0;
key.objectid = BTRFS_INODE_ITEM_KEY;
key.type = BTRFS_INODE_ITEM_KEY;
key.offset = 0;
setup_items_for_insert(root, &path, &key, &value_len, 1);
}
/*
* Build the most complicated map of extents the earth has ever seen. We want
* this so we can test all of the corner cases of btrfs_get_extent. Here is a
* diagram of how the extents will look though this may not be possible we still
* want to make sure everything acts normally (the last number is not inclusive)
*
* [0 - 5][5 - 6][ 6 - 4096 ][ 4096 - 4100][4100 - 8195][8195 - 12291]
* [hole ][inline][hole but no extent][ hole ][ regular ][regular1 split]
*
* [12291 - 16387][16387 - 24579][24579 - 28675][ 28675 - 32771][32771 - 36867 ]
* [ hole ][regular1 split][ prealloc ][ prealloc1 ][prealloc1 written]
*
* [36867 - 45059][45059 - 53251][53251 - 57347][57347 - 61443][61443- 69635]
* [ prealloc1 ][ compressed ][ compressed1 ][ regular ][ compressed1]
*
* [69635-73731][ 73731 - 86019 ][86019-90115]
* [ regular ][ hole but no extent][ regular ]
*/
static void setup_file_extents(struct btrfs_root *root, u32 sectorsize)
{
int slot = 0;
u64 disk_bytenr = SZ_1M;
u64 offset = 0;
/* First we want a hole */
insert_extent(root, offset, 5, 5, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0,
slot);
slot++;
offset += 5;
/*
* Now we want an inline extent, I don't think this is possible but hey
* why not? Also keep in mind if we have an inline extent it counts as
* the whole first page. If we were to expand it we would have to cow
* and we wouldn't have an inline extent anymore.
*/
insert_extent(root, offset, 1, 1, 0, 0, 0, BTRFS_FILE_EXTENT_INLINE,