提交 5f39d397 编写于 作者: C Chris Mason

Btrfs: Create extent_buffer interface for large blocksizes

Signed-off-by: NChris Mason <chris.mason@oracle.com>
上级 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
此差异已折叠。
此差异已折叠。
......@@ -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);
......
......@@ -23,138 +23,132 @@
#include <linux/swap.h>
#include <linux/radix-tree.h>
#include <linux/writeback.h>
#include <linux/buffer_head.h> // for block_sync_page
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
#include "btrfs_inode.h"
u64 bh_blocknr(struct buffer_head *bh)
#if 0
static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf)
{
return bh->b_blocknr;
}
static int check_tree_block(struct btrfs_root *root, struct buffer_head *buf)
{
struct btrfs_node *node = btrfs_buffer_node(buf);
if (bh_blocknr(buf) != btrfs_header_blocknr(&node->header)) {
printk(KERN_CRIT "bh_blocknr(buf) is %llu, header is %llu\n",
(unsigned long long)bh_blocknr(buf),
(unsigned long long)btrfs_header_blocknr(&node->header));
if (extent_buffer_blocknr(buf) != btrfs_header_blocknr(buf)) {
printk(KERN_CRIT "buf blocknr(buf) is %llu, header is %llu\n",
(unsigned long long)extent_buffer_blocknr(buf),
(unsigned long long)btrfs_header_blocknr(buf));
return 1;
}
return 0;
}
#endif
struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr)
struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
u64 blocknr)
{
struct address_space *mapping = root->fs_info->btree_inode->i_mapping;
int blockbits = root->fs_info->sb->s_blocksize_bits;
unsigned long index = blocknr >> (PAGE_CACHE_SHIFT - blockbits);
struct page *page;
struct buffer_head *bh;
struct buffer_head *head;
struct buffer_head *ret = NULL;
page = find_lock_page(mapping, index);
if (!page)
return NULL;
if (!page_has_buffers(page))
goto out_unlock;
struct inode *btree_inode = root->fs_info->btree_inode;
return find_extent_buffer(&BTRFS_I(btree_inode)->extent_tree,
blocknr * root->sectorsize,
root->sectorsize, GFP_NOFS);
}
head = page_buffers(page);
bh = head;
do {
if (buffer_mapped(bh) && bh_blocknr(bh) == blocknr) {
ret = bh;
get_bh(bh);
goto out_unlock;
}
bh = bh->b_this_page;
} while (bh != head);
out_unlock:
unlock_page(page);
page_cache_release(page);
return ret;
struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
u64 blocknr)
{
struct inode *btree_inode = root->fs_info->btree_inode;
return alloc_extent_buffer(&BTRFS_I(btree_inode)->extent_tree,
blocknr * root->sectorsize,
root->sectorsize, GFP_NOFS);
}
int btrfs_map_bh_to_logical(struct btrfs_root *root, struct buffer_head *bh,
u64 logical)
struct extent_map *btree_get_extent(struct inode *inode, struct page *page,
size_t page_offset, u64 start, u64 end,
int create)
{
if (logical == 0) {
bh->b_bdev = NULL;
bh->b_blocknr = 0;
set_buffer_mapped(bh);
} else {
map_bh(bh, root->fs_info->sb, logical);
struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
struct extent_map *em;
int ret;
again:
em = lookup_extent_mapping(em_tree, start, end);
if (em) {
goto out;
}
return 0;
em = alloc_extent_map(GFP_NOFS);
if (!em) {
em = ERR_PTR(-ENOMEM);
goto out;
}
em->start = 0;
em->end = (i_size_read(inode) & ~((u64)PAGE_CACHE_SIZE -1)) - 1;
em->block_start = 0;
em->block_end = em->end;
em->bdev = inode->i_sb->s_bdev;
ret = add_extent_mapping(em_tree, em);
if (ret == -EEXIST) {
free_extent_map(em);
em = NULL;
goto again;
} else if (ret) {
em = ERR_PTR(ret);
}
out:
return em;
}
struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root,
u64 blocknr)
static int btree_writepage(struct page *page, struct writeback_control *wbc)
{
struct address_space *mapping = root->fs_info->btree_inode->i_mapping;
int blockbits = root->fs_info->sb->s_blocksize_bits;
unsigned long index = blocknr >> (PAGE_CACHE_SHIFT - blockbits);
struct page *page;
struct buffer_head *bh;
struct buffer_head *head;
struct buffer_head *ret = NULL;
int err;
u64 first_block = index << (PAGE_CACHE_SHIFT - blockbits);
struct extent_map_tree *tree;
tree = &BTRFS_I(page->mapping->host)->extent_tree;
return extent_write_full_page(tree, page, btree_get_extent, wbc);
}
int btree_readpage(struct file *file, struct page *page)
{
struct extent_map_tree *tree;
tree = &BTRFS_I(page->mapping->host)->extent_tree;
return extent_read_full_page(tree, page, btree_get_extent);
}
page = find_or_create_page(mapping, index, GFP_NOFS);
if (!page)
return NULL;
static int btree_releasepage(struct page *page, gfp_t unused_gfp_flags)
{
struct extent_map_tree *tree;
int ret;
if (!page_has_buffers(page))
create_empty_buffers(page, root->fs_info->sb->s_blocksize, 0);
head = page_buffers(page);
bh = head;
do {
if (!buffer_mapped(bh)) {
err = btrfs_map_bh_to_logical(root, bh, first_block);
BUG_ON(err);
}
if (bh_blocknr(bh) == blocknr) {
ret = bh;
get_bh(bh);
goto out_unlock;
}
bh = bh->b_this_page;
first_block++;
} while (bh != head);
out_unlock:
unlock_page(page);
if (ret)
touch_buffer(ret);
page_cache_release(page);
BUG_ON(page->private != 1);
tree = &BTRFS_I(page->mapping->host)->extent_tree;
ret = try_release_extent_mapping(tree, page);
if (ret == 1) {
ClearPagePrivate(page);
set_page_private(page, 0);
page_cache_release(page);
}
return ret;
}
static int btree_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh, int create)
static void btree_invalidatepage(struct page *page, unsigned long offset)
{
int err;
struct btrfs_root *root = BTRFS_I(bh->b_page->mapping->host)->root;
err = btrfs_map_bh_to_logical(root, bh, iblock);
return err;
struct extent_map_tree *tree;
tree = &BTRFS_I(page->mapping->host)->extent_tree;
extent_invalidatepage(tree, page, offset);
btree_releasepage(page, GFP_NOFS);
}
int btrfs_csum_data(struct btrfs_root * root, char *data, size_t len,
char *result)
{
return 0;
#if 0
u32 crc;
crc = crc32c(0, data, len);
memcpy(result, &crc, BTRFS_CRC32_SIZE);
return 0;
#endif
}
static int csum_tree_block(struct btrfs_root *root, struct buffer_head *bh,
#if 0
static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
int verify)
{
return 0;
char result[BTRFS_CRC32_SIZE];
int ret;
struct btrfs_node *node;
......@@ -176,7 +170,9 @@ static int csum_tree_block(struct btrfs_root *root, struct buffer_head *bh,
}
return 0;
}
#endif
#if 0
static int btree_writepage(struct page *page, struct writeback_control *wbc)
{
struct buffer_head *bh;
......@@ -195,87 +191,65 @@ static int btree_writepage(struct page *page, struct writeback_control *wbc)
} while (bh != head);
return block_write_full_page(page, btree_get_block, wbc);
}
static int btree_readpage(struct file * file, struct page * page)
{
return block_read_full_page(page, btree_get_block);
}
#endif
static struct address_space_operations btree_aops = {
.readpage = btree_readpage,
.writepage = btree_writepage,
.releasepage = btree_releasepage,
.invalidatepage = btree_invalidatepage,
.sync_page = block_sync_page,
};
int readahead_tree_block(struct btrfs_root *root, u64 blocknr)
{
struct buffer_head *bh = NULL;
struct extent_buffer *buf = NULL;
struct inode *btree_inode = root->fs_info->btree_inode;
int ret = 0;
bh = btrfs_find_create_tree_block(root, blocknr);
if (!bh)
buf = btrfs_find_create_tree_block(root, blocknr);
if (!buf)
return 0;
if (buffer_uptodate(bh)) {
ret = 1;
goto done;
}
if (test_set_buffer_locked(bh)) {
ret = 1;
goto done;
}
if (!buffer_uptodate(bh)) {
get_bh(bh);
bh->b_end_io = end_buffer_read_sync;
submit_bh(READ, bh);
} else {
unlock_buffer(bh);
ret = 1;
}
done:
brelse(bh);
read_extent_buffer_pages(&BTRFS_I(btree_inode)->extent_tree,
buf, 0);
free_extent_buffer(buf);
return ret;
}
struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr)
struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr)
{
struct buffer_head *bh = NULL;
bh = btrfs_find_create_tree_block(root, blocknr);
if (!bh)
return bh;
if (buffer_uptodate(bh))
goto uptodate;
lock_buffer(bh);
if (!buffer_uptodate(bh)) {
get_bh(bh);
bh->b_end_io = end_buffer_read_sync;
submit_bh(READ, bh);
wait_on_buffer(bh);
if (!buffer_uptodate(bh))
goto fail;
} else {
unlock_buffer(bh);
}
uptodate:
if (!buffer_checked(bh)) {
csum_tree_block(root, bh, 1);
set_buffer_checked(bh);
}
if (check_tree_block(root, bh))
goto fail;
return bh;
fail:
brelse(bh);
return NULL;
struct extent_buffer *buf = NULL;
struct inode *btree_inode = root->fs_info->btree_inode;
buf = btrfs_find_create_tree_block(root, blocknr);
if (!buf)
return NULL;
read_extent_buffer_pages(&BTRFS_I(btree_inode)->extent_tree,
buf, 1);
return buf;
}
int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct buffer_head *buf)
struct extent_buffer *buf)
{
WARN_ON(atomic_read(&buf->b_count) == 0);
lock_buffer(buf);
clear_buffer_dirty(buf);
unlock_buffer(buf);
struct inode *btree_inode = root->fs_info->btree_inode;
clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf);
return 0;
}
int wait_on_tree_block_writeback(struct btrfs_root *root,
struct extent_buffer *buf)
{
struct inode *btree_inode = root->fs_info->btree_inode;
wait_on_extent_buffer_writeback(&BTRFS_I(btree_inode)->extent_tree,
buf);
return 0;
}
int set_tree_block_dirty(struct btrfs_root *root, struct extent_buffer *buf)
{
struct inode *btree_inode = root->fs_info->btree_inode;
set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf);
return 0;
}
......@@ -287,7 +261,9 @@ static int __setup_root(int blocksize,
root->node = NULL;
root->inode = NULL;
root->commit_root = NULL;
root->blocksize = blocksize;
root->sectorsize = blocksize;
root->nodesize = blocksize;
root->leafsize = blocksize;
root->ref_cows = 0;
root->fs_info = fs_info;
root->objectid = objectid;
......@@ -332,7 +308,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
struct btrfs_root *root;
struct btrfs_root *tree_root = fs_info->tree_root;
struct btrfs_path *path;
struct btrfs_leaf *l;
struct extent_buffer *l;
u64 highest_inode;
int ret = 0;
......@@ -361,11 +337,10 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
ret = -ENOENT;
goto out;
}
l = btrfs_buffer_leaf(path->nodes[0]);
memcpy(&root->root_item,
btrfs_item_ptr(l, path->slots[0], struct btrfs_root_item),
l = path->nodes[0];
read_extent_buffer(l, &root->root_item,
btrfs_item_ptr_offset(l, path->slots[0]),
sizeof(root->root_item));
memcpy(&root->root_key, location, sizeof(*location));
ret = 0;
out:
btrfs_release_path(root, path);
......@@ -406,21 +381,21 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
(unsigned long)root->root_key.objectid,
root);
if (ret) {
brelse(root->node);
free_extent_buffer(root->node);
kfree(root);
return ERR_PTR(ret);
}
ret = btrfs_set_root_name(root, name, namelen);
if (ret) {
brelse(root->node);
free_extent_buffer(root->node);
kfree(root);
return ERR_PTR(ret);
}
ret = btrfs_sysfs_add_root(root);
if (ret) {
brelse(root->node);
free_extent_buffer(root->node);
kfree(root->name);
kfree(root);
return ERR_PTR(ret);
......@@ -471,6 +446,9 @@ struct btrfs_root *open_ctree(struct super_block *sb)
fs_info->btree_inode->i_nlink = 1;
fs_info->btree_inode->i_size = sb->s_bdev->bd_inode->i_size;
fs_info->btree_inode->i_mapping->a_ops = &btree_aops;
extent_map_tree_init(&BTRFS_I(fs_info->btree_inode)->extent_tree,
fs_info->btree_inode->i_mapping,
GFP_NOFS);
fs_info->do_barriers = 1;
fs_info->closing = 0;
......@@ -493,10 +471,14 @@ struct btrfs_root *open_ctree(struct super_block *sb)
if (!fs_info->sb_buffer)
goto fail_iput;
disk_super = (struct btrfs_super_block *)fs_info->sb_buffer->b_data;
fs_info->disk_super = disk_super;
memcpy(&fs_info->super_copy, disk_super, sizeof(fs_info->super_copy));
read_extent_buffer(fs_info->sb_buffer, &fs_info->super_copy, 0,
sizeof(fs_info->super_copy));
read_extent_buffer(fs_info->sb_buffer, fs_info->fsid,
(unsigned long)btrfs_super_fsid(fs_info->sb_buffer),
BTRFS_FSID_SIZE);
disk_super = &fs_info->super_copy;
if (!btrfs_super_root(disk_super))
goto fail_sb_buffer;
......@@ -530,9 +512,9 @@ struct btrfs_root *open_ctree(struct super_block *sb)
return tree_root;
fail_tree_root:
btrfs_block_release(tree_root, tree_root->node);
free_extent_buffer(tree_root->node);
fail_sb_buffer:
btrfs_block_release(tree_root, fs_info->sb_buffer);
free_extent_buffer(fs_info->sb_buffer);
fail_iput:
iput(fs_info->btree_inode);
fail:
......@@ -546,31 +528,13 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
*root)
{
int ret;
struct buffer_head *bh = root->fs_info->sb_buffer;
lock_buffer(bh);
WARN_ON(atomic_read(&bh->b_count) < 1);
clear_buffer_dirty(bh);
csum_tree_block(root, bh, 0);
bh->b_end_io = end_buffer_write_sync;
get_bh(bh);
if (root->fs_info->do_barriers)
ret = submit_bh(WRITE_BARRIER, bh);
else
ret = submit_bh(WRITE, bh);
if (ret == -EOPNOTSUPP) {
get_bh(bh);
lock_buffer(bh);
set_buffer_uptodate(bh);
root->fs_info->do_barriers = 0;
ret = submit_bh(WRITE, bh);
}
wait_on_buffer(bh);
if (!buffer_uptodate(bh)) {
WARN_ON(1);
return -EIO;
}
return 0;
struct extent_buffer *super = root->fs_info->sb_buffer;
struct inode *btree_inode = root->fs_info->btree_inode;
set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, super);
ret = sync_page_range_nolock(btree_inode, btree_inode->i_mapping,
super->start, super->len);
return ret;
}
int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
......@@ -581,9 +545,9 @@ int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
if (root->inode)
iput(root->inode);
if (root->node)
brelse(root->node);
free_extent_buffer(root->node);
if (root->commit_root)
brelse(root->commit_root);
free_extent_buffer(root->commit_root);
if (root->name)
kfree(root->name);
kfree(root);
......@@ -629,12 +593,10 @@ int close_ctree(struct btrfs_root *root)
mutex_unlock(&fs_info->fs_mutex);
if (fs_info->extent_root->node)
btrfs_block_release(fs_info->extent_root,
fs_info->extent_root->node);
free_extent_buffer(fs_info->extent_root->node);
if (fs_info->tree_root->node)
btrfs_block_release(fs_info->tree_root,
fs_info->tree_root->node);
btrfs_block_release(root, fs_info->sb_buffer);
free_extent_buffer(fs_info->tree_root->node);
free_extent_buffer(fs_info->sb_buffer);
truncate_inode_pages(fs_info->btree_inode->i_mapping, 0);
iput(fs_info->btree_inode);
......@@ -645,25 +607,32 @@ int close_ctree(struct btrfs_root *root)
return 0;
}
void btrfs_mark_buffer_dirty(struct buffer_head *bh)
int btrfs_buffer_uptodate(struct extent_buffer *buf)
{
struct inode *btree_inode = buf->pages[0]->mapping->host;
return extent_buffer_uptodate(&BTRFS_I(btree_inode)->extent_tree, buf);
}
int btrfs_set_buffer_uptodate(struct extent_buffer *buf)
{
struct btrfs_root *root = BTRFS_I(bh->b_page->mapping->host)->root;
u64 transid = btrfs_header_generation(btrfs_buffer_header(bh));
struct inode *btree_inode = buf->pages[0]->mapping->host;
return set_extent_buffer_uptodate(&BTRFS_I(btree_inode)->extent_tree,
buf);
}
WARN_ON(!atomic_read(&bh->b_count));
void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
{
struct btrfs_root *root = BTRFS_I(buf->pages[0]->mapping->host)->root;
u64 transid = btrfs_header_generation(buf);
struct inode *btree_inode = root->fs_info->btree_inode;
if (transid != root->fs_info->generation) {
printk(KERN_CRIT "transid mismatch buffer %llu, found %Lu running %Lu\n",
(unsigned long long)bh->b_blocknr,
(unsigned long long)extent_buffer_blocknr(buf),
transid, root->fs_info->generation);
WARN_ON(1);
}
mark_buffer_dirty(bh);
}
void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf)
{
brelse(buf);
set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf);
}
void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
......
......@@ -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
此差异已折叠。
此差异已折叠。
......@@ -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);
......
此差异已折叠。
......@@ -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)
......
此差异已折叠。
此差异已折叠。
......@@ -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
此差异已折叠。
......@@ -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) */
......
此差异已折叠。
......@@ -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
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册