1 /* 2 * Copyright (c) 2011-2014 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@dragonflybsd.org> 6 * by Venkatesh Srinivas <vsrinivas@dragonflybsd.org> 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 3. Neither the name of The DragonFly Project nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific, prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 32 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include <sys/cdefs.h> 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/types.h> 40 #include <sys/lock.h> 41 #include <sys/uuid.h> 42 43 #include "hammer2.h" 44 45 #define FLUSH_DEBUG 0 46 47 /* 48 * Recursively flush the specified chain. The chain is locked and 49 * referenced by the caller and will remain so on return. The chain 50 * will remain referenced throughout but can temporarily lose its 51 * lock during the recursion to avoid unnecessarily stalling user 52 * processes. 53 */ 54 struct hammer2_flush_info { 55 hammer2_chain_t *parent; 56 hammer2_trans_t *trans; 57 int depth; 58 int diddeferral; 59 int cache_index; 60 int domodify; 61 struct h2_flush_deferral_list flush_list; 62 hammer2_tid_t sync_tid; /* flush synchronization point */ 63 }; 64 65 typedef struct hammer2_flush_info hammer2_flush_info_t; 66 67 static void hammer2_flush_core(hammer2_flush_info_t *info, 68 hammer2_chain_t **chainp, int deleting); 69 static int hammer2_flush_pass1(hammer2_chain_t *child, void *data); 70 static int hammer2_flush_pass2(hammer2_chain_t *child, void *data); 71 static int hammer2_flush_pass3(hammer2_chain_t *child, void *data); 72 static int hammer2_flush_pass4(hammer2_chain_t *child, void *data); 73 static void hammer2_rollup_stats(hammer2_chain_t *parent, 74 hammer2_chain_t *child, int how); 75 76 77 /* 78 * Can we ignore a chain for the purposes of flushing modifications 79 * to the media? 80 * 81 * This code is now degenerate. We used to have to distinguish between 82 * deleted chains and deleted chains associated with inodes that were 83 * still open. This mechanic has been fixed so the function is now 84 * a simple test. 85 */ 86 static __inline 87 int 88 h2ignore_deleted(hammer2_flush_info_t *info, hammer2_chain_t *chain) 89 { 90 return (chain->delete_tid <= info->sync_tid); 91 } 92 93 #if 0 94 static __inline 95 void 96 hammer2_updatestats(hammer2_flush_info_t *info, hammer2_blockref_t *bref, 97 int how) 98 { 99 hammer2_key_t bytes; 100 101 if (bref->type != 0) { 102 bytes = 1 << (bref->data_off & HAMMER2_OFF_MASK_RADIX); 103 if (bref->type == HAMMER2_BREF_TYPE_INODE) 104 info->inode_count += how; 105 if (how < 0) 106 info->data_count -= bytes; 107 else 108 info->data_count += bytes; 109 } 110 } 111 #endif 112 113 /* 114 * Transaction support functions for writing to the filesystem. 115 * 116 * Initializing a new transaction allocates a transaction ID. Typically 117 * passed a pmp (hmp passed as NULL), indicating a cluster transaction. Can 118 * be passed a NULL pmp and non-NULL hmp to indicate a transaction on a single 119 * media target. The latter mode is used by the recovery code. 120 * 121 * TWO TRANSACTION IDs can run concurrently, where one is a flush and the 122 * other is a set of any number of concurrent filesystem operations. We 123 * can either have <running_fs_ops> + <waiting_flush> + <blocked_fs_ops> 124 * or we can have <running_flush> + <concurrent_fs_ops>. 125 * 126 * During a flush, new fs_ops are only blocked until the fs_ops prior to 127 * the flush complete. The new fs_ops can then run concurrent with the flush. 128 * 129 * Buffer-cache transactions operate as fs_ops but never block. A 130 * buffer-cache flush will run either before or after the current pending 131 * flush depending on its state. 132 * 133 * NOTE: The sync_tid for a flush's freemap allocation will match the 134 * sync_tid of the following <concurrent_fs_ops> transaction(s). 135 * The freemap topology will be out-of-step by one transaction id 136 * in order to give the flusher a stable freemap topology to flush 137 * out. This is fixed up at mount-time using a quick incremental 138 * scan. 139 */ 140 void 141 hammer2_trans_init(hammer2_trans_t *trans, hammer2_pfsmount_t *pmp, 142 hammer2_mount_t *hmp, int flags) 143 { 144 hammer2_trans_t *head; 145 146 bzero(trans, sizeof(*trans)); 147 if (pmp) { 148 trans->pmp = pmp; 149 KKASSERT(hmp == NULL); 150 hmp = pmp->cluster.chains[0]->hmp; /* XXX */ 151 } else { 152 trans->hmp_single = hmp; 153 KKASSERT(hmp); 154 } 155 156 hammer2_voldata_lock(hmp); 157 trans->flags = flags; 158 trans->td = curthread; 159 /*trans->delete_gen = 0;*/ /* multiple deletions within trans */ 160 161 if (flags & HAMMER2_TRANS_ISFLUSH) { 162 /* 163 * If multiple flushes are trying to run we have to 164 * wait until it is our turn. All flushes are serialized. 165 * 166 * We queue ourselves and then wait to become the head 167 * of the queue, allowing all prior flushes to complete. 168 * 169 * Multiple normal transactions can share the current 170 * transaction id but a flush transaction needs its own 171 * unique TID for proper block table update accounting. 172 */ 173 ++hmp->flushcnt; 174 ++hmp->voldata.alloc_tid; 175 trans->sync_tid = hmp->voldata.alloc_tid; 176 trans->orig_tid = trans->sync_tid; 177 ++hmp->voldata.alloc_tid; 178 TAILQ_INSERT_TAIL(&hmp->transq, trans, entry); 179 if (TAILQ_FIRST(&hmp->transq) != trans) { 180 trans->blocked = 1; 181 while (trans->blocked) { 182 lksleep(&trans->sync_tid, &hmp->voldatalk, 183 0, "h2multf", hz); 184 } 185 } 186 } else if (hmp->flushcnt == 0) { 187 /* 188 * No flushes are pending, we can go. 189 */ 190 TAILQ_INSERT_TAIL(&hmp->transq, trans, entry); 191 trans->sync_tid = hmp->voldata.alloc_tid; 192 trans->orig_tid = trans->sync_tid; 193 194 /* XXX improve/optimize inode allocation */ 195 } else { 196 /* 197 * One or more flushes are pending. We insert after 198 * the current flush and may block. We have priority 199 * over any flushes that are not the current flush. 200 * 201 * TRANS_BUFCACHE transactions cannot block. 202 */ 203 TAILQ_FOREACH(head, &hmp->transq, entry) { 204 if (head->flags & HAMMER2_TRANS_ISFLUSH) 205 break; 206 } 207 KKASSERT(head); 208 TAILQ_INSERT_AFTER(&hmp->transq, head, trans, entry); 209 trans->sync_tid = head->orig_tid + 1; 210 trans->orig_tid = trans->sync_tid; 211 trans->flags |= HAMMER2_TRANS_CONCURRENT; 212 213 if ((trans->flags & HAMMER2_TRANS_BUFCACHE) == 0) { 214 /* 215 * If synchronous flush mode is enabled concurrent 216 * frontend transactions during the flush are not 217 * allowed (except we don't have a choice for buffer 218 * cache ops). 219 */ 220 if (hammer2_synchronous_flush > 0 || 221 TAILQ_FIRST(&hmp->transq) != head) { 222 trans->blocked = 1; 223 while (trans->blocked) { 224 lksleep(&trans->sync_tid, 225 &hmp->voldatalk, 0, 226 "h2multf", hz); 227 } 228 } 229 } 230 } 231 if (flags & HAMMER2_TRANS_NEWINODE) { 232 if (hmp->voldata.inode_tid < HAMMER2_INODE_START) 233 hmp->voldata.inode_tid = HAMMER2_INODE_START; 234 trans->inode_tid = hmp->voldata.inode_tid++; 235 } 236 hammer2_voldata_unlock(hmp, 0); 237 } 238 239 void 240 hammer2_trans_done(hammer2_trans_t *trans) 241 { 242 hammer2_mount_t *hmp; 243 hammer2_trans_t *head; 244 hammer2_trans_t *scan; 245 246 if (trans->pmp) 247 hmp = trans->pmp->cluster.chains[0]->hmp; 248 else 249 hmp = trans->hmp_single; 250 251 /* 252 * Remove. 253 */ 254 hammer2_voldata_lock(hmp); 255 TAILQ_REMOVE(&hmp->transq, trans, entry); 256 head = TAILQ_FIRST(&hmp->transq); 257 258 /* 259 * Adjust flushcnt if this was a flush, clear TRANS_CONCURRENT 260 * up through the next flush. (If the head is a flush then we 261 * stop there, unlike the unblock code following this section). 262 */ 263 if (trans->flags & HAMMER2_TRANS_ISFLUSH) { 264 --hmp->flushcnt; 265 scan = head; 266 while (scan && (scan->flags & HAMMER2_TRANS_ISFLUSH) == 0) { 267 atomic_clear_int(&scan->flags, 268 HAMMER2_TRANS_CONCURRENT); 269 scan = TAILQ_NEXT(head, entry); 270 } 271 } 272 273 /* 274 * Unblock the head of the queue and any additional transactions 275 * up to the next flush. The head can be a flush and it will be 276 * unblocked along with the non-flush transactions following it 277 * (which are allowed to run concurrently with it). 278 * 279 * In synchronous flush mode we stop if the head transaction is 280 * a flush. 281 */ 282 if (head && head->blocked) { 283 head->blocked = 0; 284 wakeup(&head->sync_tid); 285 286 if (hammer2_synchronous_flush > 0) 287 scan = head; 288 else 289 scan = TAILQ_NEXT(head, entry); 290 while (scan && (scan->flags & HAMMER2_TRANS_ISFLUSH) == 0) { 291 if (scan->blocked) { 292 scan->blocked = 0; 293 wakeup(&scan->sync_tid); 294 } 295 scan = TAILQ_NEXT(scan, entry); 296 } 297 } 298 hammer2_voldata_unlock(hmp, 0); 299 } 300 301 /* 302 * Flush the chain and all modified sub-chains through the specified 303 * synchronization point (sync_tid), propagating parent chain modifications 304 * and mirror_tid updates back up as needed. Since we are recursing downward 305 * we do not have to deal with the complexities of multi-homed chains (chains 306 * with multiple parents). 307 * 308 * Caller must have interlocked against any non-flush-related modifying 309 * operations in progress whos modify_tid values are less than or equal 310 * to the passed sync_tid. 311 * 312 * Caller must have already vetted synchronization points to ensure they 313 * are properly flushed. Only snapshots and cluster flushes can create 314 * these sorts of synchronization points. 315 * 316 * This routine can be called from several places but the most important 317 * is from VFS_SYNC. 318 * 319 * chain is locked on call and will remain locked on return. If a flush 320 * occured, the chain's FLUSH_CREATE and/or FLUSH_DELETE bit will be set 321 * indicating that its parent (which is not part of the flush) should be 322 * updated. The chain may be replaced by the call if it was modified. 323 */ 324 void 325 hammer2_flush(hammer2_trans_t *trans, hammer2_chain_t **chainp) 326 { 327 hammer2_chain_t *chain = *chainp; 328 hammer2_chain_t *scan; 329 hammer2_chain_core_t *core; 330 hammer2_flush_info_t info; 331 int loops; 332 333 /* 334 * Execute the recursive flush and handle deferrals. 335 * 336 * Chains can be ridiculously long (thousands deep), so to 337 * avoid blowing out the kernel stack the recursive flush has a 338 * depth limit. Elements at the limit are placed on a list 339 * for re-execution after the stack has been popped. 340 */ 341 bzero(&info, sizeof(info)); 342 TAILQ_INIT(&info.flush_list); 343 info.trans = trans; 344 info.sync_tid = trans->sync_tid; 345 info.cache_index = -1; 346 347 core = chain->core; 348 349 /* 350 * Extra ref needed because flush_core expects it when replacing 351 * chain. 352 */ 353 hammer2_chain_ref(chain); 354 loops = 0; 355 356 for (;;) { 357 /* 358 * Unwind deep recursions which had been deferred. This 359 * can leave the FLUSH_* bits set for these chains, which 360 * will be handled when we [re]flush chain after the unwind. 361 */ 362 while ((scan = TAILQ_FIRST(&info.flush_list)) != NULL) { 363 KKASSERT(scan->flags & HAMMER2_CHAIN_DEFERRED); 364 TAILQ_REMOVE(&info.flush_list, scan, flush_node); 365 atomic_clear_int(&scan->flags, HAMMER2_CHAIN_DEFERRED); 366 367 /* 368 * Now that we've popped back up we can do a secondary 369 * recursion on the deferred elements. 370 * 371 * NOTE: hammer2_flush() may replace scan. 372 */ 373 if (hammer2_debug & 0x0040) 374 kprintf("deferred flush %p\n", scan); 375 hammer2_chain_lock(scan, HAMMER2_RESOLVE_MAYBE); 376 hammer2_chain_drop(scan); /* ref from deferral */ 377 hammer2_flush(trans, &scan); 378 hammer2_chain_unlock(scan); 379 } 380 381 /* 382 * [re]flush chain. 383 */ 384 info.diddeferral = 0; 385 hammer2_flush_core(&info, &chain, 0); 386 387 /* 388 * Only loop if deep recursions have been deferred. 389 */ 390 if (TAILQ_EMPTY(&info.flush_list)) 391 break; 392 393 if (++loops % 1000 == 0) { 394 kprintf("hammer2_flush: excessive loops on %p\n", 395 chain); 396 if (hammer2_debug & 0x100000) 397 Debugger("hell4"); 398 } 399 } 400 hammer2_chain_drop(chain); 401 *chainp = chain; 402 } 403 404 /* 405 * This is the core of the chain flushing code. The chain is locked by the 406 * caller and must also have an extra ref on it by the caller, and remains 407 * locked and will have an extra ref on return. Upon return, the caller can 408 * test the FLUSH_CREATE and FLUSH_DELETE bits to determine what action must 409 * be taken on the parent. 410 * 411 * (1) Determine if this node is a candidate for the flush, return if it is 412 * not. fchain and vchain are always candidates for the flush. 413 * 414 * (2) If we recurse too deep the chain is entered onto the deferral list and 415 * the current flush stack is aborted until after the deferral list is 416 * run. 417 * 418 * (3) Recursively flush live children (rbtree). This can create deferrals. 419 * A successful flush clears the MODIFIED bit in the children. 420 * 421 * (4) Recursively flush deleted children (dbtree). Deletions may be 422 * considered 'live' if the delete_tid is beyond the flush_tid. If 423 * considered 'dead' the recursion is still needed in order to clean 424 * up the chain. This can create deferrals. 425 * 426 * A successful flush clears the MODIFIED bit in the children. 427 * 428 * (5) Calculate block table updates on chain based on the children scans 429 * in (3) and (4) by testing the FLUSH_CREATE and FLUSH_DELETE bits, 430 * modifying chain if necessary to perform the block table updates. 431 * Deletions must be removed from dbtree when removed from the 432 * chain's block table. 433 * 434 * If 'chain' itself is marked DELETED but treated as live, the block 435 * table update(s) must be propagated to all contemporary chains. In 436 * fact, all contemporary chains must be locked and updated uninterrupted 437 * to avoid lookup races. Once MODIFIED and FLUSH_CREATE is cleared, 438 * a chain can be unloaded from memory with the expectation that it can 439 * be reloaded later via the block table at any time. 440 * 441 * NOTE: chain->bref.modify_tid is different from chain->modify_tid. COW 442 * propagations for block updates do not update chain->bref.modify_tid, 443 * only chain->bref.mirror_tid. The MODIFIED bit is set on any 444 * modified chain, including COW propagations, but the flusher normally 445 * just keys off of the FLUSH_* bits. FLUSH_CREATE will also be set 446 * in this situation. 447 * 448 * NOTE: We are responsible for updating chain->bref.mirror_tid and 449 * chain->update_lo. The caller is responsible for processing us into 450 * our parent (if any). 451 */ 452 static void 453 hammer2_flush_core(hammer2_flush_info_t *info, hammer2_chain_t **chainp, 454 int deleting) 455 { 456 hammer2_chain_t *chain = *chainp; 457 hammer2_chain_t *saved_parent; 458 hammer2_mount_t *hmp; 459 hammer2_chain_core_t *core; 460 int diddeferral; 461 int saved_domodify; 462 463 hmp = chain->hmp; 464 core = chain->core; 465 diddeferral = info->diddeferral; 466 467 /* 468 * (1) Check if we even have any work to do. 469 * 470 * This bit of code is capable of short-cutting entire sub-trees 471 * if they have not been touched or if they have already been 472 * flushed. 473 */ 474 if (/*(chain->flags & HAMMER2_CHAIN_MODIFIED) == 0 &&*/ 475 (chain->update_lo >= info->sync_tid || /* already synced */ 476 chain->update_lo >= chain->update_hi)) { /* old/unchanged */ 477 /* update_lo/_hi already filters chain out, do not update */ 478 /* don't update bref.mirror_tid, pass2 is not called */ 479 return; 480 } 481 482 /* 483 * mirror_tid should not be forward-indexed 484 */ 485 KKASSERT(chain->bref.mirror_tid <= info->sync_tid); 486 487 /* 488 * Ignore chains modified beyond the current flush point. These 489 * will be treated as if they did not exist. Subchains with lower 490 * modify_tid's will still be accessible via other parents. 491 * 492 * Do not update bref.mirror_tid here, it will interfere with 493 * synchronization. e.g. inode flush tid 1, concurrent D-D tid 2, 494 * then later on inode flush tid 2. If we were to set mirror_tid 495 * to 1 during inode flush tid 1 the blockrefs would only be partially 496 * updated (and likely panic). 497 * 498 * We must update chain->update_lo here to prevent re-entry in this 499 * flush transaction. 500 * 501 * (vchain and fchain are exceptions since they cannot be duplicated) 502 */ 503 if (chain->modify_tid > info->sync_tid && 504 chain != &hmp->fchain && chain != &hmp->vchain) { 505 /* do not update bref.mirror_tid, pass2 ignores chain */ 506 /* chain->update_lo = info->sync_tid; */ 507 return; 508 } 509 510 /* 511 * (2) Recurse downward and check recursion depth. 512 * (3) Flush live children 513 * (4) Flush deleted children 514 * 515 * We adjust update_lo if not deferring chain to prevent re-entry 516 * in this flush cycle, but it must be set AFTER the flush in case 517 * a deeper flush hits the chain. Otherwise the deeper flush cannot 518 * complete. We re-check the condition after finishing the flushes. 519 * 520 * update_hi was already checked and prevents initial recursions on 521 * subtrees which have not been modified. 522 */ 523 saved_parent = info->parent; 524 saved_domodify = info->domodify; 525 info->parent = chain; 526 info->domodify = 0; 527 528 if (chain->flags & HAMMER2_CHAIN_DEFERRED) { 529 ++info->diddeferral; 530 } else if (info->depth == HAMMER2_FLUSH_DEPTH_LIMIT) { 531 if ((chain->flags & HAMMER2_CHAIN_DEFERRED) == 0) { 532 hammer2_chain_ref(chain); 533 TAILQ_INSERT_TAIL(&info->flush_list, 534 chain, flush_node); 535 atomic_set_int(&chain->flags, 536 HAMMER2_CHAIN_DEFERRED); 537 } 538 ++info->diddeferral; 539 } else { 540 hammer2_chain_t *scan; 541 542 /* 543 * The flush is queue-agnostic when running pass1, but order 544 * is important to catch any races where an existing 545 * flush-visible child is moved from rbtree->dbtree/dbq. 546 * 547 * New children added by concurrent operations are not visible 548 * to the flush anyway so we don't care about those races. 549 * However, the flush itself can move a child from dbq to 550 * dbtree (rare in pass1 but it is possible). 551 * 552 * pass1 can handle re-execution of a child. 553 */ 554 spin_lock(&core->cst.spin); 555 KKASSERT(core->good == 0x1234 && core->sharecnt > 0); 556 RB_SCAN(hammer2_chain_tree, &core->rbtree, 557 NULL, hammer2_flush_pass1, info); 558 RB_SCAN(hammer2_chain_tree, &core->dbtree, 559 NULL, hammer2_flush_pass1, info); 560 scan = TAILQ_FIRST(&core->dbq); 561 while (scan) { 562 KKASSERT(scan->flags & HAMMER2_CHAIN_ONDBQ); 563 hammer2_flush_pass1(scan, info); 564 if (scan->flags & HAMMER2_CHAIN_ONDBQ) 565 scan = TAILQ_NEXT(scan, db_entry); 566 else 567 scan = TAILQ_FIRST(&core->dbq); 568 } 569 spin_unlock(&core->cst.spin); 570 } 571 572 /* 573 * Stop if deferred, do not update update_lo. 574 */ 575 if (info->diddeferral) 576 goto done; 577 578 /* 579 * If a block table update is needed place the parent in a modified 580 * state, which might delete-duplicate it. 581 * 582 * - To prevent loops and other confusion, we synchronize update_lo 583 * for the original chain. 584 * 585 * - The original parent will not be used by the flush so we can 586 * clear its MODIFIED bit. 587 */ 588 if (info->domodify) { 589 hammer2_chain_modify(info->trans, &info->parent, 590 HAMMER2_MODIFY_NO_MODIFY_TID); 591 if (info->parent != chain) { 592 /* 593 * chain - old 594 * info->parent - new 595 * 596 * NOTE: bref.mirror_tid cannot be updated 597 * unless MODIFIED is cleared or already 598 * clear. 599 */ 600 chain->inode_reason += 0x10000000; 601 info->parent->inode_reason += 0x100; 602 KKASSERT(info->parent->core == chain->core); 603 if (chain->flags & HAMMER2_CHAIN_MODIFIED) { 604 atomic_clear_int(&chain->flags, 605 HAMMER2_CHAIN_MODIFIED); 606 hammer2_chain_memory_wakeup(chain->pmp); 607 hammer2_chain_drop(chain); 608 } 609 #if 0 610 if (chain->flags & HAMMER2_CHAIN_FLUSH_CREATE) { 611 atomic_clear_int(&chain->flags, 612 HAMMER2_CHAIN_FLUSH_CREATE); 613 hammer2_chain_drop(chain); 614 } 615 if (info->parent->flags & HAMMER2_CHAIN_FLUSH_DELETE) { 616 atomic_clear_int(&info->parent->flags, 617 HAMMER2_CHAIN_FLUSH_DELETE); 618 hammer2_chain_drop(info->parent); 619 } 620 #endif 621 #if 0 622 if (chain->bref.mirror_tid < info->sync_tid) 623 chain->bref.mirror_tid = info->sync_tid; 624 #endif 625 if (chain->update_lo < info->sync_tid) 626 chain->update_lo = info->sync_tid; 627 KKASSERT(info->parent->update_lo < info->sync_tid); 628 hammer2_chain_drop(chain); 629 hammer2_chain_ref(info->parent); 630 } 631 chain = info->parent; 632 } 633 634 /* 635 * If a blocktable update is needed determine if this is the last 636 * parent requiring modification (check all parents using the core). 637 * 638 * Set bit 1 (0x02) of domodify if this is the last parent, 639 * which will cause scan2 to clear FLUSH_CREATE and FLUSH_DELETE. 640 */ 641 if (1) { 642 hammer2_chain_t *scan; 643 644 spin_lock(&core->cst.spin); 645 TAILQ_FOREACH(scan, &core->ownerq, core_entry) { 646 /* 647 * Ignore chains which have already been updated 648 * Ignore unmodified chains 649 */ 650 if ((scan->flags & HAMMER2_CHAIN_MODIFIED) == 0 && 651 (scan->update_lo >= info->sync_tid || 652 scan->update_lo >= scan->update_hi)) { 653 continue; 654 } 655 656 /* 657 * Ignore the current parent being processed (we do 658 * not adjust update_lo until after the fixup). 659 */ 660 if (scan == chain) 661 continue; 662 663 /* 664 * Cannot exhaust all parents if one is not visible 665 * to the flush. The root chains are special-cased 666 * because they cannot really be delete-duplicated. 667 */ 668 if (scan != &scan->hmp->fchain && 669 scan != &scan->hmp->vchain && 670 scan->modify_tid > info->sync_tid) { 671 break; 672 } 673 674 /* 675 * Fail if update_lo has not been synchronized to 676 * at least our sync_tid on any modified parent chain. 677 */ 678 if (scan->update_lo < info->sync_tid) 679 break; 680 } 681 spin_unlock(&core->cst.spin); 682 if (scan == NULL) 683 info->domodify |= 2; 684 } 685 686 /* 687 * (5) Calculate block table updates or child cleanups. 688 * (this whole operation has to be atomic) 689 * 690 * domodify 0x01 - block table updates 691 * 0x02 - child cleanups 692 * 693 * pass2 - Process deletions from dbtree and dbq. 694 * pass3 - Process insertions from rbtree, dbtree, and dbq. 695 * pass4 - Cleanup child flags on the last parent and 696 * Adjust queues on the live parent. 697 */ 698 if (info->domodify) { 699 hammer2_chain_t *scan; 700 701 spin_lock(&core->cst.spin); 702 703 while ((info->domodify & 1) && info->parent) { 704 /* PASS2 - Deletions */ 705 RB_SCAN(hammer2_chain_tree, &core->rbtree, 706 NULL, hammer2_flush_pass2, info); 707 RB_SCAN(hammer2_chain_tree, &core->dbtree, 708 NULL, hammer2_flush_pass2, info); 709 scan = TAILQ_FIRST(&core->dbq); 710 TAILQ_FOREACH(scan, &core->dbq, db_entry) { 711 KKASSERT(scan->flags & HAMMER2_CHAIN_ONDBQ); 712 hammer2_flush_pass2(scan, info); 713 } 714 715 /* PASS3 - Insertions */ 716 RB_SCAN(hammer2_chain_tree, &core->rbtree, 717 NULL, hammer2_flush_pass3, info); 718 RB_SCAN(hammer2_chain_tree, &core->dbtree, 719 NULL, hammer2_flush_pass3, info); 720 TAILQ_FOREACH(scan, &core->dbq, db_entry) { 721 KKASSERT(scan->flags & HAMMER2_CHAIN_ONDBQ); 722 hammer2_flush_pass3(scan, info); 723 } 724 info->parent = TAILQ_NEXT(info->parent, core_entry); 725 if (info->parent) 726 kprintf("FLUSH SPECIAL UPDATE (%p) %p.%d %08x\n", 727 chain, info->parent, 728 info->parent->bref.type, 729 info->parent->flags); 730 } 731 info->parent = chain; 732 733 /* PASS4 - Cleanup */ 734 RB_SCAN(hammer2_chain_tree, &core->rbtree, 735 NULL, hammer2_flush_pass4, info); 736 scan = TAILQ_FIRST(&core->dbq); 737 while (scan) { 738 KKASSERT(scan->flags & HAMMER2_CHAIN_ONDBQ); 739 hammer2_flush_pass4(scan, info); 740 if (scan->flags & HAMMER2_CHAIN_ONDBQ) 741 scan = TAILQ_NEXT(scan, db_entry); 742 else 743 scan = TAILQ_FIRST(&core->dbq); 744 } 745 RB_SCAN(hammer2_chain_tree, &core->dbtree, 746 NULL, hammer2_flush_pass4, info); 747 748 spin_unlock(&core->cst.spin); 749 } 750 751 /* 752 * Synchronize update_lo to prevent reentrant block updates of this 753 * parent. 754 */ 755 chain->update_lo = info->sync_tid; 756 757 /* 758 * Skip the flush if the chain was not placed in a modified state 759 * or was not already in a modified state. 760 */ 761 if ((chain->flags & HAMMER2_CHAIN_MODIFIED) == 0) 762 goto done; 763 764 /* 765 * FLUSH THE CHAIN (on the way back up the recursion) 766 * 767 * Chain is now deterministically being flushed and not being deferred. 768 * We've finished running the recursion and the blockref update. 769 * 770 * update bref.mirror_tid. update_lo has already been updated. 771 */ 772 if (chain->bref.mirror_tid < info->sync_tid) 773 chain->bref.mirror_tid = info->sync_tid; 774 775 /* 776 * Dispose of the modified bit. FLUSH_CREATE should already be 777 * set. 778 */ 779 KKASSERT(chain->flags & HAMMER2_CHAIN_FLUSH_CREATE); 780 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED); 781 hammer2_chain_memory_wakeup(chain->pmp); 782 783 if ((chain->flags & HAMMER2_CHAIN_FLUSH_CREATE) || 784 chain == &hmp->vchain || 785 chain == &hmp->fchain) { 786 /* 787 * Drop the ref from the MODIFIED bit we cleared, 788 * net -1 ref. 789 */ 790 hammer2_chain_drop(chain); 791 } else { 792 /* 793 * Drop the ref from the MODIFIED bit we cleared and 794 * set a ref for the FLUSH_CREATE bit we are setting. 795 * Net 0 refs. 796 */ 797 atomic_set_int(&chain->flags, HAMMER2_CHAIN_FLUSH_CREATE); 798 } 799 800 /* 801 * Skip the actual flush operation if the chain has been deleted 802 * in our flus hview. There will be no block table entry that 803 * references it. 804 */ 805 if (h2ignore_deleted(info, chain)) 806 goto done; 807 808 /* 809 * Issue flush. 810 * 811 * A DELETED node that reaches this point must be flushed for 812 * synchronization point consistency. 813 * 814 * Update bref.mirror_tid, clear MODIFIED, and set MOVED. 815 * 816 * The caller will update the parent's reference to this chain 817 * by testing MOVED as long as the modification was in-bounds. 818 * 819 * MOVED is never set on the volume root as there is no parent 820 * to adjust. 821 */ 822 if (hammer2_debug & 0x1000) { 823 kprintf("Flush %p.%d %016jx/%d sync_tid=%016jx data=%016jx\n", 824 chain, chain->bref.type, 825 chain->bref.key, chain->bref.keybits, 826 info->sync_tid, chain->bref.data_off); 827 } 828 if (hammer2_debug & 0x2000) { 829 Debugger("Flush hell"); 830 } 831 832 /* 833 * If this is part of a recursive flush we can go ahead and write 834 * out the buffer cache buffer and pass a new bref back up the chain 835 * via the MOVED bit. 836 * 837 * Volume headers are NOT flushed here as they require special 838 * processing. 839 */ 840 switch(chain->bref.type) { 841 case HAMMER2_BREF_TYPE_FREEMAP: 842 hammer2_modify_volume(hmp); 843 hmp->voldata.freemap_tid = hmp->fchain.bref.mirror_tid; 844 break; 845 case HAMMER2_BREF_TYPE_VOLUME: 846 /* 847 * The free block table is flushed by hammer2_vfs_sync() 848 * before it flushes vchain. We must still hold fchain 849 * locked while copying voldata to volsync, however. 850 */ 851 hammer2_chain_lock(&hmp->fchain, HAMMER2_RESOLVE_ALWAYS); 852 #if 0 853 if ((hmp->fchain.flags & HAMMER2_CHAIN_MODIFIED) || 854 hmp->voldata.freemap_tid < info->trans->sync_tid) { 855 /* this will modify vchain as a side effect */ 856 hammer2_chain_t *tmp = &hmp->fchain; 857 hammer2_chain_flush(info->trans, &tmp); 858 KKASSERT(tmp == &hmp->fchain); 859 } 860 #endif 861 862 /* 863 * There is no parent to our root vchain and fchain to 864 * synchronize the bref to, their updated mirror_tid's 865 * must be synchronized to the volume header. 866 */ 867 hmp->voldata.mirror_tid = chain->bref.mirror_tid; 868 /*hmp->voldata.freemap_tid = hmp->fchain.bref.mirror_tid;*/ 869 870 /* 871 * The volume header is flushed manually by the syncer, not 872 * here. All we do here is adjust the crc's. 873 */ 874 KKASSERT(chain->data != NULL); 875 KKASSERT(chain->dio == NULL); 876 877 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT1]= 878 hammer2_icrc32( 879 (char *)&hmp->voldata + 880 HAMMER2_VOLUME_ICRC1_OFF, 881 HAMMER2_VOLUME_ICRC1_SIZE); 882 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT0]= 883 hammer2_icrc32( 884 (char *)&hmp->voldata + 885 HAMMER2_VOLUME_ICRC0_OFF, 886 HAMMER2_VOLUME_ICRC0_SIZE); 887 hmp->voldata.icrc_volheader = 888 hammer2_icrc32( 889 (char *)&hmp->voldata + 890 HAMMER2_VOLUME_ICRCVH_OFF, 891 HAMMER2_VOLUME_ICRCVH_SIZE); 892 hmp->volsync = hmp->voldata; 893 atomic_set_int(&chain->flags, HAMMER2_CHAIN_VOLUMESYNC); 894 hammer2_chain_unlock(&hmp->fchain); 895 break; 896 case HAMMER2_BREF_TYPE_DATA: 897 /* 898 * Data elements have already been flushed via the logical 899 * file buffer cache. Their hash was set in the bref by 900 * the vop_write code. 901 * 902 * Make sure any device buffer(s) have been flushed out here. 903 * (there aren't usually any to flush). 904 */ 905 break; 906 #if 0 907 case HAMMER2_BREF_TYPE_INDIRECT: 908 /* 909 * Indirect blocks may be in an INITIAL state. Use the 910 * chain_lock() call to ensure that the buffer has been 911 * instantiated (even though it is already locked the buffer 912 * might not have been instantiated). 913 * 914 * Only write the buffer out if it is dirty, it is possible 915 * the operating system had already written out the buffer. 916 */ 917 hammer2_chain_lock(chain, HAMMER2_RESOLVE_ALWAYS); 918 KKASSERT(chain->dio != NULL); 919 920 chain->data = NULL; 921 hammer2_io_bqrelse(&chain->dio); 922 hammer2_chain_unlock(chain); 923 break; 924 #endif 925 case HAMMER2_BREF_TYPE_INDIRECT: 926 case HAMMER2_BREF_TYPE_FREEMAP_NODE: 927 case HAMMER2_BREF_TYPE_FREEMAP_LEAF: 928 case HAMMER2_BREF_TYPE_INODE: 929 /* 930 * Device-backed. Buffer will be flushed by the sync 931 * code XXX. 932 */ 933 KKASSERT((chain->flags & HAMMER2_CHAIN_EMBEDDED) == 0); 934 break; 935 default: 936 KKASSERT(chain->flags & HAMMER2_CHAIN_EMBEDDED); 937 panic("hammer2_chain_flush_core: unsupported embedded bref %d", 938 chain->bref.type); 939 /* NOT REACHED */ 940 } 941 942 /* 943 * Final cleanup after flush 944 */ 945 done: 946 KKASSERT(chain->refs > 1); 947 info->domodify = saved_domodify; 948 info->parent = saved_parent; 949 *chainp = chain; 950 951 KKASSERT(chain->bref.mirror_tid <= info->sync_tid); 952 } 953 954 /* 955 * Flush helper pass1 (recursive) 956 * 957 * Flushes the children of the caller's chain (info->parent), restricted 958 * by sync_tid. Set info->domodify if the child's blockref must propagate 959 * back up to the parent. 960 * 961 * Ripouts can move child from rbtree to dbtree or dbq but the caller's 962 * flush scan order prevents any chains from being lost. A child can be 963 * executes more than once (update_lo is used to prevent infinite recursions). 964 * 965 * WARNING! If we do not call hammer2_flush_core() we must update 966 * bref.mirror_tid ourselves to indicate that the flush has 967 * processed the child. 968 * 969 * WARNING! parent->core spinlock is held on entry and return. 970 */ 971 static int 972 hammer2_flush_pass1(hammer2_chain_t *child, void *data) 973 { 974 hammer2_flush_info_t *info = data; 975 hammer2_trans_t *trans = info->trans; 976 hammer2_chain_t *parent = info->parent; 977 978 /* 979 * Child modified in a later transactions, nothing to flush in this 980 * transaction. 981 * 982 * Remember that modifications generally delete-duplicate so if the 983 * sub-tree is dirty another child will get us there. But not this 984 * one. 985 * 986 * (child can never be fchain or vchain so a special check isn't 987 * needed). 988 */ 989 if (child->modify_tid > trans->sync_tid) { 990 KKASSERT(child->delete_tid >= child->modify_tid); 991 /*child->update_lo = info->sync_tid;*/ 992 /* do not update mirror_tid, pass2 will ignore chain */ 993 return (0); 994 } 995 996 /* 997 * We must ref the child before unlocking the spinlock. 998 * 999 * The caller has added a ref to the parent so we can temporarily 1000 * unlock it in order to lock the child. 1001 */ 1002 hammer2_chain_ref(child); 1003 spin_unlock(&parent->core->cst.spin); 1004 1005 hammer2_chain_unlock(parent); 1006 hammer2_chain_lock(child, HAMMER2_RESOLVE_MAYBE); 1007 1008 /* 1009 * Recurse and collect deferral data. We only recursively sync 1010 * (basically) if update_lo has not been updated, indicating that 1011 * the child has not already been processed. 1012 */ 1013 if ((child->flags & HAMMER2_CHAIN_MODIFIED) || 1014 (child->update_lo < info->sync_tid && 1015 child->update_lo < child->update_hi)) { 1016 ++info->depth; 1017 hammer2_flush_core(info, &child, 0); /* XXX deleting */ 1018 --info->depth; 1019 } 1020 1021 /* 1022 * Determine if domodify should be set. Do not otherwise adjust 1023 * the child or pass2 will get confused. 1024 * 1025 * Insertion: 1026 * - child is flagged as possibly needing block table insertion. 1027 * - child not deleted or deletion is beyond transaction id 1028 * - child created beyond parent synchronization point 1029 * - parent not deleted as-of this transaction 1030 */ 1031 if ((child->flags & HAMMER2_CHAIN_FLUSH_CREATE) && 1032 child->delete_tid > trans->sync_tid && 1033 child->modify_tid > parent->update_lo && 1034 parent->delete_tid > trans->sync_tid) { 1035 info->domodify = 1; 1036 } 1037 1038 /* 1039 * Removal: 1040 * - child is flagged as possibly needing block table removal. 1041 * - child deleted before or during this transaction 1042 * - child created prior or during parent synchronization point 1043 * - parent not yet synchronized to child deletion 1044 * - parent not deleted as-of this transaction 1045 */ 1046 if ((child->flags & HAMMER2_CHAIN_FLUSH_DELETE) && 1047 child->delete_tid <= trans->sync_tid && 1048 child->modify_tid <= parent->update_lo && 1049 child->delete_tid > parent->update_lo && 1050 parent->delete_tid > trans->sync_tid) { 1051 info->domodify = 1; 1052 } 1053 1054 /* 1055 * Relock to continue the loop 1056 */ 1057 hammer2_chain_unlock(child); 1058 hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE); 1059 hammer2_chain_drop(child); 1060 KKASSERT(info->parent == parent); 1061 1062 spin_lock(&parent->core->cst.spin); 1063 return (0); 1064 } 1065 1066 /* 1067 * PASS2 - BLOCKTABLE DELETIONS 1068 */ 1069 static int 1070 hammer2_flush_pass2(hammer2_chain_t *child, void *data) 1071 { 1072 hammer2_flush_info_t *info = data; 1073 hammer2_chain_t *parent = info->parent; 1074 hammer2_mount_t *hmp = child->hmp; 1075 hammer2_trans_t *trans = info->trans; 1076 hammer2_blockref_t *base; 1077 int count; 1078 1079 /* 1080 * Prefilter - Ignore children not flagged as needing a parent 1081 * blocktable update. 1082 */ 1083 if ((child->flags & HAMMER2_CHAIN_FLUSH_DELETE) == 0) 1084 return (0); 1085 1086 /* 1087 * Prefilter - Ignore children created after our flush_tid (not 1088 * visible to our flush). 1089 */ 1090 if (child->modify_tid > trans->sync_tid) { 1091 KKASSERT(child->delete_tid >= child->modify_tid); 1092 return 0; 1093 } 1094 1095 /* 1096 * Prefilter - Don't bother updating the blockrefs for a deleted 1097 * parent (from the flush's perspective). Otherwise, 1098 * we need to be COUNTEDBREFS synchronized for the 1099 * hammer2_base_*() functions. 1100 * 1101 * NOTE: This test must match the similar one in flush_core. 1102 */ 1103 if (h2ignore_deleted(info, parent)) 1104 return 0; 1105 1106 /* 1107 * Calculate blockmap pointer 1108 */ 1109 switch(parent->bref.type) { 1110 case HAMMER2_BREF_TYPE_INODE: 1111 /* 1112 * Access the inode's block array. However, there is no 1113 * block array if the inode is flagged DIRECTDATA. The 1114 * DIRECTDATA case typicaly only occurs when a hardlink has 1115 * been shifted up the tree and the original inode gets 1116 * replaced with an OBJTYPE_HARDLINK placeholding inode. 1117 */ 1118 if (parent->data && 1119 (parent->data->ipdata.op_flags & 1120 HAMMER2_OPFLAG_DIRECTDATA) == 0) { 1121 base = &parent->data->ipdata.u.blockset.blockref[0]; 1122 } else { 1123 base = NULL; 1124 } 1125 count = HAMMER2_SET_COUNT; 1126 break; 1127 case HAMMER2_BREF_TYPE_INDIRECT: 1128 case HAMMER2_BREF_TYPE_FREEMAP_NODE: 1129 if (parent->data) 1130 base = &parent->data->npdata[0]; 1131 else 1132 base = NULL; 1133 count = parent->bytes / sizeof(hammer2_blockref_t); 1134 break; 1135 case HAMMER2_BREF_TYPE_VOLUME: 1136 base = &hmp->voldata.sroot_blockset.blockref[0]; 1137 count = HAMMER2_SET_COUNT; 1138 break; 1139 case HAMMER2_BREF_TYPE_FREEMAP: 1140 base = &parent->data->npdata[0]; 1141 count = HAMMER2_SET_COUNT; 1142 break; 1143 default: 1144 base = NULL; 1145 count = 0; 1146 panic("hammer2_chain_flush_pass2: " 1147 "unrecognized blockref type: %d", 1148 parent->bref.type); 1149 } 1150 1151 /* 1152 * Removal 1153 * - child is flagged for removal 1154 * - child deleted before or during this transaction 1155 * - child created prior or during parent synchronization point 1156 * - parent not yet synchronized to child's deletion 1157 */ 1158 if (child->delete_tid <= trans->sync_tid && 1159 child->modify_tid <= parent->update_lo && 1160 child->delete_tid > parent->update_lo) { 1161 /* can't assert BMAPPED because state adjustment may occur 1162 * before we are done, and BMAPPED only applies to the live 1163 * parent. 1164 *KKASSERT(child->flags & HAMMER2_CHAIN_BMAPPED);*/ 1165 if (base) { 1166 hammer2_rollup_stats(parent, child, -1); 1167 hammer2_base_delete(trans, parent, base, count, 1168 &info->cache_index, child); 1169 } 1170 } 1171 1172 return 0; 1173 } 1174 1175 /* 1176 * PASS3 - BLOCKTABLE INSERTIONS 1177 */ 1178 static int 1179 hammer2_flush_pass3(hammer2_chain_t *child, void *data) 1180 { 1181 hammer2_flush_info_t *info = data; 1182 hammer2_chain_t *parent = info->parent; 1183 hammer2_mount_t *hmp = child->hmp; 1184 hammer2_trans_t *trans = info->trans; 1185 hammer2_blockref_t *base; 1186 int count; 1187 1188 /* 1189 * Prefilter - Ignore children not flagged as needing a parent 1190 * blocktable update. 1191 */ 1192 if ((child->flags & HAMMER2_CHAIN_FLUSH_CREATE) == 0) 1193 return (0); 1194 1195 /* 1196 * Prefilter - Ignore children created after our flush_tid (not 1197 * visible to our flush). 1198 */ 1199 if (child->modify_tid > trans->sync_tid) { 1200 KKASSERT(child->delete_tid >= child->modify_tid); 1201 return 0; 1202 } 1203 1204 /* 1205 * Prefilter - Don't bother updating the blockrefs for a deleted 1206 * parent (from the flush's perspective). Otherwise, 1207 * we need to be COUNTEDBREFS synchronized for the 1208 * hammer2_base_*() functions. 1209 * 1210 * NOTE: This test must match the similar one in flush_core. 1211 */ 1212 if (h2ignore_deleted(info, parent)) 1213 return 0; 1214 1215 /* 1216 * Calculate blockmap pointer 1217 */ 1218 switch(parent->bref.type) { 1219 case HAMMER2_BREF_TYPE_INODE: 1220 /* 1221 * Access the inode's block array. However, there is no 1222 * block array if the inode is flagged DIRECTDATA. The 1223 * DIRECTDATA case typicaly only occurs when a hardlink has 1224 * been shifted up the tree and the original inode gets 1225 * replaced with an OBJTYPE_HARDLINK placeholding inode. 1226 */ 1227 if (parent->data && 1228 (parent->data->ipdata.op_flags & 1229 HAMMER2_OPFLAG_DIRECTDATA) == 0) { 1230 base = &parent->data->ipdata.u.blockset.blockref[0]; 1231 } else { 1232 base = NULL; 1233 } 1234 count = HAMMER2_SET_COUNT; 1235 break; 1236 case HAMMER2_BREF_TYPE_INDIRECT: 1237 case HAMMER2_BREF_TYPE_FREEMAP_NODE: 1238 if (parent->data) 1239 base = &parent->data->npdata[0]; 1240 else 1241 base = NULL; 1242 count = parent->bytes / sizeof(hammer2_blockref_t); 1243 break; 1244 case HAMMER2_BREF_TYPE_VOLUME: 1245 base = &hmp->voldata.sroot_blockset.blockref[0]; 1246 count = HAMMER2_SET_COUNT; 1247 break; 1248 case HAMMER2_BREF_TYPE_FREEMAP: 1249 base = &parent->data->npdata[0]; 1250 count = HAMMER2_SET_COUNT; 1251 break; 1252 default: 1253 base = NULL; 1254 count = 0; 1255 panic("hammer2_chain_flush_pass2: " 1256 "unrecognized blockref type: %d", 1257 parent->bref.type); 1258 } 1259 1260 /* 1261 * Insertion 1262 * - child is flagged as possibly needing block table insertion. 1263 * - child not deleted or deletion is beyond transaction id 1264 * - child created beyond parent synchronization point 1265 */ 1266 if (child->delete_tid > trans->sync_tid && 1267 child->modify_tid > parent->update_lo) { 1268 if (base) { 1269 hammer2_rollup_stats(parent, child, 1); 1270 hammer2_base_insert(trans, parent, base, count, 1271 &info->cache_index, child); 1272 } 1273 } 1274 1275 return 0; 1276 } 1277 1278 /* 1279 * PASS4 - CLEANUP CHILDREN (non-recursive, but CAN be re-entrant) 1280 * 1281 * Adjust queues and set or clear BMAPPED appropriately if processing 1282 * the live parent. 1283 * 1284 * Cleanup FLUSH_CREATE/FLUSH_DELETE on the last parent. 1285 */ 1286 static int 1287 hammer2_flush_pass4(hammer2_chain_t *child, void *data) 1288 { 1289 hammer2_flush_info_t *info = data; 1290 hammer2_chain_t *parent = info->parent; 1291 hammer2_chain_t *xchain; 1292 hammer2_chain_core_t *above = child->above; 1293 hammer2_trans_t *trans = info->trans; 1294 1295 /* 1296 * Prefilter - Ignore children created after our flush_tid (not 1297 * visible to our flush). 1298 */ 1299 if (child->modify_tid > trans->sync_tid) { 1300 KKASSERT(child->delete_tid >= child->modify_tid); 1301 return 0; 1302 } 1303 1304 /* 1305 * Ref and lock child for operation, spinlock must be temporarily 1306 * Make sure child is referenced before we unlock. 1307 */ 1308 hammer2_chain_ref(child); 1309 spin_unlock(&above->cst.spin); 1310 hammer2_chain_lock(child, HAMMER2_RESOLVE_NEVER); 1311 KKASSERT(child->above == above); 1312 KKASSERT(parent->core == above); 1313 1314 /* 1315 * Adjust BMAPPED state and rbtree/queue only when we hit the 1316 * actual live parent. 1317 */ 1318 if ((parent->flags & HAMMER2_CHAIN_DELETED) == 0) { 1319 /* 1320 * Deleting from blockmap, move child out of dbtree 1321 * and clear BMAPPED. Child should not be on RBTREE. 1322 */ 1323 spin_lock(&above->cst.spin); 1324 if (child->delete_tid <= trans->sync_tid && 1325 child->modify_tid <= parent->update_lo && 1326 child->delete_tid > parent->update_lo && 1327 (child->flags & HAMMER2_CHAIN_BMAPPED)) { 1328 KKASSERT(child->flags & HAMMER2_CHAIN_ONDBTREE); 1329 RB_REMOVE(hammer2_chain_tree, &above->dbtree, child); 1330 atomic_clear_int(&child->flags, HAMMER2_CHAIN_ONDBTREE); 1331 atomic_clear_int(&child->flags, HAMMER2_CHAIN_BMAPPED); 1332 } 1333 1334 /* 1335 * Inserting into blockmap, place child in rbtree or dbtree. 1336 */ 1337 if (child->delete_tid > trans->sync_tid && 1338 child->modify_tid > parent->update_lo && 1339 (child->flags & HAMMER2_CHAIN_BMAPPED) == 0) { 1340 if (child->flags & HAMMER2_CHAIN_ONDBQ) { 1341 TAILQ_REMOVE(&above->dbq, child, db_entry); 1342 atomic_clear_int(&child->flags, 1343 HAMMER2_CHAIN_ONDBQ); 1344 } 1345 if ((child->flags & HAMMER2_CHAIN_DELETED) == 0 && 1346 (child->flags & HAMMER2_CHAIN_ONRBTREE) == 0) { 1347 KKASSERT((child->flags & 1348 (HAMMER2_CHAIN_ONDBTREE | 1349 HAMMER2_CHAIN_ONDBQ)) == 0); 1350 xchain = RB_INSERT(hammer2_chain_tree, 1351 &above->rbtree, child); 1352 KKASSERT(xchain == NULL); 1353 atomic_set_int(&child->flags, 1354 HAMMER2_CHAIN_ONRBTREE); 1355 } else 1356 if ((child->flags & HAMMER2_CHAIN_DELETED) && 1357 (child->flags & HAMMER2_CHAIN_ONDBTREE) == 0) { 1358 KKASSERT((child->flags & 1359 (HAMMER2_CHAIN_ONRBTREE | 1360 HAMMER2_CHAIN_ONDBQ)) == 0); 1361 xchain = RB_INSERT(hammer2_chain_tree, 1362 &above->dbtree, child); 1363 KKASSERT(xchain == NULL); 1364 atomic_set_int(&child->flags, 1365 HAMMER2_CHAIN_ONDBTREE); 1366 } 1367 atomic_set_int(&child->flags, HAMMER2_CHAIN_BMAPPED); 1368 KKASSERT(child->flags & 1369 (HAMMER2_CHAIN_ONRBTREE | 1370 HAMMER2_CHAIN_ONDBTREE | 1371 HAMMER2_CHAIN_ONDBQ)); 1372 } 1373 1374 /* 1375 * Not on any list, place child on DBQ 1376 */ 1377 if ((child->flags & (HAMMER2_CHAIN_ONRBTREE | 1378 HAMMER2_CHAIN_ONDBTREE | 1379 HAMMER2_CHAIN_ONDBQ)) == 0) { 1380 KKASSERT((child->flags & HAMMER2_CHAIN_BMAPPED) == 0); 1381 TAILQ_INSERT_TAIL(&above->dbq, child, db_entry); 1382 atomic_set_int(&child->flags, HAMMER2_CHAIN_ONDBQ); 1383 } 1384 spin_unlock(&above->cst.spin); 1385 } 1386 1387 #if 0 1388 /* 1389 * Adjust queues and adjust BMAPPED on the live parent only 1390 * (there should be only one). 1391 * 1392 * First handle deletions 1393 */ 1394 if (parent->delete_tid > info->sync_tid && 1395 child->delete_tid <= trans->sync_tid && 1396 child->modify_tid <= parent->update_lo && 1397 child->delete_tid > parent->update_lo) { 1398 KKASSERT(child->flags & HAMMER2_CHAIN_FLUSH_DELETE); 1399 if (child->flags & HAMMER2_CHAIN_ONDBTREE) { 1400 KKASSERT(child->flags & HAMMER2_CHAIN_FLUSH_DELETE); 1401 KKASSERT(child->flags & HAMMER2_CHAIN_BMAPPED); 1402 spin_lock(&above->cst.spin); 1403 RB_REMOVE(hammer2_chain_tree, &above->dbtree, child); 1404 atomic_clear_int(&child->flags, HAMMER2_CHAIN_ONDBTREE); 1405 atomic_clear_int(&child->flags, HAMMER2_CHAIN_BMAPPED); 1406 TAILQ_INSERT_TAIL(&above->dbq, child, db_entry); 1407 atomic_set_int(&child->flags, HAMMER2_CHAIN_ONDBQ); 1408 spin_unlock(&above->cst.spin); 1409 } else { 1410 KKASSERT(child->flags & HAMMER2_CHAIN_ONDBQ); 1411 } 1412 } 1413 1414 /* 1415 * Adjust child state when updating a live parent. 1416 * Adjust child state on the last parent. 1417 */ 1418 if (parent->delete_tid > info->sync_tid && 1419 child->delete_tid > trans->sync_tid && 1420 child->modify_tid > parent->update_lo) { 1421 /* 1422 * NOTE: FLUSH_CREATE may have already been cleared and 1423 * BMAPPED may have already been set due to 1424 * reentrancy due to the queue movement below. 1425 */ 1426 atomic_set_int(&child->flags, HAMMER2_CHAIN_BMAPPED); 1427 1428 if ((child->flags & HAMMER2_CHAIN_DELETED) && 1429 (child->flags & HAMMER2_CHAIN_ONDBQ)) { 1430 /* 1431 * A deleted child that is on DBQ which has been 1432 * inserted must be moved to DBTREE. However, 1433 * temporary deleted children are only applicable to 1434 * the current flush and must not have any visibility 1435 * beyond it, so temporary children are left on DBQ. 1436 * 1437 * We run DBQ before DBTREE so this can cause pass4 1438 * to be called twice on this child. 1439 */ 1440 KKASSERT((child->flags & HAMMER2_CHAIN_ONRBTREE) == 0); 1441 if ((child->flags & (HAMMER2_CHAIN_ONDBQ | 1442 HAMMER2_CHAIN_FLUSH_TEMPORARY)) == 1443 HAMMER2_CHAIN_ONDBQ) { 1444 spin_lock(&above->cst.spin); 1445 1446 KKASSERT(child->flags & 1447 HAMMER2_CHAIN_FLUSH_CREATE); 1448 TAILQ_REMOVE(&above->dbq, child, db_entry); 1449 atomic_clear_int(&child->flags, 1450 HAMMER2_CHAIN_ONDBQ); 1451 xchain = RB_INSERT(hammer2_chain_tree, 1452 &above->dbtree, child); 1453 KASSERT(xchain == NULL, ("pass4: collision with %p moving %p to dbtree", xchain, child)); 1454 atomic_set_int(&child->flags, 1455 HAMMER2_CHAIN_ONDBTREE); 1456 spin_unlock(&above->cst.spin); 1457 } 1458 } else if (child->flags & HAMMER2_CHAIN_DELETED) { 1459 KKASSERT(child->flags & HAMMER2_CHAIN_ONDBTREE); 1460 } else { 1461 /* 1462 * If the child is not deleted it must be on 1463 * the rbtree. 1464 */ 1465 KKASSERT(child->flags & HAMMER2_CHAIN_ONRBTREE); 1466 } 1467 } 1468 #endif 1469 1470 /* 1471 * Cleanup flags on last parent iterated for flush. 1472 */ 1473 if (info->domodify & 2) { 1474 if (child->flags & HAMMER2_CHAIN_FLUSH_CREATE) { 1475 atomic_clear_int(&child->flags, 1476 HAMMER2_CHAIN_FLUSH_CREATE); 1477 hammer2_chain_drop(child); 1478 } 1479 if ((child->flags & HAMMER2_CHAIN_FLUSH_DELETE) && 1480 child->delete_tid <= trans->sync_tid) { 1481 KKASSERT((child->flags & HAMMER2_CHAIN_ONDBTREE) == 0); 1482 KKASSERT((child->flags & HAMMER2_CHAIN_BMAPPED) == 0); 1483 atomic_clear_int(&child->flags, 1484 HAMMER2_CHAIN_FLUSH_DELETE); 1485 hammer2_chain_drop(child); 1486 } 1487 } 1488 1489 /* 1490 * Unlock the child. This can wind up dropping the child's 1491 * last ref, removing it from the parent's RB tree, and deallocating 1492 * the structure. The RB_SCAN() our caller is doing handles the 1493 * situation. 1494 */ 1495 hammer2_chain_unlock(child); 1496 hammer2_chain_drop(child); 1497 spin_lock(&above->cst.spin); 1498 1499 /* 1500 * The parent may have been delete-duplicated. 1501 */ 1502 return (0); 1503 } 1504 1505 void 1506 hammer2_rollup_stats(hammer2_chain_t *parent, hammer2_chain_t *child, int how) 1507 { 1508 #if 0 1509 hammer2_chain_t *grandp; 1510 #endif 1511 1512 parent->data_count += child->data_count; 1513 parent->inode_count += child->inode_count; 1514 child->data_count = 0; 1515 child->inode_count = 0; 1516 if (how < 0) { 1517 parent->data_count -= child->bytes; 1518 if (child->bref.type == HAMMER2_BREF_TYPE_INODE) { 1519 parent->inode_count -= 1; 1520 #if 0 1521 /* XXX child->data may be NULL atm */ 1522 parent->data_count -= child->data->ipdata.data_count; 1523 parent->inode_count -= child->data->ipdata.inode_count; 1524 #endif 1525 } 1526 } else if (how > 0) { 1527 parent->data_count += child->bytes; 1528 if (child->bref.type == HAMMER2_BREF_TYPE_INODE) { 1529 parent->inode_count += 1; 1530 #if 0 1531 /* XXX child->data may be NULL atm */ 1532 parent->data_count += child->data->ipdata.data_count; 1533 parent->inode_count += child->data->ipdata.inode_count; 1534 #endif 1535 } 1536 } 1537 if (parent->bref.type == HAMMER2_BREF_TYPE_INODE) { 1538 parent->data->ipdata.data_count += parent->data_count; 1539 parent->data->ipdata.inode_count += parent->inode_count; 1540 #if 0 1541 for (grandp = parent->above->first_parent; 1542 grandp; 1543 grandp = grandp->next_parent) { 1544 grandp->data_count += parent->data_count; 1545 grandp->inode_count += parent->inode_count; 1546 } 1547 #endif 1548 parent->data_count = 0; 1549 parent->inode_count = 0; 1550 } 1551 } 1552