1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2007 Oracle. All rights reserved. 4 */ 5 6 #include "ctree.h" 7 #include "disk-io.h" 8 #include "transaction.h" 9 10 /* 11 * insert a name into a directory, doing overflow properly if there is a hash 12 * collision. data_size indicates how big the item inserted should be. On 13 * success a struct btrfs_dir_item pointer is returned, otherwise it is 14 * an ERR_PTR. 15 * 16 * The name is not copied into the dir item, you have to do that yourself. 17 */ 18 static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle 19 *trans, 20 struct btrfs_root *root, 21 struct btrfs_path *path, 22 struct btrfs_key *cpu_key, 23 u32 data_size, 24 const char *name, 25 int name_len) 26 { 27 struct btrfs_fs_info *fs_info = root->fs_info; 28 int ret; 29 char *ptr; 30 struct extent_buffer *leaf; 31 32 ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size); 33 if (ret == -EEXIST) { 34 struct btrfs_dir_item *di; 35 di = btrfs_match_dir_item_name(fs_info, path, name, name_len); 36 if (di) 37 return ERR_PTR(-EEXIST); 38 btrfs_extend_item(path, data_size); 39 } else if (ret < 0) 40 return ERR_PTR(ret); 41 WARN_ON(ret > 0); 42 leaf = path->nodes[0]; 43 ptr = btrfs_item_ptr(leaf, path->slots[0], char); 44 ASSERT(data_size <= btrfs_item_size(leaf, path->slots[0])); 45 ptr += btrfs_item_size(leaf, path->slots[0]) - data_size; 46 return (struct btrfs_dir_item *)ptr; 47 } 48 49 /* 50 * xattrs work a lot like directories, this inserts an xattr item 51 * into the tree 52 */ 53 int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, 54 struct btrfs_root *root, 55 struct btrfs_path *path, u64 objectid, 56 const char *name, u16 name_len, 57 const void *data, u16 data_len) 58 { 59 int ret = 0; 60 struct btrfs_dir_item *dir_item; 61 unsigned long name_ptr, data_ptr; 62 struct btrfs_key key, location; 63 struct btrfs_disk_key disk_key; 64 struct extent_buffer *leaf; 65 u32 data_size; 66 67 if (name_len + data_len > BTRFS_MAX_XATTR_SIZE(root->fs_info)) 68 return -ENOSPC; 69 70 key.objectid = objectid; 71 key.type = BTRFS_XATTR_ITEM_KEY; 72 key.offset = btrfs_name_hash(name, name_len); 73 74 data_size = sizeof(*dir_item) + name_len + data_len; 75 dir_item = insert_with_overflow(trans, root, path, &key, data_size, 76 name, name_len); 77 if (IS_ERR(dir_item)) 78 return PTR_ERR(dir_item); 79 memset(&location, 0, sizeof(location)); 80 81 leaf = path->nodes[0]; 82 btrfs_cpu_key_to_disk(&disk_key, &location); 83 btrfs_set_dir_item_key(leaf, dir_item, &disk_key); 84 btrfs_set_dir_type(leaf, dir_item, BTRFS_FT_XATTR); 85 btrfs_set_dir_name_len(leaf, dir_item, name_len); 86 btrfs_set_dir_transid(leaf, dir_item, trans->transid); 87 btrfs_set_dir_data_len(leaf, dir_item, data_len); 88 name_ptr = (unsigned long)(dir_item + 1); 89 data_ptr = (unsigned long)((char *)name_ptr + name_len); 90 91 write_extent_buffer(leaf, name, name_ptr, name_len); 92 write_extent_buffer(leaf, data, data_ptr, data_len); 93 btrfs_mark_buffer_dirty(path->nodes[0]); 94 95 return ret; 96 } 97 98 /* 99 * insert a directory item in the tree, doing all the magic for 100 * both indexes. 'dir' indicates which objectid to insert it into, 101 * 'location' is the key to stuff into the directory item, 'type' is the 102 * type of the inode we're pointing to, and 'index' is the sequence number 103 * to use for the second index (if one is created). 104 * Will return 0 or -ENOMEM 105 */ 106 int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, const char *name, 107 int name_len, struct btrfs_inode *dir, 108 struct btrfs_key *location, u8 type, u64 index) 109 { 110 int ret = 0; 111 int ret2 = 0; 112 struct btrfs_root *root = dir->root; 113 struct btrfs_path *path; 114 struct btrfs_dir_item *dir_item; 115 struct extent_buffer *leaf; 116 unsigned long name_ptr; 117 struct btrfs_key key; 118 struct btrfs_disk_key disk_key; 119 u32 data_size; 120 121 key.objectid = btrfs_ino(dir); 122 key.type = BTRFS_DIR_ITEM_KEY; 123 key.offset = btrfs_name_hash(name, name_len); 124 125 path = btrfs_alloc_path(); 126 if (!path) 127 return -ENOMEM; 128 129 btrfs_cpu_key_to_disk(&disk_key, location); 130 131 data_size = sizeof(*dir_item) + name_len; 132 dir_item = insert_with_overflow(trans, root, path, &key, data_size, 133 name, name_len); 134 if (IS_ERR(dir_item)) { 135 ret = PTR_ERR(dir_item); 136 if (ret == -EEXIST) 137 goto second_insert; 138 goto out_free; 139 } 140 141 leaf = path->nodes[0]; 142 btrfs_set_dir_item_key(leaf, dir_item, &disk_key); 143 btrfs_set_dir_type(leaf, dir_item, type); 144 btrfs_set_dir_data_len(leaf, dir_item, 0); 145 btrfs_set_dir_name_len(leaf, dir_item, name_len); 146 btrfs_set_dir_transid(leaf, dir_item, trans->transid); 147 name_ptr = (unsigned long)(dir_item + 1); 148 149 write_extent_buffer(leaf, name, name_ptr, name_len); 150 btrfs_mark_buffer_dirty(leaf); 151 152 second_insert: 153 /* FIXME, use some real flag for selecting the extra index */ 154 if (root == root->fs_info->tree_root) { 155 ret = 0; 156 goto out_free; 157 } 158 btrfs_release_path(path); 159 160 ret2 = btrfs_insert_delayed_dir_index(trans, name, name_len, dir, 161 &disk_key, type, index); 162 out_free: 163 btrfs_free_path(path); 164 if (ret) 165 return ret; 166 if (ret2) 167 return ret2; 168 return 0; 169 } 170 171 static struct btrfs_dir_item *btrfs_lookup_match_dir( 172 struct btrfs_trans_handle *trans, 173 struct btrfs_root *root, struct btrfs_path *path, 174 struct btrfs_key *key, const char *name, 175 int name_len, int mod) 176 { 177 const int ins_len = (mod < 0 ? -1 : 0); 178 const int cow = (mod != 0); 179 int ret; 180 181 ret = btrfs_search_slot(trans, root, key, path, ins_len, cow); 182 if (ret < 0) 183 return ERR_PTR(ret); 184 if (ret > 0) 185 return ERR_PTR(-ENOENT); 186 187 return btrfs_match_dir_item_name(root->fs_info, path, name, name_len); 188 } 189 190 /* 191 * Lookup for a directory item by name. 192 * 193 * @trans: The transaction handle to use. Can be NULL if @mod is 0. 194 * @root: The root of the target tree. 195 * @path: Path to use for the search. 196 * @dir: The inode number (objectid) of the directory. 197 * @name: The name associated to the directory entry we are looking for. 198 * @name_len: The length of the name. 199 * @mod: Used to indicate if the tree search is meant for a read only 200 * lookup, for a modification lookup or for a deletion lookup, so 201 * its value should be 0, 1 or -1, respectively. 202 * 203 * Returns: NULL if the dir item does not exists, an error pointer if an error 204 * happened, or a pointer to a dir item if a dir item exists for the given name. 205 */ 206 struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, 207 struct btrfs_root *root, 208 struct btrfs_path *path, u64 dir, 209 const char *name, int name_len, 210 int mod) 211 { 212 struct btrfs_key key; 213 struct btrfs_dir_item *di; 214 215 key.objectid = dir; 216 key.type = BTRFS_DIR_ITEM_KEY; 217 key.offset = btrfs_name_hash(name, name_len); 218 219 di = btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod); 220 if (IS_ERR(di) && PTR_ERR(di) == -ENOENT) 221 return NULL; 222 223 return di; 224 } 225 226 int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir, 227 const char *name, int name_len) 228 { 229 int ret; 230 struct btrfs_key key; 231 struct btrfs_dir_item *di; 232 int data_size; 233 struct extent_buffer *leaf; 234 int slot; 235 struct btrfs_path *path; 236 237 path = btrfs_alloc_path(); 238 if (!path) 239 return -ENOMEM; 240 241 key.objectid = dir; 242 key.type = BTRFS_DIR_ITEM_KEY; 243 key.offset = btrfs_name_hash(name, name_len); 244 245 di = btrfs_lookup_match_dir(NULL, root, path, &key, name, name_len, 0); 246 if (IS_ERR(di)) { 247 ret = PTR_ERR(di); 248 /* Nothing found, we're safe */ 249 if (ret == -ENOENT) { 250 ret = 0; 251 goto out; 252 } 253 254 if (ret < 0) 255 goto out; 256 } 257 258 /* we found an item, look for our name in the item */ 259 if (di) { 260 /* our exact name was found */ 261 ret = -EEXIST; 262 goto out; 263 } 264 265 /* 266 * see if there is room in the item to insert this 267 * name 268 */ 269 data_size = sizeof(*di) + name_len; 270 leaf = path->nodes[0]; 271 slot = path->slots[0]; 272 if (data_size + btrfs_item_size(leaf, slot) + 273 sizeof(struct btrfs_item) > BTRFS_LEAF_DATA_SIZE(root->fs_info)) { 274 ret = -EOVERFLOW; 275 } else { 276 /* plenty of insertion room */ 277 ret = 0; 278 } 279 out: 280 btrfs_free_path(path); 281 return ret; 282 } 283 284 /* 285 * Lookup for a directory index item by name and index number. 286 * 287 * @trans: The transaction handle to use. Can be NULL if @mod is 0. 288 * @root: The root of the target tree. 289 * @path: Path to use for the search. 290 * @dir: The inode number (objectid) of the directory. 291 * @index: The index number. 292 * @name: The name associated to the directory entry we are looking for. 293 * @name_len: The length of the name. 294 * @mod: Used to indicate if the tree search is meant for a read only 295 * lookup, for a modification lookup or for a deletion lookup, so 296 * its value should be 0, 1 or -1, respectively. 297 * 298 * Returns: NULL if the dir index item does not exists, an error pointer if an 299 * error happened, or a pointer to a dir item if the dir index item exists and 300 * matches the criteria (name and index number). 301 */ 302 struct btrfs_dir_item * 303 btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans, 304 struct btrfs_root *root, 305 struct btrfs_path *path, u64 dir, 306 u64 index, const char *name, int name_len, 307 int mod) 308 { 309 struct btrfs_dir_item *di; 310 struct btrfs_key key; 311 312 key.objectid = dir; 313 key.type = BTRFS_DIR_INDEX_KEY; 314 key.offset = index; 315 316 di = btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod); 317 if (di == ERR_PTR(-ENOENT)) 318 return NULL; 319 320 return di; 321 } 322 323 struct btrfs_dir_item * 324 btrfs_search_dir_index_item(struct btrfs_root *root, 325 struct btrfs_path *path, u64 dirid, 326 const char *name, int name_len) 327 { 328 struct extent_buffer *leaf; 329 struct btrfs_dir_item *di; 330 struct btrfs_key key; 331 u32 nritems; 332 int ret; 333 334 key.objectid = dirid; 335 key.type = BTRFS_DIR_INDEX_KEY; 336 key.offset = 0; 337 338 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 339 if (ret < 0) 340 return ERR_PTR(ret); 341 342 leaf = path->nodes[0]; 343 nritems = btrfs_header_nritems(leaf); 344 345 while (1) { 346 if (path->slots[0] >= nritems) { 347 ret = btrfs_next_leaf(root, path); 348 if (ret < 0) 349 return ERR_PTR(ret); 350 if (ret > 0) 351 break; 352 leaf = path->nodes[0]; 353 nritems = btrfs_header_nritems(leaf); 354 continue; 355 } 356 357 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); 358 if (key.objectid != dirid || key.type != BTRFS_DIR_INDEX_KEY) 359 break; 360 361 di = btrfs_match_dir_item_name(root->fs_info, path, 362 name, name_len); 363 if (di) 364 return di; 365 366 path->slots[0]++; 367 } 368 return NULL; 369 } 370 371 struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, 372 struct btrfs_root *root, 373 struct btrfs_path *path, u64 dir, 374 const char *name, u16 name_len, 375 int mod) 376 { 377 struct btrfs_key key; 378 struct btrfs_dir_item *di; 379 380 key.objectid = dir; 381 key.type = BTRFS_XATTR_ITEM_KEY; 382 key.offset = btrfs_name_hash(name, name_len); 383 384 di = btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod); 385 if (IS_ERR(di) && PTR_ERR(di) == -ENOENT) 386 return NULL; 387 388 return di; 389 } 390 391 /* 392 * helper function to look at the directory item pointed to by 'path' 393 * this walks through all the entries in a dir item and finds one 394 * for a specific name. 395 */ 396 struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_fs_info *fs_info, 397 struct btrfs_path *path, 398 const char *name, int name_len) 399 { 400 struct btrfs_dir_item *dir_item; 401 unsigned long name_ptr; 402 u32 total_len; 403 u32 cur = 0; 404 u32 this_len; 405 struct extent_buffer *leaf; 406 407 leaf = path->nodes[0]; 408 dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); 409 410 total_len = btrfs_item_size(leaf, path->slots[0]); 411 while (cur < total_len) { 412 this_len = sizeof(*dir_item) + 413 btrfs_dir_name_len(leaf, dir_item) + 414 btrfs_dir_data_len(leaf, dir_item); 415 name_ptr = (unsigned long)(dir_item + 1); 416 417 if (btrfs_dir_name_len(leaf, dir_item) == name_len && 418 memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) 419 return dir_item; 420 421 cur += this_len; 422 dir_item = (struct btrfs_dir_item *)((char *)dir_item + 423 this_len); 424 } 425 return NULL; 426 } 427 428 /* 429 * given a pointer into a directory item, delete it. This 430 * handles items that have more than one entry in them. 431 */ 432 int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, 433 struct btrfs_root *root, 434 struct btrfs_path *path, 435 struct btrfs_dir_item *di) 436 { 437 438 struct extent_buffer *leaf; 439 u32 sub_item_len; 440 u32 item_len; 441 int ret = 0; 442 443 leaf = path->nodes[0]; 444 sub_item_len = sizeof(*di) + btrfs_dir_name_len(leaf, di) + 445 btrfs_dir_data_len(leaf, di); 446 item_len = btrfs_item_size(leaf, path->slots[0]); 447 if (sub_item_len == item_len) { 448 ret = btrfs_del_item(trans, root, path); 449 } else { 450 /* MARKER */ 451 unsigned long ptr = (unsigned long)di; 452 unsigned long start; 453 454 start = btrfs_item_ptr_offset(leaf, path->slots[0]); 455 memmove_extent_buffer(leaf, ptr, ptr + sub_item_len, 456 item_len - (ptr + sub_item_len - start)); 457 btrfs_truncate_item(path, item_len - sub_item_len, 1); 458 } 459 return ret; 460 } 461