1 /* 2 * Copyright (c) 2011-2014 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@dragonflybsd.org> 6 * by Venkatesh Srinivas <vsrinivas@dragonflybsd.org> 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 3. Neither the name of The DragonFly Project nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific, prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 32 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 #include <sys/cdefs.h> 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/types.h> 39 #include <sys/lock.h> 40 #include <sys/uuid.h> 41 42 #include "hammer2.h" 43 44 #define INODE_DEBUG 0 45 46 static void hammer2_inode_move_to_hidden(hammer2_trans_t *trans, 47 hammer2_cluster_t **cparentp, 48 hammer2_cluster_t **clusterp, 49 hammer2_tid_t inum); 50 51 RB_GENERATE2(hammer2_inode_tree, hammer2_inode, rbnode, hammer2_inode_cmp, 52 hammer2_tid_t, meta.inum); 53 54 int 55 hammer2_inode_cmp(hammer2_inode_t *ip1, hammer2_inode_t *ip2) 56 { 57 if (ip1->meta.inum < ip2->meta.inum) 58 return(-1); 59 if (ip1->meta.inum > ip2->meta.inum) 60 return(1); 61 return(0); 62 } 63 64 /* 65 * HAMMER2 inode locks 66 * 67 * HAMMER2 offers shared and exclusive locks on inodes. Pass a mask of 68 * flags for options: 69 * 70 * - pass HAMMER2_RESOLVE_SHARED if a shared lock is desired. The 71 * inode locking function will automatically set the RDONLY flag. 72 * 73 * - pass HAMMER2_RESOLVE_ALWAYS if you need the inode's meta-data. 74 * Most front-end inode locks do. 75 * 76 * - pass HAMMER2_RESOLVE_NEVER if you do not want to require that 77 * the inode data be resolved. This is used by the syncthr because 78 * it can run on an unresolved/out-of-sync cluster, and also by the 79 * vnode reclamation code to avoid unnecessary I/O (particularly when 80 * disposing of hundreds of thousands of cached vnodes). 81 * 82 * The inode locking function locks the inode itself, resolves any stale 83 * chains in the inode's cluster, and allocates a fresh copy of the 84 * cluster with 1 ref and all the underlying chains locked. 85 * 86 * ip->cluster will be stable while the inode is locked. 87 * 88 * NOTE: We don't combine the inode/chain lock because putting away an 89 * inode would otherwise confuse multiple lock holders of the inode. 90 * 91 * NOTE: In-memory inodes always point to hardlink targets (the actual file), 92 * and never point to a hardlink pointer. 93 * 94 * NOTE: If caller passes HAMMER2_RESOLVE_RDONLY the exclusive locking code 95 * will feel free to reduce the chain set in the cluster as an 96 * optimization. It will still be validated against the quorum if 97 * appropriate, but the optimization might be able to reduce data 98 * accesses to one node. This flag is automatically set if the inode 99 * is locked with HAMMER2_RESOLVE_SHARED. 100 */ 101 void 102 hammer2_inode_lock(hammer2_inode_t *ip, int how) 103 { 104 hammer2_inode_ref(ip); 105 106 /* 107 * Inode structure mutex 108 */ 109 if (how & HAMMER2_RESOLVE_SHARED) { 110 /*how |= HAMMER2_RESOLVE_RDONLY; not used */ 111 hammer2_mtx_sh(&ip->lock); 112 } else { 113 hammer2_mtx_ex(&ip->lock); 114 } 115 } 116 117 /* 118 * Create a locked copy of ip->cluster. Note that the copy will have a 119 * ref on the cluster AND its chains and we don't want a second ref to 120 * either when we lock it. 121 * 122 * Exclusive inode locks set the template focus chain in (ip) 123 * as a hint. Cluster locks can ALWAYS replace the focus in the 124 * working copy if the hint does not work out, so beware. 125 */ 126 hammer2_cluster_t * 127 hammer2_inode_cluster(hammer2_inode_t *ip, int how) 128 { 129 hammer2_cluster_t *cluster; 130 131 cluster = hammer2_cluster_copy(&ip->cluster); 132 hammer2_cluster_lock(cluster, how); 133 hammer2_cluster_resolve(cluster); 134 135 /* 136 * cluster->focus will be set if resolving RESOLVE_ALWAYS, but 137 * only update the cached focus in the inode structure when taking 138 * out an exclusive lock. 139 */ 140 if ((how & HAMMER2_RESOLVE_SHARED) == 0) 141 ip->cluster.focus = cluster->focus; 142 143 return cluster; 144 } 145 146 void 147 hammer2_inode_unlock(hammer2_inode_t *ip, hammer2_cluster_t *cluster) 148 { 149 if (cluster) { 150 hammer2_cluster_unlock(cluster); 151 hammer2_cluster_drop(cluster); 152 } 153 hammer2_mtx_unlock(&ip->lock); 154 hammer2_inode_drop(ip); 155 } 156 157 /* 158 * Temporarily release a lock held shared or exclusive. Caller must 159 * hold the lock shared or exclusive on call and lock will be released 160 * on return. 161 * 162 * Restore a lock that was temporarily released. 163 */ 164 hammer2_mtx_state_t 165 hammer2_inode_lock_temp_release(hammer2_inode_t *ip) 166 { 167 return hammer2_mtx_temp_release(&ip->lock); 168 } 169 170 void 171 hammer2_inode_lock_temp_restore(hammer2_inode_t *ip, hammer2_mtx_state_t ostate) 172 { 173 hammer2_mtx_temp_restore(&ip->lock, ostate); 174 } 175 176 /* 177 * Upgrade a shared inode lock to exclusive and return. If the inode lock 178 * is already held exclusively this is a NOP. 179 * 180 * The caller MUST hold the inode lock either shared or exclusive on call 181 * and will own the lock exclusively on return. 182 * 183 * Returns non-zero if the lock was already exclusive prior to the upgrade. 184 */ 185 int 186 hammer2_inode_lock_upgrade(hammer2_inode_t *ip) 187 { 188 int wasexclusive; 189 190 if (mtx_islocked_ex(&ip->lock)) { 191 wasexclusive = 1; 192 } else { 193 hammer2_mtx_unlock(&ip->lock); 194 hammer2_mtx_ex(&ip->lock); 195 wasexclusive = 0; 196 } 197 return wasexclusive; 198 } 199 200 /* 201 * Downgrade an inode lock from exclusive to shared only if the inode 202 * lock was previously shared. If the inode lock was previously exclusive, 203 * this is a NOP. 204 */ 205 void 206 hammer2_inode_lock_downgrade(hammer2_inode_t *ip, int wasexclusive) 207 { 208 if (wasexclusive == 0) 209 mtx_downgrade(&ip->lock); 210 } 211 212 /* 213 * Lookup an inode by inode number 214 */ 215 hammer2_inode_t * 216 hammer2_inode_lookup(hammer2_pfs_t *pmp, hammer2_tid_t inum) 217 { 218 hammer2_inode_t *ip; 219 220 KKASSERT(pmp); 221 if (pmp->spmp_hmp) { 222 ip = NULL; 223 } else { 224 hammer2_spin_ex(&pmp->inum_spin); 225 ip = RB_LOOKUP(hammer2_inode_tree, &pmp->inum_tree, inum); 226 if (ip) 227 hammer2_inode_ref(ip); 228 hammer2_spin_unex(&pmp->inum_spin); 229 } 230 return(ip); 231 } 232 233 /* 234 * Adding a ref to an inode is only legal if the inode already has at least 235 * one ref. 236 * 237 * (can be called with spinlock held) 238 */ 239 void 240 hammer2_inode_ref(hammer2_inode_t *ip) 241 { 242 atomic_add_int(&ip->refs, 1); 243 } 244 245 /* 246 * Drop an inode reference, freeing the inode when the last reference goes 247 * away. 248 */ 249 void 250 hammer2_inode_drop(hammer2_inode_t *ip) 251 { 252 hammer2_pfs_t *pmp; 253 hammer2_inode_t *pip; 254 u_int refs; 255 256 while (ip) { 257 refs = ip->refs; 258 cpu_ccfence(); 259 if (refs == 1) { 260 /* 261 * Transition to zero, must interlock with 262 * the inode inumber lookup tree (if applicable). 263 * It should not be possible for anyone to race 264 * the transition to 0. 265 * 266 */ 267 pmp = ip->pmp; 268 KKASSERT(pmp); 269 hammer2_spin_ex(&pmp->inum_spin); 270 271 if (atomic_cmpset_int(&ip->refs, 1, 0)) { 272 KKASSERT(hammer2_mtx_refs(&ip->lock) == 0); 273 if (ip->flags & HAMMER2_INODE_ONRBTREE) { 274 atomic_clear_int(&ip->flags, 275 HAMMER2_INODE_ONRBTREE); 276 RB_REMOVE(hammer2_inode_tree, 277 &pmp->inum_tree, ip); 278 } 279 hammer2_spin_unex(&pmp->inum_spin); 280 281 pip = ip->pip; 282 ip->pip = NULL; 283 ip->pmp = NULL; 284 285 /* 286 * Cleaning out ip->cluster isn't entirely 287 * trivial. 288 */ 289 hammer2_inode_repoint(ip, NULL, NULL); 290 291 /* 292 * We have to drop pip (if non-NULL) to 293 * dispose of our implied reference from 294 * ip->pip. We can simply loop on it. 295 */ 296 kfree(ip, pmp->minode); 297 atomic_add_long(&pmp->inmem_inodes, -1); 298 ip = pip; 299 /* continue with pip (can be NULL) */ 300 } else { 301 hammer2_spin_unex(&ip->pmp->inum_spin); 302 } 303 } else { 304 /* 305 * Non zero transition 306 */ 307 if (atomic_cmpset_int(&ip->refs, refs, refs - 1)) 308 break; 309 } 310 } 311 } 312 313 /* 314 * Get the vnode associated with the given inode, allocating the vnode if 315 * necessary. The vnode will be returned exclusively locked. 316 * 317 * The caller must lock the inode (shared or exclusive). 318 * 319 * Great care must be taken to avoid deadlocks and vnode acquisition/reclaim 320 * races. 321 */ 322 struct vnode * 323 hammer2_igetv(hammer2_inode_t *ip, hammer2_cluster_t *cparent, int *errorp) 324 { 325 const hammer2_inode_data_t *ripdata; 326 hammer2_pfs_t *pmp; 327 struct vnode *vp; 328 329 pmp = ip->pmp; 330 KKASSERT(pmp != NULL); 331 *errorp = 0; 332 333 ripdata = &hammer2_cluster_rdata(cparent)->ipdata; 334 335 for (;;) { 336 /* 337 * Attempt to reuse an existing vnode assignment. It is 338 * possible to race a reclaim so the vget() may fail. The 339 * inode must be unlocked during the vget() to avoid a 340 * deadlock against a reclaim. 341 */ 342 int wasexclusive; 343 344 vp = ip->vp; 345 if (vp) { 346 /* 347 * Inode must be unlocked during the vget() to avoid 348 * possible deadlocks, but leave the ip ref intact. 349 * 350 * vnode is held to prevent destruction during the 351 * vget(). The vget() can still fail if we lost 352 * a reclaim race on the vnode. 353 */ 354 hammer2_mtx_state_t ostate; 355 356 vhold(vp); 357 ostate = hammer2_inode_lock_temp_release(ip); 358 if (vget(vp, LK_EXCLUSIVE)) { 359 vdrop(vp); 360 hammer2_inode_lock_temp_restore(ip, ostate); 361 continue; 362 } 363 hammer2_inode_lock_temp_restore(ip, ostate); 364 vdrop(vp); 365 /* vp still locked and ref from vget */ 366 if (ip->vp != vp) { 367 kprintf("hammer2: igetv race %p/%p\n", 368 ip->vp, vp); 369 vput(vp); 370 continue; 371 } 372 *errorp = 0; 373 break; 374 } 375 376 /* 377 * No vnode exists, allocate a new vnode. Beware of 378 * allocation races. This function will return an 379 * exclusively locked and referenced vnode. 380 */ 381 *errorp = getnewvnode(VT_HAMMER2, pmp->mp, &vp, 0, 0); 382 if (*errorp) { 383 kprintf("hammer2: igetv getnewvnode failed %d\n", 384 *errorp); 385 vp = NULL; 386 break; 387 } 388 389 /* 390 * Lock the inode and check for an allocation race. 391 */ 392 wasexclusive = hammer2_inode_lock_upgrade(ip); 393 if (ip->vp != NULL) { 394 vp->v_type = VBAD; 395 vx_put(vp); 396 hammer2_inode_lock_downgrade(ip, wasexclusive); 397 continue; 398 } 399 400 switch (ripdata->meta.type) { 401 case HAMMER2_OBJTYPE_DIRECTORY: 402 vp->v_type = VDIR; 403 break; 404 case HAMMER2_OBJTYPE_REGFILE: 405 vp->v_type = VREG; 406 vinitvmio(vp, ripdata->meta.size, 407 HAMMER2_LBUFSIZE, 408 (int)ripdata->meta.size & HAMMER2_LBUFMASK); 409 break; 410 case HAMMER2_OBJTYPE_SOFTLINK: 411 /* 412 * XXX for now we are using the generic file_read 413 * and file_write code so we need a buffer cache 414 * association. 415 */ 416 vp->v_type = VLNK; 417 vinitvmio(vp, ripdata->meta.size, 418 HAMMER2_LBUFSIZE, 419 (int)ripdata->meta.size & HAMMER2_LBUFMASK); 420 break; 421 case HAMMER2_OBJTYPE_CDEV: 422 vp->v_type = VCHR; 423 /* fall through */ 424 case HAMMER2_OBJTYPE_BDEV: 425 vp->v_ops = &pmp->mp->mnt_vn_spec_ops; 426 if (ripdata->meta.type != HAMMER2_OBJTYPE_CDEV) 427 vp->v_type = VBLK; 428 addaliasu(vp, 429 ripdata->meta.rmajor, 430 ripdata->meta.rminor); 431 break; 432 case HAMMER2_OBJTYPE_FIFO: 433 vp->v_type = VFIFO; 434 vp->v_ops = &pmp->mp->mnt_vn_fifo_ops; 435 break; 436 default: 437 panic("hammer2: unhandled objtype %d", 438 ripdata->meta.type); 439 break; 440 } 441 442 if (ip == pmp->iroot) 443 vsetflags(vp, VROOT); 444 445 vp->v_data = ip; 446 ip->vp = vp; 447 hammer2_inode_ref(ip); /* vp association */ 448 hammer2_inode_lock_downgrade(ip, wasexclusive); 449 break; 450 } 451 452 /* 453 * Return non-NULL vp and *errorp == 0, or NULL vp and *errorp != 0. 454 */ 455 if (hammer2_debug & 0x0002) { 456 kprintf("igetv vp %p refs 0x%08x aux 0x%08x\n", 457 vp, vp->v_refcnt, vp->v_auxrefs); 458 } 459 return (vp); 460 } 461 462 /* 463 * Returns the inode associated with the passed-in cluster, creating the 464 * inode if necessary and synchronizing it to the passed-in cluster otherwise. 465 * 466 * The passed-in cluster must be locked and will remain locked on return. 467 * The returned inode will be locked and the caller may dispose of both 468 * via hammer2_inode_unlock() + hammer2_inode_drop(). However, if the caller 469 * needs to resolve a hardlink it must ref/unlock/relock/drop the inode. 470 * 471 * The hammer2_inode structure regulates the interface between the high level 472 * kernel VNOPS API and the filesystem backend (the chains). 473 * 474 * On return the inode is locked with the supplied cluster. 475 */ 476 hammer2_inode_t * 477 hammer2_inode_get(hammer2_pfs_t *pmp, hammer2_inode_t *dip, 478 hammer2_cluster_t *cluster) 479 { 480 hammer2_inode_t *nip; 481 const hammer2_inode_data_t *iptmp; 482 const hammer2_inode_data_t *nipdata; 483 484 KKASSERT(cluster == NULL || 485 hammer2_cluster_type(cluster) == HAMMER2_BREF_TYPE_INODE); 486 KKASSERT(pmp); 487 488 /* 489 * Interlocked lookup/ref of the inode. This code is only needed 490 * when looking up inodes with nlinks != 0 (TODO: optimize out 491 * otherwise and test for duplicates). 492 * 493 * Cluster can be NULL during the initial pfs allocation. 494 */ 495 again: 496 while (cluster) { 497 iptmp = &hammer2_cluster_rdata(cluster)->ipdata; 498 nip = hammer2_inode_lookup(pmp, iptmp->meta.inum); 499 if (nip == NULL) 500 break; 501 502 hammer2_mtx_ex(&nip->lock); 503 504 /* 505 * Handle SMP race (not applicable to the super-root spmp 506 * which can't index inodes due to duplicative inode numbers). 507 */ 508 if (pmp->spmp_hmp == NULL && 509 (nip->flags & HAMMER2_INODE_ONRBTREE) == 0) { 510 hammer2_mtx_unlock(&nip->lock); 511 hammer2_inode_drop(nip); 512 continue; 513 } 514 hammer2_inode_repoint(nip, NULL, cluster); 515 516 return nip; 517 } 518 519 /* 520 * We couldn't find the inode number, create a new inode. 521 */ 522 nip = kmalloc(sizeof(*nip), pmp->minode, M_WAITOK | M_ZERO); 523 spin_init(&nip->cluster_spin, "h2clspin"); 524 atomic_add_long(&pmp->inmem_inodes, 1); 525 hammer2_pfs_memory_inc(pmp); 526 hammer2_pfs_memory_wakeup(pmp); 527 if (pmp->spmp_hmp) 528 nip->flags = HAMMER2_INODE_SROOT; 529 530 /* 531 * Initialize nip's cluster. A cluster is provided for normal 532 * inodes but typically not for the super-root or PFS inodes. 533 */ 534 nip->cluster.refs = 1; 535 nip->cluster.pmp = pmp; 536 nip->cluster.flags |= HAMMER2_CLUSTER_INODE; 537 if (cluster) { 538 nipdata = &hammer2_cluster_rdata(cluster)->ipdata; 539 nip->meta = nipdata->meta; 540 hammer2_cluster_bref(cluster, &nip->bref); 541 atomic_set_int(&nip->flags, HAMMER2_INODE_METAGOOD); 542 hammer2_inode_repoint(nip, NULL, cluster); 543 } else { 544 nip->meta.inum = 1; /* PFS inum is always 1 XXX */ 545 /* mtime will be updated when a cluster is available */ 546 atomic_set_int(&nip->flags, HAMMER2_INODE_METAGOOD);/*XXX*/ 547 } 548 549 nip->pip = dip; /* can be NULL */ 550 if (dip) 551 hammer2_inode_ref(dip); /* ref dip for nip->pip */ 552 553 nip->pmp = pmp; 554 555 /* 556 * ref and lock on nip gives it state compatible to after a 557 * hammer2_inode_lock() call. 558 */ 559 nip->refs = 1; 560 hammer2_mtx_init(&nip->lock, "h2inode"); 561 hammer2_mtx_ex(&nip->lock); 562 /* combination of thread lock and chain lock == inode lock */ 563 564 /* 565 * Attempt to add the inode. If it fails we raced another inode 566 * get. Undo all the work and try again. 567 */ 568 if (pmp->spmp_hmp == NULL) { 569 hammer2_spin_ex(&pmp->inum_spin); 570 if (RB_INSERT(hammer2_inode_tree, &pmp->inum_tree, nip)) { 571 hammer2_spin_unex(&pmp->inum_spin); 572 hammer2_mtx_unlock(&nip->lock); 573 hammer2_inode_drop(nip); 574 goto again; 575 } 576 atomic_set_int(&nip->flags, HAMMER2_INODE_ONRBTREE); 577 hammer2_spin_unex(&pmp->inum_spin); 578 } 579 580 return (nip); 581 } 582 583 /* 584 * Create a new inode in the specified directory using the vattr to 585 * figure out the type of inode. 586 * 587 * If no error occurs the new inode with its cluster locked is returned in 588 * *nipp, otherwise an error is returned and *nipp is set to NULL. 589 * 590 * If vap and/or cred are NULL the related fields are not set and the 591 * inode type defaults to a directory. This is used when creating PFSs 592 * under the super-root, so the inode number is set to 1 in this case. 593 * 594 * dip is not locked on entry. 595 * 596 * NOTE: When used to create a snapshot, the inode is temporarily associated 597 * with the super-root spmp. XXX should pass new pmp for snapshot. 598 */ 599 hammer2_inode_t * 600 hammer2_inode_create(hammer2_trans_t *trans, hammer2_inode_t *dip, 601 struct vattr *vap, struct ucred *cred, 602 const uint8_t *name, size_t name_len, 603 hammer2_cluster_t **clusterp, 604 int flags, int *errorp) 605 { 606 const hammer2_inode_data_t *dipdata; 607 hammer2_inode_data_t *nipdata; 608 hammer2_cluster_t *cluster; 609 hammer2_cluster_t *cparent; 610 hammer2_inode_t *nip; 611 hammer2_key_t key_dummy; 612 hammer2_key_t lhc; 613 int error; 614 uid_t xuid; 615 uuid_t dip_uid; 616 uuid_t dip_gid; 617 uint32_t dip_mode; 618 uint8_t dip_comp_algo; 619 uint8_t dip_check_algo; 620 621 lhc = hammer2_dirhash(name, name_len); 622 *errorp = 0; 623 624 /* 625 * Locate the inode or indirect block to create the new 626 * entry in. At the same time check for key collisions 627 * and iterate until we don't get one. 628 * 629 * NOTE: hidden inodes do not have iterators. 630 */ 631 retry: 632 hammer2_inode_lock(dip, HAMMER2_RESOLVE_ALWAYS); 633 cparent = hammer2_inode_cluster(dip, HAMMER2_RESOLVE_ALWAYS); 634 dipdata = &hammer2_cluster_rdata(cparent)->ipdata; 635 dip_uid = dipdata->meta.uid; 636 dip_gid = dipdata->meta.gid; 637 dip_mode = dipdata->meta.mode; 638 dip_comp_algo = dipdata->meta.comp_algo; 639 dip_check_algo = dipdata->meta.check_algo; 640 641 error = 0; 642 while (error == 0) { 643 cluster = hammer2_cluster_lookup(cparent, &key_dummy, 644 lhc, lhc, 0); 645 if (cluster == NULL) 646 break; 647 if ((lhc & HAMMER2_DIRHASH_VISIBLE) == 0) 648 error = ENOSPC; 649 if ((lhc & HAMMER2_DIRHASH_LOMASK) == HAMMER2_DIRHASH_LOMASK) 650 error = ENOSPC; 651 hammer2_cluster_unlock(cluster); 652 hammer2_cluster_drop(cluster); 653 cluster = NULL; 654 ++lhc; 655 } 656 657 if (error == 0) { 658 error = hammer2_cluster_create(trans, cparent, &cluster, 659 lhc, 0, 660 HAMMER2_BREF_TYPE_INODE, 661 HAMMER2_INODE_BYTES, 662 flags); 663 } 664 #if INODE_DEBUG 665 kprintf("CREATE INODE %*.*s chain=%p\n", 666 (int)name_len, (int)name_len, name, 667 (cluster ? cluster->focus : NULL)); 668 #endif 669 670 /* 671 * Cleanup and handle retries. 672 */ 673 if (error == EAGAIN) { 674 hammer2_cluster_ref(cparent); 675 hammer2_inode_unlock(dip, cparent); 676 hammer2_cluster_wait(cparent); 677 hammer2_cluster_drop(cparent); 678 goto retry; 679 } 680 hammer2_inode_unlock(dip, cparent); 681 cparent = NULL; 682 683 if (error) { 684 KKASSERT(cluster == NULL); 685 *errorp = error; 686 return (NULL); 687 } 688 689 /* 690 * Set up the new inode. 691 * 692 * NOTE: *_get() integrates chain's lock into the inode lock. 693 * 694 * NOTE: Only one new inode can currently be created per 695 * transaction. If the need arises we can adjust 696 * hammer2_trans_init() to allow more. 697 * 698 * NOTE: nipdata will have chain's blockset data. 699 */ 700 KKASSERT(cluster->focus->flags & HAMMER2_CHAIN_MODIFIED); 701 nipdata = &hammer2_cluster_wdata(cluster)->ipdata; 702 nipdata->meta.inum = trans->inode_tid; 703 hammer2_cluster_modsync(cluster); 704 nip = hammer2_inode_get(dip->pmp, dip, cluster); 705 nipdata = &hammer2_cluster_wdata(cluster)->ipdata; 706 707 if (vap) { 708 KKASSERT(trans->inodes_created == 0); 709 nipdata->meta.type = hammer2_get_obj_type(vap->va_type); 710 nipdata->meta.inum = trans->inode_tid; 711 ++trans->inodes_created; 712 713 switch (nipdata->meta.type) { 714 case HAMMER2_OBJTYPE_CDEV: 715 case HAMMER2_OBJTYPE_BDEV: 716 nipdata->meta.rmajor = vap->va_rmajor; 717 nipdata->meta.rminor = vap->va_rminor; 718 break; 719 default: 720 break; 721 } 722 } else { 723 nipdata->meta.type = HAMMER2_OBJTYPE_DIRECTORY; 724 nipdata->meta.inum = 1; 725 } 726 727 /* Inherit parent's inode compression mode. */ 728 nip->comp_heuristic = 0; 729 nipdata->meta.comp_algo = dip_comp_algo; 730 nipdata->meta.check_algo = dip_check_algo; 731 nipdata->meta.version = HAMMER2_INODE_VERSION_ONE; 732 hammer2_update_time(&nipdata->meta.ctime); 733 nipdata->meta.mtime = nipdata->meta.ctime; 734 if (vap) 735 nipdata->meta.mode = vap->va_mode; 736 nipdata->meta.nlinks = 1; 737 if (vap) { 738 if (dip && dip->pmp) { 739 xuid = hammer2_to_unix_xid(&dip_uid); 740 xuid = vop_helper_create_uid(dip->pmp->mp, 741 dip_mode, 742 xuid, 743 cred, 744 &vap->va_mode); 745 } else { 746 /* super-root has no dip and/or pmp */ 747 xuid = 0; 748 } 749 if (vap->va_vaflags & VA_UID_UUID_VALID) 750 nipdata->meta.uid = vap->va_uid_uuid; 751 else if (vap->va_uid != (uid_t)VNOVAL) 752 hammer2_guid_to_uuid(&nipdata->meta.uid, vap->va_uid); 753 else 754 hammer2_guid_to_uuid(&nipdata->meta.uid, xuid); 755 756 if (vap->va_vaflags & VA_GID_UUID_VALID) 757 nipdata->meta.gid = vap->va_gid_uuid; 758 else if (vap->va_gid != (gid_t)VNOVAL) 759 hammer2_guid_to_uuid(&nipdata->meta.gid, vap->va_gid); 760 else if (dip) 761 nipdata->meta.gid = dip_gid; 762 } 763 764 /* 765 * Regular files and softlinks allow a small amount of data to be 766 * directly embedded in the inode. This flag will be cleared if 767 * the size is extended past the embedded limit. 768 */ 769 if (nipdata->meta.type == HAMMER2_OBJTYPE_REGFILE || 770 nipdata->meta.type == HAMMER2_OBJTYPE_SOFTLINK) { 771 nipdata->meta.op_flags |= HAMMER2_OPFLAG_DIRECTDATA; 772 } 773 774 KKASSERT(name_len < HAMMER2_INODE_MAXNAME); 775 bcopy(name, nipdata->filename, name_len); 776 nipdata->meta.name_key = lhc; 777 nipdata->meta.name_len = name_len; 778 nip->meta = nipdata->meta; 779 hammer2_cluster_modsync(cluster); 780 *clusterp = cluster; 781 782 return (nip); 783 } 784 785 /* 786 * The cluster has been removed from the original directory and replaced 787 * with a hardlink pointer. Move the cluster to the specified parent 788 * directory, change the filename to "0xINODENUMBER", and adjust the key. 789 * The cluster becomes our invisible hardlink target. 790 * 791 * The original cluster must be deleted on entry. 792 */ 793 static 794 void 795 hammer2_hardlink_shiftup(hammer2_trans_t *trans, hammer2_cluster_t *cluster, 796 hammer2_inode_t *ip, hammer2_inode_t *dip, 797 hammer2_cluster_t *dcluster, 798 int nlinks, int *errorp) 799 { 800 const hammer2_inode_data_t *iptmp; 801 hammer2_inode_data_t *nipdata; 802 hammer2_cluster_t *xcluster; 803 hammer2_key_t key_dummy; 804 hammer2_key_t lhc; 805 hammer2_blockref_t bref; 806 807 iptmp = &hammer2_cluster_rdata(cluster)->ipdata; 808 lhc = iptmp->meta.inum; 809 KKASSERT((lhc & HAMMER2_DIRHASH_VISIBLE) == 0); 810 811 /* 812 * Locate the inode or indirect block to create the new 813 * entry in. lhc represents the inode number so there is 814 * no collision iteration. 815 * 816 * There should be no key collisions with invisible inode keys. 817 * 818 * WARNING! Must use inode_lock_ex() on dip to handle a stale 819 * dip->cluster cache. 820 */ 821 *errorp = 0; 822 xcluster = hammer2_cluster_lookup(dcluster, &key_dummy, 823 lhc, lhc, 0); 824 if (xcluster) { 825 kprintf("X3 chain %p dip %p dchain %p dip->chain %p\n", 826 xcluster->focus, dip, dcluster->focus, 827 dip->cluster.focus); 828 hammer2_cluster_unlock(xcluster); 829 hammer2_cluster_drop(xcluster); 830 xcluster = NULL; 831 *errorp = ENOSPC; 832 #if 0 833 Debugger("X3"); 834 #endif 835 } 836 837 /* 838 * Handle the error case 839 */ 840 if (*errorp) { 841 panic("error2"); 842 KKASSERT(xcluster == NULL); 843 return; 844 } 845 846 /* 847 * Use xcluster as a placeholder for (lhc). Duplicate cluster to the 848 * same target bref as xcluster and then delete xcluster. The 849 * duplication occurs after xcluster in flush order even though 850 * xcluster is deleted after the duplication. XXX 851 * 852 * WARNING! Duplications (to a different parent) can cause indirect 853 * blocks to be inserted, refactor xcluster. 854 * 855 * WARNING! Only key and keybits is extracted from a passed-in bref. 856 */ 857 hammer2_cluster_bref(cluster, &bref); 858 bref.key = lhc; /* invisible dir entry key */ 859 bref.keybits = 0; 860 hammer2_cluster_rename(trans, &bref, dcluster, cluster, 0); 861 862 /* 863 * cluster is now 'live' again.. adjust the filename. 864 * 865 * Directory entries are inodes but this is a hidden hardlink 866 * target. The name isn't used but to ease debugging give it 867 * a name after its inode number. 868 */ 869 hammer2_cluster_modify(trans, cluster, 0); 870 nipdata = &hammer2_cluster_wdata(cluster)->ipdata; 871 ksnprintf(nipdata->filename, sizeof(nipdata->filename), 872 "0x%016jx", (intmax_t)nipdata->meta.inum); 873 nipdata->meta.name_len = strlen(nipdata->filename); 874 nipdata->meta.name_key = lhc; 875 nipdata->meta.nlinks += nlinks; 876 877 /* 878 * Resync ip->meta. Some fields have to be retained. 879 */ 880 nipdata->meta.size = ip->meta.size; 881 nipdata->meta.mtime = ip->meta.mtime; 882 ip->meta = nipdata->meta; 883 884 hammer2_cluster_modsync(cluster); 885 } 886 887 /* 888 * Connect the target inode represented by (cluster) to the media topology 889 * at (dip, name, len). The caller can pass a rough *chainp, this function 890 * will issue lookup()s to position the parent chain properly for the 891 * chain insertion. 892 * 893 * If hlink is TRUE this function creates an OBJTYPE_HARDLINK directory 894 * entry instead of connecting (cluster). 895 * 896 * If hlink is FALSE this function expects (cluster) to be unparented. 897 */ 898 int 899 hammer2_inode_connect(hammer2_trans_t *trans, 900 hammer2_inode_t *ip, hammer2_cluster_t **clusterp, 901 int hlink, 902 hammer2_inode_t *dip, hammer2_cluster_t *dcluster, 903 const uint8_t *name, size_t name_len, 904 hammer2_key_t lhc) 905 { 906 hammer2_inode_data_t *wipdata; 907 hammer2_cluster_t *ocluster; 908 hammer2_cluster_t *ncluster; 909 hammer2_key_t key_dummy; 910 int error; 911 912 /* 913 * Since ocluster is either disconnected from the topology or 914 * represents a hardlink terminus which is always a parent of or 915 * equal to dip, we should be able to safely lock dip->chain for 916 * our setup. 917 * 918 * WARNING! Must use inode_lock_ex() on dip to handle a stale 919 * dip->cluster. 920 * 921 * If name is non-NULL we calculate lhc, else we use the passed-in 922 * lhc. 923 */ 924 ocluster = *clusterp; 925 926 if (name) { 927 lhc = hammer2_dirhash(name, name_len); 928 929 /* 930 * Locate the inode or indirect block to create the new 931 * entry in. At the same time check for key collisions 932 * and iterate until we don't get one. 933 */ 934 error = 0; 935 while (error == 0) { 936 ncluster = hammer2_cluster_lookup(dcluster, &key_dummy, 937 lhc, lhc, 0); 938 if (ncluster == NULL) 939 break; 940 if ((lhc & HAMMER2_DIRHASH_LOMASK) == 941 HAMMER2_DIRHASH_LOMASK) { 942 error = ENOSPC; 943 } 944 hammer2_cluster_unlock(ncluster); 945 hammer2_cluster_drop(ncluster); 946 ncluster = NULL; 947 ++lhc; 948 } 949 } else { 950 /* 951 * Reconnect to specific key (used when moving 952 * unlinked-but-open files into the hidden directory). 953 */ 954 ncluster = hammer2_cluster_lookup(dcluster, &key_dummy, 955 lhc, lhc, 0); 956 KKASSERT(ncluster == NULL); 957 error = 0; 958 } 959 960 if (error == 0) { 961 if (hlink) { 962 /* 963 * Hardlink pointer needed, create totally fresh 964 * directory entry. 965 * 966 * We must refactor ocluster because it might have 967 * been shifted into an indirect cluster by the 968 * create. 969 */ 970 KKASSERT(ncluster == NULL); 971 error = hammer2_cluster_create(trans, 972 dcluster, &ncluster, 973 lhc, 0, 974 HAMMER2_BREF_TYPE_INODE, 975 HAMMER2_INODE_BYTES, 976 0); 977 } else { 978 /* 979 * Reconnect the original cluster under the new name. 980 * Original cluster must have already been deleted by 981 * teh caller. 982 * 983 * WARNING! Can cause held-over clusters to require a 984 * refactor. Fortunately we have none (our 985 * locked clusters are passed into and 986 * modified by the call). 987 */ 988 ncluster = ocluster; 989 ocluster = NULL; 990 error = hammer2_cluster_create(trans, 991 dcluster, &ncluster, 992 lhc, 0, 993 HAMMER2_BREF_TYPE_INODE, 994 HAMMER2_INODE_BYTES, 995 0); 996 } 997 } 998 999 /* 1000 * Unlock stuff. 1001 */ 1002 KKASSERT(error != EAGAIN); 1003 1004 /* 1005 * ncluster should be NULL on error, leave ocluster 1006 * (ocluster == *clusterp) alone. 1007 */ 1008 if (error) { 1009 KKASSERT(ncluster == NULL); 1010 return (error); 1011 } 1012 1013 /* 1014 * Directory entries are inodes so if the name has changed we have 1015 * to update the inode. 1016 * 1017 * When creating an OBJTYPE_HARDLINK entry remember to unlock the 1018 * cluster, the caller will access the hardlink via the actual hardlink 1019 * target file and not the hardlink pointer entry, so we must still 1020 * return ocluster. 1021 */ 1022 if (hlink && hammer2_hardlink_enable >= 0) { 1023 /* 1024 * Create the HARDLINK pointer. oip represents the hardlink 1025 * target in this situation. 1026 * 1027 * We will return ocluster (the hardlink target). 1028 */ 1029 hammer2_cluster_modify(trans, ncluster, 0); 1030 KKASSERT(name_len < HAMMER2_INODE_MAXNAME); 1031 wipdata = &hammer2_cluster_wdata(ncluster)->ipdata; 1032 bcopy(name, wipdata->filename, name_len); 1033 wipdata->meta.name_key = lhc; 1034 wipdata->meta.name_len = name_len; 1035 wipdata->meta.target_type = 1036 hammer2_cluster_rdata(ocluster)->ipdata.meta.type; 1037 wipdata->meta.type = HAMMER2_OBJTYPE_HARDLINK; 1038 wipdata->meta.inum = 1039 hammer2_cluster_rdata(ocluster)->ipdata.meta.inum; 1040 wipdata->meta.version = HAMMER2_INODE_VERSION_ONE; 1041 wipdata->meta.nlinks = 1; 1042 wipdata->meta.op_flags = HAMMER2_OPFLAG_DIRECTDATA; 1043 hammer2_cluster_modsync(ncluster); 1044 hammer2_cluster_unlock(ncluster); 1045 hammer2_cluster_drop(ncluster); 1046 ncluster = ocluster; 1047 ocluster = NULL; 1048 } else { 1049 /* 1050 * ncluster is a duplicate of ocluster at the new location. 1051 * We must fixup the name stored in the inode data. 1052 * The bref key has already been adjusted by inode_connect(). 1053 */ 1054 hammer2_cluster_modify(trans, ncluster, 0); 1055 wipdata = &hammer2_cluster_wdata(ncluster)->ipdata; 1056 1057 KKASSERT(name_len < HAMMER2_INODE_MAXNAME); 1058 bcopy(name, wipdata->filename, name_len); 1059 wipdata->meta.name_key = lhc; 1060 wipdata->meta.name_len = name_len; 1061 wipdata->meta.nlinks = 1; 1062 hammer2_cluster_modsync(ncluster); 1063 1064 /* 1065 * Resync the in-memory inode, some fields must be retained. 1066 */ 1067 if (ip) { /* XXX move_to_hidden passes NULL */ 1068 wipdata->meta.size = ip->meta.size; 1069 wipdata->meta.mtime = ip->meta.mtime; 1070 ip->meta = wipdata->meta; 1071 } 1072 } 1073 1074 /* 1075 * We are replacing ocluster with ncluster, unlock ocluster. In the 1076 * case where ocluster is left unchanged the code above sets 1077 * ncluster to ocluster and ocluster to NULL, resulting in a NOP here. 1078 */ 1079 if (ocluster) { 1080 hammer2_cluster_unlock(ocluster); 1081 hammer2_cluster_drop(ocluster); 1082 } 1083 *clusterp = ncluster; 1084 1085 return (0); 1086 } 1087 1088 /* 1089 * Repoint ip->cluster's chains to cluster's chains and fixup the default 1090 * focus. Only valid elements are repointed. Invalid elements have to be 1091 * adjusted by the appropriate slave sync threads. 1092 * 1093 * Caller must hold the inode and cluster exclusive locked, if not NULL, 1094 * must also be locked. 1095 * 1096 * Cluster may be NULL to clean out any chains in ip->cluster. 1097 */ 1098 void 1099 hammer2_inode_repoint(hammer2_inode_t *ip, hammer2_inode_t *pip, 1100 hammer2_cluster_t *cluster) 1101 { 1102 hammer2_chain_t *dropch[HAMMER2_MAXCLUSTER]; 1103 hammer2_chain_t *ochain; 1104 hammer2_chain_t *nchain; 1105 hammer2_inode_t *opip; 1106 int i; 1107 1108 bzero(dropch, sizeof(dropch)); 1109 1110 /* 1111 * Replace chains in ip->cluster with chains from cluster and 1112 * adjust the focus if necessary. 1113 * 1114 * NOTE: nchain and/or ochain can be NULL due to gaps 1115 * in the cluster arrays. 1116 */ 1117 hammer2_spin_ex(&ip->cluster_spin); 1118 for (i = 0; cluster && i < cluster->nchains; ++i) { 1119 /* 1120 * Do not replace invalid elements as this might race 1121 * syncthr replacements. 1122 */ 1123 if (cluster->array[i].flags & HAMMER2_CITEM_INVALID) 1124 continue; 1125 1126 /* 1127 * Do not replace elements which are the same. Also handle 1128 * element count discrepancies. 1129 */ 1130 nchain = cluster->array[i].chain; 1131 if (i < ip->cluster.nchains) { 1132 ochain = ip->cluster.array[i].chain; 1133 if (ochain == nchain) 1134 continue; 1135 } else { 1136 ochain = NULL; 1137 } 1138 1139 /* 1140 * Make adjustments 1141 */ 1142 ip->cluster.array[i].chain = nchain; 1143 ip->cluster.array[i].flags &= ~HAMMER2_CITEM_INVALID; 1144 ip->cluster.array[i].flags |= cluster->array[i].flags & 1145 HAMMER2_CITEM_INVALID; 1146 if (nchain) 1147 hammer2_chain_ref(nchain); 1148 dropch[i] = ochain; 1149 } 1150 1151 /* 1152 * Release any left-over chains in ip->cluster. 1153 */ 1154 while (i < ip->cluster.nchains) { 1155 nchain = ip->cluster.array[i].chain; 1156 if (nchain) { 1157 ip->cluster.array[i].chain = NULL; 1158 ip->cluster.array[i].flags |= HAMMER2_CITEM_INVALID; 1159 } 1160 dropch[i] = nchain; 1161 ++i; 1162 } 1163 1164 /* 1165 * Fixup fields. Note that the inode-embedded cluster is never 1166 * directly locked. 1167 */ 1168 if (cluster) { 1169 ip->cluster.nchains = cluster->nchains; 1170 ip->cluster.focus = cluster->focus; 1171 ip->cluster.flags = cluster->flags & ~HAMMER2_CLUSTER_LOCKED; 1172 } else { 1173 ip->cluster.nchains = 0; 1174 ip->cluster.focus = NULL; 1175 ip->cluster.flags &= ~HAMMER2_CLUSTER_ZFLAGS; 1176 } 1177 1178 /* 1179 * Repoint ip->pip if requested (non-NULL pip). 1180 */ 1181 if (pip && ip->pip != pip) { 1182 opip = ip->pip; 1183 hammer2_inode_ref(pip); 1184 ip->pip = pip; 1185 } else { 1186 opip = NULL; 1187 } 1188 hammer2_spin_unex(&ip->cluster_spin); 1189 1190 /* 1191 * Cleanup outside of spinlock 1192 */ 1193 while (--i >= 0) { 1194 if (dropch[i]) 1195 hammer2_chain_drop(dropch[i]); 1196 } 1197 if (opip) 1198 hammer2_inode_drop(opip); 1199 } 1200 1201 /* 1202 * Repoint a single element from the cluster to the ip. Used by the 1203 * synchronization threads to piecemeal update inodes. Does not change 1204 * focus and requires inode to be re-locked to clean-up flags (XXX). 1205 */ 1206 void 1207 hammer2_inode_repoint_one(hammer2_inode_t *ip, hammer2_cluster_t *cluster, 1208 int idx) 1209 { 1210 hammer2_chain_t *ochain; 1211 hammer2_chain_t *nchain; 1212 int i; 1213 1214 hammer2_spin_ex(&ip->cluster_spin); 1215 KKASSERT(idx < cluster->nchains); 1216 if (idx < ip->cluster.nchains) { 1217 ochain = ip->cluster.array[idx].chain; 1218 nchain = cluster->array[idx].chain; 1219 } else { 1220 ochain = NULL; 1221 nchain = cluster->array[idx].chain; 1222 ip->cluster.nchains = idx + 1; 1223 for (i = ip->cluster.nchains; i <= idx; ++i) { 1224 bzero(&ip->cluster.array[i], 1225 sizeof(ip->cluster.array[i])); 1226 ip->cluster.array[i].flags |= HAMMER2_CITEM_INVALID; 1227 } 1228 } 1229 if (ochain != nchain) { 1230 /* 1231 * Make adjustments. 1232 */ 1233 ip->cluster.array[idx].chain = nchain; 1234 ip->cluster.array[idx].flags &= ~HAMMER2_CITEM_INVALID; 1235 ip->cluster.array[idx].flags |= cluster->array[idx].flags & 1236 HAMMER2_CITEM_INVALID; 1237 } 1238 hammer2_spin_unex(&ip->cluster_spin); 1239 if (ochain != nchain) { 1240 if (nchain) 1241 hammer2_chain_ref(nchain); 1242 if (ochain) 1243 hammer2_chain_drop(ochain); 1244 } 1245 } 1246 1247 /* 1248 * Unlink the file (dip, name, name_len), from the specified directory inode. 1249 * If the caller also has the hammer2_inode the caller must pass it locked as 1250 * (ip), but may pass NULL if it does not have the inode in hand. 1251 * 1252 * The directory inode does not need to be locked. 1253 * 1254 * isdir determines whether a directory/non-directory check should be made. 1255 * No check is made if isdir is set to -1. 1256 * 1257 * isopen specifies whether special unlink-with-open-descriptor handling 1258 * must be performed. If set to -1 the caller is deleting a PFS and we 1259 * check whether the chain is mounted or not (chain->pmp != NULL). 1 is 1260 * implied if it is mounted. 1261 * 1262 * If isopen is 1 and nlinks drops to 0 this function must move the chain 1263 * to a special hidden directory until last-close occurs on the file. 1264 * 1265 * NOTE! The underlying file can still be active with open descriptors 1266 * or if the inode is being manually held (e.g. for rename). 1267 * 1268 * NOTE! When unlinking an open file the inode will be temporarily moved to 1269 * a hidden directory, otherwise the inode will be deleted. 1270 */ 1271 int 1272 hammer2_unlink_file(hammer2_trans_t *trans, 1273 hammer2_inode_t *dip, hammer2_inode_t *ip, 1274 const uint8_t *name, size_t name_len, 1275 int isdir, int *hlinkp, struct nchandle *nch, 1276 int nlinks) 1277 { 1278 const hammer2_inode_data_t *ripdata; 1279 hammer2_cluster_t *cparent; 1280 hammer2_cluster_t *hcluster; 1281 hammer2_cluster_t *hparent; 1282 hammer2_cluster_t *cluster; 1283 hammer2_cluster_t *dparent; 1284 hammer2_cluster_t *dcluster; 1285 hammer2_key_t key_dummy; 1286 hammer2_key_t key_next; 1287 hammer2_key_t lhc; 1288 int last_link; 1289 int error; 1290 int hlink; 1291 int myip; 1292 uint8_t type; 1293 1294 error = 0; 1295 hlink = 0; 1296 myip = 0; 1297 hcluster = NULL; 1298 hparent = NULL; 1299 lhc = hammer2_dirhash(name, name_len); 1300 1301 again: 1302 /* 1303 * Locate the filename in the directory and instantiate the ip 1304 * if necessary. If the ip is already known we must still locate 1305 * the filename to adjust cparent for possible deletion. 1306 */ 1307 hammer2_inode_lock(dip, HAMMER2_RESOLVE_ALWAYS); 1308 cparent = hammer2_inode_cluster(dip, HAMMER2_RESOLVE_ALWAYS); 1309 cluster = hammer2_cluster_lookup(cparent, &key_next, 1310 lhc, lhc + HAMMER2_DIRHASH_LOMASK, 0); 1311 while (cluster) { 1312 if (hammer2_cluster_type(cluster) == HAMMER2_BREF_TYPE_INODE) { 1313 ripdata = &hammer2_cluster_rdata(cluster)->ipdata; 1314 if (ripdata->meta.name_len == name_len && 1315 bcmp(ripdata->filename, name, name_len) == 0) { 1316 break; 1317 } 1318 } 1319 cluster = hammer2_cluster_next(cparent, cluster, &key_next, 1320 key_next, 1321 lhc + HAMMER2_DIRHASH_LOMASK, 1322 0); 1323 } 1324 hammer2_inode_unlock(dip, NULL); /* retain cparent */ 1325 1326 /* 1327 * Not found or wrong type (isdir < 0 disables the type check). 1328 * If a hardlink pointer, type checks use the hardlink target. 1329 */ 1330 if (cluster == NULL) { 1331 error = ENOENT; 1332 goto done; 1333 } 1334 1335 ripdata = &hammer2_cluster_rdata(cluster)->ipdata; 1336 type = ripdata->meta.type; 1337 if (type == HAMMER2_OBJTYPE_HARDLINK) { 1338 hlink = 1; 1339 type = ripdata->meta.target_type; 1340 } 1341 1342 if (type == HAMMER2_OBJTYPE_DIRECTORY && isdir == 0) { 1343 error = ENOTDIR; 1344 goto done; 1345 } 1346 if (type != HAMMER2_OBJTYPE_DIRECTORY && isdir >= 1) { 1347 error = EISDIR; 1348 goto done; 1349 } 1350 1351 /* 1352 * Hardlink must be resolved. We can't hold the parent locked 1353 * while we do this or we could deadlock. The physical file will 1354 * be located at or above the current directory. 1355 * 1356 * We loop to reacquire the hardlink origination. 1357 * 1358 * NOTE: hammer2_hardlink_find() will locate the hardlink target, 1359 * returning a modified hparent and hcluster. 1360 */ 1361 if (ripdata->meta.type == HAMMER2_OBJTYPE_HARDLINK) { 1362 if (hcluster == NULL) { 1363 hcluster = cluster; 1364 cluster = NULL; /* safety */ 1365 hammer2_cluster_unlock(cparent); 1366 hammer2_cluster_drop(cparent); 1367 cparent = NULL; /* safety */ 1368 ripdata = NULL; /* safety (associated w/cparent) */ 1369 error = hammer2_hardlink_find(dip, &hparent, &hcluster); 1370 1371 /* 1372 * If we couldn't find the hardlink target then some 1373 * parent directory containing the hardlink pointer 1374 * probably got renamed to above the original target, 1375 * a case not yet handled by H2. 1376 */ 1377 if (error) { 1378 kprintf("H2 unlink_file: hardlink target for " 1379 "\"%s\" not found\n", 1380 name); 1381 kprintf("(likely due to known directory " 1382 "rename bug)\n"); 1383 goto done; 1384 } 1385 goto again; 1386 } 1387 } 1388 1389 /* 1390 * If this is a directory the directory must be empty. However, if 1391 * isdir < 0 we are doing a rename and the directory does not have 1392 * to be empty, and if isdir > 1 we are deleting a PFS/snapshot 1393 * and the directory does not have to be empty. 1394 * 1395 * NOTE: We check the full key range here which covers both visible 1396 * and invisible entries. Theoretically there should be no 1397 * invisible (hardlink target) entries if there are no visible 1398 * entries. 1399 */ 1400 if (type == HAMMER2_OBJTYPE_DIRECTORY && isdir == 1) { 1401 dparent = hammer2_cluster_lookup_init(cluster, 0); 1402 dcluster = hammer2_cluster_lookup(dparent, &key_dummy, 1403 0, (hammer2_key_t)-1, 1404 HAMMER2_LOOKUP_NODATA); 1405 if (dcluster) { 1406 hammer2_cluster_unlock(dcluster); 1407 hammer2_cluster_drop(dcluster); 1408 hammer2_cluster_lookup_done(dparent); 1409 error = ENOTEMPTY; 1410 goto done; 1411 } 1412 hammer2_cluster_lookup_done(dparent); 1413 dparent = NULL; 1414 /* dcluster NULL */ 1415 } 1416 1417 /* 1418 * If this was a hardlink then (cparent, cluster) is the hardlink 1419 * pointer, which we can simply destroy outright. Discard the 1420 * clusters and replace with the hardlink target. 1421 */ 1422 if (hcluster) { 1423 hammer2_cluster_delete(trans, cparent, cluster, 1424 HAMMER2_DELETE_PERMANENT); 1425 hammer2_cluster_unlock(cparent); 1426 hammer2_cluster_drop(cparent); 1427 hammer2_cluster_unlock(cluster); 1428 hammer2_cluster_drop(cluster); 1429 cparent = hparent; 1430 cluster = hcluster; 1431 hparent = NULL; 1432 hcluster = NULL; 1433 } 1434 1435 /* 1436 * This leaves us with the hardlink target or non-hardlinked file 1437 * or directory in (cparent, cluster). 1438 * 1439 * Delete the target when nlinks reaches 0 with special handling 1440 * to avoid I/O (to avoid actually updating the inode) for the 1->0 1441 * transition, if possible. This optimization makes rm -rf very 1442 * fast. 1443 * 1444 * NOTE! In DragonFly the vnops function calls cache_unlink() after 1445 * calling us here to clean out the namecache association, 1446 * (which does not represent a ref for the open-test), and to 1447 * force finalization of the vnode if/when the last ref gets 1448 * dropped. 1449 * 1450 * NOTE! Files are unlinked by rename and then relinked. nch will be 1451 * passed as NULL in this situation. hammer2_inode_connect() 1452 * will bump nlinks. 1453 */ 1454 KKASSERT(cluster != NULL); 1455 1456 /* 1457 * Instantiate ip if necessary for ip->meta data consolidation. 1458 */ 1459 if (ip == NULL) { 1460 ip = hammer2_inode_get(dip->pmp, dip, cluster); 1461 myip = 1; 1462 } 1463 1464 1465 /* 1466 * Note: nlinks is negative when decrementing, positive when 1467 * incrementing. 1468 */ 1469 last_link = (ip->meta.nlinks + nlinks == 0); 1470 1471 if (last_link) { 1472 /* 1473 * Target nlinks has reached 0, file now unlinked (but may 1474 * still be open). 1475 * 1476 * nlinks will be -1 for a normal remove(). If this is the 1477 * last link we must flag the inode so we can optimally 1478 * throw away buffer data and destroy the file on reclaim. 1479 */ 1480 if (nlinks == -1) 1481 atomic_set_int(&ip->flags, HAMMER2_INODE_ISUNLINKED); 1482 1483 if (nch && cache_isopen(nch)) { 1484 /* 1485 * If an unlinked file is still open we must update 1486 * the inodes link count. 1487 */ 1488 /*hammer2_cluster_modify(trans, cluster, 0);*/ 1489 hammer2_inode_modify(trans, ip); 1490 ip->meta.nlinks += nlinks; 1491 if ((int64_t)ip->meta.nlinks < 0) /* safety */ 1492 ip->meta.nlinks = 0; 1493 hammer2_inode_move_to_hidden(trans, &cparent, &cluster, 1494 ip->meta.inum); 1495 /* hammer2_cluster_modsync(cluster); */ 1496 } else { 1497 /* 1498 * This won't get everything if a vnode is still 1499 * present, but the cache_unlink() call the caller 1500 * makes will. 1501 */ 1502 hammer2_cluster_delete(trans, cparent, cluster, 1503 HAMMER2_DELETE_PERMANENT); 1504 } 1505 } else if (hlink == 0) { 1506 /* 1507 * In this situation a normal non-hardlinked file (which can 1508 * only have nlinks == 1) still has a non-zero nlinks, the 1509 * caller must be doing a RENAME operation and so is passing 1510 * a nlinks adjustment of 0, and only wishes to remove file 1511 * in order to be able to reconnect it under a different name. 1512 * 1513 * In this situation we do a temporary deletion of the 1514 * chain in order to allow the file to be reconnected in 1515 * a different location. 1516 */ 1517 KKASSERT(nlinks == 0); 1518 hammer2_cluster_delete(trans, cparent, cluster, 0); 1519 } else { 1520 /* 1521 * Links remain, must update the inode link count. 1522 */ 1523 /*hammer2_cluster_modify(trans, cluster, 0);*/ 1524 hammer2_inode_modify(trans, ip); 1525 ip->meta.nlinks += nlinks; 1526 if ((int64_t)ip->meta.nlinks < 0) 1527 ip->meta.nlinks = 0; 1528 /* hammer2_cluster_modsync(cluster); */ 1529 } 1530 1531 if (myip) { 1532 hammer2_inode_unlock(ip, NULL); 1533 } 1534 1535 error = 0; 1536 done: 1537 if (cparent) { 1538 hammer2_cluster_unlock(cparent); 1539 hammer2_cluster_drop(cparent); 1540 } 1541 if (cluster) { 1542 hammer2_cluster_unlock(cluster); 1543 hammer2_cluster_drop(cluster); 1544 } 1545 if (hparent) { 1546 hammer2_cluster_unlock(hparent); 1547 hammer2_cluster_drop(hparent); 1548 } 1549 if (hcluster) { 1550 hammer2_cluster_unlock(hcluster); 1551 hammer2_cluster_drop(hcluster); 1552 } 1553 if (hlinkp) 1554 *hlinkp = hlink; 1555 1556 return error; 1557 } 1558 1559 /* 1560 * This is called from the mount code to initialize pmp->ihidden 1561 */ 1562 void 1563 hammer2_inode_install_hidden(hammer2_pfs_t *pmp) 1564 { 1565 hammer2_trans_t trans; 1566 hammer2_cluster_t *cparent; 1567 hammer2_cluster_t *cluster; 1568 hammer2_cluster_t *scan; 1569 const hammer2_inode_data_t *ripdata; 1570 hammer2_inode_data_t *wipdata; 1571 hammer2_key_t key_dummy; 1572 hammer2_key_t key_next; 1573 int error; 1574 int count; 1575 int dip_check_algo; 1576 int dip_comp_algo; 1577 1578 if (pmp->ihidden) 1579 return; 1580 1581 /* 1582 * Find the hidden directory 1583 */ 1584 bzero(&key_dummy, sizeof(key_dummy)); 1585 hammer2_trans_init(&trans, pmp, 0); 1586 1587 /* 1588 * Setup for lookup, retrieve iroot's check and compression 1589 * algorithm request which was likely generated by newfs_hammer2. 1590 * 1591 * The check/comp fields will probably never be used since inodes 1592 * are renamed into the hidden directory and not created relative to 1593 * the hidden directory, chain creation inherits from bref.methods, 1594 * and data chains inherit from their respective file inode *_algo 1595 * fields. 1596 */ 1597 hammer2_inode_lock(pmp->iroot, HAMMER2_RESOLVE_ALWAYS); 1598 cparent = hammer2_inode_cluster(pmp->iroot, HAMMER2_RESOLVE_ALWAYS); 1599 ripdata = &hammer2_cluster_rdata(cparent)->ipdata; 1600 dip_check_algo = ripdata->meta.check_algo; 1601 dip_comp_algo = ripdata->meta.comp_algo; 1602 ripdata = NULL; 1603 1604 cluster = hammer2_cluster_lookup(cparent, &key_dummy, 1605 HAMMER2_INODE_HIDDENDIR, 1606 HAMMER2_INODE_HIDDENDIR, 1607 0); 1608 if (cluster) { 1609 pmp->ihidden = hammer2_inode_get(pmp, pmp->iroot, cluster); 1610 hammer2_inode_ref(pmp->ihidden); 1611 1612 /* 1613 * Remove any unlinked files which were left open as-of 1614 * any system crash. 1615 * 1616 * Don't pass NODATA, we need the inode data so the delete 1617 * can do proper statistics updates. 1618 */ 1619 count = 0; 1620 scan = hammer2_cluster_lookup(cluster, &key_next, 1621 0, HAMMER2_TID_MAX, 0); 1622 while (scan) { 1623 if (hammer2_cluster_type(scan) == 1624 HAMMER2_BREF_TYPE_INODE) { 1625 hammer2_cluster_delete(&trans, cluster, scan, 1626 HAMMER2_DELETE_PERMANENT); 1627 ++count; 1628 } 1629 scan = hammer2_cluster_next(cluster, scan, &key_next, 1630 0, HAMMER2_TID_MAX, 0); 1631 } 1632 1633 hammer2_inode_unlock(pmp->ihidden, cluster); 1634 hammer2_inode_unlock(pmp->iroot, cparent); 1635 hammer2_trans_done(&trans); 1636 kprintf("hammer2: PFS loaded hidden dir, " 1637 "removed %d dead entries\n", count); 1638 return; 1639 } 1640 1641 /* 1642 * Create the hidden directory 1643 */ 1644 error = hammer2_cluster_create(&trans, cparent, &cluster, 1645 HAMMER2_INODE_HIDDENDIR, 0, 1646 HAMMER2_BREF_TYPE_INODE, 1647 HAMMER2_INODE_BYTES, 1648 0); 1649 hammer2_inode_unlock(pmp->iroot, cparent); 1650 1651 hammer2_cluster_modify(&trans, cluster, 0); 1652 wipdata = &hammer2_cluster_wdata(cluster)->ipdata; 1653 wipdata->meta.type = HAMMER2_OBJTYPE_DIRECTORY; 1654 wipdata->meta.inum = HAMMER2_INODE_HIDDENDIR; 1655 wipdata->meta.nlinks = 1; 1656 wipdata->meta.comp_algo = dip_comp_algo; 1657 wipdata->meta.check_algo = dip_check_algo; 1658 hammer2_cluster_modsync(cluster); 1659 kprintf("hammer2: PFS root missing hidden directory, creating\n"); 1660 1661 pmp->ihidden = hammer2_inode_get(pmp, pmp->iroot, cluster); 1662 hammer2_inode_ref(pmp->ihidden); 1663 hammer2_inode_unlock(pmp->ihidden, cluster); 1664 hammer2_trans_done(&trans); 1665 } 1666 1667 /* 1668 * If an open file is unlinked H2 needs to retain the file in the topology 1669 * to ensure that its backing store is not recovered by the bulk free scan. 1670 * This also allows us to avoid having to special-case the CHAIN_DELETED flag. 1671 * 1672 * To do this the file is moved to a hidden directory in the PFS root and 1673 * renamed. The hidden directory must be created if it does not exist. 1674 */ 1675 static 1676 void 1677 hammer2_inode_move_to_hidden(hammer2_trans_t *trans, 1678 hammer2_cluster_t **cparentp, 1679 hammer2_cluster_t **clusterp, 1680 hammer2_tid_t inum) 1681 { 1682 hammer2_cluster_t *dcluster; 1683 hammer2_pfs_t *pmp; 1684 int error; 1685 1686 pmp = (*clusterp)->pmp; 1687 KKASSERT(pmp != NULL); 1688 KKASSERT(pmp->ihidden != NULL); 1689 1690 hammer2_cluster_delete(trans, *cparentp, *clusterp, 0); 1691 hammer2_inode_lock(pmp->ihidden, HAMMER2_RESOLVE_ALWAYS); 1692 dcluster = hammer2_inode_cluster(pmp->ihidden, HAMMER2_RESOLVE_ALWAYS); 1693 error = hammer2_inode_connect(trans, 1694 NULL/*XXX*/, clusterp, 0, 1695 pmp->ihidden, dcluster, 1696 NULL, 0, inum); 1697 hammer2_inode_unlock(pmp->ihidden, dcluster); 1698 KKASSERT(error == 0); 1699 } 1700 1701 /* 1702 * Given an exclusively locked inode and cluster we consolidate the cluster 1703 * for hardlink creation, adding (nlinks) to the file's link count and 1704 * potentially relocating the inode to (cdip) which is a parent directory 1705 * common to both the current location of the inode and the intended new 1706 * hardlink. 1707 * 1708 * Replaces (*clusterp) if consolidation occurred, unlocking the old cluster 1709 * and returning a new locked cluster. 1710 * 1711 * NOTE! This function will also replace ip->cluster. 1712 */ 1713 int 1714 hammer2_hardlink_consolidate(hammer2_trans_t *trans, 1715 hammer2_inode_t *ip, 1716 hammer2_cluster_t **clusterp, 1717 hammer2_inode_t *cdip, 1718 hammer2_cluster_t *cdcluster, 1719 int nlinks) 1720 { 1721 hammer2_cluster_t *cluster; 1722 hammer2_cluster_t *cparent; 1723 int error; 1724 1725 cluster = *clusterp; 1726 if (nlinks == 0 && /* no hardlink needed */ 1727 (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE)) { 1728 return (0); 1729 } 1730 1731 if (hammer2_hardlink_enable == 0) { /* disallow hardlinks */ 1732 hammer2_cluster_unlock(cluster); 1733 hammer2_cluster_drop(cluster); 1734 *clusterp = NULL; 1735 return (ENOTSUP); 1736 } 1737 1738 cparent = NULL; 1739 1740 /* 1741 * If no change in the hardlink's target directory is required and 1742 * this is already a hardlink target, all we need to do is adjust 1743 * the link count. 1744 */ 1745 if (cdip == ip->pip && 1746 (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE) == 0) { 1747 if (nlinks) { 1748 hammer2_inode_modify(trans, ip); 1749 ip->meta.nlinks += nlinks; 1750 #if 0 1751 hammer2_cluster_modify(trans, cluster, 0); 1752 wipdata = &hammer2_cluster_wdata(cluster)->ipdata; 1753 wipdata->meta.nlinks += nlinks; 1754 hammer2_cluster_modsync(cluster); 1755 ripdata = wipdata; 1756 #endif 1757 } 1758 error = 0; 1759 goto done; 1760 } 1761 1762 /* 1763 * Cluster is the real inode. The originating directory is locked 1764 * by the caller so we can manipulate it without worrying about races 1765 * against other lookups. 1766 * 1767 * If cluster is visible we need to delete it from the current 1768 * location and create a hardlink pointer in its place. If it is 1769 * not visible we need only delete it. Then later cluster will be 1770 * renamed to a parent directory and converted (if necessary) to 1771 * a hidden inode (via shiftup). 1772 * 1773 * NOTE! We must hold cparent locked through the delete/create/rename 1774 * operation to ensure that other threads block resolving to 1775 * the same hardlink, otherwise the other threads may not see 1776 * the hardlink. 1777 */ 1778 KKASSERT((cluster->focus->flags & HAMMER2_CHAIN_DELETED) == 0); 1779 cparent = hammer2_cluster_parent(cluster); 1780 1781 hammer2_cluster_delete(trans, cparent, cluster, 0); 1782 1783 KKASSERT(ip->meta.type != HAMMER2_OBJTYPE_HARDLINK); 1784 if (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE) { 1785 const hammer2_inode_data_t *ripdata; 1786 hammer2_inode_data_t *wipdata; 1787 hammer2_cluster_t *ncluster; 1788 hammer2_key_t lhc; 1789 1790 ncluster = NULL; 1791 lhc = cluster->focus->bref.key; 1792 error = hammer2_cluster_create(trans, cparent, &ncluster, 1793 lhc, 0, 1794 HAMMER2_BREF_TYPE_INODE, 1795 HAMMER2_INODE_BYTES, 1796 0); 1797 hammer2_cluster_modify(trans, ncluster, 0); 1798 wipdata = &hammer2_cluster_wdata(ncluster)->ipdata; 1799 1800 /* wipdata->meta.comp_algo = ip->meta.comp_algo; */ 1801 wipdata->meta.comp_algo = 0; 1802 wipdata->meta.check_algo = 0; 1803 wipdata->meta.version = HAMMER2_INODE_VERSION_ONE; 1804 wipdata->meta.inum = ip->meta.inum; 1805 wipdata->meta.target_type = ip->meta.type; 1806 wipdata->meta.type = HAMMER2_OBJTYPE_HARDLINK; 1807 wipdata->meta.uflags = 0; 1808 wipdata->meta.rmajor = 0; 1809 wipdata->meta.rminor = 0; 1810 wipdata->meta.ctime = 0; 1811 wipdata->meta.mtime = 0; 1812 wipdata->meta.atime = 0; 1813 wipdata->meta.btime = 0; 1814 bzero(&wipdata->meta.uid, sizeof(wipdata->meta.uid)); 1815 bzero(&wipdata->meta.gid, sizeof(wipdata->meta.gid)); 1816 wipdata->meta.op_flags = HAMMER2_OPFLAG_DIRECTDATA; 1817 wipdata->meta.cap_flags = 0; 1818 wipdata->meta.mode = 0; 1819 wipdata->meta.size = 0; 1820 wipdata->meta.nlinks = 1; 1821 wipdata->meta.iparent = 0; /* XXX */ 1822 wipdata->meta.pfs_type = 0; 1823 wipdata->meta.pfs_inum = 0; 1824 bzero(&wipdata->meta.pfs_clid, sizeof(wipdata->meta.pfs_clid)); 1825 bzero(&wipdata->meta.pfs_fsid, sizeof(wipdata->meta.pfs_fsid)); 1826 wipdata->meta.data_quota = 0; 1827 /* wipdata->data_count = 0; */ 1828 wipdata->meta.inode_quota = 0; 1829 /* wipdata->inode_count = 0; */ 1830 wipdata->meta.attr_tid = 0; 1831 wipdata->meta.dirent_tid = 0; 1832 bzero(&wipdata->u, sizeof(wipdata->u)); 1833 ripdata = &hammer2_cluster_rdata(cluster)->ipdata; 1834 KKASSERT(ip->meta.name_len <= sizeof(wipdata->filename)); 1835 bcopy(ripdata->filename, wipdata->filename, 1836 ip->meta.name_len); 1837 wipdata->meta.name_key = ncluster->focus->bref.key; 1838 wipdata->meta.name_len = ip->meta.name_len; 1839 /* XXX transaction ids */ 1840 hammer2_cluster_modsync(ncluster); 1841 hammer2_cluster_unlock(ncluster); 1842 hammer2_cluster_drop(ncluster); 1843 } 1844 1845 /* 1846 * cluster represents the hardlink target and is now flagged deleted. 1847 * duplicate it to the parent directory and adjust nlinks. 1848 * 1849 * WARNING! The shiftup() call can cause ncluster to be moved into 1850 * an indirect block, and our ncluster will wind up pointing 1851 * to the older/original version. 1852 */ 1853 KKASSERT(cluster->focus->flags & HAMMER2_CHAIN_DELETED); 1854 hammer2_hardlink_shiftup(trans, cluster, ip, cdip, cdcluster, 1855 nlinks, &error); 1856 1857 if (error == 0) 1858 hammer2_inode_repoint(ip, cdip, cluster); 1859 1860 done: 1861 /* 1862 * Cleanup, cluster/ncluster already dealt with. 1863 * 1864 * Return the shifted cluster in *clusterp. 1865 */ 1866 if (cparent) { 1867 hammer2_cluster_unlock(cparent); 1868 hammer2_cluster_drop(cparent); 1869 } 1870 *clusterp = cluster; 1871 1872 return (error); 1873 } 1874 1875 /* 1876 * If (*ochainp) is non-NULL it points to the forward OBJTYPE_HARDLINK 1877 * inode while (*chainp) points to the resolved (hidden hardlink 1878 * target) inode. In this situation when nlinks is 1 we wish to 1879 * deconsolidate the hardlink, moving it back to the directory that now 1880 * represents the only remaining link. 1881 */ 1882 int 1883 hammer2_hardlink_deconsolidate(hammer2_trans_t *trans, 1884 hammer2_inode_t *dip, 1885 hammer2_chain_t **chainp, 1886 hammer2_chain_t **ochainp) 1887 { 1888 if (*ochainp == NULL) 1889 return (0); 1890 /* XXX */ 1891 return (0); 1892 } 1893 1894 /* 1895 * The caller presents a locked cluster with an obj_type of 1896 * HAMMER2_OBJTYPE_HARDLINK in (*clusterp). This routine will locate 1897 * the inode and replace (*clusterp) with a new locked cluster containing 1898 * the target hardlink, also locked. The original cluster will be 1899 * unlocked and released. 1900 * 1901 * If cparentp is not NULL a locked cluster representing the hardlink's 1902 * parent is also returned. 1903 * 1904 * If we are unable to locate the hardlink target EIO is returned, 1905 * (*cparentp) is set to NULL, the original passed-in (*clusterp) 1906 * will be unlocked and released and (*clusterp) will be set to NULL 1907 * as well. 1908 */ 1909 int 1910 hammer2_hardlink_find(hammer2_inode_t *dip, 1911 hammer2_cluster_t **cparentp, 1912 hammer2_cluster_t **clusterp) 1913 { 1914 const hammer2_inode_data_t *ipdata; 1915 hammer2_cluster_t *cluster; 1916 hammer2_cluster_t *cparent; 1917 hammer2_cluster_t *rcluster; 1918 hammer2_inode_t *ip; 1919 hammer2_inode_t *pip; 1920 hammer2_key_t key_dummy; 1921 hammer2_key_t lhc; 1922 1923 cluster = *clusterp; 1924 pip = dip; 1925 hammer2_inode_ref(pip); /* for loop */ 1926 1927 /* 1928 * Locate the hardlink. pip is referenced and not locked. 1929 * Unlock and release (*clusterp) after extracting the needed 1930 * data. 1931 */ 1932 ipdata = &hammer2_cluster_rdata(cluster)->ipdata; 1933 lhc = ipdata->meta.inum; 1934 ipdata = NULL; /* safety */ 1935 hammer2_cluster_unlock(cluster); 1936 hammer2_cluster_drop(cluster); 1937 *clusterp = NULL; /* safety */ 1938 1939 rcluster = NULL; 1940 cparent = NULL; 1941 1942 while ((ip = pip) != NULL) { 1943 hammer2_inode_lock(ip, HAMMER2_RESOLVE_ALWAYS); 1944 cparent = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); 1945 hammer2_inode_drop(ip); /* loop */ 1946 KKASSERT(hammer2_cluster_type(cparent) == 1947 HAMMER2_BREF_TYPE_INODE); 1948 rcluster = hammer2_cluster_lookup(cparent, &key_dummy, 1949 lhc, lhc, 0); 1950 if (rcluster) 1951 break; 1952 hammer2_cluster_lookup_done(cparent); /* discard parent */ 1953 cparent = NULL; /* safety */ 1954 pip = ip->pip; /* safe, ip held locked */ 1955 if (pip) 1956 hammer2_inode_ref(pip); /* loop */ 1957 hammer2_inode_unlock(ip, NULL); 1958 } 1959 1960 /* 1961 * chain is locked, ip is locked. Unlock ip, return the locked 1962 * chain. *ipp is already set w/a ref count and not locked. 1963 * 1964 * (cparent is already unlocked). 1965 */ 1966 *clusterp = rcluster; 1967 if (rcluster) { 1968 if (cparentp) { 1969 *cparentp = cparent; 1970 hammer2_inode_unlock(ip, NULL); 1971 } else { 1972 hammer2_inode_unlock(ip, cparent); 1973 } 1974 return (0); 1975 } else { 1976 if (cparentp) 1977 *cparentp = NULL; 1978 if (ip) 1979 hammer2_inode_unlock(ip, cparent); 1980 return (EIO); 1981 } 1982 } 1983 1984 /* 1985 * Find the directory common to both fdip and tdip. 1986 * 1987 * Returns a held but not locked inode. Caller typically locks the inode, 1988 * and when through unlocks AND drops it. 1989 */ 1990 hammer2_inode_t * 1991 hammer2_inode_common_parent(hammer2_inode_t *fdip, hammer2_inode_t *tdip) 1992 { 1993 hammer2_inode_t *scan1; 1994 hammer2_inode_t *scan2; 1995 1996 /* 1997 * We used to have a depth field but it complicated matters too 1998 * much for directory renames. So now its ugly. Check for 1999 * simple cases before giving up and doing it the expensive way. 2000 * 2001 * XXX need a bottom-up topology stability lock 2002 */ 2003 if (fdip == tdip || fdip == tdip->pip) { 2004 hammer2_inode_ref(fdip); 2005 return(fdip); 2006 } 2007 if (fdip->pip == tdip) { 2008 hammer2_inode_ref(tdip); 2009 return(tdip); 2010 } 2011 2012 /* 2013 * XXX not MPSAFE 2014 */ 2015 for (scan1 = fdip; scan1->pmp == fdip->pmp; scan1 = scan1->pip) { 2016 scan2 = tdip; 2017 while (scan2->pmp == tdip->pmp) { 2018 if (scan1 == scan2) { 2019 hammer2_inode_ref(scan1); 2020 return(scan1); 2021 } 2022 scan2 = scan2->pip; 2023 if (scan2 == NULL) 2024 break; 2025 } 2026 } 2027 panic("hammer2_inode_common_parent: no common parent %p %p\n", 2028 fdip, tdip); 2029 /* NOT REACHED */ 2030 return(NULL); 2031 } 2032 2033 /* 2034 * Set an inode's cluster modified, marking the related chains RW and 2035 * duplicating them if necessary. 2036 * 2037 * The passed-in chain is a localized copy of the chain previously acquired 2038 * when the inode was locked (and possilby replaced in the mean time), and 2039 * must also be updated. In fact, we update it first and then synchronize 2040 * the inode's cluster cache. 2041 */ 2042 void 2043 hammer2_inode_modify(hammer2_trans_t *trans, hammer2_inode_t *ip) 2044 { 2045 atomic_set_int(&ip->flags, HAMMER2_INODE_MODIFIED); 2046 if (ip->vp) 2047 vsetisdirty(ip->vp); 2048 } 2049 2050 /* 2051 * Synchronize the inode's frontend state with the chain state prior 2052 * to any explicit flush of the inode or any strategy write call. 2053 * 2054 * Called with a locked inode. 2055 */ 2056 void 2057 hammer2_inode_fsync(hammer2_trans_t *trans, hammer2_inode_t *ip, 2058 hammer2_cluster_t *cparent) 2059 { 2060 int clear_directdata = 0; 2061 2062 /* temporary hack, allow cparent to be NULL */ 2063 if (cparent == NULL) { 2064 cparent = hammer2_inode_cluster(ip, HAMMER2_RESOLVE_ALWAYS); 2065 hammer2_inode_fsync(trans, ip, cparent); 2066 hammer2_cluster_unlock(cparent); 2067 hammer2_cluster_drop(cparent); 2068 return; 2069 } 2070 2071 if ((ip->flags & HAMMER2_INODE_RESIZED) == 0) { 2072 /* do nothing */ 2073 } else if (ip->meta.size < ip->osize) { 2074 /* 2075 * We must delete any chains beyond the EOF. The chain 2076 * straddling the EOF will be pending in the bioq. 2077 */ 2078 hammer2_cluster_t *dparent; 2079 hammer2_cluster_t *cluster; 2080 hammer2_key_t lbase; 2081 hammer2_key_t key_next; 2082 2083 lbase = (ip->meta.size + HAMMER2_PBUFMASK64) & 2084 ~HAMMER2_PBUFMASK64; 2085 dparent = hammer2_cluster_lookup_init(&ip->cluster, 0); 2086 cluster = hammer2_cluster_lookup(dparent, &key_next, 2087 lbase, (hammer2_key_t)-1, 2088 HAMMER2_LOOKUP_NODATA); 2089 while (cluster) { 2090 /* 2091 * Degenerate embedded case, nothing to loop on 2092 */ 2093 switch (hammer2_cluster_type(cluster)) { 2094 case HAMMER2_BREF_TYPE_INODE: 2095 hammer2_cluster_unlock(cluster); 2096 hammer2_cluster_drop(cluster); 2097 cluster = NULL; 2098 break; 2099 case HAMMER2_BREF_TYPE_DATA: 2100 hammer2_cluster_delete(trans, dparent, cluster, 2101 HAMMER2_DELETE_PERMANENT); 2102 /* fall through */ 2103 default: 2104 cluster = hammer2_cluster_next(dparent, cluster, 2105 &key_next, 2106 key_next, (hammer2_key_t)-1, 2107 HAMMER2_LOOKUP_NODATA); 2108 break; 2109 } 2110 } 2111 hammer2_cluster_lookup_done(dparent); 2112 atomic_clear_int(&ip->flags, HAMMER2_INODE_RESIZED); 2113 KKASSERT(ip->flags & HAMMER2_INODE_MODIFIED); 2114 } else if (ip->meta.size > ip->osize) { 2115 /* 2116 * When resizing larger we may not have any direct-data 2117 * available. 2118 */ 2119 if ((ip->meta.op_flags & HAMMER2_OPFLAG_DIRECTDATA) && 2120 ip->meta.size > HAMMER2_EMBEDDED_BYTES) { 2121 ip->meta.op_flags &= ~HAMMER2_OPFLAG_DIRECTDATA; 2122 clear_directdata = 1; 2123 } 2124 atomic_clear_int(&ip->flags, HAMMER2_INODE_RESIZED); 2125 KKASSERT(ip->flags & HAMMER2_INODE_MODIFIED); 2126 } else { 2127 /* 2128 * RESIZED was set but size didn't change. 2129 */ 2130 atomic_clear_int(&ip->flags, HAMMER2_INODE_RESIZED); 2131 KKASSERT(ip->flags & HAMMER2_INODE_MODIFIED); 2132 } 2133 2134 /* 2135 * Sync inode meta-data 2136 */ 2137 if (ip->flags & HAMMER2_INODE_MODIFIED) { 2138 hammer2_inode_data_t *wipdata; 2139 2140 atomic_clear_int(&ip->flags, HAMMER2_INODE_MODIFIED); 2141 hammer2_cluster_modify(trans, cparent, 0); 2142 hammer2_inode_repoint(ip, NULL, cparent); 2143 2144 wipdata = &hammer2_cluster_wdata(cparent)->ipdata; 2145 wipdata->meta = ip->meta; 2146 if (clear_directdata) { 2147 bzero(&wipdata->u.blockset, 2148 sizeof(wipdata->u.blockset)); 2149 } 2150 hammer2_cluster_modsync(cparent); 2151 } 2152 } 2153