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 * Non-flush transactions can typically run concurrently. However if
78 * there are non-flush transaction both before AND after a flush trans,
79 * the transactions after stall until the ones before finish.
81 * Non-flush transactions occuring after a flush pointer can run concurrently
82 * with that flush. They only have to wait for transactions prior to the
83 * flush trans to complete before they unstall.
85 * WARNING! Modifications to the root volume cannot dup the root volume
86 * header to handle synchronization points, so alloc_tid can
87 * wind up (harmlessly) more advanced on flush.
89 * WARNING! Operations which might call inode_duplicate()/chain_duplicate()
90 * depend heavily on having a unique sync_tid to avoid duplication
91 * collisions (which key off of delete_tid).
94 hammer2_trans_init(hammer2_mount_t *hmp, hammer2_trans_t *trans, int flags)
96 hammer2_trans_t *scan;
98 bzero(trans, sizeof(*trans));
101 hammer2_voldata_lock(hmp);
102 trans->sync_tid = hmp->voldata.alloc_tid++;
103 trans->flags = flags;
104 trans->td = curthread;
105 TAILQ_INSERT_TAIL(&hmp->transq, trans, entry);
107 if (flags & HAMMER2_TRANS_ISFLUSH) {
109 * If we are a flush we have to wait for all transactions
110 * prior to our flush synchronization point to complete
111 * before we can start our flush.
114 if (hmp->curflush == NULL) {
115 hmp->curflush = trans;
116 hmp->flush_tid = trans->sync_tid;;
118 while (TAILQ_FIRST(&hmp->transq) != trans) {
119 lksleep(&trans->sync_tid, &hmp->voldatalk,
124 * Once we become the running flush we can wakeup anyone
128 while ((scan = TAILQ_NEXT(scan, entry)) != NULL) {
129 if (scan->flags & HAMMER2_TRANS_ISFLUSH)
131 if (scan->blocked == 0)
134 wakeup(&scan->blocked);
138 * If we are not a flush but our sync_tid is after a
139 * stalled flush, we have to wait until that flush unstalls
140 * (that is, all transactions prior to that flush complete),
141 * but then we can run concurrently with that flush.
143 * (flushcnt check only good as pre-condition, otherwise it
144 * may represent elements queued after us after we block).
146 if (hmp->flushcnt > 1 ||
148 TAILQ_FIRST(&hmp->transq) != hmp->curflush)) {
150 while (trans->blocked) {
151 lksleep(&trans->blocked, &hmp->voldatalk,
156 hammer2_voldata_unlock(hmp, 0);
160 hammer2_trans_done(hammer2_trans_t *trans)
162 hammer2_mount_t *hmp = trans->hmp;
163 hammer2_trans_t *scan;
165 hammer2_voldata_lock(hmp);
166 TAILQ_REMOVE(&hmp->transq, trans, entry);
167 if (trans->flags & HAMMER2_TRANS_ISFLUSH) {
169 * If we were a flush we have to adjust curflush to the
172 * flush_tid is used to partition copy-on-write operations
173 * (mostly duplicate-on-modify ops), which is what allows
174 * us to execute a flush concurrent with modifying operations
179 TAILQ_FOREACH(scan, &hmp->transq, entry) {
180 if (scan->flags & HAMMER2_TRANS_ISFLUSH)
184 hmp->curflush = scan;
185 hmp->flush_tid = scan->sync_tid;
188 * Theoretically we don't have to clear flush_tid
189 * here since the flush will have synchronized
190 * all operations <= flush_tid already. But for
193 hmp->curflush = NULL;
198 * If we are not a flush but a flush is now at the head
199 * of the queue and we were previously blocking it,
200 * we can now unblock it.
203 (scan = TAILQ_FIRST(&hmp->transq)) != NULL &&
204 trans->sync_tid < scan->sync_tid &&
205 (scan->flags & HAMMER2_TRANS_ISFLUSH)) {
206 wakeup(&scan->sync_tid);
209 hammer2_voldata_unlock(hmp, 0);
215 * Flush the chain and all modified sub-chains through the specified
216 * synchronization point (sync_tid), propagating parent chain modifications
217 * and mirror_tid updates back up as needed. Since we are recursing downward
218 * we do not have to deal with the complexities of multi-homed chains (chains
219 * with multiple parents).
221 * Caller must have interlocked against any non-flush-related modifying
222 * operations in progress whos modify_tid values are less than or equal
223 * to the passed sync_tid.
225 * Caller must have already vetted synchronization points to ensure they
226 * are properly flushed. Only snapshots and cluster flushes can create
227 * these sorts of synchronization points.
229 * SUBMODIFIED is not cleared if modified elements with higher modify_tid
230 * values (thus not flushed) are still present after the flush.
232 * If a chain is unable to completely flush we have to be sure that
233 * SUBMODIFIED remains set up the parent chain, and that MOVED is not
234 * cleared or our desynchronized bref will not properly update in the
235 * parent. The parent's indirect block is copied-on-write and adjusted
236 * as needed so it no longer needs to be placemarked by the subchains,
237 * allowing the sub-chains to be cleaned out.
239 * This routine can be called from several places but the most important
240 * is from the hammer2_vop_reclaim() function. We want to try to completely
241 * clean out the inode structure to prevent disconnected inodes from
242 * building up and blowing out the kmalloc pool. However, it is not actually
243 * necessary to flush reclaimed inodes to maintain HAMMER2's crash recovery
246 * chain is locked on call and will remain locked on return. If a flush
247 * occured, the chain's MOVED bit will be set indicating that its parent
248 * (which is not part of the flush) should be updated.
251 hammer2_chain_flush(hammer2_trans_t *trans, hammer2_chain_t *chain)
253 hammer2_chain_t *scan;
254 hammer2_flush_info_t info;
257 * Execute the recursive flush and handle deferrals.
259 * Chains can be ridiculously long (thousands deep), so to
260 * avoid blowing out the kernel stack the recursive flush has a
261 * depth limit. Elements at the limit are placed on a list
262 * for re-execution after the stack has been popped.
264 bzero(&info, sizeof(info));
265 TAILQ_INIT(&info.flush_list);
266 info.hmp = trans->hmp;
268 info.sync_tid = trans->sync_tid;
273 * Unwind deep recursions which had been deferred. This
274 * can leave MOVED set for these chains, which will be
275 * handled when we [re]flush chain after the unwind.
277 while ((scan = TAILQ_FIRST(&info.flush_list)) != NULL) {
278 KKASSERT(scan->flags & HAMMER2_CHAIN_DEFERRED);
279 TAILQ_REMOVE(&info.flush_list, scan, flush_node);
280 atomic_clear_int(&scan->flags, HAMMER2_CHAIN_DEFERRED);
283 * Now that we've popped back up we can do a secondary
284 * recursion on the deferred elements.
286 if (hammer2_debug & 0x0040)
287 kprintf("defered flush %p\n", scan);
288 hammer2_chain_lock(scan, HAMMER2_RESOLVE_MAYBE);
289 hammer2_chain_flush(trans, scan);
290 hammer2_chain_unlock(scan);
291 hammer2_chain_drop(scan); /* ref from deferral */
295 * Flush pass1 on root. SUBMODIFIED can remain set after
296 * this call for numerous reasons, including write failures,
297 * but most likely due to only a partial flush being
298 * requested or the chain element belongs to the wrong
299 * synchronization point.
301 info.diddeferral = 0;
302 hammer2_chain_flush_core(&info, chain);
304 kprintf("flush_core_done parent=<base> chain=%p.%d %08x\n",
305 chain, chain->bref.type, chain->flags);
309 * Only loop if deep recursions have been deferred.
311 if (TAILQ_EMPTY(&info.flush_list))
316 * SUBMODIFIED can be temporarily cleared and then re-set, which
317 * can prevent concurrent setsubmods from reaching all the way to
318 * the root. If after the flush we find the node is still in need
319 * of flushing (though possibly due to modifications made outside
320 * the requested synchronization zone), we must call setsubmod again
323 if (chain->flags & (HAMMER2_CHAIN_MOVED |
324 HAMMER2_CHAIN_DELETED |
325 HAMMER2_CHAIN_MODIFIED |
326 HAMMER2_CHAIN_SUBMODIFIED)) {
327 hammer2_chain_parent_setsubmod(trans, chain);
332 * This is the core of the chain flushing code. The chain is locked by the
333 * caller and remains locked on return. This function is keyed off of
334 * the SUBMODIFIED bit but must make fine-grained choices based on the
335 * synchronization point we are flushing to.
337 * If the flush accomplished any work chain will be flagged MOVED
338 * indicating a copy-on-write propagation back up is required.
339 * Deep sub-nodes may also have been entered onto the deferral list.
340 * MOVED is never set on the volume root.
342 * NOTE: modify_tid is different from MODIFIED. modify_tid is updated
343 * only when a chain is specifically modified, and not updated
344 * for copy-on-write propagations. MODIFIED is set on any modification
345 * including copy-on-write propagations.
348 hammer2_chain_flush_core(hammer2_flush_info_t *info, hammer2_chain_t *chain)
350 hammer2_mount_t *hmp;
351 hammer2_blockref_t *bref;
353 hammer2_tid_t saved_sync;
354 hammer2_trans_t *trans = info->trans;
367 kprintf("flush_core %p->%p.%d %08x (%s)\n",
368 info->parent, chain, chain->bref.type,
370 ((chain->bref.type == HAMMER2_BREF_TYPE_INODE) ?
371 chain->data->ipdata.filename : "?"));
373 kprintf("flush_core NULL->%p.%d %08x (%s)\n",
374 chain, chain->bref.type,
376 ((chain->bref.type == HAMMER2_BREF_TYPE_INODE) ?
377 chain->data->ipdata.filename : "?"));
381 * Restricted (snapshot) flushes ignore chains modified beyond
382 * the flush point. Deletions which are part of the flush do
383 * not need to be flushed (the parent will pick-up the deletion).
385 if (trans->flags & HAMMER2_TRANS_RESTRICTED) {
386 if (chain->modify_tid > info->sync_tid)
388 if (chain->delete_tid <= info->sync_tid)
392 saved_sync = info->sync_tid;
395 * If SUBMODIFIED is set we recurse the flush and adjust the
396 * blockrefs accordingly.
398 * NOTE: Looping on SUBMODIFIED can prevent a flush from ever
399 * finishing in the face of filesystem activity.
401 if (chain->flags & HAMMER2_CHAIN_SUBMODIFIED) {
402 hammer2_chain_t *saved_parent;
403 hammer2_tid_t saved_mirror;
406 * Clear SUBMODIFIED to catch races. Note that any child
407 * with MODIFIED, DELETED, or MOVED set during Scan2, after
408 * it processes the child, will cause SUBMODIFIED to be
410 * child has to be flushed SUBMODIFIED will wind up being
411 * set again (for next time), but this does not stop us from
412 * synchronizing block updates which occurred.
414 * We don't want to set our chain to MODIFIED gratuitously.
416 * We need an extra ref on chain because we are going to
417 * release its lock temporarily in our child loop.
419 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_SUBMODIFIED);
420 hammer2_chain_ref(chain);
423 * Run two passes. The first pass handles MODIFIED and
424 * SUBMODIFIED chains and recurses while the second pass
425 * handles MOVED chains on the way back up.
427 * If the stack gets too deep we defer scan1, but must
428 * be sure to still run scan2 if on the next loop the
429 * deferred chain has been flushed and now needs MOVED
430 * handling on the way back up.
432 * Scan1 is recursive.
434 * NOTE: The act of handling a modified/submodified chain can
435 * cause the MOVED Flag to be set. It can also be set
436 * via hammer2_chain_delete() and in other situations.
438 * NOTE: RB_SCAN() must be used instead of RB_FOREACH()
439 * because children can be physically removed during
442 saved_parent = info->parent;
443 saved_mirror = info->mirror_tid;
444 info->parent = chain;
445 info->mirror_tid = chain->bref.mirror_tid;
447 if (info->depth == HAMMER2_FLUSH_DEPTH_LIMIT) {
448 if ((chain->flags & HAMMER2_CHAIN_DEFERRED) == 0) {
449 hammer2_chain_ref(chain);
450 TAILQ_INSERT_TAIL(&info->flush_list,
452 atomic_set_int(&chain->flags,
453 HAMMER2_CHAIN_DEFERRED);
457 info->diddeferral = 0;
458 spin_lock(&chain->core->cst.spin);
459 RB_SCAN(hammer2_chain_tree, &chain->core->rbtree,
460 NULL, hammer2_chain_flush_scan1, info);
461 spin_unlock(&chain->core->cst.spin);
462 diddeferral += info->diddeferral;
466 * Handle successfully flushed children who are in the MOVED
467 * state on the way back up the recursion. This can have
468 * the side-effect of clearing MOVED.
470 * We execute this even if there were deferrals to try to
471 * keep the chain topology cleaner.
473 * Scan2 is non-recursive.
476 kprintf("scan2_start parent %p %08x\n", chain, chain->flags);
478 spin_lock(&chain->core->cst.spin);
479 RB_SCAN(hammer2_chain_tree, &chain->core->rbtree,
480 NULL, hammer2_chain_flush_scan2, info);
481 spin_unlock(&chain->core->cst.spin);
483 kprintf("scan2_stop parent %p %08x\n", chain, chain->flags);
485 chain->bref.mirror_tid = info->mirror_tid;
486 info->mirror_tid = saved_mirror;
487 info->parent = saved_parent;
488 hammer2_chain_drop(chain);
492 * Restore sync_tid in case it was restricted by a delete/duplicate.
494 info->sync_tid = saved_sync;
497 * Rollup diddeferral for caller. Note direct assignment, not +=.
499 info->diddeferral = diddeferral;
502 * Do not flush chain if there were any deferrals. It will be
503 * retried later after the deferrals are independently handled.
506 if (hammer2_debug & 0x0008) {
507 kprintf("%*.*s} %p/%d %04x (deferred)",
508 info->depth, info->depth, "",
509 chain, chain->refs, chain->flags);
515 * The DESTROYED flag is set when an inode is physically deleted
516 * and no longer referenced (no open descriptors). DESTROYED is
517 * usually set along with DELETED at the top-level point, but
518 * only the DESTROYED flag propagates downward.
520 * We can safely clear the MODIFIED bit in this case. We must leave
521 * the MOVED bit intact for the parent.
523 if ((chain->flags & HAMMER2_CHAIN_DESTROYED) &&
524 (chain->flags & HAMMER2_CHAIN_DELETED) &&
525 (trans->flags & HAMMER2_TRANS_RESTRICTED) == 0) {
527 * Throw-away the MODIFIED flag
529 if (chain->flags & HAMMER2_CHAIN_MODIFIED) {
531 chain->bp->b_flags |= B_INVAL|B_RELBUF;
532 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
533 hammer2_chain_drop(chain);
539 * A degenerate flush might not have flushed anything and thus not
540 * processed modified blocks on the way back up. Detect the case.
542 * Note that MOVED can be set without MODIFIED being set due to
543 * a deletion, in which case it is handled by Scan2 later on.
545 * Both bits can be set along with DELETED due to a deletion if
546 * modified data within the synchronization zone and the chain
547 * was then deleted beyond the zone, in which case we still have
548 * to flush for synchronization point consistency. Otherwise though
549 * DELETED and MODIFIED are treated as separate flags.
551 if ((chain->flags & HAMMER2_CHAIN_MODIFIED) == 0)
557 * A DESTROYED node that reaches this point must be flushed for
558 * synchronization point consistency.
562 * Update mirror_tid, clear MODIFIED, and set MOVED.
564 * The caller will update the parent's reference to this chain
565 * by testing MOVED as long as the modification was in-bounds.
567 * MOVED is never set on the volume root as there is no parent
570 if (chain->bref.mirror_tid < info->sync_tid)
571 chain->bref.mirror_tid = info->sync_tid;
572 wasmodified = (chain->flags & HAMMER2_CHAIN_MODIFIED) != 0;
573 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
574 if (chain == &hmp->vchain)
575 kprintf("(FLUSHED VOLUME HEADER)\n");
577 if ((chain->flags & HAMMER2_CHAIN_MOVED) ||
578 chain == &hmp->vchain) {
580 * Drop the ref from the MODIFIED bit we cleared.
583 hammer2_chain_drop(chain);
586 * If we were MODIFIED we inherit the ref from clearing
587 * that bit, otherwise we need another ref.
589 if (wasmodified == 0)
590 hammer2_chain_ref(chain);
591 atomic_set_int(&chain->flags, HAMMER2_CHAIN_MOVED);
595 * If this is part of a recursive flush we can go ahead and write
596 * out the buffer cache buffer and pass a new bref back up the chain
599 * Volume headers are NOT flushed here as they require special
602 switch(chain->bref.type) {
603 case HAMMER2_BREF_TYPE_VOLUME:
605 * The volume header is flushed manually by the syncer, not
606 * here. All we do is adjust the crc's.
608 KKASSERT(chain->data != NULL);
609 KKASSERT(chain->bp == NULL);
610 kprintf("volume header mirror_tid %jd\n",
611 hmp->voldata.mirror_tid);
613 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT1]=
615 (char *)&hmp->voldata +
616 HAMMER2_VOLUME_ICRC1_OFF,
617 HAMMER2_VOLUME_ICRC1_SIZE);
618 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT0]=
620 (char *)&hmp->voldata +
621 HAMMER2_VOLUME_ICRC0_OFF,
622 HAMMER2_VOLUME_ICRC0_SIZE);
623 hmp->voldata.icrc_volheader =
625 (char *)&hmp->voldata +
626 HAMMER2_VOLUME_ICRCVH_OFF,
627 HAMMER2_VOLUME_ICRCVH_SIZE);
628 hmp->volsync = hmp->voldata;
629 atomic_set_int(&chain->flags, HAMMER2_CHAIN_VOLUMESYNC);
631 case HAMMER2_BREF_TYPE_DATA:
633 * Data elements have already been flushed via the logical
634 * file buffer cache. Their hash was set in the bref by
635 * the vop_write code.
637 * Make sure any device buffer(s) have been flushed out here.
638 * (there aren't usually any to flush).
640 bbytes = chain->bytes;
641 pbase = chain->bref.data_off & ~(hammer2_off_t)(bbytes - 1);
642 boff = chain->bref.data_off & HAMMER2_OFF_MASK & (bbytes - 1);
644 bp = getblk(hmp->devvp, pbase, bbytes, GETBLK_NOWAIT, 0);
646 if ((bp->b_flags & (B_CACHE | B_DIRTY)) ==
647 (B_CACHE | B_DIRTY)) {
650 bp->b_flags |= B_RELBUF;
655 case HAMMER2_BREF_TYPE_INDIRECT:
657 * Indirect blocks may be in an INITIAL state. Use the
658 * chain_lock() call to ensure that the buffer has been
659 * instantiated (even though it is already locked the buffer
660 * might not have been instantiated).
662 * Only write the buffer out if it is dirty, it is possible
663 * the operating system had already written out the buffer.
665 hammer2_chain_lock(chain, HAMMER2_RESOLVE_ALWAYS);
666 KKASSERT(chain->bp != NULL);
669 if ((chain->flags & HAMMER2_CHAIN_DIRTYBP) ||
670 (bp->b_flags & B_DIRTY)) {
677 hammer2_chain_unlock(chain);
681 * Embedded elements have to be flushed out.
683 KKASSERT(chain->data != NULL);
684 KKASSERT(chain->bp == NULL);
687 KKASSERT((bref->data_off & HAMMER2_OFF_MASK) != 0);
688 KKASSERT(HAMMER2_DEC_CHECK(chain->bref.methods) ==
689 HAMMER2_CHECK_ISCSI32);
691 if (chain->bp == NULL) {
693 * The data is embedded, we have to acquire the
694 * buffer cache buffer and copy the data into it.
696 if ((bbytes = chain->bytes) < HAMMER2_MINIOSIZE)
697 bbytes = HAMMER2_MINIOSIZE;
698 pbase = bref->data_off & ~(hammer2_off_t)(bbytes - 1);
699 boff = bref->data_off & HAMMER2_OFF_MASK & (bbytes - 1);
702 * The getblk() optimization can only be used if the
703 * physical block size matches the request.
705 if (chain->bytes == bbytes) {
706 bp = getblk(hmp->devvp, pbase, bbytes, 0, 0);
709 error = bread(hmp->devvp, pbase, bbytes, &bp);
710 KKASSERT(error == 0);
712 bdata = (char *)bp->b_data + boff;
715 * Copy the data to the buffer, mark the buffer
716 * dirty, and convert the chain to unmodified.
718 bcopy(chain->data, bdata, chain->bytes);
719 bp->b_flags |= B_CLUSTEROK;
722 chain->bref.check.iscsi32.value =
723 hammer2_icrc32(chain->data, chain->bytes);
724 if (chain->bref.type == HAMMER2_BREF_TYPE_INODE)
725 ++hammer2_iod_meta_write;
727 ++hammer2_iod_indr_write;
729 chain->bref.check.iscsi32.value =
730 hammer2_icrc32(chain->data, chain->bytes);
736 * Flush helper scan1 (recursive)
738 * Flushes the children of the caller's chain (parent) and updates
739 * the blockref, restricted by sync_tid.
741 * Ripouts during the loop should not cause any problems. Because we are
742 * flushing to a synchronization point, modification races will occur after
743 * sync_tid and do not have to be flushed anyway.
745 * It is also ok if the parent is chain_duplicate()'d while unlocked because
746 * the delete/duplication will install a delete_tid that is still larger than
747 * our current sync_tid.
750 hammer2_chain_flush_scan1(hammer2_chain_t *child, void *data)
752 hammer2_flush_info_t *info = data;
753 hammer2_chain_t *parent = info->parent;
754 /*hammer2_mount_t *hmp = info->hmp;*/
758 * We should only need to recurse if SUBMODIFIED is set, but as
759 * a safety also recurse if MODIFIED is also set. Return early
760 * if neither bit is set.
762 if ((child->flags & (HAMMER2_CHAIN_SUBMODIFIED |
763 HAMMER2_CHAIN_MODIFIED)) == 0) {
766 hammer2_chain_ref(child);
767 spin_unlock(&parent->core->cst.spin);
770 * The caller has added a ref to the parent so we can temporarily
771 * unlock it in order to lock the child. Re-check the flags before
774 hammer2_chain_unlock(parent);
775 hammer2_chain_lock(child, HAMMER2_RESOLVE_MAYBE);
777 if ((child->flags & (HAMMER2_CHAIN_SUBMODIFIED |
778 HAMMER2_CHAIN_MODIFIED)) == 0) {
779 hammer2_chain_unlock(child);
780 hammer2_chain_drop(child);
781 hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
782 spin_lock(&parent->core->cst.spin);
787 * The DESTROYED flag can only be initially set on an unreferenced
788 * deleted inode and will propagate downward via the mechanic below.
789 * Such inode chains have been deleted for good and should no longer
790 * be subject to delete/duplication.
792 * This optimization allows the inode reclaim (destroy unlinked file
793 * on vnode reclamation after last close) to be flagged by just
794 * setting HAMMER2_CHAIN_DESTROYED at the top level and then will
795 * cause the chains to be terminated and related buffers to be
796 * invalidated and not flushed out.
798 * We have to be careful not to propagate the DESTROYED flag if
799 * the destruction occurred after our flush sync_tid.
801 if ((parent->flags & HAMMER2_CHAIN_DESTROYED) &&
802 (child->flags & HAMMER2_CHAIN_DELETED) &&
803 (child->flags & HAMMER2_CHAIN_DESTROYED) == 0) {
804 KKASSERT(child->duplink == NULL);
805 atomic_set_int(&child->flags,
806 HAMMER2_CHAIN_DESTROYED |
807 HAMMER2_CHAIN_SUBMODIFIED);
811 * Recurse and collect deferral data.
813 diddeferral = info->diddeferral;
815 hammer2_chain_flush_core(info, child);
817 kprintf("flush_core_done parent=%p flags=%08x child=%p.%d %08x\n",
818 parent, parent->flags, child, child->bref.type, child->flags);
821 info->diddeferral += diddeferral;
823 hammer2_chain_unlock(child);
824 hammer2_chain_drop(child);
826 hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
828 spin_lock(&parent->core->cst.spin);
833 * Flush helper scan2 (non-recursive)
835 * This pass on a chain's children propagates any MOVED or DELETED
836 * elements back up the chain towards the root after those elements have
837 * been fully flushed. Unlike scan1, this function is NOT recursive and
838 * the parent remains locked across the entire scan.
840 * NOTE! We must re-set SUBMODIFIED on the parent(s) as appropriate, and
841 * due to the above conditions it is possible to do this and still
842 * have some children flagged MOVED depending on the synchronization.
844 * NOTE! A deletion is a visbility issue, there can still be referenced to
845 * deleted elements (for example, to an unlinked file which is still
846 * open), and there can also be multiple chains pointing to the same
847 * bref where some are deleted and some are not (for example due to
848 * a rename). So a chain marked for deletion is basically considered
849 * to be live until it is explicitly destroyed or until its ref-count
850 * reaches zero (also implying that MOVED and MODIFIED are clear).
853 hammer2_chain_flush_scan2(hammer2_chain_t *child, void *data)
855 hammer2_flush_info_t *info = data;
856 hammer2_chain_t *parent = info->parent;
857 hammer2_mount_t *hmp = info->hmp;
858 hammer2_trans_t *trans = info->trans;
859 hammer2_blockref_t *base;
864 * Inodes with stale children that have been converted to DIRECTDATA
865 * mode (file extension or hardlink conversion typically) need to
866 * skipped right now before we start messing with a non-existant
869 if (parent->bref.type == HAMMER2_BREF_TYPE_INODE &&
870 (parent->data->ipdata.op_flags & HAMMER2_OPFLAG_DIRECTDATA)) {
879 * Ignore children which have not changed.
881 if ((child->flags & HAMMER2_CHAIN_MOVED) == 0) {
882 child_flags = child->flags;
889 hammer2_chain_ref(child);
890 spin_unlock(&parent->core->cst.spin);
893 * The MOVED bit implies an additional reference which prevents
894 * the child from being destroyed out from under our operation
895 * so we can lock the child safely without worrying about it
896 * getting ripped up (?).
898 * We can only update parents where child->parent matches. The
899 * child->parent link will migrate along the chain but the flush
900 * order must be enforced absolutely. Parent reflushed after the
901 * child has passed them by should skip due to the modify_tid test.
903 hammer2_chain_lock(child, HAMMER2_RESOLVE_NEVER);
906 * The parent's blockref to the child must be deleted or updated.
908 * This point is not reached on successful DESTROYED optimizations
909 * but can be reached on recursive deletions and restricted flushes.
911 * Because flushes are ordered we do not have to make a
912 * modify/duplicate of indirect blocks. That is, the flush
913 * code does not have to kmalloc or duplicate anything. We
914 * can adjust the indirect block table in-place and reuse the
915 * chain. It IS possible that the chain has already been duplicated
916 * or may wind up being duplicated on-the-fly by modifying code
917 * on the frontend. We simply use the original and ignore such
918 * chains. However, it does mean we can't clear the MOVED bit.
920 * XXX recursive deletions not optimized.
922 hammer2_chain_modify(trans, &parent,
923 HAMMER2_MODIFY_NO_MODIFY_TID |
924 HAMMER2_MODIFY_ASSERTNOCOPY);
926 switch(parent->bref.type) {
927 case HAMMER2_BREF_TYPE_INODE:
929 * XXX Should assert that OPFLAG_DIRECTDATA is 0 once we
930 * properly duplicate the inode headers and do proper flush
931 * range checks (all the children should be beyond the flush
932 * point). For now just don't sync the non-applicable
935 * XXX Can also occur due to hardlink consolidation. We
936 * set OPFLAG_DIRECTDATA to prevent the indirect and data
937 * blocks from syncing ot the hardlink pointer.
940 KKASSERT((parent->data->ipdata.op_flags &
941 HAMMER2_OPFLAG_DIRECTDATA) == 0);
943 if (parent->data->ipdata.op_flags &
944 HAMMER2_OPFLAG_DIRECTDATA) {
947 base = &parent->data->ipdata.u.blockset.blockref[0];
948 count = HAMMER2_SET_COUNT;
951 case HAMMER2_BREF_TYPE_INDIRECT:
953 base = &parent->data->npdata.blockref[0];
956 KKASSERT(child->flags & HAMMER2_CHAIN_DELETED);
958 count = parent->bytes / sizeof(hammer2_blockref_t);
960 case HAMMER2_BREF_TYPE_VOLUME:
961 base = &hmp->voldata.sroot_blockset.blockref[0];
962 count = HAMMER2_SET_COUNT;
967 panic("hammer2_chain_get: "
968 "unrecognized blockref type: %d",
973 * Update the parent's blockref table and propagate mirror_tid.
974 * blockref updates do not touch modify_tid. Instead, mirroring
975 * operations always reconcile the entire array during their
976 * mirror_tid based recursion.
978 * WARNING! Deleted chains may still be used by the filesystem
979 * in a later duplication, for example in a rename()
980 * operation. Also any topological movement of the
981 * related blocks. We only mess with the parent
982 * block array, we do not mess with the child!
984 * We adjust the parent's bref pointer to the child but
985 * we do not modify the contents of the child.
987 if ((trans->flags & HAMMER2_TRANS_RESTRICTED) &&
988 child->delete_tid <= trans->sync_tid) {
990 KKASSERT(child->index < count);
991 bzero(&base[child->index], sizeof(child->bref));
992 if (info->mirror_tid < child->delete_tid)
993 info->mirror_tid = child->delete_tid;
995 } else if ((trans->flags & HAMMER2_TRANS_RESTRICTED) &&
996 child->modify_tid <= trans->sync_tid) {
998 KKASSERT(child->index < count);
999 base[child->index] = child->bref;
1000 if (info->mirror_tid < child->modify_tid)
1001 info->mirror_tid = child->modify_tid;
1003 } else if (child->flags & HAMMER2_CHAIN_DELETED) {
1005 KKASSERT(child->index < count);
1006 bzero(&base[child->index], sizeof(child->bref));
1007 if (info->mirror_tid < child->delete_tid)
1008 info->mirror_tid = child->delete_tid;
1012 KKASSERT(child->index < count);
1013 base[child->index] = child->bref;
1014 if (info->mirror_tid < child->modify_tid)
1015 info->mirror_tid = child->modify_tid;
1018 KKASSERT(child->index >= 0);
1021 * Propagate mirror_tid back up.
1023 if (info->mirror_tid < child->bref.mirror_tid) {
1024 info->mirror_tid = child->bref.mirror_tid;
1026 if (parent->bref.type == HAMMER2_BREF_TYPE_VOLUME &&
1027 hmp->voldata.mirror_tid < child->bref.mirror_tid) {
1028 hmp->voldata.mirror_tid = child->bref.mirror_tid;
1032 * Cleanup the children. Clear the MOVED flag
1034 * Only unrestricted flushes can clear the MOVED flag.
1036 if (child->flags & HAMMER2_CHAIN_MOVED) {
1037 if ((trans->flags & HAMMER2_TRANS_RESTRICTED) == 0) {
1038 atomic_clear_int(&child->flags, HAMMER2_CHAIN_MOVED);
1039 hammer2_chain_drop(child); /* flag */
1044 * Unlock the child. This can wind up dropping the child's
1045 * last ref, removing it from the parent's RB tree, and deallocating
1046 * the structure. The RB_SCAN() our caller is doing handles the
1049 child_flags = child->flags;
1050 hammer2_chain_unlock(child);
1051 hammer2_chain_drop(child);
1052 spin_lock(&parent->core->cst.spin);
1058 * The parent cleared SUBMODIFIED prior to the scan. If the child
1059 * still requires a flush (possibly due to being outside the current
1060 * synchronization zone), we must re-set SUBMODIFIED on the way back
1065 kprintf("G child %08x act=%08x\n", child_flags, child->flags);
1067 if (child_flags & (HAMMER2_CHAIN_MOVED |
1068 HAMMER2_CHAIN_DELETED |
1069 HAMMER2_CHAIN_MODIFIED |
1070 HAMMER2_CHAIN_SUBMODIFIED)) {
1071 atomic_set_int(&parent->flags, HAMMER2_CHAIN_SUBMODIFIED);