Commit | Line | Data |
---|---|---|
2e635a27 | 1 | #include <linux/module.h> |
1e1d2701 | 2 | #include "ctree.h" |
dee26a9f | 3 | #include "disk-io.h" |
9f5fae2f | 4 | #include "transaction.h" |
1e1d2701 | 5 | |
dee26a9f CM |
6 | int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans, |
7 | struct btrfs_root *root, | |
8 | u64 objectid, u64 offset, | |
9 | u64 num_blocks, u64 hint_block, | |
10 | u64 *result) | |
9f5fae2f | 11 | { |
dee26a9f CM |
12 | struct btrfs_key ins; |
13 | int ret = 0; | |
14 | struct btrfs_file_extent_item *item; | |
15 | struct btrfs_key file_key; | |
5caf2a00 | 16 | struct btrfs_path *path; |
dee26a9f | 17 | |
5caf2a00 CM |
18 | path = btrfs_alloc_path(); |
19 | BUG_ON(!path); | |
20 | btrfs_init_path(path); | |
dee26a9f CM |
21 | ret = btrfs_alloc_extent(trans, root, num_blocks, hint_block, |
22 | (u64)-1, objectid, &ins); | |
23 | BUG_ON(ret); | |
24 | file_key.objectid = objectid; | |
25 | file_key.offset = offset; | |
26 | file_key.flags = 0; | |
27 | btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); | |
28 | ||
5caf2a00 | 29 | ret = btrfs_insert_empty_item(trans, root, path, &file_key, |
dee26a9f | 30 | sizeof(*item)); |
9773a788 | 31 | BUG_ON(ret); |
5caf2a00 | 32 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
dee26a9f CM |
33 | struct btrfs_file_extent_item); |
34 | btrfs_set_file_extent_disk_blocknr(item, ins.objectid); | |
35 | btrfs_set_file_extent_disk_num_blocks(item, ins.offset); | |
36 | btrfs_set_file_extent_offset(item, 0); | |
37 | btrfs_set_file_extent_num_blocks(item, ins.offset); | |
71951f35 | 38 | btrfs_set_file_extent_generation(item, trans->transid); |
5caf2a00 | 39 | btrfs_mark_buffer_dirty(path->nodes[0]); |
dee26a9f | 40 | *result = ins.objectid; |
5caf2a00 CM |
41 | btrfs_release_path(root, path); |
42 | btrfs_free_path(path); | |
9f5fae2f CM |
43 | return 0; |
44 | } | |
dee26a9f CM |
45 | |
46 | int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans, | |
47 | struct btrfs_root *root, | |
48 | struct btrfs_path *path, u64 objectid, | |
9773a788 | 49 | u64 offset, int mod) |
dee26a9f CM |
50 | { |
51 | int ret; | |
52 | struct btrfs_key file_key; | |
53 | int ins_len = mod < 0 ? -1 : 0; | |
54 | int cow = mod != 0; | |
55 | ||
56 | file_key.objectid = objectid; | |
9773a788 | 57 | file_key.offset = offset; |
dee26a9f CM |
58 | file_key.flags = 0; |
59 | btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); | |
60 | ret = btrfs_search_slot(trans, root, &file_key, path, ins_len, cow); | |
61 | return ret; | |
62 | } | |
f254e52c CM |
63 | |
64 | int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | |
65 | struct btrfs_root *root, | |
66 | u64 objectid, u64 offset, | |
67 | char *data, size_t len) | |
68 | { | |
69 | int ret; | |
70 | struct btrfs_key file_key; | |
5caf2a00 | 71 | struct btrfs_path *path; |
f254e52c CM |
72 | struct btrfs_csum_item *item; |
73 | ||
5caf2a00 CM |
74 | path = btrfs_alloc_path(); |
75 | BUG_ON(!path); | |
76 | btrfs_init_path(path); | |
f254e52c CM |
77 | file_key.objectid = objectid; |
78 | file_key.offset = offset; | |
79 | file_key.flags = 0; | |
80 | btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); | |
5caf2a00 | 81 | ret = btrfs_insert_empty_item(trans, root, path, &file_key, |
f254e52c CM |
82 | BTRFS_CSUM_SIZE); |
83 | if (ret != 0 && ret != -EEXIST) | |
84 | goto fail; | |
5caf2a00 | 85 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
f254e52c CM |
86 | struct btrfs_csum_item); |
87 | ret = 0; | |
88 | ret = btrfs_csum_data(root, data, len, item->csum); | |
5caf2a00 | 89 | btrfs_mark_buffer_dirty(path->nodes[0]); |
f254e52c | 90 | fail: |
5caf2a00 CM |
91 | btrfs_release_path(root, path); |
92 | btrfs_free_path(path); | |
f254e52c CM |
93 | return ret; |
94 | } | |
95 | ||
96 | int btrfs_csum_verify_file_block(struct btrfs_root *root, | |
97 | u64 objectid, u64 offset, | |
98 | char *data, size_t len) | |
99 | { | |
100 | int ret; | |
101 | struct btrfs_key file_key; | |
5caf2a00 | 102 | struct btrfs_path *path; |
f254e52c CM |
103 | struct btrfs_csum_item *item; |
104 | char result[BTRFS_CSUM_SIZE]; | |
105 | ||
5caf2a00 CM |
106 | path = btrfs_alloc_path(); |
107 | BUG_ON(!path); | |
108 | btrfs_init_path(path); | |
f254e52c CM |
109 | file_key.objectid = objectid; |
110 | file_key.offset = offset; | |
111 | file_key.flags = 0; | |
112 | btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); | |
2da566ed | 113 | mutex_lock(&root->fs_info->fs_mutex); |
5caf2a00 | 114 | ret = btrfs_search_slot(NULL, root, &file_key, path, 0, 0); |
f254e52c CM |
115 | if (ret) |
116 | goto fail; | |
5caf2a00 | 117 | item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], |
f254e52c CM |
118 | struct btrfs_csum_item); |
119 | ret = 0; | |
120 | ret = btrfs_csum_data(root, data, len, result); | |
121 | WARN_ON(ret); | |
122 | if (memcmp(result, item->csum, BTRFS_CSUM_SIZE)) | |
123 | ret = 1; | |
124 | fail: | |
5caf2a00 CM |
125 | btrfs_release_path(root, path); |
126 | btrfs_free_path(path); | |
2da566ed | 127 | mutex_unlock(&root->fs_info->fs_mutex); |
f254e52c CM |
128 | return ret; |
129 | } | |
130 |