hammer2 - Stabilization pass, more flush refactoring
[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         int             pass;
58         int             cache_index;
59         int             domodify;
60         struct h2_flush_deferral_list flush_list;
61         hammer2_tid_t   sync_tid;       /* flush synchronization point */
62         hammer2_tid_t   mirror_tid;     /* collect mirror TID updates */
63 };
64
65 typedef struct hammer2_flush_info hammer2_flush_info_t;
66
67 static void hammer2_chain_flush_core(hammer2_flush_info_t *info,
68                                 hammer2_chain_t **chainp);
69 static int hammer2_chain_flush_scan1(hammer2_chain_t *child, void *data);
70 static int hammer2_chain_flush_scan2(hammer2_chain_t *child, void *data);
71 static void hammer2_rollup_stats(hammer2_chain_t *parent,
72                                 hammer2_chain_t *child, int how);
73
74 #if 0
75 static __inline
76 void
77 hammer2_updatestats(hammer2_flush_info_t *info, hammer2_blockref_t *bref,
78                     int how)
79 {
80         hammer2_key_t bytes;
81
82         if (bref->type != 0) {
83                 bytes = 1 << (bref->data_off & HAMMER2_OFF_MASK_RADIX);
84                 if (bref->type == HAMMER2_BREF_TYPE_INODE)
85                         info->inode_count += how;
86                 if (how < 0)
87                         info->data_count -= bytes;
88                 else
89                         info->data_count += bytes;
90         }
91 }
92 #endif
93
94 /*
95  * Transaction support functions for writing to the filesystem.
96  *
97  * Initializing a new transaction allocates a transaction ID.  We
98  * don't bother marking the volume header MODIFIED.  Instead, the volume
99  * will be synchronized at a later time as part of a larger flush sequence.
100  *
101  * Non-flush transactions can typically run concurrently.  However if
102  * there are non-flush transaction both before AND after a flush trans,
103  * the transactions after stall until the ones before finish.
104  *
105  * Non-flush transactions occuring after a flush pointer can run concurrently
106  * with that flush.  They only have to wait for transactions prior to the
107  * flush trans to complete before they unstall.
108  *
109  * WARNING! Transaction ids are only allocated when the transaction becomes
110  *          active, which allows other transactions to insert ahead of us
111  *          if we are forced to block (only bioq transactions do that).
112  *
113  * WARNING! Modifications to the root volume cannot dup the root volume
114  *          header to handle synchronization points, so alloc_tid can
115  *          wind up (harmlessly) more advanced on flush.
116  */
117 void
118 hammer2_trans_init(hammer2_trans_t *trans, hammer2_pfsmount_t *pmp, int flags)
119 {
120         hammer2_mount_t *hmp;
121         hammer2_trans_t *head;
122
123         bzero(trans, sizeof(*trans));
124         trans->pmp = pmp;
125         hmp = pmp->cluster.chains[0]->hmp;      /* XXX */
126
127         hammer2_voldata_lock(hmp);
128         trans->flags = flags;
129         trans->td = curthread;
130         /*trans->delete_gen = 0;*/      /* multiple deletions within trans */
131
132         if (flags & HAMMER2_TRANS_ISFLUSH) {
133                 /*
134                  * If multiple flushes are trying to run we have to
135                  * wait until it is our turn.  All flushes are serialized.
136                  *
137                  * We queue ourselves and then wait to become the head
138                  * of the queue, allowing all prior flushes to complete.
139                  */
140                 ++hmp->flushcnt;
141                 trans->sync_tid = hmp->voldata.alloc_tid++;
142                 trans->real_tid = trans->sync_tid;
143                 TAILQ_INSERT_TAIL(&hmp->transq, trans, entry);
144                 if (TAILQ_FIRST(&hmp->transq) != trans) {
145                         trans->blocked = 1;
146                         while (trans->blocked) {
147                                 lksleep(&trans->sync_tid, &hmp->voldatalk,
148                                         0, "h2multf", hz);
149                         }
150                 }
151         } else if (hmp->flushcnt == 0) {
152                 /*
153                  * No flushes are pending, we can go.
154                  */
155                 TAILQ_INSERT_TAIL(&hmp->transq, trans, entry);
156                 trans->sync_tid = hmp->voldata.alloc_tid;
157                 trans->real_tid = trans->sync_tid;
158
159                 /* XXX improve/optimize inode allocation */
160         } else {
161                 /*
162                  * One or more flushes are pending.  We insert after
163                  * the current flush and may block.  We have priority
164                  * over any flushes that are not the current flush.
165                  *
166                  * TRANS_BUFCACHE transactions cannot block.
167                  */
168                 TAILQ_FOREACH(head, &hmp->transq, entry) {
169                         if (head->flags & HAMMER2_TRANS_ISFLUSH)
170                                 break;
171                 }
172                 KKASSERT(head);
173                 TAILQ_INSERT_AFTER(&hmp->transq, head, trans, entry);
174                 trans->sync_tid = head->real_tid + 1;
175                 trans->real_tid = trans->sync_tid;
176
177                 if ((trans->flags & HAMMER2_TRANS_BUFCACHE) == 0) {
178                         if (TAILQ_FIRST(&hmp->transq) != head) {
179                                 trans->blocked = 1;
180                                 while (trans->blocked) {
181                                         lksleep(&trans->sync_tid,
182                                                 &hmp->voldatalk, 0,
183                                                 "h2multf", hz);
184                                 }
185                         }
186                 }
187         }
188         if (flags & HAMMER2_TRANS_NEWINODE)
189                 trans->inode_tid = hmp->voldata.inode_tid++;
190         hammer2_voldata_unlock(hmp, 0);
191 }
192
193 void
194 hammer2_trans_done(hammer2_trans_t *trans)
195 {
196         hammer2_mount_t *hmp;
197         hammer2_trans_t *head;
198         hammer2_trans_t *scan;
199
200         hmp = trans->pmp->cluster.chains[0]->hmp;
201
202         /*
203          * Remove and adjust flushcnt
204          */
205         hammer2_voldata_lock(hmp);
206         TAILQ_REMOVE(&hmp->transq, trans, entry);
207         if (trans->flags & HAMMER2_TRANS_ISFLUSH)
208                 --hmp->flushcnt;
209
210         /*
211          * Unblock the head of the queue and any additional transactions
212          * up to the next flush.
213          */
214         head = TAILQ_FIRST(&hmp->transq);
215         if (head && head->blocked) {
216                 head->blocked = 0;
217                 wakeup(&head->sync_tid);
218
219                 scan = TAILQ_NEXT(head, entry);
220                 while (scan && (scan->flags & HAMMER2_TRANS_ISFLUSH) == 0) {
221                         scan->blocked = 0;
222                         wakeup(&scan->sync_tid);
223                         scan = TAILQ_NEXT(scan, entry);
224                 }
225         }
226         hammer2_voldata_unlock(hmp, 0);
227 }
228
229 /*
230  * Flush the chain and all modified sub-chains through the specified
231  * synchronization point (sync_tid), propagating parent chain modifications
232  * and mirror_tid updates back up as needed.  Since we are recursing downward
233  * we do not have to deal with the complexities of multi-homed chains (chains
234  * with multiple parents).
235  *
236  * Caller must have interlocked against any non-flush-related modifying
237  * operations in progress whos modify_tid values are less than or equal
238  * to the passed sync_tid.
239  *
240  * Caller must have already vetted synchronization points to ensure they
241  * are properly flushed.  Only snapshots and cluster flushes can create
242  * these sorts of synchronization points.
243  *
244  * This routine can be called from several places but the most important
245  * is from the hammer2_vop_reclaim() function.  We want to try to completely
246  * clean out the inode structure to prevent disconnected inodes from
247  * building up and blowing out the kmalloc pool.  However, it is not actually
248  * necessary to flush reclaimed inodes to maintain HAMMER2's crash recovery
249  * capability.
250  *
251  * chain is locked on call and will remain locked on return.  If a flush
252  * occured, the chain's MOVED bit will be set indicating that its parent
253  * (which is not part of the flush) should be updated.
254  */
255 void
256 hammer2_chain_flush(hammer2_trans_t *trans, hammer2_chain_t **chainp)
257 {
258         hammer2_chain_t *chain = *chainp;
259         hammer2_chain_t *scan;
260         hammer2_chain_core_t *core;
261         hammer2_flush_info_t info;
262
263         /*
264          * Execute the recursive flush and handle deferrals.
265          *
266          * Chains can be ridiculously long (thousands deep), so to
267          * avoid blowing out the kernel stack the recursive flush has a
268          * depth limit.  Elements at the limit are placed on a list
269          * for re-execution after the stack has been popped.
270          */
271         bzero(&info, sizeof(info));
272         TAILQ_INIT(&info.flush_list);
273         info.trans = trans;
274         info.sync_tid = trans->sync_tid;
275         info.mirror_tid = 0;
276         info.cache_index = -1;
277
278         core = chain->core;
279 #if FLUSH_DEBUG
280         kprintf("CHAIN FLUSH trans %p.%016jx chain %p.%d mod %016jx upd %016jx\n", trans, trans->sync_tid, chain, chain->bref.type, chain->modify_tid, core->update_tid);
281 #endif
282
283         /*
284          * Extra ref needed because flush_core expects it when replacing
285          * chain.
286          */
287         hammer2_chain_ref(chain);
288
289         for (;;) {
290                 /*
291                  * Unwind deep recursions which had been deferred.  This
292                  * can leave MOVED set for these chains, which will be
293                  * handled when we [re]flush chain after the unwind.
294                  */
295                 while ((scan = TAILQ_FIRST(&info.flush_list)) != NULL) {
296                         KKASSERT(scan->flags & HAMMER2_CHAIN_DEFERRED);
297                         TAILQ_REMOVE(&info.flush_list, scan, flush_node);
298                         atomic_clear_int(&scan->flags, HAMMER2_CHAIN_DEFERRED);
299
300                         /*
301                          * Now that we've popped back up we can do a secondary
302                          * recursion on the deferred elements.
303                          */
304                         if (hammer2_debug & 0x0040)
305                                 kprintf("defered flush %p\n", scan);
306                         hammer2_chain_lock(scan, HAMMER2_RESOLVE_MAYBE);
307                         hammer2_chain_flush(trans, &scan);
308                         hammer2_chain_unlock(scan);
309                         hammer2_chain_drop(scan);       /* ref from deferral */
310                 }
311
312                 /*
313                  * Flush pass1 on root.
314                  */
315                 info.diddeferral = 0;
316                 hammer2_chain_flush_core(&info, &chain);
317 #if FLUSH_DEBUG
318                 kprintf("flush_core_done parent=<base> chain=%p.%d %08x\n",
319                         chain, chain->bref.type, chain->flags);
320 #endif
321
322                 /*
323                  * Only loop if deep recursions have been deferred.
324                  */
325                 if (TAILQ_EMPTY(&info.flush_list))
326                         break;
327         }
328         hammer2_chain_drop(chain);
329         *chainp = chain;
330 }
331
332 /*
333  * This is the core of the chain flushing code.  The chain is locked by the
334  * caller and must also have an extra ref on it by the caller, and remains
335  * locked and will have an extra ref on return.
336  *
337  * This function is keyed off of the update_tid bit but must make
338  * fine-grained choices based on the synchronization point we are flushing to.
339  *
340  * If the flush accomplished any work chain will be flagged MOVED
341  * indicating a copy-on-write propagation back up is required.
342  * Deep sub-nodes may also have been entered onto the deferral list.
343  * MOVED is never set on the volume root.
344  *
345  * NOTE: modify_tid is different from MODIFIED.  modify_tid is updated
346  *       only when a chain is specifically modified, and not updated
347  *       for copy-on-write propagations.  MODIFIED is set on any modification
348  *       including copy-on-write propagations.
349  */
350 static void
351 hammer2_chain_flush_core(hammer2_flush_info_t *info, hammer2_chain_t **chainp)
352 {
353         hammer2_chain_t *chain = *chainp;
354         hammer2_mount_t *hmp;
355         hammer2_blockref_t *bref;
356         hammer2_off_t pbase;
357         hammer2_off_t pmask;
358 #if 0
359         hammer2_trans_t *trans = info->trans;
360 #endif
361         hammer2_chain_core_t *core;
362         size_t psize;
363         size_t boff;
364         char *bdata;
365         struct buf *bp;
366         int error;
367         int wasmodified;
368         int diddeferral = 0;
369
370         hmp = chain->hmp;
371
372 #if FLUSH_DEBUG
373         if (info->parent)
374                 kprintf("flush_core %p->%p.%d %08x (%s)\n",
375                         info->parent, chain, chain->bref.type,
376                         chain->flags,
377                         ((chain->bref.type == HAMMER2_BREF_TYPE_INODE) ?
378                                 chain->data->ipdata.filename : "?"));
379         else
380                 kprintf("flush_core NULL->%p.%d %08x (%s)\n",
381                         chain, chain->bref.type,
382                         chain->flags,
383                         ((chain->bref.type == HAMMER2_BREF_TYPE_INODE) ?
384                                 chain->data->ipdata.filename : "?"));
385         kprintf("PUSH   %p.%d %08x mod=%016jx del=%016jx mirror=%016jx\n", chain, chain->bref.type, chain->flags, chain->modify_tid, chain->delete_tid, chain->bref.mirror_tid);
386 #endif
387
388         /*
389          * Ignore chains modified beyond the current flush point.  These
390          * will be treated as if they did not exist.  Subchains with lower
391          * modify_tid's will still be accessible via other parents.
392          *
393          * (vchain and fchain are exceptions since they cannot be duplicated)
394          */
395         if (chain->modify_tid > info->sync_tid &&
396             chain != &hmp->fchain && chain != &hmp->vchain) {
397                 chain->debug_reason = (chain->debug_reason & ~255) | 5;
398                 return;
399         }
400
401         core = chain->core;
402
403         /*
404          * If update_tid triggers we recurse the flush and adjust the
405          * blockrefs accordingly.
406          *
407          * NOTE: Looping on update_tid can prevent a flush from ever
408          *       finishing in the face of filesystem activity.
409          *
410          * NOTE: We must recurse whether chain is flagged DELETED or not.
411          *       However, if it is flagged DELETED we limit sync_tid to
412          *       delete_tid to ensure that the chain's bref.mirror_tid is
413          *       not fully updated and causes it to miss the non-DELETED
414          *       path.
415          */
416         if (chain->bref.mirror_tid < core->update_tid &&
417             chain->bref.mirror_tid < info->sync_tid) {
418                 hammer2_chain_t *saved_parent;
419                 hammer2_tid_t saved_mirror;
420                 hammer2_chain_layer_t *layer;
421                 int saved_domodify;
422                 int save_gen;
423
424                 /*
425                  * Races will bump update_tid above trans->sync_tid causing
426                  * us to catch the issue in a later flush.  We do not update
427                  * update_tid if a deferral (or error XXX) occurs.
428                  *
429                  * We don't want to set our chain to MODIFIED gratuitously.
430                  *
431                  * We need an extra ref on chain because we are going to
432                  * release its lock temporarily in our child loop.
433                  */
434
435                 /*
436                  * Run two passes.  The first pass handles MODIFIED and
437                  * update_tid recursions while the second pass handles
438                  * MOVED chains on the way back up.
439                  *
440                  * If the stack gets too deep we defer scan1, but must
441                  * be sure to still run scan2 if on the next loop the
442                  * deferred chain has been flushed and now needs MOVED
443                  * handling on the way back up.
444                  *
445                  * Scan1 is recursive.
446                  *
447                  * NOTE: The act of handling a modified/submodified chain can
448                  *       cause the MOVED Flag to be set.  It can also be set
449                  *       via hammer2_chain_delete() and in other situations.
450                  *
451                  * NOTE: RB_SCAN() must be used instead of RB_FOREACH()
452                  *       because children can be physically removed during
453                  *       the scan.
454                  *
455                  * NOTE: We would normally not care about insertions except
456                  *       that some insertions might occur from the flush
457                  *       itself, so loop on generation number changes.
458                  */
459                 saved_parent = info->parent;
460                 saved_mirror = info->mirror_tid;
461                 saved_domodify = info->domodify;
462                 info->parent = chain;
463                 info->mirror_tid = chain->bref.mirror_tid;
464                 info->domodify = 0;
465                 chain->debug_reason = (chain->debug_reason & ~255) | 6;
466
467                 if (info->depth == HAMMER2_FLUSH_DEPTH_LIMIT) {
468                         if ((chain->flags & HAMMER2_CHAIN_DEFERRED) == 0) {
469                                 hammer2_chain_ref(chain);
470                                 TAILQ_INSERT_TAIL(&info->flush_list,
471                                                   chain, flush_node);
472                                 atomic_set_int(&chain->flags,
473                                                HAMMER2_CHAIN_DEFERRED);
474                         }
475                         diddeferral = 1;
476                 } else {
477                         info->diddeferral = 0;
478                         spin_lock(&core->cst.spin);
479                         KKASSERT(core->good == 0x1234 && core->sharecnt > 0);
480                         do {
481                                 save_gen = core->generation;
482                                 TAILQ_FOREACH_REVERSE(layer, &core->layerq,
483                                                       h2_layer_list, entry) {
484                                         ++layer->refs;
485                                         KKASSERT(layer->good == 0xABCD);
486                                         RB_SCAN(hammer2_chain_tree,
487                                                 &layer->rbtree,
488                                                 NULL, hammer2_chain_flush_scan1,
489                                                 info);
490                                         --layer->refs;
491                                         diddeferral += info->diddeferral;
492                                 }
493                         } while (core->generation != save_gen);
494                         spin_unlock(&core->cst.spin);
495                 }
496
497                 /*
498                  * Blockrefs are only updated on live chains.
499                  *
500                  * We are possibly causing a delete-duplicate from inside the
501                  * flush itself.  The parent might be live or might have been
502                  * deleted concurrently in a post-flush transaction.  If
503                  * the parent was deleted our modified chain will also be
504                  * marked deleted, but since it inherits the parent's
505                  * delete_tid it will still appear to be 'live' for the
506                  * purposes of the flush.
507                  *
508                  * There may also be a side-effect due to the freemap
509                  * allocation.  See freemap_alloc()
510                  */
511                 if (info->domodify && chain->delete_tid > info->sync_tid) {
512                         hammer2_chain_modify(info->trans, &info->parent,
513                                              HAMMER2_MODIFY_NO_MODIFY_TID);
514                         if (info->parent != chain) {
515                                 hammer2_chain_drop(chain);
516                                 hammer2_chain_ref(info->parent);
517                         }
518                         chain = info->parent;
519                 }
520                 chain->debug_reason = (chain->debug_reason & ~255) | 7;
521
522                 /*
523                  * Handle successfully flushed children who are in the MOVED
524                  * state on the way back up the recursion.  This can have
525                  * the side-effect of clearing MOVED.
526                  *
527                  * Scan2 may replace info->parent.  If it does it will also
528                  * replace the extra ref we made.
529                  *
530                  * Scan2 is non-recursive.
531                  */
532                 if (diddeferral) {
533                         spin_lock(&core->cst.spin);
534                 } else {
535                         spin_lock(&core->cst.spin);
536                         KKASSERT(core->good == 0x1234 && core->sharecnt > 0);
537                         TAILQ_FOREACH_REVERSE(layer, &core->layerq,
538                                               h2_layer_list, entry) {
539                                 info->pass = 1;
540                                 ++layer->refs;
541                                 KKASSERT(layer->good == 0xABCD);
542                                 RB_SCAN(hammer2_chain_tree, &layer->rbtree,
543                                         NULL, hammer2_chain_flush_scan2, info);
544                                 info->pass = 2;
545                                 RB_SCAN(hammer2_chain_tree, &layer->rbtree,
546                                         NULL, hammer2_chain_flush_scan2, info);
547                                 --layer->refs;
548                                 KKASSERT(info->parent->core == core);
549                         }
550
551                         /*
552                          * Mirror_tid propagates all changes.  It is also used
553                          * in scan2 to determine when a chain must be applied
554                          * to the related block table.
555                          */
556                         KKASSERT(info->parent->bref.mirror_tid <=
557                                  info->mirror_tid);
558                         chain->bref.mirror_tid = info->mirror_tid;
559                 }
560
561                 /*
562                  * info->parent must not have been replaced again
563                  */
564                 KKASSERT(info->parent == chain);
565
566                 chain->debug_reason = (chain->debug_reason & ~255) | 8;
567                 *chainp = chain;
568
569                 hammer2_chain_layer_check_locked(chain->hmp, core);
570                 spin_unlock(&core->cst.spin);
571
572                 info->mirror_tid = saved_mirror;
573                 info->parent = saved_parent;
574                 info->domodify = saved_domodify;
575                 KKASSERT(chain->refs > 1);
576         }
577
578 #if FLUSH_DEBUG
579         kprintf("POP    %p.%d\n", chain, chain->bref.type);
580 #endif
581
582         /*
583          * Rollup diddeferral for caller.  Note direct assignment, not +=.
584          */
585         info->diddeferral = diddeferral;
586
587         /*
588          * Do not flush chain if there were any deferrals.  It will be
589          * retried later after the deferrals are independently handled.
590          */
591         if (diddeferral) {
592                 chain->debug_reason = (chain->debug_reason & ~255) | 99;
593                 if (hammer2_debug & 0x0008) {
594                         kprintf("%*.*s} %p/%d %04x (deferred)",
595                                 info->depth, info->depth, "",
596                                 chain, chain->refs, chain->flags);
597                 }
598                 return;
599         }
600
601         /*
602          * If we encounter a deleted chain within our flush we can clear
603          * the MODIFIED bit and avoid flushing it whether it has been
604          * destroyed or not.  We must make sure that the chain is flagged
605          * MOVED in this situation so the parent picks up the deletion.
606          *
607          * Since this chain will now never be written to disk we need to
608          * adjust bref.mirror_tid such that it does not prevent sub-chains
609          * from clearing their MOVED bits.
610          *
611          * NOTE:  scan2 has already executed above so statistics have
612          *        already been rolled up.
613          *
614          * NOTE:  Deletions do not prevent flush recursion as a deleted
615          *        inode (removed file) which is still open may still require
616          *        on-media storage to be able to clean related pages out from
617          *        the system caches.
618          *
619          * NOTE:  Even though this chain will not issue write I/O, we must
620          *        still update chain->bref.mirror_tid for flush management
621          *        purposes.
622          */
623         if (chain->delete_tid <= info->sync_tid) {
624                 chain->debug_reason = (chain->debug_reason & ~255) | 9;
625                 if (chain->flags & HAMMER2_CHAIN_MODIFIED) {
626                         if (chain->bp) {
627                                 if (chain->bytes == chain->bp->b_bufsize)
628                                         chain->bp->b_flags |= B_INVAL|B_RELBUF;
629                         }
630                         if ((chain->flags & HAMMER2_CHAIN_MOVED) == 0) {
631                                 hammer2_chain_ref(chain);
632                                 atomic_set_int(&chain->flags,
633                                                HAMMER2_CHAIN_MOVED);
634                         }
635                         atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
636                         if (chain->bref.mirror_tid < info->sync_tid)
637                                 chain->bref.mirror_tid = info->sync_tid;
638                         hammer2_chain_drop(chain);
639                 }
640                 if (chain->bref.mirror_tid < info->sync_tid)
641                         chain->bref.mirror_tid = info->sync_tid;
642                 return;
643         }
644 #if 0
645         if ((chain->flags & HAMMER2_CHAIN_DESTROYED) &&
646             (chain->flags & HAMMER2_CHAIN_DELETED) &&
647             (trans->flags & HAMMER2_TRANS_RESTRICTED) == 0) {
648                 /*
649                  * Throw-away the MODIFIED flag
650                  */
651                 if (chain->flags & HAMMER2_CHAIN_MODIFIED) {
652                         if (chain->bp) {
653                                 if (chain->bytes == chain->bp->b_bufsize)
654                                         chain->bp->b_flags |= B_INVAL|B_RELBUF;
655                         }
656                         atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
657                         hammer2_chain_drop(chain);
658                 }
659                 return;
660         }
661 #endif
662
663         /*
664          * A degenerate flush might not have flushed anything and thus not
665          * processed modified blocks on the way back up.  Detect the case.
666          *
667          * Note that MOVED can be set without MODIFIED being set due to
668          * a deletion, in which case it is handled by Scan2 later on.
669          *
670          * Both bits can be set along with DELETED due to a deletion if
671          * modified data within the synchronization zone and the chain
672          * was then deleted beyond the zone, in which case we still have
673          * to flush for synchronization point consistency.  Otherwise though
674          * DELETED and MODIFIED are treated as separate flags.
675          */
676         if ((chain->flags & HAMMER2_CHAIN_MODIFIED) == 0) {
677                 if (chain->bref.mirror_tid < info->sync_tid)
678                         chain->bref.mirror_tid = info->sync_tid;
679                 chain->debug_reason = (chain->debug_reason & ~255) | 10;
680                 return;
681         }
682         chain->debug_reason = (chain->debug_reason & ~255) | 11;
683
684         /*
685          * Issue flush.
686          *
687          * A DESTROYED node that reaches this point must be flushed for
688          * synchronization point consistency.
689          */
690
691         /*
692          * Update mirror_tid, clear MODIFIED, and set MOVED.
693          *
694          * The caller will update the parent's reference to this chain
695          * by testing MOVED as long as the modification was in-bounds.
696          *
697          * MOVED is never set on the volume root as there is no parent
698          * to adjust.
699          */
700         if (hammer2_debug & 0x1000) {
701                 kprintf("Flush %p.%d %016jx/%d sync_tid %016jx\n",
702                         chain, chain->bref.type,
703                         chain->bref.key, chain->bref.keybits,
704                         info->sync_tid);
705         }
706         if (hammer2_debug & 0x2000) {
707                 Debugger("Flush hell");
708         }
709         if (chain->bref.mirror_tid < info->sync_tid)
710                 chain->bref.mirror_tid = info->sync_tid;
711         wasmodified = (chain->flags & HAMMER2_CHAIN_MODIFIED) != 0;
712         atomic_clear_int(&chain->flags, HAMMER2_CHAIN_MODIFIED);
713         if (chain == &hmp->vchain)
714                 kprintf("(FLUSHED VOLUME HEADER)\n");
715         if (chain == &hmp->fchain)
716                 kprintf("(FLUSHED FREEMAP HEADER)\n");
717
718         if ((chain->flags & HAMMER2_CHAIN_MOVED) ||
719             chain == &hmp->vchain ||
720             chain == &hmp->fchain) {
721                 /*
722                  * Drop the ref from the MODIFIED bit we cleared.
723                  * Net is -0 or -1 ref depending.
724                  */
725                 if (wasmodified)
726                         hammer2_chain_drop(chain);
727         } else {
728                 /*
729                  * Drop the ref from the MODIFIED bit we cleared and
730                  * set a ref for the MOVED bit we are setting.  Net
731                  * is +0 or +1 ref depending.
732                  */
733                 if (wasmodified == 0)
734                         hammer2_chain_ref(chain);
735                 atomic_set_int(&chain->flags, HAMMER2_CHAIN_MOVED);
736         }
737
738         /*
739          * If this is part of a recursive flush we can go ahead and write
740          * out the buffer cache buffer and pass a new bref back up the chain
741          * via the MOVED bit.
742          *
743          * Volume headers are NOT flushed here as they require special
744          * processing.
745          */
746         switch(chain->bref.type) {
747         case HAMMER2_BREF_TYPE_FREEMAP:
748                 hammer2_modify_volume(hmp);
749                 hmp->voldata.freemap_tid = chain->bref.mirror_tid;
750                 break;
751         case HAMMER2_BREF_TYPE_VOLUME:
752                 /*
753                  * We should flush the free block table before we calculate
754                  * CRCs and copy voldata -> volsync.
755                  *
756                  * To prevent SMP races, fchain must remain locked until
757                  * voldata is copied to volsync.
758                  */
759                 hammer2_chain_lock(&hmp->fchain, HAMMER2_RESOLVE_ALWAYS);
760                 if ((hmp->fchain.flags & HAMMER2_CHAIN_MODIFIED) ||
761                     hmp->voldata.freemap_tid < hmp->fchain.core->update_tid) {
762                         /* this will modify vchain as a side effect */
763                         hammer2_chain_t *tmp = &hmp->fchain;
764                         hammer2_chain_flush(info->trans, &tmp);
765                         KKASSERT(tmp == &hmp->fchain);
766                 }
767                 hmp->voldata.mirror_tid = chain->bref.mirror_tid;
768
769                 /*
770                  * The volume header is flushed manually by the syncer, not
771                  * here.  All we do is adjust the crc's.
772                  */
773                 KKASSERT(chain->data != NULL);
774                 KKASSERT(chain->bp == NULL);
775                 kprintf("volume header mirror_tid %jd\n",
776                         hmp->voldata.mirror_tid);
777
778                 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT1]=
779                         hammer2_icrc32(
780                                 (char *)&hmp->voldata +
781                                  HAMMER2_VOLUME_ICRC1_OFF,
782                                 HAMMER2_VOLUME_ICRC1_SIZE);
783                 hmp->voldata.icrc_sects[HAMMER2_VOL_ICRC_SECT0]=
784                         hammer2_icrc32(
785                                 (char *)&hmp->voldata +
786                                  HAMMER2_VOLUME_ICRC0_OFF,
787                                 HAMMER2_VOLUME_ICRC0_SIZE);
788                 hmp->voldata.icrc_volheader =
789                         hammer2_icrc32(
790                                 (char *)&hmp->voldata +
791                                  HAMMER2_VOLUME_ICRCVH_OFF,
792                                 HAMMER2_VOLUME_ICRCVH_SIZE);
793                 hmp->volsync = hmp->voldata;
794                 atomic_set_int(&chain->flags, HAMMER2_CHAIN_VOLUMESYNC);
795                 hammer2_chain_unlock(&hmp->fchain);
796                 break;
797         case HAMMER2_BREF_TYPE_DATA:
798                 /*
799                  * Data elements have already been flushed via the logical
800                  * file buffer cache.  Their hash was set in the bref by
801                  * the vop_write code.
802                  *
803                  * Make sure any device buffer(s) have been flushed out here.
804                  * (there aren't usually any to flush).
805                  */
806                 psize = hammer2_devblksize(chain->bytes);
807                 pmask = (hammer2_off_t)psize - 1;
808                 pbase = chain->bref.data_off & ~pmask;
809                 boff = chain->bref.data_off & (HAMMER2_OFF_MASK & pmask);
810
811                 bp = getblk(hmp->devvp, pbase, psize, GETBLK_NOWAIT, 0);
812                 if (bp) {
813                         if ((bp->b_flags & (B_CACHE | B_DIRTY)) ==
814                             (B_CACHE | B_DIRTY)) {
815                                 cluster_awrite(bp);
816                         } else {
817                                 bp->b_flags |= B_RELBUF;
818                                 brelse(bp);
819                         }
820                 }
821                 break;
822 #if 0
823         case HAMMER2_BREF_TYPE_INDIRECT:
824                 /*
825                  * Indirect blocks may be in an INITIAL state.  Use the
826                  * chain_lock() call to ensure that the buffer has been
827                  * instantiated (even though it is already locked the buffer
828                  * might not have been instantiated).
829                  *
830                  * Only write the buffer out if it is dirty, it is possible
831                  * the operating system had already written out the buffer.
832                  */
833                 hammer2_chain_lock(chain, HAMMER2_RESOLVE_ALWAYS);
834                 KKASSERT(chain->bp != NULL);
835
836                 bp = chain->bp;
837                 if ((chain->flags & HAMMER2_CHAIN_DIRTYBP) ||
838                     (bp->b_flags & B_DIRTY)) {
839                         bdwrite(chain->bp);
840                 } else {
841                         brelse(chain->bp);
842                 }
843                 chain->bp = NULL;
844                 chain->data = NULL;
845                 hammer2_chain_unlock(chain);
846                 break;
847 #endif
848         case HAMMER2_BREF_TYPE_INDIRECT:
849         case HAMMER2_BREF_TYPE_FREEMAP_NODE:
850                 /*
851                  * Device-backed.  Buffer will be flushed by the sync
852                  * code XXX.
853                  */
854                 KKASSERT((chain->flags & HAMMER2_CHAIN_EMBEDDED) == 0);
855                 break;
856         case HAMMER2_BREF_TYPE_FREEMAP_LEAF:
857         default:
858                 /*
859                  * Embedded elements have to be flushed out.
860                  * (Basically just BREF_TYPE_INODE).
861                  */
862                 KKASSERT(chain->flags & HAMMER2_CHAIN_EMBEDDED);
863                 KKASSERT(chain->data != NULL);
864                 KKASSERT(chain->bp == NULL);
865                 bref = &chain->bref;
866
867                 KKASSERT((bref->data_off & HAMMER2_OFF_MASK) != 0);
868                 KKASSERT(HAMMER2_DEC_CHECK(chain->bref.methods) ==
869                          HAMMER2_CHECK_ISCSI32 ||
870                          HAMMER2_DEC_CHECK(chain->bref.methods) ==
871                          HAMMER2_CHECK_FREEMAP);
872
873                 /*
874                  * The data is embedded, we have to acquire the
875                  * buffer cache buffer and copy the data into it.
876                  */
877                 psize = hammer2_devblksize(chain->bytes);
878                 pmask = (hammer2_off_t)psize - 1;
879                 pbase = bref->data_off & ~pmask;
880                 boff = bref->data_off & (HAMMER2_OFF_MASK & pmask);
881
882                 /*
883                  * The getblk() optimization can only be used if the
884                  * physical block size matches the request.
885                  */
886                 error = bread(hmp->devvp, pbase, psize, &bp);
887                 KKASSERT(error == 0);
888
889                 bdata = (char *)bp->b_data + boff;
890
891                 /*
892                  * Copy the data to the buffer, mark the buffer
893                  * dirty, and convert the chain to unmodified.
894                  */
895                 bcopy(chain->data, bdata, chain->bytes);
896                 bp->b_flags |= B_CLUSTEROK;
897                 bdwrite(bp);
898                 bp = NULL;
899
900                 switch(HAMMER2_DEC_CHECK(chain->bref.methods)) {
901                 case HAMMER2_CHECK_FREEMAP:
902                         chain->bref.check.freemap.icrc32 =
903                                 hammer2_icrc32(chain->data, chain->bytes);
904                         break;
905                 case HAMMER2_CHECK_ISCSI32:
906                         chain->bref.check.iscsi32.value =
907                                 hammer2_icrc32(chain->data, chain->bytes);
908                         break;
909                 default:
910                         panic("hammer2_flush_core: bad crc type");
911                         break; /* NOT REACHED */
912                 }
913                 if (chain->bref.type == HAMMER2_BREF_TYPE_INODE)
914                         ++hammer2_iod_meta_write;
915                 else
916                         ++hammer2_iod_indr_write;
917         }
918 }
919
920 /*
921  * Flush helper scan1 (recursive)
922  *
923  * Flushes the children of the caller's chain (parent) and updates
924  * the blockref, restricted by sync_tid.
925  *
926  * Ripouts during the loop should not cause any problems.  Because we are
927  * flushing to a synchronization point, modification races will occur after
928  * sync_tid and do not have to be flushed anyway.
929  *
930  * It is also ok if the parent is chain_duplicate()'d while unlocked because
931  * the delete/duplication will install a delete_tid that is still larger than
932  * our current sync_tid.
933  */
934 static int
935 hammer2_chain_flush_scan1(hammer2_chain_t *child, void *data)
936 {
937         hammer2_flush_info_t *info = data;
938         hammer2_trans_t *trans = info->trans;
939         hammer2_chain_t *parent = info->parent;
940         int diddeferral;
941
942         /*
943          * Child is beyond the flush synchronization zone, don't persue.
944          * Remember that modifications generally delete-duplicate so if the
945          * sub-tree is dirty another child will get us there.  But not this
946          * one.
947          *
948          * Or MODIFIED is not set and child is already fully synchronized
949          * with its sub-tree.  Don't persue.
950          */
951         if (child->modify_tid > trans->sync_tid) {
952                 KKASSERT(child->delete_tid >= child->modify_tid);
953                 child->debug_reason = (child->debug_reason & ~255) | 1;
954                 return (0);
955         }
956
957         /*
958          * We must ref the child before unlocking the spinlock.
959          *
960          * The caller has added a ref to the parent so we can temporarily
961          * unlock it in order to lock the child.
962          */
963         hammer2_chain_ref(child);
964         spin_unlock(&parent->core->cst.spin);
965
966         hammer2_chain_unlock(parent);
967         hammer2_chain_lock(child, HAMMER2_RESOLVE_MAYBE);
968
969         if ((child->flags & HAMMER2_CHAIN_MODIFIED) == 0 &&
970             (child->bref.mirror_tid >= child->core->update_tid ||
971              child->bref.mirror_tid >= info->sync_tid)) {
972                 child->debug_reason = (child->debug_reason & ~255) | 2;
973                 goto skip;
974         }
975
976         /*
977          * Re-check the flags before continuing.
978          */
979         if (child->modify_tid > trans->sync_tid) {
980                 child->debug_reason = (child->debug_reason & ~255) | 3;
981                 hammer2_chain_unlock(child);
982                 hammer2_chain_drop(child);
983                 hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
984                 spin_lock(&parent->core->cst.spin);
985                 return (0);
986         }
987
988         if ((child->flags & HAMMER2_CHAIN_MODIFIED) == 0 &&
989             (child->bref.mirror_tid >= child->core->update_tid ||
990              child->bref.mirror_tid >= info->sync_tid)) {
991                 child->debug_reason = (child->debug_reason & ~255) | 4;
992                 goto skip;
993         }
994
995         /*
996          * The DESTROYED flag can only be initially set on an unreferenced
997          * deleted inode and will propagate downward via the mechanic below.
998          * Such inode chains have been deleted for good and should no longer
999          * be subject to delete/duplication.
1000          *
1001          * This optimization allows the inode reclaim (destroy unlinked file
1002          * on vnode reclamation after last close) to be flagged by just
1003          * setting HAMMER2_CHAIN_DESTROYED at the top level and then will
1004          * cause the chains to be terminated and related buffers to be
1005          * invalidated and not flushed out.
1006          *
1007          * We have to be careful not to propagate the DESTROYED flag if
1008          * the destruction occurred after our flush sync_tid.
1009          */
1010         if ((parent->flags & HAMMER2_CHAIN_DESTROYED) &&
1011             (child->flags & HAMMER2_CHAIN_DELETED) &&
1012             (child->flags & HAMMER2_CHAIN_DESTROYED) == 0) {
1013                 atomic_set_int(&child->flags, HAMMER2_CHAIN_DESTROYED);
1014                 /*
1015                  * Force downward recursion by bringing update_tid up to
1016                  * at least sync_tid.  Parent's mirror_tid has not yet
1017                  * been updated.
1018                  *
1019                  * Vnode reclamation may have forced update_tid to MAX_TID
1020                  * (we do this because there was no transaction at the time).
1021                  * In this situation bring it down to something reasonable
1022                  * so the elements being destroyed can be retired.
1023                  */
1024                 spin_lock(&child->core->cst.spin);
1025                 if (child->core->update_tid < trans->sync_tid ||
1026                     child->core->update_tid == HAMMER2_MAX_TID) {
1027                         child->core->update_tid = trans->sync_tid;
1028                 }
1029                 spin_unlock(&child->core->cst.spin);
1030         }
1031
1032         /*
1033          * Recurse and collect deferral data.
1034          */
1035         diddeferral = info->diddeferral;
1036         ++info->depth;
1037         hammer2_chain_flush_core(info, &child);
1038
1039         /*
1040          * NOTE: If child failed to fully synchronize, child's bref.mirror_tid
1041          *       will not have been updated.  Bumping diddeferral prevents
1042          *       the parent chain from updating bref.mirror_tid on the way
1043          *       back up in order to force a retry later.
1044          */
1045         if (child->bref.mirror_tid < child->core->update_tid &&
1046             child->bref.mirror_tid < info->sync_tid) {
1047                 ++diddeferral;
1048         }
1049
1050         --info->depth;
1051         info->diddeferral += diddeferral;
1052
1053 skip:
1054         /*
1055          * Check the conditions that could cause SCAN2 to modify the parent.
1056          * Modify the parent here instead of in SCAN2, which would cause
1057          * rollup chicken-and-egg races.
1058          */
1059         if (child->delete_tid <= trans->sync_tid &&
1060             child->delete_tid > parent->bref.mirror_tid &&
1061             child->modify_tid <= parent->bref.mirror_tid) {
1062                 info->domodify = 1;
1063         } else if (child->delete_tid > trans->sync_tid &&
1064                    child->modify_tid > parent->bref.mirror_tid) {
1065                 info->domodify = 1;
1066         }
1067
1068         /*
1069          * Relock to continue the loop
1070          */
1071         hammer2_chain_unlock(child);
1072         hammer2_chain_lock(parent, HAMMER2_RESOLVE_MAYBE);
1073         hammer2_chain_drop(child);
1074         KKASSERT(info->parent == parent);
1075
1076         spin_lock(&parent->core->cst.spin);
1077         return (0);
1078 }
1079
1080 /*
1081  * Flush helper scan2 (non-recursive)
1082  *
1083  * This pass on a chain's children propagates any MOVED or DELETED
1084  * elements back up the chain towards the root after those elements have
1085  * been fully flushed.  Unlike scan1, this function is NOT recursive and
1086  * the parent remains locked across the entire scan.
1087  *
1088  * SCAN2 is called twice, once with pass set to 1 and once with it set to 2.
1089  * We have to do this so base[] elements can be deleted in pass 1 to make
1090  * room for adding new elements in pass 2.
1091  *
1092  * This function also rolls up storage statistics.
1093  *
1094  * NOTE!  A deletion is a visbility issue, there can still be references to
1095  *        deleted elements (for example, to an unlinked file which is still
1096  *        open), and there can also be multiple chains pointing to the same
1097  *        bref where some are deleted and some are not (for example due to
1098  *        a rename).   So a chain marked for deletion is basically considered
1099  *        to be live until it is explicitly destroyed or until its ref-count
1100  *        reaches zero (also implying that MOVED and MODIFIED are clear).
1101  *
1102  * NOTE!  Info->parent will be locked but will only be instantiated/modified
1103  *        if it is either MODIFIED or if scan1 determined that block table
1104  *        updates will occur.
1105  */
1106 static int
1107 hammer2_chain_flush_scan2(hammer2_chain_t *child, void *data)
1108 {
1109         hammer2_flush_info_t *info = data;
1110         hammer2_chain_t *parent = info->parent;
1111         hammer2_chain_core_t *above = child->above;
1112         hammer2_mount_t *hmp = child->hmp;
1113         hammer2_trans_t *trans = info->trans;
1114         hammer2_blockref_t *base;
1115         int count;
1116         int ok;
1117
1118 #if FLUSH_DEBUG
1119         kprintf("SCAN2 %p.%d %08x mod=%016jx del=%016jx trans=%016jx\n", child, child->bref.type, child->flags, child->modify_tid, child->delete_tid, info->trans->sync_tid);
1120 #endif
1121         /*
1122          * Inodes with stale children that have been converted to DIRECTDATA
1123          * mode (file extension or hardlink conversion typically) need to
1124          * skipped right now before we start messing with a non-existant
1125          * block table.
1126          */
1127 #if 0
1128         if (parent->bref.type == HAMMER2_BREF_TYPE_INODE &&
1129             (parent->data->ipdata.op_flags & HAMMER2_OPFLAG_DIRECTDATA)) {
1130                 goto finalize;
1131         }
1132 #endif
1133
1134         /*
1135          * Ignore children created after our flush point, treating them as
1136          * if they did not exist).  These children will not cause the parent
1137          * to be updated.
1138          *
1139          * Children deleted after our flush point are treated as having been
1140          * created for the purposes of the flush.  The parent's update_tid
1141          * will already be higher than our trans->sync_tid so the flush path
1142          * is left intact.
1143          *
1144          * When we encounter such children and the parent chain has not been
1145          * deleted, delete/duplicated, or delete/duplicated-for-move, then
1146          * the parent may be used to funnel through several flush points.
1147          * These chains will still be visible to later flushes due to having
1148          * a higher update_tid than we can set in the current flush.
1149          */
1150         if (child->modify_tid > trans->sync_tid) {
1151                 KKASSERT(child->delete_tid >= child->modify_tid);
1152                 goto finalize;
1153         }
1154
1155         /*
1156          * Ignore children which have not changed.  The parent's block table
1157          * is already correct.
1158          *
1159          * XXX The MOVED bit is only cleared when all multi-homed parents
1160          *     have flushed, creating a situation where a re-flush can occur
1161          *     via a parent which has already flushed.  The hammer2_base_*()
1162          *     functions currently have a hack to deal with this case but
1163          *     we need something better.
1164          */
1165         if ((child->flags & HAMMER2_CHAIN_MOVED) == 0) {
1166                 KKASSERT((child->flags & HAMMER2_CHAIN_MODIFIED) == 0);
1167                 goto finalize;
1168         }
1169
1170         /*
1171          * Make sure child is referenced before we unlock.
1172          */
1173         hammer2_chain_ref(child);
1174         spin_unlock(&above->cst.spin);
1175
1176         /*
1177          * Parent reflushed after the child has passed them by should skip
1178          * due to the modify_tid test. XXX
1179          */
1180         hammer2_chain_lock(child, HAMMER2_RESOLVE_NEVER);
1181         KKASSERT(child->above == above);
1182         KKASSERT(parent->core == above);
1183
1184         /*
1185          * The parent's blockref to the child must be deleted or updated.
1186          *
1187          * This point is not reached on successful DESTROYED optimizations
1188          * but can be reached on recursive deletions and restricted flushes.
1189          *
1190          * The chain_modify here may delete-duplicate the block.  This can
1191          * cause a multitude of issues if the block was already modified
1192          * by a later (post-flush) transaction.  Primarily blockrefs in
1193          * the later block can be out-of-date, so if the situation occurs
1194          * we can't throw away the MOVED bit on the current blocks until
1195          * the later blocks are flushed (so as to be able to regenerate all
1196          * the changes that were made).
1197          *
1198          * Because flushes are ordered we do not have to make a
1199          * modify/duplicate of indirect blocks.  That is, the flush
1200          * code does not have to kmalloc or duplicate anything.  We
1201          * can adjust the indirect block table in-place and reuse the
1202          * chain.  It IS possible that the chain has already been duplicated
1203          * or may wind up being duplicated on-the-fly by modifying code
1204          * on the frontend.  We simply use the original and ignore such
1205          * chains.  However, it does mean we can't clear the MOVED bit.
1206          *
1207          * XXX recursive deletions not optimized.
1208          */
1209
1210         switch(parent->bref.type) {
1211         case HAMMER2_BREF_TYPE_INODE:
1212                 /*
1213                  * XXX Should assert that OPFLAG_DIRECTDATA is 0 once we
1214                  * properly duplicate the inode headers and do proper flush
1215                  * range checks (all the children should be beyond the flush
1216                  * point).  For now just don't sync the non-applicable
1217                  * children.
1218                  *
1219                  * XXX Can also occur due to hardlink consolidation.  We
1220                  * set OPFLAG_DIRECTDATA to prevent the indirect and data
1221                  * blocks from syncing ot the hardlink pointer.
1222                  */
1223                 if (parent->data)
1224                         base = &parent->data->ipdata.u.blockset.blockref[0];
1225                 else
1226                         base = NULL;
1227                 count = HAMMER2_SET_COUNT;
1228                 break;
1229         case HAMMER2_BREF_TYPE_INDIRECT:
1230         case HAMMER2_BREF_TYPE_FREEMAP_NODE:
1231                 if (parent->data)
1232                         base = &parent->data->npdata[0];
1233                 else
1234                         base = NULL;
1235                 count = parent->bytes / sizeof(hammer2_blockref_t);
1236                 break;
1237         case HAMMER2_BREF_TYPE_VOLUME:
1238                 base = &hmp->voldata.sroot_blockset.blockref[0];
1239                 count = HAMMER2_SET_COUNT;
1240                 break;
1241         case HAMMER2_BREF_TYPE_FREEMAP:
1242                 base = &parent->data->npdata[0];
1243                 count = HAMMER2_SET_COUNT;
1244                 break;
1245         default:
1246                 base = NULL;
1247                 count = 0;
1248                 panic("hammer2_chain_flush_scan2: "
1249                       "unrecognized blockref type: %d",
1250                       parent->bref.type);
1251         }
1252
1253         /*
1254          * Don't bother updating a deleted parent's blockrefs (caller will
1255          * optimize-out the disk write).  Note that this is not optional,
1256          * a deleted parent's blockref array might not be synchronized at
1257          * all so calling hammer2_base*() functions could result in a panic.
1258          *
1259          * Otherwise, we need to be COUNTEDBREFS synchronized for the
1260          * hammer2_base_*() functions.
1261          */
1262 #if FLUSH_DEBUG
1263         kprintf("SCAN2 base=%p pass=%d PARENT %p.%d DTID=%016jx SYNC=%016jx\n",
1264                 base,
1265                 info->pass, parent, parent->bref.type, parent->delete_tid, trans->sync_tid);
1266 #endif
1267         if (parent->delete_tid <= trans->sync_tid)
1268                 base = NULL;
1269         else if ((parent->core->flags & HAMMER2_CORE_COUNTEDBREFS) == 0)
1270                 hammer2_chain_countbrefs(parent, base, count);
1271
1272         /*
1273          * Update the parent's blockref table and propagate mirror_tid.
1274          *
1275          * NOTE! Children with modify_tid's beyond our flush point are
1276          *       considered to not exist for the purposes of updating the
1277          *       parent's blockref array.
1278          *
1279          * NOTE! Updates to a parent's blockref table do not adjust the
1280          *       parent's bref.modify_tid, only its bref.mirror_tid.
1281          *
1282          *       SCAN1 has already put the parent in a modified state
1283          *       so if it isn't we panic.
1284          *
1285          * NOTE! chain->modify_tid vs chain->bref.modify_tid.  The chain's
1286          *       internal modify_tid is always updated based on creation
1287          *       or delete-duplicate.  However, the bref.modify_tid is NOT
1288          *       updated due to simple blockref updates.
1289          */
1290 #if FLUSH_DEBUG
1291         kprintf("chain %p->%p pass %d trans %016jx sync %p.%d %016jx/%d C=%016jx D=%016jx PMIRROR %016jx\n",
1292                 parent, child,
1293                 info->pass, trans->sync_tid,
1294                 child, child->bref.type,
1295                 child->bref.key, child->bref.keybits,
1296                 child->modify_tid, child->delete_tid, parent->bref.mirror_tid);
1297 #endif
1298
1299         if (info->pass == 1 && child->delete_tid <= trans->sync_tid) {
1300                 /*
1301                  * Deleting.  The block array is expected to contain the
1302                  * child's entry if:
1303                  *
1304                  * (1) The deletion occurred after the parent's block table
1305                  *     was last synchronized (delete_tid), and
1306                  *
1307                  * (2) The creation occurred before or during the parent's
1308                  *     last block table synchronization.
1309                  */
1310 #if FLUSH_DEBUG
1311                 kprintf("S2A %p b=%p d/b=%016jx/%016jx m/b=%016jx/%016jx\n",
1312                         child, base, child->delete_tid, parent->bref.mirror_tid,
1313                         child->modify_tid, parent->bref.mirror_tid);
1314 #endif
1315                 ok = 1;
1316                 if (base &&
1317                     child->delete_tid > parent->bref.mirror_tid &&
1318                     child->modify_tid <= parent->bref.mirror_tid) {
1319                         KKASSERT(parent->modify_tid == trans->sync_tid);
1320                         hammer2_rollup_stats(parent, child, -1);
1321                         spin_lock(&above->cst.spin);
1322 #if FLUSH_DEBUG
1323                         kprintf("trans %jx parent %p.%d child %p.%d m/d %016jx/%016jx "
1324                                 "flg=%08x %016jx/%d delete\n",
1325                                 trans->sync_tid,
1326                                 parent, parent->bref.type,
1327                                 child, child->bref.type,
1328                                 child->modify_tid, child->delete_tid,
1329                                 child->flags,
1330                                 child->bref.key, child->bref.keybits);
1331 #endif
1332                         hammer2_base_delete(parent, base, count,
1333                                             &info->cache_index, child);
1334                         spin_unlock(&above->cst.spin);
1335                 }
1336                 if (info->mirror_tid < child->delete_tid)
1337                         info->mirror_tid = child->delete_tid;
1338         } else if (info->pass == 2 && child->delete_tid > trans->sync_tid) {
1339                 /*
1340                  * Inserting.  The block array is expected to NOT contain
1341                  * the child's entry if:
1342                  *
1343                  * (1) The creation occurred after the parent's block table
1344                  *     was last synchronized (modify_tid), and
1345                  *
1346                  * (2) The child is not being deleted in the same
1347                  *     transaction.
1348                  */
1349                 ok = 1;
1350                 if (base &&
1351                     child->modify_tid > parent->bref.mirror_tid) {
1352                         KKASSERT(parent->modify_tid == trans->sync_tid);
1353                         hammer2_rollup_stats(parent, child, 1);
1354                         spin_lock(&above->cst.spin);
1355 #if FLUSH_DEBUG
1356                         kprintf("trans %jx parent %p.%d child %p.%d m/d %016jx/%016jx "
1357                                 "flg=%08x %016jx/%d insert\n",
1358                                 trans->sync_tid,
1359                                 parent, parent->bref.type,
1360                                 child, child->bref.type,
1361                                 child->modify_tid, child->delete_tid,
1362                                 child->flags,
1363                                 child->bref.key, child->bref.keybits);
1364 #endif
1365                         hammer2_base_insert(parent, base, count,
1366                                             &info->cache_index, child);
1367                         spin_unlock(&above->cst.spin);
1368                 }
1369                 if (info->mirror_tid < child->modify_tid)
1370                         info->mirror_tid = child->modify_tid;
1371         } else {
1372                 ok = 0;
1373         }
1374
1375         if (info->mirror_tid < child->bref.mirror_tid) {
1376                 KKASSERT(child->bref.mirror_tid <= trans->sync_tid);
1377                 info->mirror_tid = child->bref.mirror_tid;
1378         }
1379
1380         /*
1381          * Only clear MOVED once all possible parents have been flushed.
1382          *
1383          * When can we safely clear the MOVED flag?  Flushes down duplicate
1384          * paths can occur out of order, for example if an inode is moved
1385          * as part of a hardlink consolidation or if an inode is moved into
1386          * an indirect block indexed before the inode.
1387          */
1388         if (ok && (child->flags & HAMMER2_CHAIN_MOVED)) {
1389                 hammer2_chain_t *scan;
1390
1391                 if (hammer2_debug & 0x4000)
1392                         kprintf("CHECKMOVED %p (parent=%p)", child, parent);
1393
1394                 spin_lock(&above->cst.spin);
1395                 TAILQ_FOREACH(scan, &above->ownerq, core_entry) {
1396                         /*
1397                          * Can't clear child's MOVED until all parent's have
1398                          * synchronized with it.
1399                          *
1400                          * Ignore our current parent (we use 'ok' from above),
1401                          *
1402                          * ignore any parents which have been deleted as-of
1403                          * our transaction id (their block array doesn't get
1404                          * updated).
1405                          */
1406                         if (scan == parent ||
1407                             scan->delete_tid <= trans->sync_tid)
1408                                 continue;
1409
1410                         /*
1411                          * parent not synchronized if child modified or
1412                          * deleted after the parent's last sync point.
1413                          *
1414                          * (For the purpose of clearing the MOVED bit
1415                          *  we do not restrict the tests to just flush
1416                          *  transactions).
1417                          */
1418                         if (scan->bref.mirror_tid < child->modify_tid ||
1419                             ((child->flags & HAMMER2_CHAIN_DELETED) &&
1420                              scan->bref.mirror_tid < child->delete_tid)) {
1421                                 if (hammer2_debug & 0x4000)
1422                                         kprintf("(fail scan %p %016jx/%016jx)",
1423                                                 scan, scan->bref.mirror_tid,
1424                                                 child->modify_tid);
1425                                 ok = 0;
1426                         }
1427                 }
1428                 if (hammer2_debug & 0x4000)
1429                         kprintf("\n");
1430                 spin_unlock(&above->cst.spin);
1431
1432                 /*
1433                  * Can we finally clear MOVED?
1434                  */
1435                 if (ok) {
1436                         if (hammer2_debug & 0x4000)
1437                                 kprintf("clear moved %p.%d %016jx/%d\n",
1438                                         child, child->bref.type,
1439                                         child->bref.key, child->bref.keybits);
1440                         if (child->modify_tid <= trans->sync_tid &&
1441                             (child->delete_tid == HAMMER2_MAX_TID ||
1442                              child->delete_tid <= trans->sync_tid)) {
1443                                 atomic_clear_int(&child->flags,
1444                                                  HAMMER2_CHAIN_MOVED);
1445                                 hammer2_chain_drop(child);      /* flag */
1446                                 KKASSERT((child->flags &
1447                                                 HAMMER2_CHAIN_MODIFIED) == 0);
1448                         } else {
1449                                 kprintf("ok problem child %p %016jx/%016jx vs %016jx\n", child, child->modify_tid, child->delete_tid, trans->sync_tid);
1450                         }
1451                 } else {
1452                         if (hammer2_debug & 0x4000)
1453                                 kprintf("keep  moved %p.%d %016jx/%d\n",
1454                                         child, child->bref.type,
1455                                         child->bref.key, child->bref.keybits);
1456                 }
1457         }
1458
1459         /*
1460          * Unlock the child.  This can wind up dropping the child's
1461          * last ref, removing it from the parent's RB tree, and deallocating
1462          * the structure.  The RB_SCAN() our caller is doing handles the
1463          * situation.
1464          */
1465         hammer2_chain_unlock(child);
1466         hammer2_chain_drop(child);
1467         spin_lock(&above->cst.spin);
1468
1469         /*
1470          * The parent may have been delete-duplicated.
1471          */
1472         info->parent = parent;
1473 finalize:
1474         return (0);
1475 }
1476
1477 static
1478 void
1479 hammer2_rollup_stats(hammer2_chain_t *parent, hammer2_chain_t *child, int how)
1480 {
1481 #if 0
1482         hammer2_chain_t *grandp;
1483 #endif
1484
1485         parent->data_count += child->data_count;
1486         parent->inode_count += child->inode_count;
1487         child->data_count = 0;
1488         child->inode_count = 0;
1489         if (how < 0) {
1490                 parent->data_count -= child->bytes;
1491                 if (child->bref.type == HAMMER2_BREF_TYPE_INODE) {
1492                         parent->inode_count -= 1;
1493 #if 0
1494                         /* XXX child->data may be NULL atm */
1495                         parent->data_count -= child->data->ipdata.data_count;
1496                         parent->inode_count -= child->data->ipdata.inode_count;
1497 #endif
1498                 }
1499         } else if (how > 0) {
1500                 parent->data_count += child->bytes;
1501                 if (child->bref.type == HAMMER2_BREF_TYPE_INODE) {
1502                         parent->inode_count += 1;
1503 #if 0
1504                         /* XXX child->data may be NULL atm */
1505                         parent->data_count += child->data->ipdata.data_count;
1506                         parent->inode_count += child->data->ipdata.inode_count;
1507 #endif
1508                 }
1509         }
1510         if (parent->bref.type == HAMMER2_BREF_TYPE_INODE) {
1511                 parent->data->ipdata.data_count += parent->data_count;
1512                 parent->data->ipdata.inode_count += parent->inode_count;
1513 #if 0
1514                 for (grandp = parent->above->first_parent;
1515                      grandp;
1516                      grandp = grandp->next_parent) {
1517                         grandp->data_count += parent->data_count;
1518                         grandp->inode_count += parent->inode_count;
1519                 }
1520 #endif
1521                 parent->data_count = 0;
1522                 parent->inode_count = 0;
1523         }
1524 }