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