file-item.c 3.6 KB
Newer Older
1
#include <linux/module.h>
C
Chris Mason 已提交
2
#include "ctree.h"
C
Chris Mason 已提交
3
#include "disk-io.h"
4
#include "transaction.h"
C
Chris Mason 已提交
5

C
Chris Mason 已提交
6 7 8 9 10
int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans,
			       struct btrfs_root *root,
			       u64 objectid, u64 offset,
			       u64 num_blocks, u64 hint_block,
			       u64 *result)
11
{
C
Chris Mason 已提交
12 13 14 15
	struct btrfs_key ins;
	int ret = 0;
	struct btrfs_file_extent_item *item;
	struct btrfs_key file_key;
16
	struct btrfs_path *path;
C
Chris Mason 已提交
17

18 19 20
	path = btrfs_alloc_path();
	BUG_ON(!path);
	btrfs_init_path(path);
C
Chris Mason 已提交
21
	ret = btrfs_alloc_extent(trans, root, num_blocks, hint_block,
C
Chris Mason 已提交
22
				 (u64)-1, &ins);
C
Chris Mason 已提交
23 24 25 26 27 28
	BUG_ON(ret);
	file_key.objectid = objectid;
	file_key.offset = offset;
	file_key.flags = 0;
	btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY);

29
	ret = btrfs_insert_empty_item(trans, root, path, &file_key,
C
Chris Mason 已提交
30
				      sizeof(*item));
C
Chris Mason 已提交
31
	BUG_ON(ret);
32
	item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
C
Chris Mason 已提交
33 34 35 36 37
			      struct btrfs_file_extent_item);
	btrfs_set_file_extent_disk_blocknr(item, ins.objectid);
	btrfs_set_file_extent_disk_num_blocks(item, ins.offset);
	btrfs_set_file_extent_offset(item, 0);
	btrfs_set_file_extent_num_blocks(item, ins.offset);
38
	btrfs_set_file_extent_generation(item, trans->transid);
39
	btrfs_mark_buffer_dirty(path->nodes[0]);
C
Chris Mason 已提交
40
	*result = ins.objectid;
41 42
	btrfs_release_path(root, path);
	btrfs_free_path(path);
43 44
	return 0;
}
C
Chris Mason 已提交
45 46 47 48

int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
			     struct btrfs_root *root,
			     struct btrfs_path *path, u64 objectid,
C
Chris Mason 已提交
49
			     u64 offset, int mod)
C
Chris Mason 已提交
50 51 52 53 54 55 56
{
	int ret;
	struct btrfs_key file_key;
	int ins_len = mod < 0 ? -1 : 0;
	int cow = mod != 0;

	file_key.objectid = objectid;
C
Chris Mason 已提交
57
	file_key.offset = offset;
C
Chris Mason 已提交
58 59 60 61 62
	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;
}
C
Chris Mason 已提交
63 64 65 66 67 68 69 70

int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
			  struct btrfs_root *root,
			  u64 objectid, u64 offset,
			  char *data, size_t len)
{
	int ret;
	struct btrfs_key file_key;
71
	struct btrfs_path *path;
C
Chris Mason 已提交
72 73
	struct btrfs_csum_item *item;

74 75 76
	path = btrfs_alloc_path();
	BUG_ON(!path);
	btrfs_init_path(path);
C
Chris Mason 已提交
77 78 79 80
	file_key.objectid = objectid;
	file_key.offset = offset;
	file_key.flags = 0;
	btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY);
81
	ret = btrfs_insert_empty_item(trans, root, path, &file_key,
C
Chris Mason 已提交
82 83 84
				      BTRFS_CSUM_SIZE);
	if (ret != 0 && ret != -EEXIST)
		goto fail;
85
	item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
C
Chris Mason 已提交
86 87 88
			      struct btrfs_csum_item);
	ret = 0;
	ret = btrfs_csum_data(root, data, len, item->csum);
89
	btrfs_mark_buffer_dirty(path->nodes[0]);
C
Chris Mason 已提交
90
fail:
91 92
	btrfs_release_path(root, path);
	btrfs_free_path(path);
C
Chris Mason 已提交
93 94 95 96 97 98 99 100 101
	return ret;
}

int btrfs_csum_verify_file_block(struct btrfs_root *root,
				 u64 objectid, u64 offset,
				 char *data, size_t len)
{
	int ret;
	struct btrfs_key file_key;
102
	struct btrfs_path *path;
C
Chris Mason 已提交
103 104 105
	struct btrfs_csum_item *item;
	char result[BTRFS_CSUM_SIZE];

106 107 108
	path = btrfs_alloc_path();
	BUG_ON(!path);
	btrfs_init_path(path);
C
Chris Mason 已提交
109 110 111 112
	file_key.objectid = objectid;
	file_key.offset = offset;
	file_key.flags = 0;
	btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY);
113
	mutex_lock(&root->fs_info->fs_mutex);
114
	ret = btrfs_search_slot(NULL, root, &file_key, path, 0, 0);
C
Chris Mason 已提交
115 116
	if (ret)
		goto fail;
117
	item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
C
Chris Mason 已提交
118 119 120 121 122 123 124
			      struct btrfs_csum_item);
	ret = 0;
	ret = btrfs_csum_data(root, data, len, result);
	WARN_ON(ret);
	if (memcmp(result, item->csum, BTRFS_CSUM_SIZE))
		ret = 1;
fail:
125 126
	btrfs_release_path(root, path);
	btrfs_free_path(path);
127
	mutex_unlock(&root->fs_info->fs_mutex);
C
Chris Mason 已提交
128 129 130
	return ret;
}