Commit 5f39d397 authored by Chris Mason's avatar Chris Mason

Btrfs: Create extent_buffer interface for large blocksizes

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 50b78c24
......@@ -23,4 +23,6 @@ modules_install:
clean:
$(MAKE) -C $(KERNELDIR) M=`pwd` clean
tester:
$(MAKE) -C $(KERNELDIR) M=`pwd` tree-defrag.o transaction.o sysfs.o super.o root-tree.o inode-map.o inode-item.o inode.o file-item.o file.o extent_map.o disk-io.o ctree.o dir-item.o extent-tree.o
endif
This diff is collapsed.
This diff is collapsed.
......@@ -33,7 +33,7 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle
int ret;
char *ptr;
struct btrfs_item *item;
struct btrfs_leaf *leaf;
struct extent_buffer *leaf;
ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
if (ret == -EEXIST) {
......@@ -49,11 +49,11 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle
if (ret < 0)
return ERR_PTR(ret);
WARN_ON(ret > 0);
leaf = btrfs_buffer_leaf(path->nodes[0]);
item = leaf->items + path->slots[0];
leaf = path->nodes[0];
item = btrfs_item_nr(leaf, path->slots[0]);
ptr = btrfs_item_ptr(leaf, path->slots[0], char);
BUG_ON(data_size > btrfs_item_size(item));
ptr += btrfs_item_size(item) - data_size;
BUG_ON(data_size > btrfs_item_size(leaf, item));
ptr += btrfs_item_size(leaf, item) - data_size;
return (struct btrfs_dir_item *)ptr;
}
......@@ -65,12 +65,13 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
int ret2 = 0;
struct btrfs_path *path;
struct btrfs_dir_item *dir_item;
char *name_ptr;
struct extent_buffer *leaf;
unsigned long name_ptr;
struct btrfs_key key;
struct btrfs_disk_key disk_key;
u32 data_size;
key.objectid = dir;
key.flags = 0;
btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
ret = btrfs_name_hash(name, name_len, &key.offset);
BUG_ON(ret);
......@@ -85,14 +86,16 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
goto out;
}
btrfs_cpu_key_to_disk(&dir_item->location, location);
btrfs_set_dir_type(dir_item, type);
btrfs_set_dir_flags(dir_item, 0);
btrfs_set_dir_name_len(dir_item, name_len);
name_ptr = (char *)(dir_item + 1);
leaf = path->nodes[0];
btrfs_cpu_key_to_disk(&disk_key, location);
btrfs_set_dir_item_key(leaf, dir_item, &disk_key);
btrfs_set_dir_type(leaf, dir_item, type);
btrfs_set_dir_flags(leaf, dir_item, 0);
btrfs_set_dir_name_len(leaf, dir_item, name_len);
name_ptr = (unsigned long)(dir_item + 1);
btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len);
btrfs_mark_buffer_dirty(path->nodes[0]);
write_extent_buffer(leaf, name, name_ptr, name_len);
btrfs_mark_buffer_dirty(leaf);
second_insert:
/* FIXME, use some real flag for selecting the extra index */
......@@ -110,13 +113,15 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
ret2 = PTR_ERR(dir_item);
goto out;
}
btrfs_cpu_key_to_disk(&dir_item->location, location);
btrfs_set_dir_type(dir_item, type);
btrfs_set_dir_flags(dir_item, 0);
btrfs_set_dir_name_len(dir_item, name_len);
name_ptr = (char *)(dir_item + 1);
btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len);
btrfs_mark_buffer_dirty(path->nodes[0]);
leaf = path->nodes[0];
btrfs_cpu_key_to_disk(&disk_key, location);
btrfs_set_dir_item_key(leaf, dir_item, &disk_key);
btrfs_set_dir_type(leaf, dir_item, type);
btrfs_set_dir_flags(leaf, dir_item, 0);
btrfs_set_dir_name_len(leaf, dir_item, name_len);
name_ptr = (unsigned long)(dir_item + 1);
write_extent_buffer(leaf, name, name_ptr, name_len);
btrfs_mark_buffer_dirty(leaf);
out:
btrfs_free_path(path);
if (ret)
......@@ -136,14 +141,15 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans,
struct btrfs_key key;
int ins_len = mod < 0 ? -1 : 0;
int cow = mod != 0;
struct btrfs_disk_key *found_key;
struct btrfs_leaf *leaf;
struct btrfs_key found_key;
struct extent_buffer *leaf;
key.objectid = dir;
key.flags = 0;
btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
ret = btrfs_name_hash(name, name_len, &key.offset);
BUG_ON(ret);
ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
if (ret < 0)
return ERR_PTR(ret);
......@@ -152,12 +158,13 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans,
return NULL;
path->slots[0]--;
}
leaf = btrfs_buffer_leaf(path->nodes[0]);
found_key = &leaf->items[path->slots[0]].key;
if (btrfs_disk_key_objectid(found_key) != dir ||
btrfs_disk_key_type(found_key) != BTRFS_DIR_ITEM_KEY ||
btrfs_disk_key_offset(found_key) != key.offset)
leaf = path->nodes[0];
btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
if (found_key.objectid != dir ||
btrfs_key_type(&found_key) != BTRFS_DIR_ITEM_KEY ||
found_key.offset != key.offset)
return NULL;
return btrfs_match_dir_item_name(root, path, name, name_len);
......@@ -176,7 +183,6 @@ btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans,
int cow = mod != 0;
key.objectid = dir;
key.flags = 0;
btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY);
key.offset = objectid;
......@@ -193,21 +199,22 @@ struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
const char *name, int name_len)
{
struct btrfs_dir_item *dir_item;
char *name_ptr;
unsigned long name_ptr;
u32 total_len;
u32 cur = 0;
u32 this_len;
struct btrfs_leaf *leaf;
struct extent_buffer *leaf;
leaf = btrfs_buffer_leaf(path->nodes[0]);
leaf = path->nodes[0];
dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item);
total_len = btrfs_item_size(leaf->items + path->slots[0]);
total_len = btrfs_item_size_nr(leaf, path->slots[0]);
while(cur < total_len) {
this_len = sizeof(*dir_item) + btrfs_dir_name_len(dir_item);
name_ptr = (char *)(dir_item + 1);
this_len = sizeof(*dir_item) +
btrfs_dir_name_len(leaf, dir_item);
name_ptr = (unsigned long)(dir_item + 1);
if (btrfs_dir_name_len(dir_item) == name_len &&
memcmp(name_ptr, name, name_len) == 0)
if (btrfs_dir_name_len(leaf, dir_item) == name_len &&
memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)
return dir_item;
cur += this_len;
......@@ -223,20 +230,23 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
struct btrfs_dir_item *di)
{
struct btrfs_leaf *leaf;
struct extent_buffer *leaf;
u32 sub_item_len;
u32 item_len;
int ret = 0;
leaf = btrfs_buffer_leaf(path->nodes[0]);
sub_item_len = sizeof(*di) + btrfs_dir_name_len(di);
item_len = btrfs_item_size(leaf->items + path->slots[0]);
if (sub_item_len == btrfs_item_size(leaf->items + path->slots[0])) {
leaf = path->nodes[0];
sub_item_len = sizeof(*di) + btrfs_dir_name_len(leaf, di);
item_len = btrfs_item_size_nr(leaf, path->slots[0]);
if (sub_item_len == item_len) {
ret = btrfs_del_item(trans, root, path);
} else {
char *ptr = (char *)di;
char *start = btrfs_item_ptr(leaf, path->slots[0], char);
btrfs_memmove(root, leaf, ptr, ptr + sub_item_len,
/* MARKER */
unsigned long ptr = (unsigned long)di;
unsigned long start;
start = btrfs_item_ptr_offset(leaf, path->slots[0]);
memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
item_len - (ptr + sub_item_len - start));
ret = btrfs_truncate_item(trans, root, path,
item_len - sub_item_len);
......
This diff is collapsed.
......@@ -19,68 +19,35 @@
#ifndef __DISKIO__
#define __DISKIO__
#include <linux/buffer_head.h>
#define BTRFS_SUPER_INFO_OFFSET (16 * 1024)
enum btrfs_bh_state_bits {
BH_Checked = BH_PrivateStart,
BH_Defrag,
BH_DefragDone,
};
BUFFER_FNS(Checked, checked);
BUFFER_FNS(Defrag, defrag);
BUFFER_FNS(DefragDone, defrag_done);
static inline struct btrfs_node *btrfs_buffer_node(struct buffer_head *bh)
{
return (struct btrfs_node *)bh->b_data;
}
static inline struct btrfs_leaf *btrfs_buffer_leaf(struct buffer_head *bh)
{
return (struct btrfs_leaf *)bh->b_data;
}
static inline struct btrfs_header *btrfs_buffer_header(struct buffer_head *bh)
{
return &((struct btrfs_node *)bh->b_data)->header;
}
struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr);
struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr);
int readahead_tree_block(struct btrfs_root *root, u64 blocknr);
struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root,
u64 blocknr);
int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct buffer_head *buf);
int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct buffer_head *buf);
struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
u64 blocknr);
int clean_tree_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct buffer_head *buf);
int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
struct btrfs_root *root, struct extent_buffer *buf);
struct btrfs_root *open_ctree(struct super_block *sb);
int close_ctree(struct btrfs_root *root);
void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf);
int write_ctree_super(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr);
int btrfs_csum_data(struct btrfs_root * root, char *data, size_t len,
char *result);
struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
u64 blocknr);
struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
struct btrfs_key *location,
const char *name, int namelen);
struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
struct btrfs_key *location);
u64 bh_blocknr(struct buffer_head *bh);
int btrfs_insert_dev_radix(struct btrfs_root *root,
struct block_device *bdev,
u64 device_id,
u64 block_start,
u64 num_blocks);
int btrfs_map_bh_to_logical(struct btrfs_root *root, struct buffer_head *bh,
u64 logical);
void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr);
int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root);
void btrfs_mark_buffer_dirty(struct buffer_head *bh);
void btrfs_mark_buffer_dirty(struct extent_buffer *buf);
int btrfs_buffer_uptodate(struct extent_buffer *buf);
int btrfs_set_buffer_uptodate(struct extent_buffer *buf);
int wait_on_tree_block_writeback(struct btrfs_root *root,
struct extent_buffer *buf);
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -3,9 +3,20 @@
#include <linux/rbtree.h>
#define EXTENT_MAP_HOLE (u64)-3
#define EXTENT_MAP_INLINE (u64)-2
#define EXTENT_MAP_DELALLOC (u64)-1
/* bits for the extent state */
#define EXTENT_DIRTY 1
#define EXTENT_WRITEBACK (1 << 1)
#define EXTENT_UPTODATE (1 << 2)
#define EXTENT_LOCKED (1 << 3)
#define EXTENT_NEW (1 << 4)
#define EXTENT_DELALLOC (1 << 5)
#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
struct extent_map_ops {
int (*fill_delalloc)(struct inode *inode, u64 start, u64 end);
int (*writepage_io_hook)(struct page *page, u64 start, u64 end);
......@@ -51,10 +62,13 @@ struct extent_state {
struct list_head list;
};
#define EXTENT_BUFFER_SIZE(nr) (sizeof(struct extent_buffer) + \
(nr - 1) * sizeof(struct page *))
struct extent_buffer {
u64 start;
u64 end; /* inclusive */
char *addr;
unsigned long len;
atomic_t refs;
int flags;
struct page *pages[];
};
......@@ -87,8 +101,12 @@ int set_extent_new(struct extent_map_tree *tree, u64 start, u64 end,
gfp_t mask);
int set_extent_dirty(struct extent_map_tree *tree, u64 start, u64 end,
gfp_t mask);
int clear_extent_dirty(struct extent_map_tree *tree, u64 start, u64 end,
gfp_t mask);
int set_extent_delalloc(struct extent_map_tree *tree, u64 start, u64 end,
gfp_t mask);
int find_first_extent_bit(struct extent_map_tree *tree, u64 start,
u64 *start_ret, u64 *end_ret, int bits);
int extent_invalidatepage(struct extent_map_tree *tree,
struct page *page, unsigned long offset);
int extent_write_full_page(struct extent_map_tree *tree, struct page *page,
......@@ -106,4 +124,57 @@ int set_range_dirty(struct extent_map_tree *tree, u64 start, u64 end);
int set_state_private(struct extent_map_tree *tree, u64 start, u64 private);
int get_state_private(struct extent_map_tree *tree, u64 start, u64 *private);
void set_page_extent_mapped(struct page *page);
struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree,
u64 start, unsigned long len,
gfp_t mask);
struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree,
u64 start, unsigned long len,
gfp_t mask);
void free_extent_buffer(struct extent_buffer *eb);
int read_extent_buffer_pages(struct extent_map_tree *tree,
struct extent_buffer *eb, int wait);
static inline void extent_buffer_get(struct extent_buffer *eb)
{
atomic_inc(&eb->refs);
}
static inline u64 extent_buffer_blocknr(struct extent_buffer *eb)
{
return eb->start / 4096;
}
int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv,
unsigned long start,
unsigned long len);
void read_extent_buffer(struct extent_buffer *eb, void *dst,
unsigned long start,
unsigned long len);
void write_extent_buffer(struct extent_buffer *eb, const void *src,
unsigned long start, unsigned long len);
void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
unsigned long dst_offset, unsigned long src_offset,
unsigned long len);
void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
unsigned long src_offset, unsigned long len);
void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
unsigned long src_offset, unsigned long len);
void memset_extent_buffer(struct extent_buffer *eb, char c,
unsigned long start, unsigned long len);
int wait_on_extent_buffer_writeback(struct extent_map_tree *tree,
struct extent_buffer *eb);
int clear_extent_buffer_dirty(struct extent_map_tree *tree,
struct extent_buffer *eb);
int set_extent_buffer_dirty(struct extent_map_tree *tree,
struct extent_buffer *eb);
int set_extent_buffer_uptodate(struct extent_map_tree *tree,
struct extent_buffer *eb);
int extent_buffer_uptodate(struct extent_map_tree *tree,
struct extent_buffer *eb);
int map_extent_buffer(struct extent_buffer *eb, unsigned long offset,
char **token, char **map,
unsigned long *map_start,
unsigned long *map_len, int km);
void unmap_extent_buffer(struct extent_buffer *eb, char *token, int km);
#endif
......@@ -34,12 +34,12 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
struct btrfs_file_extent_item *item;
struct btrfs_key file_key;
struct btrfs_path *path;
struct extent_buffer *leaf;
path = btrfs_alloc_path();
BUG_ON(!path);
file_key.objectid = objectid;
file_key.offset = pos;
file_key.flags = 0;
btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY);
ret = btrfs_insert_empty_item(trans, root, path, &file_key,
......@@ -47,15 +47,16 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
if (ret < 0)
goto out;
BUG_ON(ret);
item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
leaf = path->nodes[0];
item = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_file_extent_item);
btrfs_set_file_extent_disk_blocknr(item, offset);
btrfs_set_file_extent_disk_num_blocks(item, disk_num_blocks);
btrfs_set_file_extent_offset(item, 0);
btrfs_set_file_extent_num_blocks(item, num_blocks);
btrfs_set_file_extent_generation(item, trans->transid);
btrfs_set_file_extent_type(item, BTRFS_FILE_EXTENT_REG);
btrfs_mark_buffer_dirty(path->nodes[0]);
btrfs_set_file_extent_disk_blocknr(leaf, item, offset);
btrfs_set_file_extent_disk_num_blocks(leaf, item, disk_num_blocks);
btrfs_set_file_extent_offset(leaf, item, 0);
btrfs_set_file_extent_num_blocks(leaf, item, num_blocks);
btrfs_set_file_extent_generation(leaf, item, trans->transid);
btrfs_set_file_extent_type(leaf, item, BTRFS_FILE_EXTENT_REG);
btrfs_mark_buffer_dirty(leaf);
out:
btrfs_free_path(path);
return ret;
......@@ -71,32 +72,30 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
struct btrfs_key file_key;
struct btrfs_key found_key;
struct btrfs_csum_item *item;
struct btrfs_leaf *leaf;
struct extent_buffer *leaf;
u64 csum_offset = 0;
int csums_in_item;
file_key.objectid = objectid;
file_key.offset = offset;
file_key.flags = 0;
btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY);
ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow);
if (ret < 0)
goto fail;
leaf = btrfs_buffer_leaf(path->nodes[0]);
leaf = path->nodes[0];
if (ret > 0) {
ret = 1;
if (path->slots[0] == 0)
goto fail;
path->slots[0]--;
btrfs_disk_key_to_cpu(&found_key,
&leaf->items[path->slots[0]].key);
btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY ||
found_key.objectid != objectid) {
goto fail;
}
csum_offset = (offset - found_key.offset) >>
root->fs_info->sb->s_blocksize_bits;
csums_in_item = btrfs_item_size(leaf->items + path->slots[0]);
csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]);
csums_in_item /= BTRFS_CRC32_SIZE;
if (csum_offset >= csums_in_item) {
......@@ -127,7 +126,6 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
file_key.objectid = objectid;
file_key.offset = offset;
file_key.flags = 0;
btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY);
ret = btrfs_search_slot(trans, root, &file_key, path, ins_len, cow);
return ret;
......@@ -138,12 +136,14 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
u64 objectid, u64 offset,
char *data, size_t len)
{
return 0;
#if 0
int ret;
struct btrfs_key file_key;
struct btrfs_key found_key;
struct btrfs_path *path;
struct btrfs_csum_item *item;
struct btrfs_leaf *leaf;
struct extent_buffer *leaf;
u64 csum_offset;
path = btrfs_alloc_path();
......@@ -161,8 +161,8 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
if (ret == -EFBIG) {
u32 item_size;
/* we found one, but it isn't big enough yet */
leaf = btrfs_buffer_leaf(path->nodes[0]);
item_size = btrfs_item_size(leaf->items + path->slots[0]);
leaf = path->nodes[0];
item_size = btrfs_item_size_nr(leaf, path->slots[0]);
if ((item_size / BTRFS_CRC32_SIZE) >= MAX_CSUM_ITEMS(root)) {
/* already at max size, make a new one */
goto insert;
......@@ -188,8 +188,8 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
goto insert;
}
path->slots[0]--;
leaf = btrfs_buffer_leaf(path->nodes[0]);
btrfs_disk_key_to_cpu(&found_key, &leaf->items[path->slots[0]].key);
leaf = path->nodes[0];
btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
csum_offset = (offset - found_key.offset) >>
root->fs_info->sb->s_blocksize_bits;
if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY ||
......@@ -197,10 +197,10 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
csum_offset >= MAX_CSUM_ITEMS(root)) {
goto insert;
}
if (csum_offset >= btrfs_item_size(leaf->items + path->slots[0]) /
if (csum_offset >= btrfs_item_size_nr(leaf, path->slots[0]) /
BTRFS_CRC32_SIZE) {
u32 diff = (csum_offset + 1) * BTRFS_CRC32_SIZE;
diff = diff - btrfs_item_size(leaf->items + path->slots[0]);
diff = diff - btrfs_item_size_nr(leaf, path->slots[0]);
if (diff != BTRFS_CRC32_SIZE)
goto insert;
ret = btrfs_extend_item(trans, root, path, diff);
......@@ -220,21 +220,20 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
goto fail;
}
csum:
item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
struct btrfs_csum_item);
leaf = path->nodes[0];
item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
ret = 0;
item = (struct btrfs_csum_item *)((unsigned char *)item +
csum_offset * BTRFS_CRC32_SIZE);
found:
btrfs_check_bounds(&item->csum, BTRFS_CRC32_SIZE,
path->nodes[0]->b_data,
root->fs_info->sb->s_blocksize);
/* FIXME!!!!!!!!!!!! */
ret = btrfs_csum_data(root, data, len, &item->csum);
btrfs_mark_buffer_dirty(path->nodes[0]);
fail:
btrfs_release_path(root, path);
btrfs_free_path(path);
return ret;
#endif
}
int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
......@@ -242,21 +241,21 @@ int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
u64 isize)
{
struct btrfs_key key;
struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[0]);
struct extent_buffer *leaf = path->nodes[0];
int slot = path->slots[0];
int ret;
u32 new_item_size;
u64 new_item_span;
u64 blocks;
btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key);
btrfs_item_key_to_cpu(leaf, &key, slot);
if (isize <= key.offset)
return 0;
new_item_span = isize - key.offset;
blocks = (new_item_span + root->blocksize - 1) >>
blocks = (new_item_span + root->sectorsize - 1) >>
root->fs_info->sb->s_blocksize_bits;
new_item_size = blocks * BTRFS_CRC32_SIZE;
if (new_item_size >= btrfs_item_size(leaf->items + slot))
if (new_item_size >= btrfs_item_size_nr(leaf, slot))
return 0;
ret = btrfs_truncate_item(trans, root, path, new_item_size);
BUG_ON(ret);
......
This diff is collapsed.
......@@ -20,24 +20,18 @@
#include "disk-io.h"
#include "transaction.h"
int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root
*root, u64 objectid, struct btrfs_inode_item
*inode_item)
int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_path *path, u64 objectid)
{
struct btrfs_path *path;
struct btrfs_key key;
int ret;
key.objectid = objectid;
key.flags = 0;
btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
key.offset = 0;
path = btrfs_alloc_path();
BUG_ON(!path);
ret = btrfs_insert_item(trans, root, &key, inode_item,
sizeof(*inode_item));
btrfs_release_path(root, path);
btrfs_free_path(path);
ret = btrfs_insert_empty_item(trans, root, path, &key,
sizeof(struct btrfs_inode_item));
if (ret == 0 && objectid > root->highest_inode)
root->highest_inode = objectid;
return ret;
......@@ -51,15 +45,15 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
int cow = mod != 0;
int ret;
int slot;
struct btrfs_leaf *leaf;
struct extent_buffer *leaf;
struct btrfs_key found_key;
ret = btrfs_search_slot(trans, root, location, path, ins_len, cow);
if (ret > 0 && btrfs_key_type(location) == BTRFS_ROOT_ITEM_KEY &&
location->offset == (u64)-1 && path->slots[0] != 0) {
slot = path->slots[0] - 1;
leaf = btrfs_buffer_leaf(path->nodes[0]);
btrfs_disk_key_to_cpu(&found_key, &leaf->items[slot].key);
leaf = path->nodes[0];
btrfs_item_key_to_cpu(leaf, &found_key, slot);
if (found_key.objectid == location->objectid &&
btrfs_key_type(&found_key) == btrfs_key_type(location)) {
path->slots[0]--;
......
......@@ -24,8 +24,9 @@ int btrfs_find_highest_inode(struct btrfs_root *root, u64 *objectid)
{
struct btrfs_path *path;
int ret;
struct btrfs_leaf *l;
struct extent_buffer *l;
struct btrfs_key search_key;
struct btrfs_key found_key;
int slot;
path = btrfs_alloc_path();
......@@ -39,8 +40,9 @@ int btrfs_find_highest_inode(struct btrfs_root *root, u64 *objectid)
BUG_ON(ret == 0);
if (path->slots[0] > 0) {
slot = path->slots[0] - 1;
l = btrfs_buffer_leaf(path->nodes[0]);
*objectid = btrfs_disk_key_objectid(&l->items[slot].key);
l = path->nodes[0];
btrfs_item_key_to_cpu(l, &found_key, slot);
*objectid = found_key.objectid;
} else {
*objectid = BTRFS_FIRST_FREE_OBJECTID;
}
......@@ -64,13 +66,12 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
int slot = 0;
u64 last_ino = 0;
int start_found;
struct btrfs_leaf *l;
struct extent_buffer *l;
struct btrfs_key search_key;
u64 search_start = dirid;
path = btrfs_alloc_path();
BUG_ON(!path);
search_key.flags = 0;
search_start = root->last_inode_alloc;
search_start = max(search_start, BTRFS_FIRST_FREE_OBJECTID);
search_key.objectid = search_start;
......@@ -86,9 +87,9 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
path->slots[0]--;
while (1) {
l = btrfs_buffer_leaf(path->nodes[0]);
l = path->nodes[0];
slot = path->slots[0];
if (slot >= btrfs_header_nritems(&l->header)) {
if (slot >= btrfs_header_nritems(l)) {
ret = btrfs_next_leaf(root, path);
if (ret == 0)
continue;
......@@ -103,7 +104,7 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
last_ino : search_start;
goto found;
}
btrfs_disk_key_to_cpu(&key, &l->items[slot].key);
btrfs_item_key_to_cpu(l, &key, slot);
if (key.objectid >= search_start) {
if (start_found) {
if (last_ino < search_start)
......
This diff is collapsed.
This diff is collapsed.
......@@ -18,6 +18,6 @@
#ifndef __PRINT_TREE_
#define __PRINT_TREE_
void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l);
void btrfs_print_tree(struct btrfs_root *root, struct buffer_head *t);
void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l);
void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *t);
#endif
This diff is collapsed.
......@@ -41,7 +41,7 @@
#include "ioctl.h"
#include "print-tree.h"
#define BTRFS_SUPER_MAGIC 0x9123682E
#define BTRFS_SUPER_MAGIC 0x9123683E
static struct super_operations btrfs_super_ops;
......@@ -115,13 +115,12 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
return -EIO;
}
sb->s_fs_info = tree_root;
disk_super = tree_root->fs_info->disk_super;
disk_super = &tree_root->fs_info->super_copy;
inode = btrfs_iget_locked(sb, btrfs_super_root_dir(disk_super),
tree_root);
bi = BTRFS_I(inode);
bi->location.objectid = inode->i_ino;
bi->location.offset = 0;
bi->location.flags = 0;
bi->root = tree_root;
btrfs_set_key_type(&bi->location, BTRFS_INODE_ITEM_KEY);
......@@ -281,6 +280,7 @@ int btrfs_get_sb_bdev(struct file_system_type *fs_type,
error_bdev:
close_bdev_excl(bdev);
error:
printk("get_sb failed\n");
return error;
}
/* end copy & paste */
......@@ -295,6 +295,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type,
ret = btrfs_get_sb_bdev(fs_type, flags, dev_name, data,
btrfs_fill_super, mnt,
subvol_name ? subvol_name : "default");
printk("btrfs_get_sb returns %d\n", ret);
return ret;
}
......
......@@ -31,31 +31,31 @@
static ssize_t root_blocks_used_show(struct btrfs_root *root, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%llu\n",
(unsigned long long)btrfs_root_blocks_used(&root->root_item));
(unsigned long long)btrfs_root_used(&root->root_item));
}
static ssize_t root_block_limit_show(struct btrfs_root *root, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%llu\n",
(unsigned long long)btrfs_root_block_limit(&root->root_item));
(unsigned long long)btrfs_root_limit(&root->root_item));
}
static ssize_t super_blocks_used_show(struct btrfs_fs_info *fs, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%llu\n",
(unsigned long long)btrfs_super_blocks_used(fs->disk_super));
(unsigned long long)btrfs_super_blocks_used(&fs->super_copy));
}
static ssize_t super_total_blocks_show(struct btrfs_fs_info *fs, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%llu\n",
(unsigned long long)btrfs_super_total_blocks(fs->disk_super));
(unsigned long long)btrfs_super_total_blocks(&fs->super_copy));
}
static ssize_t super_blocksize_show(struct btrfs_fs_info *fs, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%llu\n",
(unsigned long long)btrfs_super_blocksize(fs->disk_super));
(unsigned long long)btrfs_super_sectorsize(&fs->super_copy));
}
/* this is for root attrs (subvols/snapshots) */
......
This diff is collapsed.
......@@ -28,7 +28,7 @@ struct btrfs_transaction {
int use_count;
int commit_done;
struct list_head list;
struct radix_tree_root dirty_pages;
struct extent_map_tree dirty_pages;
unsigned long start_time;
wait_queue_head_t writer_wait;
wait_queue_head_t commit_wait;
......@@ -83,5 +83,6 @@ int btrfs_add_dead_root(struct btrfs_root *root, struct btrfs_root *latest,
int btrfs_defrag_dirty_roots(struct btrfs_fs_info *info);
int btrfs_defrag_root(struct btrfs_root *root, int cacheonly);
int btrfs_clean_old_snapshots(struct btrfs_root *root);
int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
#endif
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment