2 * Copyright (c) 2011-2014 The DragonFly Project. All rights reserved.
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>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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
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.
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
36 #include <sys/cdefs.h>
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/types.h>
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
54 struct hammer2_flush_info {
55 hammer2_chain_t *parent;
56 hammer2_trans_t *trans;
61 struct h2_flush_deferral_list flush_list;
62 hammer2_tid_t sync_tid; /* flush synchronization point */
65 typedef struct hammer2_flush_info hammer2_flush_info_t;
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 int hammer2_flush_pass5(hammer2_chain_t *child, void *data);
74 static void hammer2_rollup_stats(hammer2_chain_t *parent,
75 hammer2_chain_t *child, int how);
79 * Can we ignore a chain for the purposes of flushing modifications
82 * This code is now degenerate. We used to have to distinguish between
83 * deleted chains and deleted chains associated with inodes that were
84 * still open. This mechanic has been fixed so the function is now
89 h2ignore_deleted(hammer2_flush_info_t *info, hammer2_chain_t *chain)
91 return (chain->delete_tid <= info->sync_tid);
97 hammer2_updatestats(hammer2_flush_info_t *info, hammer2_blockref_t *bref,
102 if (bref->type != 0) {
103 bytes = 1 << (bref->data_off & HAMMER2_OFF_MASK_RADIX);
104 if (bref->type == HAMMER2_BREF_TYPE_INODE)
105 info->inode_count += how;
107 info->data_count -= bytes;
109 info->data_count += bytes;
115 * Transaction support functions for writing to the filesystem.
117 * Initializing a new transaction allocates a transaction ID. Typically
118 * passed a pmp (hmp passed as NULL), indicating a cluster transaction. Can
119 * be passed a NULL pmp and non-NULL hmp to indicate a transaction on a single
120 * media target. The latter mode is used by the recovery code.
122 * TWO TRANSACTION IDs can run concurrently, where one is a flush and the
123 * other is a set of any number of concurrent filesystem operations. We
124 * can either have <running_fs_ops> + <waiting_flush> + <blocked_fs_ops>
125 * or we can have <running_flush> + <concurrent_fs_ops>.
127 * During a flush, new fs_ops are only blocked until the fs_ops prior to
128 * the flush complete. The new fs_ops can then run concurrent with the flush.
130 * Buffer-cache transactions operate as fs_ops but never block. A
131 * buffer-cache flush will run either before or after the current pending
132 * flush depending on its state.
134 * NOTE: The sync_tid for a flush's freemap allocation will match the
135 * sync_tid of the following <concurrent_fs_ops> transaction(s).
136 * The freemap topology will be out-of-step by one transaction id
137 * in order to give the flusher a stable freemap topology to flush
138 * out. This is fixed up at mount-time using a quick incremental
142 hammer2_trans_init(hammer2_trans_t *trans, hammer2_pfsmount_t *pmp,
143 hammer2_mount_t *hmp, int flags)
145 hammer2_trans_t *head;
147 bzero(trans, sizeof(*trans));
150 KKASSERT(hmp == NULL);
151 hmp = pmp->cluster.focus->hmp; /* XXX */
153 trans->hmp_single = hmp;
157 hammer2_voldata_lock(hmp);
158 trans->flags = flags;
159 trans->td = curthread;
160 /*trans->delete_gen = 0;*/ /* multiple deletions within trans */
162 if (flags & HAMMER2_TRANS_ISFLUSH) {
164 * If multiple flushes are trying to run we have to
165 * wait until it is our turn. All flushes are serialized.
167 * We queue ourselves and then wait to become the head
168 * of the queue, allowing all prior flushes to complete.
170 * Multiple normal transactions can share the current
171 * transaction id but a flush transaction needs its own
172 * unique TID for proper block table update accounting.
175 ++hmp->voldata.alloc_tid;
176 trans->sync_tid = hmp->voldata.alloc_tid;
177 trans->orig_tid = trans->sync_tid;
178 ++hmp->voldata.alloc_tid;
179 TAILQ_INSERT_TAIL(&hmp->transq, trans, entry);
180 if (TAILQ_FIRST(&hmp->transq) != trans) {
182 while (trans->blocked) {
183 lksleep(&trans->sync_tid, &hmp->voldatalk,
187 } else if (hmp->flushcnt == 0) {
189 * No flushes are pending, we can go.
191 TAILQ_INSERT_TAIL(&hmp->transq, trans, entry);
192 trans->sync_tid = hmp->voldata.alloc_tid;
193 trans->orig_tid = trans->sync_tid;
195 /* XXX improve/optimize inode allocation */
196 } else if (trans->flags & HAMMER2_TRANS_BUFCACHE) {
198 * A buffer cache transaction is requested while a flush
199 * is in progress. The flush's PREFLUSH flag must be set
202 * The buffer cache flush takes on the main flush's
205 TAILQ_FOREACH(head, &hmp->transq, entry) {
206 if (head->flags & HAMMER2_TRANS_ISFLUSH)
210 KKASSERT(head->flags & HAMMER2_TRANS_PREFLUSH);
211 trans->flags |= HAMMER2_TRANS_PREFLUSH;
212 TAILQ_INSERT_AFTER(&hmp->transq, head, trans, entry);
213 trans->sync_tid = head->orig_tid;
214 trans->orig_tid = trans->sync_tid;
215 trans->flags |= HAMMER2_TRANS_CONCURRENT;
216 /* not allowed to block */
219 * A normal transaction is requested while a flush is in
220 * progress. We insert after the current flush and may
221 * block. Assign sync_tid = flush's tid + 1.
223 TAILQ_FOREACH(head, &hmp->transq, entry) {
224 if (head->flags & HAMMER2_TRANS_ISFLUSH)
228 TAILQ_INSERT_AFTER(&hmp->transq, head, trans, entry);
229 trans->sync_tid = head->orig_tid + 1;
230 trans->orig_tid = trans->sync_tid;
231 trans->flags |= HAMMER2_TRANS_CONCURRENT;
234 * XXX for now we must block new transactions, synchronous
235 * flush mode is on by default.
237 * If synchronous flush mode is enabled concurrent
238 * frontend transactions during the flush are not
239 * allowed (except we don't have a choice for buffer
242 if (hammer2_synchronous_flush > 0 ||
243 TAILQ_FIRST(&hmp->transq) != head) {
245 while (trans->blocked) {
246 lksleep(&trans->sync_tid,
252 if (flags & HAMMER2_TRANS_NEWINODE) {
253 if (hmp->voldata.inode_tid < HAMMER2_INODE_START)
254 hmp->voldata.inode_tid = HAMMER2_INODE_START;
255 trans->inode_tid = hmp->voldata.inode_tid++;
257 hammer2_voldata_unlock(hmp, 0);
261 hammer2_trans_done(hammer2_trans_t *trans)
263 hammer2_mount_t *hmp;
264 hammer2_trans_t *head;
265 hammer2_trans_t *scan;
268 hmp = trans->pmp->cluster.focus->hmp;
270 hmp = trans->hmp_single;
275 hammer2_voldata_lock(hmp);
276 TAILQ_REMOVE(&hmp->transq, trans, entry);
277 head = TAILQ_FIRST(&hmp->transq);
280 * Adjust flushcnt if this was a flush, clear TRANS_CONCURRENT
281 * up through the next flush. (If the head is a flush then we
282 * stop there, unlike the unblock code following this section).
284 if (trans->flags & HAMMER2_TRANS_ISFLUSH) {
287 while (scan && (scan->flags & HAMMER2_TRANS_ISFLUSH) == 0) {
288 atomic_clear_int(&scan->flags,
289 HAMMER2_TRANS_CONCURRENT);
290 scan = TAILQ_NEXT(scan, entry);
295 * Unblock the head of the queue and any additional transactions
296 * up to the next flush. The head can be a flush and it will be
297 * unblocked along with the non-flush transactions following it
298 * (which are allowed to run concurrently with it).
300 * In synchronous flush mode we stop if the head transaction is
303 if (head && head->blocked) {
305 wakeup(&head->sync_tid);
307 if (hammer2_synchronous_flush > 0)
310 scan = TAILQ_NEXT(head, entry);
311 while (scan && (scan->flags & HAMMER2_TRANS_ISFLUSH) == 0) {
314 wakeup(&scan->sync_tid);
316 scan = TAILQ_NEXT(scan, entry);
319 hammer2_voldata_unlock(hmp, 0);
323 * Flush the chain and all modified sub-chains through the specified
324 * synchronization point (sync_tid), propagating parent chain modifications
325 * and mirror_tid updates back up as needed. Since we are recursing downward
326 * we do not have to deal with the complexities of multi-homed chains (chains
327 * with multiple parents).
329 * Caller must have interlocked against any non-flush-related modifying
330 * operations in progress whos modify_tid values are less than or equal
331 * to the passed sync_tid.
333 * Caller must have already vetted synchronization points to ensure they
334 * are properly flushed. Only snapshots and cluster flushes can create
335 * these sorts of synchronization points.
337 * This routine can be called from several places but the most important
340 * chain is locked on call and will remain locked on return. If a flush
341 * occured, the chain's FLUSH_CREATE and/or FLUSH_DELETE bit will be set
342 * indicating that its parent (which is not part of the flush) should be
343 * updated. The chain may be replaced by the call if it was modified.
346 hammer2_flush(hammer2_trans_t *trans, hammer2_chain_t **chainp)
348 hammer2_chain_t *chain = *chainp;
349 hammer2_chain_t *scan;
350 hammer2_chain_core_t *core;
351 hammer2_flush_info_t info;
355 * Execute the recursive flush and handle deferrals.
357 * Chains can be ridiculously long (thousands deep), so to
358 * avoid blowing out the kernel stack the recursive flush has a
359 * depth limit. Elements at the limit are placed on a list
360 * for re-execution after the stack has been popped.
362 bzero(&info, sizeof(info));
363 TAILQ_INIT(&info.flush_list);
365 info.sync_tid = trans->sync_tid;
366 info.cache_index = -1;
371 * Extra ref needed because flush_core expects it when replacing
374 hammer2_chain_ref(chain);
379 * Unwind deep recursions which had been deferred. This
380 * can leave the FLUSH_* bits set for these chains, which
381 * will be handled when we [re]flush chain after the unwind.
383 while ((scan = TAILQ_FIRST(&info.flush_list)) != NULL) {
384 KKASSERT(scan->flags & HAMMER2_CHAIN_DEFERRED);
385 TAILQ_REMOVE(&info.flush_list, scan, flush_node);
386 atomic_clear_int(&scan->flags, HAMMER2_CHAIN_DEFERRED);
389 * Now that we've popped back up we can do a secondary
390 * recursion on the deferred elements.
392 * NOTE: hammer2_flush() may replace scan.
394 if (hammer2_debug & 0x0040)
395 kprintf("deferred flush %p\n", scan);
396 hammer2_chain_lock(scan, HAMMER2_RESOLVE_MAYBE);
397 hammer2_chain_drop(scan); /* ref from deferral */
398 hammer2_flush(trans, &scan);
399 hammer2_chain_unlock(scan);
405 info.diddeferral = 0;
406 hammer2_flush_core(&info, &chain, 0);
409 * Only loop if deep recursions have been deferred.
411 if (TAILQ_EMPTY(&info.flush_list))
414 if (++loops % 1000 == 0) {
415 kprintf("hammer2_flush: excessive loops on %p\n",
417 if (hammer2_debug & 0x100000)
421 hammer2_chain_drop(chain);
426 * This is the core of the chain flushing code. The chain is locked by the
427 * caller and must also have an extra ref on it by the caller, and remains
428 * locked and will have an extra ref on return. Upon return, the caller can
429 * test the FLUSH_CREATE and FLUSH_DELETE bits to determine what action must
430 * be taken on the parent.
432 * (1) Determine if this node is a candidate for the flush, return if it is
433 * not. fchain and vchain are always candidates for the flush.
435 * (2) If we recurse too deep the chain is entered onto the deferral list and
436 * the current flush stack is aborted until after the deferral list is
439 * (3) Recursively flush live children (rbtree). This can create deferrals.
440 * A successful flush clears the MODIFIED bit in the children.
442 * (4) Recursively flush deleted children (dbtree). Deletions may be
443 * considered 'live' if the delete_tid is beyond the flush_tid. If
444 * considered 'dead' the recursion is still needed in order to clean
445 * up the chain. This can create deferrals.
447 * A successful flush clears the MODIFIED bit in the children.
449 * (5) Calculate block table updates on chain based on the children scans
450 * in (3) and (4) by testing the FLUSH_CREATE and FLUSH_DELETE bits,
451 * modifying chain if necessary to perform the block table updates.
452 * Deletions must be removed from dbtree when removed from the
453 * chain's block table.
455 * If 'chain' itself is marked DELETED but treated as live, the block
456 * table update(s) must be propagated to all contemporary chains. In
457 * fact, all contemporary chains must be locked and updated uninterrupted
458 * to avoid lookup races. Once MODIFIED and FLUSH_CREATE is cleared,
459 * a chain can be unloaded from memory with the expectation that it can
460 * be reloaded later via the block table at any time.
462 * NOTE: chain->bref.modify_tid is different from chain->modify_tid. COW
463 * propagations for block updates do not update chain->bref.modify_tid,
464 * only chain->bref.mirror_tid. The MODIFIED bit is set on any
465 * modified chain, including COW propagations, but the flusher normally
466 * just keys off of the FLUSH_* bits. FLUSH_CREATE will also be set
469 * NOTE: We are responsible for updating chain->bref.mirror_tid and
470 * chain->update_lo. The caller is responsible for processing us into
471 * our parent (if any).
474 hammer2_flush_core(hammer2_flush_info_t *info, hammer2_chain_t **chainp,
477 hammer2_chain_t *chain = *chainp;
478 hammer2_chain_t *saved_parent;
479 hammer2_mount_t *hmp;
480 hammer2_chain_core_t *core;
486 diddeferral = info->diddeferral;
489 * (1) Check if we even have any work to do.
491 * This bit of code is capable of short-cutting entire sub-trees
492 * if they have not been touched or if they have already been
495 if (/*(chain->flags & HAMMER2_CHAIN_MODIFIED) == 0 &&*/
496 (chain->update_lo >= info->sync_tid || /* already synced */
497 chain->update_lo >= chain->update_hi)) { /* old/unchanged */
498 /* update_lo/_hi already filters chain out, do not update */
499 /* don't update bref.mirror_tid, pass2 is not called */
504 * mirror_tid should not be forward-indexed
506 KKASSERT(chain->bref.mirror_tid <= info->sync_tid);
509 * Ignore chains modified beyond the current flush point. These
510 * will be treated as if they did not exist. Subchains with lower
511 * modify_tid's will still be accessible via other parents.
513 * Do not update bref.mirror_tid here, it will interfere with
514 * synchronization. e.g. inode flush tid 1, concurrent D-D tid 2,
515 * then later on inode flush tid 2. If we were to set mirror_tid
516 * to 1 during inode flush tid 1 the blockrefs would only be partially
517 * updated (and likely panic).
519 * We must update chain->update_lo here to prevent re-entry in this
522 * (vchain and fchain are exceptions since they cannot be duplicated)
524 if (chain->modify_tid > info->sync_tid &&
525 chain != &hmp->fchain && chain != &hmp->vchain) {
526 /* do not update bref.mirror_tid, pass2 ignores chain */
527 /* chain->update_lo = info->sync_tid; */
532 * (2) Recurse downward and check recursion depth.
533 * (3) Flush live children
534 * (4) Flush deleted children
536 * We adjust update_lo if not deferring chain to prevent re-entry
537 * in this flush cycle, but it must be set AFTER the flush in case
538 * a deeper flush hits the chain. Otherwise the deeper flush cannot
539 * complete. We re-check the condition after finishing the flushes.
541 * update_hi was already checked and prevents initial recursions on
542 * subtrees which have not been modified.
544 saved_parent = info->parent;
545 saved_domodify = info->domodify;
546 info->parent = chain;
549 if (chain->flags & HAMMER2_CHAIN_DEFERRED) {
551 } else if (info->depth == HAMMER2_FLUSH_DEPTH_LIMIT) {
552 if ((chain->flags & HAMMER2_CHAIN_DEFERRED) == 0) {
553 hammer2_chain_ref(chain);
554 TAILQ_INSERT_TAIL(&info->flush_list,
556 atomic_set_int(&chain->flags,
557 HAMMER2_CHAIN_DEFERRED);
561 hammer2_chain_t *scan;
564 * The flush is queue-agnostic when running pass1, but order
565 * is important to catch any races where an existing
566 * flush-visible child is moved from rbtree->dbtree/dbq.
568 * New children added by concurrent operations are not visible
569 * to the flush anyway so we don't care about those races.
570 * However, the flush itself can move a child from dbq to
571 * dbtree (rare in pass1 but it is possible).
573 * pass1 can handle re-execution of a child.
575 spin_lock(&core->cst.spin);
576 KKASSERT(core->good == 0x1234 && core->sharecnt > 0);
577 RB_SCAN(hammer2_chain_tree, &core->rbtree,
578 NULL, hammer2_flush_pass1, info);
579 RB_SCAN(hammer2_chain_tree, &core->dbtree,
580 NULL, hammer2_flush_pass1, info);
581 scan = TAILQ_FIRST(&core->dbq);
583 KKASSERT(scan->flags & HAMMER2_CHAIN_ONDBQ);
584 hammer2_flush_pass1(scan, info);
585 if (scan->flags & HAMMER2_CHAIN_ONDBQ)
586 scan = TAILQ_NEXT(scan, db_entry);
588 scan = TAILQ_FIRST(&core->dbq);
590 spin_unlock(&core->cst.spin);
594 * Stop if deferred, do not update update_lo.
596 if (info->diddeferral)
600 * If a block table update is needed place the parent in a modified
601 * state, which might delete-duplicate it.
603 * - To prevent loops and other confusion, we synchronize update_lo
604 * for the original chain.
606 * - The original parent will not be used by the flush so we can
607 * clear its MODIFIED bit.
609 if (info->domodify) {
610 hammer2_chain_modify(info->trans, &info->parent,
611 HAMMER2_MODIFY_NO_MODIFY_TID);
612 if (info->parent != chain) {
617 * NOTE: bref.mirror_tid cannot be updated
618 * unless MODIFIED is cleared or already
621 chain->inode_reason += 0x10000000;
622 info->parent->inode_reason += 0x100;
623 KKASSERT(info->parent->core == chain->core);
624 if (chain->flags & HAMMER2_CHAIN_MODIFIED) {
625 atomic_clear_int(&chain->flags,
626 HAMMER2_CHAIN_MODIFIED);
627 hammer2_pfs_memory_wakeup(chain->pmp);
628 hammer2_chain_drop(chain);
631 if (chain->flags & HAMMER2_CHAIN_FLUSH_CREATE) {
632 atomic_clear_int(&chain->flags,
633 HAMMER2_CHAIN_FLUSH_CREATE);
634 hammer2_chain_drop(chain);
636 if (info->parent->flags & HAMMER2_CHAIN_FLUSH_DELETE) {
637 atomic_clear_int(&info->parent->flags,
638 HAMMER2_CHAIN_FLUSH_DELETE);
639 hammer2_chain_drop(info->parent);
643 if (chain->bref.mirror_tid < info->sync_tid)
644 chain->bref.mirror_tid = info->sync_tid;
646 if (chain->update_lo < info->sync_tid)
647 chain->update_lo = info->sync_tid;
648 KKASSERT(info->parent->update_lo < info->sync_tid);
649 hammer2_chain_drop(chain);
650 hammer2_chain_ref(info->parent);
652 chain = info->parent;
656 * If a blocktable update is needed determine if this is the last
657 * parent requiring modification (check all parents using the core).
659 * Set bit 1 (0x02) of domodify if this is the last parent,
660 * which will cause scan2 to clear FLUSH_CREATE and FLUSH_DELETE.
663 hammer2_chain_t *scan;
665 spin_lock(&core->cst.spin);
666 TAILQ_FOREACH(scan, &core->ownerq, core_entry) {
668 * Ignore chains which have already been updated
669 * Ignore unmodified chains
671 if ((scan->flags & HAMMER2_CHAIN_MODIFIED) == 0 &&
672 (scan->update_lo >= info->sync_tid ||
673 scan->update_lo >= scan->update_hi)) {
678 * Ignore the current parent being processed (we do
679 * not adjust update_lo until after the fixup).
685 * Cannot exhaust all parents if one is not visible
686 * to the flush. The root chains are special-cased
687 * because they cannot really be delete-duplicated.
689 if (scan != &scan->hmp->fchain &&
690 scan != &scan->hmp->vchain &&
691 scan->modify_tid > info->sync_tid) {
696 * Fail if update_lo has not been synchronized to
697 * at least our sync_tid on any modified parent chain.
699 if (scan->update_lo < info->sync_tid)
702 spin_unlock(&core->cst.spin);
708 * (5) Calculate block table updates or child cleanups.
709 * (this whole operation has to be atomic)
711 * domodify 0x01 - block table updates
712 * 0x02 - child cleanups
714 * pass2 - Process deletions from dbtree and dbq.
715 * pass3 - Process insertions from rbtree, dbtree, and dbq.
716 * pass4 - Cleanup child flags on the last parent and
717 * Adjust queues on the live parent (deletions).
718 * pass5 - Cleanup child flags on the last parent and
719 * Adjust queues on the live parent (insertions).
721 * Queue adjustments had to be separated into deletions and
722 * insertions because both can occur on dbtree.
724 if (info->domodify) {
725 hammer2_chain_t *scan;
727 spin_lock(&core->cst.spin);
729 while ((info->domodify & 1) && info->parent) {
730 /* PASS2 - Deletions */
731 RB_SCAN(hammer2_chain_tree, &core->rbtree,
732 NULL, hammer2_flush_pass2, info);
733 RB_SCAN(hammer2_chain_tree, &core->dbtree,
734 NULL, hammer2_flush_pass2, info);
735 scan = TAILQ_FIRST(&core->dbq);
736 TAILQ_FOREACH(scan, &core->dbq, db_entry) {
737 KKASSERT(scan->flags & HAMMER2_CHAIN_ONDBQ);
738 hammer2_flush_pass2(scan, info);
741 /* PASS3 - Insertions */
742 RB_SCAN(hammer2_chain_tree, &core->rbtree,
743 NULL, hammer2_flush_pass3, info);
744 RB_SCAN(hammer2_chain_tree, &core->dbtree,
745 NULL, hammer2_flush_pass3, info);
746 TAILQ_FOREACH(scan, &core->dbq, db_entry) {
747 KKASSERT(scan->flags & HAMMER2_CHAIN_ONDBQ);
748 hammer2_flush_pass3(scan, info);
750 info->parent = TAILQ_NEXT(info->parent, core_entry);
752 kprintf("FLUSH SPECIAL UPDATE (%p) %p.%d %08x\n",
754 info->parent->bref.type,
755 info->parent->flags);
757 info->parent = chain;
759 /* PASS4 - Cleanup */
760 RB_SCAN(hammer2_chain_tree, &core->rbtree,
761 NULL, hammer2_flush_pass4, info);
762 scan = TAILQ_FIRST(&core->dbq);
764 KKASSERT(scan->flags & HAMMER2_CHAIN_ONDBQ);
765 hammer2_flush_pass4(scan, info);
766 if (scan->flags & HAMMER2_CHAIN_ONDBQ)
767 scan = TAILQ_NEXT(scan, db_entry);
769 scan = TAILQ_FIRST(&core->dbq);
771 RB_SCAN(hammer2_chain_tree, &core->dbtree,
772 NULL, hammer2_flush_pass4, info);
774 /* PASS5 - Cleanup */
775 RB_SCAN(hammer2_chain_tree, &core->rbtree,
776 NULL, hammer2_flush_pass5, info);
777 scan = TAILQ_FIRST(&core->dbq);
779 KKASSERT(scan->flags & HAMMER2_CHAIN_ONDBQ);
780 hammer2_flush_pass5(scan, info);
781 if (scan->flags & HAMMER2_CHAIN_ONDBQ)
782 scan = TAILQ_NEXT(scan, db_entry);
784 scan = TAILQ_FIRST(&core->dbq);
786 RB_SCAN(hammer2_chain_tree, &core->dbtree,
787 NULL, hammer2_flush_pass5, info);
789 spin_unlock(&core->cst.spin);
793 * Synchronize update_lo to prevent reentrant block updates of this
796 chain->update_lo = info->sync_tid;
799 * Skip the flush if the chain was not placed in a modified state
800 * or was not already in a modified state.
802 if ((chain->flags & HAMMER2_CHAIN_MODIFIED) == 0)
806 * FLUSH THE CHAIN (on the way back up the recursion)
808 * Chain is now deterministically being flushed and not being deferred.
809 * We've finished running the recursion and the blockref update.
811 * update bref.mirror_tid. update_lo has already been updated.
813 if (chain->bref.mirror_tid < info->sync_tid)
814 chain->bref.mirror_tid = info->sync_tid;
817 * Dispose of the modified bit. FLUSH_CREATE should already be
820 KKASSERT(chain->flags & HAMMER2_CHAIN_FLUSH_CREATE);
821 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
822 hammer2_pfs_memory_wakeup(chain->pmp);
824 if ((chain->flags & HAMMER2_CHAIN_FLUSH_CREATE) ||
825 chain == &hmp->vchain ||
826 chain == &hmp->fchain) {
828 * Drop the ref from the MODIFIED bit we cleared,
831 hammer2_chain_drop(chain);
834 * Drop the ref from the MODIFIED bit we cleared and
835 * set a ref for the FLUSH_CREATE bit we are setting.
838 atomic_set_int(&chain->flags, HAMMER2_CHAIN_FLUSH_CREATE);
842 * Skip the actual flush operation if the chain has been deleted
843 * in our flus hview. There will be no block table entry that
846 if (h2ignore_deleted(info, chain))
852 * A DELETED node that reaches this point must be flushed for
853 * synchronization point consistency.
855 * Update bref.mirror_tid, clear MODIFIED, and set MOVED.
857 * The caller will update the parent's reference to this chain
858 * by testing MOVED as long as the modification was in-bounds.
860 * MOVED is never set on the volume root as there is no parent
863 if (hammer2_debug & 0x1000) {
864 kprintf("Flush %p.%d %016jx/%d sync_tid=%016jx data=%016jx\n",
865 chain, chain->bref.type,
866 chain->bref.key, chain->bref.keybits,
867 info->sync_tid, chain->bref.data_off);
869 if (hammer2_debug & 0x2000) {
870 Debugger("Flush hell");
874 * If this is part of a recursive flush we can go ahead and write
875 * out the buffer cache buffer and pass a new bref back up the chain
878 * Volume headers are NOT flushed here as they require special
881 switch(chain->bref.type) {
882 case HAMMER2_BREF_TYPE_FREEMAP:
883 hammer2_modify_volume(hmp);
884 hmp->voldata.freemap_tid = hmp->fchain.bref.mirror_tid;
886 case HAMMER2_BREF_TYPE_VOLUME:
888 * The free block table is flushed by hammer2_vfs_sync()
889 * before it flushes vchain. We must still hold fchain
890 * locked while copying voldata to volsync, however.
892 hammer2_chain_lock(&hmp->fchain, HAMMER2_RESOLVE_ALWAYS);
894 if ((hmp->fchain.flags & HAMMER2_CHAIN_MODIFIED) ||
895 hmp->voldata.freemap_tid < info->trans->sync_tid) {
896 /* this will modify vchain as a side effect */
897 hammer2_chain_t *tmp = &hmp->fchain;
898 hammer2_chain_flush(info->trans, &tmp);
899 KKASSERT(tmp == &hmp->fchain);
904 * There is no parent to our root vchain and fchain to
905 * synchronize the bref to, their updated mirror_tid's
906 * must be synchronized to the volume header.
908 hmp->voldata.mirror_tid = chain->bref.mirror_tid;
909 /*hmp->voldata.freemap_tid = hmp->fchain.bref.mirror_tid;*/
912 * The volume header is flushed manually by the syncer, not
913 * here. All we do here is adjust the crc's.
915 KKASSERT(chain->data != NULL);
916 KKASSERT(chain->dio == NULL);
918 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT1]=
920 (char *)&hmp->voldata +
921 HAMMER2_VOLUME_ICRC1_OFF,
922 HAMMER2_VOLUME_ICRC1_SIZE);
923 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT0]=
925 (char *)&hmp->voldata +
926 HAMMER2_VOLUME_ICRC0_OFF,
927 HAMMER2_VOLUME_ICRC0_SIZE);
928 hmp->voldata.icrc_volheader =
930 (char *)&hmp->voldata +
931 HAMMER2_VOLUME_ICRCVH_OFF,
932 HAMMER2_VOLUME_ICRCVH_SIZE);
933 hmp->volsync = hmp->voldata;
934 atomic_set_int(&chain->flags, HAMMER2_CHAIN_VOLUMESYNC);
935 hammer2_chain_unlock(&hmp->fchain);
937 case HAMMER2_BREF_TYPE_DATA:
939 * Data elements have already been flushed via the logical
940 * file buffer cache. Their hash was set in the bref by
941 * the vop_write code.
943 * Make sure any device buffer(s) have been flushed out here.
944 * (there aren't usually any to flush).
948 case HAMMER2_BREF_TYPE_INDIRECT:
950 * Indirect blocks may be in an INITIAL state. Use the
951 * chain_lock() call to ensure that the buffer has been
952 * instantiated (even though it is already locked the buffer
953 * might not have been instantiated).
955 * Only write the buffer out if it is dirty, it is possible
956 * the operating system had already written out the buffer.
958 hammer2_chain_lock(chain, HAMMER2_RESOLVE_ALWAYS);
959 KKASSERT(chain->dio != NULL);
962 hammer2_io_bqrelse(&chain->dio);
963 hammer2_chain_unlock(chain);
966 case HAMMER2_BREF_TYPE_INDIRECT:
967 case HAMMER2_BREF_TYPE_FREEMAP_NODE:
968 case HAMMER2_BREF_TYPE_FREEMAP_LEAF:
969 case HAMMER2_BREF_TYPE_INODE:
971 * Device-backed. Buffer will be flushed by the sync
974 KKASSERT((chain->flags & HAMMER2_CHAIN_EMBEDDED) == 0);
977 KKASSERT(chain->flags & HAMMER2_CHAIN_EMBEDDED);
978 panic("hammer2_chain_flush_core: unsupported embedded bref %d",
984 * Final cleanup after flush
987 KKASSERT(chain->refs > 1);
988 info->domodify = saved_domodify;
989 info->parent = saved_parent;
992 KKASSERT(chain->bref.mirror_tid <= info->sync_tid);
996 * Flush helper pass1 (recursive)
998 * Flushes the children of the caller's chain (info->parent), restricted
999 * by sync_tid. Set info->domodify if the child's blockref must propagate
1000 * back up to the parent.
1002 * Ripouts can move child from rbtree to dbtree or dbq but the caller's
1003 * flush scan order prevents any chains from being lost. A child can be
1004 * executes more than once (update_lo is used to prevent infinite recursions).
1006 * WARNING! If we do not call hammer2_flush_core() we must update
1007 * bref.mirror_tid ourselves to indicate that the flush has
1008 * processed the child.
1010 * WARNING! parent->core spinlock is held on entry and return.
1013 hammer2_flush_pass1(hammer2_chain_t *child, void *data)
1015 hammer2_flush_info_t *info = data;
1016 hammer2_trans_t *trans = info->trans;
1017 hammer2_chain_t *parent = info->parent;
1020 * Child modified in a later transactions, nothing to flush in this
1023 * Remember that modifications generally delete-duplicate so if the
1024 * sub-tree is dirty another child will get us there. But not this
1027 * (child can never be fchain or vchain so a special check isn't
1030 if (child->modify_tid > trans->sync_tid) {
1031 KKASSERT(child->delete_tid >= child->modify_tid);
1032 /*child->update_lo = info->sync_tid;*/
1033 /* do not update mirror_tid, pass2 will ignore chain */
1038 * We must ref the child before unlocking the spinlock.
1040 * The caller has added a ref to the parent so we can temporarily
1041 * unlock it in order to lock the child.
1043 hammer2_chain_ref(child);
1044 spin_unlock(&parent->core->cst.spin);
1046 hammer2_chain_unlock(parent);
1047 hammer2_chain_lock(child, HAMMER2_RESOLVE_MAYBE);
1050 * Recurse and collect deferral data. We only recursively sync
1051 * (basically) if update_lo has not been updated, indicating that
1052 * the child has not already been processed.
1054 if ((child->flags & HAMMER2_CHAIN_MODIFIED) ||
1055 (child->update_lo < info->sync_tid &&
1056 child->update_lo < child->update_hi)) {
1058 hammer2_flush_core(info, &child, 0); /* XXX deleting */
1063 * Determine if domodify should be set. Do not otherwise adjust
1064 * the child or pass2 will get confused.
1067 * - child is flagged as possibly needing block table insertion.
1068 * - child not deleted or deletion is beyond transaction id
1069 * - child created beyond parent synchronization point
1070 * - parent not deleted as-of this transaction
1072 if ((child->flags & HAMMER2_CHAIN_FLUSH_CREATE) &&
1073 child->delete_tid > trans->sync_tid &&
1074 child->modify_tid > parent->update_lo &&
1075 parent->delete_tid > trans->sync_tid) {
1081 * - child is flagged as possibly needing block table removal.
1082 * - child deleted before or during this transaction
1083 * - child created prior or during parent synchronization point
1084 * - parent not yet synchronized to child deletion
1085 * - parent not deleted as-of this transaction
1087 if ((child->flags & HAMMER2_CHAIN_FLUSH_DELETE) &&
1088 child->delete_tid <= trans->sync_tid &&
1089 child->modify_tid <= parent->update_lo &&
1090 child->delete_tid > parent->update_lo &&
1091 parent->delete_tid > trans->sync_tid) {
1096 * Relock to continue the loop
1098 hammer2_chain_unlock(child);
1099 hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
1100 hammer2_chain_drop(child);
1101 KKASSERT(info->parent == parent);
1103 spin_lock(&parent->core->cst.spin);
1108 * PASS2 - BLOCKTABLE DELETIONS
1111 hammer2_flush_pass2(hammer2_chain_t *child, void *data)
1113 hammer2_flush_info_t *info = data;
1114 hammer2_chain_t *parent = info->parent;
1115 hammer2_mount_t *hmp = child->hmp;
1116 hammer2_trans_t *trans = info->trans;
1117 hammer2_blockref_t *base;
1121 * Prefilter - Ignore children not flagged as needing a parent
1122 * blocktable update.
1124 if ((child->flags & HAMMER2_CHAIN_FLUSH_DELETE) == 0)
1128 * Prefilter - Ignore children created after our flush_tid (not
1129 * visible to our flush).
1131 if (child->modify_tid > trans->sync_tid) {
1132 KKASSERT(child->delete_tid >= child->modify_tid);
1137 * Prefilter - Don't bother updating the blockrefs for a deleted
1138 * parent (from the flush's perspective). Otherwise,
1139 * we need to be COUNTEDBREFS synchronized for the
1140 * hammer2_base_*() functions.
1142 * NOTE: This test must match the similar one in flush_core.
1144 if (h2ignore_deleted(info, parent))
1148 * Calculate blockmap pointer
1150 switch(parent->bref.type) {
1151 case HAMMER2_BREF_TYPE_INODE:
1153 * Access the inode's block array. However, there is no
1154 * block array if the inode is flagged DIRECTDATA. The
1155 * DIRECTDATA case typicaly only occurs when a hardlink has
1156 * been shifted up the tree and the original inode gets
1157 * replaced with an OBJTYPE_HARDLINK placeholding inode.
1160 (parent->data->ipdata.op_flags &
1161 HAMMER2_OPFLAG_DIRECTDATA) == 0) {
1162 base = &parent->data->ipdata.u.blockset.blockref[0];
1166 count = HAMMER2_SET_COUNT;
1168 case HAMMER2_BREF_TYPE_INDIRECT:
1169 case HAMMER2_BREF_TYPE_FREEMAP_NODE:
1171 base = &parent->data->npdata[0];
1174 count = parent->bytes / sizeof(hammer2_blockref_t);
1176 case HAMMER2_BREF_TYPE_VOLUME:
1177 base = &hmp->voldata.sroot_blockset.blockref[0];
1178 count = HAMMER2_SET_COUNT;
1180 case HAMMER2_BREF_TYPE_FREEMAP:
1181 base = &parent->data->npdata[0];
1182 count = HAMMER2_SET_COUNT;
1187 panic("hammer2_chain_flush_pass2: "
1188 "unrecognized blockref type: %d",
1194 * - child is flagged for removal
1195 * - child deleted before or during this transaction
1196 * - child created prior or during parent synchronization point
1197 * - parent not yet synchronized to child's deletion
1199 if (child->delete_tid <= trans->sync_tid &&
1200 child->modify_tid <= parent->update_lo &&
1201 child->delete_tid > parent->update_lo) {
1202 /* can't assert BMAPPED because state adjustment may occur
1203 * before we are done, and BMAPPED only applies to the live
1205 *KKASSERT(child->flags & HAMMER2_CHAIN_BMAPPED);*/
1207 hammer2_rollup_stats(parent, child, -1);
1208 hammer2_base_delete(trans, parent, base, count,
1209 &info->cache_index, child);
1217 * PASS3 - BLOCKTABLE INSERTIONS
1220 hammer2_flush_pass3(hammer2_chain_t *child, void *data)
1222 hammer2_flush_info_t *info = data;
1223 hammer2_chain_t *parent = info->parent;
1224 hammer2_mount_t *hmp = child->hmp;
1225 hammer2_trans_t *trans = info->trans;
1226 hammer2_blockref_t *base;
1230 * Prefilter - Ignore children not flagged as needing a parent
1231 * blocktable update.
1233 if ((child->flags & HAMMER2_CHAIN_FLUSH_CREATE) == 0)
1237 * Prefilter - Ignore children created after our flush_tid (not
1238 * visible to our flush).
1240 if (child->modify_tid > trans->sync_tid) {
1241 KKASSERT(child->delete_tid >= child->modify_tid);
1246 * Prefilter - Don't bother updating the blockrefs for a deleted
1247 * parent (from the flush's perspective). Otherwise,
1248 * we need to be COUNTEDBREFS synchronized for the
1249 * hammer2_base_*() functions.
1251 * NOTE: This test must match the similar one in flush_core.
1253 if (h2ignore_deleted(info, parent))
1257 * Calculate blockmap pointer
1259 switch(parent->bref.type) {
1260 case HAMMER2_BREF_TYPE_INODE:
1262 * Access the inode's block array. However, there is no
1263 * block array if the inode is flagged DIRECTDATA. The
1264 * DIRECTDATA case typicaly only occurs when a hardlink has
1265 * been shifted up the tree and the original inode gets
1266 * replaced with an OBJTYPE_HARDLINK placeholding inode.
1269 (parent->data->ipdata.op_flags &
1270 HAMMER2_OPFLAG_DIRECTDATA) == 0) {
1271 base = &parent->data->ipdata.u.blockset.blockref[0];
1275 count = HAMMER2_SET_COUNT;
1277 case HAMMER2_BREF_TYPE_INDIRECT:
1278 case HAMMER2_BREF_TYPE_FREEMAP_NODE:
1280 base = &parent->data->npdata[0];
1283 count = parent->bytes / sizeof(hammer2_blockref_t);
1285 case HAMMER2_BREF_TYPE_VOLUME:
1286 base = &hmp->voldata.sroot_blockset.blockref[0];
1287 count = HAMMER2_SET_COUNT;
1289 case HAMMER2_BREF_TYPE_FREEMAP:
1290 base = &parent->data->npdata[0];
1291 count = HAMMER2_SET_COUNT;
1296 panic("hammer2_chain_flush_pass2: "
1297 "unrecognized blockref type: %d",
1303 * - child is flagged as possibly needing block table insertion.
1304 * - child not deleted or deletion is beyond transaction id
1305 * - child created beyond parent synchronization point
1307 if (child->delete_tid > trans->sync_tid &&
1308 child->modify_tid > parent->update_lo) {
1310 hammer2_rollup_stats(parent, child, 1);
1311 hammer2_base_insert(trans, parent, base, count,
1312 &info->cache_index, child);
1320 * PASS4 - CLEANUP CHILDREN (non-recursive, but CAN be re-entrant)
1322 * Adjust queues and set or clear BMAPPED appropriately if processing
1323 * the live parent. pass4 handles deletions, pass5 handles insertions.
1324 * Separate passes are required because both deletions and insertions can
1327 * Cleanup FLUSH_CREATE/FLUSH_DELETE on the last parent.
1330 hammer2_flush_pass4(hammer2_chain_t *child, void *data)
1332 hammer2_flush_info_t *info = data;
1333 hammer2_chain_t *parent = info->parent;
1334 hammer2_chain_core_t *above = child->above;
1335 hammer2_trans_t *trans = info->trans;
1338 * Prefilter - Ignore children created after our flush_tid (not
1339 * visible to our flush).
1341 if (child->modify_tid > trans->sync_tid) {
1342 KKASSERT(child->delete_tid >= child->modify_tid);
1347 * Ref and lock child for operation, spinlock must be temporarily
1348 * Make sure child is referenced before we unlock.
1350 hammer2_chain_ref(child);
1351 spin_unlock(&above->cst.spin);
1352 hammer2_chain_lock(child, HAMMER2_RESOLVE_NEVER);
1353 KKASSERT(child->above == above);
1354 KKASSERT(parent->core == above);
1357 * Adjust BMAPPED state and rbtree/queue only when we hit the
1358 * actual live parent.
1360 if ((parent->flags & HAMMER2_CHAIN_DELETED) == 0) {
1361 spin_lock(&above->cst.spin);
1364 * Deleting from blockmap, move child out of dbtree
1365 * and clear BMAPPED. Child should not be on RBTREE.
1367 if (child->delete_tid <= trans->sync_tid &&
1368 child->modify_tid <= parent->update_lo &&
1369 child->delete_tid > parent->update_lo &&
1370 (child->flags & HAMMER2_CHAIN_BMAPPED)) {
1371 KKASSERT(child->flags & HAMMER2_CHAIN_ONDBTREE);
1372 RB_REMOVE(hammer2_chain_tree, &above->dbtree, child);
1373 atomic_clear_int(&child->flags, HAMMER2_CHAIN_ONDBTREE);
1374 atomic_clear_int(&child->flags, HAMMER2_CHAIN_BMAPPED);
1378 * Not on any list, place child on DBQ
1380 if ((child->flags & (HAMMER2_CHAIN_ONRBTREE |
1381 HAMMER2_CHAIN_ONDBTREE |
1382 HAMMER2_CHAIN_ONDBQ)) == 0) {
1383 KKASSERT((child->flags & HAMMER2_CHAIN_BMAPPED) == 0);
1384 TAILQ_INSERT_TAIL(&above->dbq, child, db_entry);
1385 atomic_set_int(&child->flags, HAMMER2_CHAIN_ONDBQ);
1387 spin_unlock(&above->cst.spin);
1391 * Unlock the child. This can wind up dropping the child's
1392 * last ref, removing it from the parent's RB tree, and deallocating
1393 * the structure. The RB_SCAN() our caller is doing handles the
1396 hammer2_chain_unlock(child);
1397 hammer2_chain_drop(child);
1398 spin_lock(&above->cst.spin);
1401 * The parent may have been delete-duplicated.
1407 hammer2_flush_pass5(hammer2_chain_t *child, void *data)
1409 hammer2_flush_info_t *info = data;
1410 hammer2_chain_t *parent = info->parent;
1411 hammer2_chain_t *xchain;
1412 hammer2_chain_core_t *above = child->above;
1413 hammer2_trans_t *trans = info->trans;
1416 * Prefilter - Ignore children created after our flush_tid (not
1417 * visible to our flush).
1419 if (child->modify_tid > trans->sync_tid) {
1420 KKASSERT(child->delete_tid >= child->modify_tid);
1425 * Ref and lock child for operation, spinlock must be temporarily
1426 * Make sure child is referenced before we unlock.
1428 hammer2_chain_ref(child);
1429 spin_unlock(&above->cst.spin);
1430 hammer2_chain_lock(child, HAMMER2_RESOLVE_NEVER);
1431 KKASSERT(child->above == above);
1432 KKASSERT(parent->core == above);
1435 * Adjust BMAPPED state and rbtree/queue only when we hit the
1436 * actual live parent.
1438 if ((parent->flags & HAMMER2_CHAIN_DELETED) == 0) {
1439 spin_lock(&above->cst.spin);
1442 * Inserting into blockmap, place child in rbtree or dbtree.
1444 if (child->delete_tid > trans->sync_tid &&
1445 child->modify_tid > parent->update_lo &&
1446 (child->flags & HAMMER2_CHAIN_BMAPPED) == 0) {
1447 if (child->flags & HAMMER2_CHAIN_ONDBQ) {
1448 TAILQ_REMOVE(&above->dbq, child, db_entry);
1449 atomic_clear_int(&child->flags,
1450 HAMMER2_CHAIN_ONDBQ);
1452 if ((child->flags & HAMMER2_CHAIN_DELETED) == 0 &&
1453 (child->flags & HAMMER2_CHAIN_ONRBTREE) == 0) {
1454 KKASSERT((child->flags &
1455 (HAMMER2_CHAIN_ONDBTREE |
1456 HAMMER2_CHAIN_ONDBQ)) == 0);
1457 xchain = RB_INSERT(hammer2_chain_tree,
1458 &above->rbtree, child);
1459 KKASSERT(xchain == NULL);
1460 atomic_set_int(&child->flags,
1461 HAMMER2_CHAIN_ONRBTREE);
1463 if ((child->flags & HAMMER2_CHAIN_DELETED) &&
1464 (child->flags & HAMMER2_CHAIN_ONDBTREE) == 0) {
1465 KKASSERT((child->flags &
1466 (HAMMER2_CHAIN_ONRBTREE |
1467 HAMMER2_CHAIN_ONDBQ)) == 0);
1468 xchain = RB_INSERT(hammer2_chain_tree,
1469 &above->dbtree, child);
1470 KKASSERT(xchain == NULL);
1471 atomic_set_int(&child->flags,
1472 HAMMER2_CHAIN_ONDBTREE);
1474 atomic_set_int(&child->flags, HAMMER2_CHAIN_BMAPPED);
1475 KKASSERT(child->flags &
1476 (HAMMER2_CHAIN_ONRBTREE |
1477 HAMMER2_CHAIN_ONDBTREE |
1478 HAMMER2_CHAIN_ONDBQ));
1482 * Not on any list, place child on DBQ
1484 if ((child->flags & (HAMMER2_CHAIN_ONRBTREE |
1485 HAMMER2_CHAIN_ONDBTREE |
1486 HAMMER2_CHAIN_ONDBQ)) == 0) {
1487 KKASSERT((child->flags & HAMMER2_CHAIN_BMAPPED) == 0);
1488 TAILQ_INSERT_TAIL(&above->dbq, child, db_entry);
1489 atomic_set_int(&child->flags, HAMMER2_CHAIN_ONDBQ);
1491 spin_unlock(&above->cst.spin);
1495 * Cleanup flags on last parent iterated for flush.
1497 if (info->domodify & 2) {
1498 if (child->flags & HAMMER2_CHAIN_FLUSH_CREATE) {
1499 atomic_clear_int(&child->flags,
1500 HAMMER2_CHAIN_FLUSH_CREATE);
1501 hammer2_chain_drop(child);
1503 if ((child->flags & HAMMER2_CHAIN_FLUSH_DELETE) &&
1504 child->delete_tid <= trans->sync_tid) {
1505 KKASSERT((parent->flags & HAMMER2_CHAIN_DELETED) ||
1506 (child->flags & HAMMER2_CHAIN_ONDBTREE) == 0);
1507 /* XXX delete-duplicate chain insertion mech wrong */
1508 KKASSERT((parent->flags & HAMMER2_CHAIN_DELETED) ||
1509 (child->flags & HAMMER2_CHAIN_BMAPPED) == 0);
1510 atomic_clear_int(&child->flags,
1511 HAMMER2_CHAIN_FLUSH_DELETE);
1512 hammer2_chain_drop(child);
1517 * Unlock the child. This can wind up dropping the child's
1518 * last ref, removing it from the parent's RB tree, and deallocating
1519 * the structure. The RB_SCAN() our caller is doing handles the
1522 hammer2_chain_unlock(child);
1523 hammer2_chain_drop(child);
1524 spin_lock(&above->cst.spin);
1527 * The parent may have been delete-duplicated.
1533 hammer2_rollup_stats(hammer2_chain_t *parent, hammer2_chain_t *child, int how)
1536 hammer2_chain_t *grandp;
1539 parent->data_count += child->data_count;
1540 parent->inode_count += child->inode_count;
1541 child->data_count = 0;
1542 child->inode_count = 0;
1544 parent->data_count -= child->bytes;
1545 if (child->bref.type == HAMMER2_BREF_TYPE_INODE) {
1546 parent->inode_count -= 1;
1548 /* XXX child->data may be NULL atm */
1549 parent->data_count -= child->data->ipdata.data_count;
1550 parent->inode_count -= child->data->ipdata.inode_count;
1553 } else if (how > 0) {
1554 parent->data_count += child->bytes;
1555 if (child->bref.type == HAMMER2_BREF_TYPE_INODE) {
1556 parent->inode_count += 1;
1558 /* XXX child->data may be NULL atm */
1559 parent->data_count += child->data->ipdata.data_count;
1560 parent->inode_count += child->data->ipdata.inode_count;
1564 if (parent->bref.type == HAMMER2_BREF_TYPE_INODE) {
1565 parent->data->ipdata.data_count += parent->data_count;
1566 parent->data->ipdata.inode_count += parent->inode_count;
1568 for (grandp = parent->above->first_parent;
1570 grandp = grandp->next_parent) {
1571 grandp->data_count += parent->data_count;
1572 grandp->inode_count += parent->inode_count;
1575 parent->data_count = 0;
1576 parent->inode_count = 0;