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