hammer2 - Merge Daniel Flores's HAMMER2 GSOC project into the main tree
[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_chain_t *parent;
54         hammer2_trans_t *trans;
55         int             depth;
56         int             diddeferral;
57         struct flush_deferral_list flush_list;
58         hammer2_tid_t   sync_tid;       /* flush synchronization point */
59         hammer2_tid_t   mirror_tid;     /* collect mirror TID updates */
60 };
61
62 typedef struct hammer2_flush_info hammer2_flush_info_t;
63
64 static void hammer2_chain_flush_core(hammer2_flush_info_t *info,
65                                 hammer2_chain_t *chain);
66 static int hammer2_chain_flush_scan1(hammer2_chain_t *child, void *data);
67 static int hammer2_chain_flush_scan2(hammer2_chain_t *child, void *data);
68 static void hammer2_rollup_stats(hammer2_chain_t *parent,
69                                 hammer2_chain_t *child, int how);
70
71 #if 0
72 static __inline
73 void
74 hammer2_updatestats(hammer2_flush_info_t *info, hammer2_blockref_t *bref,
75                     int how)
76 {
77         hammer2_key_t bytes;
78
79         if (bref->type != 0) {
80                 bytes = 1 << (bref->data_off & HAMMER2_OFF_MASK_RADIX);
81                 if (bref->type == HAMMER2_BREF_TYPE_INODE)
82                         info->inode_count += how;
83                 if (how < 0)
84                         info->data_count -= bytes;
85                 else
86                         info->data_count += bytes;
87         }
88 }
89 #endif
90
91 /*
92  * Transaction support functions for writing to the filesystem.
93  *
94  * Initializing a new transaction allocates a transaction ID.  We
95  * don't bother marking the volume header MODIFIED.  Instead, the volume
96  * will be synchronized at a later time as part of a larger flush sequence.
97  *
98  * Non-flush transactions can typically run concurrently.  However if
99  * there are non-flush transaction both before AND after a flush trans,
100  * the transactions after stall until the ones before finish.
101  *
102  * Non-flush transactions occuring after a flush pointer can run concurrently
103  * with that flush.  They only have to wait for transactions prior to the
104  * flush trans to complete before they unstall.
105  *
106  * WARNING! Transaction ids are only allocated when the transaction becomes
107  *          active, which allows other transactions to insert ahead of us
108  *          if we are forced to block (only bioq transactions do that).
109  *
110  * WARNING! Modifications to the root volume cannot dup the root volume
111  *          header to handle synchronization points, so alloc_tid can
112  *          wind up (harmlessly) more advanced on flush.
113  *
114  * WARNING! Operations which might call inode_duplicate()/chain_duplicate()
115  *          depend heavily on having a unique sync_tid to avoid duplication
116  *          collisions (which key off of delete_tid).
117  */
118 void
119 hammer2_trans_init(hammer2_trans_t *trans, hammer2_pfsmount_t *pmp, int flags)
120 {
121         hammer2_cluster_t *cluster;
122         hammer2_mount_t *hmp;
123         hammer2_trans_t *scan;
124
125         bzero(trans, sizeof(*trans));
126         trans->pmp = pmp;
127         cluster = pmp->cluster;
128         hmp = cluster->hmp;
129
130         hammer2_voldata_lock(hmp);
131         trans->flags = flags;
132         trans->td = curthread;
133
134         if (flags & HAMMER2_TRANS_ISFLUSH) {
135                 /*
136                  * If multiple flushes are trying to run we have to
137                  * wait until it is our turn, then set curflush to
138                  * indicate that a flush is now pending (but not
139                  * necessarily active yet).
140                  *
141                  * NOTE: Do not set trans->blocked here.
142                  */
143                 ++hmp->flushcnt;
144                 while (hmp->curflush != NULL) {
145                         lksleep(&hmp->curflush, &hmp->voldatalk,
146                                 0, "h2multf", hz);
147                 }
148                 hmp->curflush = trans;
149                 TAILQ_INSERT_TAIL(&hmp->transq, trans, entry);
150
151                 /*
152                  * If we are a flush we have to wait for all transactions
153                  * prior to our flush synchronization point to complete
154                  * before we can start our flush.
155                  *
156                  * Most importantly, this includes bioq flushes.
157                  *
158                  * NOTE: Do not set trans->blocked here.
159                  */
160                 while (TAILQ_FIRST(&hmp->transq) != trans) {
161                         lksleep(&trans->sync_tid, &hmp->voldatalk,
162                                 0, "h2syncw", hz);
163                 }
164
165                 /*
166                  * don't assign sync_tid until we become the running
167                  * flush.  topo_flush_tid is used to control when
168                  * chain modifications in concurrent transactions are
169                  * required to delete-duplicate (so as not to disturb
170                  * the state of what is being currently flushed).
171                  */
172                 trans->sync_tid = hmp->voldata.alloc_tid++;
173                 hmp->topo_flush_tid = trans->sync_tid;
174
175                 /*
176                  * Once we become the running flush we can wakeup anyone
177                  * who blocked on us, up to the next flush.  That is,
178                  * our flush can run concurrent with frontend operations.
179                  */
180                 scan = trans;
181                 while ((scan = TAILQ_NEXT(scan, entry)) != NULL) {
182                         if (scan->flags & HAMMER2_TRANS_ISFLUSH)
183                                 break;
184                         if (scan->blocked == 0)
185                                 break;
186                         scan->blocked = 0;
187                         wakeup(&scan->blocked);
188                 }
189         } else if ((flags & HAMMER2_TRANS_BUFCACHE) && hmp->curflush) {
190                 /*
191                  * We cannot block if we are the bioq thread.  When a
192                  * flush is not pending we can operate normally but
193                  * if a flush IS pending the bioq thread's transaction
194                  * must be placed either before or after curflush.
195                  *
196                  * If the current flush is waiting the bioq thread's
197                  * transaction is placed before.  If it is running the
198                  * bioq thread's transaction is placed after.
199                  */
200                 scan = TAILQ_FIRST(&hmp->transq);
201                 if (scan != hmp->curflush) {
202                         TAILQ_INSERT_BEFORE(hmp->curflush, trans, entry);
203                 } else {
204                         TAILQ_INSERT_TAIL(&hmp->transq, trans, entry);
205                 }
206                 trans->sync_tid = hmp->voldata.alloc_tid++;
207         } else {
208                 /*
209                  * If this is a normal transaction and not a flush, or
210                  * if this is a bioq transaction and no flush is pending,
211                  * we can queue normally.
212                  *
213                  * Normal transactions must block while a pending flush is
214                  * waiting for prior transactions to complete.  Once the
215                  * pending flush becomes active we can run concurrently
216                  * with it.
217                  */
218                 TAILQ_INSERT_TAIL(&hmp->transq, trans, entry);
219                 scan = TAILQ_FIRST(&hmp->transq);
220                 if (hmp->curflush && hmp->curflush != scan) {
221                         trans->blocked = 1;
222                         while (trans->blocked) {
223                                 lksleep(&trans->blocked, &hmp->voldatalk,
224                                         0, "h2trans", hz);
225                         }
226                 }
227                 trans->sync_tid = hmp->voldata.alloc_tid++;
228         }
229         hammer2_voldata_unlock(hmp, 0);
230 }
231
232 void
233 hammer2_trans_done(hammer2_trans_t *trans)
234 {
235         hammer2_cluster_t *cluster;
236         hammer2_mount_t *hmp;
237         hammer2_trans_t *scan;
238
239         cluster = trans->pmp->cluster;
240         hmp = cluster->hmp;
241
242         hammer2_voldata_lock(hmp);
243         TAILQ_REMOVE(&hmp->transq, trans, entry);
244         if (trans->flags & HAMMER2_TRANS_ISFLUSH) {
245                 --hmp->flushcnt;
246                 if (hmp->flushcnt) {
247                         /*
248                          * If we were a flush then wakeup anyone waiting on
249                          * curflush (i.e. other flushes that want to run).
250                          * Leave topo_flush_id set (I think we could probably
251                          * clear it to zero here).
252                          */
253                         hmp->curflush = NULL;
254                         wakeup(&hmp->curflush);
255                 } else {
256                         /*
257                          * Theoretically we don't have to clear flush_tid
258                          * here since the flush will have synchronized
259                          * all operations <= flush_tid already.  But for
260                          * now zero-it.
261                          */
262                         hmp->curflush = NULL;
263                         hmp->topo_flush_tid = 0;
264                 }
265         } else {
266                 /*
267                  * If we are not a flush but a flush is now at the head
268                  * of the queue and we were previously blocking it,
269                  * we can now unblock it.
270                  */
271                 if (hmp->flushcnt &&
272                     (scan = TAILQ_FIRST(&hmp->transq)) != NULL &&
273                     trans->sync_tid < scan->sync_tid &&
274                     (scan->flags & HAMMER2_TRANS_ISFLUSH)) {
275                         wakeup(&scan->sync_tid);
276                 }
277         }
278         hammer2_voldata_unlock(hmp, 0);
279 }
280
281 /*
282  * Flush the chain and all modified sub-chains through the specified
283  * synchronization point (sync_tid), propagating parent chain modifications
284  * and mirror_tid updates back up as needed.  Since we are recursing downward
285  * we do not have to deal with the complexities of multi-homed chains (chains
286  * with multiple parents).
287  *
288  * Caller must have interlocked against any non-flush-related modifying
289  * operations in progress whos modify_tid values are less than or equal
290  * to the passed sync_tid.
291  *
292  * Caller must have already vetted synchronization points to ensure they
293  * are properly flushed.  Only snapshots and cluster flushes can create
294  * these sorts of synchronization points.
295  *
296  * This routine can be called from several places but the most important
297  * is from the hammer2_vop_reclaim() function.  We want to try to completely
298  * clean out the inode structure to prevent disconnected inodes from
299  * building up and blowing out the kmalloc pool.  However, it is not actually
300  * necessary to flush reclaimed inodes to maintain HAMMER2's crash recovery
301  * capability.
302  *
303  * chain is locked on call and will remain locked on return.  If a flush
304  * occured, the chain's MOVED bit will be set indicating that its parent
305  * (which is not part of the flush) should be updated.
306  */
307 void
308 hammer2_chain_flush(hammer2_trans_t *trans, hammer2_chain_t *chain)
309 {
310         hammer2_chain_t *scan;
311         hammer2_chain_core_t *core;
312         hammer2_flush_info_t info;
313
314         /*
315          * Execute the recursive flush and handle deferrals.
316          *
317          * Chains can be ridiculously long (thousands deep), so to
318          * avoid blowing out the kernel stack the recursive flush has a
319          * depth limit.  Elements at the limit are placed on a list
320          * for re-execution after the stack has been popped.
321          */
322         bzero(&info, sizeof(info));
323         TAILQ_INIT(&info.flush_list);
324         info.trans = trans;
325         info.sync_tid = trans->sync_tid;
326         info.mirror_tid = 0;
327
328         core = chain->core;
329
330         for (;;) {
331                 /*
332                  * Unwind deep recursions which had been deferred.  This
333                  * can leave MOVED set for these chains, which will be
334                  * handled when we [re]flush chain after the unwind.
335                  */
336                 while ((scan = TAILQ_FIRST(&info.flush_list)) != NULL) {
337                         KKASSERT(scan->flags & HAMMER2_CHAIN_DEFERRED);
338                         TAILQ_REMOVE(&info.flush_list, scan, flush_node);
339                         atomic_clear_int(&scan->flags, HAMMER2_CHAIN_DEFERRED);
340
341                         /*
342                          * Now that we've popped back up we can do a secondary
343                          * recursion on the deferred elements.
344                          */
345                         if (hammer2_debug & 0x0040)
346                                 kprintf("defered flush %p\n", scan);
347                         hammer2_chain_lock(scan, HAMMER2_RESOLVE_MAYBE);
348                         hammer2_chain_flush(trans, scan);
349                         hammer2_chain_unlock(scan);
350                         hammer2_chain_drop(scan);       /* ref from deferral */
351                 }
352
353                 /*
354                  * Flush pass1 on root.
355                  */
356                 info.diddeferral = 0;
357                 hammer2_chain_flush_core(&info, chain);
358 #if FLUSH_DEBUG
359                 kprintf("flush_core_done parent=<base> chain=%p.%d %08x\n",
360                         chain, chain->bref.type, chain->flags);
361 #endif
362
363                 /*
364                  * Only loop if deep recursions have been deferred.
365                  */
366                 if (TAILQ_EMPTY(&info.flush_list))
367                         break;
368         }
369 }
370
371 /*
372  * This is the core of the chain flushing code.  The chain is locked by the
373  * caller and remains locked on return.  This function is keyed off of
374  * the SUBMODIFIED bit but must make fine-grained choices based on the
375  * synchronization point we are flushing to.
376  *
377  * If the flush accomplished any work chain will be flagged MOVED
378  * indicating a copy-on-write propagation back up is required.
379  * Deep sub-nodes may also have been entered onto the deferral list.
380  * MOVED is never set on the volume root.
381  *
382  * NOTE: modify_tid is different from MODIFIED.  modify_tid is updated
383  *       only when a chain is specifically modified, and not updated
384  *       for copy-on-write propagations.  MODIFIED is set on any modification
385  *       including copy-on-write propagations.
386  */
387 static void
388 hammer2_chain_flush_core(hammer2_flush_info_t *info, hammer2_chain_t *chain)
389 {
390         hammer2_mount_t *hmp;
391         hammer2_blockref_t *bref;
392         hammer2_off_t pbase;
393         hammer2_off_t pmask;
394         hammer2_tid_t saved_sync;
395         hammer2_trans_t *trans = info->trans;
396         hammer2_chain_core_t *core;
397         size_t psize;
398         size_t boff;
399         char *bdata;
400         struct buf *bp;
401         int error;
402         int wasmodified;
403         int diddeferral = 0;
404
405         hmp = chain->hmp;
406
407 #if FLUSH_DEBUG
408         if (info->parent)
409                 kprintf("flush_core %p->%p.%d %08x (%s)\n",
410                         info->parent, chain, chain->bref.type,
411                         chain->flags,
412                         ((chain->bref.type == HAMMER2_BREF_TYPE_INODE) ?
413                                 chain->data->ipdata.filename : "?"));
414         else
415                 kprintf("flush_core NULL->%p.%d %08x (%s)\n",
416                         chain, chain->bref.type,
417                         chain->flags,
418                         ((chain->bref.type == HAMMER2_BREF_TYPE_INODE) ?
419                                 chain->data->ipdata.filename : "?"));
420 #endif
421         /*
422          * Ignore chains modified beyond the current flush point.  These
423          * will be treated as if they did not exist.
424          */
425         if (chain->modify_tid > info->sync_tid)
426                 return;
427
428         /*
429          * Deleted chains which have not been destroyed must be retained,
430          * and we probably have to recurse to clean-up any sub-trees.
431          * However, restricted flushes can stop processing here because
432          * the chain cleanup will be handled by a later normal flush.
433          *
434          * The MODIFIED bit can likely be cleared in this situation and we
435          * will do so later on in this procedure.
436          */
437         if (chain->delete_tid <= info->sync_tid) {
438                 if (trans->flags & HAMMER2_TRANS_RESTRICTED)
439                         return;
440         }
441
442         saved_sync = info->sync_tid;
443         core = chain->core;
444
445         /*
446          * If SUBMODIFIED is set we recurse the flush and adjust the
447          * blockrefs accordingly.
448          *
449          * NOTE: Looping on SUBMODIFIED can prevent a flush from ever
450          *       finishing in the face of filesystem activity.
451          */
452         if (chain->flags & HAMMER2_CHAIN_SUBMODIFIED) {
453                 hammer2_chain_t *saved_parent;
454                 hammer2_tid_t saved_mirror;
455
456                 /*
457                  * Clear SUBMODIFIED to catch races.  Note that any child
458                  * with MODIFIED, DELETED, or MOVED set during Scan2, after
459                  * it processes the child, will cause SUBMODIFIED to be
460                  * re-set.
461                  * child has to be flushed SUBMODIFIED will wind up being
462                  * set again (for next time), but this does not stop us from
463                  * synchronizing block updates which occurred.
464                  *
465                  * We don't want to set our chain to MODIFIED gratuitously.
466                  *
467                  * We need an extra ref on chain because we are going to
468                  * release its lock temporarily in our child loop.
469                  */
470                 atomic_clear_int(&chain->flags, HAMMER2_CHAIN_SUBMODIFIED);
471                 hammer2_chain_ref(chain);
472
473                 /*
474                  * Run two passes.  The first pass handles MODIFIED and
475                  * SUBMODIFIED chains and recurses while the second pass
476                  * handles MOVED chains on the way back up.
477                  *
478                  * If the stack gets too deep we defer scan1, but must
479                  * be sure to still run scan2 if on the next loop the
480                  * deferred chain has been flushed and now needs MOVED
481                  * handling on the way back up.
482                  *
483                  * Scan1 is recursive.
484                  *
485                  * NOTE: The act of handling a modified/submodified chain can
486                  *       cause the MOVED Flag to be set.  It can also be set
487                  *       via hammer2_chain_delete() and in other situations.
488                  *
489                  * NOTE: RB_SCAN() must be used instead of RB_FOREACH()
490                  *       because children can be physically removed during
491                  *       the scan.
492                  */
493                 saved_parent = info->parent;
494                 saved_mirror = info->mirror_tid;
495                 info->parent = chain;
496                 info->mirror_tid = chain->bref.mirror_tid;
497
498                 if (info->depth == HAMMER2_FLUSH_DEPTH_LIMIT) {
499                         if ((chain->flags & HAMMER2_CHAIN_DEFERRED) == 0) {
500                                 hammer2_chain_ref(chain);
501                                 TAILQ_INSERT_TAIL(&info->flush_list,
502                                                   chain, flush_node);
503                                 atomic_set_int(&chain->flags,
504                                                HAMMER2_CHAIN_DEFERRED);
505                         }
506                         diddeferral = 1;
507                 } else {
508                         info->diddeferral = 0;
509                         spin_lock(&core->cst.spin);
510                         RB_SCAN(hammer2_chain_tree, &chain->core->rbtree,
511                                 NULL, hammer2_chain_flush_scan1, info);
512                         spin_unlock(&core->cst.spin);
513                         diddeferral += info->diddeferral;
514                 }
515
516                 /*
517                  * Handle successfully flushed children who are in the MOVED
518                  * state on the way back up the recursion.  This can have
519                  * the side-effect of clearing MOVED.
520                  *
521                  * We execute this even if there were deferrals to try to
522                  * keep the chain topology cleaner.
523                  *
524                  * Scan2 is non-recursive.
525                  */
526                 if (diddeferral) {
527                         atomic_set_int(&chain->flags,
528                                        HAMMER2_CHAIN_SUBMODIFIED);
529                 } else {
530 #if FLUSH_DEBUG
531                         kprintf("scan2_start parent %p %08x\n",
532                                 chain, chain->flags);
533 #endif
534                         spin_lock(&core->cst.spin);
535                         RB_SCAN(hammer2_chain_tree, &core->rbtree,
536                                 NULL, hammer2_chain_flush_scan2, info);
537                         spin_unlock(&core->cst.spin);
538 #if FLUSH_DEBUG
539                         kprintf("scan2_stop  parent %p %08x\n",
540                                 chain, chain->flags);
541 #endif
542                 }
543                 chain->bref.mirror_tid = info->mirror_tid;
544                 info->mirror_tid = saved_mirror;
545                 info->parent = saved_parent;
546                 hammer2_chain_drop(chain);
547         }
548
549         /*
550          * Restore sync_tid in case it was restricted by a delete/duplicate.
551          */
552         info->sync_tid = saved_sync;
553
554         /*
555          * Rollup diddeferral for caller.  Note direct assignment, not +=.
556          */
557         info->diddeferral = diddeferral;
558
559         /*
560          * Do not flush chain if there were any deferrals.  It will be
561          * retried later after the deferrals are independently handled.
562          */
563         if (diddeferral) {
564                 if (hammer2_debug & 0x0008) {
565                         kprintf("%*.*s} %p/%d %04x (deferred)",
566                                 info->depth, info->depth, "",
567                                 chain, chain->refs, chain->flags);
568                 }
569                 return;
570         }
571
572         /*
573          * If we encounter a deleted chain within our flush we can clear
574          * the MODIFIED bit and avoid flushing it whether it has been
575          * destroyed or not.  We must make sure that the chain is flagged
576          * MOVED in this situation so the parent picks up the deletion.
577          *
578          * Note that scan2 has already executed above so statistics have
579          * already been rolled up.
580          */
581         if (chain->delete_tid <= info->sync_tid) {
582                 if (chain->flags & HAMMER2_CHAIN_MODIFIED) {
583                         if (chain->bp) {
584                                 if (chain->bytes == chain->bp->b_bufsize)
585                                         chain->bp->b_flags |= B_INVAL|B_RELBUF;
586                         }
587                         if ((chain->flags & HAMMER2_CHAIN_MOVED) == 0) {
588                                 hammer2_chain_ref(chain);
589                                 atomic_set_int(&chain->flags,
590                                                HAMMER2_CHAIN_MOVED);
591                         }
592                         atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
593                         hammer2_chain_drop(chain);
594                 }
595                 return;
596         }
597 #if 0
598         if ((chain->flags & HAMMER2_CHAIN_DESTROYED) &&
599             (chain->flags & HAMMER2_CHAIN_DELETED) &&
600             (trans->flags & HAMMER2_TRANS_RESTRICTED) == 0) {
601                 /*
602                  * Throw-away the MODIFIED flag
603                  */
604                 if (chain->flags & HAMMER2_CHAIN_MODIFIED) {
605                         if (chain->bp) {
606                                 if (chain->bytes == chain->bp->b_bufsize)
607                                         chain->bp->b_flags |= B_INVAL|B_RELBUF;
608                         }
609                         atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
610                         hammer2_chain_drop(chain);
611                 }
612                 return;
613         }
614 #endif
615
616         /*
617          * A degenerate flush might not have flushed anything and thus not
618          * processed modified blocks on the way back up.  Detect the case.
619          *
620          * Note that MOVED can be set without MODIFIED being set due to
621          * a deletion, in which case it is handled by Scan2 later on.
622          *
623          * Both bits can be set along with DELETED due to a deletion if
624          * modified data within the synchronization zone and the chain
625          * was then deleted beyond the zone, in which case we still have
626          * to flush for synchronization point consistency.  Otherwise though
627          * DELETED and MODIFIED are treated as separate flags.
628          */
629         if ((chain->flags & HAMMER2_CHAIN_MODIFIED) == 0)
630                 return;
631
632         /*
633          * Issue flush.
634          *
635          * A DESTROYED node that reaches this point must be flushed for
636          * synchronization point consistency.
637          */
638
639         /*
640          * Update mirror_tid, clear MODIFIED, and set MOVED.
641          *
642          * The caller will update the parent's reference to this chain
643          * by testing MOVED as long as the modification was in-bounds.
644          *
645          * MOVED is never set on the volume root as there is no parent
646          * to adjust.
647          */
648         if (chain->bref.mirror_tid < info->sync_tid)
649                 chain->bref.mirror_tid = info->sync_tid;
650         wasmodified = (chain->flags & HAMMER2_CHAIN_MODIFIED) != 0;
651         atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
652         if (chain == &hmp->vchain)
653                 kprintf("(FLUSHED VOLUME HEADER)\n");
654         if (chain == &hmp->fchain)
655                 kprintf("(FLUSHED FREEMAP HEADER)\n");
656
657         if ((chain->flags & HAMMER2_CHAIN_MOVED) ||
658             chain == &hmp->vchain ||
659             chain == &hmp->fchain) {
660                 /*
661                  * Drop the ref from the MODIFIED bit we cleared.
662                  */
663                 if (wasmodified)
664                         hammer2_chain_drop(chain);
665         } else {
666                 /*
667                  * If we were MODIFIED we inherit the ref from clearing
668                  * that bit, otherwise we need another ref.
669                  */
670                 if (wasmodified == 0)
671                         hammer2_chain_ref(chain);
672                 atomic_set_int(&chain->flags, HAMMER2_CHAIN_MOVED);
673         }
674
675         /*
676          * If this is part of a recursive flush we can go ahead and write
677          * out the buffer cache buffer and pass a new bref back up the chain
678          * via the MOVED bit.
679          *
680          * Volume headers are NOT flushed here as they require special
681          * processing.
682          */
683         switch(chain->bref.type) {
684         case HAMMER2_BREF_TYPE_FREEMAP:
685                 hammer2_modify_volume(hmp);
686                 break;
687         case HAMMER2_BREF_TYPE_VOLUME:
688                 /*
689                  * We should flush the free block table before we calculate
690                  * CRCs and copy voldata -> volsync.
691                  *
692                  * To prevent SMP races, fchain must remain locked until
693                  * voldata is copied to volsync.
694                  */
695                 hammer2_chain_lock(&hmp->fchain, HAMMER2_RESOLVE_ALWAYS);
696                 if (hmp->fchain.flags & (HAMMER2_CHAIN_MODIFIED |
697                                          HAMMER2_CHAIN_SUBMODIFIED)) {
698                         /* this will modify vchain as a side effect */
699                         hammer2_chain_flush(info->trans, &hmp->fchain);
700                 }
701
702                 /*
703                  * The volume header is flushed manually by the syncer, not
704                  * here.  All we do is adjust the crc's.
705                  */
706                 KKASSERT(chain->data != NULL);
707                 KKASSERT(chain->bp == NULL);
708                 kprintf("volume header mirror_tid %jd\n",
709                         hmp->voldata.mirror_tid);
710
711                 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT1]=
712                         hammer2_icrc32(
713                                 (char *)&hmp->voldata +
714                                  HAMMER2_VOLUME_ICRC1_OFF,
715                                 HAMMER2_VOLUME_ICRC1_SIZE);
716                 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT0]=
717                         hammer2_icrc32(
718                                 (char *)&hmp->voldata +
719                                  HAMMER2_VOLUME_ICRC0_OFF,
720                                 HAMMER2_VOLUME_ICRC0_SIZE);
721                 hmp->voldata.icrc_volheader =
722                         hammer2_icrc32(
723                                 (char *)&hmp->voldata +
724                                  HAMMER2_VOLUME_ICRCVH_OFF,
725                                 HAMMER2_VOLUME_ICRCVH_SIZE);
726                 hmp->volsync = hmp->voldata;
727                 atomic_set_int(&chain->flags, HAMMER2_CHAIN_VOLUMESYNC);
728                 hammer2_chain_unlock(&hmp->fchain);
729                 break;
730         case HAMMER2_BREF_TYPE_DATA:
731                 /*
732                  * Data elements have already been flushed via the logical
733                  * file buffer cache.  Their hash was set in the bref by
734                  * the vop_write code.
735                  *
736                  * Make sure any device buffer(s) have been flushed out here.
737                  * (there aren't usually any to flush).
738                  */
739                 psize = hammer2_devblksize(chain->bytes);
740                 pmask = (hammer2_off_t)psize - 1;
741                 pbase = chain->bref.data_off & ~pmask;
742                 boff = chain->bref.data_off & (HAMMER2_OFF_MASK & pmask);
743
744                 bp = getblk(hmp->devvp, pbase, psize, GETBLK_NOWAIT, 0);
745                 if (bp) {
746                         if ((bp->b_flags & (B_CACHE | B_DIRTY)) ==
747                             (B_CACHE | B_DIRTY)) {
748                                 cluster_awrite(bp);
749                         } else {
750                                 bp->b_flags |= B_RELBUF;
751                                 brelse(bp);
752                         }
753                 }
754                 break;
755 #if 0
756         case HAMMER2_BREF_TYPE_INDIRECT:
757                 /*
758                  * Indirect blocks may be in an INITIAL state.  Use the
759                  * chain_lock() call to ensure that the buffer has been
760                  * instantiated (even though it is already locked the buffer
761                  * might not have been instantiated).
762                  *
763                  * Only write the buffer out if it is dirty, it is possible
764                  * the operating system had already written out the buffer.
765                  */
766                 hammer2_chain_lock(chain, HAMMER2_RESOLVE_ALWAYS);
767                 KKASSERT(chain->bp != NULL);
768
769                 bp = chain->bp;
770                 if ((chain->flags & HAMMER2_CHAIN_DIRTYBP) ||
771                     (bp->b_flags & B_DIRTY)) {
772                         bdwrite(chain->bp);
773                 } else {
774                         brelse(chain->bp);
775                 }
776                 chain->bp = NULL;
777                 chain->data = NULL;
778                 hammer2_chain_unlock(chain);
779                 break;
780 #endif
781         case HAMMER2_BREF_TYPE_INDIRECT:
782         case HAMMER2_BREF_TYPE_FREEMAP_NODE:
783                 /*
784                  * Device-backed.  Buffer will be flushed by the sync
785                  * code XXX.
786                  */
787                 KKASSERT((chain->flags & HAMMER2_CHAIN_EMBEDDED) == 0);
788                 break;
789         case HAMMER2_BREF_TYPE_FREEMAP_LEAF:
790         default:
791                 /*
792                  * Embedded elements have to be flushed out.
793                  * (Basically just BREF_TYPE_INODE).
794                  */
795                 KKASSERT(chain->flags & HAMMER2_CHAIN_EMBEDDED);
796                 KKASSERT(chain->data != NULL);
797                 KKASSERT(chain->bp == NULL);
798                 bref = &chain->bref;
799
800                 KKASSERT((bref->data_off & HAMMER2_OFF_MASK) != 0);
801                 KKASSERT(HAMMER2_DEC_CHECK(chain->bref.methods) ==
802                          HAMMER2_CHECK_ISCSI32 ||
803                          HAMMER2_DEC_CHECK(chain->bref.methods) ==
804                          HAMMER2_CHECK_FREEMAP);
805
806                 /*
807                  * The data is embedded, we have to acquire the
808                  * buffer cache buffer and copy the data into it.
809                  */
810                 psize = hammer2_devblksize(chain->bytes);
811                 pmask = (hammer2_off_t)psize - 1;
812                 pbase = bref->data_off & ~pmask;
813                 boff = bref->data_off & (HAMMER2_OFF_MASK & pmask);
814
815                 /*
816                  * The getblk() optimization can only be used if the
817                  * physical block size matches the request.
818                  */
819                 error = bread(hmp->devvp, pbase, psize, &bp);
820                 KKASSERT(error == 0);
821
822                 bdata = (char *)bp->b_data + boff;
823
824                 /*
825                  * Copy the data to the buffer, mark the buffer
826                  * dirty, and convert the chain to unmodified.
827                  */
828                 bcopy(chain->data, bdata, chain->bytes);
829                 bp->b_flags |= B_CLUSTEROK;
830                 bdwrite(bp);
831                 bp = NULL;
832
833                 switch(HAMMER2_DEC_CHECK(chain->bref.methods)) {
834                 case HAMMER2_CHECK_FREEMAP:
835                         chain->bref.check.freemap.icrc32 =
836                                 hammer2_icrc32(chain->data, chain->bytes);
837                         break;
838                 case HAMMER2_CHECK_ISCSI32:
839                         chain->bref.check.iscsi32.value =
840                                 hammer2_icrc32(chain->data, chain->bytes);
841                         break;
842                 default:
843                         panic("hammer2_flush_core: bad crc type");
844                         break; /* NOT REACHED */
845                 }
846                 if (chain->bref.type == HAMMER2_BREF_TYPE_INODE)
847                         ++hammer2_iod_meta_write;
848                 else
849                         ++hammer2_iod_indr_write;
850         }
851 }
852
853 /*
854  * Flush helper scan1 (recursive)
855  *
856  * Flushes the children of the caller's chain (parent) and updates
857  * the blockref, restricted by sync_tid.
858  *
859  * Ripouts during the loop should not cause any problems.  Because we are
860  * flushing to a synchronization point, modification races will occur after
861  * sync_tid and do not have to be flushed anyway.
862  *
863  * It is also ok if the parent is chain_duplicate()'d while unlocked because
864  * the delete/duplication will install a delete_tid that is still larger than
865  * our current sync_tid.
866  */
867 static int
868 hammer2_chain_flush_scan1(hammer2_chain_t *child, void *data)
869 {
870         hammer2_flush_info_t *info = data;
871         hammer2_trans_t *trans = info->trans;
872         hammer2_chain_t *parent = info->parent;
873         int diddeferral;
874
875         /*
876          * We should only need to recurse if SUBMODIFIED is set, but as
877          * a safety also recurse if MODIFIED is also set.
878          *
879          * Return early if neither bit is set.  We must re-assert the
880          * SUBMODIFIED flag in the parent if any child covered by the
881          * parent (via delete_tid) is skipped.
882          */
883         if ((child->flags & (HAMMER2_CHAIN_MODIFIED |
884                              HAMMER2_CHAIN_SUBMODIFIED)) == 0) {
885                 return (0);
886         }
887         if (child->modify_tid > trans->sync_tid) {
888                 if (parent->delete_tid > trans->sync_tid) {
889                         atomic_set_int(&parent->flags,
890                                        HAMMER2_CHAIN_SUBMODIFIED);
891                 }
892                 return (0);
893         }
894
895         hammer2_chain_ref(child);
896         spin_unlock(&parent->core->cst.spin);
897
898         /*
899          * The caller has added a ref to the parent so we can temporarily
900          * unlock it in order to lock the child.  Re-check the flags before
901          * continuing.
902          */
903         hammer2_chain_unlock(parent);
904         hammer2_chain_lock(child, HAMMER2_RESOLVE_MAYBE);
905
906         if ((child->flags & (HAMMER2_CHAIN_MODIFIED |
907                              HAMMER2_CHAIN_SUBMODIFIED)) == 0) {
908                 hammer2_chain_unlock(child);
909                 hammer2_chain_drop(child);
910                 hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
911                 spin_lock(&parent->core->cst.spin);
912                 return (0);
913         }
914         if (child->modify_tid > trans->sync_tid) {
915                 hammer2_chain_unlock(child);
916                 hammer2_chain_drop(child);
917                 hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
918                 spin_lock(&parent->core->cst.spin);
919                 if (parent->delete_tid > trans->sync_tid) {
920                         atomic_set_int(&parent->flags,
921                                        HAMMER2_CHAIN_SUBMODIFIED);
922                 }
923                 return (0);
924         }
925
926         /*
927          * The DESTROYED flag can only be initially set on an unreferenced
928          * deleted inode and will propagate downward via the mechanic below.
929          * Such inode chains have been deleted for good and should no longer
930          * be subject to delete/duplication.
931          *
932          * This optimization allows the inode reclaim (destroy unlinked file
933          * on vnode reclamation after last close) to be flagged by just
934          * setting HAMMER2_CHAIN_DESTROYED at the top level and then will
935          * cause the chains to be terminated and related buffers to be
936          * invalidated and not flushed out.
937          *
938          * We have to be careful not to propagate the DESTROYED flag if
939          * the destruction occurred after our flush sync_tid.
940          */
941         if ((parent->flags & HAMMER2_CHAIN_DESTROYED) &&
942             (child->flags & HAMMER2_CHAIN_DELETED) &&
943             (child->flags & HAMMER2_CHAIN_DESTROYED) == 0) {
944                 atomic_set_int(&child->flags, HAMMER2_CHAIN_DESTROYED |
945                                               HAMMER2_CHAIN_SUBMODIFIED);
946         }
947
948         /*
949          * Recurse and collect deferral data.
950          */
951         diddeferral = info->diddeferral;
952         ++info->depth;
953         hammer2_chain_flush_core(info, child);
954 #if FLUSH_DEBUG
955         kprintf("flush_core_done parent=%p flags=%08x child=%p.%d %08x\n",
956                 parent, parent->flags, child, child->bref.type, child->flags);
957 #endif
958         --info->depth;
959         info->diddeferral += diddeferral;
960
961         if (child->flags & HAMMER2_CHAIN_SUBMODIFIED)
962                 atomic_set_int(&parent->flags, HAMMER2_CHAIN_SUBMODIFIED);
963
964         hammer2_chain_unlock(child);
965         hammer2_chain_drop(child);
966
967         hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
968
969         spin_lock(&parent->core->cst.spin);
970         return (0);
971 }
972
973 /*
974  * Flush helper scan2 (non-recursive)
975  *
976  * This pass on a chain's children propagates any MOVED or DELETED
977  * elements back up the chain towards the root after those elements have
978  * been fully flushed.  Unlike scan1, this function is NOT recursive and
979  * the parent remains locked across the entire scan.
980  *
981  * This function also rolls up storage statistics.
982  *
983  * NOTE!  We must re-set SUBMODIFIED on the parent(s) as appropriate, and
984  *        due to the above conditions it is possible to do this and still
985  *        have some children flagged MOVED depending on the synchronization.
986  *
987  * NOTE!  A deletion is a visbility issue, there can still be referenced to
988  *        deleted elements (for example, to an unlinked file which is still
989  *        open), and there can also be multiple chains pointing to the same
990  *        bref where some are deleted and some are not (for example due to
991  *        a rename).   So a chain marked for deletion is basically considered
992  *        to be live until it is explicitly destroyed or until its ref-count
993  *        reaches zero (also implying that MOVED and MODIFIED are clear).
994  */
995 static int
996 hammer2_chain_flush_scan2(hammer2_chain_t *child, void *data)
997 {
998         hammer2_flush_info_t *info = data;
999         hammer2_chain_t *parent = info->parent;
1000         hammer2_chain_core_t *above = child->above;
1001         hammer2_mount_t *hmp = child->hmp;
1002         hammer2_trans_t *trans = info->trans;
1003         hammer2_blockref_t *base;
1004         int count;
1005
1006         /*
1007          * Inodes with stale children that have been converted to DIRECTDATA
1008          * mode (file extension or hardlink conversion typically) need to
1009          * skipped right now before we start messing with a non-existant
1010          * block table.
1011          */
1012 #if 0
1013         if (parent->bref.type == HAMMER2_BREF_TYPE_INODE &&
1014             (parent->data->ipdata.op_flags & HAMMER2_OPFLAG_DIRECTDATA)) {
1015 #if FLUSH_DEBUG
1016                 kprintf("B");
1017 #endif
1018                 goto finalize;
1019         }
1020 #endif
1021
1022         /*
1023          * Ignore children created after our flush point, treating them as
1024          * if they did not exist).  These children will not cause the parent
1025          * to be updated.
1026          *
1027          * When we encounter such children and the parent chain has not been
1028          * deleted, delete/duplicated, or delete/duplicated-for-move, then
1029          * the parent may be used to funnel through several flush points.
1030          * We must re-set the SUBMODIFIED flag in the parent to ensure that
1031          * those flushes have visbility.  A simple test of delete_tid suffices
1032          * to determine if the parent spans beyond our current flush.
1033          */
1034         if (child->modify_tid > trans->sync_tid) {
1035 #if FLUSH_DEBUG
1036                 kprintf("E");
1037 #endif
1038                 goto finalize;
1039         }
1040
1041         /*
1042          * Ignore children which have not changed.  The parent's block table
1043          * is already correct.
1044          */
1045         if ((child->flags & HAMMER2_CHAIN_MOVED) == 0) {
1046 #if FLUSH_DEBUG
1047                 kprintf("D");
1048 #endif
1049                 goto finalize;
1050         }
1051
1052
1053         hammer2_chain_ref(child);
1054         spin_unlock(&above->cst.spin);
1055
1056         /*
1057          * The MOVED bit implies an additional reference which prevents
1058          * the child from being destroyed out from under our operation
1059          * so we can lock the child safely without worrying about it
1060          * getting ripped up (?).
1061          *
1062          * We can only update parents where child->parent matches.  The
1063          * child->parent link will migrate along the chain but the flush
1064          * order must be enforced absolutely.  Parent reflushed after the
1065          * child has passed them by should skip due to the modify_tid test.
1066          */
1067         hammer2_chain_lock(child, HAMMER2_RESOLVE_NEVER);
1068
1069         /*
1070          * The parent's blockref to the child must be deleted or updated.
1071          *
1072          * This point is not reached on successful DESTROYED optimizations
1073          * but can be reached on recursive deletions and restricted flushes.
1074          *
1075          * Because flushes are ordered we do not have to make a
1076          * modify/duplicate of indirect blocks.  That is, the flush
1077          * code does not have to kmalloc or duplicate anything.  We
1078          * can adjust the indirect block table in-place and reuse the
1079          * chain.  It IS possible that the chain has already been duplicated
1080          * or may wind up being duplicated on-the-fly by modifying code
1081          * on the frontend.  We simply use the original and ignore such
1082          * chains.  However, it does mean we can't clear the MOVED bit.
1083          *
1084          * XXX recursive deletions not optimized.
1085          */
1086         hammer2_chain_modify(trans, &parent,
1087                              HAMMER2_MODIFY_NO_MODIFY_TID |
1088                              HAMMER2_MODIFY_ASSERTNOCOPY);
1089
1090         switch(parent->bref.type) {
1091         case HAMMER2_BREF_TYPE_INODE:
1092                 /*
1093                  * XXX Should assert that OPFLAG_DIRECTDATA is 0 once we
1094                  * properly duplicate the inode headers and do proper flush
1095                  * range checks (all the children should be beyond the flush
1096                  * point).  For now just don't sync the non-applicable
1097                  * children.
1098                  *
1099                  * XXX Can also occur due to hardlink consolidation.  We
1100                  * set OPFLAG_DIRECTDATA to prevent the indirect and data
1101                  * blocks from syncing ot the hardlink pointer.
1102                  */
1103 #if 0
1104                 KKASSERT((parent->data->ipdata.op_flags &
1105                           HAMMER2_OPFLAG_DIRECTDATA) == 0);
1106 #endif
1107 #if 0
1108                 if (parent->data->ipdata.op_flags &
1109                     HAMMER2_OPFLAG_DIRECTDATA) {
1110                         base = NULL;
1111                 } else
1112 #endif
1113                 {
1114                         base = &parent->data->ipdata.u.blockset.blockref[0];
1115                         count = HAMMER2_SET_COUNT;
1116                 }
1117                 break;
1118         case HAMMER2_BREF_TYPE_INDIRECT:
1119         case HAMMER2_BREF_TYPE_FREEMAP_NODE:
1120                 if (parent->data) {
1121                         base = &parent->data->npdata[0];
1122                 } else {
1123                         base = NULL;
1124                         KKASSERT(child->flags & HAMMER2_CHAIN_DELETED);
1125                 }
1126                 count = parent->bytes / sizeof(hammer2_blockref_t);
1127                 break;
1128         case HAMMER2_BREF_TYPE_VOLUME:
1129                 base = &hmp->voldata.sroot_blockset.blockref[0];
1130                 count = HAMMER2_SET_COUNT;
1131                 break;
1132         case HAMMER2_BREF_TYPE_FREEMAP:
1133                 base = &parent->data->npdata[0];
1134                 count = HAMMER2_SET_COUNT;
1135                 break;
1136         default:
1137                 base = NULL;
1138                 count = 0;
1139                 panic("hammer2_chain_get: "
1140                       "unrecognized blockref type: %d",
1141                       parent->bref.type);
1142         }
1143
1144         /*
1145          * Update the parent's blockref table and propagate mirror_tid.
1146          *
1147          * NOTE! Children with modify_tid's beyond our flush point are
1148          *       considered to not exist for the purposes of updating the
1149          *       parent's blockref array.
1150          *
1151          * NOTE! Updates to a parent's blockref table do not adjust the
1152          *       parent's bref.modify_tid, only its bref.mirror_tid.
1153          */
1154         KKASSERT(child->index >= 0);
1155         if (child->delete_tid <= trans->sync_tid) {
1156                 if (base) {
1157                         hammer2_rollup_stats(parent, child, -1);
1158                         KKASSERT(child->index < count);
1159                         bzero(&base[child->index], sizeof(child->bref));
1160                 }
1161                 if (info->mirror_tid < child->delete_tid)
1162                         info->mirror_tid = child->delete_tid;
1163         } else {
1164                 if (base) {
1165                         KKASSERT(child->index < count);
1166                         if (base[child->index].type == 0)
1167                                 hammer2_rollup_stats(parent, child, 1);
1168                         else
1169                                 hammer2_rollup_stats(parent, child, 0);
1170                         base[child->index] = child->bref;
1171                 }
1172                 if (info->mirror_tid < child->modify_tid)
1173                         info->mirror_tid = child->modify_tid;
1174         }
1175
1176         if (info->mirror_tid < child->bref.mirror_tid) {
1177                 info->mirror_tid = child->bref.mirror_tid;
1178         }
1179         if ((parent->bref.type == HAMMER2_BREF_TYPE_VOLUME ||
1180              parent->bref.type == HAMMER2_BREF_TYPE_FREEMAP) &&
1181             hmp->voldata.mirror_tid < child->bref.mirror_tid) {
1182                 hmp->voldata.mirror_tid = child->bref.mirror_tid;
1183         }
1184
1185         /*
1186          * When can we safely clear the MOVED flag?  Flushes down duplicate
1187          * paths can occur out of order, for example if an inode is moved
1188          * as part of a hardlink consolidation or if an inode is moved into
1189          * an indirect block indexed before the inode.
1190          *
1191          * Only clear MOVED once all possible parents have been flushed.
1192          */
1193         if (child->flags & HAMMER2_CHAIN_MOVED) {
1194                 hammer2_chain_t *scan;
1195                 int ok = 1;
1196
1197                 spin_lock(&above->cst.spin);
1198                 for (scan = above->first_parent;
1199                      scan;
1200                      scan = scan->next_parent) {
1201                         /*
1202                          * XXX weird code also checked at the top of scan2,
1203                          *     I would like to fix this by detaching the core
1204                          *     on initial hardlink consolidation (1->2 nlinks).
1205                          */
1206 #if 0
1207                         if (scan->bref.type == HAMMER2_BREF_TYPE_INODE &&
1208                             (scan->data->ipdata.op_flags &
1209                              HAMMER2_OPFLAG_DIRECTDATA)) {
1210                                 continue;
1211                         }
1212 #endif
1213                         if (scan->flags & HAMMER2_CHAIN_SUBMODIFIED) {
1214                                 ok = 0;
1215                                 break;
1216                         }
1217                 }
1218                 spin_unlock(&above->cst.spin);
1219                 if (ok) {
1220                         atomic_clear_int(&child->flags, HAMMER2_CHAIN_MOVED);
1221                         hammer2_chain_drop(child);      /* flag */
1222                 }
1223         }
1224
1225         /*
1226          * Unlock the child.  This can wind up dropping the child's
1227          * last ref, removing it from the parent's RB tree, and deallocating
1228          * the structure.  The RB_SCAN() our caller is doing handles the
1229          * situation.
1230          */
1231         hammer2_chain_unlock(child);
1232         hammer2_chain_drop(child);
1233         spin_lock(&above->cst.spin);
1234 #if FLUSH_DEBUG
1235         kprintf("F");
1236 #endif
1237
1238         /*
1239          * The parent cleared SUBMODIFIED prior to the scan.  If the child
1240          * still requires a flush (possibly due to being outside the current
1241          * synchronization zone), we must re-set SUBMODIFIED on the way back
1242          * up.
1243          */
1244 finalize:
1245 #if FLUSH_DEBUG
1246         kprintf("G child %p 08x\n", child, child->flags);
1247 #endif
1248         return (0);
1249 }
1250
1251 static
1252 void
1253 hammer2_rollup_stats(hammer2_chain_t *parent, hammer2_chain_t *child, int how)
1254 {
1255         hammer2_chain_t *grandp;
1256
1257         parent->data_count += child->data_count;
1258         parent->inode_count += child->inode_count;
1259         child->data_count = 0;
1260         child->inode_count = 0;
1261         if (how < 0) {
1262                 parent->data_count -= child->bytes;
1263                 if (child->bref.type == HAMMER2_BREF_TYPE_INODE) {
1264                         parent->inode_count -= 1;
1265 #if 0
1266                         /* XXX child->data may be NULL atm */
1267                         parent->data_count -= child->data->ipdata.data_count;
1268                         parent->inode_count -= child->data->ipdata.inode_count;
1269 #endif
1270                 }
1271         } else if (how > 0) {
1272                 parent->data_count += child->bytes;
1273                 if (child->bref.type == HAMMER2_BREF_TYPE_INODE) {
1274                         parent->inode_count += 1;
1275 #if 0
1276                         /* XXX child->data may be NULL atm */
1277                         parent->data_count += child->data->ipdata.data_count;
1278                         parent->inode_count += child->data->ipdata.inode_count;
1279 #endif
1280                 }
1281         }
1282         if (parent->bref.type == HAMMER2_BREF_TYPE_INODE) {
1283                 parent->data->ipdata.data_count += parent->data_count;
1284                 parent->data->ipdata.inode_count += parent->inode_count;
1285                 for (grandp = parent->above->first_parent;
1286                      grandp;
1287                      grandp = grandp->next_parent) {
1288                         grandp->data_count += parent->data_count;
1289                         grandp->inode_count += parent->inode_count;
1290                 }
1291                 parent->data_count = 0;
1292                 parent->inode_count = 0;
1293         }
1294 }