1 /* 2 * Copyright (C) 2007 Oracle. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public 6 * License v2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public 14 * License along with this program; if not, write to the 15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 * Boston, MA 021110-1307, USA. 17 */ 18 19 /// D translation of extent_io.h from btrfs-progs (v5.9) 20 module btrfs.c.kernel_shared.extent_io; 21 22 import core.stdc.config; 23 24 import btrfs.c.kerncompat; 25 import btrfs.c.kernel_lib.list; 26 import btrfs.c.common.extent_cache; 27 28 import btrfs.c.kernel_shared.ctree : btrfs_fs_info; 29 30 enum EXTENT_DIRTY = 1U << 0; 31 enum EXTENT_WRITEBACK = 1U << 1; 32 enum EXTENT_UPTODATE = 1U << 2; 33 enum EXTENT_LOCKED = 1U << 3; 34 enum EXTENT_NEW = 1U << 4; 35 enum EXTENT_DELALLOC = 1U << 5; 36 enum EXTENT_DEFRAG = 1U << 6; 37 enum EXTENT_DEFRAG_DONE = 1U << 7; 38 enum EXTENT_BUFFER_FILLED = 1U << 8; 39 enum EXTENT_CSUM = 1U << 9; 40 enum EXTENT_BAD_TRANSID = 1U << 10; 41 enum EXTENT_BUFFER_DUMMY = 1U << 11; 42 enum EXTENT_IOBITS = EXTENT_LOCKED | EXTENT_WRITEBACK; 43 44 enum BLOCK_GROUP_DATA = 1U << 1; 45 enum BLOCK_GROUP_METADATA = 1U << 2; 46 enum BLOCK_GROUP_SYSTEM = 1U << 4; 47 48 /* 49 * The extent buffer bitmap operations are done with byte granularity instead of 50 * word granularity for two reasons: 51 * 1. The bitmaps must be little-endian on disk. 52 * 2. Bitmap items are not guaranteed to be aligned to a word and therefore a 53 * single word in a bitmap may straddle two pages in the extent buffer. 54 */ 55 auto BIT_BYTE(T)(T nr) { return nr / BITS_PER_BYTE; } 56 enum BYTE_MASK = (1 << BITS_PER_BYTE) - 1; 57 auto BITMAP_FIRST_BYTE_MASK(T)(T start) { return 58 ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK); } 59 auto BITMAP_LAST_BYTE_MASK(T)(T nbits) { return 60 (BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1))); } 61 62 int le_test_bit(int nr, const u8 *addr) 63 { 64 return 1U & (addr[BIT_BYTE(nr)] >> (nr & (BITS_PER_BYTE-1))); 65 } 66 67 struct extent_io_tree { 68 cache_tree state; 69 cache_tree cache; 70 list_head lru; 71 u64 cache_size; 72 u64 max_cache_size; 73 } 74 75 struct extent_state { 76 cache_extent cache_node; 77 u64 start; 78 u64 end; 79 int refs; 80 c_ulong state; 81 u64 xprivate; 82 } 83 84 struct extent_buffer { 85 cache_extent cache_node; 86 u64 start; 87 u64 dev_bytenr; 88 list_head lru; 89 list_head recow; 90 u32 len; 91 int refs; 92 u32 flags; 93 int fd; 94 btrfs_fs_info *fs_info; 95 align(8) char[0] data; 96 } 97 98 void extent_buffer_get()(extent_buffer *eb) 99 { 100 eb.refs++; 101 } 102 103 void extent_io_tree_init(extent_io_tree *tree); 104 void extent_io_tree_init_cache_max(extent_io_tree *tree, 105 u64 max_cache_size); 106 void extent_io_tree_cleanup(extent_io_tree *tree); 107 int set_extent_bits(extent_io_tree *tree, u64 start, u64 end, int bits); 108 int clear_extent_bits(extent_io_tree *tree, u64 start, u64 end, int bits); 109 int find_first_extent_bit(extent_io_tree *tree, u64 start, 110 u64 *start_ret, u64 *end_ret, int bits); 111 int test_range_bit(extent_io_tree *tree, u64 start, u64 end, 112 int bits, int filled); 113 int set_extent_dirty(extent_io_tree *tree, u64 start, u64 end); 114 int clear_extent_dirty(extent_io_tree *tree, u64 start, u64 end); 115 int set_extent_buffer_uptodate(extent_buffer *eb) 116 { 117 eb.flags |= EXTENT_UPTODATE; 118 return 0; 119 } 120 121 int clear_extent_buffer_uptodate(extent_buffer *eb) 122 { 123 eb.flags &= ~EXTENT_UPTODATE; 124 return 0; 125 } 126 127 int extent_buffer_uptodate(extent_buffer *eb) 128 { 129 if (!eb || IS_ERR(eb)) 130 return 0; 131 if (eb.flags & EXTENT_UPTODATE) 132 return 1; 133 return 0; 134 } 135 136 int set_state_private(extent_io_tree *tree, u64 start, u64 xprivate); 137 int get_state_private(extent_io_tree *tree, u64 start, u64 *xprivate); 138 extent_buffer *find_extent_buffer(extent_io_tree *tree, 139 u64 bytenr, u32 blocksize); 140 extent_buffer *find_first_extent_buffer(extent_io_tree *tree, 141 u64 start); 142 extent_buffer *alloc_extent_buffer(btrfs_fs_info *fs_info, 143 u64 bytenr, u32 blocksize); 144 extent_buffer *btrfs_clone_extent_buffer(extent_buffer *src); 145 extent_buffer *alloc_dummy_extent_buffer(btrfs_fs_info *fs_info, 146 u64 bytenr, u32 blocksize); 147 void free_extent_buffer(extent_buffer *eb); 148 void free_extent_buffer_nocache(extent_buffer *eb); 149 int read_extent_from_disk(extent_buffer *eb, 150 c_ulong offset, ulong len); 151 int write_extent_to_disk(extent_buffer *eb); 152 int memcmp_extent_buffer(const extent_buffer *eb, const void *ptrv, 153 c_ulong start, c_ulong len); 154 void read_extent_buffer(const extent_buffer *eb, void *dst, 155 c_ulong start, c_ulong len); 156 void write_extent_buffer(extent_buffer *eb, const void *src, 157 c_ulong start, c_ulong len); 158 void copy_extent_buffer(extent_buffer *dst, extent_buffer *src, 159 c_ulong dst_offset, c_ulong src_offset, 160 c_ulong len); 161 void memmove_extent_buffer(extent_buffer *dst, c_ulong dst_offset, 162 c_ulong src_offset, c_ulong len); 163 void memset_extent_buffer(extent_buffer *eb, char c, 164 c_ulong start, c_ulong len); 165 int extent_buffer_test_bit(extent_buffer *eb, c_ulong start, 166 c_ulong nr); 167 int set_extent_buffer_dirty(extent_buffer *eb); 168 int clear_extent_buffer_dirty(extent_buffer *eb); 169 int read_data_from_disk(btrfs_fs_info *info, void *buf, u64 offset, 170 u64 bytes, int mirror); 171 int write_data_to_disk(btrfs_fs_info *info, void *buf, u64 offset, 172 u64 bytes, int mirror); 173 void extent_buffer_bitmap_clear(extent_buffer *eb, c_ulong start, 174 c_ulong pos, c_ulong len); 175 void extent_buffer_bitmap_set(extent_buffer *eb, c_ulong start, 176 c_ulong pos, c_ulong len);