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 {
54 hammer2_chain_t *parent;
55 hammer2_trans_t *trans;
58 struct flush_deferral_list flush_list;
59 hammer2_tid_t sync_tid; /* flush synchronization point */
60 hammer2_tid_t mirror_tid; /* collect mirror TID updates */
63 typedef struct hammer2_flush_info hammer2_flush_info_t;
65 static void hammer2_chain_flush_core(hammer2_flush_info_t *info,
66 hammer2_chain_t *chain);
67 static int hammer2_chain_flush_scan1(hammer2_chain_t *child, void *data);
68 static int hammer2_chain_flush_scan2(hammer2_chain_t *child, void *data);
71 * Transaction support functions for writing to the filesystem.
73 * Initializing a new transaction allocates a transaction ID. We
74 * don't bother marking the volume header MODIFIED. Instead, the volume
75 * will be synchronized at a later time as part of a larger flush sequence.
77 * WARNING! Modifications to the root volume cannot dup the root volume
78 * header to handle synchronization points, so alloc_tid can
79 * wind up (harmlessly) more advanced on flush.
81 * WARNING! Operations which might call inode_duplicate()/chain_duplicate()
82 * depend heavily on having a unique sync_tid to avoid duplication
83 * collisions (which key off of delete_tid).
86 hammer2_trans_init(hammer2_mount_t *hmp, hammer2_trans_t *trans)
88 bzero(trans, sizeof(*trans));
90 hammer2_voldata_lock(hmp);
91 trans->sync_tid = hmp->voldata.alloc_tid++;
92 hammer2_voldata_unlock(hmp, 0);
96 hammer2_trans_init_flush(hammer2_mount_t *hmp, hammer2_trans_t *trans,
99 thread_t td = curthread;
101 bzero(trans, sizeof(*trans));
104 hammer2_voldata_lock(hmp);
107 * New master flush (sync).
109 while (hmp->flush_td) {
111 lksleep(&hmp->flush_wait, &hmp->voldatalk,
115 hmp->flush_tid = hmp->voldata.alloc_tid++;
116 trans->sync_tid = hmp->flush_tid;
117 } else if (hmp->flush_td == td) {
119 * Part of a running master flush (sync->fsync)
121 trans->sync_tid = hmp->flush_tid;
122 KKASSERT(trans->sync_tid != 0);
125 * Independent flush request, make sure the sync_tid
126 * covers all modifications made to date.
128 trans->sync_tid = hmp->voldata.alloc_tid++;
130 hammer2_voldata_unlock(hmp, 0);
134 hammer2_trans_done(hammer2_trans_t *trans)
140 hammer2_trans_done_flush(hammer2_trans_t *trans, int master)
142 hammer2_mount_t *hmp = trans->hmp;
144 hammer2_voldata_lock(hmp);
146 hmp->flush_td = NULL;
147 if (hmp->flush_wait) {
149 wakeup(&hmp->flush_wait);
152 hammer2_voldata_unlock(hmp, 0);
158 * Flush the chain and all modified sub-chains through the specified
159 * synchronization point (sync_tid), propagating parent chain modifications
160 * and mirror_tid updates back up as needed. Since we are recursing downward
161 * we do not have to deal with the complexities of multi-homed chains (chains
162 * with multiple parents).
164 * Caller must have interlocked against any non-flush-related modifying
165 * operations in progress whos modify_tid values are less than or equal
166 * to the passed sync_tid.
168 * Caller must have already vetted synchronization points to ensure they
169 * are properly flushed. Only snapshots and cluster flushes can create
170 * these sorts of synchronization points.
172 * SUBMODIFIED is not cleared if modified elements with higher modify_tid
173 * values (thus not flushed) are still present after the flush.
175 * If a chain is unable to completely flush we have to be sure that
176 * SUBMODIFIED remains set up the parent chain, and that MOVED is not
177 * cleared or our desynchronized bref will not properly update in the
178 * parent. The parent's indirect block is copied-on-write and adjusted
179 * as needed so it no longer needs to be placemarked by the subchains,
180 * allowing the sub-chains to be cleaned out.
182 * This routine can be called from several places but the most important
183 * is from the hammer2_vop_reclaim() function. We want to try to completely
184 * clean out the inode structure to prevent disconnected inodes from
185 * building up and blowing out the kmalloc pool. However, it is not actually
186 * necessary to flush reclaimed inodes to maintain HAMMER2's crash recovery
189 * chain is locked on call and will remain locked on return. If a flush
190 * occured, the chain's MOVED bit will be set indicating that its parent
191 * (which is not part of the flush) should be updated.
194 hammer2_chain_flush(hammer2_trans_t *trans, hammer2_chain_t *chain)
196 hammer2_chain_t *scan;
197 hammer2_flush_info_t info;
200 * Execute the recursive flush and handle deferrals.
202 * Chains can be ridiculously long (thousands deep), so to
203 * avoid blowing out the kernel stack the recursive flush has a
204 * depth limit. Elements at the limit are placed on a list
205 * for re-execution after the stack has been popped.
207 bzero(&info, sizeof(info));
208 TAILQ_INIT(&info.flush_list);
209 info.hmp = trans->hmp;
211 info.sync_tid = trans->sync_tid;
216 * Unwind deep recursions which had been deferred. This
217 * can leave MOVED set for these chains, which will be
218 * handled when we [re]flush chain after the unwind.
220 while ((scan = TAILQ_FIRST(&info.flush_list)) != NULL) {
221 KKASSERT(scan->flags & HAMMER2_CHAIN_DEFERRED);
222 TAILQ_REMOVE(&info.flush_list, scan, flush_node);
223 atomic_clear_int(&scan->flags, HAMMER2_CHAIN_DEFERRED);
226 * Now that we've popped back up we can do a secondary
227 * recursion on the deferred elements.
229 if (hammer2_debug & 0x0040)
230 kprintf("defered flush %p\n", scan);
231 hammer2_chain_lock(scan, HAMMER2_RESOLVE_MAYBE);
232 hammer2_chain_flush(trans, scan);
233 hammer2_chain_unlock(scan);
234 hammer2_chain_drop(scan); /* ref from deferral */
238 * Flush pass1 on root. SUBMODIFIED can remain set after
239 * this call for numerous reasons, including write failures,
240 * but most likely due to only a partial flush being
241 * requested or the chain element belongs to the wrong
242 * synchronization point.
244 info.diddeferral = 0;
245 hammer2_chain_flush_core(&info, chain);
247 kprintf("flush_core_done parent=<base> chain=%p.%d %08x\n",
248 chain, chain->bref.type, chain->flags);
252 * Only loop if deep recursions have been deferred.
254 if (TAILQ_EMPTY(&info.flush_list))
259 * SUBMODIFIED can be temporarily cleared and then re-set, which
260 * can prevent concurrent setsubmods from reaching all the way to
261 * the root. If after the flush we find the node is still in need
262 * of flushing (though possibly due to modifications made outside
263 * the requested synchronization zone), we must call setsubmod again
266 if (chain->flags & (HAMMER2_CHAIN_MOVED |
267 HAMMER2_CHAIN_DELETED |
268 HAMMER2_CHAIN_MODIFIED |
269 HAMMER2_CHAIN_SUBMODIFIED)) {
270 hammer2_chain_parent_setsubmod(chain);
275 * This is the core of the chain flushing code. The chain is locked by the
276 * caller and remains locked on return. This function is keyed off of
277 * the SUBMODIFIED bit but must make fine-grained choices based on the
278 * synchronization point we are flushing to.
280 * If the flush accomplished any work chain will be flagged MOVED
281 * indicating a copy-on-write propagation back up is required.
282 * Deep sub-nodes may also have been entered onto the deferral list.
283 * MOVED is never set on the volume root.
285 * NOTE: modify_tid is different from MODIFIED. modify_tid is updated
286 * only when a chain is specifically modified, and not updated
287 * for copy-on-write propagations. MODIFIED is set on any modification
288 * including copy-on-write propagations.
291 hammer2_chain_flush_core(hammer2_flush_info_t *info, hammer2_chain_t *chain)
293 hammer2_mount_t *hmp;
294 hammer2_blockref_t *bref;
296 hammer2_tid_t saved_sync;
309 kprintf("flush_core %p->%p.%d %08x (%s)\n",
310 info->parent, chain, chain->bref.type,
312 ((chain->bref.type == HAMMER2_BREF_TYPE_INODE) ?
313 chain->data->ipdata.filename : "?"));
315 kprintf("flush_core NULL->%p.%d %08x (%s)\n",
316 chain, chain->bref.type,
318 ((chain->bref.type == HAMMER2_BREF_TYPE_INODE) ?
319 chain->data->ipdata.filename : "?"));
324 * A chain modified beyond our flush point is ignored by the current
325 * flush. We could safely flush such chains if we wanted to (they
326 * just wouldn't propagate back up and be left with MOVED set), but
327 * doing so could lead to an infinite flush loop under heavy
328 * filesystem write loads. By ignoring such elements the flush
329 * will only deal with changes as-of when the flush was started.
331 * NOTE: Unmodified chains set modify_tid to 0, allowing us to reach
334 if (chain->modify_tid > info->sync_tid)
339 * Restrict the synchronization point when we encounter a
340 * delete/duplicate chain. We do not do this for deletions
341 * at the end of the linked list because they represent an
342 * operation occuring within the flush range, whereas flushes
343 * through deleted chains which have been duplicated represent
344 * only changes made through that deletion point.
346 saved_sync = info->sync_tid;
348 if (chain->duplink && (chain->flags & HAMMER2_CHAIN_DELETED) &&
349 chain->delete_tid < saved_sync) {
350 info->sync_tid = chain->delete_tid;
355 * If SUBMODIFIED is set we recurse the flush and adjust the
356 * blockrefs accordingly.
358 * NOTE: Looping on SUBMODIFIED can prevent a flush from ever
359 * finishing in the face of filesystem activity.
361 if (chain->flags & HAMMER2_CHAIN_SUBMODIFIED) {
362 hammer2_chain_t *saved_parent;
363 hammer2_tid_t saved_mirror;
366 * Clear SUBMODIFIED to catch races. Note that any child
367 * with MODIFIED, DELETED, or MOVED set during Scan2, after
368 * it processes the child, will cause SUBMODIFIED to be
370 * child has to be flushed SUBMODIFIED will wind up being
371 * set again (for next time), but this does not stop us from
372 * synchronizing block updates which occurred.
374 * We don't want to set our chain to MODIFIED gratuitously.
376 * We need an extra ref on chain because we are going to
377 * release its lock temporarily in our child loop.
379 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_SUBMODIFIED);
380 hammer2_chain_ref(chain);
383 * Run two passes. The first pass handles MODIFIED and
384 * SUBMODIFIED chains and recurses while the second pass
385 * handles MOVED chains on the way back up.
387 * If the stack gets too deep we defer scan1, but must
388 * be sure to still run scan2 if on the next loop the
389 * deferred chain has been flushed and now needs MOVED
390 * handling on the way back up.
392 * Scan1 is recursive.
394 * NOTE: The act of handling a modified/submodified chain can
395 * cause the MOVED Flag to be set. It can also be set
396 * via hammer2_chain_delete() and in other situations.
398 * NOTE: RB_SCAN() must be used instead of RB_FOREACH()
399 * because children can be physically removed during
402 saved_parent = info->parent;
403 saved_mirror = info->mirror_tid;
404 info->parent = chain;
405 info->mirror_tid = chain->bref.mirror_tid;
407 if (info->depth == HAMMER2_FLUSH_DEPTH_LIMIT) {
408 if ((chain->flags & HAMMER2_CHAIN_DEFERRED) == 0) {
409 hammer2_chain_ref(chain);
410 TAILQ_INSERT_TAIL(&info->flush_list,
412 atomic_set_int(&chain->flags,
413 HAMMER2_CHAIN_DEFERRED);
417 info->diddeferral = 0;
418 spin_lock(&chain->core->cst.spin);
419 RB_SCAN(hammer2_chain_tree, &chain->core->rbtree,
420 NULL, hammer2_chain_flush_scan1, info);
421 spin_unlock(&chain->core->cst.spin);
422 diddeferral += info->diddeferral;
426 * Handle successfully flushed children who are in the MOVED
427 * state on the way back up the recursion. This can have
428 * the side-effect of clearing MOVED.
430 * We execute this even if there were deferrals to try to
431 * keep the chain topology cleaner.
433 * Scan2 is non-recursive.
436 kprintf("scan2_start parent %p %08x\n", chain, chain->flags);
438 spin_lock(&chain->core->cst.spin);
439 RB_SCAN(hammer2_chain_tree, &chain->core->rbtree,
440 NULL, hammer2_chain_flush_scan2, info);
441 spin_unlock(&chain->core->cst.spin);
443 kprintf("scan2_stop parent %p %08x\n", chain, chain->flags);
445 chain->bref.mirror_tid = info->mirror_tid;
446 info->mirror_tid = saved_mirror;
447 info->parent = saved_parent;
448 hammer2_chain_drop(chain);
452 * Restore sync_tid in case it was restricted by a delete/duplicate.
454 info->sync_tid = saved_sync;
457 * Rollup diddeferral for caller. Note direct assignment, not +=.
459 info->diddeferral = diddeferral;
462 * Do not flush chain if there were any deferrals. It will be
463 * retried later after the deferrals are independently handled.
466 if (hammer2_debug & 0x0008) {
467 kprintf("%*.*s} %p/%d %04x (deferred)",
468 info->depth, info->depth, "",
469 chain, chain->refs, chain->flags);
475 * The DESTROYED flag is set when an inode is physically deleted
476 * and no longer referenced (no open descriptors). We can
477 * safely clear the MODIFIED bit.
479 * The MOVED bit has to be left intact as this flags the zeroing
480 * of the bref in the parent chain.
484 * Chain objects flagged for complete destruction recurse down from
485 * their inode. The inode will have already been removed from
486 * its parent. We have no need to disconnect the children from
487 * their parents or the inode in this situation (it would just
488 * waste time and storage with copy-on-write operations), so
489 * we can clear both the MODIFIED bit and the MOVED bit.
491 * DESTROYED chains stop processing here.
493 if ((chain->flags & HAMMER2_CHAIN_DESTROYED) &&
494 (chain->flags & HAMMER2_CHAIN_DELETED)) {
496 (chain->delete_tid <= info->sync_tid)) {
498 if (chain->flags & HAMMER2_CHAIN_MODIFIED) {
500 chain->bp->b_flags |= B_INVAL|B_RELBUF;
501 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
502 hammer2_chain_drop(chain);
505 if (chain->flags & HAMMER2_CHAIN_MOVED) {
506 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MOVED);
507 hammer2_chain_drop(chain);
510 if (hammer2_debug & 0x0008) {
511 kprintf("%*.*s} %p/%d %04x (destroyed)",
512 info->depth, info->depth, "",
513 chain, chain->refs, chain->flags);
519 * A degenerate flush might not have flushed anything and thus not
520 * processed modified blocks on the way back up. Detect the case.
522 * Note that MOVED can be set without MODIFIED being set due to
523 * a deletion, in which case it is handled by Scan2 later on.
525 * Both bits can be set along with DELETED due to a deletion if
526 * modified data within the synchronization zone and the chain
527 * was then deleted beyond the zone, in which case we still have
528 * to flush for synchronization point consistency. Otherwise though
529 * DELETED and MODIFIED are treated as separate flags.
531 if ((chain->flags & HAMMER2_CHAIN_MODIFIED) == 0)
537 * A DESTROYED node that reaches this point must be flushed for
538 * synchronization point consistency.
542 * Update mirror_tid, clear MODIFIED, and set MOVED.
544 * The caller will update the parent's reference to this chain
545 * by testing MOVED as long as the modification was in-bounds.
547 * MOVED is never set on the volume root as there is no parent
550 if (chain->bref.mirror_tid < info->sync_tid)
551 chain->bref.mirror_tid = info->sync_tid;
552 wasmodified = (chain->flags & HAMMER2_CHAIN_MODIFIED) != 0;
553 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
554 if (chain == &hmp->vchain)
555 kprintf("(FLUSHED VOLUME HEADER)\n");
557 if ((chain->flags & HAMMER2_CHAIN_MOVED) ||
558 chain == &hmp->vchain) {
560 * Drop the ref from the MODIFIED bit we cleared.
563 hammer2_chain_drop(chain);
566 * If we were MODIFIED we inherit the ref from clearing
567 * that bit, otherwise we need another ref.
569 if (wasmodified == 0)
570 hammer2_chain_ref(chain);
571 atomic_set_int(&chain->flags, HAMMER2_CHAIN_MOVED);
575 * If this is part of a recursive flush we can go ahead and write
576 * out the buffer cache buffer and pass a new bref back up the chain
579 * Volume headers are NOT flushed here as they require special
582 switch(chain->bref.type) {
583 case HAMMER2_BREF_TYPE_VOLUME:
585 * The volume header is flushed manually by the syncer, not
586 * here. All we do is adjust the crc's.
588 KKASSERT(chain->data != NULL);
589 KKASSERT(chain->bp == NULL);
590 kprintf("volume header mirror_tid %jd\n",
591 hmp->voldata.mirror_tid);
593 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT1]=
595 (char *)&hmp->voldata +
596 HAMMER2_VOLUME_ICRC1_OFF,
597 HAMMER2_VOLUME_ICRC1_SIZE);
598 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT0]=
600 (char *)&hmp->voldata +
601 HAMMER2_VOLUME_ICRC0_OFF,
602 HAMMER2_VOLUME_ICRC0_SIZE);
603 hmp->voldata.icrc_volheader =
605 (char *)&hmp->voldata +
606 HAMMER2_VOLUME_ICRCVH_OFF,
607 HAMMER2_VOLUME_ICRCVH_SIZE);
608 hmp->volsync = hmp->voldata;
609 atomic_set_int(&chain->flags, HAMMER2_CHAIN_VOLUMESYNC);
611 case HAMMER2_BREF_TYPE_DATA:
613 * Data elements have already been flushed via the logical
614 * file buffer cache. Their hash was set in the bref by
615 * the vop_write code.
617 * Make sure any device buffer(s) have been flushed out here.
618 * (there aren't usually any to flush).
620 bbytes = chain->bytes;
621 pbase = chain->bref.data_off & ~(hammer2_off_t)(bbytes - 1);
622 boff = chain->bref.data_off & HAMMER2_OFF_MASK & (bbytes - 1);
624 bp = getblk(hmp->devvp, pbase, bbytes, GETBLK_NOWAIT, 0);
626 if ((bp->b_flags & (B_CACHE | B_DIRTY)) ==
627 (B_CACHE | B_DIRTY)) {
630 bp->b_flags |= B_RELBUF;
635 case HAMMER2_BREF_TYPE_INDIRECT:
637 * Indirect blocks may be in an INITIAL state. Use the
638 * chain_lock() call to ensure that the buffer has been
639 * instantiated (even though it is already locked the buffer
640 * might not have been instantiated).
642 * Only write the buffer out if it is dirty, it is possible
643 * the operating system had already written out the buffer.
645 hammer2_chain_lock(chain, HAMMER2_RESOLVE_ALWAYS);
646 KKASSERT(chain->bp != NULL);
649 if ((chain->flags & HAMMER2_CHAIN_DIRTYBP) ||
650 (bp->b_flags & B_DIRTY)) {
657 hammer2_chain_unlock(chain);
661 * Embedded elements have to be flushed out.
663 KKASSERT(chain->data != NULL);
664 KKASSERT(chain->bp == NULL);
667 KKASSERT((bref->data_off & HAMMER2_OFF_MASK) != 0);
668 KKASSERT(HAMMER2_DEC_CHECK(chain->bref.methods) ==
669 HAMMER2_CHECK_ISCSI32);
671 if (chain->bp == NULL) {
673 * The data is embedded, we have to acquire the
674 * buffer cache buffer and copy the data into it.
676 if ((bbytes = chain->bytes) < HAMMER2_MINIOSIZE)
677 bbytes = HAMMER2_MINIOSIZE;
678 pbase = bref->data_off & ~(hammer2_off_t)(bbytes - 1);
679 boff = bref->data_off & HAMMER2_OFF_MASK & (bbytes - 1);
682 * The getblk() optimization can only be used if the
683 * physical block size matches the request.
685 if (chain->bytes == bbytes) {
686 bp = getblk(hmp->devvp, pbase, bbytes, 0, 0);
689 error = bread(hmp->devvp, pbase, bbytes, &bp);
690 KKASSERT(error == 0);
692 bdata = (char *)bp->b_data + boff;
695 * Copy the data to the buffer, mark the buffer
696 * dirty, and convert the chain to unmodified.
698 bcopy(chain->data, bdata, chain->bytes);
699 bp->b_flags |= B_CLUSTEROK;
702 chain->bref.check.iscsi32.value =
703 hammer2_icrc32(chain->data, chain->bytes);
704 if (chain->bref.type == HAMMER2_BREF_TYPE_INODE)
705 ++hammer2_iod_meta_write;
707 ++hammer2_iod_indr_write;
709 chain->bref.check.iscsi32.value =
710 hammer2_icrc32(chain->data, chain->bytes);
713 if (hammer2_debug & 0x0008) {
714 kprintf("%*.*s} %p/%d %04x (flushed)",
715 info->depth, info->depth, "",
716 chain, chain->refs, chain->flags);
721 * Flush helper scan1 (recursive)
723 * Flushes the children of the caller's chain (parent) and updates
724 * the blockref, restricted by sync_tid.
726 * Ripouts during the loop should not cause any problems. Because we are
727 * flushing to a synchronization point, modification races will occur after
728 * sync_tid and do not have to be flushed anyway.
730 * It is also ok if the parent is chain_duplicate()'d while unlocked because
731 * the delete/duplication will install a delete_tid that is still larger than
732 * our current sync_tid.
735 hammer2_chain_flush_scan1(hammer2_chain_t *child, void *data)
737 hammer2_flush_info_t *info = data;
738 hammer2_chain_t *parent = info->parent;
739 /*hammer2_mount_t *hmp = info->hmp;*/
743 kprintf("flush %p,%d [%08x] -> %p [%08x] %jx\n",
744 parent, child->index, parent->flags,
745 child, child->flags, child->bref.key);
749 * We should only need to recurse if SUBMODIFIED is set, but as
750 * a safety also recurse if MODIFIED is also set. Return early
751 * if neither bit is set.
753 if ((child->flags & (HAMMER2_CHAIN_SUBMODIFIED |
754 HAMMER2_CHAIN_MODIFIED)) == 0) {
757 hammer2_chain_ref(child);
758 spin_unlock(&parent->core->cst.spin);
761 * The caller has added a ref to the parent so we can temporarily
762 * unlock it in order to lock the child. Re-check the flags before
765 hammer2_chain_unlock(parent);
766 hammer2_chain_lock(child, HAMMER2_RESOLVE_MAYBE);
768 if ((child->flags & (HAMMER2_CHAIN_SUBMODIFIED |
769 HAMMER2_CHAIN_MODIFIED)) == 0) {
770 hammer2_chain_unlock(child);
771 hammer2_chain_drop(child);
772 hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
773 spin_lock(&parent->core->cst.spin);
778 * The DESTROYED flag can only be initially set on an unreferenced
779 * deleted inode and will propagate downward via the mechanic below.
780 * Such inode chains have been deleted for good and should no longer
781 * be subject to delete/duplication.
783 * This optimization allows the inode reclaim (destroy unlinked file
784 * on vnode reclamation after last close) to be flagged by just
785 * setting HAMMER2_CHAIN_DESTROYED at the top level and then will
786 * cause the chains to be terminated and related buffers to be
787 * invalidated and not flushed out.
789 * We have to be careful not to propagate the DESTROYED flag if
790 * the destruction occurred after our flush sync_tid.
792 if ((parent->flags & HAMMER2_CHAIN_DESTROYED) &&
793 (child->flags & HAMMER2_CHAIN_DELETED) &&
795 child->delete_tid <= info->sync_tid &&
797 (child->flags & HAMMER2_CHAIN_DESTROYED) == 0) {
798 KKASSERT(child->duplink == NULL);
799 atomic_set_int(&child->flags,
800 HAMMER2_CHAIN_DESTROYED |
801 HAMMER2_CHAIN_SUBMODIFIED);
805 * Recurse and collect deferral data.
807 diddeferral = info->diddeferral;
809 hammer2_chain_flush_core(info, child);
811 kprintf("flush_core_done parent=%p flags=%08x child=%p.%d %08x\n",
812 parent, parent->flags, child, child->bref.type, child->flags);
815 info->diddeferral += diddeferral;
817 hammer2_chain_unlock(child);
818 hammer2_chain_drop(child);
820 hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
822 spin_lock(&parent->core->cst.spin);
827 * Flush helper scan2 (non-recursive)
829 * This pass on a chain's children propagates any MOVED or DELETED
830 * elements back up the chain towards the root after those elements have
831 * been fully flushed. Unlike scan1, this function is NOT recursive and
832 * the parent remains locked across the entire scan.
834 * Moves - MOVED elements need to propagate their bref up to the parent.
835 * all parents from element->parent through the duplink chain
836 * must be updated. The flag can only be reset once SUBMODIFIED
837 * has been cleared for all parents in the chain.
839 * A secondary bcmp of the bref is made to catch out-of-order
840 * flushes and not re-sync parents which are already correct.
842 * Deletions - Deletions are handled via delete_tid coupled with the MOVED
843 * flag. When a deletion is detected the parent's bref to the
844 * child is properly cleared. MOVED is always set when a deletion
845 * is made. A deleted element is an element where delete_tid !=
848 * NOTE! We must re-set SUBMODIFIED on the parent(s) as appropriate, and
849 * due to the above conditions it is possible to do this and still
850 * have some children flagged MOVED depending on the synchronization.
852 * NOTE! A deletion is a visbility issue, there can still be referenced to
853 * deleted elements (for example, to an unlinked file which is still
854 * open), and there can also be multiple chains pointing to the same
855 * bref where some are deleted and some are not (for example due to
856 * a rename). So a chain marked for deletion is basically considered
857 * to be live until it is explicitly destroyed. Such chains can also
858 * be freed once all MOVED and MODIFIED handling is done.
861 hammer2_chain_flush_scan2(hammer2_chain_t *child, void *data)
863 hammer2_flush_info_t *info = data;
864 hammer2_chain_t *parent = info->parent;
865 hammer2_mount_t *hmp = info->hmp;
866 hammer2_blockref_t *base;
871 * Check update conditions prior to locking child.
872 * We may not be able to safely test the 64-bit TIDs
873 * but we can certainly test the flags.
875 * NOTE: DELETED always also sets MOVED.
878 kprintf(" scan2 parent %p %08x child %p %08x ", parent, parent->flags, child, child->flags);
880 if (parent->flags & HAMMER2_CHAIN_DELETED) {
889 * Inodes with stale children that have been converted to DIRECTDATA
890 * mode (file extension or hardlink conversion typically) need to
891 * skipped right now before we start messing with a non-existant
894 if (parent->bref.type == HAMMER2_BREF_TYPE_INODE &&
895 (parent->data->ipdata.op_flags & HAMMER2_OPFLAG_DIRECTDATA)) {
904 * Ignore children modified beyond our flush point. If the parent
905 * is deleted within our flush we don't have to re-set SUBMODIFIED,
906 * otherwise we must set it according to the child's flags so
907 * SUBMODIFIED remains flagged for later flushes.
909 * NOTE: modify_tid is only updated for modifications, NOT for
910 * deletions (delete_tid is updated for deletions). Also note
911 * that delete_tid will ALWAYS be >= modify_tid.
913 * XXX spin-lock on child->modify_tid ?
916 if (child->modify_tid > info->sync_tid) {
917 if (parent->delete_tid <= info->sync_tid)
920 child_flags = child->flags;
928 if ((child->flags & HAMMER2_CHAIN_MOVED) == 0) {
929 child_flags = child->flags;
936 hammer2_chain_ref(child);
937 spin_unlock(&parent->core->cst.spin);
940 * The MOVED bit implies an additional reference which prevents
941 * the child from being destroyed out from under our operation
942 * so we can lock the child safely without worrying about it
943 * getting ripped up (?).
945 * We can only update parents where child->parent matches. The
946 * child->parent link will migrate along the chain but the flush
947 * order must be enforced absolutely. Parent reflushed after the
948 * child has passed them by should skip due to the modify_tid test.
950 hammer2_chain_lock(child, HAMMER2_RESOLVE_NEVER);
953 if (child->parent != parent) {
954 child_flags = child->flags;
955 hammer2_chain_unlock(child);
956 spin_lock(&parent->core->cst.spin);
965 * The parent's blockref to the child must be deleted or updated.
967 * This point is not reached on successful DESTROYED optimizations
968 * but can be reached on recursive deletions.
970 * XXX recursive deletions not optimized.
972 hammer2_chain_modify(info->trans, parent, HAMMER2_MODIFY_NO_MODIFY_TID);
974 switch(parent->bref.type) {
975 case HAMMER2_BREF_TYPE_INODE:
977 * XXX Should assert that OPFLAG_DIRECTDATA is 0 once we
978 * properly duplicate the inode headers and do proper flush
979 * range checks (all the children should be beyond the flush
980 * point). For now just don't sync the non-applicable
983 * XXX Can also occur due to hardlink consolidation. We
984 * set OPFLAG_DIRECTDATA to prevent the indirect and data
985 * blocks from syncing ot the hardlink pointer.
988 KKASSERT((parent->data->ipdata.op_flags &
989 HAMMER2_OPFLAG_DIRECTDATA) == 0);
991 if (parent->data->ipdata.op_flags &
992 HAMMER2_OPFLAG_DIRECTDATA) {
995 base = &parent->data->ipdata.u.blockset.blockref[0];
996 count = HAMMER2_SET_COUNT;
999 case HAMMER2_BREF_TYPE_INDIRECT:
1001 base = &parent->data->npdata.blockref[0];
1004 KKASSERT(child->flags & HAMMER2_CHAIN_DELETED);
1006 count = parent->bytes / sizeof(hammer2_blockref_t);
1008 case HAMMER2_BREF_TYPE_VOLUME:
1009 base = &hmp->voldata.sroot_blockset.blockref[0];
1010 count = HAMMER2_SET_COUNT;
1015 panic("hammer2_chain_get: "
1016 "unrecognized blockref type: %d",
1021 * Update the parent's blockref table and propagate mirror_tid.
1022 * blockref updates do not touch modify_tid. Instead, mirroring
1023 * operations always reconcile the entire array during their
1024 * mirror_tid based recursion.
1026 * WARNING! Deleted chains may still be used by the filesystem
1027 * in a later duplication, for example in a rename()
1028 * operation. Also any topological movement of the
1029 * related blocks. We only mess with the parent
1030 * block array, we do not mess with the child!
1032 * We adjust the parent's bref pointer to the child but
1033 * we do not modify the contents of the child.
1036 if (child->delete_tid <= info->sync_tid) {
1038 if (child->flags & HAMMER2_CHAIN_DELETED) {
1040 KKASSERT(child->index < count);
1041 bzero(&base[child->index], sizeof(child->bref));
1042 if (info->mirror_tid < child->delete_tid)
1043 info->mirror_tid = child->delete_tid;
1047 KKASSERT(child->index < count);
1048 base[child->index] = child->bref;
1049 if (info->mirror_tid < child->modify_tid)
1050 info->mirror_tid = child->modify_tid;
1053 KKASSERT(child->index >= 0);
1056 * Propagate mirror_tid back up.
1058 if (info->mirror_tid < child->bref.mirror_tid) {
1059 info->mirror_tid = child->bref.mirror_tid;
1061 if (parent->bref.type == HAMMER2_BREF_TYPE_VOLUME &&
1062 hmp->voldata.mirror_tid < child->bref.mirror_tid) {
1063 hmp->voldata.mirror_tid = child->bref.mirror_tid;
1068 * Cleanup the children. Clear the MOVED flag
1070 * XXXWe can only clear the MOVED flag when the child has progressed
1071 * to the last parent in the duplication chain.
1073 * XXXMOVED might not be set if we are reflushing this chain due to
1074 * the previous chain overwriting the same index in the parent.
1077 if (child->parent == parent &&
1078 parent->duplink && (parent->flags & HAMMER2_CHAIN_DELETED)) {
1079 hammer2_chain_ref(parent->duplink);
1080 child->parent = parent->duplink;
1081 child->modify_tid = child->parent->modify_tid;
1082 hammer2_chain_drop(parent);
1085 if (child->flags & HAMMER2_CHAIN_MOVED) {
1086 atomic_clear_int(&child->flags, HAMMER2_CHAIN_MOVED);
1087 hammer2_chain_drop(child); /* flag */
1089 if (child->delete_tid == HAMMER2_MAX_TID) {
1090 atomic_clear_int(&child->flags, HAMMER2_CHAIN_MOVED);
1091 hammer2_chain_drop(child); /* flag */
1092 } else if (child->delete_tid <= info->sync_tid) {
1093 atomic_clear_int(&child->flags, HAMMER2_CHAIN_MOVED);
1094 hammer2_chain_drop(child); /* flag */
1100 * Unlock the child. This can wind up dropping the child's
1101 * last ref, removing it from the parent's RB tree, and deallocating
1102 * the structure. The RB_SCAN() our caller is doing handles the
1105 child_flags = child->flags;
1106 hammer2_chain_unlock(child);
1107 hammer2_chain_drop(child);
1108 spin_lock(&parent->core->cst.spin);
1114 * The parent cleared SUBMODIFIED prior to the scan. If the child
1115 * still requires a flush (possibly due to being outside the current
1116 * synchronization zone), we must re-set SUBMODIFIED on the way back
1121 kprintf("G child %08x act=%08x\n", child_flags, child->flags);
1123 if (child_flags & (HAMMER2_CHAIN_MOVED |
1124 HAMMER2_CHAIN_DELETED |
1125 HAMMER2_CHAIN_MODIFIED |
1126 HAMMER2_CHAIN_SUBMODIFIED)) {
1127 atomic_set_int(&parent->flags, HAMMER2_CHAIN_SUBMODIFIED);