2 * Copyright (c) 2011-2013 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>
46 * Recursively flush the specified chain. The chain is locked and
47 * referenced by the caller and will remain so on return. The chain
48 * will remain referenced throughout but can temporarily lose its
49 * lock during the recursion to avoid unnecessarily stalling user
52 struct hammer2_flush_info {
53 hammer2_chain_t *parent;
54 hammer2_trans_t *trans;
60 struct h2_flush_deferral_list flush_list;
61 hammer2_tid_t sync_tid; /* flush synchronization point */
62 hammer2_tid_t mirror_tid; /* collect mirror TID updates */
65 typedef struct hammer2_flush_info hammer2_flush_info_t;
67 static void hammer2_chain_flush_core(hammer2_flush_info_t *info,
68 hammer2_chain_t **chainp);
69 static int hammer2_chain_flush_scan1(hammer2_chain_t *child, void *data);
70 static int hammer2_chain_flush_scan2(hammer2_chain_t *child, void *data);
71 static void hammer2_rollup_stats(hammer2_chain_t *parent,
72 hammer2_chain_t *child, int how);
77 hammer2_updatestats(hammer2_flush_info_t *info, hammer2_blockref_t *bref,
82 if (bref->type != 0) {
83 bytes = 1 << (bref->data_off & HAMMER2_OFF_MASK_RADIX);
84 if (bref->type == HAMMER2_BREF_TYPE_INODE)
85 info->inode_count += how;
87 info->data_count -= bytes;
89 info->data_count += bytes;
95 * Transaction support functions for writing to the filesystem.
97 * Initializing a new transaction allocates a transaction ID. We
98 * don't bother marking the volume header MODIFIED. Instead, the volume
99 * will be synchronized at a later time as part of a larger flush sequence.
101 * Non-flush transactions can typically run concurrently. However if
102 * there are non-flush transaction both before AND after a flush trans,
103 * the transactions after stall until the ones before finish.
105 * Non-flush transactions occuring after a flush pointer can run concurrently
106 * with that flush. They only have to wait for transactions prior to the
107 * flush trans to complete before they unstall.
109 * WARNING! Transaction ids are only allocated when the transaction becomes
110 * active, which allows other transactions to insert ahead of us
111 * if we are forced to block (only bioq transactions do that).
113 * WARNING! Modifications to the root volume cannot dup the root volume
114 * header to handle synchronization points, so alloc_tid can
115 * wind up (harmlessly) more advanced on flush.
118 hammer2_trans_init(hammer2_trans_t *trans, hammer2_pfsmount_t *pmp, int flags)
120 hammer2_mount_t *hmp;
121 hammer2_trans_t *head;
123 bzero(trans, sizeof(*trans));
125 hmp = pmp->cluster.chains[0]->hmp; /* XXX */
127 hammer2_voldata_lock(hmp);
128 trans->flags = flags;
129 trans->td = curthread;
130 /*trans->delete_gen = 0;*/ /* multiple deletions within trans */
132 if (flags & HAMMER2_TRANS_ISFLUSH) {
134 * If multiple flushes are trying to run we have to
135 * wait until it is our turn. All flushes are serialized.
137 * We queue ourselves and then wait to become the head
138 * of the queue, allowing all prior flushes to complete.
141 trans->sync_tid = hmp->voldata.alloc_tid++;
142 trans->real_tid = trans->sync_tid;
143 TAILQ_INSERT_TAIL(&hmp->transq, trans, entry);
144 if (TAILQ_FIRST(&hmp->transq) != trans) {
146 while (trans->blocked) {
147 lksleep(&trans->sync_tid, &hmp->voldatalk,
151 } else if (hmp->flushcnt == 0) {
153 * No flushes are pending, we can go.
155 TAILQ_INSERT_TAIL(&hmp->transq, trans, entry);
156 trans->sync_tid = hmp->voldata.alloc_tid;
157 trans->real_tid = trans->sync_tid;
159 /* XXX improve/optimize inode allocation */
162 * One or more flushes are pending. We insert after
163 * the current flush and may block. We have priority
164 * over any flushes that are not the current flush.
166 * TRANS_BUFCACHE transactions cannot block.
168 TAILQ_FOREACH(head, &hmp->transq, entry) {
169 if (head->flags & HAMMER2_TRANS_ISFLUSH)
173 TAILQ_INSERT_AFTER(&hmp->transq, head, trans, entry);
174 trans->sync_tid = head->real_tid + 1;
175 trans->real_tid = trans->sync_tid;
177 if ((trans->flags & HAMMER2_TRANS_BUFCACHE) == 0) {
178 if (TAILQ_FIRST(&hmp->transq) != head) {
180 while (trans->blocked) {
181 lksleep(&trans->sync_tid,
188 if (flags & HAMMER2_TRANS_NEWINODE)
189 trans->inode_tid = hmp->voldata.inode_tid++;
190 hammer2_voldata_unlock(hmp, 0);
194 hammer2_trans_done(hammer2_trans_t *trans)
196 hammer2_mount_t *hmp;
197 hammer2_trans_t *head;
198 hammer2_trans_t *scan;
200 hmp = trans->pmp->cluster.chains[0]->hmp;
203 * Remove and adjust flushcnt
205 hammer2_voldata_lock(hmp);
206 TAILQ_REMOVE(&hmp->transq, trans, entry);
207 if (trans->flags & HAMMER2_TRANS_ISFLUSH)
211 * Unblock the head of the queue and any additional transactions
212 * up to the next flush.
214 head = TAILQ_FIRST(&hmp->transq);
215 if (head && head->blocked) {
217 wakeup(&head->sync_tid);
219 scan = TAILQ_NEXT(head, entry);
220 while (scan && (scan->flags & HAMMER2_TRANS_ISFLUSH) == 0) {
222 wakeup(&scan->sync_tid);
223 scan = TAILQ_NEXT(scan, entry);
226 hammer2_voldata_unlock(hmp, 0);
230 * Flush the chain and all modified sub-chains through the specified
231 * synchronization point (sync_tid), propagating parent chain modifications
232 * and mirror_tid updates back up as needed. Since we are recursing downward
233 * we do not have to deal with the complexities of multi-homed chains (chains
234 * with multiple parents).
236 * Caller must have interlocked against any non-flush-related modifying
237 * operations in progress whos modify_tid values are less than or equal
238 * to the passed sync_tid.
240 * Caller must have already vetted synchronization points to ensure they
241 * are properly flushed. Only snapshots and cluster flushes can create
242 * these sorts of synchronization points.
244 * This routine can be called from several places but the most important
245 * is from the hammer2_vop_reclaim() function. We want to try to completely
246 * clean out the inode structure to prevent disconnected inodes from
247 * building up and blowing out the kmalloc pool. However, it is not actually
248 * necessary to flush reclaimed inodes to maintain HAMMER2's crash recovery
251 * chain is locked on call and will remain locked on return. If a flush
252 * occured, the chain's MOVED bit will be set indicating that its parent
253 * (which is not part of the flush) should be updated.
256 hammer2_chain_flush(hammer2_trans_t *trans, hammer2_chain_t **chainp)
258 hammer2_chain_t *chain = *chainp;
259 hammer2_chain_t *scan;
260 hammer2_chain_core_t *core;
261 hammer2_flush_info_t info;
264 * Execute the recursive flush and handle deferrals.
266 * Chains can be ridiculously long (thousands deep), so to
267 * avoid blowing out the kernel stack the recursive flush has a
268 * depth limit. Elements at the limit are placed on a list
269 * for re-execution after the stack has been popped.
271 bzero(&info, sizeof(info));
272 TAILQ_INIT(&info.flush_list);
274 info.sync_tid = trans->sync_tid;
276 info.cache_index = -1;
280 kprintf("CHAIN FLUSH trans %p.%016jx chain %p.%d mod %016jx upd %016jx\n", trans, trans->sync_tid, chain, chain->bref.type, chain->modify_tid, core->update_tid);
284 * Extra ref needed because flush_core expects it when replacing
287 hammer2_chain_ref(chain);
291 * Unwind deep recursions which had been deferred. This
292 * can leave MOVED set for these chains, which will be
293 * handled when we [re]flush chain after the unwind.
295 while ((scan = TAILQ_FIRST(&info.flush_list)) != NULL) {
296 KKASSERT(scan->flags & HAMMER2_CHAIN_DEFERRED);
297 TAILQ_REMOVE(&info.flush_list, scan, flush_node);
298 atomic_clear_int(&scan->flags, HAMMER2_CHAIN_DEFERRED);
301 * Now that we've popped back up we can do a secondary
302 * recursion on the deferred elements.
304 if (hammer2_debug & 0x0040)
305 kprintf("defered flush %p\n", scan);
306 hammer2_chain_lock(scan, HAMMER2_RESOLVE_MAYBE);
307 hammer2_chain_flush(trans, &scan);
308 hammer2_chain_unlock(scan);
309 hammer2_chain_drop(scan); /* ref from deferral */
313 * Flush pass1 on root.
315 info.diddeferral = 0;
316 hammer2_chain_flush_core(&info, &chain);
318 kprintf("flush_core_done parent=<base> chain=%p.%d %08x\n",
319 chain, chain->bref.type, chain->flags);
323 * Only loop if deep recursions have been deferred.
325 if (TAILQ_EMPTY(&info.flush_list))
328 hammer2_chain_drop(chain);
333 * This is the core of the chain flushing code. The chain is locked by the
334 * caller and must also have an extra ref on it by the caller, and remains
335 * locked and will have an extra ref on return.
337 * This function is keyed off of the update_tid bit but must make
338 * fine-grained choices based on the synchronization point we are flushing to.
340 * If the flush accomplished any work chain will be flagged MOVED
341 * indicating a copy-on-write propagation back up is required.
342 * Deep sub-nodes may also have been entered onto the deferral list.
343 * MOVED is never set on the volume root.
345 * NOTE: modify_tid is different from MODIFIED. modify_tid is updated
346 * only when a chain is specifically modified, and not updated
347 * for copy-on-write propagations. MODIFIED is set on any modification
348 * including copy-on-write propagations.
351 hammer2_chain_flush_core(hammer2_flush_info_t *info, hammer2_chain_t **chainp)
353 hammer2_chain_t *chain = *chainp;
354 hammer2_mount_t *hmp;
355 hammer2_blockref_t *bref;
359 hammer2_trans_t *trans = info->trans;
361 hammer2_chain_core_t *core;
374 kprintf("flush_core %p->%p.%d %08x (%s)\n",
375 info->parent, chain, chain->bref.type,
377 ((chain->bref.type == HAMMER2_BREF_TYPE_INODE) ?
378 chain->data->ipdata.filename : "?"));
380 kprintf("flush_core NULL->%p.%d %08x (%s)\n",
381 chain, chain->bref.type,
383 ((chain->bref.type == HAMMER2_BREF_TYPE_INODE) ?
384 chain->data->ipdata.filename : "?"));
385 kprintf("PUSH %p.%d %08x mod=%016jx del=%016jx mirror=%016jx\n", chain, chain->bref.type, chain->flags, chain->modify_tid, chain->delete_tid, chain->bref.mirror_tid);
389 * Ignore chains modified beyond the current flush point. These
390 * will be treated as if they did not exist. Subchains with lower
391 * modify_tid's will still be accessible via other parents.
393 * (vchain and fchain are exceptions since they cannot be duplicated)
395 if (chain->modify_tid > info->sync_tid &&
396 chain != &hmp->fchain && chain != &hmp->vchain) {
397 chain->debug_reason = (chain->debug_reason & ~255) | 5;
404 * If update_tid triggers we recurse the flush and adjust the
405 * blockrefs accordingly.
407 * NOTE: Looping on update_tid can prevent a flush from ever
408 * finishing in the face of filesystem activity.
410 * NOTE: We must recurse whether chain is flagged DELETED or not.
411 * However, if it is flagged DELETED we limit sync_tid to
412 * delete_tid to ensure that the chain's bref.mirror_tid is
413 * not fully updated and causes it to miss the non-DELETED
416 if (chain->bref.mirror_tid < core->update_tid &&
417 chain->bref.mirror_tid < info->sync_tid) {
418 hammer2_chain_t *saved_parent;
419 hammer2_tid_t saved_mirror;
420 hammer2_chain_layer_t *layer;
425 * Races will bump update_tid above trans->sync_tid causing
426 * us to catch the issue in a later flush. We do not update
427 * update_tid if a deferral (or error XXX) occurs.
429 * We don't want to set our chain to MODIFIED gratuitously.
431 * We need an extra ref on chain because we are going to
432 * release its lock temporarily in our child loop.
436 * Run two passes. The first pass handles MODIFIED and
437 * update_tid recursions while the second pass handles
438 * MOVED chains on the way back up.
440 * If the stack gets too deep we defer scan1, but must
441 * be sure to still run scan2 if on the next loop the
442 * deferred chain has been flushed and now needs MOVED
443 * handling on the way back up.
445 * Scan1 is recursive.
447 * NOTE: The act of handling a modified/submodified chain can
448 * cause the MOVED Flag to be set. It can also be set
449 * via hammer2_chain_delete() and in other situations.
451 * NOTE: RB_SCAN() must be used instead of RB_FOREACH()
452 * because children can be physically removed during
455 * NOTE: We would normally not care about insertions except
456 * that some insertions might occur from the flush
457 * itself, so loop on generation number changes.
459 saved_parent = info->parent;
460 saved_mirror = info->mirror_tid;
461 saved_domodify = info->domodify;
462 info->parent = chain;
463 info->mirror_tid = chain->bref.mirror_tid;
465 chain->debug_reason = (chain->debug_reason & ~255) | 6;
467 if (info->depth == HAMMER2_FLUSH_DEPTH_LIMIT) {
468 if ((chain->flags & HAMMER2_CHAIN_DEFERRED) == 0) {
469 hammer2_chain_ref(chain);
470 TAILQ_INSERT_TAIL(&info->flush_list,
472 atomic_set_int(&chain->flags,
473 HAMMER2_CHAIN_DEFERRED);
477 info->diddeferral = 0;
478 spin_lock(&core->cst.spin);
479 KKASSERT(core->good == 0x1234 && core->sharecnt > 0);
481 save_gen = core->generation;
482 TAILQ_FOREACH_REVERSE(layer, &core->layerq,
483 h2_layer_list, entry) {
485 KKASSERT(layer->good == 0xABCD);
486 RB_SCAN(hammer2_chain_tree,
488 NULL, hammer2_chain_flush_scan1,
491 diddeferral += info->diddeferral;
493 } while (core->generation != save_gen);
494 spin_unlock(&core->cst.spin);
498 * Blockrefs are only updated on live chains.
500 * We are possibly causing a delete-duplicate from inside the
501 * flush itself. The parent might be live or might have been
502 * deleted concurrently in a post-flush transaction. If
503 * the parent was deleted our modified chain will also be
504 * marked deleted, but since it inherits the parent's
505 * delete_tid it will still appear to be 'live' for the
506 * purposes of the flush.
508 * There may also be a side-effect due to the freemap
509 * allocation. See freemap_alloc()
511 if (info->domodify && chain->delete_tid > info->sync_tid) {
512 hammer2_chain_modify(info->trans, &info->parent,
513 HAMMER2_MODIFY_NO_MODIFY_TID);
514 if (info->parent != chain) {
515 hammer2_chain_drop(chain);
516 hammer2_chain_ref(info->parent);
518 chain = info->parent;
520 chain->debug_reason = (chain->debug_reason & ~255) | 7;
523 * Handle successfully flushed children who are in the MOVED
524 * state on the way back up the recursion. This can have
525 * the side-effect of clearing MOVED.
527 * Scan2 may replace info->parent. If it does it will also
528 * replace the extra ref we made.
530 * Scan2 is non-recursive.
533 spin_lock(&core->cst.spin);
535 spin_lock(&core->cst.spin);
536 KKASSERT(core->good == 0x1234 && core->sharecnt > 0);
537 TAILQ_FOREACH_REVERSE(layer, &core->layerq,
538 h2_layer_list, entry) {
541 KKASSERT(layer->good == 0xABCD);
542 RB_SCAN(hammer2_chain_tree, &layer->rbtree,
543 NULL, hammer2_chain_flush_scan2, info);
545 RB_SCAN(hammer2_chain_tree, &layer->rbtree,
546 NULL, hammer2_chain_flush_scan2, info);
548 KKASSERT(info->parent->core == core);
552 * Mirror_tid propagates all changes. It is also used
553 * in scan2 to determine when a chain must be applied
554 * to the related block table.
556 KKASSERT(info->parent->bref.mirror_tid <=
558 chain->bref.mirror_tid = info->mirror_tid;
562 * info->parent must not have been replaced again
564 KKASSERT(info->parent == chain);
566 chain->debug_reason = (chain->debug_reason & ~255) | 8;
569 hammer2_chain_layer_check_locked(chain->hmp, core);
570 spin_unlock(&core->cst.spin);
572 info->mirror_tid = saved_mirror;
573 info->parent = saved_parent;
574 info->domodify = saved_domodify;
575 KKASSERT(chain->refs > 1);
579 kprintf("POP %p.%d\n", chain, chain->bref.type);
583 * Rollup diddeferral for caller. Note direct assignment, not +=.
585 info->diddeferral = diddeferral;
588 * Do not flush chain if there were any deferrals. It will be
589 * retried later after the deferrals are independently handled.
592 chain->debug_reason = (chain->debug_reason & ~255) | 99;
593 if (hammer2_debug & 0x0008) {
594 kprintf("%*.*s} %p/%d %04x (deferred)",
595 info->depth, info->depth, "",
596 chain, chain->refs, chain->flags);
602 * If we encounter a deleted chain within our flush we can clear
603 * the MODIFIED bit and avoid flushing it whether it has been
604 * destroyed or not. We must make sure that the chain is flagged
605 * MOVED in this situation so the parent picks up the deletion.
607 * Since this chain will now never be written to disk we need to
608 * adjust bref.mirror_tid such that it does not prevent sub-chains
609 * from clearing their MOVED bits.
611 * NOTE: scan2 has already executed above so statistics have
612 * already been rolled up.
614 * NOTE: Deletions do not prevent flush recursion as a deleted
615 * inode (removed file) which is still open may still require
616 * on-media storage to be able to clean related pages out from
619 * NOTE: Even though this chain will not issue write I/O, we must
620 * still update chain->bref.mirror_tid for flush management
623 if (chain->delete_tid <= info->sync_tid) {
624 chain->debug_reason = (chain->debug_reason & ~255) | 9;
625 if (chain->flags & HAMMER2_CHAIN_MODIFIED) {
627 if (chain->bytes == chain->bp->b_bufsize)
628 chain->bp->b_flags |= B_INVAL|B_RELBUF;
630 if ((chain->flags & HAMMER2_CHAIN_MOVED) == 0) {
631 hammer2_chain_ref(chain);
632 atomic_set_int(&chain->flags,
633 HAMMER2_CHAIN_MOVED);
635 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
636 if (chain->bref.mirror_tid < info->sync_tid)
637 chain->bref.mirror_tid = info->sync_tid;
638 hammer2_chain_drop(chain);
640 if (chain->bref.mirror_tid < info->sync_tid)
641 chain->bref.mirror_tid = info->sync_tid;
645 if ((chain->flags & HAMMER2_CHAIN_DESTROYED) &&
646 (chain->flags & HAMMER2_CHAIN_DELETED) &&
647 (trans->flags & HAMMER2_TRANS_RESTRICTED) == 0) {
649 * Throw-away the MODIFIED flag
651 if (chain->flags & HAMMER2_CHAIN_MODIFIED) {
653 if (chain->bytes == chain->bp->b_bufsize)
654 chain->bp->b_flags |= B_INVAL|B_RELBUF;
656 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
657 hammer2_chain_drop(chain);
664 * A degenerate flush might not have flushed anything and thus not
665 * processed modified blocks on the way back up. Detect the case.
667 * Note that MOVED can be set without MODIFIED being set due to
668 * a deletion, in which case it is handled by Scan2 later on.
670 * Both bits can be set along with DELETED due to a deletion if
671 * modified data within the synchronization zone and the chain
672 * was then deleted beyond the zone, in which case we still have
673 * to flush for synchronization point consistency. Otherwise though
674 * DELETED and MODIFIED are treated as separate flags.
676 if ((chain->flags & HAMMER2_CHAIN_MODIFIED) == 0) {
677 if (chain->bref.mirror_tid < info->sync_tid)
678 chain->bref.mirror_tid = info->sync_tid;
679 chain->debug_reason = (chain->debug_reason & ~255) | 10;
682 chain->debug_reason = (chain->debug_reason & ~255) | 11;
687 * A DESTROYED node that reaches this point must be flushed for
688 * synchronization point consistency.
692 * Update mirror_tid, clear MODIFIED, and set MOVED.
694 * The caller will update the parent's reference to this chain
695 * by testing MOVED as long as the modification was in-bounds.
697 * MOVED is never set on the volume root as there is no parent
700 if (hammer2_debug & 0x1000) {
701 kprintf("Flush %p.%d %016jx/%d sync_tid %016jx\n",
702 chain, chain->bref.type,
703 chain->bref.key, chain->bref.keybits,
706 if (hammer2_debug & 0x2000) {
707 Debugger("Flush hell");
709 if (chain->bref.mirror_tid < info->sync_tid)
710 chain->bref.mirror_tid = info->sync_tid;
711 wasmodified = (chain->flags & HAMMER2_CHAIN_MODIFIED) != 0;
712 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
713 if (chain == &hmp->vchain)
714 kprintf("(FLUSHED VOLUME HEADER)\n");
715 if (chain == &hmp->fchain)
716 kprintf("(FLUSHED FREEMAP HEADER)\n");
718 if ((chain->flags & HAMMER2_CHAIN_MOVED) ||
719 chain == &hmp->vchain ||
720 chain == &hmp->fchain) {
722 * Drop the ref from the MODIFIED bit we cleared.
723 * Net is -0 or -1 ref depending.
726 hammer2_chain_drop(chain);
729 * Drop the ref from the MODIFIED bit we cleared and
730 * set a ref for the MOVED bit we are setting. Net
731 * is +0 or +1 ref depending.
733 if (wasmodified == 0)
734 hammer2_chain_ref(chain);
735 atomic_set_int(&chain->flags, HAMMER2_CHAIN_MOVED);
739 * If this is part of a recursive flush we can go ahead and write
740 * out the buffer cache buffer and pass a new bref back up the chain
743 * Volume headers are NOT flushed here as they require special
746 switch(chain->bref.type) {
747 case HAMMER2_BREF_TYPE_FREEMAP:
748 hammer2_modify_volume(hmp);
749 hmp->voldata.freemap_tid = chain->bref.mirror_tid;
751 case HAMMER2_BREF_TYPE_VOLUME:
753 * We should flush the free block table before we calculate
754 * CRCs and copy voldata -> volsync.
756 * To prevent SMP races, fchain must remain locked until
757 * voldata is copied to volsync.
759 hammer2_chain_lock(&hmp->fchain, HAMMER2_RESOLVE_ALWAYS);
760 if ((hmp->fchain.flags & HAMMER2_CHAIN_MODIFIED) ||
761 hmp->voldata.freemap_tid < hmp->fchain.core->update_tid) {
762 /* this will modify vchain as a side effect */
763 hammer2_chain_t *tmp = &hmp->fchain;
764 hammer2_chain_flush(info->trans, &tmp);
765 KKASSERT(tmp == &hmp->fchain);
767 hmp->voldata.mirror_tid = chain->bref.mirror_tid;
770 * The volume header is flushed manually by the syncer, not
771 * here. All we do is adjust the crc's.
773 KKASSERT(chain->data != NULL);
774 KKASSERT(chain->bp == NULL);
775 kprintf("volume header mirror_tid %jd\n",
776 hmp->voldata.mirror_tid);
778 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT1]=
780 (char *)&hmp->voldata +
781 HAMMER2_VOLUME_ICRC1_OFF,
782 HAMMER2_VOLUME_ICRC1_SIZE);
783 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT0]=
785 (char *)&hmp->voldata +
786 HAMMER2_VOLUME_ICRC0_OFF,
787 HAMMER2_VOLUME_ICRC0_SIZE);
788 hmp->voldata.icrc_volheader =
790 (char *)&hmp->voldata +
791 HAMMER2_VOLUME_ICRCVH_OFF,
792 HAMMER2_VOLUME_ICRCVH_SIZE);
793 hmp->volsync = hmp->voldata;
794 atomic_set_int(&chain->flags, HAMMER2_CHAIN_VOLUMESYNC);
795 hammer2_chain_unlock(&hmp->fchain);
797 case HAMMER2_BREF_TYPE_DATA:
799 * Data elements have already been flushed via the logical
800 * file buffer cache. Their hash was set in the bref by
801 * the vop_write code.
803 * Make sure any device buffer(s) have been flushed out here.
804 * (there aren't usually any to flush).
806 psize = hammer2_devblksize(chain->bytes);
807 pmask = (hammer2_off_t)psize - 1;
808 pbase = chain->bref.data_off & ~pmask;
809 boff = chain->bref.data_off & (HAMMER2_OFF_MASK & pmask);
811 bp = getblk(hmp->devvp, pbase, psize, GETBLK_NOWAIT, 0);
813 if ((bp->b_flags & (B_CACHE | B_DIRTY)) ==
814 (B_CACHE | B_DIRTY)) {
817 bp->b_flags |= B_RELBUF;
823 case HAMMER2_BREF_TYPE_INDIRECT:
825 * Indirect blocks may be in an INITIAL state. Use the
826 * chain_lock() call to ensure that the buffer has been
827 * instantiated (even though it is already locked the buffer
828 * might not have been instantiated).
830 * Only write the buffer out if it is dirty, it is possible
831 * the operating system had already written out the buffer.
833 hammer2_chain_lock(chain, HAMMER2_RESOLVE_ALWAYS);
834 KKASSERT(chain->bp != NULL);
837 if ((chain->flags & HAMMER2_CHAIN_DIRTYBP) ||
838 (bp->b_flags & B_DIRTY)) {
845 hammer2_chain_unlock(chain);
848 case HAMMER2_BREF_TYPE_INDIRECT:
849 case HAMMER2_BREF_TYPE_FREEMAP_NODE:
851 * Device-backed. Buffer will be flushed by the sync
854 KKASSERT((chain->flags & HAMMER2_CHAIN_EMBEDDED) == 0);
856 case HAMMER2_BREF_TYPE_FREEMAP_LEAF:
859 * Embedded elements have to be flushed out.
860 * (Basically just BREF_TYPE_INODE).
862 KKASSERT(chain->flags & HAMMER2_CHAIN_EMBEDDED);
863 KKASSERT(chain->data != NULL);
864 KKASSERT(chain->bp == NULL);
867 KKASSERT((bref->data_off & HAMMER2_OFF_MASK) != 0);
868 KKASSERT(HAMMER2_DEC_CHECK(chain->bref.methods) ==
869 HAMMER2_CHECK_ISCSI32 ||
870 HAMMER2_DEC_CHECK(chain->bref.methods) ==
871 HAMMER2_CHECK_FREEMAP);
874 * The data is embedded, we have to acquire the
875 * buffer cache buffer and copy the data into it.
877 psize = hammer2_devblksize(chain->bytes);
878 pmask = (hammer2_off_t)psize - 1;
879 pbase = bref->data_off & ~pmask;
880 boff = bref->data_off & (HAMMER2_OFF_MASK & pmask);
883 * The getblk() optimization can only be used if the
884 * physical block size matches the request.
886 error = bread(hmp->devvp, pbase, psize, &bp);
887 KKASSERT(error == 0);
889 bdata = (char *)bp->b_data + boff;
892 * Copy the data to the buffer, mark the buffer
893 * dirty, and convert the chain to unmodified.
895 bcopy(chain->data, bdata, chain->bytes);
896 bp->b_flags |= B_CLUSTEROK;
900 switch(HAMMER2_DEC_CHECK(chain->bref.methods)) {
901 case HAMMER2_CHECK_FREEMAP:
902 chain->bref.check.freemap.icrc32 =
903 hammer2_icrc32(chain->data, chain->bytes);
905 case HAMMER2_CHECK_ISCSI32:
906 chain->bref.check.iscsi32.value =
907 hammer2_icrc32(chain->data, chain->bytes);
910 panic("hammer2_flush_core: bad crc type");
911 break; /* NOT REACHED */
913 if (chain->bref.type == HAMMER2_BREF_TYPE_INODE)
914 ++hammer2_iod_meta_write;
916 ++hammer2_iod_indr_write;
921 * Flush helper scan1 (recursive)
923 * Flushes the children of the caller's chain (parent) and updates
924 * the blockref, restricted by sync_tid.
926 * Ripouts during the loop should not cause any problems. Because we are
927 * flushing to a synchronization point, modification races will occur after
928 * sync_tid and do not have to be flushed anyway.
930 * It is also ok if the parent is chain_duplicate()'d while unlocked because
931 * the delete/duplication will install a delete_tid that is still larger than
932 * our current sync_tid.
935 hammer2_chain_flush_scan1(hammer2_chain_t *child, void *data)
937 hammer2_flush_info_t *info = data;
938 hammer2_trans_t *trans = info->trans;
939 hammer2_chain_t *parent = info->parent;
943 * Child is beyond the flush synchronization zone, don't persue.
944 * Remember that modifications generally delete-duplicate so if the
945 * sub-tree is dirty another child will get us there. But not this
948 * Or MODIFIED is not set and child is already fully synchronized
949 * with its sub-tree. Don't persue.
951 if (child->modify_tid > trans->sync_tid) {
952 KKASSERT(child->delete_tid >= child->modify_tid);
953 child->debug_reason = (child->debug_reason & ~255) | 1;
958 * We must ref the child before unlocking the spinlock.
960 * The caller has added a ref to the parent so we can temporarily
961 * unlock it in order to lock the child.
963 hammer2_chain_ref(child);
964 spin_unlock(&parent->core->cst.spin);
966 hammer2_chain_unlock(parent);
967 hammer2_chain_lock(child, HAMMER2_RESOLVE_MAYBE);
969 if ((child->flags & HAMMER2_CHAIN_MODIFIED) == 0 &&
970 (child->bref.mirror_tid >= child->core->update_tid ||
971 child->bref.mirror_tid >= info->sync_tid)) {
972 child->debug_reason = (child->debug_reason & ~255) | 2;
977 * Re-check the flags before continuing.
979 if (child->modify_tid > trans->sync_tid) {
980 child->debug_reason = (child->debug_reason & ~255) | 3;
981 hammer2_chain_unlock(child);
982 hammer2_chain_drop(child);
983 hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
984 spin_lock(&parent->core->cst.spin);
988 if ((child->flags & HAMMER2_CHAIN_MODIFIED) == 0 &&
989 (child->bref.mirror_tid >= child->core->update_tid ||
990 child->bref.mirror_tid >= info->sync_tid)) {
991 child->debug_reason = (child->debug_reason & ~255) | 4;
996 * The DESTROYED flag can only be initially set on an unreferenced
997 * deleted inode and will propagate downward via the mechanic below.
998 * Such inode chains have been deleted for good and should no longer
999 * be subject to delete/duplication.
1001 * This optimization allows the inode reclaim (destroy unlinked file
1002 * on vnode reclamation after last close) to be flagged by just
1003 * setting HAMMER2_CHAIN_DESTROYED at the top level and then will
1004 * cause the chains to be terminated and related buffers to be
1005 * invalidated and not flushed out.
1007 * We have to be careful not to propagate the DESTROYED flag if
1008 * the destruction occurred after our flush sync_tid.
1010 if ((parent->flags & HAMMER2_CHAIN_DESTROYED) &&
1011 (child->flags & HAMMER2_CHAIN_DELETED) &&
1012 (child->flags & HAMMER2_CHAIN_DESTROYED) == 0) {
1013 atomic_set_int(&child->flags, HAMMER2_CHAIN_DESTROYED);
1015 * Force downward recursion by bringing update_tid up to
1016 * at least sync_tid. Parent's mirror_tid has not yet
1019 * Vnode reclamation may have forced update_tid to MAX_TID
1020 * (we do this because there was no transaction at the time).
1021 * In this situation bring it down to something reasonable
1022 * so the elements being destroyed can be retired.
1024 spin_lock(&child->core->cst.spin);
1025 if (child->core->update_tid < trans->sync_tid ||
1026 child->core->update_tid == HAMMER2_MAX_TID) {
1027 child->core->update_tid = trans->sync_tid;
1029 spin_unlock(&child->core->cst.spin);
1033 * Recurse and collect deferral data.
1035 diddeferral = info->diddeferral;
1037 hammer2_chain_flush_core(info, &child);
1040 * NOTE: If child failed to fully synchronize, child's bref.mirror_tid
1041 * will not have been updated. Bumping diddeferral prevents
1042 * the parent chain from updating bref.mirror_tid on the way
1043 * back up in order to force a retry later.
1045 if (child->bref.mirror_tid < child->core->update_tid &&
1046 child->bref.mirror_tid < info->sync_tid) {
1051 info->diddeferral += diddeferral;
1055 * Check the conditions that could cause SCAN2 to modify the parent.
1056 * Modify the parent here instead of in SCAN2, which would cause
1057 * rollup chicken-and-egg races.
1059 if (child->delete_tid <= trans->sync_tid &&
1060 child->delete_tid > parent->bref.mirror_tid &&
1061 child->modify_tid <= parent->bref.mirror_tid) {
1063 } else if (child->delete_tid > trans->sync_tid &&
1064 child->modify_tid > parent->bref.mirror_tid) {
1069 * Relock to continue the loop
1071 hammer2_chain_unlock(child);
1072 hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
1073 hammer2_chain_drop(child);
1074 KKASSERT(info->parent == parent);
1076 spin_lock(&parent->core->cst.spin);
1081 * Flush helper scan2 (non-recursive)
1083 * This pass on a chain's children propagates any MOVED or DELETED
1084 * elements back up the chain towards the root after those elements have
1085 * been fully flushed. Unlike scan1, this function is NOT recursive and
1086 * the parent remains locked across the entire scan.
1088 * SCAN2 is called twice, once with pass set to 1 and once with it set to 2.
1089 * We have to do this so base[] elements can be deleted in pass 1 to make
1090 * room for adding new elements in pass 2.
1092 * This function also rolls up storage statistics.
1094 * NOTE! A deletion is a visbility issue, there can still be references to
1095 * deleted elements (for example, to an unlinked file which is still
1096 * open), and there can also be multiple chains pointing to the same
1097 * bref where some are deleted and some are not (for example due to
1098 * a rename). So a chain marked for deletion is basically considered
1099 * to be live until it is explicitly destroyed or until its ref-count
1100 * reaches zero (also implying that MOVED and MODIFIED are clear).
1102 * NOTE! Info->parent will be locked but will only be instantiated/modified
1103 * if it is either MODIFIED or if scan1 determined that block table
1104 * updates will occur.
1107 hammer2_chain_flush_scan2(hammer2_chain_t *child, void *data)
1109 hammer2_flush_info_t *info = data;
1110 hammer2_chain_t *parent = info->parent;
1111 hammer2_chain_core_t *above = child->above;
1112 hammer2_mount_t *hmp = child->hmp;
1113 hammer2_trans_t *trans = info->trans;
1114 hammer2_blockref_t *base;
1119 kprintf("SCAN2 %p.%d %08x mod=%016jx del=%016jx trans=%016jx\n", child, child->bref.type, child->flags, child->modify_tid, child->delete_tid, info->trans->sync_tid);
1122 * Inodes with stale children that have been converted to DIRECTDATA
1123 * mode (file extension or hardlink conversion typically) need to
1124 * skipped right now before we start messing with a non-existant
1128 if (parent->bref.type == HAMMER2_BREF_TYPE_INODE &&
1129 (parent->data->ipdata.op_flags & HAMMER2_OPFLAG_DIRECTDATA)) {
1135 * Ignore children created after our flush point, treating them as
1136 * if they did not exist). These children will not cause the parent
1139 * Children deleted after our flush point are treated as having been
1140 * created for the purposes of the flush. The parent's update_tid
1141 * will already be higher than our trans->sync_tid so the flush path
1144 * When we encounter such children and the parent chain has not been
1145 * deleted, delete/duplicated, or delete/duplicated-for-move, then
1146 * the parent may be used to funnel through several flush points.
1147 * These chains will still be visible to later flushes due to having
1148 * a higher update_tid than we can set in the current flush.
1150 if (child->modify_tid > trans->sync_tid) {
1151 KKASSERT(child->delete_tid >= child->modify_tid);
1156 * Ignore children which have not changed. The parent's block table
1157 * is already correct.
1159 * XXX The MOVED bit is only cleared when all multi-homed parents
1160 * have flushed, creating a situation where a re-flush can occur
1161 * via a parent which has already flushed. The hammer2_base_*()
1162 * functions currently have a hack to deal with this case but
1163 * we need something better.
1165 if ((child->flags & HAMMER2_CHAIN_MOVED) == 0) {
1166 KKASSERT((child->flags & HAMMER2_CHAIN_MODIFIED) == 0);
1171 * Make sure child is referenced before we unlock.
1173 hammer2_chain_ref(child);
1174 spin_unlock(&above->cst.spin);
1177 * Parent reflushed after the child has passed them by should skip
1178 * due to the modify_tid test. XXX
1180 hammer2_chain_lock(child, HAMMER2_RESOLVE_NEVER);
1181 KKASSERT(child->above == above);
1182 KKASSERT(parent->core == above);
1185 * The parent's blockref to the child must be deleted or updated.
1187 * This point is not reached on successful DESTROYED optimizations
1188 * but can be reached on recursive deletions and restricted flushes.
1190 * The chain_modify here may delete-duplicate the block. This can
1191 * cause a multitude of issues if the block was already modified
1192 * by a later (post-flush) transaction. Primarily blockrefs in
1193 * the later block can be out-of-date, so if the situation occurs
1194 * we can't throw away the MOVED bit on the current blocks until
1195 * the later blocks are flushed (so as to be able to regenerate all
1196 * the changes that were made).
1198 * Because flushes are ordered we do not have to make a
1199 * modify/duplicate of indirect blocks. That is, the flush
1200 * code does not have to kmalloc or duplicate anything. We
1201 * can adjust the indirect block table in-place and reuse the
1202 * chain. It IS possible that the chain has already been duplicated
1203 * or may wind up being duplicated on-the-fly by modifying code
1204 * on the frontend. We simply use the original and ignore such
1205 * chains. However, it does mean we can't clear the MOVED bit.
1207 * XXX recursive deletions not optimized.
1210 switch(parent->bref.type) {
1211 case HAMMER2_BREF_TYPE_INODE:
1213 * XXX Should assert that OPFLAG_DIRECTDATA is 0 once we
1214 * properly duplicate the inode headers and do proper flush
1215 * range checks (all the children should be beyond the flush
1216 * point). For now just don't sync the non-applicable
1219 * XXX Can also occur due to hardlink consolidation. We
1220 * set OPFLAG_DIRECTDATA to prevent the indirect and data
1221 * blocks from syncing ot the hardlink pointer.
1224 base = &parent->data->ipdata.u.blockset.blockref[0];
1227 count = HAMMER2_SET_COUNT;
1229 case HAMMER2_BREF_TYPE_INDIRECT:
1230 case HAMMER2_BREF_TYPE_FREEMAP_NODE:
1232 base = &parent->data->npdata[0];
1235 count = parent->bytes / sizeof(hammer2_blockref_t);
1237 case HAMMER2_BREF_TYPE_VOLUME:
1238 base = &hmp->voldata.sroot_blockset.blockref[0];
1239 count = HAMMER2_SET_COUNT;
1241 case HAMMER2_BREF_TYPE_FREEMAP:
1242 base = &parent->data->npdata[0];
1243 count = HAMMER2_SET_COUNT;
1248 panic("hammer2_chain_flush_scan2: "
1249 "unrecognized blockref type: %d",
1254 * Don't bother updating a deleted parent's blockrefs (caller will
1255 * optimize-out the disk write). Note that this is not optional,
1256 * a deleted parent's blockref array might not be synchronized at
1257 * all so calling hammer2_base*() functions could result in a panic.
1259 * Otherwise, we need to be COUNTEDBREFS synchronized for the
1260 * hammer2_base_*() functions.
1263 kprintf("SCAN2 base=%p pass=%d PARENT %p.%d DTID=%016jx SYNC=%016jx\n",
1265 info->pass, parent, parent->bref.type, parent->delete_tid, trans->sync_tid);
1267 if (parent->delete_tid <= trans->sync_tid)
1269 else if ((parent->core->flags & HAMMER2_CORE_COUNTEDBREFS) == 0)
1270 hammer2_chain_countbrefs(parent, base, count);
1273 * Update the parent's blockref table and propagate mirror_tid.
1275 * NOTE! Children with modify_tid's beyond our flush point are
1276 * considered to not exist for the purposes of updating the
1277 * parent's blockref array.
1279 * NOTE! Updates to a parent's blockref table do not adjust the
1280 * parent's bref.modify_tid, only its bref.mirror_tid.
1282 * SCAN1 has already put the parent in a modified state
1283 * so if it isn't we panic.
1285 * NOTE! chain->modify_tid vs chain->bref.modify_tid. The chain's
1286 * internal modify_tid is always updated based on creation
1287 * or delete-duplicate. However, the bref.modify_tid is NOT
1288 * updated due to simple blockref updates.
1291 kprintf("chain %p->%p pass %d trans %016jx sync %p.%d %016jx/%d C=%016jx D=%016jx PMIRROR %016jx\n",
1293 info->pass, trans->sync_tid,
1294 child, child->bref.type,
1295 child->bref.key, child->bref.keybits,
1296 child->modify_tid, child->delete_tid, parent->bref.mirror_tid);
1299 if (info->pass == 1 && child->delete_tid <= trans->sync_tid) {
1301 * Deleting. The block array is expected to contain the
1304 * (1) The deletion occurred after the parent's block table
1305 * was last synchronized (delete_tid), and
1307 * (2) The creation occurred before or during the parent's
1308 * last block table synchronization.
1311 kprintf("S2A %p b=%p d/b=%016jx/%016jx m/b=%016jx/%016jx\n",
1312 child, base, child->delete_tid, parent->bref.mirror_tid,
1313 child->modify_tid, parent->bref.mirror_tid);
1317 child->delete_tid > parent->bref.mirror_tid &&
1318 child->modify_tid <= parent->bref.mirror_tid) {
1319 KKASSERT(parent->modify_tid == trans->sync_tid);
1320 hammer2_rollup_stats(parent, child, -1);
1321 spin_lock(&above->cst.spin);
1323 kprintf("trans %jx parent %p.%d child %p.%d m/d %016jx/%016jx "
1324 "flg=%08x %016jx/%d delete\n",
1326 parent, parent->bref.type,
1327 child, child->bref.type,
1328 child->modify_tid, child->delete_tid,
1330 child->bref.key, child->bref.keybits);
1332 hammer2_base_delete(parent, base, count,
1333 &info->cache_index, child);
1334 spin_unlock(&above->cst.spin);
1336 if (info->mirror_tid < child->delete_tid)
1337 info->mirror_tid = child->delete_tid;
1338 } else if (info->pass == 2 && child->delete_tid > trans->sync_tid) {
1340 * Inserting. The block array is expected to NOT contain
1341 * the child's entry if:
1343 * (1) The creation occurred after the parent's block table
1344 * was last synchronized (modify_tid), and
1346 * (2) The child is not being deleted in the same
1351 child->modify_tid > parent->bref.mirror_tid) {
1352 KKASSERT(parent->modify_tid == trans->sync_tid);
1353 hammer2_rollup_stats(parent, child, 1);
1354 spin_lock(&above->cst.spin);
1356 kprintf("trans %jx parent %p.%d child %p.%d m/d %016jx/%016jx "
1357 "flg=%08x %016jx/%d insert\n",
1359 parent, parent->bref.type,
1360 child, child->bref.type,
1361 child->modify_tid, child->delete_tid,
1363 child->bref.key, child->bref.keybits);
1365 hammer2_base_insert(parent, base, count,
1366 &info->cache_index, child);
1367 spin_unlock(&above->cst.spin);
1369 if (info->mirror_tid < child->modify_tid)
1370 info->mirror_tid = child->modify_tid;
1375 if (info->mirror_tid < child->bref.mirror_tid) {
1376 KKASSERT(child->bref.mirror_tid <= trans->sync_tid);
1377 info->mirror_tid = child->bref.mirror_tid;
1381 * Only clear MOVED once all possible parents have been flushed.
1383 * When can we safely clear the MOVED flag? Flushes down duplicate
1384 * paths can occur out of order, for example if an inode is moved
1385 * as part of a hardlink consolidation or if an inode is moved into
1386 * an indirect block indexed before the inode.
1388 if (ok && (child->flags & HAMMER2_CHAIN_MOVED)) {
1389 hammer2_chain_t *scan;
1391 if (hammer2_debug & 0x4000)
1392 kprintf("CHECKMOVED %p (parent=%p)", child, parent);
1394 spin_lock(&above->cst.spin);
1395 TAILQ_FOREACH(scan, &above->ownerq, core_entry) {
1397 * Can't clear child's MOVED until all parent's have
1398 * synchronized with it.
1400 * Ignore our current parent (we use 'ok' from above),
1402 * ignore any parents which have been deleted as-of
1403 * our transaction id (their block array doesn't get
1406 if (scan == parent ||
1407 scan->delete_tid <= trans->sync_tid)
1411 * parent not synchronized if child modified or
1412 * deleted after the parent's last sync point.
1414 * (For the purpose of clearing the MOVED bit
1415 * we do not restrict the tests to just flush
1418 if (scan->bref.mirror_tid < child->modify_tid ||
1419 ((child->flags & HAMMER2_CHAIN_DELETED) &&
1420 scan->bref.mirror_tid < child->delete_tid)) {
1421 if (hammer2_debug & 0x4000)
1422 kprintf("(fail scan %p %016jx/%016jx)",
1423 scan, scan->bref.mirror_tid,
1428 if (hammer2_debug & 0x4000)
1430 spin_unlock(&above->cst.spin);
1433 * Can we finally clear MOVED?
1436 if (hammer2_debug & 0x4000)
1437 kprintf("clear moved %p.%d %016jx/%d\n",
1438 child, child->bref.type,
1439 child->bref.key, child->bref.keybits);
1440 if (child->modify_tid <= trans->sync_tid &&
1441 (child->delete_tid == HAMMER2_MAX_TID ||
1442 child->delete_tid <= trans->sync_tid)) {
1443 atomic_clear_int(&child->flags,
1444 HAMMER2_CHAIN_MOVED);
1445 hammer2_chain_drop(child); /* flag */
1446 KKASSERT((child->flags &
1447 HAMMER2_CHAIN_MODIFIED) == 0);
1449 kprintf("ok problem child %p %016jx/%016jx vs %016jx\n", child, child->modify_tid, child->delete_tid, trans->sync_tid);
1452 if (hammer2_debug & 0x4000)
1453 kprintf("keep moved %p.%d %016jx/%d\n",
1454 child, child->bref.type,
1455 child->bref.key, child->bref.keybits);
1460 * Unlock the child. This can wind up dropping the child's
1461 * last ref, removing it from the parent's RB tree, and deallocating
1462 * the structure. The RB_SCAN() our caller is doing handles the
1465 hammer2_chain_unlock(child);
1466 hammer2_chain_drop(child);
1467 spin_lock(&above->cst.spin);
1470 * The parent may have been delete-duplicated.
1472 info->parent = parent;
1479 hammer2_rollup_stats(hammer2_chain_t *parent, hammer2_chain_t *child, int how)
1482 hammer2_chain_t *grandp;
1485 parent->data_count += child->data_count;
1486 parent->inode_count += child->inode_count;
1487 child->data_count = 0;
1488 child->inode_count = 0;
1490 parent->data_count -= child->bytes;
1491 if (child->bref.type == HAMMER2_BREF_TYPE_INODE) {
1492 parent->inode_count -= 1;
1494 /* XXX child->data may be NULL atm */
1495 parent->data_count -= child->data->ipdata.data_count;
1496 parent->inode_count -= child->data->ipdata.inode_count;
1499 } else if (how > 0) {
1500 parent->data_count += child->bytes;
1501 if (child->bref.type == HAMMER2_BREF_TYPE_INODE) {
1502 parent->inode_count += 1;
1504 /* XXX child->data may be NULL atm */
1505 parent->data_count += child->data->ipdata.data_count;
1506 parent->inode_count += child->data->ipdata.inode_count;
1510 if (parent->bref.type == HAMMER2_BREF_TYPE_INODE) {
1511 parent->data->ipdata.data_count += parent->data_count;
1512 parent->data->ipdata.inode_count += parent->inode_count;
1514 for (grandp = parent->above->first_parent;
1516 grandp = grandp->next_parent) {
1517 grandp->data_count += parent->data_count;
1518 grandp->inode_count += parent->inode_count;
1521 parent->data_count = 0;
1522 parent->inode_count = 0;