blob: e7510ac5559d6bec0a321dd62af711d1256d7a53 [file] [log] [blame]
Chris Mason2e635a22007-03-21 11:12:56 -04001#include <linux/module.h>
Chris Mason1e1d2702007-03-15 19:03:33 -04002#include "ctree.h"
Chris Masondee26a92007-03-26 16:00:06 -04003#include "disk-io.h"
Chris Mason9f5fae22007-03-20 14:38:32 -04004#include "transaction.h"
Chris Mason1e1d2702007-03-15 19:03:33 -04005
Chris Masondee26a92007-03-26 16:00:06 -04006int 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)
Chris Mason9f5fae22007-03-20 14:38:32 -040011{
Chris Masondee26a92007-03-26 16:00:06 -040012 struct btrfs_key ins;
13 int ret = 0;
14 struct btrfs_file_extent_item *item;
15 struct btrfs_key file_key;
Chris Mason5caf2a02007-04-02 11:20:42 -040016 struct btrfs_path *path;
Chris Masondee26a92007-03-26 16:00:06 -040017
Chris Mason5caf2a02007-04-02 11:20:42 -040018 path = btrfs_alloc_path();
19 BUG_ON(!path);
20 btrfs_init_path(path);
Chris Masondee26a92007-03-26 16:00:06 -040021 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
Chris Mason5caf2a02007-04-02 11:20:42 -040029 ret = btrfs_insert_empty_item(trans, root, path, &file_key,
Chris Masondee26a92007-03-26 16:00:06 -040030 sizeof(*item));
Chris Mason9773a782007-03-27 11:26:26 -040031 BUG_ON(ret);
Chris Mason5caf2a02007-04-02 11:20:42 -040032 item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
Chris Masondee26a92007-03-26 16:00:06 -040033 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);
Chris Mason71951f32007-03-27 09:16:29 -040038 btrfs_set_file_extent_generation(item, trans->transid);
Chris Mason5caf2a02007-04-02 11:20:42 -040039 btrfs_mark_buffer_dirty(path->nodes[0]);
Chris Masondee26a92007-03-26 16:00:06 -040040 *result = ins.objectid;
Chris Mason5caf2a02007-04-02 11:20:42 -040041 btrfs_release_path(root, path);
42 btrfs_free_path(path);
Chris Mason9f5fae22007-03-20 14:38:32 -040043 return 0;
44}
Chris Masondee26a92007-03-26 16:00:06 -040045
46int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
47 struct btrfs_root *root,
48 struct btrfs_path *path, u64 objectid,
Chris Mason9773a782007-03-27 11:26:26 -040049 u64 offset, int mod)
Chris Masondee26a92007-03-26 16:00:06 -040050{
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;
Chris Mason9773a782007-03-27 11:26:26 -040057 file_key.offset = offset;
Chris Masondee26a92007-03-26 16:00:06 -040058 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}
Chris Masonf254e522007-03-29 15:15:27 -040063
64int 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;
Chris Mason5caf2a02007-04-02 11:20:42 -040071 struct btrfs_path *path;
Chris Masonf254e522007-03-29 15:15:27 -040072 struct btrfs_csum_item *item;
73
Chris Mason5caf2a02007-04-02 11:20:42 -040074 path = btrfs_alloc_path();
75 BUG_ON(!path);
76 btrfs_init_path(path);
Chris Masonf254e522007-03-29 15:15:27 -040077 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);
Chris Mason5caf2a02007-04-02 11:20:42 -040081 ret = btrfs_insert_empty_item(trans, root, path, &file_key,
Chris Masonf254e522007-03-29 15:15:27 -040082 BTRFS_CSUM_SIZE);
83 if (ret != 0 && ret != -EEXIST)
84 goto fail;
Chris Mason5caf2a02007-04-02 11:20:42 -040085 item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
Chris Masonf254e522007-03-29 15:15:27 -040086 struct btrfs_csum_item);
87 ret = 0;
88 ret = btrfs_csum_data(root, data, len, item->csum);
Chris Mason5caf2a02007-04-02 11:20:42 -040089 btrfs_mark_buffer_dirty(path->nodes[0]);
Chris Masonf254e522007-03-29 15:15:27 -040090fail:
Chris Mason5caf2a02007-04-02 11:20:42 -040091 btrfs_release_path(root, path);
92 btrfs_free_path(path);
Chris Masonf254e522007-03-29 15:15:27 -040093 return ret;
94}
95
96int 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;
Chris Mason5caf2a02007-04-02 11:20:42 -0400102 struct btrfs_path *path;
Chris Masonf254e522007-03-29 15:15:27 -0400103 struct btrfs_csum_item *item;
104 char result[BTRFS_CSUM_SIZE];
105
Chris Mason5caf2a02007-04-02 11:20:42 -0400106 path = btrfs_alloc_path();
107 BUG_ON(!path);
108 btrfs_init_path(path);
Chris Masonf254e522007-03-29 15:15:27 -0400109 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);
Chris Mason5caf2a02007-04-02 11:20:42 -0400113 ret = btrfs_search_slot(NULL, root, &file_key, path, 0, 0);
Chris Masonf254e522007-03-29 15:15:27 -0400114 if (ret)
115 goto fail;
Chris Mason5caf2a02007-04-02 11:20:42 -0400116 item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0],
Chris Masonf254e522007-03-29 15:15:27 -0400117 struct btrfs_csum_item);
118 ret = 0;
119 ret = btrfs_csum_data(root, data, len, result);
120 WARN_ON(ret);
121 if (memcmp(result, item->csum, BTRFS_CSUM_SIZE))
122 ret = 1;
123fail:
Chris Mason5caf2a02007-04-02 11:20:42 -0400124 btrfs_release_path(root, path);
125 btrfs_free_path(path);
Chris Masonf254e522007-03-29 15:15:27 -0400126 return ret;
127}
128