}
static int cache_ready;
-static struct fs_info *fs;
static struct btrfs_chunk_map chunk_map;
static struct btrfs_super_block sb;
/* used for small chunk read for btrfs_read */
}
/* raw read from disk, offset and count are bytes */
-static int raw_read(char *buf, u64 offset, u64 count)
+static int raw_read(struct fs_info *fs, char *buf, u64 offset, u64 count)
{
struct disk *disk = fs->fs_dev->disk;
size_t max = RAW_BUF_SIZE >> disk->sector_shift;
}
/* cache read from disk, offset and count are bytes */
-static int cache_read(char *buf, u64 offset, u64 count)
+static int cache_read(struct fs_info *fs, char *buf, u64 offset, u64 count)
{
const char *cd;
size_t block_size = fs->fs_dev->cache_block_size;
return total - count;
}
-static int btrfs_read(char *buf, u64 offset, u64 count)
+static int btrfs_read(struct fs_info *fs, char *buf, u64 offset, u64 count)
{
if (cache_ready)
- return cache_read(buf, offset, count);
- return raw_read(buf, offset, count);
+ return cache_read(fs, buf, offset, count);
+ return raw_read(fs, buf, offset, count);
}
/* btrfs has several super block mirrors, need to calculate their location */
}
/* find the most recent super block */
-static void btrfs_read_super_block(void)
+static void btrfs_read_super_block(struct fs_info *fs)
{
int i;
int ret;
/* find most recent super block */
for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
offset = btrfs_sb_offset(i);
- ret = btrfs_read((char *)&buf, offset, sizeof(buf));
+ ret = btrfs_read(fs, (char *)&buf, offset, sizeof(buf));
if (ret < sizeof(buf))
break;
}
/* seach tree directly on disk ... */
-static int search_tree(u64 loffset, struct btrfs_disk_key *key,
- struct btrfs_path *path)
+static int search_tree(struct fs_info *fs, u64 loffset,
+ struct btrfs_disk_key *key, struct btrfs_path *path)
{
u8 buf[BTRFS_MAX_LEAF_SIZE];
struct btrfs_header *header = (struct btrfs_header *)buf;
u64 offset;
offset = logical_physical(loffset);
- btrfs_read((char *)header, offset, sizeof(*header));
+ btrfs_read(fs, (char *)header, offset, sizeof(*header));
if (header->level) {/*node*/
- btrfs_read((char *)&node->ptrs[0], offset + sizeof(*header),
+ btrfs_read(fs, (char *)&node->ptrs[0], offset + sizeof(*header),
sb.nodesize - sizeof(*header));
path->itemsnr[header->level] = header->nritems;
path->offsets[header->level] = loffset;
if (ret && slot > path->slots[header->level])
slot--;
path->slots[header->level] = slot;
- ret = search_tree(node->ptrs[slot].blockptr, key, path);
+ ret = search_tree(fs, node->ptrs[slot].blockptr, key, path);
} else {/*leaf*/
- btrfs_read((char *)&leaf->items, offset + sizeof(*header),
+ btrfs_read(fs, (char *)&leaf->items, offset + sizeof(*header),
sb.leafsize - sizeof(*header));
path->itemsnr[header->level] = header->nritems;
path->offsets[0] = loffset;
slot--;
path->slots[0] = slot;
path->item = leaf->items[slot];
- btrfs_read((char *)&path->data,
+ btrfs_read(fs, (char *)&path->data,
offset + sizeof(*header) + leaf->items[slot].offset,
leaf->items[slot].size);
}
}
/* return 0 if leaf found */
-static int next_leaf(struct btrfs_disk_key *key, struct btrfs_path *path)
+static int next_leaf(struct fs_info *fs, struct btrfs_disk_key *key, struct btrfs_path *path)
{
int slot;
int level = 1;
}
path->slots[level] = slot;
path->slots[level-1] = 0; /* reset low level slots info */
- search_tree(path->offsets[level], key, path);
+ search_tree(fs, path->offsets[level], key, path);
break;
}
if (level == BTRFS_MAX_LEVEL)
}
/* return 0 if slot found */
-static int next_slot(struct btrfs_disk_key *key, struct btrfs_path *path)
+static int next_slot(struct fs_info *fs, struct btrfs_disk_key *key, struct btrfs_path *path)
{
int slot;
if (slot >= path->itemsnr[0])
return 1;
path->slots[0] = slot;
- search_tree(path->offsets[0], key, path);
+ search_tree(fs, path->offsets[0], key, path);
return 0;
}
}
/* read chunk items from chunk_tree and insert them to chunk map */
-static void btrfs_read_chunk_tree(void)
+static void btrfs_read_chunk_tree(struct fs_info *fs)
{
struct btrfs_disk_key search_key;
struct btrfs_chunk *chunk;
search_key.type = BTRFS_CHUNK_ITEM_KEY;
search_key.offset = 0;
clear_path(&path);
- search_tree(sb.chunk_root, &search_key, &path);
+ search_tree(fs, sb.chunk_root, &search_key, &path);
do {
do {
if (btrfs_comp_keys_type(&search_key,
item.devid = chunk->stripe.devid;
item.physical = chunk->stripe.offset;
insert_map(&item);
- } while (!next_slot(&search_key, &path));
+ } while (!next_slot(fs, &search_key, &path));
if (btrfs_comp_keys_type(&search_key, &path.item.key))
break;
- } while (!next_leaf(&search_key, &path));
+ } while (!next_leaf(fs, &search_key, &path));
}
}
search_key.type = BTRFS_INODE_ITEM_KEY;
search_key.offset = 0;
clear_path(&path);
- ret = search_tree(fs_tree, &search_key, &path);
+ ret = search_tree(fs, fs_tree, &search_key, &path);
if (ret)
return NULL;
inode_item = *(struct btrfs_inode_item *)path.data;
search_key.type = BTRFS_EXTENT_DATA_KEY;
search_key.offset = 0;
clear_path(&path);
- ret = search_tree(fs_tree, &search_key, &path);
+ ret = search_tree(fs, fs_tree, &search_key, &path);
if (ret)
return NULL; /* impossible */
extent_item = *(struct btrfs_file_extent_item *)path.data;
search_key.type = BTRFS_DIR_ITEM_KEY;
search_key.offset = btrfs_name_hash(name, strlen(name));
clear_path(&path);
- ret = search_tree(fs_tree, &search_key, &path);
+ ret = search_tree(fs, fs_tree, &search_key, &path);
if (ret)
return NULL;
dir_item = *(struct btrfs_dir_item *)path.data;
static int btrfs_readlink(struct inode *inode, char *buf)
{
- btrfs_read(buf, logical_physical(PVT(inode)->offset), inode->size);
+ btrfs_read(inode->fs, buf, logical_physical(PVT(inode)->offset), inode->size);
buf[inode->size] = '\0';
return inode->size;
}
struct btrfs_path path;
int ret;
u64 offset;
+ struct fs_info *fs = inode->fs;
u32 sec_shift = SECTOR_SHIFT(fs);
u32 sec_size = SECTOR_SIZE(fs);
search_key.type = BTRFS_EXTENT_DATA_KEY;
search_key.offset = lstart << sec_shift;
clear_path(&path);
- ret = search_tree(fs_tree, &search_key, &path);
+ ret = search_tree(fs, fs_tree, &search_key, &path);
if (ret) { /* impossible */
printf("btrfs: search extent data error!\n");
return 0;
bool *have_more)
{
u32 ret;
+ struct fs_info *fs = file->fs;
u32 off = PVT(file->inode)->offset % SECTOR_SIZE(fs);
bool handle_inline = false;
return ret;
}
-static void btrfs_get_fs_tree(void)
+static void btrfs_get_fs_tree(struct fs_info *fs)
{
struct btrfs_disk_key search_key;
struct btrfs_path path;
search_key.type = BTRFS_ROOT_REF_KEY;
search_key.offset = 0;
clear_path(&path);
- if (search_tree(sb.root, &search_key, &path))
- next_slot(&search_key, &path);
+ if (search_tree(fs, sb.root, &search_key, &path))
+ next_slot(fs, &search_key, &path);
do {
do {
struct btrfs_root_ref *ref;
subvol_ok = true;
break;
}
- } while (!next_slot(&search_key, &path));
+ } while (!next_slot(fs, &search_key, &path));
if (subvol_ok)
break;
if (btrfs_comp_keys_type(&search_key, &path.item.key))
break;
- } while (!next_leaf(&search_key, &path));
+ } while (!next_leaf(fs, &search_key, &path));
if (!subvol_ok) /* should be impossible */
printf("no subvol found!\n");
}
search_key.type = BTRFS_ROOT_ITEM_KEY;
search_key.offset = -1;
clear_path(&path);
- search_tree(sb.root, &search_key, &path);
+ search_tree(fs, sb.root, &search_key, &path);
tree = (struct btrfs_root_item *)path.data;
fs_tree = tree->bytenr;
}
fs->block_shift = BTRFS_BLOCK_SHIFT;
fs->block_size = 1 << fs->block_shift;
- btrfs_read_super_block();
+ btrfs_read_super_block(fs);
if (strncmp((char *)(&sb.magic), BTRFS_MAGIC, sizeof(sb.magic)))
return -1;
btrfs_read_sys_chunk_array();
- btrfs_read_chunk_tree();
- btrfs_get_fs_tree();
+ btrfs_read_chunk_tree(fs);
+ btrfs_get_fs_tree(fs);
cache_ready = 1;
/* Initialize the block cache */