hammer2 - Major restructuring, part 6/several
[dragonfly.git] / sys / vfs / hammer2 / hammer2_flush.c
1 /*
2  * Copyright (c) 2011-2013 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@dragonflybsd.org>
6  * by Venkatesh Srinivas <vsrinivas@dragonflybsd.org>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  * 3. Neither the name of The DragonFly Project nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific, prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
26  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35
36 #include <sys/cdefs.h>
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/types.h>
40 #include <sys/lock.h>
41 #include <sys/uuid.h>
42
43 #include "hammer2.h"
44
45 /*
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
50  * processes.
51  */
52 struct hammer2_flush_info {
53         hammer2_mount_t *hmp;
54         hammer2_chain_t *parent;
55         hammer2_trans_t *trans;
56         int             depth;
57         int             diddeferral;
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 */
61 };
62
63 typedef struct hammer2_flush_info hammer2_flush_info_t;
64
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);
69
70 /*
71  * Transaction support functions for writing to the filesystem.
72  *
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.
76  *
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.
80  *
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).
84  */
85 void
86 hammer2_trans_init(hammer2_mount_t *hmp, hammer2_trans_t *trans)
87 {
88         bzero(trans, sizeof(*trans));
89         trans->hmp = hmp;
90         hammer2_voldata_lock(hmp);
91         trans->sync_tid = hmp->voldata.alloc_tid++;
92         hammer2_voldata_unlock(hmp, 0);
93 }
94
95 void
96 hammer2_trans_init_flush(hammer2_mount_t *hmp, hammer2_trans_t *trans,
97                          int master)
98 {
99         thread_t td = curthread;
100
101         bzero(trans, sizeof(*trans));
102         trans->hmp = hmp;
103
104         hammer2_voldata_lock(hmp);
105         if (master) {
106                 /*
107                  * New master flush (sync).
108                  */
109                 while (hmp->flush_td) {
110                         hmp->flush_wait = 1;
111                         lksleep(&hmp->flush_wait, &hmp->voldatalk,
112                                 0, "h2sync", hz);
113                 }
114                 hmp->flush_td = td;
115                 hmp->flush_tid = hmp->voldata.alloc_tid++;
116                 trans->sync_tid = hmp->flush_tid;
117         } else if (hmp->flush_td == td) {
118                 /*
119                  * Part of a running master flush (sync->fsync)
120                  */
121                 trans->sync_tid = hmp->flush_tid;
122                 KKASSERT(trans->sync_tid != 0);
123         } else {
124                 /*
125                  * Independent flush request, make sure the sync_tid
126                  * covers all modifications made to date.
127                  */
128                 trans->sync_tid = hmp->voldata.alloc_tid++;
129         }
130         hammer2_voldata_unlock(hmp, 0);
131 }
132
133 void
134 hammer2_trans_done(hammer2_trans_t *trans)
135 {
136         trans->hmp = NULL;
137 }
138
139 void
140 hammer2_trans_done_flush(hammer2_trans_t *trans, int master)
141 {
142         hammer2_mount_t *hmp = trans->hmp;
143
144         hammer2_voldata_lock(hmp);
145         if (master) {
146                 hmp->flush_td = NULL;
147                 if (hmp->flush_wait) {
148                         hmp->flush_wait = 0;
149                         wakeup(&hmp->flush_wait);
150                 }
151         }
152         hammer2_voldata_unlock(hmp, 0);
153
154         trans->hmp = NULL;
155 }
156
157 /*
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).
163  *
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.
167  *
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.
171  *
172  * SUBMODIFIED is not cleared if modified elements with higher modify_tid
173  * values (thus not flushed) are still present after the flush.
174  *
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.
181  *
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
187  * capability.
188  *
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.
192  */
193 void
194 hammer2_chain_flush(hammer2_trans_t *trans, hammer2_chain_t *chain)
195 {
196         hammer2_chain_t *scan;
197         hammer2_flush_info_t info;
198
199         /*
200          * Execute the recursive flush and handle deferrals.
201          *
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.
206          */
207         bzero(&info, sizeof(info));
208         TAILQ_INIT(&info.flush_list);
209         info.hmp = trans->hmp;
210         info.trans = trans;
211         info.sync_tid = trans->sync_tid;
212         info.mirror_tid = 0;
213
214         for (;;) {
215                 /*
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.
219                  */
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);
224
225                         /*
226                          * Now that we've popped back up we can do a secondary
227                          * recursion on the deferred elements.
228                          */
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 */
235                 }
236
237                 /*
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.
243                  */
244                 info.diddeferral = 0;
245                 hammer2_chain_flush_core(&info, chain);
246 #if FLUSH_DEBUG
247                 kprintf("flush_core_done parent=<base> chain=%p.%d %08x\n",
248                         chain, chain->bref.type, chain->flags);
249 #endif
250
251                 /*
252                  * Only loop if deep recursions have been deferred.
253                  */
254                 if (TAILQ_EMPTY(&info.flush_list))
255                         break;
256         }
257
258         /*
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
264          * to cover the race.
265          */
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);
271         }
272 }
273
274 /*
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.
279  *
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.
284  *
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.
289  */
290 static void
291 hammer2_chain_flush_core(hammer2_flush_info_t *info, hammer2_chain_t *chain)
292 {
293         hammer2_mount_t *hmp;
294         hammer2_blockref_t *bref;
295         hammer2_off_t pbase;
296         hammer2_tid_t saved_sync;
297         size_t bbytes;
298         size_t boff;
299         char *bdata;
300         struct buf *bp;
301         int error;
302         int wasmodified;
303         int diddeferral = 0;
304
305         hmp = info->hmp;
306
307 #if FLUSH_DEBUG
308         if (info->parent)
309                 kprintf("flush_core %p->%p.%d %08x (%s)\n",
310                         info->parent, chain, chain->bref.type,
311                         chain->flags,
312                         ((chain->bref.type == HAMMER2_BREF_TYPE_INODE) ?
313                                 chain->data->ipdata.filename : "?"));
314         else
315                 kprintf("flush_core NULL->%p.%d %08x (%s)\n",
316                         chain, chain->bref.type,
317                         chain->flags,
318                         ((chain->bref.type == HAMMER2_BREF_TYPE_INODE) ?
319                                 chain->data->ipdata.filename : "?"));
320 #endif
321
322 #if 0
323         /*
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.
330          *
331          * NOTE: Unmodified chains set modify_tid to 0, allowing us to reach
332          *       deeper chains.
333          */
334         if (chain->modify_tid > info->sync_tid)
335                 return;
336 #endif
337
338         /*
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.
345          */
346         saved_sync = info->sync_tid;
347 #if 0
348         if (chain->duplink && (chain->flags & HAMMER2_CHAIN_DELETED) &&
349             chain->delete_tid < saved_sync) {
350                 info->sync_tid = chain->delete_tid;
351         }
352 #endif
353
354         /*
355          * If SUBMODIFIED is set we recurse the flush and adjust the
356          * blockrefs accordingly.
357          *
358          * NOTE: Looping on SUBMODIFIED can prevent a flush from ever
359          *       finishing in the face of filesystem activity.
360          */
361         if (chain->flags & HAMMER2_CHAIN_SUBMODIFIED) {
362                 hammer2_chain_t *saved_parent;
363                 hammer2_tid_t saved_mirror;
364
365                 /*
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
369                  * re-set.
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.
373                  *
374                  * We don't want to set our chain to MODIFIED gratuitously.
375                  *
376                  * We need an extra ref on chain because we are going to
377                  * release its lock temporarily in our child loop.
378                  */
379                 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_SUBMODIFIED);
380                 hammer2_chain_ref(chain);
381
382                 /*
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.
386                  *
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.
391                  *
392                  * Scan1 is recursive.
393                  *
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.
397                  *
398                  * NOTE: RB_SCAN() must be used instead of RB_FOREACH()
399                  *       because children can be physically removed during
400                  *       the scan.
401                  */
402                 saved_parent = info->parent;
403                 saved_mirror = info->mirror_tid;
404                 info->parent = chain;
405                 info->mirror_tid = chain->bref.mirror_tid;
406
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,
411                                                   chain, flush_node);
412                                 atomic_set_int(&chain->flags,
413                                                HAMMER2_CHAIN_DEFERRED);
414                         }
415                         diddeferral = 1;
416                 } else {
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;
423                 }
424
425                 /*
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.
429                  *
430                  * We execute this even if there were deferrals to try to
431                  * keep the chain topology cleaner.
432                  *
433                  * Scan2 is non-recursive.
434                  */
435 #if FLUSH_DEBUG
436                 kprintf("scan2_start parent %p %08x\n", chain, chain->flags);
437 #endif
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);
442 #if FLUSH_DEBUG
443                 kprintf("scan2_stop  parent %p %08x\n", chain, chain->flags);
444 #endif
445                 chain->bref.mirror_tid = info->mirror_tid;
446                 info->mirror_tid = saved_mirror;
447                 info->parent = saved_parent;
448                 hammer2_chain_drop(chain);
449         }
450
451         /*
452          * Restore sync_tid in case it was restricted by a delete/duplicate.
453          */
454         info->sync_tid = saved_sync;
455
456         /*
457          * Rollup diddeferral for caller.  Note direct assignment, not +=.
458          */
459         info->diddeferral = diddeferral;
460
461         /*
462          * Do not flush chain if there were any deferrals.  It will be
463          * retried later after the deferrals are independently handled.
464          */
465         if (diddeferral) {
466                 if (hammer2_debug & 0x0008) {
467                         kprintf("%*.*s} %p/%d %04x (deferred)",
468                                 info->depth, info->depth, "",
469                                 chain, chain->refs, chain->flags);
470                 }
471                 return;
472         }
473
474         /*
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.
478          *
479          * The MOVED bit has to be left intact as this flags the zeroing
480          * of the bref in the parent chain.
481          *
482          * XXX
483          *
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.
490          *
491          * DESTROYED chains stop processing here.
492          */
493         if ((chain->flags & HAMMER2_CHAIN_DESTROYED) &&
494             (chain->flags & HAMMER2_CHAIN_DELETED)) {
495 #if 0
496             (chain->delete_tid <= info->sync_tid)) {
497 #endif
498                 if (chain->flags & HAMMER2_CHAIN_MODIFIED) {
499                         if (chain->bp)
500                                 chain->bp->b_flags |= B_INVAL|B_RELBUF;
501                         atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
502                         hammer2_chain_drop(chain);
503                 }
504 #if 0
505                 if (chain->flags & HAMMER2_CHAIN_MOVED) {
506                         atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MOVED);
507                         hammer2_chain_drop(chain);
508                 }
509 #endif
510                 if (hammer2_debug & 0x0008) {
511                         kprintf("%*.*s} %p/%d %04x (destroyed)",
512                                 info->depth, info->depth, "",
513                                 chain, chain->refs, chain->flags);
514                 }
515                 return;
516         }
517
518         /*
519          * A degenerate flush might not have flushed anything and thus not
520          * processed modified blocks on the way back up.  Detect the case.
521          *
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.
524          *
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.
530          */
531         if ((chain->flags & HAMMER2_CHAIN_MODIFIED) == 0)
532                 return;
533
534         /*
535          * Issue flush.
536          *
537          * A DESTROYED node that reaches this point must be flushed for
538          * synchronization point consistency.
539          */
540
541         /*
542          * Update mirror_tid, clear MODIFIED, and set MOVED.
543          *
544          * The caller will update the parent's reference to this chain
545          * by testing MOVED as long as the modification was in-bounds.
546          *
547          * MOVED is never set on the volume root as there is no parent
548          * to adjust.
549          */
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");
556
557         if ((chain->flags & HAMMER2_CHAIN_MOVED) ||
558             chain == &hmp->vchain) {
559                 /*
560                  * Drop the ref from the MODIFIED bit we cleared.
561                  */
562                 if (wasmodified)
563                         hammer2_chain_drop(chain);
564         } else {
565                 /*
566                  * If we were MODIFIED we inherit the ref from clearing
567                  * that bit, otherwise we need another ref.
568                  */
569                 if (wasmodified == 0)
570                         hammer2_chain_ref(chain);
571                 atomic_set_int(&chain->flags, HAMMER2_CHAIN_MOVED);
572         }
573
574         /*
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
577          * via the MOVED bit.
578          *
579          * Volume headers are NOT flushed here as they require special
580          * processing.
581          */
582         switch(chain->bref.type) {
583         case HAMMER2_BREF_TYPE_VOLUME:
584                 /*
585                  * The volume header is flushed manually by the syncer, not
586                  * here.  All we do is adjust the crc's.
587                  */
588                 KKASSERT(chain->data != NULL);
589                 KKASSERT(chain->bp == NULL);
590                 kprintf("volume header mirror_tid %jd\n",
591                         hmp->voldata.mirror_tid);
592
593                 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT1]=
594                         hammer2_icrc32(
595                                 (char *)&hmp->voldata +
596                                  HAMMER2_VOLUME_ICRC1_OFF,
597                                 HAMMER2_VOLUME_ICRC1_SIZE);
598                 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT0]=
599                         hammer2_icrc32(
600                                 (char *)&hmp->voldata +
601                                  HAMMER2_VOLUME_ICRC0_OFF,
602                                 HAMMER2_VOLUME_ICRC0_SIZE);
603                 hmp->voldata.icrc_volheader =
604                         hammer2_icrc32(
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);
610                 break;
611         case HAMMER2_BREF_TYPE_DATA:
612                 /*
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.
616                  *
617                  * Make sure any device buffer(s) have been flushed out here.
618                  * (there aren't usually any to flush).
619                  */
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);
623
624                 bp = getblk(hmp->devvp, pbase, bbytes, GETBLK_NOWAIT, 0);
625                 if (bp) {
626                         if ((bp->b_flags & (B_CACHE | B_DIRTY)) ==
627                             (B_CACHE | B_DIRTY)) {
628                                 cluster_awrite(bp);
629                         } else {
630                                 bp->b_flags |= B_RELBUF;
631                                 brelse(bp);
632                         }
633                 }
634                 break;
635         case HAMMER2_BREF_TYPE_INDIRECT:
636                 /*
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).
641                  *
642                  * Only write the buffer out if it is dirty, it is possible
643                  * the operating system had already written out the buffer.
644                  */
645                 hammer2_chain_lock(chain, HAMMER2_RESOLVE_ALWAYS);
646                 KKASSERT(chain->bp != NULL);
647
648                 bp = chain->bp;
649                 if ((chain->flags & HAMMER2_CHAIN_DIRTYBP) ||
650                     (bp->b_flags & B_DIRTY)) {
651                         bdwrite(chain->bp);
652                 } else {
653                         brelse(chain->bp);
654                 }
655                 chain->bp = NULL;
656                 chain->data = NULL;
657                 hammer2_chain_unlock(chain);
658                 break;
659         default:
660                 /*
661                  * Embedded elements have to be flushed out.
662                  */
663                 KKASSERT(chain->data != NULL);
664                 KKASSERT(chain->bp == NULL);
665                 bref = &chain->bref;
666
667                 KKASSERT((bref->data_off & HAMMER2_OFF_MASK) != 0);
668                 KKASSERT(HAMMER2_DEC_CHECK(chain->bref.methods) ==
669                          HAMMER2_CHECK_ISCSI32);
670
671                 if (chain->bp == NULL) {
672                         /*
673                          * The data is embedded, we have to acquire the
674                          * buffer cache buffer and copy the data into it.
675                          */
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);
680
681                         /*
682                          * The getblk() optimization can only be used if the
683                          * physical block size matches the request.
684                          */
685                         if (chain->bytes == bbytes) {
686                                 bp = getblk(hmp->devvp, pbase, bbytes, 0, 0);
687                                 error = 0;
688                         } else {
689                                 error = bread(hmp->devvp, pbase, bbytes, &bp);
690                                 KKASSERT(error == 0);
691                         }
692                         bdata = (char *)bp->b_data + boff;
693
694                         /*
695                          * Copy the data to the buffer, mark the buffer
696                          * dirty, and convert the chain to unmodified.
697                          */
698                         bcopy(chain->data, bdata, chain->bytes);
699                         bp->b_flags |= B_CLUSTEROK;
700                         bdwrite(bp);
701                         bp = NULL;
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;
706                         else
707                                 ++hammer2_iod_indr_write;
708                 } else {
709                         chain->bref.check.iscsi32.value =
710                                 hammer2_icrc32(chain->data, chain->bytes);
711                 }
712         }
713         if (hammer2_debug & 0x0008) {
714                 kprintf("%*.*s} %p/%d %04x (flushed)",
715                         info->depth, info->depth, "",
716                         chain, chain->refs, chain->flags);
717         }
718 }
719
720 /*
721  * Flush helper scan1 (recursive)
722  *
723  * Flushes the children of the caller's chain (parent) and updates
724  * the blockref, restricted by sync_tid.
725  *
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.
729  *
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.
733  */
734 static int
735 hammer2_chain_flush_scan1(hammer2_chain_t *child, void *data)
736 {
737         hammer2_flush_info_t *info = data;
738         hammer2_chain_t *parent = info->parent;
739         /*hammer2_mount_t *hmp = info->hmp;*/
740         int diddeferral;
741
742 #if 0
743         kprintf("flush %p,%d [%08x] -> %p [%08x] %jx\n",
744                 parent, child->index, parent->flags,
745                 child, child->flags, child->bref.key);
746 #endif
747
748         /*
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.
752          */
753         if ((child->flags & (HAMMER2_CHAIN_SUBMODIFIED |
754                              HAMMER2_CHAIN_MODIFIED)) == 0) {
755                 return (0);
756         }
757         hammer2_chain_ref(child);
758         spin_unlock(&parent->core->cst.spin);
759
760         /*
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
763          * continuing.
764          */
765         hammer2_chain_unlock(parent);
766         hammer2_chain_lock(child, HAMMER2_RESOLVE_MAYBE);
767
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);
774                 return (0);
775         }
776
777         /*
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.
782          *
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.
788          *
789          * We have to be careful not to propagate the DESTROYED flag if
790          * the destruction occurred after our flush sync_tid.
791          */
792         if ((parent->flags & HAMMER2_CHAIN_DESTROYED) &&
793             (child->flags & HAMMER2_CHAIN_DELETED) &&
794 #if 0
795             child->delete_tid <= info->sync_tid &&
796 #endif
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);
802         }
803
804         /*
805          * Recurse and collect deferral data.
806          */
807         diddeferral = info->diddeferral;
808         ++info->depth;
809         hammer2_chain_flush_core(info, child);
810 #if FLUSH_DEBUG
811         kprintf("flush_core_done parent=%p flags=%08x child=%p.%d %08x\n",
812                 parent, parent->flags, child, child->bref.type, child->flags);
813 #endif
814         --info->depth;
815         info->diddeferral += diddeferral;
816
817         hammer2_chain_unlock(child);
818         hammer2_chain_drop(child);
819
820         hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
821
822         spin_lock(&parent->core->cst.spin);
823         return (0);
824 }
825
826 /*
827  * Flush helper scan2 (non-recursive)
828  *
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.
833  *
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.
838  *
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.
841  *
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 !=
846  *             HAMMER2_MAX_TID.
847  *
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.
851  *
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.
859  */
860 static int
861 hammer2_chain_flush_scan2(hammer2_chain_t *child, void *data)
862 {
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;
867         int count;
868         int child_flags;
869
870         /*
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.
874          *
875          * NOTE: DELETED always also sets MOVED.
876          */
877 #if FLUSH_DEBUG
878         kprintf("  scan2 parent %p %08x child %p %08x ", parent, parent->flags, child, child->flags);
879 #endif
880         if (parent->flags & HAMMER2_CHAIN_DELETED) {
881 #if FLUSH_DEBUG
882                 kprintf("A");
883 #endif
884                 child_flags = 0;
885                 goto finalize;
886         }
887
888         /*
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
892          * block table.
893          */
894         if (parent->bref.type == HAMMER2_BREF_TYPE_INODE &&
895             (parent->data->ipdata.op_flags & HAMMER2_OPFLAG_DIRECTDATA)) {
896 #if FLUSH_DEBUG
897                 kprintf("B");
898 #endif
899                 child_flags = 0;
900                 goto finalize;
901         }
902
903         /*
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.
908          *
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.
912          *
913          * XXX spin-lock on child->modify_tid ?
914          */
915 #if 0
916         if (child->modify_tid > info->sync_tid) {
917                 if (parent->delete_tid <= info->sync_tid)
918                         child_flags = 0;
919                 else
920                         child_flags = child->flags;
921 #if FLUSH_DEBUG
922                 kprintf("C");
923 #endif
924                 goto finalize;
925         }
926 #endif
927
928         if ((child->flags & HAMMER2_CHAIN_MOVED) == 0) {
929                 child_flags = child->flags;
930 #if FLUSH_DEBUG
931                 kprintf("D");
932 #endif
933                 goto finalize;
934         }
935
936         hammer2_chain_ref(child);
937         spin_unlock(&parent->core->cst.spin);
938
939         /*
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 (?).
944          *
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.
949          */
950         hammer2_chain_lock(child, HAMMER2_RESOLVE_NEVER);
951
952 #if 0
953         if (child->parent != parent) {
954                 child_flags = child->flags;
955                 hammer2_chain_unlock(child);
956                 spin_lock(&parent->core->cst.spin);
957 #if FLUSH_DEBUG
958                 kprintf("E");
959 #endif
960                 goto finalize;
961         }
962 #endif
963
964         /*
965          * The parent's blockref to the child must be deleted or updated.
966          *
967          * This point is not reached on successful DESTROYED optimizations
968          * but can be reached on recursive deletions.
969          *
970          * XXX recursive deletions not optimized.
971          */
972         hammer2_chain_modify(info->trans, parent, HAMMER2_MODIFY_NO_MODIFY_TID);
973
974         switch(parent->bref.type) {
975         case HAMMER2_BREF_TYPE_INODE:
976                 /*
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
981                  * children.
982                  *
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.
986                  */
987 #if 0
988                 KKASSERT((parent->data->ipdata.op_flags &
989                           HAMMER2_OPFLAG_DIRECTDATA) == 0);
990 #endif
991                 if (parent->data->ipdata.op_flags &
992                     HAMMER2_OPFLAG_DIRECTDATA) {
993                         base = NULL;
994                 } else {
995                         base = &parent->data->ipdata.u.blockset.blockref[0];
996                         count = HAMMER2_SET_COUNT;
997                 }
998                 break;
999         case HAMMER2_BREF_TYPE_INDIRECT:
1000                 if (parent->data) {
1001                         base = &parent->data->npdata.blockref[0];
1002                 } else {
1003                         base = NULL;
1004                         KKASSERT(child->flags & HAMMER2_CHAIN_DELETED);
1005                 }
1006                 count = parent->bytes / sizeof(hammer2_blockref_t);
1007                 break;
1008         case HAMMER2_BREF_TYPE_VOLUME:
1009                 base = &hmp->voldata.sroot_blockset.blockref[0];
1010                 count = HAMMER2_SET_COUNT;
1011                 break;
1012         default:
1013                 base = NULL;
1014                 count = 0;
1015                 panic("hammer2_chain_get: "
1016                       "unrecognized blockref type: %d",
1017                       parent->bref.type);
1018         }
1019
1020         /*
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.
1025          *
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!
1031          *
1032          *          We adjust the parent's bref pointer to the child but
1033          *          we do not modify the contents of the child.
1034          */
1035 #if 0
1036         if (child->delete_tid <= info->sync_tid) {
1037 #endif
1038         if (child->flags & HAMMER2_CHAIN_DELETED) {
1039                 if (base) {
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;
1044                 }
1045         } else {
1046                 if (base) {
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;
1051                 }
1052         }
1053         KKASSERT(child->index >= 0);
1054
1055         /*
1056          * Propagate mirror_tid back up.
1057          */
1058         if (info->mirror_tid < child->bref.mirror_tid) {
1059                 info->mirror_tid = child->bref.mirror_tid;
1060         }
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;
1064         }
1065
1066 /*cleanup:*/
1067         /*
1068          * Cleanup the children.  Clear the MOVED flag
1069          *
1070          * XXXWe can only clear the MOVED flag when the child has progressed
1071          * to the last parent in the duplication chain.
1072          *
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.
1075          */
1076 #if 0
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);
1083         }
1084 #endif
1085         if (child->flags & HAMMER2_CHAIN_MOVED) {
1086                 atomic_clear_int(&child->flags, HAMMER2_CHAIN_MOVED);
1087                 hammer2_chain_drop(child);      /* flag */
1088 #if 0
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 */
1095                 }
1096 #endif
1097         }
1098
1099         /*
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
1103          * situation.
1104          */
1105         child_flags = child->flags;
1106         hammer2_chain_unlock(child);
1107         hammer2_chain_drop(child);
1108         spin_lock(&parent->core->cst.spin);
1109 #if FLUSH_DEBUG
1110         kprintf("F");
1111 #endif
1112
1113         /*
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
1117          * up.
1118          */
1119 finalize:
1120 #if FLUSH_DEBUG
1121         kprintf("G child %08x act=%08x\n", child_flags, child->flags);
1122 #endif
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);
1128         }
1129
1130         return (0);
1131 }