12e635a27SChris Mason #include <linux/module.h> 21e1d2701SChris Mason #include "ctree.h" 3dee26a9fSChris Mason #include "disk-io.h" 49f5fae2fSChris Mason #include "transaction.h" 51e1d2701SChris Mason 6dee26a9fSChris Mason int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans, 7dee26a9fSChris Mason struct btrfs_root *root, 8dee26a9fSChris Mason u64 objectid, u64 offset, 9dee26a9fSChris Mason u64 num_blocks, u64 hint_block, 10dee26a9fSChris Mason u64 *result) 119f5fae2fSChris Mason { 12dee26a9fSChris Mason struct btrfs_key ins; 13dee26a9fSChris Mason int ret = 0; 14dee26a9fSChris Mason struct btrfs_file_extent_item *item; 15dee26a9fSChris Mason struct btrfs_key file_key; 165caf2a00SChris Mason struct btrfs_path *path; 17dee26a9fSChris Mason 185caf2a00SChris Mason path = btrfs_alloc_path(); 195caf2a00SChris Mason BUG_ON(!path); 205caf2a00SChris Mason btrfs_init_path(path); 21dee26a9fSChris Mason ret = btrfs_alloc_extent(trans, root, num_blocks, hint_block, 22dee26a9fSChris Mason (u64)-1, objectid, &ins); 23dee26a9fSChris Mason BUG_ON(ret); 24dee26a9fSChris Mason file_key.objectid = objectid; 25dee26a9fSChris Mason file_key.offset = offset; 26dee26a9fSChris Mason file_key.flags = 0; 27dee26a9fSChris Mason btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); 28dee26a9fSChris Mason 295caf2a00SChris Mason ret = btrfs_insert_empty_item(trans, root, path, &file_key, 30dee26a9fSChris Mason sizeof(*item)); 319773a788SChris Mason BUG_ON(ret); 325caf2a00SChris Mason item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], 33dee26a9fSChris Mason struct btrfs_file_extent_item); 34dee26a9fSChris Mason btrfs_set_file_extent_disk_blocknr(item, ins.objectid); 35dee26a9fSChris Mason btrfs_set_file_extent_disk_num_blocks(item, ins.offset); 36dee26a9fSChris Mason btrfs_set_file_extent_offset(item, 0); 37dee26a9fSChris Mason btrfs_set_file_extent_num_blocks(item, ins.offset); 3871951f35SChris Mason btrfs_set_file_extent_generation(item, trans->transid); 395caf2a00SChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 40dee26a9fSChris Mason *result = ins.objectid; 415caf2a00SChris Mason btrfs_release_path(root, path); 425caf2a00SChris Mason btrfs_free_path(path); 439f5fae2fSChris Mason return 0; 449f5fae2fSChris Mason } 45dee26a9fSChris Mason 46dee26a9fSChris Mason int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans, 47dee26a9fSChris Mason struct btrfs_root *root, 48dee26a9fSChris Mason struct btrfs_path *path, u64 objectid, 499773a788SChris Mason u64 offset, int mod) 50dee26a9fSChris Mason { 51dee26a9fSChris Mason int ret; 52dee26a9fSChris Mason struct btrfs_key file_key; 53dee26a9fSChris Mason int ins_len = mod < 0 ? -1 : 0; 54dee26a9fSChris Mason int cow = mod != 0; 55dee26a9fSChris Mason 56dee26a9fSChris Mason file_key.objectid = objectid; 579773a788SChris Mason file_key.offset = offset; 58dee26a9fSChris Mason file_key.flags = 0; 59dee26a9fSChris Mason btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); 60dee26a9fSChris Mason ret = btrfs_search_slot(trans, root, &file_key, path, ins_len, cow); 61dee26a9fSChris Mason return ret; 62dee26a9fSChris Mason } 63f254e52cSChris Mason 64f254e52cSChris Mason int btrfs_csum_file_block(struct btrfs_trans_handle *trans, 65f254e52cSChris Mason struct btrfs_root *root, 66f254e52cSChris Mason u64 objectid, u64 offset, 67f254e52cSChris Mason char *data, size_t len) 68f254e52cSChris Mason { 69f254e52cSChris Mason int ret; 70f254e52cSChris Mason struct btrfs_key file_key; 715caf2a00SChris Mason struct btrfs_path *path; 72f254e52cSChris Mason struct btrfs_csum_item *item; 73f254e52cSChris Mason 745caf2a00SChris Mason path = btrfs_alloc_path(); 755caf2a00SChris Mason BUG_ON(!path); 765caf2a00SChris Mason btrfs_init_path(path); 77f254e52cSChris Mason file_key.objectid = objectid; 78f254e52cSChris Mason file_key.offset = offset; 79f254e52cSChris Mason file_key.flags = 0; 80f254e52cSChris Mason btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); 815caf2a00SChris Mason ret = btrfs_insert_empty_item(trans, root, path, &file_key, 82f254e52cSChris Mason BTRFS_CSUM_SIZE); 83f254e52cSChris Mason if (ret != 0 && ret != -EEXIST) 84f254e52cSChris Mason goto fail; 855caf2a00SChris Mason item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], 86f254e52cSChris Mason struct btrfs_csum_item); 87f254e52cSChris Mason ret = 0; 88f254e52cSChris Mason ret = btrfs_csum_data(root, data, len, item->csum); 895caf2a00SChris Mason btrfs_mark_buffer_dirty(path->nodes[0]); 90f254e52cSChris Mason fail: 915caf2a00SChris Mason btrfs_release_path(root, path); 925caf2a00SChris Mason btrfs_free_path(path); 93f254e52cSChris Mason return ret; 94f254e52cSChris Mason } 95f254e52cSChris Mason 96f254e52cSChris Mason int btrfs_csum_verify_file_block(struct btrfs_root *root, 97f254e52cSChris Mason u64 objectid, u64 offset, 98f254e52cSChris Mason char *data, size_t len) 99f254e52cSChris Mason { 100f254e52cSChris Mason int ret; 101f254e52cSChris Mason struct btrfs_key file_key; 1025caf2a00SChris Mason struct btrfs_path *path; 103f254e52cSChris Mason struct btrfs_csum_item *item; 104f254e52cSChris Mason char result[BTRFS_CSUM_SIZE]; 105f254e52cSChris Mason 1065caf2a00SChris Mason path = btrfs_alloc_path(); 1075caf2a00SChris Mason BUG_ON(!path); 1085caf2a00SChris Mason btrfs_init_path(path); 109f254e52cSChris Mason file_key.objectid = objectid; 110f254e52cSChris Mason file_key.offset = offset; 111f254e52cSChris Mason file_key.flags = 0; 112f254e52cSChris Mason btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); 1135caf2a00SChris Mason ret = btrfs_search_slot(NULL, root, &file_key, path, 0, 0); 114f254e52cSChris Mason if (ret) 115f254e52cSChris Mason goto fail; 1165caf2a00SChris Mason item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], 117f254e52cSChris Mason struct btrfs_csum_item); 118f254e52cSChris Mason ret = 0; 119f254e52cSChris Mason ret = btrfs_csum_data(root, data, len, result); 120f254e52cSChris Mason WARN_ON(ret); 121f254e52cSChris Mason if (memcmp(result, item->csum, BTRFS_CSUM_SIZE)) 122f254e52cSChris Mason ret = 1; 123f254e52cSChris Mason fail: 1245caf2a00SChris Mason btrfs_release_path(root, path); 1255caf2a00SChris Mason btrfs_free_path(path); 126f254e52cSChris Mason return ret; 127f254e52cSChris Mason } 128f254e52cSChris Mason 129