1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2023 Western Digital Corporation or its affiliates. 4 */ 5 6 #include <linux/btrfs_tree.h> 7 #include "ctree.h" 8 #include "fs.h" 9 #include "accessors.h" 10 #include "transaction.h" 11 #include "disk-io.h" 12 #include "raid-stripe-tree.h" 13 #include "volumes.h" 14 #include "print-tree.h" 15 16 int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 length) 17 { 18 struct btrfs_fs_info *fs_info = trans->fs_info; 19 struct btrfs_root *stripe_root = fs_info->stripe_root; 20 struct btrfs_path *path; 21 struct btrfs_key key; 22 struct extent_buffer *leaf; 23 u64 found_start; 24 u64 found_end; 25 u64 end = start + length; 26 int slot; 27 int ret; 28 29 if (!stripe_root) 30 return 0; 31 32 path = btrfs_alloc_path(); 33 if (!path) 34 return -ENOMEM; 35 36 while (1) { 37 key.objectid = start; 38 key.type = BTRFS_RAID_STRIPE_KEY; 39 key.offset = length; 40 41 ret = btrfs_search_slot(trans, stripe_root, &key, path, -1, 1); 42 if (ret < 0) 43 break; 44 if (ret > 0) { 45 ret = 0; 46 if (path->slots[0] == 0) 47 break; 48 path->slots[0]--; 49 } 50 51 leaf = path->nodes[0]; 52 slot = path->slots[0]; 53 btrfs_item_key_to_cpu(leaf, &key, slot); 54 found_start = key.objectid; 55 found_end = found_start + key.offset; 56 57 /* That stripe ends before we start, we're done. */ 58 if (found_end <= start) 59 break; 60 61 trace_btrfs_raid_extent_delete(fs_info, start, end, 62 found_start, found_end); 63 64 ASSERT(found_start >= start && found_end <= end); 65 ret = btrfs_del_item(trans, stripe_root, path); 66 if (ret) 67 break; 68 69 btrfs_release_path(path); 70 } 71 72 btrfs_free_path(path); 73 return ret; 74 } 75 76 static int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans, 77 struct btrfs_io_context *bioc) 78 { 79 struct btrfs_fs_info *fs_info = trans->fs_info; 80 struct btrfs_key stripe_key; 81 struct btrfs_root *stripe_root = fs_info->stripe_root; 82 const int num_stripes = btrfs_bg_type_to_factor(bioc->map_type); 83 struct btrfs_stripe_extent *stripe_extent; 84 const size_t item_size = struct_size(stripe_extent, strides, num_stripes); 85 int ret; 86 87 stripe_extent = kzalloc(item_size, GFP_NOFS); 88 if (!stripe_extent) { 89 btrfs_abort_transaction(trans, -ENOMEM); 90 btrfs_end_transaction(trans); 91 return -ENOMEM; 92 } 93 94 trace_btrfs_insert_one_raid_extent(fs_info, bioc->logical, bioc->size, 95 num_stripes); 96 for (int i = 0; i < num_stripes; i++) { 97 u64 devid = bioc->stripes[i].dev->devid; 98 u64 physical = bioc->stripes[i].physical; 99 u64 length = bioc->stripes[i].length; 100 struct btrfs_raid_stride *raid_stride = &stripe_extent->strides[i]; 101 102 if (length == 0) 103 length = bioc->size; 104 105 btrfs_set_stack_raid_stride_devid(raid_stride, devid); 106 btrfs_set_stack_raid_stride_physical(raid_stride, physical); 107 } 108 109 stripe_key.objectid = bioc->logical; 110 stripe_key.type = BTRFS_RAID_STRIPE_KEY; 111 stripe_key.offset = bioc->size; 112 113 ret = btrfs_insert_item(trans, stripe_root, &stripe_key, stripe_extent, 114 item_size); 115 if (ret) 116 btrfs_abort_transaction(trans, ret); 117 118 kfree(stripe_extent); 119 120 return ret; 121 } 122 123 int btrfs_insert_raid_extent(struct btrfs_trans_handle *trans, 124 struct btrfs_ordered_extent *ordered_extent) 125 { 126 struct btrfs_io_context *bioc; 127 int ret; 128 129 if (!btrfs_fs_incompat(trans->fs_info, RAID_STRIPE_TREE)) 130 return 0; 131 132 list_for_each_entry(bioc, &ordered_extent->bioc_list, rst_ordered_entry) { 133 ret = btrfs_insert_one_raid_extent(trans, bioc); 134 if (ret) 135 return ret; 136 } 137 138 while (!list_empty(&ordered_extent->bioc_list)) { 139 bioc = list_first_entry(&ordered_extent->bioc_list, 140 typeof(*bioc), rst_ordered_entry); 141 list_del(&bioc->rst_ordered_entry); 142 btrfs_put_bioc(bioc); 143 } 144 145 return 0; 146 } 147 148 int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info, 149 u64 logical, u64 *length, u64 map_type, 150 u32 stripe_index, struct btrfs_io_stripe *stripe) 151 { 152 struct btrfs_root *stripe_root = fs_info->stripe_root; 153 struct btrfs_stripe_extent *stripe_extent; 154 struct btrfs_key stripe_key; 155 struct btrfs_key found_key; 156 struct btrfs_path *path; 157 struct extent_buffer *leaf; 158 const u64 end = logical + *length; 159 int num_stripes; 160 u64 offset; 161 u64 found_logical; 162 u64 found_length; 163 u64 found_end; 164 int slot; 165 int ret; 166 167 stripe_key.objectid = logical; 168 stripe_key.type = BTRFS_RAID_STRIPE_KEY; 169 stripe_key.offset = 0; 170 171 path = btrfs_alloc_path(); 172 if (!path) 173 return -ENOMEM; 174 175 if (stripe->is_scrub) { 176 path->skip_locking = 1; 177 path->search_commit_root = 1; 178 } 179 180 ret = btrfs_search_slot(NULL, stripe_root, &stripe_key, path, 0, 0); 181 if (ret < 0) 182 goto free_path; 183 if (ret) { 184 if (path->slots[0] != 0) 185 path->slots[0]--; 186 } 187 188 while (1) { 189 leaf = path->nodes[0]; 190 slot = path->slots[0]; 191 192 btrfs_item_key_to_cpu(leaf, &found_key, slot); 193 found_logical = found_key.objectid; 194 found_length = found_key.offset; 195 found_end = found_logical + found_length; 196 197 if (found_logical > end) { 198 ret = -ENOENT; 199 goto out; 200 } 201 202 if (in_range(logical, found_logical, found_length)) 203 break; 204 205 ret = btrfs_next_item(stripe_root, path); 206 if (ret) 207 goto out; 208 } 209 210 offset = logical - found_logical; 211 212 /* 213 * If we have a logically contiguous, but physically non-continuous 214 * range, we need to split the bio. Record the length after which we 215 * must split the bio. 216 */ 217 if (end > found_end) 218 *length -= end - found_end; 219 220 num_stripes = btrfs_num_raid_stripes(btrfs_item_size(leaf, slot)); 221 stripe_extent = btrfs_item_ptr(leaf, slot, struct btrfs_stripe_extent); 222 223 for (int i = 0; i < num_stripes; i++) { 224 struct btrfs_raid_stride *stride = &stripe_extent->strides[i]; 225 u64 devid = btrfs_raid_stride_devid(leaf, stride); 226 u64 physical = btrfs_raid_stride_physical(leaf, stride); 227 228 if (devid != stripe->dev->devid) 229 continue; 230 231 if ((map_type & BTRFS_BLOCK_GROUP_DUP) && stripe_index != i) 232 continue; 233 234 stripe->physical = physical + offset; 235 236 trace_btrfs_get_raid_extent_offset(fs_info, logical, *length, 237 stripe->physical, devid); 238 239 ret = 0; 240 goto free_path; 241 } 242 243 /* If we're here, we haven't found the requested devid in the stripe. */ 244 ret = -ENOENT; 245 out: 246 if (ret > 0) 247 ret = -ENOENT; 248 if (ret && ret != -EIO && !stripe->is_scrub) { 249 if (IS_ENABLED(CONFIG_BTRFS_DEBUG)) 250 btrfs_print_tree(leaf, 1); 251 btrfs_err(fs_info, 252 "cannot find raid-stripe for logical [%llu, %llu] devid %llu, profile %s", 253 logical, logical + *length, stripe->dev->devid, 254 btrfs_bg_type_to_raid_name(map_type)); 255 } 256 free_path: 257 btrfs_free_path(path); 258 259 return ret; 260 } 261