1 /* 2 * btree.c - NILFS B-tree. 3 * 4 * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 * 20 * Written by Koji Sato <koji@osrg.net>. 21 */ 22 23 #include <linux/slab.h> 24 #include <linux/string.h> 25 #include <linux/errno.h> 26 #include <linux/pagevec.h> 27 #include "nilfs.h" 28 #include "page.h" 29 #include "btnode.h" 30 #include "btree.h" 31 #include "alloc.h" 32 33 /** 34 * struct nilfs_btree_path - A path on which B-tree operations are executed 35 * @bp_bh: buffer head of node block 36 * @bp_sib_bh: buffer head of sibling node block 37 * @bp_index: index of child node 38 * @bp_oldreq: ptr end request for old ptr 39 * @bp_newreq: ptr alloc request for new ptr 40 * @bp_op: rebalance operation 41 */ 42 struct nilfs_btree_path { 43 struct buffer_head *bp_bh; 44 struct buffer_head *bp_sib_bh; 45 int bp_index; 46 union nilfs_bmap_ptr_req bp_oldreq; 47 union nilfs_bmap_ptr_req bp_newreq; 48 struct nilfs_btnode_chkey_ctxt bp_ctxt; 49 void (*bp_op)(struct nilfs_btree *, struct nilfs_btree_path *, 50 int, __u64 *, __u64 *); 51 }; 52 53 /* 54 * B-tree path operations 55 */ 56 57 static struct kmem_cache *nilfs_btree_path_cache; 58 59 int __init nilfs_btree_path_cache_init(void) 60 { 61 nilfs_btree_path_cache = 62 kmem_cache_create("nilfs2_btree_path_cache", 63 sizeof(struct nilfs_btree_path) * 64 NILFS_BTREE_LEVEL_MAX, 0, 0, NULL); 65 return (nilfs_btree_path_cache != NULL) ? 0 : -ENOMEM; 66 } 67 68 void nilfs_btree_path_cache_destroy(void) 69 { 70 kmem_cache_destroy(nilfs_btree_path_cache); 71 } 72 73 static inline struct nilfs_btree_path * 74 nilfs_btree_alloc_path(const struct nilfs_btree *btree) 75 { 76 return (struct nilfs_btree_path *) 77 kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS); 78 } 79 80 static inline void nilfs_btree_free_path(const struct nilfs_btree *btree, 81 struct nilfs_btree_path *path) 82 { 83 kmem_cache_free(nilfs_btree_path_cache, path); 84 } 85 86 static void nilfs_btree_init_path(const struct nilfs_btree *btree, 87 struct nilfs_btree_path *path) 88 { 89 int level; 90 91 for (level = NILFS_BTREE_LEVEL_DATA; 92 level < NILFS_BTREE_LEVEL_MAX; 93 level++) { 94 path[level].bp_bh = NULL; 95 path[level].bp_sib_bh = NULL; 96 path[level].bp_index = 0; 97 path[level].bp_oldreq.bpr_ptr = NILFS_BMAP_INVALID_PTR; 98 path[level].bp_newreq.bpr_ptr = NILFS_BMAP_INVALID_PTR; 99 path[level].bp_op = NULL; 100 } 101 } 102 103 static void nilfs_btree_clear_path(const struct nilfs_btree *btree, 104 struct nilfs_btree_path *path) 105 { 106 int level; 107 108 for (level = NILFS_BTREE_LEVEL_DATA; 109 level < NILFS_BTREE_LEVEL_MAX; 110 level++) { 111 if (path[level].bp_bh != NULL) { 112 nilfs_bmap_put_block(&btree->bt_bmap, 113 path[level].bp_bh); 114 path[level].bp_bh = NULL; 115 } 116 /* sib_bh is released or deleted by prepare or commit 117 * operations. */ 118 path[level].bp_sib_bh = NULL; 119 path[level].bp_index = 0; 120 path[level].bp_oldreq.bpr_ptr = NILFS_BMAP_INVALID_PTR; 121 path[level].bp_newreq.bpr_ptr = NILFS_BMAP_INVALID_PTR; 122 path[level].bp_op = NULL; 123 } 124 } 125 126 127 /* 128 * B-tree node operations 129 */ 130 131 static inline int 132 nilfs_btree_node_get_flags(const struct nilfs_btree *btree, 133 const struct nilfs_btree_node *node) 134 { 135 return node->bn_flags; 136 } 137 138 static inline void 139 nilfs_btree_node_set_flags(struct nilfs_btree *btree, 140 struct nilfs_btree_node *node, 141 int flags) 142 { 143 node->bn_flags = flags; 144 } 145 146 static inline int nilfs_btree_node_root(const struct nilfs_btree *btree, 147 const struct nilfs_btree_node *node) 148 { 149 return nilfs_btree_node_get_flags(btree, node) & NILFS_BTREE_NODE_ROOT; 150 } 151 152 static inline int 153 nilfs_btree_node_get_level(const struct nilfs_btree *btree, 154 const struct nilfs_btree_node *node) 155 { 156 return node->bn_level; 157 } 158 159 static inline void 160 nilfs_btree_node_set_level(struct nilfs_btree *btree, 161 struct nilfs_btree_node *node, 162 int level) 163 { 164 node->bn_level = level; 165 } 166 167 static inline int 168 nilfs_btree_node_get_nchildren(const struct nilfs_btree *btree, 169 const struct nilfs_btree_node *node) 170 { 171 return le16_to_cpu(node->bn_nchildren); 172 } 173 174 static inline void 175 nilfs_btree_node_set_nchildren(struct nilfs_btree *btree, 176 struct nilfs_btree_node *node, 177 int nchildren) 178 { 179 node->bn_nchildren = cpu_to_le16(nchildren); 180 } 181 182 static inline int 183 nilfs_btree_node_size(const struct nilfs_btree *btree) 184 { 185 return 1 << btree->bt_bmap.b_inode->i_blkbits; 186 } 187 188 static inline int 189 nilfs_btree_node_nchildren_min(const struct nilfs_btree *btree, 190 const struct nilfs_btree_node *node) 191 { 192 return nilfs_btree_node_root(btree, node) ? 193 NILFS_BTREE_ROOT_NCHILDREN_MIN : 194 NILFS_BTREE_NODE_NCHILDREN_MIN(nilfs_btree_node_size(btree)); 195 } 196 197 static inline int 198 nilfs_btree_node_nchildren_max(const struct nilfs_btree *btree, 199 const struct nilfs_btree_node *node) 200 { 201 return nilfs_btree_node_root(btree, node) ? 202 NILFS_BTREE_ROOT_NCHILDREN_MAX : 203 NILFS_BTREE_NODE_NCHILDREN_MAX(nilfs_btree_node_size(btree)); 204 } 205 206 static inline __le64 * 207 nilfs_btree_node_dkeys(const struct nilfs_btree *btree, 208 const struct nilfs_btree_node *node) 209 { 210 return (__le64 *)((char *)(node + 1) + 211 (nilfs_btree_node_root(btree, node) ? 212 0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE)); 213 } 214 215 static inline __le64 * 216 nilfs_btree_node_dptrs(const struct nilfs_btree *btree, 217 const struct nilfs_btree_node *node) 218 { 219 return (__le64 *)(nilfs_btree_node_dkeys(btree, node) + 220 nilfs_btree_node_nchildren_max(btree, node)); 221 } 222 223 static inline __u64 224 nilfs_btree_node_get_key(const struct nilfs_btree *btree, 225 const struct nilfs_btree_node *node, int index) 226 { 227 return nilfs_bmap_dkey_to_key(*(nilfs_btree_node_dkeys(btree, node) + 228 index)); 229 } 230 231 static inline void 232 nilfs_btree_node_set_key(struct nilfs_btree *btree, 233 struct nilfs_btree_node *node, int index, __u64 key) 234 { 235 *(nilfs_btree_node_dkeys(btree, node) + index) = 236 nilfs_bmap_key_to_dkey(key); 237 } 238 239 static inline __u64 240 nilfs_btree_node_get_ptr(const struct nilfs_btree *btree, 241 const struct nilfs_btree_node *node, 242 int index) 243 { 244 return nilfs_bmap_dptr_to_ptr(*(nilfs_btree_node_dptrs(btree, node) + 245 index)); 246 } 247 248 static inline void 249 nilfs_btree_node_set_ptr(struct nilfs_btree *btree, 250 struct nilfs_btree_node *node, 251 int index, 252 __u64 ptr) 253 { 254 *(nilfs_btree_node_dptrs(btree, node) + index) = 255 nilfs_bmap_ptr_to_dptr(ptr); 256 } 257 258 static void nilfs_btree_node_init(struct nilfs_btree *btree, 259 struct nilfs_btree_node *node, 260 int flags, int level, int nchildren, 261 const __u64 *keys, const __u64 *ptrs) 262 { 263 __le64 *dkeys; 264 __le64 *dptrs; 265 int i; 266 267 nilfs_btree_node_set_flags(btree, node, flags); 268 nilfs_btree_node_set_level(btree, node, level); 269 nilfs_btree_node_set_nchildren(btree, node, nchildren); 270 271 dkeys = nilfs_btree_node_dkeys(btree, node); 272 dptrs = nilfs_btree_node_dptrs(btree, node); 273 for (i = 0; i < nchildren; i++) { 274 dkeys[i] = nilfs_bmap_key_to_dkey(keys[i]); 275 dptrs[i] = nilfs_bmap_ptr_to_dptr(ptrs[i]); 276 } 277 } 278 279 /* Assume the buffer heads corresponding to left and right are locked. */ 280 static void nilfs_btree_node_move_left(struct nilfs_btree *btree, 281 struct nilfs_btree_node *left, 282 struct nilfs_btree_node *right, 283 int n) 284 { 285 __le64 *ldkeys, *rdkeys; 286 __le64 *ldptrs, *rdptrs; 287 int lnchildren, rnchildren; 288 289 ldkeys = nilfs_btree_node_dkeys(btree, left); 290 ldptrs = nilfs_btree_node_dptrs(btree, left); 291 lnchildren = nilfs_btree_node_get_nchildren(btree, left); 292 293 rdkeys = nilfs_btree_node_dkeys(btree, right); 294 rdptrs = nilfs_btree_node_dptrs(btree, right); 295 rnchildren = nilfs_btree_node_get_nchildren(btree, right); 296 297 memcpy(ldkeys + lnchildren, rdkeys, n * sizeof(*rdkeys)); 298 memcpy(ldptrs + lnchildren, rdptrs, n * sizeof(*rdptrs)); 299 memmove(rdkeys, rdkeys + n, (rnchildren - n) * sizeof(*rdkeys)); 300 memmove(rdptrs, rdptrs + n, (rnchildren - n) * sizeof(*rdptrs)); 301 302 lnchildren += n; 303 rnchildren -= n; 304 nilfs_btree_node_set_nchildren(btree, left, lnchildren); 305 nilfs_btree_node_set_nchildren(btree, right, rnchildren); 306 } 307 308 /* Assume that the buffer heads corresponding to left and right are locked. */ 309 static void nilfs_btree_node_move_right(struct nilfs_btree *btree, 310 struct nilfs_btree_node *left, 311 struct nilfs_btree_node *right, 312 int n) 313 { 314 __le64 *ldkeys, *rdkeys; 315 __le64 *ldptrs, *rdptrs; 316 int lnchildren, rnchildren; 317 318 ldkeys = nilfs_btree_node_dkeys(btree, left); 319 ldptrs = nilfs_btree_node_dptrs(btree, left); 320 lnchildren = nilfs_btree_node_get_nchildren(btree, left); 321 322 rdkeys = nilfs_btree_node_dkeys(btree, right); 323 rdptrs = nilfs_btree_node_dptrs(btree, right); 324 rnchildren = nilfs_btree_node_get_nchildren(btree, right); 325 326 memmove(rdkeys + n, rdkeys, rnchildren * sizeof(*rdkeys)); 327 memmove(rdptrs + n, rdptrs, rnchildren * sizeof(*rdptrs)); 328 memcpy(rdkeys, ldkeys + lnchildren - n, n * sizeof(*rdkeys)); 329 memcpy(rdptrs, ldptrs + lnchildren - n, n * sizeof(*rdptrs)); 330 331 lnchildren -= n; 332 rnchildren += n; 333 nilfs_btree_node_set_nchildren(btree, left, lnchildren); 334 nilfs_btree_node_set_nchildren(btree, right, rnchildren); 335 } 336 337 /* Assume that the buffer head corresponding to node is locked. */ 338 static void nilfs_btree_node_insert(struct nilfs_btree *btree, 339 struct nilfs_btree_node *node, 340 __u64 key, __u64 ptr, int index) 341 { 342 __le64 *dkeys; 343 __le64 *dptrs; 344 int nchildren; 345 346 dkeys = nilfs_btree_node_dkeys(btree, node); 347 dptrs = nilfs_btree_node_dptrs(btree, node); 348 nchildren = nilfs_btree_node_get_nchildren(btree, node); 349 if (index < nchildren) { 350 memmove(dkeys + index + 1, dkeys + index, 351 (nchildren - index) * sizeof(*dkeys)); 352 memmove(dptrs + index + 1, dptrs + index, 353 (nchildren - index) * sizeof(*dptrs)); 354 } 355 dkeys[index] = nilfs_bmap_key_to_dkey(key); 356 dptrs[index] = nilfs_bmap_ptr_to_dptr(ptr); 357 nchildren++; 358 nilfs_btree_node_set_nchildren(btree, node, nchildren); 359 } 360 361 /* Assume that the buffer head corresponding to node is locked. */ 362 static void nilfs_btree_node_delete(struct nilfs_btree *btree, 363 struct nilfs_btree_node *node, 364 __u64 *keyp, __u64 *ptrp, int index) 365 { 366 __u64 key; 367 __u64 ptr; 368 __le64 *dkeys; 369 __le64 *dptrs; 370 int nchildren; 371 372 dkeys = nilfs_btree_node_dkeys(btree, node); 373 dptrs = nilfs_btree_node_dptrs(btree, node); 374 key = nilfs_bmap_dkey_to_key(dkeys[index]); 375 ptr = nilfs_bmap_dptr_to_ptr(dptrs[index]); 376 nchildren = nilfs_btree_node_get_nchildren(btree, node); 377 if (keyp != NULL) 378 *keyp = key; 379 if (ptrp != NULL) 380 *ptrp = ptr; 381 382 if (index < nchildren - 1) { 383 memmove(dkeys + index, dkeys + index + 1, 384 (nchildren - index - 1) * sizeof(*dkeys)); 385 memmove(dptrs + index, dptrs + index + 1, 386 (nchildren - index - 1) * sizeof(*dptrs)); 387 } 388 nchildren--; 389 nilfs_btree_node_set_nchildren(btree, node, nchildren); 390 } 391 392 static int nilfs_btree_node_lookup(const struct nilfs_btree *btree, 393 const struct nilfs_btree_node *node, 394 __u64 key, int *indexp) 395 { 396 __u64 nkey; 397 int index, low, high, s; 398 399 /* binary search */ 400 low = 0; 401 high = nilfs_btree_node_get_nchildren(btree, node) - 1; 402 index = 0; 403 s = 0; 404 while (low <= high) { 405 index = (low + high) / 2; 406 nkey = nilfs_btree_node_get_key(btree, node, index); 407 if (nkey == key) { 408 s = 0; 409 goto out; 410 } else if (nkey < key) { 411 low = index + 1; 412 s = -1; 413 } else { 414 high = index - 1; 415 s = 1; 416 } 417 } 418 419 /* adjust index */ 420 if (nilfs_btree_node_get_level(btree, node) > 421 NILFS_BTREE_LEVEL_NODE_MIN) { 422 if ((s > 0) && (index > 0)) 423 index--; 424 } else if (s < 0) 425 index++; 426 427 out: 428 *indexp = index; 429 430 return s == 0; 431 } 432 433 static inline struct nilfs_btree_node * 434 nilfs_btree_get_root(const struct nilfs_btree *btree) 435 { 436 return (struct nilfs_btree_node *)btree->bt_bmap.b_u.u_data; 437 } 438 439 static inline struct nilfs_btree_node * 440 nilfs_btree_get_nonroot_node(const struct nilfs_btree *btree, 441 const struct nilfs_btree_path *path, 442 int level) 443 { 444 return (struct nilfs_btree_node *)path[level].bp_bh->b_data; 445 } 446 447 static inline struct nilfs_btree_node * 448 nilfs_btree_get_sib_node(const struct nilfs_btree *btree, 449 const struct nilfs_btree_path *path, 450 int level) 451 { 452 return (struct nilfs_btree_node *)path[level].bp_sib_bh->b_data; 453 } 454 455 static inline int nilfs_btree_height(const struct nilfs_btree *btree) 456 { 457 return nilfs_btree_node_get_level(btree, nilfs_btree_get_root(btree)) 458 + 1; 459 } 460 461 static inline struct nilfs_btree_node * 462 nilfs_btree_get_node(const struct nilfs_btree *btree, 463 const struct nilfs_btree_path *path, 464 int level) 465 { 466 return (level == nilfs_btree_height(btree) - 1) ? 467 nilfs_btree_get_root(btree) : 468 nilfs_btree_get_nonroot_node(btree, path, level); 469 } 470 471 static int nilfs_btree_do_lookup(const struct nilfs_btree *btree, 472 struct nilfs_btree_path *path, 473 __u64 key, __u64 *ptrp, int minlevel) 474 { 475 struct nilfs_btree_node *node; 476 __u64 ptr; 477 int level, index, found, ret; 478 479 node = nilfs_btree_get_root(btree); 480 level = nilfs_btree_node_get_level(btree, node); 481 if ((level < minlevel) || 482 (nilfs_btree_node_get_nchildren(btree, node) <= 0)) 483 return -ENOENT; 484 485 found = nilfs_btree_node_lookup(btree, node, key, &index); 486 ptr = nilfs_btree_node_get_ptr(btree, node, index); 487 path[level].bp_bh = NULL; 488 path[level].bp_index = index; 489 490 for (level--; level >= minlevel; level--) { 491 ret = nilfs_bmap_get_block(&btree->bt_bmap, ptr, 492 &path[level].bp_bh); 493 if (ret < 0) 494 return ret; 495 node = nilfs_btree_get_nonroot_node(btree, path, level); 496 BUG_ON(level != nilfs_btree_node_get_level(btree, node)); 497 if (!found) 498 found = nilfs_btree_node_lookup(btree, node, key, 499 &index); 500 else 501 index = 0; 502 if (index < nilfs_btree_node_nchildren_max(btree, node)) 503 ptr = nilfs_btree_node_get_ptr(btree, node, index); 504 else { 505 WARN_ON(found || level != NILFS_BTREE_LEVEL_NODE_MIN); 506 /* insert */ 507 ptr = NILFS_BMAP_INVALID_PTR; 508 } 509 path[level].bp_index = index; 510 } 511 if (!found) 512 return -ENOENT; 513 514 if (ptrp != NULL) 515 *ptrp = ptr; 516 517 return 0; 518 } 519 520 static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree, 521 struct nilfs_btree_path *path, 522 __u64 *keyp, __u64 *ptrp) 523 { 524 struct nilfs_btree_node *node; 525 __u64 ptr; 526 int index, level, ret; 527 528 node = nilfs_btree_get_root(btree); 529 index = nilfs_btree_node_get_nchildren(btree, node) - 1; 530 if (index < 0) 531 return -ENOENT; 532 level = nilfs_btree_node_get_level(btree, node); 533 ptr = nilfs_btree_node_get_ptr(btree, node, index); 534 path[level].bp_bh = NULL; 535 path[level].bp_index = index; 536 537 for (level--; level > 0; level--) { 538 ret = nilfs_bmap_get_block(&btree->bt_bmap, ptr, 539 &path[level].bp_bh); 540 if (ret < 0) 541 return ret; 542 node = nilfs_btree_get_nonroot_node(btree, path, level); 543 BUG_ON(level != nilfs_btree_node_get_level(btree, node)); 544 index = nilfs_btree_node_get_nchildren(btree, node) - 1; 545 ptr = nilfs_btree_node_get_ptr(btree, node, index); 546 path[level].bp_index = index; 547 } 548 549 if (keyp != NULL) 550 *keyp = nilfs_btree_node_get_key(btree, node, index); 551 if (ptrp != NULL) 552 *ptrp = ptr; 553 554 return 0; 555 } 556 557 static int nilfs_btree_lookup(const struct nilfs_bmap *bmap, 558 __u64 key, int level, __u64 *ptrp) 559 { 560 struct nilfs_btree *btree; 561 struct nilfs_btree_path *path; 562 __u64 ptr; 563 int ret; 564 565 btree = (struct nilfs_btree *)bmap; 566 path = nilfs_btree_alloc_path(btree); 567 if (path == NULL) 568 return -ENOMEM; 569 nilfs_btree_init_path(btree, path); 570 571 ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level); 572 573 if (ptrp != NULL) 574 *ptrp = ptr; 575 576 nilfs_btree_clear_path(btree, path); 577 nilfs_btree_free_path(btree, path); 578 579 return ret; 580 } 581 582 static void nilfs_btree_promote_key(struct nilfs_btree *btree, 583 struct nilfs_btree_path *path, 584 int level, __u64 key) 585 { 586 if (level < nilfs_btree_height(btree) - 1) { 587 do { 588 lock_buffer(path[level].bp_bh); 589 nilfs_btree_node_set_key( 590 btree, 591 nilfs_btree_get_nonroot_node( 592 btree, path, level), 593 path[level].bp_index, key); 594 if (!buffer_dirty(path[level].bp_bh)) 595 nilfs_btnode_mark_dirty(path[level].bp_bh); 596 unlock_buffer(path[level].bp_bh); 597 } while ((path[level].bp_index == 0) && 598 (++level < nilfs_btree_height(btree) - 1)); 599 } 600 601 /* root */ 602 if (level == nilfs_btree_height(btree) - 1) { 603 nilfs_btree_node_set_key(btree, 604 nilfs_btree_get_root(btree), 605 path[level].bp_index, key); 606 } 607 } 608 609 static void nilfs_btree_do_insert(struct nilfs_btree *btree, 610 struct nilfs_btree_path *path, 611 int level, __u64 *keyp, __u64 *ptrp) 612 { 613 struct nilfs_btree_node *node; 614 615 if (level < nilfs_btree_height(btree) - 1) { 616 lock_buffer(path[level].bp_bh); 617 node = nilfs_btree_get_nonroot_node(btree, path, level); 618 nilfs_btree_node_insert(btree, node, *keyp, *ptrp, 619 path[level].bp_index); 620 if (!buffer_dirty(path[level].bp_bh)) 621 nilfs_btnode_mark_dirty(path[level].bp_bh); 622 unlock_buffer(path[level].bp_bh); 623 624 if (path[level].bp_index == 0) 625 nilfs_btree_promote_key(btree, path, level + 1, 626 nilfs_btree_node_get_key( 627 btree, node, 0)); 628 } else { 629 node = nilfs_btree_get_root(btree); 630 nilfs_btree_node_insert(btree, node, *keyp, *ptrp, 631 path[level].bp_index); 632 } 633 } 634 635 static void nilfs_btree_carry_left(struct nilfs_btree *btree, 636 struct nilfs_btree_path *path, 637 int level, __u64 *keyp, __u64 *ptrp) 638 { 639 struct nilfs_btree_node *node, *left; 640 int nchildren, lnchildren, n, move; 641 642 lock_buffer(path[level].bp_bh); 643 lock_buffer(path[level].bp_sib_bh); 644 645 node = nilfs_btree_get_nonroot_node(btree, path, level); 646 left = nilfs_btree_get_sib_node(btree, path, level); 647 nchildren = nilfs_btree_node_get_nchildren(btree, node); 648 lnchildren = nilfs_btree_node_get_nchildren(btree, left); 649 move = 0; 650 651 n = (nchildren + lnchildren + 1) / 2 - lnchildren; 652 if (n > path[level].bp_index) { 653 /* move insert point */ 654 n--; 655 move = 1; 656 } 657 658 nilfs_btree_node_move_left(btree, left, node, n); 659 660 if (!buffer_dirty(path[level].bp_bh)) 661 nilfs_btnode_mark_dirty(path[level].bp_bh); 662 if (!buffer_dirty(path[level].bp_sib_bh)) 663 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 664 665 unlock_buffer(path[level].bp_bh); 666 unlock_buffer(path[level].bp_sib_bh); 667 668 nilfs_btree_promote_key(btree, path, level + 1, 669 nilfs_btree_node_get_key(btree, node, 0)); 670 671 if (move) { 672 nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_bh); 673 path[level].bp_bh = path[level].bp_sib_bh; 674 path[level].bp_sib_bh = NULL; 675 path[level].bp_index += lnchildren; 676 path[level + 1].bp_index--; 677 } else { 678 nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh); 679 path[level].bp_sib_bh = NULL; 680 path[level].bp_index -= n; 681 } 682 683 nilfs_btree_do_insert(btree, path, level, keyp, ptrp); 684 } 685 686 static void nilfs_btree_carry_right(struct nilfs_btree *btree, 687 struct nilfs_btree_path *path, 688 int level, __u64 *keyp, __u64 *ptrp) 689 { 690 struct nilfs_btree_node *node, *right; 691 int nchildren, rnchildren, n, move; 692 693 lock_buffer(path[level].bp_bh); 694 lock_buffer(path[level].bp_sib_bh); 695 696 node = nilfs_btree_get_nonroot_node(btree, path, level); 697 right = nilfs_btree_get_sib_node(btree, path, level); 698 nchildren = nilfs_btree_node_get_nchildren(btree, node); 699 rnchildren = nilfs_btree_node_get_nchildren(btree, right); 700 move = 0; 701 702 n = (nchildren + rnchildren + 1) / 2 - rnchildren; 703 if (n > nchildren - path[level].bp_index) { 704 /* move insert point */ 705 n--; 706 move = 1; 707 } 708 709 nilfs_btree_node_move_right(btree, node, right, n); 710 711 if (!buffer_dirty(path[level].bp_bh)) 712 nilfs_btnode_mark_dirty(path[level].bp_bh); 713 if (!buffer_dirty(path[level].bp_sib_bh)) 714 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 715 716 unlock_buffer(path[level].bp_bh); 717 unlock_buffer(path[level].bp_sib_bh); 718 719 path[level + 1].bp_index++; 720 nilfs_btree_promote_key(btree, path, level + 1, 721 nilfs_btree_node_get_key(btree, right, 0)); 722 path[level + 1].bp_index--; 723 724 if (move) { 725 nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_bh); 726 path[level].bp_bh = path[level].bp_sib_bh; 727 path[level].bp_sib_bh = NULL; 728 path[level].bp_index -= 729 nilfs_btree_node_get_nchildren(btree, node); 730 path[level + 1].bp_index++; 731 } else { 732 nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh); 733 path[level].bp_sib_bh = NULL; 734 } 735 736 nilfs_btree_do_insert(btree, path, level, keyp, ptrp); 737 } 738 739 static void nilfs_btree_split(struct nilfs_btree *btree, 740 struct nilfs_btree_path *path, 741 int level, __u64 *keyp, __u64 *ptrp) 742 { 743 struct nilfs_btree_node *node, *right; 744 __u64 newkey; 745 __u64 newptr; 746 int nchildren, n, move; 747 748 lock_buffer(path[level].bp_bh); 749 lock_buffer(path[level].bp_sib_bh); 750 751 node = nilfs_btree_get_nonroot_node(btree, path, level); 752 right = nilfs_btree_get_sib_node(btree, path, level); 753 nchildren = nilfs_btree_node_get_nchildren(btree, node); 754 move = 0; 755 756 n = (nchildren + 1) / 2; 757 if (n > nchildren - path[level].bp_index) { 758 n--; 759 move = 1; 760 } 761 762 nilfs_btree_node_move_right(btree, node, right, n); 763 764 if (!buffer_dirty(path[level].bp_bh)) 765 nilfs_btnode_mark_dirty(path[level].bp_bh); 766 if (!buffer_dirty(path[level].bp_sib_bh)) 767 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 768 769 unlock_buffer(path[level].bp_bh); 770 unlock_buffer(path[level].bp_sib_bh); 771 772 newkey = nilfs_btree_node_get_key(btree, right, 0); 773 newptr = path[level].bp_newreq.bpr_ptr; 774 775 if (move) { 776 path[level].bp_index -= 777 nilfs_btree_node_get_nchildren(btree, node); 778 nilfs_btree_node_insert(btree, right, *keyp, *ptrp, 779 path[level].bp_index); 780 781 *keyp = nilfs_btree_node_get_key(btree, right, 0); 782 *ptrp = path[level].bp_newreq.bpr_ptr; 783 784 nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_bh); 785 path[level].bp_bh = path[level].bp_sib_bh; 786 path[level].bp_sib_bh = NULL; 787 } else { 788 nilfs_btree_do_insert(btree, path, level, keyp, ptrp); 789 790 *keyp = nilfs_btree_node_get_key(btree, right, 0); 791 *ptrp = path[level].bp_newreq.bpr_ptr; 792 793 nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh); 794 path[level].bp_sib_bh = NULL; 795 } 796 797 path[level + 1].bp_index++; 798 } 799 800 static void nilfs_btree_grow(struct nilfs_btree *btree, 801 struct nilfs_btree_path *path, 802 int level, __u64 *keyp, __u64 *ptrp) 803 { 804 struct nilfs_btree_node *root, *child; 805 int n; 806 807 lock_buffer(path[level].bp_sib_bh); 808 809 root = nilfs_btree_get_root(btree); 810 child = nilfs_btree_get_sib_node(btree, path, level); 811 812 n = nilfs_btree_node_get_nchildren(btree, root); 813 814 nilfs_btree_node_move_right(btree, root, child, n); 815 nilfs_btree_node_set_level(btree, root, level + 1); 816 817 if (!buffer_dirty(path[level].bp_sib_bh)) 818 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 819 820 unlock_buffer(path[level].bp_sib_bh); 821 822 path[level].bp_bh = path[level].bp_sib_bh; 823 path[level].bp_sib_bh = NULL; 824 825 nilfs_btree_do_insert(btree, path, level, keyp, ptrp); 826 827 *keyp = nilfs_btree_node_get_key(btree, child, 0); 828 *ptrp = path[level].bp_newreq.bpr_ptr; 829 } 830 831 static __u64 nilfs_btree_find_near(const struct nilfs_btree *btree, 832 const struct nilfs_btree_path *path) 833 { 834 struct nilfs_btree_node *node; 835 int level; 836 837 if (path == NULL) 838 return NILFS_BMAP_INVALID_PTR; 839 840 /* left sibling */ 841 level = NILFS_BTREE_LEVEL_NODE_MIN; 842 if (path[level].bp_index > 0) { 843 node = nilfs_btree_get_node(btree, path, level); 844 return nilfs_btree_node_get_ptr(btree, node, 845 path[level].bp_index - 1); 846 } 847 848 /* parent */ 849 level = NILFS_BTREE_LEVEL_NODE_MIN + 1; 850 if (level <= nilfs_btree_height(btree) - 1) { 851 node = nilfs_btree_get_node(btree, path, level); 852 return nilfs_btree_node_get_ptr(btree, node, 853 path[level].bp_index); 854 } 855 856 return NILFS_BMAP_INVALID_PTR; 857 } 858 859 static __u64 nilfs_btree_find_target_v(const struct nilfs_btree *btree, 860 const struct nilfs_btree_path *path, 861 __u64 key) 862 { 863 __u64 ptr; 864 865 ptr = nilfs_bmap_find_target_seq(&btree->bt_bmap, key); 866 if (ptr != NILFS_BMAP_INVALID_PTR) 867 /* sequential access */ 868 return ptr; 869 else { 870 ptr = nilfs_btree_find_near(btree, path); 871 if (ptr != NILFS_BMAP_INVALID_PTR) 872 /* near */ 873 return ptr; 874 } 875 /* block group */ 876 return nilfs_bmap_find_target_in_group(&btree->bt_bmap); 877 } 878 879 static void nilfs_btree_set_target_v(struct nilfs_btree *btree, __u64 key, 880 __u64 ptr) 881 { 882 btree->bt_bmap.b_last_allocated_key = key; 883 btree->bt_bmap.b_last_allocated_ptr = ptr; 884 } 885 886 static int nilfs_btree_prepare_insert(struct nilfs_btree *btree, 887 struct nilfs_btree_path *path, 888 int *levelp, __u64 key, __u64 ptr, 889 struct nilfs_bmap_stats *stats) 890 { 891 struct buffer_head *bh; 892 struct nilfs_btree_node *node, *parent, *sib; 893 __u64 sibptr; 894 int pindex, level, ret; 895 896 stats->bs_nblocks = 0; 897 level = NILFS_BTREE_LEVEL_DATA; 898 899 /* allocate a new ptr for data block */ 900 if (btree->bt_ops->btop_find_target != NULL) 901 path[level].bp_newreq.bpr_ptr = 902 btree->bt_ops->btop_find_target(btree, path, key); 903 904 ret = btree->bt_bmap.b_pops->bpop_prepare_alloc_ptr( 905 &btree->bt_bmap, &path[level].bp_newreq); 906 if (ret < 0) 907 goto err_out_data; 908 909 for (level = NILFS_BTREE_LEVEL_NODE_MIN; 910 level < nilfs_btree_height(btree) - 1; 911 level++) { 912 node = nilfs_btree_get_nonroot_node(btree, path, level); 913 if (nilfs_btree_node_get_nchildren(btree, node) < 914 nilfs_btree_node_nchildren_max(btree, node)) { 915 path[level].bp_op = nilfs_btree_do_insert; 916 stats->bs_nblocks++; 917 goto out; 918 } 919 920 parent = nilfs_btree_get_node(btree, path, level + 1); 921 pindex = path[level + 1].bp_index; 922 923 /* left sibling */ 924 if (pindex > 0) { 925 sibptr = nilfs_btree_node_get_ptr(btree, parent, 926 pindex - 1); 927 ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr, 928 &bh); 929 if (ret < 0) 930 goto err_out_child_node; 931 sib = (struct nilfs_btree_node *)bh->b_data; 932 if (nilfs_btree_node_get_nchildren(btree, sib) < 933 nilfs_btree_node_nchildren_max(btree, sib)) { 934 path[level].bp_sib_bh = bh; 935 path[level].bp_op = nilfs_btree_carry_left; 936 stats->bs_nblocks++; 937 goto out; 938 } else 939 nilfs_bmap_put_block(&btree->bt_bmap, bh); 940 } 941 942 /* right sibling */ 943 if (pindex < 944 nilfs_btree_node_get_nchildren(btree, parent) - 1) { 945 sibptr = nilfs_btree_node_get_ptr(btree, parent, 946 pindex + 1); 947 ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr, 948 &bh); 949 if (ret < 0) 950 goto err_out_child_node; 951 sib = (struct nilfs_btree_node *)bh->b_data; 952 if (nilfs_btree_node_get_nchildren(btree, sib) < 953 nilfs_btree_node_nchildren_max(btree, sib)) { 954 path[level].bp_sib_bh = bh; 955 path[level].bp_op = nilfs_btree_carry_right; 956 stats->bs_nblocks++; 957 goto out; 958 } else 959 nilfs_bmap_put_block(&btree->bt_bmap, bh); 960 } 961 962 /* split */ 963 path[level].bp_newreq.bpr_ptr = 964 path[level - 1].bp_newreq.bpr_ptr + 1; 965 ret = btree->bt_bmap.b_pops->bpop_prepare_alloc_ptr( 966 &btree->bt_bmap, &path[level].bp_newreq); 967 if (ret < 0) 968 goto err_out_child_node; 969 ret = nilfs_bmap_get_new_block(&btree->bt_bmap, 970 path[level].bp_newreq.bpr_ptr, 971 &bh); 972 if (ret < 0) 973 goto err_out_curr_node; 974 975 stats->bs_nblocks++; 976 977 lock_buffer(bh); 978 nilfs_btree_node_init(btree, 979 (struct nilfs_btree_node *)bh->b_data, 980 0, level, 0, NULL, NULL); 981 unlock_buffer(bh); 982 path[level].bp_sib_bh = bh; 983 path[level].bp_op = nilfs_btree_split; 984 } 985 986 /* root */ 987 node = nilfs_btree_get_root(btree); 988 if (nilfs_btree_node_get_nchildren(btree, node) < 989 nilfs_btree_node_nchildren_max(btree, node)) { 990 path[level].bp_op = nilfs_btree_do_insert; 991 stats->bs_nblocks++; 992 goto out; 993 } 994 995 /* grow */ 996 path[level].bp_newreq.bpr_ptr = path[level - 1].bp_newreq.bpr_ptr + 1; 997 ret = btree->bt_bmap.b_pops->bpop_prepare_alloc_ptr( 998 &btree->bt_bmap, &path[level].bp_newreq); 999 if (ret < 0) 1000 goto err_out_child_node; 1001 ret = nilfs_bmap_get_new_block(&btree->bt_bmap, 1002 path[level].bp_newreq.bpr_ptr, &bh); 1003 if (ret < 0) 1004 goto err_out_curr_node; 1005 1006 lock_buffer(bh); 1007 nilfs_btree_node_init(btree, (struct nilfs_btree_node *)bh->b_data, 1008 0, level, 0, NULL, NULL); 1009 unlock_buffer(bh); 1010 path[level].bp_sib_bh = bh; 1011 path[level].bp_op = nilfs_btree_grow; 1012 1013 level++; 1014 path[level].bp_op = nilfs_btree_do_insert; 1015 1016 /* a newly-created node block and a data block are added */ 1017 stats->bs_nblocks += 2; 1018 1019 /* success */ 1020 out: 1021 *levelp = level; 1022 return ret; 1023 1024 /* error */ 1025 err_out_curr_node: 1026 btree->bt_bmap.b_pops->bpop_abort_alloc_ptr(&btree->bt_bmap, 1027 &path[level].bp_newreq); 1028 err_out_child_node: 1029 for (level--; level > NILFS_BTREE_LEVEL_DATA; level--) { 1030 nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_sib_bh); 1031 btree->bt_bmap.b_pops->bpop_abort_alloc_ptr( 1032 &btree->bt_bmap, &path[level].bp_newreq); 1033 1034 } 1035 1036 btree->bt_bmap.b_pops->bpop_abort_alloc_ptr(&btree->bt_bmap, 1037 &path[level].bp_newreq); 1038 err_out_data: 1039 *levelp = level; 1040 stats->bs_nblocks = 0; 1041 return ret; 1042 } 1043 1044 static void nilfs_btree_commit_insert(struct nilfs_btree *btree, 1045 struct nilfs_btree_path *path, 1046 int maxlevel, __u64 key, __u64 ptr) 1047 { 1048 int level; 1049 1050 set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr)); 1051 ptr = path[NILFS_BTREE_LEVEL_DATA].bp_newreq.bpr_ptr; 1052 if (btree->bt_ops->btop_set_target != NULL) 1053 btree->bt_ops->btop_set_target(btree, key, ptr); 1054 1055 for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) { 1056 if (btree->bt_bmap.b_pops->bpop_commit_alloc_ptr != NULL) { 1057 btree->bt_bmap.b_pops->bpop_commit_alloc_ptr( 1058 &btree->bt_bmap, &path[level - 1].bp_newreq); 1059 } 1060 path[level].bp_op(btree, path, level, &key, &ptr); 1061 } 1062 1063 if (!nilfs_bmap_dirty(&btree->bt_bmap)) 1064 nilfs_bmap_set_dirty(&btree->bt_bmap); 1065 } 1066 1067 static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) 1068 { 1069 struct nilfs_btree *btree; 1070 struct nilfs_btree_path *path; 1071 struct nilfs_bmap_stats stats; 1072 int level, ret; 1073 1074 btree = (struct nilfs_btree *)bmap; 1075 path = nilfs_btree_alloc_path(btree); 1076 if (path == NULL) 1077 return -ENOMEM; 1078 nilfs_btree_init_path(btree, path); 1079 1080 ret = nilfs_btree_do_lookup(btree, path, key, NULL, 1081 NILFS_BTREE_LEVEL_NODE_MIN); 1082 if (ret != -ENOENT) { 1083 if (ret == 0) 1084 ret = -EEXIST; 1085 goto out; 1086 } 1087 1088 ret = nilfs_btree_prepare_insert(btree, path, &level, key, ptr, &stats); 1089 if (ret < 0) 1090 goto out; 1091 nilfs_btree_commit_insert(btree, path, level, key, ptr); 1092 nilfs_bmap_add_blocks(bmap, stats.bs_nblocks); 1093 1094 out: 1095 nilfs_btree_clear_path(btree, path); 1096 nilfs_btree_free_path(btree, path); 1097 return ret; 1098 } 1099 1100 static void nilfs_btree_do_delete(struct nilfs_btree *btree, 1101 struct nilfs_btree_path *path, 1102 int level, __u64 *keyp, __u64 *ptrp) 1103 { 1104 struct nilfs_btree_node *node; 1105 1106 if (level < nilfs_btree_height(btree) - 1) { 1107 lock_buffer(path[level].bp_bh); 1108 node = nilfs_btree_get_nonroot_node(btree, path, level); 1109 nilfs_btree_node_delete(btree, node, keyp, ptrp, 1110 path[level].bp_index); 1111 if (!buffer_dirty(path[level].bp_bh)) 1112 nilfs_btnode_mark_dirty(path[level].bp_bh); 1113 unlock_buffer(path[level].bp_bh); 1114 if (path[level].bp_index == 0) 1115 nilfs_btree_promote_key(btree, path, level + 1, 1116 nilfs_btree_node_get_key(btree, node, 0)); 1117 } else { 1118 node = nilfs_btree_get_root(btree); 1119 nilfs_btree_node_delete(btree, node, keyp, ptrp, 1120 path[level].bp_index); 1121 } 1122 } 1123 1124 static void nilfs_btree_borrow_left(struct nilfs_btree *btree, 1125 struct nilfs_btree_path *path, 1126 int level, __u64 *keyp, __u64 *ptrp) 1127 { 1128 struct nilfs_btree_node *node, *left; 1129 int nchildren, lnchildren, n; 1130 1131 nilfs_btree_do_delete(btree, path, level, keyp, ptrp); 1132 1133 lock_buffer(path[level].bp_bh); 1134 lock_buffer(path[level].bp_sib_bh); 1135 1136 node = nilfs_btree_get_nonroot_node(btree, path, level); 1137 left = nilfs_btree_get_sib_node(btree, path, level); 1138 nchildren = nilfs_btree_node_get_nchildren(btree, node); 1139 lnchildren = nilfs_btree_node_get_nchildren(btree, left); 1140 1141 n = (nchildren + lnchildren) / 2 - nchildren; 1142 1143 nilfs_btree_node_move_right(btree, left, node, n); 1144 1145 if (!buffer_dirty(path[level].bp_bh)) 1146 nilfs_btnode_mark_dirty(path[level].bp_bh); 1147 if (!buffer_dirty(path[level].bp_sib_bh)) 1148 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 1149 1150 unlock_buffer(path[level].bp_bh); 1151 unlock_buffer(path[level].bp_sib_bh); 1152 1153 nilfs_btree_promote_key(btree, path, level + 1, 1154 nilfs_btree_node_get_key(btree, node, 0)); 1155 1156 nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh); 1157 path[level].bp_sib_bh = NULL; 1158 path[level].bp_index += n; 1159 } 1160 1161 static void nilfs_btree_borrow_right(struct nilfs_btree *btree, 1162 struct nilfs_btree_path *path, 1163 int level, __u64 *keyp, __u64 *ptrp) 1164 { 1165 struct nilfs_btree_node *node, *right; 1166 int nchildren, rnchildren, n; 1167 1168 nilfs_btree_do_delete(btree, path, level, keyp, ptrp); 1169 1170 lock_buffer(path[level].bp_bh); 1171 lock_buffer(path[level].bp_sib_bh); 1172 1173 node = nilfs_btree_get_nonroot_node(btree, path, level); 1174 right = nilfs_btree_get_sib_node(btree, path, level); 1175 nchildren = nilfs_btree_node_get_nchildren(btree, node); 1176 rnchildren = nilfs_btree_node_get_nchildren(btree, right); 1177 1178 n = (nchildren + rnchildren) / 2 - nchildren; 1179 1180 nilfs_btree_node_move_left(btree, node, right, n); 1181 1182 if (!buffer_dirty(path[level].bp_bh)) 1183 nilfs_btnode_mark_dirty(path[level].bp_bh); 1184 if (!buffer_dirty(path[level].bp_sib_bh)) 1185 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 1186 1187 unlock_buffer(path[level].bp_bh); 1188 unlock_buffer(path[level].bp_sib_bh); 1189 1190 path[level + 1].bp_index++; 1191 nilfs_btree_promote_key(btree, path, level + 1, 1192 nilfs_btree_node_get_key(btree, right, 0)); 1193 path[level + 1].bp_index--; 1194 1195 nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh); 1196 path[level].bp_sib_bh = NULL; 1197 } 1198 1199 static void nilfs_btree_concat_left(struct nilfs_btree *btree, 1200 struct nilfs_btree_path *path, 1201 int level, __u64 *keyp, __u64 *ptrp) 1202 { 1203 struct nilfs_btree_node *node, *left; 1204 int n; 1205 1206 nilfs_btree_do_delete(btree, path, level, keyp, ptrp); 1207 1208 lock_buffer(path[level].bp_bh); 1209 lock_buffer(path[level].bp_sib_bh); 1210 1211 node = nilfs_btree_get_nonroot_node(btree, path, level); 1212 left = nilfs_btree_get_sib_node(btree, path, level); 1213 1214 n = nilfs_btree_node_get_nchildren(btree, node); 1215 1216 nilfs_btree_node_move_left(btree, left, node, n); 1217 1218 if (!buffer_dirty(path[level].bp_sib_bh)) 1219 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 1220 1221 unlock_buffer(path[level].bp_bh); 1222 unlock_buffer(path[level].bp_sib_bh); 1223 1224 nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_bh); 1225 path[level].bp_bh = path[level].bp_sib_bh; 1226 path[level].bp_sib_bh = NULL; 1227 path[level].bp_index += nilfs_btree_node_get_nchildren(btree, left); 1228 } 1229 1230 static void nilfs_btree_concat_right(struct nilfs_btree *btree, 1231 struct nilfs_btree_path *path, 1232 int level, __u64 *keyp, __u64 *ptrp) 1233 { 1234 struct nilfs_btree_node *node, *right; 1235 int n; 1236 1237 nilfs_btree_do_delete(btree, path, level, keyp, ptrp); 1238 1239 lock_buffer(path[level].bp_bh); 1240 lock_buffer(path[level].bp_sib_bh); 1241 1242 node = nilfs_btree_get_nonroot_node(btree, path, level); 1243 right = nilfs_btree_get_sib_node(btree, path, level); 1244 1245 n = nilfs_btree_node_get_nchildren(btree, right); 1246 1247 nilfs_btree_node_move_left(btree, node, right, n); 1248 1249 if (!buffer_dirty(path[level].bp_bh)) 1250 nilfs_btnode_mark_dirty(path[level].bp_bh); 1251 1252 unlock_buffer(path[level].bp_bh); 1253 unlock_buffer(path[level].bp_sib_bh); 1254 1255 nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_sib_bh); 1256 path[level].bp_sib_bh = NULL; 1257 path[level + 1].bp_index++; 1258 } 1259 1260 static void nilfs_btree_shrink(struct nilfs_btree *btree, 1261 struct nilfs_btree_path *path, 1262 int level, __u64 *keyp, __u64 *ptrp) 1263 { 1264 struct nilfs_btree_node *root, *child; 1265 int n; 1266 1267 nilfs_btree_do_delete(btree, path, level, keyp, ptrp); 1268 1269 lock_buffer(path[level].bp_bh); 1270 root = nilfs_btree_get_root(btree); 1271 child = nilfs_btree_get_nonroot_node(btree, path, level); 1272 1273 nilfs_btree_node_delete(btree, root, NULL, NULL, 0); 1274 nilfs_btree_node_set_level(btree, root, level); 1275 n = nilfs_btree_node_get_nchildren(btree, child); 1276 nilfs_btree_node_move_left(btree, root, child, n); 1277 unlock_buffer(path[level].bp_bh); 1278 1279 nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_bh); 1280 path[level].bp_bh = NULL; 1281 } 1282 1283 1284 static int nilfs_btree_prepare_delete(struct nilfs_btree *btree, 1285 struct nilfs_btree_path *path, 1286 int *levelp, 1287 struct nilfs_bmap_stats *stats) 1288 { 1289 struct buffer_head *bh; 1290 struct nilfs_btree_node *node, *parent, *sib; 1291 __u64 sibptr; 1292 int pindex, level, ret; 1293 1294 ret = 0; 1295 stats->bs_nblocks = 0; 1296 for (level = NILFS_BTREE_LEVEL_NODE_MIN; 1297 level < nilfs_btree_height(btree) - 1; 1298 level++) { 1299 node = nilfs_btree_get_nonroot_node(btree, path, level); 1300 path[level].bp_oldreq.bpr_ptr = 1301 nilfs_btree_node_get_ptr(btree, node, 1302 path[level].bp_index); 1303 if (btree->bt_bmap.b_pops->bpop_prepare_end_ptr != NULL) { 1304 ret = btree->bt_bmap.b_pops->bpop_prepare_end_ptr( 1305 &btree->bt_bmap, &path[level].bp_oldreq); 1306 if (ret < 0) 1307 goto err_out_child_node; 1308 } 1309 1310 if (nilfs_btree_node_get_nchildren(btree, node) > 1311 nilfs_btree_node_nchildren_min(btree, node)) { 1312 path[level].bp_op = nilfs_btree_do_delete; 1313 stats->bs_nblocks++; 1314 goto out; 1315 } 1316 1317 parent = nilfs_btree_get_node(btree, path, level + 1); 1318 pindex = path[level + 1].bp_index; 1319 1320 if (pindex > 0) { 1321 /* left sibling */ 1322 sibptr = nilfs_btree_node_get_ptr(btree, parent, 1323 pindex - 1); 1324 ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr, 1325 &bh); 1326 if (ret < 0) 1327 goto err_out_curr_node; 1328 sib = (struct nilfs_btree_node *)bh->b_data; 1329 if (nilfs_btree_node_get_nchildren(btree, sib) > 1330 nilfs_btree_node_nchildren_min(btree, sib)) { 1331 path[level].bp_sib_bh = bh; 1332 path[level].bp_op = nilfs_btree_borrow_left; 1333 stats->bs_nblocks++; 1334 goto out; 1335 } else { 1336 path[level].bp_sib_bh = bh; 1337 path[level].bp_op = nilfs_btree_concat_left; 1338 stats->bs_nblocks++; 1339 /* continue; */ 1340 } 1341 } else if (pindex < 1342 nilfs_btree_node_get_nchildren(btree, parent) - 1) { 1343 /* right sibling */ 1344 sibptr = nilfs_btree_node_get_ptr(btree, parent, 1345 pindex + 1); 1346 ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr, 1347 &bh); 1348 if (ret < 0) 1349 goto err_out_curr_node; 1350 sib = (struct nilfs_btree_node *)bh->b_data; 1351 if (nilfs_btree_node_get_nchildren(btree, sib) > 1352 nilfs_btree_node_nchildren_min(btree, sib)) { 1353 path[level].bp_sib_bh = bh; 1354 path[level].bp_op = nilfs_btree_borrow_right; 1355 stats->bs_nblocks++; 1356 goto out; 1357 } else { 1358 path[level].bp_sib_bh = bh; 1359 path[level].bp_op = nilfs_btree_concat_right; 1360 stats->bs_nblocks++; 1361 /* continue; */ 1362 } 1363 } else { 1364 /* no siblings */ 1365 /* the only child of the root node */ 1366 WARN_ON(level != nilfs_btree_height(btree) - 2); 1367 if (nilfs_btree_node_get_nchildren(btree, node) - 1 <= 1368 NILFS_BTREE_ROOT_NCHILDREN_MAX) { 1369 path[level].bp_op = nilfs_btree_shrink; 1370 stats->bs_nblocks += 2; 1371 } else { 1372 path[level].bp_op = nilfs_btree_do_delete; 1373 stats->bs_nblocks++; 1374 } 1375 1376 goto out; 1377 1378 } 1379 } 1380 1381 node = nilfs_btree_get_root(btree); 1382 path[level].bp_oldreq.bpr_ptr = 1383 nilfs_btree_node_get_ptr(btree, node, path[level].bp_index); 1384 if (btree->bt_bmap.b_pops->bpop_prepare_end_ptr != NULL) { 1385 ret = btree->bt_bmap.b_pops->bpop_prepare_end_ptr( 1386 &btree->bt_bmap, &path[level].bp_oldreq); 1387 if (ret < 0) 1388 goto err_out_child_node; 1389 } 1390 /* child of the root node is deleted */ 1391 path[level].bp_op = nilfs_btree_do_delete; 1392 stats->bs_nblocks++; 1393 1394 /* success */ 1395 out: 1396 *levelp = level; 1397 return ret; 1398 1399 /* error */ 1400 err_out_curr_node: 1401 if (btree->bt_bmap.b_pops->bpop_abort_end_ptr != NULL) 1402 btree->bt_bmap.b_pops->bpop_abort_end_ptr( 1403 &btree->bt_bmap, &path[level].bp_oldreq); 1404 err_out_child_node: 1405 for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--) { 1406 nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh); 1407 if (btree->bt_bmap.b_pops->bpop_abort_end_ptr != NULL) 1408 btree->bt_bmap.b_pops->bpop_abort_end_ptr( 1409 &btree->bt_bmap, &path[level].bp_oldreq); 1410 } 1411 *levelp = level; 1412 stats->bs_nblocks = 0; 1413 return ret; 1414 } 1415 1416 static void nilfs_btree_commit_delete(struct nilfs_btree *btree, 1417 struct nilfs_btree_path *path, 1418 int maxlevel) 1419 { 1420 int level; 1421 1422 for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) { 1423 if (btree->bt_bmap.b_pops->bpop_commit_end_ptr != NULL) 1424 btree->bt_bmap.b_pops->bpop_commit_end_ptr( 1425 &btree->bt_bmap, &path[level].bp_oldreq); 1426 path[level].bp_op(btree, path, level, NULL, NULL); 1427 } 1428 1429 if (!nilfs_bmap_dirty(&btree->bt_bmap)) 1430 nilfs_bmap_set_dirty(&btree->bt_bmap); 1431 } 1432 1433 static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key) 1434 1435 { 1436 struct nilfs_btree *btree; 1437 struct nilfs_btree_path *path; 1438 struct nilfs_bmap_stats stats; 1439 int level, ret; 1440 1441 btree = (struct nilfs_btree *)bmap; 1442 path = nilfs_btree_alloc_path(btree); 1443 if (path == NULL) 1444 return -ENOMEM; 1445 nilfs_btree_init_path(btree, path); 1446 ret = nilfs_btree_do_lookup(btree, path, key, NULL, 1447 NILFS_BTREE_LEVEL_NODE_MIN); 1448 if (ret < 0) 1449 goto out; 1450 1451 ret = nilfs_btree_prepare_delete(btree, path, &level, &stats); 1452 if (ret < 0) 1453 goto out; 1454 nilfs_btree_commit_delete(btree, path, level); 1455 nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks); 1456 1457 out: 1458 nilfs_btree_clear_path(btree, path); 1459 nilfs_btree_free_path(btree, path); 1460 return ret; 1461 } 1462 1463 static int nilfs_btree_last_key(const struct nilfs_bmap *bmap, __u64 *keyp) 1464 { 1465 struct nilfs_btree *btree; 1466 struct nilfs_btree_path *path; 1467 int ret; 1468 1469 btree = (struct nilfs_btree *)bmap; 1470 path = nilfs_btree_alloc_path(btree); 1471 if (path == NULL) 1472 return -ENOMEM; 1473 nilfs_btree_init_path(btree, path); 1474 1475 ret = nilfs_btree_do_lookup_last(btree, path, keyp, NULL); 1476 1477 nilfs_btree_clear_path(btree, path); 1478 nilfs_btree_free_path(btree, path); 1479 1480 return ret; 1481 } 1482 1483 static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key) 1484 { 1485 struct buffer_head *bh; 1486 struct nilfs_btree *btree; 1487 struct nilfs_btree_node *root, *node; 1488 __u64 maxkey, nextmaxkey; 1489 __u64 ptr; 1490 int nchildren, ret; 1491 1492 btree = (struct nilfs_btree *)bmap; 1493 root = nilfs_btree_get_root(btree); 1494 switch (nilfs_btree_height(btree)) { 1495 case 2: 1496 bh = NULL; 1497 node = root; 1498 break; 1499 case 3: 1500 nchildren = nilfs_btree_node_get_nchildren(btree, root); 1501 if (nchildren > 1) 1502 return 0; 1503 ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1); 1504 ret = nilfs_bmap_get_block(bmap, ptr, &bh); 1505 if (ret < 0) 1506 return ret; 1507 node = (struct nilfs_btree_node *)bh->b_data; 1508 break; 1509 default: 1510 return 0; 1511 } 1512 1513 nchildren = nilfs_btree_node_get_nchildren(btree, node); 1514 maxkey = nilfs_btree_node_get_key(btree, node, nchildren - 1); 1515 nextmaxkey = (nchildren > 1) ? 1516 nilfs_btree_node_get_key(btree, node, nchildren - 2) : 0; 1517 if (bh != NULL) 1518 nilfs_bmap_put_block(bmap, bh); 1519 1520 return (maxkey == key) && (nextmaxkey < bmap->b_low); 1521 } 1522 1523 static int nilfs_btree_gather_data(struct nilfs_bmap *bmap, 1524 __u64 *keys, __u64 *ptrs, int nitems) 1525 { 1526 struct buffer_head *bh; 1527 struct nilfs_btree *btree; 1528 struct nilfs_btree_node *node, *root; 1529 __le64 *dkeys; 1530 __le64 *dptrs; 1531 __u64 ptr; 1532 int nchildren, i, ret; 1533 1534 btree = (struct nilfs_btree *)bmap; 1535 root = nilfs_btree_get_root(btree); 1536 switch (nilfs_btree_height(btree)) { 1537 case 2: 1538 bh = NULL; 1539 node = root; 1540 break; 1541 case 3: 1542 nchildren = nilfs_btree_node_get_nchildren(btree, root); 1543 WARN_ON(nchildren > 1); 1544 ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1); 1545 ret = nilfs_bmap_get_block(bmap, ptr, &bh); 1546 if (ret < 0) 1547 return ret; 1548 node = (struct nilfs_btree_node *)bh->b_data; 1549 break; 1550 default: 1551 node = NULL; 1552 return -EINVAL; 1553 } 1554 1555 nchildren = nilfs_btree_node_get_nchildren(btree, node); 1556 if (nchildren < nitems) 1557 nitems = nchildren; 1558 dkeys = nilfs_btree_node_dkeys(btree, node); 1559 dptrs = nilfs_btree_node_dptrs(btree, node); 1560 for (i = 0; i < nitems; i++) { 1561 keys[i] = nilfs_bmap_dkey_to_key(dkeys[i]); 1562 ptrs[i] = nilfs_bmap_dptr_to_ptr(dptrs[i]); 1563 } 1564 1565 if (bh != NULL) 1566 nilfs_bmap_put_block(bmap, bh); 1567 1568 return nitems; 1569 } 1570 1571 static int 1572 nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key, 1573 union nilfs_bmap_ptr_req *dreq, 1574 union nilfs_bmap_ptr_req *nreq, 1575 struct buffer_head **bhp, 1576 struct nilfs_bmap_stats *stats) 1577 { 1578 struct buffer_head *bh; 1579 struct nilfs_btree *btree; 1580 int ret; 1581 1582 btree = (struct nilfs_btree *)bmap; 1583 stats->bs_nblocks = 0; 1584 1585 /* for data */ 1586 /* cannot find near ptr */ 1587 if (btree->bt_ops->btop_find_target != NULL) 1588 dreq->bpr_ptr 1589 = btree->bt_ops->btop_find_target(btree, NULL, key); 1590 ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, dreq); 1591 if (ret < 0) 1592 return ret; 1593 1594 *bhp = NULL; 1595 stats->bs_nblocks++; 1596 if (nreq != NULL) { 1597 nreq->bpr_ptr = dreq->bpr_ptr + 1; 1598 ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, nreq); 1599 if (ret < 0) 1600 goto err_out_dreq; 1601 1602 ret = nilfs_bmap_get_new_block(bmap, nreq->bpr_ptr, &bh); 1603 if (ret < 0) 1604 goto err_out_nreq; 1605 1606 *bhp = bh; 1607 stats->bs_nblocks++; 1608 } 1609 1610 /* success */ 1611 return 0; 1612 1613 /* error */ 1614 err_out_nreq: 1615 bmap->b_pops->bpop_abort_alloc_ptr(bmap, nreq); 1616 err_out_dreq: 1617 bmap->b_pops->bpop_abort_alloc_ptr(bmap, dreq); 1618 stats->bs_nblocks = 0; 1619 return ret; 1620 1621 } 1622 1623 static void 1624 nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap, 1625 __u64 key, __u64 ptr, 1626 const __u64 *keys, const __u64 *ptrs, 1627 int n, __u64 low, __u64 high, 1628 union nilfs_bmap_ptr_req *dreq, 1629 union nilfs_bmap_ptr_req *nreq, 1630 struct buffer_head *bh) 1631 { 1632 struct nilfs_btree *btree; 1633 struct nilfs_btree_node *node; 1634 __u64 tmpptr; 1635 1636 /* free resources */ 1637 if (bmap->b_ops->bop_clear != NULL) 1638 bmap->b_ops->bop_clear(bmap); 1639 1640 /* ptr must be a pointer to a buffer head. */ 1641 set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr)); 1642 1643 /* convert and insert */ 1644 btree = (struct nilfs_btree *)bmap; 1645 nilfs_btree_init(bmap, low, high); 1646 if (nreq != NULL) { 1647 if (bmap->b_pops->bpop_commit_alloc_ptr != NULL) { 1648 bmap->b_pops->bpop_commit_alloc_ptr(bmap, dreq); 1649 bmap->b_pops->bpop_commit_alloc_ptr(bmap, nreq); 1650 } 1651 1652 /* create child node at level 1 */ 1653 lock_buffer(bh); 1654 node = (struct nilfs_btree_node *)bh->b_data; 1655 nilfs_btree_node_init(btree, node, 0, 1, n, keys, ptrs); 1656 nilfs_btree_node_insert(btree, node, 1657 key, dreq->bpr_ptr, n); 1658 if (!buffer_dirty(bh)) 1659 nilfs_btnode_mark_dirty(bh); 1660 if (!nilfs_bmap_dirty(bmap)) 1661 nilfs_bmap_set_dirty(bmap); 1662 1663 unlock_buffer(bh); 1664 nilfs_bmap_put_block(bmap, bh); 1665 1666 /* create root node at level 2 */ 1667 node = nilfs_btree_get_root(btree); 1668 tmpptr = nreq->bpr_ptr; 1669 nilfs_btree_node_init(btree, node, NILFS_BTREE_NODE_ROOT, 1670 2, 1, &keys[0], &tmpptr); 1671 } else { 1672 if (bmap->b_pops->bpop_commit_alloc_ptr != NULL) 1673 bmap->b_pops->bpop_commit_alloc_ptr(bmap, dreq); 1674 1675 /* create root node at level 1 */ 1676 node = nilfs_btree_get_root(btree); 1677 nilfs_btree_node_init(btree, node, NILFS_BTREE_NODE_ROOT, 1678 1, n, keys, ptrs); 1679 nilfs_btree_node_insert(btree, node, 1680 key, dreq->bpr_ptr, n); 1681 if (!nilfs_bmap_dirty(bmap)) 1682 nilfs_bmap_set_dirty(bmap); 1683 } 1684 1685 if (btree->bt_ops->btop_set_target != NULL) 1686 btree->bt_ops->btop_set_target(btree, key, dreq->bpr_ptr); 1687 } 1688 1689 /** 1690 * nilfs_btree_convert_and_insert - 1691 * @bmap: 1692 * @key: 1693 * @ptr: 1694 * @keys: 1695 * @ptrs: 1696 * @n: 1697 * @low: 1698 * @high: 1699 */ 1700 int nilfs_btree_convert_and_insert(struct nilfs_bmap *bmap, 1701 __u64 key, __u64 ptr, 1702 const __u64 *keys, const __u64 *ptrs, 1703 int n, __u64 low, __u64 high) 1704 { 1705 struct buffer_head *bh; 1706 union nilfs_bmap_ptr_req dreq, nreq, *di, *ni; 1707 struct nilfs_bmap_stats stats; 1708 int ret; 1709 1710 if (n + 1 <= NILFS_BTREE_ROOT_NCHILDREN_MAX) { 1711 di = &dreq; 1712 ni = NULL; 1713 } else if ((n + 1) <= NILFS_BTREE_NODE_NCHILDREN_MAX( 1714 1 << bmap->b_inode->i_blkbits)) { 1715 di = &dreq; 1716 ni = &nreq; 1717 } else { 1718 di = NULL; 1719 ni = NULL; 1720 BUG(); 1721 } 1722 1723 ret = nilfs_btree_prepare_convert_and_insert(bmap, key, di, ni, &bh, 1724 &stats); 1725 if (ret < 0) 1726 return ret; 1727 nilfs_btree_commit_convert_and_insert(bmap, key, ptr, keys, ptrs, n, 1728 low, high, di, ni, bh); 1729 nilfs_bmap_add_blocks(bmap, stats.bs_nblocks); 1730 return 0; 1731 } 1732 1733 static int nilfs_btree_propagate_p(struct nilfs_btree *btree, 1734 struct nilfs_btree_path *path, 1735 int level, 1736 struct buffer_head *bh) 1737 { 1738 while ((++level < nilfs_btree_height(btree) - 1) && 1739 !buffer_dirty(path[level].bp_bh)) 1740 nilfs_btnode_mark_dirty(path[level].bp_bh); 1741 1742 return 0; 1743 } 1744 1745 static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree, 1746 struct nilfs_btree_path *path, 1747 int level) 1748 { 1749 struct nilfs_btree_node *parent; 1750 int ret; 1751 1752 parent = nilfs_btree_get_node(btree, path, level + 1); 1753 path[level].bp_oldreq.bpr_ptr = 1754 nilfs_btree_node_get_ptr(btree, parent, 1755 path[level + 1].bp_index); 1756 path[level].bp_newreq.bpr_ptr = path[level].bp_oldreq.bpr_ptr + 1; 1757 ret = nilfs_bmap_prepare_update(&btree->bt_bmap, 1758 &path[level].bp_oldreq, 1759 &path[level].bp_newreq); 1760 if (ret < 0) 1761 return ret; 1762 1763 if (buffer_nilfs_node(path[level].bp_bh)) { 1764 path[level].bp_ctxt.oldkey = path[level].bp_oldreq.bpr_ptr; 1765 path[level].bp_ctxt.newkey = path[level].bp_newreq.bpr_ptr; 1766 path[level].bp_ctxt.bh = path[level].bp_bh; 1767 ret = nilfs_btnode_prepare_change_key( 1768 &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache, 1769 &path[level].bp_ctxt); 1770 if (ret < 0) { 1771 nilfs_bmap_abort_update(&btree->bt_bmap, 1772 &path[level].bp_oldreq, 1773 &path[level].bp_newreq); 1774 return ret; 1775 } 1776 } 1777 1778 return 0; 1779 } 1780 1781 static void nilfs_btree_commit_update_v(struct nilfs_btree *btree, 1782 struct nilfs_btree_path *path, 1783 int level) 1784 { 1785 struct nilfs_btree_node *parent; 1786 1787 nilfs_bmap_commit_update(&btree->bt_bmap, 1788 &path[level].bp_oldreq, 1789 &path[level].bp_newreq); 1790 1791 if (buffer_nilfs_node(path[level].bp_bh)) { 1792 nilfs_btnode_commit_change_key( 1793 &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache, 1794 &path[level].bp_ctxt); 1795 path[level].bp_bh = path[level].bp_ctxt.bh; 1796 } 1797 set_buffer_nilfs_volatile(path[level].bp_bh); 1798 1799 parent = nilfs_btree_get_node(btree, path, level + 1); 1800 nilfs_btree_node_set_ptr(btree, parent, path[level + 1].bp_index, 1801 path[level].bp_newreq.bpr_ptr); 1802 } 1803 1804 static void nilfs_btree_abort_update_v(struct nilfs_btree *btree, 1805 struct nilfs_btree_path *path, 1806 int level) 1807 { 1808 nilfs_bmap_abort_update(&btree->bt_bmap, 1809 &path[level].bp_oldreq, 1810 &path[level].bp_newreq); 1811 if (buffer_nilfs_node(path[level].bp_bh)) 1812 nilfs_btnode_abort_change_key( 1813 &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache, 1814 &path[level].bp_ctxt); 1815 } 1816 1817 static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree, 1818 struct nilfs_btree_path *path, 1819 int minlevel, 1820 int *maxlevelp) 1821 { 1822 int level, ret; 1823 1824 level = minlevel; 1825 if (!buffer_nilfs_volatile(path[level].bp_bh)) { 1826 ret = nilfs_btree_prepare_update_v(btree, path, level); 1827 if (ret < 0) 1828 return ret; 1829 } 1830 while ((++level < nilfs_btree_height(btree) - 1) && 1831 !buffer_dirty(path[level].bp_bh)) { 1832 1833 WARN_ON(buffer_nilfs_volatile(path[level].bp_bh)); 1834 ret = nilfs_btree_prepare_update_v(btree, path, level); 1835 if (ret < 0) 1836 goto out; 1837 } 1838 1839 /* success */ 1840 *maxlevelp = level - 1; 1841 return 0; 1842 1843 /* error */ 1844 out: 1845 while (--level > minlevel) 1846 nilfs_btree_abort_update_v(btree, path, level); 1847 if (!buffer_nilfs_volatile(path[level].bp_bh)) 1848 nilfs_btree_abort_update_v(btree, path, level); 1849 return ret; 1850 } 1851 1852 static void nilfs_btree_commit_propagate_v(struct nilfs_btree *btree, 1853 struct nilfs_btree_path *path, 1854 int minlevel, 1855 int maxlevel, 1856 struct buffer_head *bh) 1857 { 1858 int level; 1859 1860 if (!buffer_nilfs_volatile(path[minlevel].bp_bh)) 1861 nilfs_btree_commit_update_v(btree, path, minlevel); 1862 1863 for (level = minlevel + 1; level <= maxlevel; level++) 1864 nilfs_btree_commit_update_v(btree, path, level); 1865 } 1866 1867 static int nilfs_btree_propagate_v(struct nilfs_btree *btree, 1868 struct nilfs_btree_path *path, 1869 int level, 1870 struct buffer_head *bh) 1871 { 1872 int maxlevel, ret; 1873 struct nilfs_btree_node *parent; 1874 __u64 ptr; 1875 1876 get_bh(bh); 1877 path[level].bp_bh = bh; 1878 ret = nilfs_btree_prepare_propagate_v(btree, path, level, &maxlevel); 1879 if (ret < 0) 1880 goto out; 1881 1882 if (buffer_nilfs_volatile(path[level].bp_bh)) { 1883 parent = nilfs_btree_get_node(btree, path, level + 1); 1884 ptr = nilfs_btree_node_get_ptr(btree, parent, 1885 path[level + 1].bp_index); 1886 ret = nilfs_bmap_mark_dirty(&btree->bt_bmap, ptr); 1887 if (ret < 0) 1888 goto out; 1889 } 1890 1891 nilfs_btree_commit_propagate_v(btree, path, level, maxlevel, bh); 1892 1893 out: 1894 brelse(path[level].bp_bh); 1895 path[level].bp_bh = NULL; 1896 return ret; 1897 } 1898 1899 static int nilfs_btree_propagate(const struct nilfs_bmap *bmap, 1900 struct buffer_head *bh) 1901 { 1902 struct nilfs_btree *btree; 1903 struct nilfs_btree_path *path; 1904 struct nilfs_btree_node *node; 1905 __u64 key; 1906 int level, ret; 1907 1908 WARN_ON(!buffer_dirty(bh)); 1909 1910 btree = (struct nilfs_btree *)bmap; 1911 path = nilfs_btree_alloc_path(btree); 1912 if (path == NULL) 1913 return -ENOMEM; 1914 nilfs_btree_init_path(btree, path); 1915 1916 if (buffer_nilfs_node(bh)) { 1917 node = (struct nilfs_btree_node *)bh->b_data; 1918 key = nilfs_btree_node_get_key(btree, node, 0); 1919 level = nilfs_btree_node_get_level(btree, node); 1920 } else { 1921 key = nilfs_bmap_data_get_key(bmap, bh); 1922 level = NILFS_BTREE_LEVEL_DATA; 1923 } 1924 1925 ret = nilfs_btree_do_lookup(btree, path, key, NULL, level + 1); 1926 if (ret < 0) { 1927 if (unlikely(ret == -ENOENT)) 1928 printk(KERN_CRIT "%s: key = %llu, level == %d\n", 1929 __func__, (unsigned long long)key, level); 1930 goto out; 1931 } 1932 1933 ret = btree->bt_ops->btop_propagate(btree, path, level, bh); 1934 1935 out: 1936 nilfs_btree_clear_path(btree, path); 1937 nilfs_btree_free_path(btree, path); 1938 1939 return ret; 1940 } 1941 1942 static int nilfs_btree_propagate_gc(const struct nilfs_bmap *bmap, 1943 struct buffer_head *bh) 1944 { 1945 return nilfs_bmap_mark_dirty(bmap, bh->b_blocknr); 1946 } 1947 1948 static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree, 1949 struct list_head *lists, 1950 struct buffer_head *bh) 1951 { 1952 struct list_head *head; 1953 struct buffer_head *cbh; 1954 struct nilfs_btree_node *node, *cnode; 1955 __u64 key, ckey; 1956 int level; 1957 1958 get_bh(bh); 1959 node = (struct nilfs_btree_node *)bh->b_data; 1960 key = nilfs_btree_node_get_key(btree, node, 0); 1961 level = nilfs_btree_node_get_level(btree, node); 1962 list_for_each(head, &lists[level]) { 1963 cbh = list_entry(head, struct buffer_head, b_assoc_buffers); 1964 cnode = (struct nilfs_btree_node *)cbh->b_data; 1965 ckey = nilfs_btree_node_get_key(btree, cnode, 0); 1966 if (key < ckey) 1967 break; 1968 } 1969 list_add_tail(&bh->b_assoc_buffers, head); 1970 } 1971 1972 static void nilfs_btree_lookup_dirty_buffers(struct nilfs_bmap *bmap, 1973 struct list_head *listp) 1974 { 1975 struct nilfs_btree *btree = (struct nilfs_btree *)bmap; 1976 struct address_space *btcache = &NILFS_BMAP_I(bmap)->i_btnode_cache; 1977 struct list_head lists[NILFS_BTREE_LEVEL_MAX]; 1978 struct pagevec pvec; 1979 struct buffer_head *bh, *head; 1980 pgoff_t index = 0; 1981 int level, i; 1982 1983 for (level = NILFS_BTREE_LEVEL_NODE_MIN; 1984 level < NILFS_BTREE_LEVEL_MAX; 1985 level++) 1986 INIT_LIST_HEAD(&lists[level]); 1987 1988 pagevec_init(&pvec, 0); 1989 1990 while (pagevec_lookup_tag(&pvec, btcache, &index, PAGECACHE_TAG_DIRTY, 1991 PAGEVEC_SIZE)) { 1992 for (i = 0; i < pagevec_count(&pvec); i++) { 1993 bh = head = page_buffers(pvec.pages[i]); 1994 do { 1995 if (buffer_dirty(bh)) 1996 nilfs_btree_add_dirty_buffer(btree, 1997 lists, bh); 1998 } while ((bh = bh->b_this_page) != head); 1999 } 2000 pagevec_release(&pvec); 2001 cond_resched(); 2002 } 2003 2004 for (level = NILFS_BTREE_LEVEL_NODE_MIN; 2005 level < NILFS_BTREE_LEVEL_MAX; 2006 level++) 2007 list_splice(&lists[level], listp->prev); 2008 } 2009 2010 static int nilfs_btree_assign_p(struct nilfs_btree *btree, 2011 struct nilfs_btree_path *path, 2012 int level, 2013 struct buffer_head **bh, 2014 sector_t blocknr, 2015 union nilfs_binfo *binfo) 2016 { 2017 struct nilfs_btree_node *parent; 2018 __u64 key; 2019 __u64 ptr; 2020 int ret; 2021 2022 parent = nilfs_btree_get_node(btree, path, level + 1); 2023 ptr = nilfs_btree_node_get_ptr(btree, parent, 2024 path[level + 1].bp_index); 2025 if (buffer_nilfs_node(*bh)) { 2026 path[level].bp_ctxt.oldkey = ptr; 2027 path[level].bp_ctxt.newkey = blocknr; 2028 path[level].bp_ctxt.bh = *bh; 2029 ret = nilfs_btnode_prepare_change_key( 2030 &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache, 2031 &path[level].bp_ctxt); 2032 if (ret < 0) 2033 return ret; 2034 nilfs_btnode_commit_change_key( 2035 &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache, 2036 &path[level].bp_ctxt); 2037 *bh = path[level].bp_ctxt.bh; 2038 } 2039 2040 nilfs_btree_node_set_ptr(btree, parent, 2041 path[level + 1].bp_index, blocknr); 2042 2043 key = nilfs_btree_node_get_key(btree, parent, 2044 path[level + 1].bp_index); 2045 /* on-disk format */ 2046 binfo->bi_dat.bi_blkoff = nilfs_bmap_key_to_dkey(key); 2047 binfo->bi_dat.bi_level = level; 2048 2049 return 0; 2050 } 2051 2052 static int nilfs_btree_assign_v(struct nilfs_btree *btree, 2053 struct nilfs_btree_path *path, 2054 int level, 2055 struct buffer_head **bh, 2056 sector_t blocknr, 2057 union nilfs_binfo *binfo) 2058 { 2059 struct nilfs_btree_node *parent; 2060 __u64 key; 2061 __u64 ptr; 2062 union nilfs_bmap_ptr_req req; 2063 int ret; 2064 2065 parent = nilfs_btree_get_node(btree, path, level + 1); 2066 ptr = nilfs_btree_node_get_ptr(btree, parent, 2067 path[level + 1].bp_index); 2068 req.bpr_ptr = ptr; 2069 ret = btree->bt_bmap.b_pops->bpop_prepare_start_ptr(&btree->bt_bmap, 2070 &req); 2071 if (ret < 0) 2072 return ret; 2073 btree->bt_bmap.b_pops->bpop_commit_start_ptr(&btree->bt_bmap, 2074 &req, blocknr); 2075 2076 key = nilfs_btree_node_get_key(btree, parent, 2077 path[level + 1].bp_index); 2078 /* on-disk format */ 2079 binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr); 2080 binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key); 2081 2082 return 0; 2083 } 2084 2085 static int nilfs_btree_assign(struct nilfs_bmap *bmap, 2086 struct buffer_head **bh, 2087 sector_t blocknr, 2088 union nilfs_binfo *binfo) 2089 { 2090 struct nilfs_btree *btree; 2091 struct nilfs_btree_path *path; 2092 struct nilfs_btree_node *node; 2093 __u64 key; 2094 int level, ret; 2095 2096 btree = (struct nilfs_btree *)bmap; 2097 path = nilfs_btree_alloc_path(btree); 2098 if (path == NULL) 2099 return -ENOMEM; 2100 nilfs_btree_init_path(btree, path); 2101 2102 if (buffer_nilfs_node(*bh)) { 2103 node = (struct nilfs_btree_node *)(*bh)->b_data; 2104 key = nilfs_btree_node_get_key(btree, node, 0); 2105 level = nilfs_btree_node_get_level(btree, node); 2106 } else { 2107 key = nilfs_bmap_data_get_key(bmap, *bh); 2108 level = NILFS_BTREE_LEVEL_DATA; 2109 } 2110 2111 ret = nilfs_btree_do_lookup(btree, path, key, NULL, level + 1); 2112 if (ret < 0) { 2113 WARN_ON(ret == -ENOENT); 2114 goto out; 2115 } 2116 2117 ret = btree->bt_ops->btop_assign(btree, path, level, bh, 2118 blocknr, binfo); 2119 2120 out: 2121 nilfs_btree_clear_path(btree, path); 2122 nilfs_btree_free_path(btree, path); 2123 2124 return ret; 2125 } 2126 2127 static int nilfs_btree_assign_gc(struct nilfs_bmap *bmap, 2128 struct buffer_head **bh, 2129 sector_t blocknr, 2130 union nilfs_binfo *binfo) 2131 { 2132 struct nilfs_btree *btree; 2133 struct nilfs_btree_node *node; 2134 __u64 key; 2135 int ret; 2136 2137 btree = (struct nilfs_btree *)bmap; 2138 ret = nilfs_bmap_move_v(bmap, (*bh)->b_blocknr, blocknr); 2139 if (ret < 0) 2140 return ret; 2141 2142 if (buffer_nilfs_node(*bh)) { 2143 node = (struct nilfs_btree_node *)(*bh)->b_data; 2144 key = nilfs_btree_node_get_key(btree, node, 0); 2145 } else 2146 key = nilfs_bmap_data_get_key(bmap, *bh); 2147 2148 /* on-disk format */ 2149 binfo->bi_v.bi_vblocknr = cpu_to_le64((*bh)->b_blocknr); 2150 binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key); 2151 2152 return 0; 2153 } 2154 2155 static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level) 2156 { 2157 struct buffer_head *bh; 2158 struct nilfs_btree *btree; 2159 struct nilfs_btree_path *path; 2160 __u64 ptr; 2161 int ret; 2162 2163 btree = (struct nilfs_btree *)bmap; 2164 path = nilfs_btree_alloc_path(btree); 2165 if (path == NULL) 2166 return -ENOMEM; 2167 nilfs_btree_init_path(btree, path); 2168 2169 ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level + 1); 2170 if (ret < 0) { 2171 WARN_ON(ret == -ENOENT); 2172 goto out; 2173 } 2174 ret = nilfs_bmap_get_block(&btree->bt_bmap, ptr, &bh); 2175 if (ret < 0) { 2176 WARN_ON(ret == -ENOENT); 2177 goto out; 2178 } 2179 2180 if (!buffer_dirty(bh)) 2181 nilfs_btnode_mark_dirty(bh); 2182 nilfs_bmap_put_block(&btree->bt_bmap, bh); 2183 if (!nilfs_bmap_dirty(&btree->bt_bmap)) 2184 nilfs_bmap_set_dirty(&btree->bt_bmap); 2185 2186 out: 2187 nilfs_btree_clear_path(btree, path); 2188 nilfs_btree_free_path(btree, path); 2189 return ret; 2190 } 2191 2192 static const struct nilfs_bmap_operations nilfs_btree_ops = { 2193 .bop_lookup = nilfs_btree_lookup, 2194 .bop_insert = nilfs_btree_insert, 2195 .bop_delete = nilfs_btree_delete, 2196 .bop_clear = NULL, 2197 2198 .bop_propagate = nilfs_btree_propagate, 2199 2200 .bop_lookup_dirty_buffers = nilfs_btree_lookup_dirty_buffers, 2201 2202 .bop_assign = nilfs_btree_assign, 2203 .bop_mark = nilfs_btree_mark, 2204 2205 .bop_last_key = nilfs_btree_last_key, 2206 .bop_check_insert = NULL, 2207 .bop_check_delete = nilfs_btree_check_delete, 2208 .bop_gather_data = nilfs_btree_gather_data, 2209 }; 2210 2211 static const struct nilfs_bmap_operations nilfs_btree_ops_gc = { 2212 .bop_lookup = NULL, 2213 .bop_insert = NULL, 2214 .bop_delete = NULL, 2215 .bop_clear = NULL, 2216 2217 .bop_propagate = nilfs_btree_propagate_gc, 2218 2219 .bop_lookup_dirty_buffers = nilfs_btree_lookup_dirty_buffers, 2220 2221 .bop_assign = nilfs_btree_assign_gc, 2222 .bop_mark = NULL, 2223 2224 .bop_last_key = NULL, 2225 .bop_check_insert = NULL, 2226 .bop_check_delete = NULL, 2227 .bop_gather_data = NULL, 2228 }; 2229 2230 static const struct nilfs_btree_operations nilfs_btree_ops_v = { 2231 .btop_find_target = nilfs_btree_find_target_v, 2232 .btop_set_target = nilfs_btree_set_target_v, 2233 .btop_propagate = nilfs_btree_propagate_v, 2234 .btop_assign = nilfs_btree_assign_v, 2235 }; 2236 2237 static const struct nilfs_btree_operations nilfs_btree_ops_p = { 2238 .btop_find_target = NULL, 2239 .btop_set_target = NULL, 2240 .btop_propagate = nilfs_btree_propagate_p, 2241 .btop_assign = nilfs_btree_assign_p, 2242 }; 2243 2244 int nilfs_btree_init(struct nilfs_bmap *bmap, __u64 low, __u64 high) 2245 { 2246 struct nilfs_btree *btree; 2247 2248 btree = (struct nilfs_btree *)bmap; 2249 bmap->b_ops = &nilfs_btree_ops; 2250 bmap->b_low = low; 2251 bmap->b_high = high; 2252 switch (bmap->b_inode->i_ino) { 2253 case NILFS_DAT_INO: 2254 btree->bt_ops = &nilfs_btree_ops_p; 2255 break; 2256 default: 2257 btree->bt_ops = &nilfs_btree_ops_v; 2258 break; 2259 } 2260 2261 return 0; 2262 } 2263 2264 void nilfs_btree_init_gc(struct nilfs_bmap *bmap) 2265 { 2266 bmap->b_low = NILFS_BMAP_LARGE_LOW; 2267 bmap->b_high = NILFS_BMAP_LARGE_HIGH; 2268 bmap->b_ops = &nilfs_btree_ops_gc; 2269 } 2270