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