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 btrfs_dir_item *di; 329 struct btrfs_key key; 330 int ret; 331 332 key.objectid = dirid; 333 key.type = BTRFS_DIR_INDEX_KEY; 334 key.offset = 0; 335 336 btrfs_for_each_slot(root, &key, &key, path, ret) { 337 if (key.objectid != dirid || key.type != BTRFS_DIR_INDEX_KEY) 338 break; 339 340 di = btrfs_match_dir_item_name(root->fs_info, path, 341 name, name_len); 342 if (di) 343 return di; 344 } 345 /* Adjust return code if the key was not found in the next leaf. */ 346 if (ret > 0) 347 ret = 0; 348 349 return ERR_PTR(ret); 350 } 351 352 struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, 353 struct btrfs_root *root, 354 struct btrfs_path *path, u64 dir, 355 const char *name, u16 name_len, 356 int mod) 357 { 358 struct btrfs_key key; 359 struct btrfs_dir_item *di; 360 361 key.objectid = dir; 362 key.type = BTRFS_XATTR_ITEM_KEY; 363 key.offset = btrfs_name_hash(name, name_len); 364 365 di = btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod); 366 if (IS_ERR(di) && PTR_ERR(di) == -ENOENT) 367 return NULL; 368 369 return di; 370 } 371 372 /* 373 * helper function to look at the directory item pointed to by 'path' 374 * this walks through all the entries in a dir item and finds one 375 * for a specific name. 376 */ 377 struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_fs_info *fs_info, 378 struct btrfs_path *path, 379 const char *name, int name_len) 380 { 381 struct btrfs_dir_item *dir_item; 382 unsigned long name_ptr; 383 u32 total_len; 384 u32 cur = 0; 385 u32 this_len; 386 struct extent_buffer *leaf; 387 388 leaf = path->nodes[0]; 389 dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); 390 391 total_len = btrfs_item_size(leaf, path->slots[0]); 392 while (cur < total_len) { 393 this_len = sizeof(*dir_item) + 394 btrfs_dir_name_len(leaf, dir_item) + 395 btrfs_dir_data_len(leaf, dir_item); 396 name_ptr = (unsigned long)(dir_item + 1); 397 398 if (btrfs_dir_name_len(leaf, dir_item) == name_len && 399 memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) 400 return dir_item; 401 402 cur += this_len; 403 dir_item = (struct btrfs_dir_item *)((char *)dir_item + 404 this_len); 405 } 406 return NULL; 407 } 408 409 /* 410 * given a pointer into a directory item, delete it. This 411 * handles items that have more than one entry in them. 412 */ 413 int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, 414 struct btrfs_root *root, 415 struct btrfs_path *path, 416 struct btrfs_dir_item *di) 417 { 418 419 struct extent_buffer *leaf; 420 u32 sub_item_len; 421 u32 item_len; 422 int ret = 0; 423 424 leaf = path->nodes[0]; 425 sub_item_len = sizeof(*di) + btrfs_dir_name_len(leaf, di) + 426 btrfs_dir_data_len(leaf, di); 427 item_len = btrfs_item_size(leaf, path->slots[0]); 428 if (sub_item_len == item_len) { 429 ret = btrfs_del_item(trans, root, path); 430 } else { 431 /* MARKER */ 432 unsigned long ptr = (unsigned long)di; 433 unsigned long start; 434 435 start = btrfs_item_ptr_offset(leaf, path->slots[0]); 436 memmove_extent_buffer(leaf, ptr, ptr + sub_item_len, 437 item_len - (ptr + sub_item_len - start)); 438 btrfs_truncate_item(path, item_len - sub_item_len, 1); 439 } 440 return ret; 441 } 442