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