1 #include <linux/module.h>
4 #include "transaction.h"
6 #define MAX_CSUM_ITEMS(r) ((((BTRFS_LEAF_DATA_SIZE(r) - \
7 sizeof(struct btrfs_item)) / \
8 sizeof(struct btrfs_csum_item)) - 1))
9 int btrfs_insert_file_extent(struct btrfs_trans_handle
*trans
,
10 struct btrfs_root
*root
,
11 u64 objectid
, u64 pos
,
12 u64 offset
, u64 num_blocks
)
15 struct btrfs_file_extent_item
*item
;
16 struct btrfs_key file_key
;
17 struct btrfs_path
*path
;
19 path
= btrfs_alloc_path();
21 btrfs_init_path(path
);
23 ret = btrfs_alloc_extent(trans, root, num_blocks, hint_block,
27 file_key
.objectid
= objectid
;
28 file_key
.offset
= pos
;
30 btrfs_set_key_type(&file_key
, BTRFS_EXTENT_DATA_KEY
);
32 ret
= btrfs_insert_empty_item(trans
, root
, path
, &file_key
,
35 item
= btrfs_item_ptr(btrfs_buffer_leaf(path
->nodes
[0]), path
->slots
[0],
36 struct btrfs_file_extent_item
);
37 btrfs_set_file_extent_disk_blocknr(item
, offset
);
38 btrfs_set_file_extent_disk_num_blocks(item
, num_blocks
);
39 btrfs_set_file_extent_offset(item
, 0);
40 btrfs_set_file_extent_num_blocks(item
, num_blocks
);
41 btrfs_set_file_extent_generation(item
, trans
->transid
);
42 btrfs_mark_buffer_dirty(path
->nodes
[0]);
43 btrfs_release_path(root
, path
);
44 btrfs_free_path(path
);
48 struct btrfs_csum_item
*btrfs_lookup_csum(struct btrfs_trans_handle
*trans
,
49 struct btrfs_root
*root
,
50 struct btrfs_path
*path
,
51 u64 objectid
, u64 offset
,
55 struct btrfs_key file_key
;
56 struct btrfs_key found_key
;
57 struct btrfs_csum_item
*item
;
58 struct btrfs_leaf
*leaf
;
61 file_key
.objectid
= objectid
;
62 file_key
.offset
= offset
;
64 btrfs_set_key_type(&file_key
, BTRFS_CSUM_ITEM_KEY
);
65 printk("__lookup for %Lu\n", offset
);
66 ret
= btrfs_search_slot(trans
, root
, &file_key
, path
, 0, cow
);
69 leaf
= btrfs_buffer_leaf(path
->nodes
[0]);
72 if (path
->slots
[0] == 0) {
77 btrfs_disk_key_to_cpu(&found_key
,
78 &leaf
->items
[path
->slots
[0]].key
);
79 if (btrfs_key_type(&found_key
) != BTRFS_CSUM_ITEM_KEY
||
80 found_key
.objectid
!= objectid
) {
81 printk("fail2 type %u %Lu %Lu\n", btrfs_key_type(&found_key
), found_key
.objectid
, objectid
);
84 csum_offset
= (offset
- found_key
.offset
) >>
85 root
->fs_info
->sb
->s_blocksize_bits
;
87 btrfs_item_size(leaf
->items
+ path
->slots
[0]) /
88 sizeof(struct btrfs_csum_item
)) {
89 printk("fail3, csum offset %lu size %u\n", csum_offset
, btrfs_item_size(leaf
->items
+ path
->slots
[0]) / sizeof(struct btrfs_csum_item
));
93 item
= btrfs_item_ptr(leaf
, path
->slots
[0], struct btrfs_csum_item
);
103 int btrfs_lookup_file_extent(struct btrfs_trans_handle
*trans
,
104 struct btrfs_root
*root
,
105 struct btrfs_path
*path
, u64 objectid
,
109 struct btrfs_key file_key
;
110 int ins_len
= mod
< 0 ? -1 : 0;
112 struct btrfs_csum_item
*csum_item
;
114 csum_item
= btrfs_lookup_csum(trans
, root
, path
, objectid
, offset
, 0);
115 if (IS_ERR(csum_item
))
116 return PTR_ERR(csum_item
);
117 file_key
.objectid
= objectid
;
118 file_key
.offset
= btrfs_csum_extent_offset(csum_item
);
120 btrfs_set_key_type(&file_key
, BTRFS_EXTENT_DATA_KEY
);
121 btrfs_release_path(root
, path
);
122 printk("lookup file extent searches for %Lu\n", file_key
.offset
);
123 ret
= btrfs_search_slot(trans
, root
, &file_key
, path
, ins_len
, cow
);
124 printk("ret is %d\n", ret
);
128 int btrfs_csum_file_block(struct btrfs_trans_handle
*trans
,
129 struct btrfs_root
*root
,
130 u64 objectid
, u64 offset
,
132 char *data
, size_t len
)
135 struct btrfs_key file_key
;
136 struct btrfs_key found_key
;
137 struct btrfs_path
*path
;
138 struct btrfs_csum_item
*item
;
139 struct btrfs_leaf
*leaf
;
142 path
= btrfs_alloc_path();
144 btrfs_init_path(path
);
146 item
= btrfs_lookup_csum(trans
, root
, path
, objectid
, offset
, 0);
149 btrfs_release_path(root
, path
);
150 file_key
.objectid
= objectid
;
151 file_key
.offset
= offset
;
153 btrfs_set_key_type(&file_key
, BTRFS_CSUM_ITEM_KEY
);
154 printk("searching for csum %Lu %Lu\n", objectid
, offset
);
155 ret
= btrfs_search_slot(trans
, root
, &file_key
, path
,
156 sizeof(struct btrfs_csum_item
), 1);
157 printk("ret %d\n", ret
);
163 if (path
->slots
[0] == 0) {
164 btrfs_release_path(root
, path
);
168 leaf
= btrfs_buffer_leaf(path
->nodes
[0]);
169 btrfs_disk_key_to_cpu(&found_key
, &leaf
->items
[path
->slots
[0]].key
);
170 printk("found key %Lu %Lu %u\n", found_key
.objectid
, found_key
.offset
, found_key
.flags
);
171 csum_offset
= (offset
- found_key
.offset
) >>
172 root
->fs_info
->sb
->s_blocksize_bits
;
173 printk("csum_offset %Lu\n", csum_offset
);
174 if (btrfs_key_type(&found_key
) != BTRFS_CSUM_ITEM_KEY
||
175 found_key
.objectid
!= objectid
||
176 csum_offset
>= MAX_CSUM_ITEMS(root
)) {
177 btrfs_release_path(root
, path
);
181 if (csum_offset
>= btrfs_item_size(leaf
->items
+ path
->slots
[0]) /
182 sizeof(struct btrfs_csum_item
)) {
183 ret
= btrfs_extend_item(trans
, root
, path
,
184 sizeof(struct btrfs_csum_item
));
186 printk("item extended\n");
192 printk("inserting item %Lu %Lu %u\n", file_key
.objectid
, file_key
.offset
, file_key
.flags
);
193 ret
= btrfs_insert_empty_item(trans
, root
, path
, &file_key
,
194 sizeof(struct btrfs_csum_item
));
195 if (ret
!= 0 && ret
!= -EEXIST
)
198 item
= btrfs_item_ptr(btrfs_buffer_leaf(path
->nodes
[0]), path
->slots
[0],
199 struct btrfs_csum_item
);
203 ret
= btrfs_csum_data(root
, data
, len
, item
->csum
);
204 btrfs_set_csum_extent_offset(item
, extent_offset
);
205 btrfs_mark_buffer_dirty(path
->nodes
[0]);
207 btrfs_release_path(root
, path
);
208 btrfs_free_path(path
);
209 printk("return ret %d\n", ret
);
213 int btrfs_csum_verify_file_block(struct btrfs_root
*root
,
214 u64 objectid
, u64 offset
,
215 char *data
, size_t len
)
218 struct btrfs_key file_key
;
219 struct btrfs_path
*path
;
220 struct btrfs_csum_item
*item
;
221 char result
[BTRFS_CSUM_SIZE
];
223 path
= btrfs_alloc_path();
225 btrfs_init_path(path
);
226 file_key
.objectid
= objectid
;
227 file_key
.offset
= offset
;
229 btrfs_set_key_type(&file_key
, BTRFS_CSUM_ITEM_KEY
);
230 mutex_lock(&root
->fs_info
->fs_mutex
);
232 item
= btrfs_lookup_csum(NULL
, root
, path
, objectid
, offset
, 0);
238 ret
= btrfs_csum_data(root
, data
, len
, result
);
240 if (memcmp(result
, item
->csum
, BTRFS_CSUM_SIZE
))
243 btrfs_release_path(root
, path
);
244 btrfs_free_path(path
);
245 mutex_unlock(&root
->fs_info
->fs_mutex
);
This page took 0.05482 seconds and 6 git commands to generate.