2 * Copyright (c) 2011-2012 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@dragonflybsd.org>
6 * by Venkatesh Srinivas <vsrinivas@dragonflybsd.org>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
18 * 3. Neither the name of The DragonFly Project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific, prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/cdefs.h>
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/types.h>
45 * Adding a ref to an inode is only legal if the inode already has at least
49 hammer2_inode_ref(hammer2_inode_t *ip)
51 atomic_add_int(&ip->refs, 1);
55 * Drop an inode reference, freeing the inode when the last reference goes
59 hammer2_inode_drop(hammer2_inode_t *ip)
63 hammer2_chain_t *chain;
70 if (atomic_cmpset_int(&ip->refs, 1, 0)) {
71 KKASSERT(ip->topo_cst.count == 0);
80 hammer2_chain_drop(hmp, chain);
83 * We have to drop pip (if non-NULL) to
84 * dispose of our implied reference from
85 * ip->pip. We can simply loop on it.
87 kfree(ip, hmp->minode);
94 if (atomic_cmpset_int(&ip->refs, refs, refs - 1))
101 * Get the vnode associated with the given inode, allocating the vnode if
102 * necessary. The vnode will be returned exclusively locked.
104 * The caller must lock the inode (shared or exclusive).
106 * Great care must be taken to avoid deadlocks and vnode acquisition/reclaim
110 hammer2_igetv(hammer2_inode_t *ip, int *errorp)
112 hammer2_inode_data_t *ipdata;
113 hammer2_pfsmount_t *pmp;
118 KKASSERT(pmp != NULL);
120 ipdata = &ip->chain->data->ipdata;
124 * Attempt to reuse an existing vnode assignment. It is
125 * possible to race a reclaim so the vget() may fail. The
126 * inode must be unlocked during the vget() to avoid a
127 * deadlock against a reclaim.
132 * Inode must be unlocked during the vget() to avoid
133 * possible deadlocks, but leave the ip ref intact.
135 * vnode is held to prevent destruction during the
136 * vget(). The vget() can still fail if we lost
137 * a reclaim race on the vnode.
139 vhold_interlocked(vp);
140 ostate = hammer2_inode_lock_temp_release(ip);
141 if (vget(vp, LK_EXCLUSIVE)) {
143 hammer2_inode_lock_restore(ip, ostate);
146 hammer2_inode_lock_restore(ip, ostate);
148 /* vp still locked and ref from vget */
150 kprintf("hammer2: igetv race %p/%p\n",
160 * No vnode exists, allocate a new vnode. Beware of
161 * allocation races. This function will return an
162 * exclusively locked and referenced vnode.
164 *errorp = getnewvnode(VT_HAMMER2, pmp->mp, &vp, 0, 0);
166 kprintf("hammer2: igetv getnewvnode failed %d\n",
173 * Lock the inode and check for an allocation race.
175 ostate = hammer2_inode_lock_upgrade(ip);
176 if (ip->vp != NULL) {
179 hammer2_inode_lock_restore(ip, ostate);
183 switch (ipdata->type) {
184 case HAMMER2_OBJTYPE_DIRECTORY:
187 case HAMMER2_OBJTYPE_REGFILE:
189 vinitvmio(vp, ipdata->size,
191 (int)ipdata->size & HAMMER2_LBUFMASK);
193 case HAMMER2_OBJTYPE_SOFTLINK:
195 * XXX for now we are using the generic file_read
196 * and file_write code so we need a buffer cache
200 vinitvmio(vp, ipdata->size,
202 (int)ipdata->size & HAMMER2_LBUFMASK);
206 panic("hammer2: unhandled objtype %d", ipdata->type);
210 if (ip == pmp->iroot)
211 vsetflags(vp, VROOT);
215 hammer2_inode_ref(ip); /* vp association */
216 hammer2_inode_lock_restore(ip, ostate);
221 * Return non-NULL vp and *errorp == 0, or NULL vp and *errorp != 0.
223 if (hammer2_debug & 0x0002) {
224 kprintf("igetv vp %p refs %d aux %d\n",
225 vp, vp->v_sysref.refcnt, vp->v_auxrefs);
231 * The passed-in chain must be locked and the returned inode will also be
232 * locked. A ref is added to both the chain and the inode.
234 * The hammer2_inode structure regulates the interface between the high level
235 * kernel VNOPS API and the filesystem backend (the chains).
237 * NOTE! This routine allocates the hammer2_inode structure
238 * unconditionally, and thus there might be several which
239 * are associated with the same chain. Particularly for hardlinks
240 * but this can also happen temporarily for normal files and
243 * WARNING! This routine sucks up the chain's lock (makes it part of the
244 * inode lock from the point of view of the inode lock API),
245 * so callers need to be careful.
247 * WARNING! The mount code is allowed to pass dip == NULL for iroot and
248 * is allowed to pass pmp == NULL and dip == NULL for sroot.
251 hammer2_inode_get(hammer2_mount_t *hmp, hammer2_pfsmount_t *pmp,
252 hammer2_inode_t *dip, hammer2_chain_t *chain)
254 hammer2_inode_t *nip;
256 KKASSERT(chain->bref.type == HAMMER2_BREF_TYPE_INODE);
258 nip = kmalloc(sizeof(*nip), hmp->minode, M_WAITOK | M_ZERO);
261 hammer2_chain_ref(hmp, chain); /* nip->chain */
262 nip->pip = dip; /* can be NULL */
264 hammer2_inode_ref(dip); /* ref dip for nip->pip */
270 * ref and lock on nip gives it state compatible to after a
271 * hammer2_inode_lock_ex() call.
274 ccms_cst_init(&nip->topo_cst, &nip->chain);
275 ccms_thread_lock(&nip->topo_cst, CCMS_STATE_EXCLUSIVE);
276 /* combination of thread lock and chain lock == inode lock */
282 * Put away an inode, disconnecting it from its chain. The inode must be
283 * exclusively locked.
285 * The inode will be unlocked by this function. Note however that any related
286 * chain returned by the hammer2_inode_lock_*() call will NOT be unlocked
287 * by this function. The related chain is dropped to undo the ref that
288 * hammer2_inode_get() put on it.
290 * passed_chain is unlocked normally and does not have to be directly
291 * associated with (ip). This is simply so the API works the same as
292 * the hammer2_inode_unlock_ex() API. NULL is ok.
295 hammer2_inode_put(hammer2_inode_t *ip, hammer2_chain_t *passed_chain)
297 hammer2_mount_t *hmp = ip->hmp;
298 hammer2_inode_t *pip;
299 hammer2_chain_t *chain;
304 if ((chain = ip->chain) != NULL) {
306 hammer2_chain_drop(hmp, chain); /* from *_get() */
308 KKASSERT(ip->topo_cst.count == -1); /* one excl lock allowed */
313 if ((pip = ip->pip) != NULL) {
315 hammer2_inode_drop(pip);
319 * clean up the ip, we use an inode_unlock_ex-compatible API.
321 hammer2_inode_unlock_ex(ip, passed_chain);
325 * Create a new inode in the specified directory using the vattr to
326 * figure out the type of inode.
328 * If no error occurs the new inode with its chain locked is returned in
329 * *nipp, otherwise an error is returned and *nipp is set to NULL.
331 * If vap and/or cred are NULL the related fields are not set and the
332 * inode type defaults to a directory. This is used when creating PFSs
333 * under the super-root, so the inode number is set to 1 in this case.
335 * dip is not locked on entry.
338 hammer2_inode_create(hammer2_inode_t *dip,
339 struct vattr *vap, struct ucred *cred,
340 const uint8_t *name, size_t name_len,
341 hammer2_inode_t **nipp, hammer2_chain_t **nchainp)
343 hammer2_inode_data_t *nipdata;
344 hammer2_mount_t *hmp;
345 hammer2_chain_t *chain;
346 hammer2_chain_t *parent;
347 hammer2_inode_t *nip;
356 lhc = hammer2_dirhash(name, name_len);
359 * Locate the inode or indirect block to create the new
360 * entry in. At the same time check for key collisions
361 * and iterate until we don't get one.
364 parent = hammer2_inode_lock_ex(dip);
366 dip_uid = parent->data->ipdata.uid;
367 dip_gid = parent->data->ipdata.gid;
368 dip_mode = parent->data->ipdata.mode;
372 chain = hammer2_chain_lookup(hmp, &parent, lhc, lhc, 0);
375 if ((lhc & HAMMER2_DIRHASH_VISIBLE) == 0)
377 if ((lhc & HAMMER2_DIRHASH_LOMASK) == HAMMER2_DIRHASH_LOMASK)
379 hammer2_chain_unlock(hmp, chain);
384 chain = hammer2_chain_create(hmp, parent, NULL, lhc, 0,
385 HAMMER2_BREF_TYPE_INODE,
390 hammer2_inode_unlock_ex(dip, parent);
393 * Handle the error case
396 KKASSERT(chain == NULL);
397 if (error == EAGAIN) {
398 hammer2_chain_wait(hmp, parent);
407 * Set up the new inode.
409 * NOTE: *_get() integrates chain's lock into the inode lock.
411 nip = hammer2_inode_get(dip->hmp, dip->pmp, dip, chain);
414 nipdata = &chain->data->ipdata;
416 hammer2_voldata_lock(hmp);
418 nipdata->type = hammer2_get_obj_type(vap->va_type);
419 nipdata->inum = hmp->voldata.alloc_tid++;
420 /* XXX modify/lock */
422 nipdata->type = HAMMER2_OBJTYPE_DIRECTORY;
425 hammer2_voldata_unlock(hmp);
426 nipdata->version = HAMMER2_INODE_VERSION_ONE;
427 hammer2_update_time(&nipdata->ctime);
428 nipdata->mtime = nipdata->ctime;
430 nipdata->mode = vap->va_mode;
434 xuid = hammer2_to_unix_xid(&dip_uid);
435 xuid = vop_helper_create_uid(dip->pmp->mp,
443 if (vap->va_vaflags & VA_UID_UUID_VALID)
444 nipdata->uid = vap->va_uid_uuid;
445 else if (vap->va_uid != (uid_t)VNOVAL)
446 hammer2_guid_to_uuid(&nipdata->uid, vap->va_uid);
448 hammer2_guid_to_uuid(&nipdata->uid, xuid);
450 if (vap->va_vaflags & VA_GID_UUID_VALID)
451 nipdata->gid = vap->va_gid_uuid;
452 else if (vap->va_gid != (gid_t)VNOVAL)
453 hammer2_guid_to_uuid(&nipdata->gid, vap->va_gid);
455 nipdata->gid = dip_gid;
459 * Regular files and softlinks allow a small amount of data to be
460 * directly embedded in the inode. This flag will be cleared if
461 * the size is extended past the embedded limit.
463 if (nipdata->type == HAMMER2_OBJTYPE_REGFILE ||
464 nipdata->type == HAMMER2_OBJTYPE_SOFTLINK) {
465 nipdata->op_flags |= HAMMER2_OPFLAG_DIRECTDATA;
468 KKASSERT(name_len < HAMMER2_INODE_MAXNAME);
469 bcopy(name, nipdata->filename, name_len);
470 nipdata->name_key = lhc;
471 nipdata->name_len = name_len;
477 * Create a duplicate of the inode (chain) in the specified target directory
478 * (dip), return the duplicated chain in *nchainp (locked). chain is locked
479 * on call and remains locked on return.
481 * If name is NULL the inode is duplicated as a hidden directory entry.
483 * XXX name needs to be NULL for now.
486 hammer2_inode_duplicate(hammer2_inode_t *dip,
487 hammer2_chain_t *ochain, hammer2_chain_t **nchainp)
489 hammer2_inode_data_t *nipdata;
490 hammer2_mount_t *hmp;
491 hammer2_chain_t *parent;
492 hammer2_chain_t *chain;
497 lhc = ochain->data->ipdata.inum;
499 KKASSERT((lhc & HAMMER2_DIRHASH_VISIBLE) == 0);
502 * Locate the inode or indirect block to create the new
505 * There should be no key collisions with invisible inode keys.
509 hammer2_chain_lock(hmp, parent, HAMMER2_RESOLVE_ALWAYS);
510 chain = hammer2_chain_lookup(hmp, &parent, lhc, lhc, 0);
512 hammer2_chain_unlock(hmp, chain);
518 * Create entry in common parent directory.
521 chain = hammer2_chain_create(hmp, parent, NULL, lhc, 0,
522 HAMMER2_BREF_TYPE_INODE, /* n/a */
523 HAMMER2_INODE_BYTES, /* n/a */
528 * Clean up, but we need to retain a ref on parent so we can wait
529 * on it for certain errors.
532 hammer2_chain_ref(hmp, parent);
533 hammer2_chain_unlock(hmp, parent);
536 * Handle the error case
539 KKASSERT(chain == NULL);
540 if (error == EAGAIN) {
541 hammer2_chain_wait(hmp, parent);
542 hammer2_chain_drop(hmp, parent);
549 * XXX This is currently a horrible hack. Well, if we wanted to
550 * duplicate a file, i.e. as in a snapshot, we definitely
551 * would have to flush it first.
553 * For hardlink target generation we can theoretically move any
554 * active chain structures without flushing, but that gets really
555 * iffy for code which follows chain->parent and ip->pip links.
557 * XXX only works with files. Duplicating a directory hierarchy
558 * requires a flush but doesn't deal with races post-flush.
559 * Well, it would work I guess, but you might catch some files
562 * We cannot leave ochain with any in-memory chains because (for a
563 * hardlink), ochain will become a OBJTYPE_HARDLINK which is just a
564 * pointer to the real hardlink's inum and can't have any sub-chains.
565 * XXX might be 0-ref chains left.
567 hammer2_chain_flush(hmp, ochain, 0);
568 /*KKASSERT(RB_EMPTY(&ochain.rbhead));*/
570 hammer2_chain_modify(hmp, chain, 0);
571 nipdata = &chain->data->ipdata;
572 *nipdata = ochain->data->ipdata;
575 * Directory entries are inodes but this is a hidden hardlink
576 * target. The name isn't used but to ease debugging give it
577 * a name after its inode number.
579 ksnprintf(nipdata->filename, sizeof(nipdata->filename),
580 "0x%016jx", (intmax_t)nipdata->inum);
581 nipdata->name_len = strlen(nipdata->filename);
582 nipdata->name_key = lhc;
590 * Connect *chainp to the media topology represented by (dip, name, len).
591 * A directory entry is created which points to *chainp. *chainp is then
592 * unlocked and set to NULL.
594 * If *chainp is not currently connected we simply connect it up.
596 * If *chainp is already connected we create a OBJTYPE_HARDLINK entry which
597 * points to chain's inode number. *chainp is expected to be the terminus of
598 * the hardlink sitting as a hidden file in a common parent directory
601 * The caller always wants to reference the hardlink terminus, not the
602 * hardlink pointer that we might be creating, so we do NOT replace
603 * *chainp here, we simply unlock and NULL it out.
606 hammer2_inode_connect(hammer2_inode_t *dip, hammer2_chain_t **chainp,
607 const uint8_t *name, size_t name_len)
609 hammer2_inode_data_t *ipdata;
610 hammer2_mount_t *hmp;
611 hammer2_chain_t *nchain;
612 hammer2_chain_t *parent;
613 hammer2_chain_t *ochain;
624 * Since ochain is either disconnected from the topology or represents
625 * a hardlink terminus which is always a parent of or equal to dip,
626 * we should be able to safely lock dip->chain for our setup.
630 hammer2_chain_lock(hmp, parent, HAMMER2_RESOLVE_ALWAYS);
632 lhc = hammer2_dirhash(name, name_len);
633 hlink = (ochain->parent != NULL);
636 * In fake mode flush oip so we can just snapshot it downbelow.
638 if (hlink && hammer2_hardlink_enable < 0)
639 hammer2_chain_flush(hmp, ochain, 0);
642 * Locate the inode or indirect block to create the new
643 * entry in. At the same time check for key collisions
644 * and iterate until we don't get one.
648 nchain = hammer2_chain_lookup(hmp, &parent, lhc, lhc, 0);
651 if ((lhc & HAMMER2_DIRHASH_LOMASK) == HAMMER2_DIRHASH_LOMASK)
653 hammer2_chain_unlock(hmp, nchain);
659 * Passing a non-NULL chain to hammer2_chain_create() reconnects the
660 * existing chain instead of creating a new one. The chain's bref
661 * will be properly updated.
665 nchain = hammer2_chain_create(hmp, parent,
667 HAMMER2_BREF_TYPE_INODE,
672 * NOTE: reconnects oip->chain to the media
673 * topology and returns its argument
676 * No additional locks or refs are obtained on
677 * the returned chain so don't double-unlock!
679 nchain = hammer2_chain_create(hmp, parent,
681 HAMMER2_BREF_TYPE_INODE,
688 * Unlock stuff. This is a bit messy, if we have an EAGAIN error
689 * we need to wait for operations on parent to finish.
692 hammer2_chain_ref(hmp, parent);
693 hammer2_chain_unlock(hmp, parent);
696 * ochain still active.
698 * Handle the error case
701 KKASSERT(nchain == NULL);
702 if (error == EAGAIN) {
703 hammer2_chain_wait(hmp, parent);
704 hammer2_chain_drop(hmp, parent);
707 hammer2_chain_unlock(hmp, ochain);
712 * Directory entries are inodes so if the name has changed we have
713 * to update the inode.
715 * When creating an OBJTYPE_HARDLINK entry remember to unlock the
716 * chain, the caller will access the hardlink via the actual hardlink
717 * target file and not the hardlink pointer entry.
719 if (hlink && hammer2_hardlink_enable >= 0) {
721 * Create the HARDLINK pointer. oip represents the hardlink
722 * target in this situation.
724 * NOTE: *_get() integrates chain's lock into the inode lock.
726 hammer2_chain_modify(hmp, nchain, 0);
727 KKASSERT(name_len < HAMMER2_INODE_MAXNAME);
728 ipdata = &nchain->data->ipdata;
729 bcopy(name, ipdata->filename, name_len);
730 ipdata->name_key = lhc;
731 ipdata->name_len = name_len;
732 ipdata->target_type = ochain->data->ipdata.type;
733 ipdata->type = HAMMER2_OBJTYPE_HARDLINK;
734 ipdata->inum = ochain->data->ipdata.inum;
736 kprintf("created hardlink %*.*s\n",
737 (int)name_len, (int)name_len, name);
738 hammer2_chain_unlock(hmp, nchain);
739 } else if (hlink && hammer2_hardlink_enable < 0) {
741 * Create a snapshot (hardlink fake mode for debugging).
743 * NOTE: *_get() integrates nchain's lock into the inode lock.
745 hammer2_chain_modify(hmp, nchain, 0);
746 KKASSERT(name_len < HAMMER2_INODE_MAXNAME);
747 ipdata = &nchain->data->ipdata;
748 *ipdata = ochain->data->ipdata;
749 bcopy(name, ipdata->filename, name_len);
750 ipdata->name_key = lhc;
751 ipdata->name_len = name_len;
752 kprintf("created fake hardlink %*.*s\n",
753 (int)name_len, (int)name_len, name);
754 hammer2_chain_unlock(hmp, nchain);
757 * Normally disconnected inode (e.g. during a rename) that
758 * was reconnected. We must fixup the name stored in
761 * We are using oip as chain, already locked by caller,
764 hammer2_chain_modify(hmp, ochain, 0);
765 ipdata = &ochain->data->ipdata;
767 if (ipdata->name_len != name_len ||
768 bcmp(ipdata->filename, name, name_len) != 0) {
769 KKASSERT(name_len < HAMMER2_INODE_MAXNAME);
770 bcopy(name, ipdata->filename, name_len);
771 ipdata->name_key = lhc;
772 ipdata->name_len = name_len;
776 hammer2_chain_unlock(hmp, ochain);
781 * Unlink the file from the specified directory inode. The directory inode
782 * does not need to be locked. The caller should pass a non-NULL (ip)
783 * representing the object being removed only if the related vnode is
784 * potentially inactive (not referenced in the caller's active path),
785 * so we can vref/vrele it to trigger the VOP_INACTIVE path and properly
788 * isdir determines whether a directory/non-directory check should be made.
789 * No check is made if isdir is set to -1.
791 * If retain_chain is non-NULL this function can fail with an EAGAIN if it
792 * catches the object in the middle of a flush.
795 hammer2_unlink_file(hammer2_inode_t *dip,
796 const uint8_t *name, size_t name_len,
797 int isdir, hammer2_chain_t *retain_chain)
799 hammer2_inode_data_t *ipdata;
800 hammer2_mount_t *hmp;
801 hammer2_chain_t *parent;
802 hammer2_chain_t *ochain;
803 hammer2_chain_t *chain;
804 hammer2_chain_t *dparent;
805 hammer2_chain_t *dchain;
815 lhc = hammer2_dirhash(name, name_len);
818 * Search for the filename in the directory
820 parent = hammer2_inode_lock_ex(dip);
821 chain = hammer2_chain_lookup(hmp, &parent,
822 lhc, lhc + HAMMER2_DIRHASH_LOMASK,
825 if (chain->bref.type == HAMMER2_BREF_TYPE_INODE &&
826 name_len == chain->data->ipdata.name_len &&
827 bcmp(name, chain->data->ipdata.filename, name_len) == 0) {
830 chain = hammer2_chain_next(hmp, &parent, chain,
831 lhc, lhc + HAMMER2_DIRHASH_LOMASK,
834 hammer2_inode_unlock_ex(dip, NULL); /* retain parent */
837 * Not found or wrong type (isdir < 0 disables the type check).
838 * If a hardlink pointer, type checks use the hardlink target.
844 if ((type = chain->data->ipdata.type) == HAMMER2_OBJTYPE_HARDLINK)
845 type = chain->data->ipdata.target_type;
847 if (type == HAMMER2_OBJTYPE_DIRECTORY && isdir == 0) {
851 if (type != HAMMER2_OBJTYPE_DIRECTORY && isdir == 1) {
857 * Hardlink must be resolved. We can't hold parent locked while we
858 * do this or we could deadlock.
860 * On success chain will be adjusted to point at the hardlink target
861 * and ochain will point to the hardlink pointer in the original
862 * directory. Otherwise chain remains pointing to the original.
864 if (chain->data->ipdata.type == HAMMER2_OBJTYPE_HARDLINK) {
865 KKASSERT(parent_ref == 0);
866 hammer2_chain_unlock(hmp, parent);
868 error = hammer2_hardlink_find(dip, &chain, &ochain);
872 * If this is a directory the directory must be empty. However, if
873 * isdir < 0 we are doing a rename and the directory does not have
876 * NOTE: We check the full key range here which covers both visible
877 * and invisible entries. Theoretically there should be no
878 * invisible (hardlink target) entries if there are no visible
881 if (type == HAMMER2_OBJTYPE_DIRECTORY && isdir >= 0) {
883 hammer2_chain_lock(hmp, dparent, HAMMER2_RESOLVE_ALWAYS);
884 dchain = hammer2_chain_lookup(hmp, &dparent,
885 0, (hammer2_key_t)-1,
886 HAMMER2_LOOKUP_NODATA);
888 hammer2_chain_unlock(hmp, dchain);
889 hammer2_chain_unlock(hmp, dparent);
893 hammer2_chain_unlock(hmp, dparent);
899 * Ok, we can now unlink the chain. We always decrement nlinks even
900 * if the entry can be deleted in case someone has the file open and
903 * The chain itself will no longer be in the on-media topology but
904 * can still be flushed to the media (e.g. if an open descriptor
905 * remains). When the last vnode/ip ref goes away the chain will
906 * be marked unmodified, avoiding any further (now unnecesary) I/O.
908 * A non-NULL ochain indicates a hardlink.
912 * Delete the original hardlink pointer.
914 * NOTE: parent from above is NULL when ochain != NULL
915 * so we can reuse it.
917 hammer2_chain_lock(hmp, ochain, HAMMER2_RESOLVE_ALWAYS);
920 parent = ochain->parent;
921 hammer2_chain_ref(hmp, parent);
922 hammer2_chain_unlock(hmp, ochain);
923 hammer2_chain_lock(hmp, parent, HAMMER2_RESOLVE_ALWAYS);
924 hammer2_chain_lock(hmp, ochain, HAMMER2_RESOLVE_ALWAYS);
925 if (ochain->parent == parent)
927 hammer2_chain_unlock(hmp, parent);
928 hammer2_chain_drop(hmp, parent);
931 if (ochain == retain_chain && ochain->flushing) {
932 hammer2_chain_unlock(hmp, ochain);
936 hammer2_chain_delete(hmp, parent, ochain,
937 (ochain == retain_chain));
938 hammer2_chain_unlock(hmp, ochain);
939 hammer2_chain_unlock(hmp, parent);
940 hammer2_chain_drop(hmp, parent);
944 * Then decrement nlinks on hardlink target, deleting
945 * the target when nlinks drops to 0.
947 if (chain->data->ipdata.nlinks == 1) {
948 dparent = chain->parent;
949 hammer2_chain_ref(hmp, chain);
950 hammer2_chain_unlock(hmp, chain);
951 hammer2_chain_lock(hmp, dparent,
952 HAMMER2_RESOLVE_ALWAYS);
953 hammer2_chain_lock(hmp, chain,
954 HAMMER2_RESOLVE_ALWAYS);
955 hammer2_chain_drop(hmp, chain);
956 hammer2_chain_modify(hmp, chain, 0);
957 --chain->data->ipdata.nlinks;
958 hammer2_chain_delete(hmp, dparent, chain, 0);
959 hammer2_chain_unlock(hmp, dparent);
961 hammer2_chain_modify(hmp, chain, 0);
962 --chain->data->ipdata.nlinks;
966 * Otherwise this was not a hardlink and we can just
967 * remove the entry and decrement nlinks.
969 * NOTE: *_get() integrates chain's lock into the inode lock.
971 ipdata = &chain->data->ipdata;
972 if (chain == retain_chain && chain->flushing) {
976 hammer2_chain_modify(hmp, chain, 0);
978 hammer2_chain_delete(hmp, parent, chain,
979 (retain_chain == chain));
985 hammer2_chain_unlock(hmp, chain);
987 hammer2_chain_unlock(hmp, parent);
989 hammer2_chain_drop(hmp, parent);
992 hammer2_chain_drop(hmp, ochain);
998 * Calculate the allocation size for the file fragment straddling EOF
1001 hammer2_inode_calc_alloc(hammer2_key_t filesize)
1003 int frag = (int)filesize & HAMMER2_PBUFMASK;
1008 for (radix = HAMMER2_MINALLOCRADIX; frag > (1 << radix); ++radix)
1014 * Given an unlocked ip consolidate for hardlink creation, adding (nlinks)
1015 * to the file's link count and potentially relocating the file to a
1016 * directory common to ip->pip and tdip.
1018 * If the file has to be relocated ip->chain will also be adjusted.
1021 hammer2_hardlink_consolidate(hammer2_inode_t *ip, hammer2_chain_t **chainp,
1022 hammer2_inode_t *tdip, int nlinks)
1024 hammer2_inode_data_t *ipdata;
1025 hammer2_mount_t *hmp;
1026 hammer2_inode_t *fdip;
1027 hammer2_inode_t *cdip;
1028 hammer2_chain_t *chain;
1029 hammer2_chain_t *nchain;
1030 hammer2_chain_t *parent;
1035 chain = hammer2_inode_lock_ex(ip);
1037 if (nlinks == 0 && /* no hardlink needed */
1038 (chain->data->ipdata.name_key & HAMMER2_DIRHASH_VISIBLE)) {
1039 hammer2_inode_unlock_ex(ip, NULL);
1043 if (hammer2_hardlink_enable < 0) { /* fake hardlinks */
1044 hammer2_inode_unlock_ex(ip, NULL);
1048 if (hammer2_hardlink_enable == 0) { /* disallow hardlinks */
1049 hammer2_inode_unlock_ex(ip, chain);
1054 * cdip will be returned with a ref, but not locked.
1057 cdip = hammer2_inode_common_parent(hmp, fdip, tdip);
1060 * If no change in the hardlink's target directory is required and
1061 * this is already a hardlink target, all we need to do is adjust
1065 (chain->data->ipdata.name_key & HAMMER2_DIRHASH_VISIBLE) == 0) {
1067 hammer2_chain_modify(hmp, chain, 0);
1068 chain->data->ipdata.nlinks += nlinks;
1076 * We either have to move an existing hardlink target or we have
1077 * to create a fresh hardlink target.
1079 * Hardlink targets are hidden inodes in a parent directory common
1080 * to all directory entries referencing the hardlink.
1082 error = hammer2_inode_duplicate(cdip, chain, &nchain);
1085 * Bump nlinks on duplicated hidden inode.
1087 hammer2_chain_modify(hmp, nchain, 0);
1088 nchain->data->ipdata.nlinks += nlinks;
1091 * If the old chain is not a hardlink target then replace
1092 * it with a OBJTYPE_HARDLINK pointer.
1094 * If the old chain IS a hardlink target then delete it.
1096 if (chain->data->ipdata.name_key & HAMMER2_DIRHASH_VISIBLE) {
1097 hammer2_chain_modify(hmp, chain, 0);
1098 ipdata = &chain->data->ipdata;
1099 ipdata->target_type = ipdata->type;
1100 ipdata->type = HAMMER2_OBJTYPE_HARDLINK;
1108 bzero(&ipdata->uid, sizeof(ipdata->uid));
1109 bzero(&ipdata->gid, sizeof(ipdata->gid));
1110 ipdata->op_flags = HAMMER2_OPFLAG_DIRECTDATA;
1111 ipdata->cap_flags = 0;
1115 ipdata->iparent = 0; /* XXX */
1116 ipdata->pfs_type = 0;
1117 ipdata->pfs_inum = 0;
1118 bzero(&ipdata->pfs_clid, sizeof(ipdata->pfs_clid));
1119 bzero(&ipdata->pfs_fsid, sizeof(ipdata->pfs_fsid));
1120 ipdata->data_quota = 0;
1121 ipdata->data_count = 0;
1122 ipdata->inode_quota = 0;
1123 ipdata->inode_count = 0;
1124 ipdata->attr_tid = 0;
1125 ipdata->dirent_tid = 0;
1126 bzero(&ipdata->u, sizeof(ipdata->u));
1127 /* XXX transaction ids */
1129 kprintf("DELETE INVISIBLE\n");
1131 parent = chain->parent;
1132 hammer2_chain_ref(hmp, parent);
1133 hammer2_chain_ref(hmp, chain);
1134 hammer2_chain_unlock(hmp, chain);
1135 hammer2_chain_lock(hmp, parent,
1136 HAMMER2_RESOLVE_ALWAYS);
1137 hammer2_chain_lock(hmp, chain,
1138 HAMMER2_RESOLVE_ALWAYS);
1139 hammer2_chain_drop(hmp, chain);
1140 if (chain->parent == parent)
1142 hammer2_chain_unlock(hmp, parent);
1143 hammer2_chain_drop(hmp, parent);
1145 hammer2_chain_delete(hmp, parent, chain, 0);
1146 hammer2_chain_unlock(hmp, parent);
1147 hammer2_chain_drop(hmp, parent);
1151 * Replace ip->chain with nchain (ip is still locked).
1153 hammer2_chain_ref(hmp, nchain); /* ip->chain */
1155 hammer2_chain_drop(hmp, ip->chain); /* ip->chain */
1158 hammer2_chain_unlock(hmp, chain);
1161 hammer2_chain_unlock(hmp, chain);
1165 * Cleanup, chain/nchain already dealt with.
1168 hammer2_inode_unlock_ex(ip, NULL);
1169 hammer2_inode_drop(cdip);
1175 * If (*ochainp) is non-NULL it points to the forward OBJTYPE_HARDLINK
1176 * inode while (*chainp) points to the resolved (hidden hardlink
1177 * target) inode. In this situation when nlinks is 1 we wish to
1178 * deconsolidate the hardlink, moving it back to the directory that now
1179 * represents the only remaining link.
1182 hammer2_hardlink_deconsolidate(hammer2_inode_t *dip,
1183 hammer2_chain_t **chainp,
1184 hammer2_chain_t **ochainp)
1186 if (*ochainp == NULL)
1193 * The caller presents a locked *chainp pointing to a HAMMER2_BREF_TYPE_INODE
1194 * with an obj_type of HAMMER2_OBJTYPE_HARDLINK. This routine will gobble
1195 * the *chainp and return a new locked *chainp representing the file target
1196 * (the original *chainp will be unlocked).
1198 * When a match is found the chain representing the original HARDLINK
1199 * will be returned in *ochainp with a ref, but not locked.
1201 * When no match is found *chainp is set to NULL and EIO is returned.
1202 * (*ochainp) will still be set to the original chain with a ref but not
1206 hammer2_hardlink_find(hammer2_inode_t *dip, hammer2_chain_t **chainp,
1207 hammer2_chain_t **ochainp)
1209 hammer2_mount_t *hmp = dip->hmp;
1210 hammer2_chain_t *chain = *chainp;
1211 hammer2_chain_t *parent;
1212 hammer2_inode_t *ip;
1213 hammer2_inode_t *pip;
1217 hammer2_inode_ref(pip); /* for loop */
1218 hammer2_chain_ref(hmp, chain); /* for (*ochainp) */
1223 * Locate the hardlink. pip is referenced and not locked,
1228 lhc = chain->data->ipdata.inum;
1229 hammer2_chain_unlock(hmp, chain);
1232 while ((ip = pip) != NULL) {
1233 parent = hammer2_inode_lock_ex(ip);
1234 hammer2_inode_drop(ip); /* loop */
1235 KKASSERT(parent->bref.type == HAMMER2_BREF_TYPE_INODE);
1236 chain = hammer2_chain_lookup(hmp, &parent, lhc, lhc, 0);
1237 hammer2_chain_unlock(hmp, parent);
1240 pip = ip->pip; /* safe, ip held locked */
1242 hammer2_inode_ref(pip); /* loop */
1243 hammer2_inode_unlock_ex(ip, NULL);
1247 * chain is locked, ip is locked. Unlock ip, return the locked
1248 * chain. *ipp is already set w/a ref count and not locked.
1250 * (parent is already unlocked).
1252 hammer2_inode_unlock_ex(ip, NULL);
1255 KKASSERT(chain->bref.type == HAMMER2_BREF_TYPE_INODE);
1256 /* already locked */
1264 * Find the directory common to both fdip and tdip, hold and return
1268 hammer2_inode_common_parent(hammer2_mount_t *hmp,
1269 hammer2_inode_t *fdip, hammer2_inode_t *tdip)
1271 hammer2_inode_t *scan1;
1272 hammer2_inode_t *scan2;
1275 * We used to have a depth field but it complicated matters too
1276 * much for directory renames. So now its ugly. Check for
1277 * simple cases before giving up and doing it the expensive way.
1279 * XXX need a bottom-up topology stability lock
1281 if (fdip == tdip || fdip == tdip->pip) {
1282 hammer2_inode_ref(fdip);
1285 if (fdip->pip == tdip) {
1286 hammer2_inode_ref(tdip);
1293 for (scan1 = fdip; scan1->pmp == fdip->pmp; scan1 = scan1->pip) {
1295 while (scan2->pmp == tdip->pmp) {
1296 if (scan1 == scan2) {
1297 hammer2_inode_ref(scan1);
1303 panic("hammer2_inode_common_parent: no common parent %p %p\n",