hammer2 - skeleton multi target mount detection
[dragonfly.git] / sys / vfs / hammer2 / hammer2_inode.c
1 /*
2  * Copyright (c) 2011-2014 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 #include <sys/cdefs.h>
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/types.h>
39 #include <sys/lock.h>
40 #include <sys/uuid.h>
41
42 #include "hammer2.h"
43
44 #define INODE_DEBUG     0
45
46 static void hammer2_inode_move_to_hidden(hammer2_trans_t *trans,
47                                          hammer2_cluster_t **clusterp,
48                                          hammer2_tid_t inum);
49
50 RB_GENERATE2(hammer2_inode_tree, hammer2_inode, rbnode, hammer2_inode_cmp,
51              hammer2_tid_t, inum);
52
53 int
54 hammer2_inode_cmp(hammer2_inode_t *ip1, hammer2_inode_t *ip2)
55 {
56         if (ip1->inum < ip2->inum)
57                 return(-1);
58         if (ip1->inum > ip2->inum)
59                 return(1);
60         return(0);
61 }
62
63 /*
64  * HAMMER2 inode locks
65  *
66  * HAMMER2 offers shared locks and exclusive locks on inodes.
67  *
68  * The inode locking function locks the inode itself, resolves any stale
69  * chains in the inode's cluster, and allocates a fresh copy of the
70  * cluster with 1 ref and all the underlying chains locked.  Duplication
71  * races are handled by this function.
72  *
73  * ip->cluster will be stable while the inode is locked.
74  *
75  * NOTE: We don't combine the inode/chain lock because putting away an
76  *       inode would otherwise confuse multiple lock holders of the inode.
77  *
78  * NOTE: Hardlinks are followed in the returned cluster but not in the
79  *       inode's internal cluster (ip->cluster).
80  */
81 hammer2_cluster_t *
82 hammer2_inode_lock_ex(hammer2_inode_t *ip)
83 {
84         const hammer2_inode_data_t *ipdata;
85         hammer2_cluster_t *cluster;
86         hammer2_chain_t *chain;
87         hammer2_chain_t *ochain;
88         hammer2_chain_core_t *core;
89         int error;
90         int i;
91
92         hammer2_inode_ref(ip);
93         ccms_thread_lock(&ip->topo_cst, CCMS_STATE_EXCLUSIVE);
94         cluster = hammer2_cluster_copy(&ip->cluster, 0);
95
96         ip->cluster.focus = NULL;
97         cluster->focus = NULL;
98
99         for (i = 0; i < cluster->nchains; ++i) {
100                 chain = ip->cluster.array[i];
101                 core = chain->core;
102                 for (;;) {
103                         if (chain->flags & HAMMER2_CHAIN_DUPLICATED) {
104                                 spin_lock(&core->cst.spin);
105                                 while (chain->flags & HAMMER2_CHAIN_DUPLICATED)
106                                         chain = TAILQ_NEXT(chain, core_entry);
107                                 hammer2_chain_ref(chain);
108                                 spin_unlock(&core->cst.spin);
109                                 ochain = ip->cluster.array[i];
110                                 ip->cluster.array[i] = chain;
111                                 if (ip->cluster.focus == NULL)
112                                         ip->cluster.focus = chain;
113                                 hammer2_chain_drop(ochain);
114                         }
115                         hammer2_chain_lock(chain, HAMMER2_RESOLVE_ALWAYS);
116                         if ((chain->flags & HAMMER2_CHAIN_DUPLICATED) == 0)
117                                 break;
118                         hammer2_chain_unlock(chain);
119                 }
120                 cluster->array[i] = chain;
121                 if (cluster->focus == NULL)
122                         cluster->focus = chain;
123                 if (ip->cluster.focus == NULL)
124                         ip->cluster.focus = chain;
125         }
126
127         /*
128          * Returned cluster must resolve hardlink pointers
129          */
130         ipdata = &hammer2_cluster_data(cluster)->ipdata;
131         if (ipdata->type == HAMMER2_OBJTYPE_HARDLINK &&
132             (cluster->focus->flags & HAMMER2_CHAIN_DELETED) == 0) {
133                 error = hammer2_hardlink_find(ip->pip, cluster);
134                 KKASSERT((cluster->focus->flags &
135                           HAMMER2_CHAIN_DUPLICATED) == 0);
136                 KKASSERT(error == 0);
137         }
138
139         return (cluster);
140 }
141
142 void
143 hammer2_inode_unlock_ex(hammer2_inode_t *ip, hammer2_cluster_t *cluster)
144 {
145         if (cluster)
146                 hammer2_cluster_unlock(cluster);
147         ccms_thread_unlock(&ip->topo_cst);
148         hammer2_inode_drop(ip);
149 }
150
151 /*
152  * NOTE: We don't combine the inode/chain lock because putting away an
153  *       inode would otherwise confuse multiple lock holders of the inode.
154  *
155  *       Shared locks are especially sensitive to having too many shared
156  *       lock counts (from the same thread) on certain paths which might
157  *       need to upgrade them.  Only one count of a shared lock can be
158  *       upgraded.
159  */
160 hammer2_cluster_t *
161 hammer2_inode_lock_sh(hammer2_inode_t *ip)
162 {
163         const hammer2_inode_data_t *ipdata;
164         hammer2_cluster_t *cluster;
165         hammer2_chain_core_t *core;
166         hammer2_chain_t *chain;
167         int error = 0;
168         int i;
169
170         hammer2_inode_ref(ip);
171         cluster = hammer2_cluster_copy(&ip->cluster, 0);
172         ccms_thread_lock(&ip->topo_cst, CCMS_STATE_SHARED);
173
174         cluster->focus = NULL;
175
176         for (i = 0; i < cluster->nchains; ++i) {
177                 chain = ip->cluster.array[i];
178                 core = chain->core;
179
180                 if (chain->flags & HAMMER2_CHAIN_DUPLICATED)
181                         goto cycle_excl;
182                 hammer2_chain_lock(chain, HAMMER2_RESOLVE_ALWAYS |
183                                           HAMMER2_RESOLVE_SHARED);
184                 if (chain->flags & HAMMER2_CHAIN_DUPLICATED) {
185                         hammer2_chain_unlock(chain);
186
187                         /*
188                          * Cycle exclusive inode lock and start the loop
189                          * over again.
190                          */
191 cycle_excl:
192                         while (--i >= 0) {
193                                 chain = cluster->array[i];
194                                 cluster->array[i] = NULL;
195                                 hammer2_chain_unlock(chain);
196                         }
197                         ccms_thread_unlock(&ip->topo_cst);
198                         hammer2_inode_unlock_ex(ip, hammer2_inode_lock_ex(ip));
199                         ccms_thread_lock(&ip->topo_cst, CCMS_STATE_SHARED);
200                         cluster->focus = NULL;
201                         continue;       /* restart at i=-1 -> i=0 on loop */
202                 }
203                 cluster->array[i] = chain;
204                 if (cluster->focus == NULL)
205                         cluster->focus = chain;
206         }
207
208         /*
209          * Returned cluster must resolve hardlink pointers
210          */
211         ipdata = &hammer2_cluster_data(cluster)->ipdata;
212         if (ipdata->type == HAMMER2_OBJTYPE_HARDLINK &&
213             (cluster->focus->flags & HAMMER2_CHAIN_DELETED) == 0) {
214                 error = hammer2_hardlink_find(ip->pip, cluster);
215                 KKASSERT((cluster->focus->flags &
216                           HAMMER2_CHAIN_DUPLICATED) == 0);
217                 KKASSERT(error == 0);
218         }
219
220         return (cluster);
221 }
222
223 void
224 hammer2_inode_unlock_sh(hammer2_inode_t *ip, hammer2_cluster_t *cluster)
225 {
226         if (cluster)
227                 hammer2_cluster_unlock(cluster);
228         ccms_thread_unlock(&ip->topo_cst);
229         hammer2_inode_drop(ip);
230 }
231
232 ccms_state_t
233 hammer2_inode_lock_temp_release(hammer2_inode_t *ip)
234 {
235         return(ccms_thread_lock_temp_release(&ip->topo_cst));
236 }
237
238 void
239 hammer2_inode_lock_temp_restore(hammer2_inode_t *ip, ccms_state_t ostate)
240 {
241         ccms_thread_lock_temp_restore(&ip->topo_cst, ostate);
242 }
243
244 ccms_state_t
245 hammer2_inode_lock_upgrade(hammer2_inode_t *ip)
246 {
247         return(ccms_thread_lock_upgrade(&ip->topo_cst));
248 }
249
250 void
251 hammer2_inode_lock_downgrade(hammer2_inode_t *ip, ccms_state_t ostate)
252 {
253         ccms_thread_lock_downgrade(&ip->topo_cst, ostate);
254 }
255
256 /*
257  * Lookup an inode by inode number
258  */
259 hammer2_inode_t *
260 hammer2_inode_lookup(hammer2_pfsmount_t *pmp, hammer2_tid_t inum)
261 {
262         hammer2_inode_t *ip;
263
264         if (pmp) {
265                 spin_lock(&pmp->inum_spin);
266                 ip = RB_LOOKUP(hammer2_inode_tree, &pmp->inum_tree, inum);
267                 if (ip)
268                         hammer2_inode_ref(ip);
269                 spin_unlock(&pmp->inum_spin);
270         } else {
271                 ip = NULL;
272         }
273         return(ip);
274 }
275
276 /*
277  * Adding a ref to an inode is only legal if the inode already has at least
278  * one ref.
279  */
280 void
281 hammer2_inode_ref(hammer2_inode_t *ip)
282 {
283         atomic_add_int(&ip->refs, 1);
284 }
285
286 /*
287  * Drop an inode reference, freeing the inode when the last reference goes
288  * away.
289  */
290 void
291 hammer2_inode_drop(hammer2_inode_t *ip)
292 {
293         hammer2_pfsmount_t *pmp;
294         hammer2_inode_t *pip;
295         u_int refs;
296
297         while (ip) {
298                 refs = ip->refs;
299                 cpu_ccfence();
300                 if (refs == 1) {
301                         /*
302                          * Transition to zero, must interlock with
303                          * the inode inumber lookup tree (if applicable).
304                          *
305                          * NOTE: The super-root inode has no pmp.
306                          */
307                         pmp = ip->pmp;
308                         if (pmp)
309                                 spin_lock(&pmp->inum_spin);
310
311                         if (atomic_cmpset_int(&ip->refs, 1, 0)) {
312                                 KKASSERT(ip->topo_cst.count == 0);
313                                 if (ip->flags & HAMMER2_INODE_ONRBTREE) {
314                                         atomic_clear_int(&ip->flags,
315                                                      HAMMER2_INODE_ONRBTREE);
316                                         RB_REMOVE(hammer2_inode_tree,
317                                                   &pmp->inum_tree, ip);
318                                 }
319                                 if (pmp)
320                                         spin_unlock(&pmp->inum_spin);
321
322                                 pip = ip->pip;
323                                 ip->pip = NULL;
324                                 ip->pmp = NULL;
325
326                                 /*
327                                  * Cleaning out ip->cluster isn't entirely
328                                  * trivial.
329                                  */
330                                 hammer2_inode_repoint(ip, NULL, NULL);
331
332                                 /*
333                                  * We have to drop pip (if non-NULL) to
334                                  * dispose of our implied reference from
335                                  * ip->pip.  We can simply loop on it.
336                                  */
337                                 if (pmp) {
338                                         KKASSERT((ip->flags &
339                                                   HAMMER2_INODE_SROOT) == 0);
340                                         kfree(ip, pmp->minode);
341                                         atomic_add_long(&pmp->inmem_inodes, -1);
342                                 } else {
343                                         KKASSERT(ip->flags &
344                                                  HAMMER2_INODE_SROOT);
345                                         kfree(ip, M_HAMMER2);
346                                 }
347                                 ip = pip;
348                                 /* continue with pip (can be NULL) */
349                         } else {
350                                 if (pmp)
351                                         spin_unlock(&ip->pmp->inum_spin);
352                         }
353                 } else {
354                         /*
355                          * Non zero transition
356                          */
357                         if (atomic_cmpset_int(&ip->refs, refs, refs - 1))
358                                 break;
359                 }
360         }
361 }
362
363 /*
364  * Get the vnode associated with the given inode, allocating the vnode if
365  * necessary.  The vnode will be returned exclusively locked.
366  *
367  * The caller must lock the inode (shared or exclusive).
368  *
369  * Great care must be taken to avoid deadlocks and vnode acquisition/reclaim
370  * races.
371  */
372 struct vnode *
373 hammer2_igetv(hammer2_inode_t *ip, hammer2_cluster_t *cparent, int *errorp)
374 {
375         const hammer2_inode_data_t *ipdata;
376         hammer2_pfsmount_t *pmp;
377         struct vnode *vp;
378         ccms_state_t ostate;
379
380         pmp = ip->pmp;
381         KKASSERT(pmp != NULL);
382         *errorp = 0;
383
384         ipdata = &hammer2_cluster_data(cparent)->ipdata;
385
386         for (;;) {
387                 /*
388                  * Attempt to reuse an existing vnode assignment.  It is
389                  * possible to race a reclaim so the vget() may fail.  The
390                  * inode must be unlocked during the vget() to avoid a
391                  * deadlock against a reclaim.
392                  */
393                 vp = ip->vp;
394                 if (vp) {
395                         /*
396                          * Inode must be unlocked during the vget() to avoid
397                          * possible deadlocks, but leave the ip ref intact.
398                          *
399                          * vnode is held to prevent destruction during the
400                          * vget().  The vget() can still fail if we lost
401                          * a reclaim race on the vnode.
402                          */
403                         vhold(vp);
404                         ostate = hammer2_inode_lock_temp_release(ip);
405                         if (vget(vp, LK_EXCLUSIVE)) {
406                                 vdrop(vp);
407                                 hammer2_inode_lock_temp_restore(ip, ostate);
408                                 continue;
409                         }
410                         hammer2_inode_lock_temp_restore(ip, ostate);
411                         vdrop(vp);
412                         /* vp still locked and ref from vget */
413                         if (ip->vp != vp) {
414                                 kprintf("hammer2: igetv race %p/%p\n",
415                                         ip->vp, vp);
416                                 vput(vp);
417                                 continue;
418                         }
419                         *errorp = 0;
420                         break;
421                 }
422
423                 /*
424                  * No vnode exists, allocate a new vnode.  Beware of
425                  * allocation races.  This function will return an
426                  * exclusively locked and referenced vnode.
427                  */
428                 *errorp = getnewvnode(VT_HAMMER2, pmp->mp, &vp, 0, 0);
429                 if (*errorp) {
430                         kprintf("hammer2: igetv getnewvnode failed %d\n",
431                                 *errorp);
432                         vp = NULL;
433                         break;
434                 }
435
436                 /*
437                  * Lock the inode and check for an allocation race.
438                  */
439                 ostate = hammer2_inode_lock_upgrade(ip);
440                 if (ip->vp != NULL) {
441                         vp->v_type = VBAD;
442                         vx_put(vp);
443                         hammer2_inode_lock_downgrade(ip, ostate);
444                         continue;
445                 }
446
447                 switch (ipdata->type) {
448                 case HAMMER2_OBJTYPE_DIRECTORY:
449                         vp->v_type = VDIR;
450                         break;
451                 case HAMMER2_OBJTYPE_REGFILE:
452                         vp->v_type = VREG;
453                         vinitvmio(vp, ipdata->size,
454                                   HAMMER2_LBUFSIZE,
455                                   (int)ipdata->size & HAMMER2_LBUFMASK);
456                         break;
457                 case HAMMER2_OBJTYPE_SOFTLINK:
458                         /*
459                          * XXX for now we are using the generic file_read
460                          * and file_write code so we need a buffer cache
461                          * association.
462                          */
463                         vp->v_type = VLNK;
464                         vinitvmio(vp, ipdata->size,
465                                   HAMMER2_LBUFSIZE,
466                                   (int)ipdata->size & HAMMER2_LBUFMASK);
467                         break;
468                 case HAMMER2_OBJTYPE_CDEV:
469                         vp->v_type = VCHR;
470                         /* fall through */
471                 case HAMMER2_OBJTYPE_BDEV:
472                         vp->v_ops = &pmp->mp->mnt_vn_spec_ops;
473                         if (ipdata->type != HAMMER2_OBJTYPE_CDEV)
474                                 vp->v_type = VBLK;
475                         addaliasu(vp, ipdata->rmajor, ipdata->rminor);
476                         break;
477                 case HAMMER2_OBJTYPE_FIFO:
478                         vp->v_type = VFIFO;
479                         vp->v_ops = &pmp->mp->mnt_vn_fifo_ops;
480                         break;
481                 default:
482                         panic("hammer2: unhandled objtype %d", ipdata->type);
483                         break;
484                 }
485
486                 if (ip == pmp->iroot)
487                         vsetflags(vp, VROOT);
488
489                 vp->v_data = ip;
490                 ip->vp = vp;
491                 hammer2_inode_ref(ip);          /* vp association */
492                 hammer2_inode_lock_downgrade(ip, ostate);
493                 break;
494         }
495
496         /*
497          * Return non-NULL vp and *errorp == 0, or NULL vp and *errorp != 0.
498          */
499         if (hammer2_debug & 0x0002) {
500                 kprintf("igetv vp %p refs 0x%08x aux 0x%08x\n",
501                         vp, vp->v_refcnt, vp->v_auxrefs);
502         }
503         return (vp);
504 }
505
506 /*
507  * Returns the inode associated with the passed-in cluster, creating the
508  * inode if necessary and synchronizing it to the passed-in cluster otherwise.
509  *
510  * The passed-in chain must be locked and will remain locked on return.
511  * The returned inode will be locked and the caller may dispose of both
512  * via hammer2_inode_unlock_ex().  However, if the caller needs to resolve
513  * a hardlink it must ref/unlock/relock/drop the inode.
514  *
515  * The hammer2_inode structure regulates the interface between the high level
516  * kernel VNOPS API and the filesystem backend (the chains).
517  *
518  * WARNING!  The mount code is allowed to pass dip == NULL for iroot and
519  *           is allowed to pass pmp == NULL and dip == NULL for sroot.
520  */
521 hammer2_inode_t *
522 hammer2_inode_get(hammer2_pfsmount_t *pmp, hammer2_inode_t *dip,
523                   hammer2_cluster_t *cluster)
524 {
525         hammer2_inode_t *nip;
526         const hammer2_inode_data_t *iptmp;
527         const hammer2_inode_data_t *nipdata;
528
529         KKASSERT(hammer2_cluster_type(cluster) == HAMMER2_BREF_TYPE_INODE);
530
531         /*
532          * Interlocked lookup/ref of the inode.  This code is only needed
533          * when looking up inodes with nlinks != 0 (TODO: optimize out
534          * otherwise and test for duplicates).
535          */
536 again:
537         for (;;) {
538                 iptmp = &hammer2_cluster_data(cluster)->ipdata;
539                 nip = hammer2_inode_lookup(pmp, iptmp->inum);
540                 if (nip == NULL)
541                         break;
542
543                 ccms_thread_lock(&nip->topo_cst, CCMS_STATE_EXCLUSIVE);
544                 if ((nip->flags & HAMMER2_INODE_ONRBTREE) == 0) { /* race */
545                         ccms_thread_unlock(&nip->topo_cst);
546                         hammer2_inode_drop(nip);
547                         continue;
548                 }
549                 hammer2_inode_repoint(nip, NULL, cluster);
550                 return nip;
551         }
552
553         /*
554          * We couldn't find the inode number, create a new inode.
555          */
556         if (pmp) {
557                 nip = kmalloc(sizeof(*nip), pmp->minode, M_WAITOK | M_ZERO);
558                 atomic_add_long(&pmp->inmem_inodes, 1);
559                 hammer2_pfs_memory_inc(pmp);
560                 hammer2_pfs_memory_wakeup(pmp);
561         } else {
562                 nip = kmalloc(sizeof(*nip), M_HAMMER2, M_WAITOK | M_ZERO);
563                 nip->flags = HAMMER2_INODE_SROOT;
564         }
565
566         /*
567          * Initialize nip's cluster
568          */
569         nip->cluster.refs = 1;
570         nip->cluster.pmp = pmp;
571         nip->cluster.flags |= HAMMER2_CLUSTER_INODE;
572         hammer2_cluster_replace(&nip->cluster, cluster);
573
574         nipdata = &hammer2_cluster_data(cluster)->ipdata;
575         nip->inum = nipdata->inum;
576         nip->size = nipdata->size;
577         nip->mtime = nipdata->mtime;
578         hammer2_inode_repoint(nip, NULL, cluster);
579         nip->pip = dip;                         /* can be NULL */
580         if (dip)
581                 hammer2_inode_ref(dip); /* ref dip for nip->pip */
582
583         nip->pmp = pmp;
584
585         /*
586          * ref and lock on nip gives it state compatible to after a
587          * hammer2_inode_lock_ex() call.
588          */
589         nip->refs = 1;
590         ccms_cst_init(&nip->topo_cst, &nip->cluster);
591         ccms_thread_lock(&nip->topo_cst, CCMS_STATE_EXCLUSIVE);
592         /* combination of thread lock and chain lock == inode lock */
593
594         /*
595          * Attempt to add the inode.  If it fails we raced another inode
596          * get.  Undo all the work and try again.
597          */
598         if (pmp) {
599                 spin_lock(&pmp->inum_spin);
600                 if (RB_INSERT(hammer2_inode_tree, &pmp->inum_tree, nip)) {
601                         spin_unlock(&pmp->inum_spin);
602                         ccms_thread_unlock(&nip->topo_cst);
603                         hammer2_inode_drop(nip);
604                         goto again;
605                 }
606                 atomic_set_int(&nip->flags, HAMMER2_INODE_ONRBTREE);
607                 spin_unlock(&pmp->inum_spin);
608         }
609
610         return (nip);
611 }
612
613 /*
614  * Create a new inode in the specified directory using the vattr to
615  * figure out the type of inode.
616  *
617  * If no error occurs the new inode with its cluster locked is returned in
618  * *nipp, otherwise an error is returned and *nipp is set to NULL.
619  *
620  * If vap and/or cred are NULL the related fields are not set and the
621  * inode type defaults to a directory.  This is used when creating PFSs
622  * under the super-root, so the inode number is set to 1 in this case.
623  *
624  * dip is not locked on entry.
625  */
626 hammer2_inode_t *
627 hammer2_inode_create(hammer2_trans_t *trans, hammer2_inode_t *dip,
628                      struct vattr *vap, struct ucred *cred,
629                      const uint8_t *name, size_t name_len,
630                      hammer2_cluster_t **clusterp, int *errorp)
631 {
632         const hammer2_inode_data_t *dipdata;
633         hammer2_inode_data_t *nipdata;
634         hammer2_cluster_t *cluster;
635         hammer2_cluster_t *cparent;
636         hammer2_inode_t *nip;
637         hammer2_key_t key_dummy;
638         hammer2_key_t lhc;
639         int error;
640         uid_t xuid;
641         uuid_t dip_uid;
642         uuid_t dip_gid;
643         uint32_t dip_mode;
644         uint8_t dip_algo;
645         int ddflag;
646
647         lhc = hammer2_dirhash(name, name_len);
648         *errorp = 0;
649
650         /*
651          * Locate the inode or indirect block to create the new
652          * entry in.  At the same time check for key collisions
653          * and iterate until we don't get one.
654          *
655          * NOTE: hidden inodes do not have iterators.
656          */
657 retry:
658         cparent = hammer2_inode_lock_ex(dip);
659         dipdata = &hammer2_cluster_data(cparent)->ipdata;
660         dip_uid = dipdata->uid;
661         dip_gid = dipdata->gid;
662         dip_mode = dipdata->mode;
663         dip_algo = dipdata->comp_algo;
664
665         error = 0;
666         while (error == 0) {
667                 cluster = hammer2_cluster_lookup(cparent, &key_dummy,
668                                                  lhc, lhc, 0, &ddflag);
669                 if (cluster == NULL)
670                         break;
671                 if ((lhc & HAMMER2_DIRHASH_VISIBLE) == 0)
672                         error = ENOSPC;
673                 if ((lhc & HAMMER2_DIRHASH_LOMASK) == HAMMER2_DIRHASH_LOMASK)
674                         error = ENOSPC;
675                 hammer2_cluster_unlock(cluster);
676                 cluster = NULL;
677                 ++lhc;
678         }
679
680         if (error == 0) {
681                 error = hammer2_cluster_create(trans, cparent, &cluster,
682                                              lhc, 0,
683                                              HAMMER2_BREF_TYPE_INODE,
684                                              HAMMER2_INODE_BYTES);
685         }
686 #if INODE_DEBUG
687         kprintf("CREATE INODE %*.*s chain=%p\n",
688                 (int)name_len, (int)name_len, name,
689                 (cluster ? cluster->focus : NULL));
690 #endif
691
692         /*
693          * Cleanup and handle retries.
694          */
695         if (error == EAGAIN) {
696                 hammer2_cluster_ref(cparent);
697                 hammer2_inode_unlock_ex(dip, cparent);
698                 hammer2_cluster_wait(cparent);
699                 hammer2_cluster_drop(cparent);
700                 goto retry;
701         }
702         hammer2_inode_unlock_ex(dip, cparent);
703         cparent = NULL;
704
705         if (error) {
706                 KKASSERT(cluster == NULL);
707                 *errorp = error;
708                 return (NULL);
709         }
710
711         /*
712          * Set up the new inode.
713          *
714          * NOTE: *_get() integrates chain's lock into the inode lock.
715          *
716          * NOTE: Only one new inode can currently be created per
717          *       transaction.  If the need arises we can adjust
718          *       hammer2_trans_init() to allow more.
719          *
720          * NOTE: nipdata will have chain's blockset data.
721          */
722         KKASSERT(cluster->focus->flags & HAMMER2_CHAIN_MODIFIED);
723         nipdata = &hammer2_cluster_wdata(cluster)->ipdata;
724         nipdata->inum = trans->inode_tid;
725         nip = hammer2_inode_get(dip->pmp, dip, cluster);
726         nipdata = &hammer2_cluster_wdata(cluster)->ipdata;
727
728         if (vap) {
729                 KKASSERT(trans->inodes_created == 0);
730                 nipdata->type = hammer2_get_obj_type(vap->va_type);
731                 nipdata->inum = trans->inode_tid;
732                 ++trans->inodes_created;
733
734                 switch (nipdata->type) {
735                 case HAMMER2_OBJTYPE_CDEV:
736                 case HAMMER2_OBJTYPE_BDEV:
737                         nipdata->rmajor = vap->va_rmajor;
738                         nipdata->rminor = vap->va_rminor;
739                         break;
740                 default:
741                         break;
742                 }
743         } else {
744                 nipdata->type = HAMMER2_OBJTYPE_DIRECTORY;
745                 nipdata->inum = 1;
746         }
747         
748         /* Inherit parent's inode compression mode. */
749         nip->comp_heuristic = 0;
750         nipdata->comp_algo = dip_algo;
751         nipdata->version = HAMMER2_INODE_VERSION_ONE;
752         hammer2_update_time(&nipdata->ctime);
753         nipdata->mtime = nipdata->ctime;
754         if (vap)
755                 nipdata->mode = vap->va_mode;
756         nipdata->nlinks = 1;
757         if (vap) {
758                 if (dip && dip->pmp) {
759                         xuid = hammer2_to_unix_xid(&dip_uid);
760                         xuid = vop_helper_create_uid(dip->pmp->mp,
761                                                      dip_mode,
762                                                      xuid,
763                                                      cred,
764                                                      &vap->va_mode);
765                 } else {
766                         /* super-root has no dip and/or pmp */
767                         xuid = 0;
768                 }
769                 if (vap->va_vaflags & VA_UID_UUID_VALID)
770                         nipdata->uid = vap->va_uid_uuid;
771                 else if (vap->va_uid != (uid_t)VNOVAL)
772                         hammer2_guid_to_uuid(&nipdata->uid, vap->va_uid);
773                 else
774                         hammer2_guid_to_uuid(&nipdata->uid, xuid);
775
776                 if (vap->va_vaflags & VA_GID_UUID_VALID)
777                         nipdata->gid = vap->va_gid_uuid;
778                 else if (vap->va_gid != (gid_t)VNOVAL)
779                         hammer2_guid_to_uuid(&nipdata->gid, vap->va_gid);
780                 else if (dip)
781                         nipdata->gid = dip_gid;
782         }
783
784         /*
785          * Regular files and softlinks allow a small amount of data to be
786          * directly embedded in the inode.  This flag will be cleared if
787          * the size is extended past the embedded limit.
788          */
789         if (nipdata->type == HAMMER2_OBJTYPE_REGFILE ||
790             nipdata->type == HAMMER2_OBJTYPE_SOFTLINK) {
791                 nipdata->op_flags |= HAMMER2_OPFLAG_DIRECTDATA;
792         }
793
794         KKASSERT(name_len < HAMMER2_INODE_MAXNAME);
795         bcopy(name, nipdata->filename, name_len);
796         nipdata->name_key = lhc;
797         nipdata->name_len = name_len;
798         *clusterp = cluster;
799
800         return (nip);
801 }
802
803 /*
804  * Shift *chainp up to the specified directory, change the filename
805  * to "0xINODENUMBER", and adjust the key.  The chain becomes the
806  * invisible hardlink target.
807  *
808  * The original *chainp has already been marked deleted.
809  */
810 static
811 void
812 hammer2_hardlink_shiftup(hammer2_trans_t *trans, hammer2_cluster_t *cluster,
813                         hammer2_inode_t *dip, hammer2_cluster_t *dcluster,
814                         int nlinks, int *errorp)
815 {
816         const hammer2_inode_data_t *iptmp;
817         hammer2_inode_data_t *nipdata;
818         hammer2_cluster_t *xcluster;
819         hammer2_key_t key_dummy;
820         hammer2_key_t lhc;
821         hammer2_blockref_t bref;
822         int ddflag;
823
824         iptmp = &hammer2_cluster_data(cluster)->ipdata;
825         lhc = iptmp->inum;
826         KKASSERT((lhc & HAMMER2_DIRHASH_VISIBLE) == 0);
827
828         /*
829          * Locate the inode or indirect block to create the new
830          * entry in.  lhc represents the inode number so there is
831          * no collision iteration.
832          *
833          * There should be no key collisions with invisible inode keys.
834          *
835          * WARNING! Must use inode_lock_ex() on dip to handle a stale
836          *          dip->cluster cache.
837          */
838 retry:
839         *errorp = 0;
840         xcluster = hammer2_cluster_lookup(dcluster, &key_dummy,
841                                       lhc, lhc, 0, &ddflag);
842         if (xcluster) {
843                 kprintf("X3 chain %p dip %p dchain %p dip->chain %p\n",
844                         xcluster->focus, dip, dcluster->focus,
845                         dip->cluster.focus);
846                 hammer2_cluster_unlock(xcluster);
847                 xcluster = NULL;
848                 *errorp = ENOSPC;
849 #if 0
850                 Debugger("X3");
851 #endif
852         }
853
854         /*
855          * Create entry in common parent directory using the seek position
856          * calculated above.
857          *
858          * We must refactor cluster because it might have been shifted into
859          * an indirect cluster by the create.
860          */
861         if (*errorp == 0) {
862                 KKASSERT(xcluster == NULL);
863 #if 0
864                 *errorp = hammer2_cluster_create(trans, dcluster, &xcluster,
865                                                lhc, 0,
866                                                HAMMER2_BREF_TYPE_INODE,/* n/a */
867                                                HAMMER2_INODE_BYTES);   /* n/a */
868 #endif
869                 /*XXX this somehow isn't working on cluster XXX*/
870                 /*KKASSERT(xxx)*/
871         }
872
873         /*
874          * Cleanup and handle retries.
875          */
876         if (*errorp == EAGAIN) {
877                 kprintf("R");
878                 hammer2_cluster_wait(dcluster);
879                 hammer2_cluster_drop(dcluster);
880                 goto retry;
881         }
882
883         /*
884          * Handle the error case
885          */
886         if (*errorp) {
887                 panic("error2");
888                 KKASSERT(xcluster == NULL);
889                 return;
890         }
891
892         /*
893          * Use xcluster as a placeholder for (lhc).  Duplicate cluster to the
894          * same target bref as xcluster and then delete xcluster.  The
895          * duplication occurs after xcluster in flush order even though
896          * xcluster is deleted after the duplication. XXX
897          *
898          * WARNING! Duplications (to a different parent) can cause indirect
899          *          blocks to be inserted, refactor xcluster.
900          *
901          * WARNING! Only key and keybits is extracted from a passed-in bref.
902          */
903         hammer2_cluster_bref(cluster, &bref);
904         bref.key = lhc;                 /* invisible dir entry key */
905         bref.keybits = 0;
906         hammer2_cluster_duplicate(trans, dcluster, cluster, &bref, 0, 2);
907
908         /*
909          * cluster is now 'live' again.. adjust the filename.
910          *
911          * Directory entries are inodes but this is a hidden hardlink
912          * target.  The name isn't used but to ease debugging give it
913          * a name after its inode number.
914          */
915         hammer2_cluster_modify(trans, cluster, 0);
916         nipdata = &hammer2_cluster_wdata(cluster)->ipdata;
917         ksnprintf(nipdata->filename, sizeof(nipdata->filename),
918                   "0x%016jx", (intmax_t)nipdata->inum);
919         nipdata->name_len = strlen(nipdata->filename);
920         nipdata->name_key = lhc;
921         nipdata->nlinks += nlinks;
922         hammer2_cluster_modsync(cluster);
923 }
924
925 /*
926  * Connect the target inode represented by (*chainp) to the media topology
927  * at (dip, name, len).  The caller can pass a rough *chainp, this function
928  * will issue lookup()s to position the parent chain properly for the
929  * chain insertion.
930  *
931  * If hlink is TRUE this function creates an OBJTYPE_HARDLINK directory
932  * entry instead of connecting (*chainp).
933  *
934  * If hlink is FALSE this function uses chain_duplicate() to make a copy
935  * if (*chainp) in the directory entry.  (*chainp) is likely to be deleted
936  * by the caller in this case (e.g. rename).
937  */
938 int
939 hammer2_inode_connect(hammer2_trans_t *trans,
940                       hammer2_cluster_t **clusterp, int hlink,
941                       hammer2_inode_t *dip, hammer2_cluster_t *dcluster,
942                       const uint8_t *name, size_t name_len,
943                       hammer2_key_t lhc)
944 {
945         hammer2_inode_data_t *wipdata;
946         hammer2_cluster_t *ocluster;
947         hammer2_cluster_t *ncluster;
948         hammer2_key_t key_dummy;
949         int ddflag;
950         int error;
951
952         /*
953          * Since ocluster is either disconnected from the topology or
954          * represents a hardlink terminus which is always a parent of or
955          * equal to dip, we should be able to safely lock dip->chain for
956          * our setup.
957          *
958          * WARNING! Must use inode_lock_ex() on dip to handle a stale
959          *          dip->cluster.
960          */
961         ocluster = *clusterp;
962
963         /*
964          * If name is non-NULL we calculate lhc, else we use the passed-in
965          * lhc.
966          */
967         if (name) {
968                 lhc = hammer2_dirhash(name, name_len);
969
970                 /*
971                  * Locate the inode or indirect block to create the new
972                  * entry in.  At the same time check for key collisions
973                  * and iterate until we don't get one.
974                  */
975                 error = 0;
976                 while (error == 0) {
977                         ncluster = hammer2_cluster_lookup(dcluster, &key_dummy,
978                                                       lhc, lhc,
979                                                       0, &ddflag);
980                         if (ncluster == NULL)
981                                 break;
982                         if ((lhc & HAMMER2_DIRHASH_LOMASK) ==
983                             HAMMER2_DIRHASH_LOMASK) {
984                                 error = ENOSPC;
985                         }
986                         hammer2_cluster_unlock(ncluster);
987                         ncluster = NULL;
988                         ++lhc;
989                 }
990         } else {
991                 /*
992                  * Reconnect to specific key (used when moving
993                  * unlinked-but-open files into the hidden directory).
994                  */
995                 ncluster = hammer2_cluster_lookup(dcluster, &key_dummy,
996                                                   lhc, lhc,
997                                                   0, &ddflag);
998                 KKASSERT(ncluster == NULL);
999         }
1000
1001         if (error == 0) {
1002                 if (hlink) {
1003                         /*
1004                          * Hardlink pointer needed, create totally fresh
1005                          * directory entry.
1006                          *
1007                          * We must refactor ocluster because it might have
1008                          * been shifted into an indirect cluster by the
1009                          * create.
1010                          */
1011                         KKASSERT(ncluster == NULL);
1012                         error = hammer2_cluster_create(trans,
1013                                                        dcluster, &ncluster,
1014                                                        lhc, 0,
1015                                                        HAMMER2_BREF_TYPE_INODE,
1016                                                        HAMMER2_INODE_BYTES);
1017                         hammer2_cluster_refactor(ocluster);
1018                 } else {
1019                         /*
1020                          * Reconnect the original cluster and rename.  Use
1021                          * cluster_duplicate().  The caller will likely delete
1022                          * or has already deleted the original chain in
1023                          * this case.
1024                          *
1025                          * NOTE: cluster_duplicate() generates a new cluster
1026                          *       with CHAIN_DELETED cleared (ocluster typically
1027                          *       has it set from the file unlink).
1028                          *
1029                          * WARNING! Can cause held-over clusters to require a
1030                          *          refactor.  Fortunately we have none (our
1031                          *          locked clusters are passed into and
1032                          *          modified by the call).
1033                          */
1034                         ncluster = ocluster;
1035                         ocluster = NULL;
1036                         hammer2_cluster_duplicate(trans, NULL, ncluster, NULL,
1037                                                   0, 3);
1038                         error = hammer2_cluster_create(trans,
1039                                                        dcluster, &ncluster,
1040                                                        lhc, 0,
1041                                                        HAMMER2_BREF_TYPE_INODE,
1042                                                        HAMMER2_INODE_BYTES);
1043                 }
1044         }
1045
1046         /*
1047          * Unlock stuff.
1048          */
1049         KKASSERT(error != EAGAIN);
1050
1051         /*
1052          * ncluster should be NULL on error, leave ocluster
1053          * (ocluster == *clusterp) alone.
1054          */
1055         if (error) {
1056                 KKASSERT(ncluster == NULL);
1057                 return (error);
1058         }
1059
1060         /*
1061          * Directory entries are inodes so if the name has changed we have
1062          * to update the inode.
1063          *
1064          * When creating an OBJTYPE_HARDLINK entry remember to unlock the
1065          * cluster, the caller will access the hardlink via the actual hardlink
1066          * target file and not the hardlink pointer entry, so we must still
1067          * return ocluster.
1068          */
1069         if (hlink && hammer2_hardlink_enable >= 0) {
1070                 /*
1071                  * Create the HARDLINK pointer.  oip represents the hardlink
1072                  * target in this situation.
1073                  *
1074                  * We will return ocluster (the hardlink target).
1075                  */
1076                 hammer2_cluster_modify(trans, ncluster, 0);
1077                 KKASSERT(name_len < HAMMER2_INODE_MAXNAME);
1078                 wipdata = &hammer2_cluster_wdata(ncluster)->ipdata;
1079                 bcopy(name, wipdata->filename, name_len);
1080                 wipdata->name_key = lhc;
1081                 wipdata->name_len = name_len;
1082                 wipdata->target_type =
1083                                 hammer2_cluster_data(ocluster)->ipdata.type;
1084                 wipdata->type = HAMMER2_OBJTYPE_HARDLINK;
1085                 wipdata->inum = hammer2_cluster_data(ocluster)->ipdata.inum;
1086                 wipdata->nlinks = 1;
1087                 hammer2_cluster_modsync(ncluster);
1088                 hammer2_cluster_unlock(ncluster);
1089                 ncluster = ocluster;
1090                 ocluster = NULL;
1091         } else {
1092                 /*
1093                  * ncluster is a duplicate of ocluster at the new location.
1094                  * We must fixup the name stored in oip.  The bref key
1095                  * has already been set up.
1096                  */
1097                 hammer2_cluster_modify(trans, ncluster, 0);
1098                 wipdata = &hammer2_cluster_wdata(ncluster)->ipdata;
1099
1100                 KKASSERT(name_len < HAMMER2_INODE_MAXNAME);
1101                 bcopy(name, wipdata->filename, name_len);
1102                 wipdata->name_key = lhc;
1103                 wipdata->name_len = name_len;
1104                 wipdata->nlinks = 1;
1105                 hammer2_cluster_modsync(ncluster);
1106         }
1107
1108         /*
1109          * We are replacing ocluster with ncluster, unlock ocluster.  In the
1110          * case where ocluster is left unchanged the code above sets
1111          * ncluster to ocluster and ocluster to NULL, resulting in a NOP here.
1112          */
1113         if (ocluster)
1114                 hammer2_cluster_unlock(ocluster);
1115         *clusterp = ncluster;
1116
1117         return (0);
1118 }
1119
1120 /*
1121  * Repoint ip->cluster's chains to cluster's chains.  Caller must hold
1122  * the inode exclusively locked.  cluster may be NULL to clean out any
1123  * chains in ip->cluster.
1124  */
1125 void
1126 hammer2_inode_repoint(hammer2_inode_t *ip, hammer2_inode_t *pip,
1127                       hammer2_cluster_t *cluster)
1128 {
1129         hammer2_chain_t *ochain;
1130         hammer2_chain_t *nchain;
1131         hammer2_inode_t *opip;
1132         int i;
1133
1134         /*
1135          * Replace chains in ip->cluster with chains from cluster and
1136          * adjust the focus if necessary.
1137          *
1138          * NOTE: nchain and/or ochain can be NULL due to gaps
1139          *       in the cluster arrays.
1140          */
1141         ip->cluster.focus = NULL;
1142         for (i = 0; cluster && i < cluster->nchains; ++i) {
1143                 nchain = cluster->array[i];
1144                 if (i < ip->cluster.nchains) {
1145                         ochain = ip->cluster.array[i];
1146                         if (ochain == nchain) {
1147                                 if (ip->cluster.focus == NULL)
1148                                         ip->cluster.focus = nchain;
1149                                 continue;
1150                         }
1151                 } else {
1152                         ochain = NULL;
1153                 }
1154
1155                 /*
1156                  * Make adjustments
1157                  */
1158                 ip->cluster.array[i] = nchain;
1159                 if (ip->cluster.focus == NULL)
1160                         ip->cluster.focus = nchain;
1161                 if (nchain)
1162                         hammer2_chain_ref(nchain);
1163                 if (ochain)
1164                         hammer2_chain_drop(ochain);
1165         }
1166
1167         /*
1168          * Release any left-over chains in ip->cluster.
1169          */
1170         while (i < ip->cluster.nchains) {
1171                 nchain = ip->cluster.array[i];
1172                 if (nchain) {
1173                         ip->cluster.array[i] = NULL;
1174                         hammer2_chain_drop(nchain);
1175                 }
1176                 ++i;
1177         }
1178         ip->cluster.nchains = cluster ? cluster->nchains : 0;
1179
1180         /*
1181          * Repoint ip->pip if requested (non-NULL pip).
1182          */
1183         if (pip && ip->pip != pip) {
1184                 opip = ip->pip;
1185                 hammer2_inode_ref(pip);
1186                 ip->pip = pip;
1187                 if (opip)
1188                         hammer2_inode_drop(opip);
1189         }
1190 }
1191
1192 /*
1193  * Unlink the file from the specified directory inode.  The directory inode
1194  * does not need to be locked.
1195  *
1196  * isdir determines whether a directory/non-directory check should be made.
1197  * No check is made if isdir is set to -1.
1198  *
1199  * isopen specifies whether special unlink-with-open-descriptor handling
1200  * must be performed.  If set to -1 the caller is deleting a PFS and we
1201  * check whether the chain is mounted or not (chain->pmp != NULL).  1 is
1202  * implied if it is mounted.
1203  *
1204  * If isopen is 1 and nlinks drops to 0 this function must move the chain
1205  * to a special hidden directory until last-close occurs on the file.
1206  *
1207  * NOTE!  The underlying file can still be active with open descriptors
1208  *        or if the chain is being manually held (e.g. for rename).
1209  *
1210  *        The caller is responsible for fixing up ip->chain if e.g. a
1211  *        rename occurs (see chain_duplicate()).
1212  */
1213 int
1214 hammer2_unlink_file(hammer2_trans_t *trans, hammer2_inode_t *dip,
1215                     const uint8_t *name, size_t name_len,
1216                     int isdir, int *hlinkp, struct nchandle *nch)
1217 {
1218         const hammer2_inode_data_t *ripdata;
1219         hammer2_inode_data_t *wipdata;
1220         hammer2_cluster_t *cparent;
1221         hammer2_cluster_t *ocluster;
1222         hammer2_cluster_t *cluster;
1223         hammer2_cluster_t *dparent;
1224         hammer2_cluster_t *dcluster;
1225         hammer2_key_t key_dummy;
1226         hammer2_key_t key_next;
1227         hammer2_key_t lhc;
1228         int error;
1229         int ddflag;
1230         uint8_t type;
1231
1232         error = 0;
1233         ocluster = NULL;
1234         lhc = hammer2_dirhash(name, name_len);
1235
1236         /*
1237          * Search for the filename in the directory
1238          */
1239         if (hlinkp)
1240                 *hlinkp = 0;
1241         cparent = hammer2_inode_lock_ex(dip);
1242         cluster = hammer2_cluster_lookup(cparent, &key_next,
1243                                      lhc, lhc + HAMMER2_DIRHASH_LOMASK,
1244                                      0, &ddflag);
1245         while (cluster) {
1246                 if (hammer2_cluster_type(cluster) == HAMMER2_BREF_TYPE_INODE) {
1247                         ripdata = &hammer2_cluster_data(cluster)->ipdata;
1248                         if (ripdata->name_len == name_len &&
1249                             bcmp(ripdata->filename, name, name_len) == 0) {
1250                                 break;
1251                         }
1252                 }
1253                 cluster = hammer2_cluster_next(cparent, cluster, &key_next,
1254                                                key_next,
1255                                                lhc + HAMMER2_DIRHASH_LOMASK,
1256                                                0);
1257         }
1258         hammer2_inode_unlock_ex(dip, NULL);     /* retain parent */
1259
1260         /*
1261          * Not found or wrong type (isdir < 0 disables the type check).
1262          * If a hardlink pointer, type checks use the hardlink target.
1263          */
1264         if (cluster == NULL) {
1265                 error = ENOENT;
1266                 goto done;
1267         }
1268         ripdata = &hammer2_cluster_data(cluster)->ipdata;
1269         type = ripdata->type;
1270         if (type == HAMMER2_OBJTYPE_HARDLINK) {
1271                 if (hlinkp)
1272                         *hlinkp = 1;
1273                 type = ripdata->target_type;
1274         }
1275
1276         if (type == HAMMER2_OBJTYPE_DIRECTORY && isdir == 0) {
1277                 error = ENOTDIR;
1278                 goto done;
1279         }
1280         if (type != HAMMER2_OBJTYPE_DIRECTORY && isdir >= 1) {
1281                 error = EISDIR;
1282                 goto done;
1283         }
1284
1285         /*
1286          * Hardlink must be resolved.  We can't hold the parent locked
1287          * while we do this or we could deadlock.
1288          *
1289          * On success cluster will be adjusted to point at the hardlink target
1290          * and ocluster will point to the hardlink pointer in the original
1291          * directory.  Otherwise cluster remains pointing to the original.
1292          *
1293          * Lock ownership is transfered to cluster.  ocluster is merely
1294          * referenced.
1295          */
1296         if (ripdata->type == HAMMER2_OBJTYPE_HARDLINK) {
1297                 hammer2_cluster_unlock(cparent);
1298                 cparent = NULL;
1299
1300                 ocluster = cluster;
1301                 cluster = hammer2_cluster_copy(ocluster,
1302                                                HAMMER2_CLUSTER_COPY_CHAINS);
1303                 error = hammer2_hardlink_find(dip, cluster);
1304                 KKASSERT(error == 0);
1305         }
1306
1307         /*
1308          * If this is a directory the directory must be empty.  However, if
1309          * isdir < 0 we are doing a rename and the directory does not have
1310          * to be empty, and if isdir > 1 we are deleting a PFS/snapshot
1311          * and the directory does not have to be empty.
1312          *
1313          * NOTE: We check the full key range here which covers both visible
1314          *       and invisible entries.  Theoretically there should be no
1315          *       invisible (hardlink target) entries if there are no visible
1316          *       entries.
1317          */
1318         if (type == HAMMER2_OBJTYPE_DIRECTORY && isdir == 1) {
1319                 dparent = hammer2_cluster_lookup_init(cluster, 0);
1320                 dcluster = hammer2_cluster_lookup(dparent, &key_dummy,
1321                                                   0, (hammer2_key_t)-1,
1322                                                   HAMMER2_LOOKUP_NODATA,
1323                                                   &ddflag);
1324                 if (dcluster) {
1325                         hammer2_cluster_unlock(dcluster);
1326                         hammer2_cluster_lookup_done(dparent);
1327                         error = ENOTEMPTY;
1328                         goto done;
1329                 }
1330                 hammer2_cluster_lookup_done(dparent);
1331                 dparent = NULL;
1332                 /* dcluster NULL */
1333         }
1334
1335         /*
1336          * Ok, we can now unlink the cluster.  We always decrement nlinks even
1337          * if the entry can be deleted in case someone has the file open and
1338          * does an fstat().
1339          *
1340          * The cluster itself will no longer be in the on-media topology but
1341          * can still be flushed to the media (e.g. if an open descriptor
1342          * remains).  When the last vnode/ip ref goes away the cluster will
1343          * be marked unmodified, avoiding any further (now unnecesary) I/O.
1344          *
1345          * A non-NULL ocluster indicates a hardlink.
1346          */
1347         if (ocluster) {
1348                 /*
1349                  * Delete the original hardlink pointer unconditionally.
1350                  * (any open descriptors will migrate to the hardlink
1351                  * target and have no affect on this operation).
1352                  *
1353                  * NOTE: parent from above is NULL when ocluster != NULL
1354                  *       so we can reuse it.
1355                  */
1356                 hammer2_cluster_lock(ocluster, HAMMER2_RESOLVE_ALWAYS);
1357                 hammer2_cluster_delete(trans, ocluster, 0);
1358                 hammer2_cluster_unlock(ocluster);
1359         }
1360
1361         /*
1362          * Decrement nlinks on the hardlink target (or original file if
1363          * there it was not hardlinked).  Delete the target when nlinks
1364          * reaches 0 with special handling if (isopen) is set.
1365          *
1366          * NOTE! In DragonFly the vnops function calls cache_unlink() after
1367          *       calling us here to clean out the namecache association,
1368          *       (which does not represent a ref for the open-test), and to
1369          *       force finalization of the vnode if/when the last ref gets
1370          *       dropped.
1371          *
1372          * NOTE! Files are unlinked by rename and then relinked.  nch will be
1373          *       passed as NULL in this situation.  hammer2_inode_connect()
1374          *       will bump nlinks.
1375          */
1376         KKASSERT(cluster != NULL);
1377         hammer2_cluster_modify(trans, cluster, 0);
1378         wipdata = &hammer2_cluster_wdata(cluster)->ipdata;
1379         ripdata = wipdata;
1380         --wipdata->nlinks;
1381         if ((int64_t)wipdata->nlinks < 0) {     /* XXX debugging */
1382                 wipdata->nlinks = 0;
1383         }
1384         hammer2_cluster_modsync(cluster);
1385
1386         if (wipdata->nlinks == 0) {
1387                 if ((cluster->focus->flags & HAMMER2_CHAIN_PFSROOT) &&
1388                     cluster->pmp) {
1389                         error = EINVAL;
1390                         kprintf("hammer2: PFS \"%s\" cannot be deleted "
1391                                 "while still mounted\n",
1392                                 wipdata->filename);
1393                         goto done;
1394                 }
1395                 if (nch && cache_isopen(nch)) {
1396                         kprintf("WARNING: unlinking open file\n");
1397                         hammer2_cluster_set_chainflags(cluster,
1398                                                         HAMMER2_CHAIN_UNLINKED);
1399                         hammer2_inode_move_to_hidden(trans, &cluster,
1400                                                      wipdata->inum);
1401                 } else {
1402                         hammer2_cluster_delete(trans, cluster, 0);
1403                 }
1404         }
1405         error = 0;
1406 done:
1407         if (cluster)
1408                 hammer2_cluster_unlock(cluster);
1409         if (cparent)
1410                 hammer2_cluster_lookup_done(cparent);
1411         if (ocluster) {
1412                 hammer2_cluster_drop(ocluster);
1413         }
1414
1415         return error;
1416 }
1417
1418 /*
1419  * This is called from the mount code to initialize pmp->ihidden
1420  */
1421 void
1422 hammer2_inode_install_hidden(hammer2_pfsmount_t *pmp)
1423 {
1424         hammer2_trans_t trans;
1425         hammer2_cluster_t *cparent;
1426         hammer2_cluster_t *cluster;
1427         hammer2_cluster_t *scan;
1428         hammer2_inode_data_t *wipdata;
1429         hammer2_key_t key_dummy;
1430         hammer2_key_t key_next;
1431         int ddflag;
1432         int error;
1433         int count;
1434
1435         if (pmp->ihidden)
1436                 return;
1437
1438         /*
1439          * Find the hidden directory
1440          */
1441         bzero(&key_dummy, sizeof(key_dummy));
1442         hammer2_trans_init(&trans, pmp, NULL, 0);
1443
1444         cparent = hammer2_inode_lock_ex(pmp->iroot);
1445         cluster = hammer2_cluster_lookup(cparent, &key_dummy,
1446                                          HAMMER2_INODE_HIDDENDIR,
1447                                          HAMMER2_INODE_HIDDENDIR,
1448                                          0, &ddflag);
1449         if (cluster) {
1450                 pmp->ihidden = hammer2_inode_get(pmp, pmp->iroot, cluster);
1451                 hammer2_inode_ref(pmp->ihidden);
1452
1453                 /*
1454                  * Remove any unlinked files which were left open as-of
1455                  * any system crash.
1456                  */
1457                 count = 0;
1458                 scan = hammer2_cluster_lookup(cluster, &key_next,
1459                                               0, HAMMER2_MAX_TID,
1460                                               HAMMER2_LOOKUP_NODATA, &ddflag);
1461                 while (scan) {
1462                         if (hammer2_cluster_type(scan) ==
1463                             HAMMER2_BREF_TYPE_INODE) {
1464                                 hammer2_cluster_delete(&trans, scan, 0);
1465                                 ++count;
1466                         }
1467                         scan = hammer2_cluster_next(cluster, scan, &key_next,
1468                                                     0, HAMMER2_MAX_TID,
1469                                                     HAMMER2_LOOKUP_NODATA);
1470                 }
1471
1472                 hammer2_inode_unlock_ex(pmp->ihidden, cluster);
1473                 hammer2_inode_unlock_ex(pmp->iroot, cparent);
1474                 hammer2_trans_done(&trans);
1475                 kprintf("hammer2: PFS loaded hidden dir, "
1476                         "removed %d dead entries\n", count);
1477                 return;
1478         }
1479
1480         /*
1481          * Create the hidden directory
1482          */
1483         error = hammer2_cluster_create(&trans, cparent, &cluster,
1484                                        HAMMER2_INODE_HIDDENDIR, 0,
1485                                        HAMMER2_BREF_TYPE_INODE,
1486                                        HAMMER2_INODE_BYTES);
1487         hammer2_inode_unlock_ex(pmp->iroot, cparent);
1488
1489         hammer2_cluster_modify(&trans, cluster, 0);
1490         wipdata = &hammer2_cluster_wdata(cluster)->ipdata;
1491         wipdata->type = HAMMER2_OBJTYPE_DIRECTORY;
1492         wipdata->inum = HAMMER2_INODE_HIDDENDIR;
1493         wipdata->nlinks = 1;
1494         hammer2_cluster_modsync(cluster);
1495         kprintf("hammer2: PFS root missing hidden directory, creating\n");
1496
1497         pmp->ihidden = hammer2_inode_get(pmp, pmp->iroot, cluster);
1498         hammer2_inode_ref(pmp->ihidden);
1499         hammer2_inode_unlock_ex(pmp->ihidden, cluster);
1500         hammer2_trans_done(&trans);
1501 }
1502
1503 /*
1504  * If an open file is unlinked H2 needs to retain the file in the topology
1505  * to ensure that its backing store is not recovered by the bulk free scan.
1506  * This also allows us to avoid having to special-case the CHAIN_DELETED flag.
1507  *
1508  * To do this the file is moved to a hidden directory in the PFS root and
1509  * renamed.  The hidden directory must be created if it does not exist.
1510  */
1511 static
1512 void
1513 hammer2_inode_move_to_hidden(hammer2_trans_t *trans,
1514                              hammer2_cluster_t **clusterp, hammer2_tid_t inum)
1515 {
1516         hammer2_cluster_t *dcluster;
1517         hammer2_pfsmount_t *pmp;
1518         int error;
1519
1520         pmp = (*clusterp)->pmp;
1521         KKASSERT(pmp != NULL);
1522         KKASSERT(pmp->ihidden != NULL);
1523
1524         hammer2_cluster_delete(trans, *clusterp, 0);
1525         dcluster = hammer2_inode_lock_ex(pmp->ihidden);
1526         error = hammer2_inode_connect(trans, clusterp, 0,
1527                                       pmp->ihidden, dcluster,
1528                                       NULL, 0, inum);
1529         hammer2_inode_unlock_ex(pmp->ihidden, dcluster);
1530         KKASSERT(error == 0);
1531 }
1532
1533 /*
1534  * Given an exclusively locked inode and cluster we consolidate its cluster
1535  * for hardlink creation, adding (nlinks) to the file's link count and
1536  * potentially relocating the inode to a directory common to ip->pip and tdip.
1537  *
1538  * Replaces (*clusterp) if consolidation occurred, unlocking the old cluster
1539  * and returning a new locked cluster.
1540  *
1541  * NOTE!  This function will also replace ip->cluster.
1542  */
1543 int
1544 hammer2_hardlink_consolidate(hammer2_trans_t *trans,
1545                              hammer2_inode_t *ip,
1546                              hammer2_cluster_t **clusterp,
1547                              hammer2_inode_t *cdip,
1548                              hammer2_cluster_t *cdcluster,
1549                              int nlinks)
1550 {
1551         const hammer2_inode_data_t *ripdata;
1552         hammer2_inode_data_t *wipdata;
1553         hammer2_cluster_t *cluster;
1554         hammer2_cluster_t *ncluster;
1555         int error;
1556
1557         cluster = *clusterp;
1558         ripdata = &hammer2_cluster_data(cluster)->ipdata;
1559         if (nlinks == 0 &&                      /* no hardlink needed */
1560             (ripdata->name_key & HAMMER2_DIRHASH_VISIBLE)) {
1561                 return (0);
1562         }
1563
1564         if (hammer2_hardlink_enable == 0) {     /* disallow hardlinks */
1565                 hammer2_cluster_unlock(cluster);
1566                 *clusterp = NULL;
1567                 return (ENOTSUP);
1568         }
1569
1570         /*
1571          * If no change in the hardlink's target directory is required and
1572          * this is already a hardlink target, all we need to do is adjust
1573          * the link count.
1574          */
1575         ripdata = &hammer2_cluster_data(cluster)->ipdata;
1576         if (cdip == ip->pip &&
1577             (ripdata->name_key & HAMMER2_DIRHASH_VISIBLE) == 0) {
1578                 if (nlinks) {
1579                         hammer2_cluster_modify(trans, cluster, 0);
1580                         wipdata = &hammer2_cluster_wdata(cluster)->ipdata;
1581                         wipdata->nlinks += nlinks;
1582                         hammer2_cluster_modsync(cluster);
1583                         ripdata = wipdata;
1584                 }
1585                 error = 0;
1586                 goto done;
1587         }
1588
1589
1590         /*
1591          * cluster is the real inode.  If it's visible we have to convert it
1592          * to a hardlink pointer.  If it is not visible then it is already
1593          * a hardlink target and only needs to be deleted.
1594          */
1595         KKASSERT((cluster->focus->flags & HAMMER2_CHAIN_DELETED) == 0);
1596         ripdata = &hammer2_cluster_data(cluster)->ipdata;
1597         KKASSERT(ripdata->type != HAMMER2_OBJTYPE_HARDLINK);
1598         if (ripdata->name_key & HAMMER2_DIRHASH_VISIBLE) {
1599                 /*
1600                  * We are going to duplicate cluster later, causing its
1601                  * media block to be shifted to the duplicate.  Even though
1602                  * we are delete-duplicating ncluster here it might decide not
1603                  * to reallocate the block.  Set FORCECOW to force it to.
1604                  */
1605                 ncluster = hammer2_cluster_copy(cluster,
1606                                                 HAMMER2_CLUSTER_COPY_CHAINS |
1607                                                 HAMMER2_CLUSTER_COPY_NOREF);
1608                 hammer2_cluster_lock(ncluster, HAMMER2_RESOLVE_ALWAYS);
1609                 hammer2_cluster_set_chainflags(ncluster,
1610                                                HAMMER2_CHAIN_FORCECOW);
1611                 hammer2_cluster_delete_duplicate(trans, ncluster,
1612                                                  HAMMER2_DELDUP_RECORE);
1613                 KKASSERT((ncluster->focus->flags &
1614                          HAMMER2_CHAIN_DUPLICATED) == 0);
1615                 wipdata = &hammer2_cluster_wdata(ncluster)->ipdata;
1616                 wipdata->target_type = wipdata->type;
1617                 wipdata->type = HAMMER2_OBJTYPE_HARDLINK;
1618                 wipdata->uflags = 0;
1619                 wipdata->rmajor = 0;
1620                 wipdata->rminor = 0;
1621                 wipdata->ctime = 0;
1622                 wipdata->mtime = 0;
1623                 wipdata->atime = 0;
1624                 wipdata->btime = 0;
1625                 bzero(&wipdata->uid, sizeof(wipdata->uid));
1626                 bzero(&wipdata->gid, sizeof(wipdata->gid));
1627                 wipdata->op_flags = HAMMER2_OPFLAG_DIRECTDATA;
1628                 wipdata->cap_flags = 0;
1629                 wipdata->mode = 0;
1630                 wipdata->size = 0;
1631                 wipdata->nlinks = 1;
1632                 wipdata->iparent = 0;   /* XXX */
1633                 wipdata->pfs_type = 0;
1634                 wipdata->pfs_inum = 0;
1635                 bzero(&wipdata->pfs_clid, sizeof(wipdata->pfs_clid));
1636                 bzero(&wipdata->pfs_fsid, sizeof(wipdata->pfs_fsid));
1637                 wipdata->data_quota = 0;
1638                 wipdata->data_count = 0;
1639                 wipdata->inode_quota = 0;
1640                 wipdata->inode_count = 0;
1641                 wipdata->attr_tid = 0;
1642                 wipdata->dirent_tid = 0;
1643                 bzero(&wipdata->u, sizeof(wipdata->u));
1644                 /* XXX transaction ids */
1645                 hammer2_cluster_modsync(ncluster);
1646         } else {
1647                 hammer2_cluster_delete(trans, cluster, 0);
1648                 ncluster = NULL;
1649         }
1650         ripdata = wipdata;
1651
1652         /*
1653          * cluster represents the hardlink target and is now flagged deleted.
1654          * duplicate it to the parent directory and adjust nlinks.
1655          *
1656          * WARNING! The shiftup() call can cause ncluster to be moved into
1657          *          an indirect block, and our ncluster will wind up pointing
1658          *          to the older/original version.
1659          */
1660         KKASSERT(cluster->focus->flags & HAMMER2_CHAIN_DELETED);
1661         hammer2_hardlink_shiftup(trans, cluster, cdip, cdcluster,
1662                                  nlinks, &error);
1663
1664         if (error == 0)
1665                 hammer2_inode_repoint(ip, cdip, cluster);
1666
1667         /*
1668          * Unlock and destroy ncluster.
1669          * Return the shifted cluster in *clusterp.
1670          */
1671         if (ncluster)
1672                 hammer2_cluster_unlock(ncluster);
1673
1674 done:
1675         /*
1676          * Cleanup, cluster/ncluster already dealt with.
1677          */
1678         *clusterp = cluster;
1679         hammer2_inode_drop(cdip);
1680
1681         return (error);
1682 }
1683
1684 /*
1685  * If (*ochainp) is non-NULL it points to the forward OBJTYPE_HARDLINK
1686  * inode while (*chainp) points to the resolved (hidden hardlink
1687  * target) inode.  In this situation when nlinks is 1 we wish to
1688  * deconsolidate the hardlink, moving it back to the directory that now
1689  * represents the only remaining link.
1690  */
1691 int
1692 hammer2_hardlink_deconsolidate(hammer2_trans_t *trans,
1693                                hammer2_inode_t *dip,
1694                                hammer2_chain_t **chainp,
1695                                hammer2_chain_t **ochainp)
1696 {
1697         if (*ochainp == NULL)
1698                 return (0);
1699         /* XXX */
1700         return (0);
1701 }
1702
1703 /*
1704  * The caller presents a locked *chainp pointing to a HAMMER2_BREF_TYPE_INODE
1705  * with an obj_type of HAMMER2_OBJTYPE_HARDLINK.  This routine will gobble
1706  * the *chainp and return a new locked *chainp representing the file target
1707  * (the original *chainp will be unlocked).
1708  *
1709  * When a match is found the chain representing the original HARDLINK
1710  * will be returned in *ochainp with a ref, but not locked.
1711  *
1712  * When no match is found *chainp is set to NULL and EIO is returned.
1713  * (*ochainp) will still be set to the original chain with a ref but not
1714  * locked.
1715  */
1716 int
1717 hammer2_hardlink_find(hammer2_inode_t *dip, hammer2_cluster_t *cluster)
1718 {
1719         const hammer2_inode_data_t *ipdata;
1720         hammer2_cluster_t *cparent;
1721         hammer2_cluster_t *rcluster;
1722         hammer2_inode_t *ip;
1723         hammer2_inode_t *pip;
1724         hammer2_key_t key_dummy;
1725         hammer2_key_t lhc;
1726         int ddflag;
1727
1728         pip = dip;
1729         hammer2_inode_ref(pip);         /* for loop */
1730
1731         /*
1732          * Locate the hardlink.  pip is referenced and not locked.
1733          */
1734         ipdata = &hammer2_cluster_data(cluster)->ipdata;
1735         lhc = ipdata->inum;
1736
1737         /*
1738          * We don't need the cluster's chains, but we need to retain the
1739          * cluster structure itself so we can load the hardlink search
1740          * result into it.
1741          */
1742         KKASSERT(cluster->refs == 1);
1743         atomic_add_int(&cluster->refs, 1);
1744         hammer2_cluster_unlock(cluster);        /* hack */
1745         cluster->nchains = 0;                   /* hack */
1746
1747         rcluster = NULL;
1748
1749         while ((ip = pip) != NULL) {
1750                 cparent = hammer2_inode_lock_ex(ip);
1751                 hammer2_inode_drop(ip);                 /* loop */
1752                 KKASSERT(hammer2_cluster_type(cparent) ==
1753                          HAMMER2_BREF_TYPE_INODE);
1754                 rcluster = hammer2_cluster_lookup(cparent, &key_dummy,
1755                                              lhc, lhc, 0, &ddflag);
1756                 hammer2_cluster_lookup_done(cparent);   /* discard parent */
1757                 if (rcluster)
1758                         break;
1759                 pip = ip->pip;          /* safe, ip held locked */
1760                 if (pip)
1761                         hammer2_inode_ref(pip);         /* loop */
1762                 hammer2_inode_unlock_ex(ip, NULL);
1763         }
1764
1765         /*
1766          * chain is locked, ip is locked.  Unlock ip, return the locked
1767          * chain.  *ipp is already set w/a ref count and not locked.
1768          *
1769          * (cparent is already unlocked).
1770          */
1771         if (ip)
1772                 hammer2_inode_unlock_ex(ip, NULL);
1773
1774         if (rcluster) {
1775                 hammer2_cluster_replace(cluster, rcluster);
1776                 hammer2_cluster_drop(rcluster);
1777                 return (0);
1778         } else {
1779                 return (EIO);
1780         }
1781 }
1782
1783 /*
1784  * Find the directory common to both fdip and tdip, hold and return
1785  * its inode.
1786  */
1787 hammer2_inode_t *
1788 hammer2_inode_common_parent(hammer2_inode_t *fdip, hammer2_inode_t *tdip)
1789 {
1790         hammer2_inode_t *scan1;
1791         hammer2_inode_t *scan2;
1792
1793         /*
1794          * We used to have a depth field but it complicated matters too
1795          * much for directory renames.  So now its ugly.  Check for
1796          * simple cases before giving up and doing it the expensive way.
1797          *
1798          * XXX need a bottom-up topology stability lock
1799          */
1800         if (fdip == tdip || fdip == tdip->pip) {
1801                 hammer2_inode_ref(fdip);
1802                 return(fdip);
1803         }
1804         if (fdip->pip == tdip) {
1805                 hammer2_inode_ref(tdip);
1806                 return(tdip);
1807         }
1808
1809         /*
1810          * XXX not MPSAFE
1811          */
1812         for (scan1 = fdip; scan1->pmp == fdip->pmp; scan1 = scan1->pip) {
1813                 scan2 = tdip;
1814                 while (scan2->pmp == tdip->pmp) {
1815                         if (scan1 == scan2) {
1816                                 hammer2_inode_ref(scan1);
1817                                 return(scan1);
1818                         }
1819                         scan2 = scan2->pip;
1820                         if (scan2 == NULL)
1821                                 break;
1822                 }
1823         }
1824         panic("hammer2_inode_common_parent: no common parent %p %p\n",
1825               fdip, tdip);
1826         /* NOT REACHED */
1827         return(NULL);
1828 }
1829
1830 /*
1831  * Synchronize the inode's frontend state with the chain state prior
1832  * to any explicit flush of the inode or any strategy write call.
1833  *
1834  * Called with a locked inode.
1835  */
1836 void
1837 hammer2_inode_fsync(hammer2_trans_t *trans, hammer2_inode_t *ip, 
1838                     hammer2_cluster_t *cparent)
1839 {
1840         const hammer2_inode_data_t *ripdata;
1841         hammer2_inode_data_t *wipdata;
1842         hammer2_cluster_t *dparent;
1843         hammer2_cluster_t *cluster;
1844         hammer2_key_t lbase;
1845         hammer2_key_t key_next;
1846         int dosync = 0;
1847         int ddflag;
1848
1849         ripdata = &hammer2_cluster_data(cparent)->ipdata;    /* target file */
1850
1851         if (ip->flags & HAMMER2_INODE_MTIME) {
1852                 wipdata = hammer2_cluster_modify_ip(trans, ip, cparent, 0);
1853                 atomic_clear_int(&ip->flags, HAMMER2_INODE_MTIME);
1854                 wipdata->mtime = ip->mtime;
1855                 dosync = 1;
1856                 ripdata = wipdata;
1857         }
1858         if ((ip->flags & HAMMER2_INODE_RESIZED) && ip->size < ripdata->size) {
1859                 wipdata = hammer2_cluster_modify_ip(trans, ip, cparent, 0);
1860                 wipdata->size = ip->size;
1861                 dosync = 1;
1862                 ripdata = wipdata;
1863                 atomic_clear_int(&ip->flags, HAMMER2_INODE_RESIZED);
1864
1865                 /*
1866                  * We must delete any chains beyond the EOF.  The chain
1867                  * straddling the EOF will be pending in the bioq.
1868                  */
1869                 lbase = (ripdata->size + HAMMER2_PBUFMASK64) &
1870                         ~HAMMER2_PBUFMASK64;
1871                 dparent = hammer2_cluster_lookup_init(&ip->cluster, 0);
1872                 cluster = hammer2_cluster_lookup(dparent, &key_next,
1873                                                  lbase, (hammer2_key_t)-1,
1874                                                  HAMMER2_LOOKUP_NODATA,
1875                                                  &ddflag);
1876                 while (cluster) {
1877                         /*
1878                          * Degenerate embedded case, nothing to loop on
1879                          */
1880                         switch (hammer2_cluster_type(cluster)) {
1881                         case HAMMER2_BREF_TYPE_INODE:
1882                                 hammer2_cluster_unlock(cluster);
1883                                 cluster = NULL;
1884                                 break;
1885                         case HAMMER2_BREF_TYPE_DATA:
1886                                 hammer2_cluster_delete(trans, cluster, 0);
1887                                 /* fall through */
1888                         default:
1889                                 cluster = hammer2_cluster_next(dparent, cluster,
1890                                                    &key_next,
1891                                                    key_next, (hammer2_key_t)-1,
1892                                                    HAMMER2_LOOKUP_NODATA);
1893                                 break;
1894                         }
1895                 }
1896                 hammer2_cluster_lookup_done(dparent);
1897         } else
1898         if ((ip->flags & HAMMER2_INODE_RESIZED) && ip->size > ripdata->size) {
1899                 wipdata = hammer2_cluster_modify_ip(trans, ip, cparent, 0);
1900                 wipdata->size = ip->size;
1901                 atomic_clear_int(&ip->flags, HAMMER2_INODE_RESIZED);
1902
1903                 /*
1904                  * When resizing larger we may not have any direct-data
1905                  * available.
1906                  */
1907                 if ((wipdata->op_flags & HAMMER2_OPFLAG_DIRECTDATA) &&
1908                     ip->size > HAMMER2_EMBEDDED_BYTES) {
1909                         wipdata->op_flags &= ~HAMMER2_OPFLAG_DIRECTDATA;
1910                         bzero(&wipdata->u.blockset,
1911                               sizeof(wipdata->u.blockset));
1912                 }
1913                 dosync = 1;
1914                 ripdata = wipdata;
1915         }
1916         if (dosync)
1917                 hammer2_cluster_modsync(cparent);
1918 }