1 /* 2 * Copyright (c) 2011-2013 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@dragonflybsd.org> 6 * by Venkatesh Srinivas <vsrinivas@dragonflybsd.org> 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 3. Neither the name of The DragonFly Project nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific, prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 32 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 /* 36 * Kernel Filesystem interface 37 * 38 * NOTE! local ipdata pointers must be reloaded on any modifying operation 39 * to the inode as its underlying chain may have changed. 40 */ 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/kernel.h> 45 #include <sys/fcntl.h> 46 #include <sys/buf.h> 47 #include <sys/proc.h> 48 #include <sys/namei.h> 49 #include <sys/mount.h> 50 #include <sys/vnode.h> 51 #include <sys/mountctl.h> 52 #include <sys/dirent.h> 53 #include <sys/uio.h> 54 55 #include "hammer2.h" 56 57 #define ZFOFFSET (-2LL) 58 59 static int hammer2_read_file(hammer2_inode_t *ip, struct uio *uio, 60 int seqcount); 61 static int hammer2_write_file(hammer2_trans_t *trans, hammer2_inode_t *ip, 62 hammer2_chain_t **parentp, 63 struct uio *uio, int ioflag, int seqcount); 64 static void hammer2_write_bp(hammer2_chain_t *chain, struct buf *bp, 65 int ioflag); 66 static hammer2_chain_t *hammer2_assign_physical(hammer2_trans_t *trans, 67 hammer2_inode_t *ip, hammer2_chain_t **parentp, 68 hammer2_key_t lbase, int lblksize, 69 int *errorp); 70 static void hammer2_extend_file(hammer2_trans_t *trans, hammer2_inode_t *ip, 71 hammer2_chain_t **parentp, hammer2_key_t nsize); 72 static void hammer2_truncate_file(hammer2_trans_t *trans, hammer2_inode_t *ip, 73 hammer2_chain_t **parentp, hammer2_key_t nsize); 74 75 static __inline 76 void 77 hammer2_knote(struct vnode *vp, int flags) 78 { 79 if (flags) 80 KNOTE(&vp->v_pollinfo.vpi_kqinfo.ki_note, flags); 81 } 82 83 /* 84 * Last reference to a vnode is going away but it is still cached. 85 */ 86 static 87 int 88 hammer2_vop_inactive(struct vop_inactive_args *ap) 89 { 90 hammer2_inode_t *ip; 91 hammer2_chain_t *parent; 92 struct vnode *vp; 93 94 vp = ap->a_vp; 95 ip = VTOI(vp); 96 97 /* 98 * Degenerate case 99 */ 100 if (ip == NULL) { 101 vrecycle(vp); 102 return (0); 103 } 104 105 /* 106 * Detect updates to the embedded data which may be synchronized by 107 * the strategy code. Simply mark the inode modified so it gets 108 * picked up by our normal flush. 109 */ 110 parent = hammer2_inode_lock_ex(ip); 111 KKASSERT(parent); 112 113 /* 114 * Check for deleted inodes and recycle immediately. 115 */ 116 if (parent->flags & HAMMER2_CHAIN_DELETED) { 117 hammer2_inode_unlock_ex(ip, parent); 118 vrecycle(vp); 119 } else { 120 hammer2_inode_unlock_ex(ip, parent); 121 } 122 return (0); 123 } 124 125 /* 126 * Reclaim a vnode so that it can be reused; after the inode is 127 * disassociated, the filesystem must manage it alone. 128 */ 129 static 130 int 131 hammer2_vop_reclaim(struct vop_reclaim_args *ap) 132 { 133 hammer2_chain_t *chain; 134 hammer2_inode_t *ip; 135 #if 0 136 hammer2_trans_t trans; 137 #endif 138 struct vnode *vp; 139 140 vp = ap->a_vp; 141 ip = VTOI(vp); 142 if (ip == NULL) 143 return(0); 144 145 /* 146 * Set SUBMODIFIED so we can detect and propagate the DESTROYED 147 * bit in the flush code. 148 * 149 * ip->chain might be stale, correct it before checking as older 150 * versions of the chain are likely marked deleted even if the 151 * file hasn't been. XXX ip->chain should never be stale on 152 * reclaim. 153 */ 154 chain = hammer2_inode_lock_ex(ip); 155 #if 0 156 if (chain->next_parent) 157 kprintf("RECLAIM DUPLINKED IP: %p ip->ch=%p ch=%p np=%p\n", 158 ip, ip->chain, chain, chain->next_parent); 159 #endif 160 161 /* 162 * The final close of a deleted file or directory marks it for 163 * destruction. The DESTROYED flag allows the flusher to shortcut 164 * any modified blocks still unflushed (that is, just ignore them). 165 * 166 * HAMMER2 usually does not try to optimize the freemap by returning 167 * deleted blocks to it as it does not usually know how many snapshots 168 * might be referencing portions of the file/dir. XXX TODO. 169 * 170 * XXX TODO - However, any modified file as-of when a snapshot is made 171 * cannot use this optimization as some of the modifications 172 * may wind up being part of the snapshot. 173 */ 174 vp->v_data = NULL; 175 ip->vp = NULL; 176 if (chain->flags & HAMMER2_CHAIN_DELETED) { 177 KKASSERT(chain->flags & HAMMER2_CHAIN_DELETED); 178 atomic_set_int(&chain->flags, HAMMER2_CHAIN_DESTROYED | 179 HAMMER2_CHAIN_SUBMODIFIED); 180 } 181 #if 0 182 /* 183 * XXX chains will be flushed on sync, no need to do it here. 184 */ 185 if (chain->flags & (HAMMER2_CHAIN_MODIFIED | 186 HAMMER2_CHAIN_DELETED | 187 HAMMER2_CHAIN_SUBMODIFIED)) { 188 hammer2_trans_init(&trans, ip->pmp, HAMMER2_TRANS_ISFLUSH); 189 hammer2_chain_flush(&trans, chain); 190 hammer2_trans_done(&trans); 191 } 192 #endif 193 hammer2_inode_unlock_ex(ip, chain); /* unlock */ 194 hammer2_inode_drop(ip); /* vp ref */ 195 /* chain no longer referenced */ 196 /* chain = NULL; not needed */ 197 198 /* 199 * XXX handle background sync when ip dirty, kernel will no longer 200 * notify us regarding this inode because there is no longer a 201 * vnode attached to it. 202 */ 203 204 return (0); 205 } 206 207 static 208 int 209 hammer2_vop_fsync(struct vop_fsync_args *ap) 210 { 211 hammer2_inode_t *ip; 212 hammer2_trans_t trans; 213 hammer2_chain_t *chain; 214 struct vnode *vp; 215 216 vp = ap->a_vp; 217 ip = VTOI(vp); 218 219 hammer2_trans_init(&trans, ip->pmp, HAMMER2_TRANS_ISFLUSH); 220 chain = hammer2_inode_lock_ex(ip); 221 222 vfsync(vp, ap->a_waitfor, 1, NULL, NULL); 223 224 /* 225 * Calling chain_flush here creates a lot of duplicative 226 * COW operations due to non-optimal vnode ordering. 227 * 228 * Only do it for an actual fsync() syscall. The other forms 229 * which call this function will eventually call chain_flush 230 * on the volume root as a catch-all, which is far more optimal. 231 */ 232 atomic_clear_int(&ip->flags, HAMMER2_INODE_MODIFIED); 233 if (ap->a_flags & VOP_FSYNC_SYSCALL) { 234 hammer2_chain_flush(&trans, chain); 235 } 236 hammer2_inode_unlock_ex(ip, chain); 237 hammer2_trans_done(&trans); 238 239 return (0); 240 } 241 242 static 243 int 244 hammer2_vop_access(struct vop_access_args *ap) 245 { 246 hammer2_inode_t *ip = VTOI(ap->a_vp); 247 hammer2_inode_data_t *ipdata; 248 hammer2_chain_t *chain; 249 uid_t uid; 250 gid_t gid; 251 int error; 252 253 chain = hammer2_inode_lock_sh(ip); 254 ipdata = &chain->data->ipdata; 255 uid = hammer2_to_unix_xid(&ipdata->uid); 256 gid = hammer2_to_unix_xid(&ipdata->gid); 257 error = vop_helper_access(ap, uid, gid, ipdata->mode, ipdata->uflags); 258 hammer2_inode_unlock_sh(ip, chain); 259 260 return (error); 261 } 262 263 static 264 int 265 hammer2_vop_getattr(struct vop_getattr_args *ap) 266 { 267 hammer2_inode_data_t *ipdata; 268 hammer2_chain_t *chain; 269 hammer2_pfsmount_t *pmp; 270 hammer2_inode_t *ip; 271 struct vnode *vp; 272 struct vattr *vap; 273 274 vp = ap->a_vp; 275 vap = ap->a_vap; 276 277 ip = VTOI(vp); 278 pmp = ip->pmp; 279 280 chain = hammer2_inode_lock_sh(ip); 281 ipdata = &chain->data->ipdata; 282 283 vap->va_fsid = pmp->mp->mnt_stat.f_fsid.val[0]; 284 vap->va_fileid = ipdata->inum; 285 vap->va_mode = ipdata->mode; 286 vap->va_nlink = ipdata->nlinks; 287 vap->va_uid = hammer2_to_unix_xid(&ipdata->uid); 288 vap->va_gid = hammer2_to_unix_xid(&ipdata->gid); 289 vap->va_rmajor = 0; 290 vap->va_rminor = 0; 291 vap->va_size = ipdata->size; 292 vap->va_blocksize = HAMMER2_PBUFSIZE; 293 vap->va_flags = ipdata->uflags; 294 hammer2_time_to_timespec(ipdata->ctime, &vap->va_ctime); 295 hammer2_time_to_timespec(ipdata->mtime, &vap->va_mtime); 296 hammer2_time_to_timespec(ipdata->mtime, &vap->va_atime); 297 vap->va_gen = 1; 298 vap->va_bytes = vap->va_size; /* XXX */ 299 vap->va_type = hammer2_get_vtype(chain); 300 vap->va_filerev = 0; 301 vap->va_uid_uuid = ipdata->uid; 302 vap->va_gid_uuid = ipdata->gid; 303 vap->va_vaflags = VA_UID_UUID_VALID | VA_GID_UUID_VALID | 304 VA_FSID_UUID_VALID; 305 306 hammer2_inode_unlock_sh(ip, chain); 307 308 return (0); 309 } 310 311 static 312 int 313 hammer2_vop_setattr(struct vop_setattr_args *ap) 314 { 315 hammer2_inode_data_t *ipdata; 316 hammer2_inode_t *ip; 317 hammer2_chain_t *chain; 318 hammer2_trans_t trans; 319 struct vnode *vp; 320 struct vattr *vap; 321 int error; 322 int kflags = 0; 323 int domtime = 0; 324 uint64_t ctime; 325 326 vp = ap->a_vp; 327 vap = ap->a_vap; 328 hammer2_update_time(&ctime); 329 330 ip = VTOI(vp); 331 332 if (ip->pmp->ronly) 333 return(EROFS); 334 335 hammer2_trans_init(&trans, ip->pmp, 0); 336 chain = hammer2_inode_lock_ex(ip); 337 ipdata = &chain->data->ipdata; 338 error = 0; 339 340 if (vap->va_flags != VNOVAL) { 341 u_int32_t flags; 342 343 flags = ipdata->uflags; 344 error = vop_helper_setattr_flags(&flags, vap->va_flags, 345 hammer2_to_unix_xid(&ipdata->uid), 346 ap->a_cred); 347 if (error == 0) { 348 if (ipdata->uflags != flags) { 349 ipdata = hammer2_chain_modify_ip(&trans, ip, 350 &chain, 0); 351 ipdata->uflags = flags; 352 ipdata->ctime = ctime; 353 kflags |= NOTE_ATTRIB; 354 } 355 if (ipdata->uflags & (IMMUTABLE | APPEND)) { 356 error = 0; 357 goto done; 358 } 359 } 360 goto done; 361 } 362 if (ipdata->uflags & (IMMUTABLE | APPEND)) { 363 error = EPERM; 364 goto done; 365 } 366 if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) { 367 mode_t cur_mode = ipdata->mode; 368 uid_t cur_uid = hammer2_to_unix_xid(&ipdata->uid); 369 gid_t cur_gid = hammer2_to_unix_xid(&ipdata->gid); 370 uuid_t uuid_uid; 371 uuid_t uuid_gid; 372 373 error = vop_helper_chown(ap->a_vp, vap->va_uid, vap->va_gid, 374 ap->a_cred, 375 &cur_uid, &cur_gid, &cur_mode); 376 if (error == 0) { 377 hammer2_guid_to_uuid(&uuid_uid, cur_uid); 378 hammer2_guid_to_uuid(&uuid_gid, cur_gid); 379 if (bcmp(&uuid_uid, &ipdata->uid, sizeof(uuid_uid)) || 380 bcmp(&uuid_gid, &ipdata->gid, sizeof(uuid_gid)) || 381 ipdata->mode != cur_mode 382 ) { 383 ipdata = hammer2_chain_modify_ip(&trans, ip, 384 &chain, 0); 385 ipdata->uid = uuid_uid; 386 ipdata->gid = uuid_gid; 387 ipdata->mode = cur_mode; 388 ipdata->ctime = ctime; 389 } 390 kflags |= NOTE_ATTRIB; 391 } 392 } 393 394 /* 395 * Resize the file 396 */ 397 if (vap->va_size != VNOVAL && ipdata->size != vap->va_size) { 398 switch(vp->v_type) { 399 case VREG: 400 if (vap->va_size == ipdata->size) 401 break; 402 if (vap->va_size < ipdata->size) { 403 hammer2_truncate_file(&trans, ip, 404 &chain, vap->va_size); 405 } else { 406 hammer2_extend_file(&trans, ip, 407 &chain, vap->va_size); 408 } 409 ipdata = &chain->data->ipdata; /* RELOAD */ 410 domtime = 1; 411 break; 412 default: 413 error = EINVAL; 414 goto done; 415 } 416 } 417 #if 0 418 /* atime not supported */ 419 if (vap->va_atime.tv_sec != VNOVAL) { 420 ipdata = hammer2_chain_modify_ip(&trans, ip, &chain, 0); 421 ipdata->atime = hammer2_timespec_to_time(&vap->va_atime); 422 kflags |= NOTE_ATTRIB; 423 } 424 #endif 425 if (vap->va_mtime.tv_sec != VNOVAL) { 426 ipdata = hammer2_chain_modify_ip(&trans, ip, &chain, 0); 427 ipdata->mtime = hammer2_timespec_to_time(&vap->va_mtime); 428 kflags |= NOTE_ATTRIB; 429 } 430 if (vap->va_mode != (mode_t)VNOVAL) { 431 mode_t cur_mode = ipdata->mode; 432 uid_t cur_uid = hammer2_to_unix_xid(&ipdata->uid); 433 gid_t cur_gid = hammer2_to_unix_xid(&ipdata->gid); 434 435 error = vop_helper_chmod(ap->a_vp, vap->va_mode, ap->a_cred, 436 cur_uid, cur_gid, &cur_mode); 437 if (error == 0 && ipdata->mode != cur_mode) { 438 ipdata = hammer2_chain_modify_ip(&trans, ip, &chain, 0); 439 ipdata->mode = cur_mode; 440 ipdata->ctime = ctime; 441 kflags |= NOTE_ATTRIB; 442 } 443 } 444 done: 445 hammer2_inode_unlock_ex(ip, chain); 446 hammer2_trans_done(&trans); 447 return (error); 448 } 449 450 static 451 int 452 hammer2_vop_readdir(struct vop_readdir_args *ap) 453 { 454 hammer2_inode_data_t *ipdata; 455 hammer2_inode_t *ip; 456 hammer2_inode_t *xip; 457 hammer2_chain_t *parent; 458 hammer2_chain_t *chain; 459 hammer2_chain_t *xchain; 460 hammer2_tid_t inum; 461 hammer2_key_t lkey; 462 struct uio *uio; 463 off_t *cookies; 464 off_t saveoff; 465 int cookie_index; 466 int ncookies; 467 int error; 468 int dtype; 469 int r; 470 471 ip = VTOI(ap->a_vp); 472 uio = ap->a_uio; 473 saveoff = uio->uio_offset; 474 475 /* 476 * Setup cookies directory entry cookies if requested 477 */ 478 if (ap->a_ncookies) { 479 ncookies = uio->uio_resid / 16 + 1; 480 if (ncookies > 1024) 481 ncookies = 1024; 482 cookies = kmalloc(ncookies * sizeof(off_t), M_TEMP, M_WAITOK); 483 } else { 484 ncookies = -1; 485 cookies = NULL; 486 } 487 cookie_index = 0; 488 489 parent = hammer2_inode_lock_sh(ip); 490 ipdata = &parent->data->ipdata; 491 492 /* 493 * Handle artificial entries. To ensure that only positive 64 bit 494 * quantities are returned to userland we always strip off bit 63. 495 * The hash code is designed such that codes 0x0000-0x7FFF are not 496 * used, allowing us to use these codes for articial entries. 497 * 498 * Entry 0 is used for '.' and entry 1 is used for '..'. Do not 499 * allow '..' to cross the mount point into (e.g.) the super-root. 500 */ 501 error = 0; 502 chain = (void *)(intptr_t)-1; /* non-NULL for early goto done case */ 503 504 if (saveoff == 0) { 505 inum = ipdata->inum & HAMMER2_DIRHASH_USERMSK; 506 r = vop_write_dirent(&error, uio, inum, DT_DIR, 1, "."); 507 if (r) 508 goto done; 509 if (cookies) 510 cookies[cookie_index] = saveoff; 511 ++saveoff; 512 ++cookie_index; 513 if (cookie_index == ncookies) 514 goto done; 515 } 516 517 if (saveoff == 1) { 518 /* 519 * Be careful with lockorder when accessing ".." 520 * 521 * (ip is the current dir. xip is the parent dir). 522 */ 523 inum = ipdata->inum & HAMMER2_DIRHASH_USERMSK; 524 while (ip->pip != NULL && ip != ip->pmp->iroot) { 525 xip = ip->pip; 526 hammer2_inode_ref(xip); 527 hammer2_inode_unlock_sh(ip, parent); 528 xchain = hammer2_inode_lock_sh(xip); 529 parent = hammer2_inode_lock_sh(ip); 530 hammer2_inode_drop(xip); 531 if (xip == ip->pip) { 532 inum = xchain->data->ipdata.inum & 533 HAMMER2_DIRHASH_USERMSK; 534 hammer2_inode_unlock_sh(xip, xchain); 535 break; 536 } 537 hammer2_inode_unlock_sh(xip, xchain); 538 } 539 r = vop_write_dirent(&error, uio, inum, DT_DIR, 2, ".."); 540 if (r) 541 goto done; 542 if (cookies) 543 cookies[cookie_index] = saveoff; 544 ++saveoff; 545 ++cookie_index; 546 if (cookie_index == ncookies) 547 goto done; 548 } 549 550 lkey = saveoff | HAMMER2_DIRHASH_VISIBLE; 551 552 /* 553 * parent is the inode chain, already locked for us. Don't 554 * double lock shared locks as this will screw up upgrades. 555 */ 556 if (error) { 557 goto done; 558 } 559 chain = hammer2_chain_lookup(&parent, lkey, lkey, 560 HAMMER2_LOOKUP_SHARED); 561 if (chain == NULL) { 562 chain = hammer2_chain_lookup(&parent, 563 lkey, (hammer2_key_t)-1, 564 HAMMER2_LOOKUP_SHARED); 565 } 566 while (chain) { 567 if (chain->bref.type == HAMMER2_BREF_TYPE_INODE) { 568 dtype = hammer2_get_dtype(chain); 569 saveoff = chain->bref.key & HAMMER2_DIRHASH_USERMSK; 570 r = vop_write_dirent(&error, uio, 571 chain->data->ipdata.inum & 572 HAMMER2_DIRHASH_USERMSK, 573 dtype, 574 chain->data->ipdata.name_len, 575 chain->data->ipdata.filename); 576 if (r) 577 break; 578 if (cookies) 579 cookies[cookie_index] = saveoff; 580 ++cookie_index; 581 } else { 582 /* XXX chain error */ 583 kprintf("bad chain type readdir %d\n", 584 chain->bref.type); 585 } 586 587 /* 588 * Keys may not be returned in order so once we have a 589 * placemarker (chain) the scan must allow the full range 590 * or some entries will be missed. 591 */ 592 chain = hammer2_chain_next(&parent, chain, 593 HAMMER2_DIRHASH_VISIBLE, 594 (hammer2_key_t)-1, 595 HAMMER2_LOOKUP_SHARED); 596 if (chain) { 597 saveoff = (chain->bref.key & 598 HAMMER2_DIRHASH_USERMSK) + 1; 599 } else { 600 saveoff = (hammer2_key_t)-1; 601 } 602 if (cookie_index == ncookies) 603 break; 604 } 605 if (chain) 606 hammer2_chain_unlock(chain); 607 done: 608 hammer2_inode_unlock_sh(ip, parent); 609 if (ap->a_eofflag) 610 *ap->a_eofflag = (chain == NULL); 611 uio->uio_offset = saveoff & ~HAMMER2_DIRHASH_VISIBLE; 612 if (error && cookie_index == 0) { 613 if (cookies) { 614 kfree(cookies, M_TEMP); 615 *ap->a_ncookies = 0; 616 *ap->a_cookies = NULL; 617 } 618 } else { 619 if (cookies) { 620 *ap->a_ncookies = cookie_index; 621 *ap->a_cookies = cookies; 622 } 623 } 624 return (error); 625 } 626 627 /* 628 * hammer2_vop_readlink { vp, uio, cred } 629 */ 630 static 631 int 632 hammer2_vop_readlink(struct vop_readlink_args *ap) 633 { 634 struct vnode *vp; 635 hammer2_inode_t *ip; 636 int error; 637 638 vp = ap->a_vp; 639 if (vp->v_type != VLNK) 640 return (EINVAL); 641 ip = VTOI(vp); 642 643 error = hammer2_read_file(ip, ap->a_uio, 0); 644 return (error); 645 } 646 647 static 648 int 649 hammer2_vop_read(struct vop_read_args *ap) 650 { 651 struct vnode *vp; 652 hammer2_inode_t *ip; 653 struct uio *uio; 654 int error; 655 int seqcount; 656 int bigread; 657 658 /* 659 * Read operations supported on this vnode? 660 */ 661 vp = ap->a_vp; 662 if (vp->v_type != VREG) 663 return (EINVAL); 664 665 /* 666 * Misc 667 */ 668 ip = VTOI(vp); 669 uio = ap->a_uio; 670 error = 0; 671 672 seqcount = ap->a_ioflag >> 16; 673 bigread = (uio->uio_resid > 100 * 1024 * 1024); 674 675 error = hammer2_read_file(ip, uio, seqcount); 676 return (error); 677 } 678 679 static 680 int 681 hammer2_vop_write(struct vop_write_args *ap) 682 { 683 hammer2_inode_t *ip; 684 hammer2_trans_t trans; 685 hammer2_chain_t *parent; 686 thread_t td; 687 struct vnode *vp; 688 struct uio *uio; 689 int error; 690 int seqcount; 691 int bigwrite; 692 693 /* 694 * Read operations supported on this vnode? 695 */ 696 vp = ap->a_vp; 697 if (vp->v_type != VREG) 698 return (EINVAL); 699 700 /* 701 * Misc 702 */ 703 ip = VTOI(vp); 704 uio = ap->a_uio; 705 error = 0; 706 if (ip->pmp->ronly) 707 return (EROFS); 708 709 seqcount = ap->a_ioflag >> 16; 710 bigwrite = (uio->uio_resid > 100 * 1024 * 1024); 711 712 /* 713 * Check resource limit 714 */ 715 if (uio->uio_resid > 0 && (td = uio->uio_td) != NULL && td->td_proc && 716 uio->uio_offset + uio->uio_resid > 717 td->td_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur) { 718 lwpsignal(td->td_proc, td->td_lwp, SIGXFSZ); 719 return (EFBIG); 720 } 721 722 bigwrite = (uio->uio_resid > 100 * 1024 * 1024); 723 724 /* 725 * ip must be locked if extending the file. 726 * ip must be locked to avoid racing a truncation. 727 * 728 * ip must be marked modified, particularly because the write 729 * might wind up being copied into the embedded data area. 730 */ 731 hammer2_trans_init(&trans, ip->pmp, 0); 732 parent = hammer2_inode_lock_ex(ip); 733 error = hammer2_write_file(&trans, ip, &parent, 734 uio, ap->a_ioflag, seqcount); 735 hammer2_inode_unlock_ex(ip, parent); 736 hammer2_trans_done(&trans); 737 738 return (error); 739 } 740 741 /* 742 * Perform read operations on a file or symlink given an UNLOCKED 743 * inode and uio. 744 * 745 * The passed ip is not locked. 746 */ 747 static 748 int 749 hammer2_read_file(hammer2_inode_t *ip, struct uio *uio, int seqcount) 750 { 751 hammer2_off_t size; 752 hammer2_chain_t *parent; 753 struct buf *bp; 754 int error; 755 756 error = 0; 757 758 /* 759 * UIO read loop. 760 */ 761 parent = hammer2_inode_lock_sh(ip); 762 size = ip->chain->data->ipdata.size; 763 764 while (uio->uio_resid > 0 && uio->uio_offset < size) { 765 hammer2_key_t lbase; 766 hammer2_key_t leof; 767 int lblksize; 768 int loff; 769 int n; 770 771 lblksize = hammer2_calc_logical(ip, uio->uio_offset, 772 &lbase, &leof); 773 774 error = cluster_read(ip->vp, leof, lbase, lblksize, 775 uio->uio_resid, seqcount * BKVASIZE, 776 &bp); 777 778 if (error) 779 break; 780 loff = (int)(uio->uio_offset - lbase); 781 n = lblksize - loff; 782 if (n > uio->uio_resid) 783 n = uio->uio_resid; 784 if (n > size - uio->uio_offset) 785 n = (int)(size - uio->uio_offset); 786 bp->b_flags |= B_AGE; 787 uiomove((char *)bp->b_data + loff, n, uio); 788 bqrelse(bp); 789 } 790 hammer2_inode_unlock_sh(ip, parent); 791 return (error); 792 } 793 794 /* 795 * Called with a locked (ip) to do the underlying write to a file or 796 * to build the symlink target. 797 */ 798 static 799 int 800 hammer2_write_file(hammer2_trans_t *trans, hammer2_inode_t *ip, 801 hammer2_chain_t **parentp, 802 struct uio *uio, int ioflag, int seqcount) 803 { 804 hammer2_inode_data_t *ipdata; 805 hammer2_key_t old_eof; 806 struct buf *bp; 807 int kflags; 808 int error; 809 int modified = 0; 810 811 /* 812 * Setup if append 813 */ 814 ipdata = hammer2_chain_modify_ip(trans, ip, parentp, 0); 815 if (ioflag & IO_APPEND) 816 uio->uio_offset = ipdata->size; 817 kflags = 0; 818 error = 0; 819 820 /* 821 * vfs_sync visibility. Interlocked by the inode ex lock so we 822 * shouldn't have to reassert it multiple times if the ip->chain 823 * is modified/flushed multiple times during the write, except 824 * when we release/reacquire the inode ex lock. 825 */ 826 atomic_set_int(&ip->flags, HAMMER2_INODE_MODIFIED); 827 828 /* 829 * Extend the file if necessary. If the write fails at some point 830 * we will truncate it back down to cover as much as we were able 831 * to write. 832 * 833 * Doing this now makes it easier to calculate buffer sizes in 834 * the loop. 835 */ 836 KKASSERT(ipdata->type != HAMMER2_OBJTYPE_HARDLINK); 837 old_eof = ipdata->size; 838 if (uio->uio_offset + uio->uio_resid > ipdata->size) { 839 modified = 1; 840 hammer2_extend_file(trans, ip, parentp, 841 uio->uio_offset + uio->uio_resid); 842 ipdata = &ip->chain->data->ipdata; /* RELOAD */ 843 kflags |= NOTE_EXTEND; 844 } 845 KKASSERT(ipdata->type != HAMMER2_OBJTYPE_HARDLINK); 846 847 /* 848 * UIO write loop 849 */ 850 while (uio->uio_resid > 0) { 851 hammer2_chain_t *chain; 852 hammer2_key_t lbase; 853 hammer2_key_t leof; 854 int trivial; 855 int lblksize; 856 int loff; 857 int n; 858 859 /* 860 * Don't allow the buffer build to blow out the buffer 861 * cache. 862 */ 863 if ((ioflag & IO_RECURSE) == 0) { 864 /* 865 * XXX should try to leave this unlocked through 866 * the whole loop 867 */ 868 hammer2_inode_unlock_ex(ip, *parentp); 869 bwillwrite(HAMMER2_PBUFSIZE); 870 *parentp = hammer2_inode_lock_ex(ip); 871 atomic_set_int(&ip->flags, HAMMER2_INODE_MODIFIED); 872 ipdata = &ip->chain->data->ipdata; /* reload */ 873 } 874 875 /* XXX bigwrite & signal check test */ 876 877 /* 878 * This nominally tells us how much we can cluster and 879 * what the logical buffer size needs to be. Currently 880 * we don't try to cluster the write and just handle one 881 * block at a time. 882 */ 883 lblksize = hammer2_calc_logical(ip, uio->uio_offset, 884 &lbase, &leof); 885 loff = (int)(uio->uio_offset - lbase); 886 887 /* 888 * Calculate bytes to copy this transfer and whether the 889 * copy completely covers the buffer or not. 890 */ 891 trivial = 0; 892 n = lblksize - loff; 893 if (n > uio->uio_resid) { 894 n = uio->uio_resid; 895 if (loff == lbase && 896 uio->uio_offset + n == ipdata->size) 897 trivial = 1; 898 } else if (loff == 0) { 899 trivial = 1; 900 } 901 902 /* 903 * Get the buffer 904 */ 905 if (uio->uio_segflg == UIO_NOCOPY) { 906 /* 907 * Issuing a write with the same data backing the 908 * buffer. Instantiate the buffer to collect the 909 * backing vm pages, then read-in any missing bits. 910 * 911 * This case is used by vop_stdputpages(). 912 */ 913 bp = getblk(ip->vp, lbase, lblksize, GETBLK_BHEAVY, 0); 914 if ((bp->b_flags & B_CACHE) == 0) { 915 bqrelse(bp); 916 error = bread(ip->vp, lbase, lblksize, &bp); 917 } 918 } else if (trivial) { 919 /* 920 * Even though we are entirely overwriting the buffer 921 * we may still have to zero it out to avoid a 922 * mmap/write visibility issue. 923 */ 924 bp = getblk(ip->vp, lbase, lblksize, GETBLK_BHEAVY, 0); 925 if ((bp->b_flags & B_CACHE) == 0) 926 vfs_bio_clrbuf(bp); 927 } else { 928 /* 929 * Partial overwrite, read in any missing bits then 930 * replace the portion being written. 931 * 932 * (The strategy code will detect zero-fill physical 933 * blocks for this case). 934 */ 935 error = bread(ip->vp, lbase, lblksize, &bp); 936 if (error == 0) 937 bheavy(bp); 938 } 939 940 if (error) { 941 brelse(bp); 942 break; 943 } 944 945 /* 946 * Ok, copy the data in 947 */ 948 hammer2_inode_unlock_ex(ip, *parentp); 949 error = uiomove(bp->b_data + loff, n, uio); 950 *parentp = hammer2_inode_lock_ex(ip); 951 atomic_set_int(&ip->flags, HAMMER2_INODE_MODIFIED); 952 ipdata = &ip->chain->data->ipdata; /* reload */ 953 kflags |= NOTE_WRITE; 954 modified = 1; 955 if (error) { 956 brelse(bp); 957 break; 958 } 959 960 /* 961 * We have to assign physical storage to the buffer we intend 962 * to dirty or write now to avoid deadlocks in the strategy 963 * code later. 964 * 965 * This can return NOOFFSET for inode-embedded data. The 966 * strategy code will take care of it in that case. 967 */ 968 chain = hammer2_assign_physical(trans, ip, parentp, 969 lbase, lblksize, &error); 970 ipdata = &ip->chain->data->ipdata; /* RELOAD */ 971 972 if (error) { 973 KKASSERT(chain == NULL); 974 brelse(bp); 975 break; 976 } 977 978 /* XXX update ip_data.mtime */ 979 980 /* 981 * Once we dirty a buffer any cached offset becomes invalid. 982 * 983 * NOTE: For cluster_write() always use the trailing block 984 * size, which is HAMMER2_PBUFSIZE. lblksize is the 985 * eof-straddling blocksize and is incorrect. 986 */ 987 bp->b_flags |= B_AGE; 988 hammer2_write_bp(chain, bp, ioflag); 989 hammer2_chain_unlock(chain); 990 } 991 992 /* 993 * Cleanup. If we extended the file EOF but failed to write through 994 * the entire write is a failure and we have to back-up. 995 */ 996 if (error && ipdata->size != old_eof) { 997 hammer2_truncate_file(trans, ip, parentp, old_eof); 998 ipdata = &ip->chain->data->ipdata; /* RELOAD */ 999 } else if (modified) { 1000 ipdata = hammer2_chain_modify_ip(trans, ip, parentp, 0); 1001 hammer2_update_time(&ipdata->mtime); 1002 } 1003 hammer2_knote(ip->vp, kflags); 1004 1005 return error; 1006 } 1007 1008 /* 1009 * Write the logical file bp out. 1010 */ 1011 static 1012 void 1013 hammer2_write_bp(hammer2_chain_t *chain, struct buf *bp, int ioflag) 1014 { 1015 hammer2_off_t pbase; 1016 hammer2_off_t pmask; 1017 hammer2_off_t peof; 1018 struct buf *dbp; 1019 size_t boff; 1020 size_t psize; 1021 1022 KKASSERT(chain->flags & HAMMER2_CHAIN_MODIFIED); 1023 1024 switch(chain->bref.type) { 1025 case HAMMER2_BREF_TYPE_INODE: 1026 KKASSERT(chain->data->ipdata.op_flags & 1027 HAMMER2_OPFLAG_DIRECTDATA); 1028 KKASSERT(bp->b_loffset == 0); 1029 bcopy(bp->b_data, chain->data->ipdata.u.data, 1030 HAMMER2_EMBEDDED_BYTES); 1031 break; 1032 case HAMMER2_BREF_TYPE_DATA: 1033 psize = hammer2_devblksize(chain->bytes); 1034 pmask = (hammer2_off_t)psize - 1; 1035 pbase = chain->bref.data_off & ~pmask; 1036 boff = chain->bref.data_off & (HAMMER2_OFF_MASK & pmask); 1037 peof = (pbase + HAMMER2_SEGMASK64) & ~HAMMER2_SEGMASK64; 1038 1039 KKASSERT(chain->bytes == psize); 1040 dbp = getblk(chain->hmp->devvp, pbase, psize, 0, 0); 1041 bcopy(bp->b_data, dbp->b_data + boff, chain->bytes); 1042 1043 if (ioflag & IO_SYNC) { 1044 /* 1045 * Synchronous I/O requested. 1046 */ 1047 bwrite(dbp); 1048 /* 1049 } else if ((ioflag & IO_DIRECT) && loff + n == lblksize) { 1050 bdwrite(dbp); 1051 */ 1052 } else if (ioflag & IO_ASYNC) { 1053 bawrite(dbp); 1054 } else if (hammer2_cluster_enable) { 1055 cluster_write(dbp, peof, HAMMER2_PBUFSIZE, 4/*XXX*/); 1056 } else { 1057 bdwrite(dbp); 1058 } 1059 break; 1060 default: 1061 panic("hammer2_write_bp: bad chain type %d\n", 1062 chain->bref.type); 1063 /* NOT REACHED */ 1064 break; 1065 } 1066 bqrelse(bp); 1067 } 1068 1069 /* 1070 * Assign physical storage to a logical block. This function creates the 1071 * related meta-data chains representing the data blocks and marks them 1072 * MODIFIED. We could mark them MOVED instead but ultimately I need to 1073 * XXX code the flusher to check that the related logical buffer is 1074 * flushed. 1075 * 1076 * NOOFFSET is returned if the data is inode-embedded. In this case the 1077 * strategy code will simply bcopy() the data into the inode. 1078 * 1079 * The inode's delta_dcount is adjusted. 1080 */ 1081 static 1082 hammer2_chain_t * 1083 hammer2_assign_physical(hammer2_trans_t *trans, 1084 hammer2_inode_t *ip, hammer2_chain_t **parentp, 1085 hammer2_key_t lbase, int lblksize, int *errorp) 1086 { 1087 hammer2_chain_t *parent; 1088 hammer2_chain_t *chain; 1089 hammer2_off_t pbase; 1090 1091 /* 1092 * Locate the chain associated with lbase, return a locked chain. 1093 * However, do not instantiate any data reference (which utilizes a 1094 * device buffer) because we will be using direct IO via the 1095 * logical buffer cache buffer. 1096 */ 1097 *errorp = 0; 1098 retry: 1099 parent = *parentp; 1100 hammer2_chain_lock(parent, HAMMER2_RESOLVE_ALWAYS); /* extra lock */ 1101 chain = hammer2_chain_lookup(&parent, 1102 lbase, lbase, 1103 HAMMER2_LOOKUP_NODATA); 1104 1105 if (chain == NULL) { 1106 /* 1107 * We found a hole, create a new chain entry. 1108 * 1109 * NOTE: DATA chains are created without device backing 1110 * store (nor do we want any). 1111 */ 1112 *errorp = hammer2_chain_create(trans, &parent, &chain, 1113 lbase, HAMMER2_PBUFRADIX, 1114 HAMMER2_BREF_TYPE_DATA, 1115 lblksize); 1116 if (chain == NULL) { 1117 hammer2_chain_lookup_done(parent); 1118 panic("hammer2_chain_create: par=%p error=%d\n", 1119 parent, *errorp); 1120 goto retry; 1121 } 1122 1123 pbase = chain->bref.data_off & ~HAMMER2_OFF_MASK_RADIX; 1124 /*ip->delta_dcount += lblksize;*/ 1125 } else { 1126 switch (chain->bref.type) { 1127 case HAMMER2_BREF_TYPE_INODE: 1128 /* 1129 * The data is embedded in the inode. The 1130 * caller is responsible for marking the inode 1131 * modified and copying the data to the embedded 1132 * area. 1133 */ 1134 pbase = NOOFFSET; 1135 break; 1136 case HAMMER2_BREF_TYPE_DATA: 1137 if (chain->bytes != lblksize) { 1138 panic("hammer2_assign_physical: " 1139 "size mismatch %d/%d\n", 1140 lblksize, chain->bytes); 1141 } 1142 hammer2_chain_modify(trans, &chain, 1143 HAMMER2_MODIFY_OPTDATA); 1144 pbase = chain->bref.data_off & ~HAMMER2_OFF_MASK_RADIX; 1145 break; 1146 default: 1147 panic("hammer2_assign_physical: bad type"); 1148 /* NOT REACHED */ 1149 pbase = NOOFFSET; 1150 break; 1151 } 1152 } 1153 1154 /* 1155 * Cleanup. If chain wound up being the inode (i.e. DIRECTDATA), 1156 * we might have to replace *parentp. 1157 */ 1158 hammer2_chain_lookup_done(parent); 1159 if (chain) { 1160 if (*parentp != chain && 1161 (*parentp)->core == chain->core) { 1162 parent = *parentp; 1163 *parentp = chain; /* eats lock */ 1164 hammer2_chain_unlock(parent); 1165 hammer2_chain_lock(chain, 0); /* need another */ 1166 } 1167 /* else chain already locked for return */ 1168 } 1169 return (chain); 1170 } 1171 1172 /* 1173 * Truncate the size of a file. 1174 * 1175 * This routine adjusts ipdata->size smaller, destroying any related 1176 * data beyond the new EOF and potentially resizing the block straddling 1177 * the EOF. 1178 * 1179 * The inode must be locked. 1180 */ 1181 static 1182 void 1183 hammer2_truncate_file(hammer2_trans_t *trans, hammer2_inode_t *ip, 1184 hammer2_chain_t **parentp, hammer2_key_t nsize) 1185 { 1186 hammer2_inode_data_t *ipdata; 1187 hammer2_chain_t *parent; 1188 hammer2_chain_t *chain; 1189 hammer2_key_t lbase; 1190 hammer2_key_t leof; 1191 struct buf *bp; 1192 int loff; 1193 int error; 1194 int oblksize; 1195 int nblksize; 1196 1197 bp = NULL; 1198 error = 0; 1199 ipdata = hammer2_chain_modify_ip(trans, ip, parentp, 0); 1200 1201 /* 1202 * Destroy any logical buffer cache buffers beyond the file EOF. 1203 * 1204 * We call nvtruncbuf() w/ trivial == 1 to prevent it from messing 1205 * around with the buffer straddling EOF, because we need to assign 1206 * a new physical offset to it. 1207 */ 1208 if (ip->vp) { 1209 nvtruncbuf(ip->vp, nsize, 1210 HAMMER2_PBUFSIZE, (int)nsize & HAMMER2_PBUFMASK, 1211 1); 1212 } 1213 1214 /* 1215 * Setup for lookup/search 1216 */ 1217 parent = hammer2_chain_lookup_init(ip->chain, 0); 1218 1219 /* 1220 * Handle the case where a chain/logical-buffer straddles the new 1221 * EOF. We told nvtruncbuf() above not to mess with the logical 1222 * buffer straddling the EOF because we need to reassign its storage 1223 * and can't let the strategy code do it for us. 1224 */ 1225 loff = (int)nsize & HAMMER2_PBUFMASK; 1226 if (loff && ip->vp) { 1227 oblksize = hammer2_calc_logical(ip, nsize, &lbase, &leof); 1228 error = bread(ip->vp, lbase, oblksize, &bp); 1229 KKASSERT(error == 0); 1230 } 1231 ipdata->size = nsize; 1232 nblksize = hammer2_calc_logical(ip, nsize, &lbase, &leof); 1233 1234 /* 1235 * Fixup the chain element. If we have a logical buffer in-hand 1236 * we don't want to create a conflicting device buffer. 1237 */ 1238 if (loff && bp) { 1239 chain = hammer2_chain_lookup(&parent, lbase, lbase, 1240 HAMMER2_LOOKUP_NODATA); 1241 if (chain) { 1242 switch(chain->bref.type) { 1243 case HAMMER2_BREF_TYPE_DATA: 1244 hammer2_chain_resize(trans, ip, bp, 1245 parent, &chain, 1246 hammer2_getradix(nblksize), 1247 HAMMER2_MODIFY_OPTDATA); 1248 allocbuf(bp, nblksize); 1249 bzero(bp->b_data + loff, nblksize - loff); 1250 bp->b_bio2.bio_caller_info1.ptr = chain->hmp; 1251 bp->b_bio2.bio_offset = chain->bref.data_off & 1252 HAMMER2_OFF_MASK; 1253 break; 1254 case HAMMER2_BREF_TYPE_INODE: 1255 allocbuf(bp, nblksize); 1256 bzero(bp->b_data + loff, nblksize - loff); 1257 bp->b_bio2.bio_caller_info1.ptr = NULL; 1258 bp->b_bio2.bio_offset = NOOFFSET; 1259 break; 1260 default: 1261 panic("hammer2_truncate_file: bad type"); 1262 break; 1263 } 1264 hammer2_write_bp(chain, bp, 0); 1265 hammer2_chain_unlock(chain); 1266 } else { 1267 /* 1268 * Destroy clean buffer w/ wrong buffer size. Retain 1269 * backing store. 1270 */ 1271 bp->b_flags |= B_RELBUF; 1272 KKASSERT(bp->b_bio2.bio_offset == NOOFFSET); 1273 KKASSERT((bp->b_flags & B_DIRTY) == 0); 1274 bqrelse(bp); 1275 } 1276 } else if (loff) { 1277 /* 1278 * WARNING: This utilizes a device buffer for the data. 1279 * 1280 * This case should not occur because file truncations without 1281 * a vnode (and hence no logical buffer cache) should only 1282 * always truncate to 0-length. 1283 */ 1284 panic("hammer2_truncate_file: non-zero truncation, no-vnode"); 1285 } 1286 1287 /* 1288 * Clean up any fragmentory VM pages now that we have properly 1289 * resized the straddling buffer. These pages are no longer 1290 * part of the buffer. 1291 */ 1292 if (ip->vp) { 1293 nvtruncbuf(ip->vp, nsize, 1294 nblksize, (int)nsize & (nblksize - 1), 1295 1); 1296 } 1297 1298 /* 1299 * Destroy any physical blocks after the new EOF point. 1300 */ 1301 lbase = (nsize + HAMMER2_PBUFMASK64) & ~HAMMER2_PBUFMASK64; 1302 chain = hammer2_chain_lookup(&parent, 1303 lbase, (hammer2_key_t)-1, 1304 HAMMER2_LOOKUP_NODATA); 1305 while (chain) { 1306 /* 1307 * Degenerate embedded data case, nothing to loop on. 1308 */ 1309 if (chain->bref.type == HAMMER2_BREF_TYPE_INODE) { 1310 hammer2_chain_unlock(chain); 1311 break; 1312 } 1313 1314 /* 1315 * Delete physical data blocks past the file EOF. 1316 */ 1317 if (chain->bref.type == HAMMER2_BREF_TYPE_DATA) { 1318 /*ip->delta_dcount -= chain->bytes;*/ 1319 hammer2_chain_delete(trans, chain); 1320 } 1321 /* XXX check parent if empty indirect block & delete */ 1322 chain = hammer2_chain_next(&parent, chain, 1323 lbase, (hammer2_key_t)-1, 1324 HAMMER2_LOOKUP_NODATA); 1325 } 1326 hammer2_chain_lookup_done(parent); 1327 } 1328 1329 /* 1330 * Extend the size of a file. The inode must be locked. 1331 * 1332 * We may have to resize the block straddling the old EOF. 1333 */ 1334 static 1335 void 1336 hammer2_extend_file(hammer2_trans_t *trans, hammer2_inode_t *ip, 1337 hammer2_chain_t **parentp, hammer2_key_t nsize) 1338 { 1339 hammer2_inode_data_t *ipdata; 1340 hammer2_chain_t *parent; 1341 hammer2_chain_t *chain; 1342 struct buf *bp; 1343 hammer2_key_t osize; 1344 hammer2_key_t obase; 1345 hammer2_key_t nbase; 1346 hammer2_key_t leof; 1347 int oblksize; 1348 int nblksize; 1349 int nradix; 1350 int error; 1351 1352 KKASSERT(ip->vp); 1353 1354 ipdata = hammer2_chain_modify_ip(trans, ip, parentp, 0); 1355 1356 /* 1357 * Nothing to do if the direct-data case is still intact 1358 */ 1359 if ((ipdata->op_flags & HAMMER2_OPFLAG_DIRECTDATA) && 1360 nsize <= HAMMER2_EMBEDDED_BYTES) { 1361 ipdata->size = nsize; 1362 nvextendbuf(ip->vp, 1363 ipdata->size, nsize, 1364 0, HAMMER2_EMBEDDED_BYTES, 1365 0, (int)nsize, 1366 1); 1367 /* ipdata = &ip->chain->data->ipdata; RELOAD */ 1368 return; 1369 } 1370 1371 /* 1372 * Calculate the blocksize at the original EOF and resize the block 1373 * if necessary. Adjust the file size in the inode. 1374 */ 1375 osize = ipdata->size; 1376 oblksize = hammer2_calc_logical(ip, osize, &obase, &leof); 1377 ipdata->size = nsize; 1378 nblksize = hammer2_calc_logical(ip, osize, &nbase, &leof); 1379 1380 /* 1381 * Do all required vnode operations, but do not mess with the 1382 * buffer straddling the orignal EOF. 1383 */ 1384 nvextendbuf(ip->vp, 1385 ipdata->size, nsize, 1386 0, nblksize, 1387 0, (int)nsize & HAMMER2_PBUFMASK, 1388 1); 1389 ipdata = &ip->chain->data->ipdata; 1390 1391 /* 1392 * Early return if we have no more work to do. 1393 */ 1394 if (obase == nbase && oblksize == nblksize && 1395 (ipdata->op_flags & HAMMER2_OPFLAG_DIRECTDATA) == 0) { 1396 return; 1397 } 1398 1399 /* 1400 * We have work to do, including possibly resizing the buffer 1401 * at the previous EOF point and turning off DIRECTDATA mode. 1402 */ 1403 bp = NULL; 1404 if (((int)osize & HAMMER2_PBUFMASK)) { 1405 error = bread(ip->vp, obase, oblksize, &bp); 1406 KKASSERT(error == 0); 1407 } 1408 1409 /* 1410 * Disable direct-data mode by loading up a buffer cache buffer 1411 * with the data, then converting the inode data area into the 1412 * inode indirect block array area. 1413 */ 1414 if (ipdata->op_flags & HAMMER2_OPFLAG_DIRECTDATA) { 1415 ipdata->op_flags &= ~HAMMER2_OPFLAG_DIRECTDATA; 1416 bzero(&ipdata->u.blockset, sizeof(ipdata->u.blockset)); 1417 } 1418 1419 /* 1420 * Resize the chain element at the old EOF. 1421 */ 1422 if (((int)osize & HAMMER2_PBUFMASK)) { 1423 retry: 1424 error = 0; 1425 parent = hammer2_chain_lookup_init(ip->chain, 0); 1426 nradix = hammer2_getradix(nblksize); 1427 1428 chain = hammer2_chain_lookup(&parent, 1429 obase, obase, 1430 HAMMER2_LOOKUP_NODATA); 1431 if (chain == NULL) { 1432 error = hammer2_chain_create(trans, &parent, &chain, 1433 obase, nblksize, 1434 HAMMER2_BREF_TYPE_DATA, 1435 nblksize); 1436 if (chain == NULL) { 1437 hammer2_chain_lookup_done(parent); 1438 panic("hammer2_chain_create: par=%p error=%d\n", 1439 parent, error); 1440 goto retry; 1441 } 1442 /*ip->delta_dcount += nblksize;*/ 1443 } else { 1444 KKASSERT(chain->bref.type == HAMMER2_BREF_TYPE_DATA); 1445 hammer2_chain_resize(trans, ip, bp, 1446 parent, &chain, 1447 nradix, 1448 HAMMER2_MODIFY_OPTDATA); 1449 } 1450 if (obase != nbase) { 1451 if (oblksize != HAMMER2_PBUFSIZE) 1452 allocbuf(bp, HAMMER2_PBUFSIZE); 1453 } else { 1454 if (oblksize != nblksize) 1455 allocbuf(bp, nblksize); 1456 } 1457 hammer2_write_bp(chain, bp, 0); 1458 hammer2_chain_unlock(chain); 1459 hammer2_chain_lookup_done(parent); 1460 } 1461 } 1462 1463 static 1464 int 1465 hammer2_vop_nresolve(struct vop_nresolve_args *ap) 1466 { 1467 hammer2_inode_t *ip; 1468 hammer2_inode_t *dip; 1469 hammer2_chain_t *parent; 1470 hammer2_chain_t *chain; 1471 hammer2_chain_t *ochain; 1472 hammer2_trans_t trans; 1473 struct namecache *ncp; 1474 const uint8_t *name; 1475 size_t name_len; 1476 hammer2_key_t lhc; 1477 int error = 0; 1478 struct vnode *vp; 1479 1480 dip = VTOI(ap->a_dvp); 1481 ncp = ap->a_nch->ncp; 1482 name = ncp->nc_name; 1483 name_len = ncp->nc_nlen; 1484 lhc = hammer2_dirhash(name, name_len); 1485 1486 /* 1487 * Note: In DragonFly the kernel handles '.' and '..'. 1488 */ 1489 parent = hammer2_inode_lock_sh(dip); 1490 chain = hammer2_chain_lookup(&parent, 1491 lhc, lhc + HAMMER2_DIRHASH_LOMASK, 1492 HAMMER2_LOOKUP_SHARED); 1493 while (chain) { 1494 if (chain->bref.type == HAMMER2_BREF_TYPE_INODE && 1495 name_len == chain->data->ipdata.name_len && 1496 bcmp(name, chain->data->ipdata.filename, name_len) == 0) { 1497 break; 1498 } 1499 chain = hammer2_chain_next(&parent, chain, 1500 lhc, lhc + HAMMER2_DIRHASH_LOMASK, 1501 HAMMER2_LOOKUP_SHARED); 1502 } 1503 hammer2_inode_unlock_sh(dip, parent); 1504 1505 /* 1506 * If the inode represents a forwarding entry for a hardlink we have 1507 * to locate the actual inode. The original ip is saved for possible 1508 * deconsolidation. (ip) will only be set to non-NULL when we have 1509 * to locate the real file via a hardlink. ip will be referenced but 1510 * not locked in that situation. chain is passed in locked and 1511 * returned locked. 1512 * 1513 * XXX what kind of chain lock? 1514 */ 1515 ochain = NULL; 1516 if (chain && chain->data->ipdata.type == HAMMER2_OBJTYPE_HARDLINK) { 1517 error = hammer2_hardlink_find(dip, &chain, &ochain); 1518 if (error) { 1519 kprintf("hammer2: unable to find hardlink\n"); 1520 if (chain) { 1521 hammer2_chain_unlock(chain); 1522 chain = NULL; 1523 } 1524 goto failed; 1525 } 1526 } 1527 1528 /* 1529 * Deconsolidate any hardlink whos nlinks == 1. Ignore errors. 1530 * If an error occurs chain and ip are left alone. 1531 * 1532 * XXX upgrade shared lock? 1533 */ 1534 if (ochain && chain && 1535 chain->data->ipdata.nlinks == 1 && !dip->pmp->ronly) { 1536 kprintf("hammer2: need to unconsolidate hardlink for %s\n", 1537 chain->data->ipdata.filename); 1538 /* XXX retain shared lock on dip? (currently not held) */ 1539 hammer2_trans_init(&trans, dip->pmp, 0); 1540 hammer2_hardlink_deconsolidate(&trans, dip, &chain, &ochain); 1541 hammer2_trans_done(&trans); 1542 } 1543 1544 /* 1545 * Acquire the related vnode 1546 * 1547 * NOTE: For error processing, only ENOENT resolves the namecache 1548 * entry to NULL, otherwise we just return the error and 1549 * leave the namecache unresolved. 1550 * 1551 * NOTE: multiple hammer2_inode structures can be aliased to the 1552 * same chain element, for example for hardlinks. This 1553 * use case does not 'reattach' inode associations that 1554 * might already exist, but always allocates a new one. 1555 * 1556 * WARNING: inode structure is locked exclusively via inode_get 1557 * but chain was locked shared. inode_unlock_ex() 1558 * will handle it properly. 1559 */ 1560 if (chain) { 1561 ip = hammer2_inode_get(dip->pmp, dip, chain); 1562 vp = hammer2_igetv(ip, &error); 1563 if (error == 0) { 1564 vn_unlock(vp); 1565 cache_setvp(ap->a_nch, vp); 1566 } else if (error == ENOENT) { 1567 cache_setvp(ap->a_nch, NULL); 1568 } 1569 hammer2_inode_unlock_ex(ip, chain); 1570 1571 /* 1572 * The vp should not be released until after we've disposed 1573 * of our locks, because it might cause vop_inactive() to 1574 * be called. 1575 */ 1576 if (vp) 1577 vrele(vp); 1578 } else { 1579 error = ENOENT; 1580 cache_setvp(ap->a_nch, NULL); 1581 } 1582 failed: 1583 KASSERT(error || ap->a_nch->ncp->nc_vp != NULL, 1584 ("resolve error %d/%p chain %p ap %p\n", 1585 error, ap->a_nch->ncp->nc_vp, chain, ap)); 1586 if (ochain) 1587 hammer2_chain_drop(ochain); 1588 return error; 1589 } 1590 1591 static 1592 int 1593 hammer2_vop_nlookupdotdot(struct vop_nlookupdotdot_args *ap) 1594 { 1595 hammer2_inode_t *dip; 1596 hammer2_inode_t *ip; 1597 hammer2_chain_t *parent; 1598 int error; 1599 1600 dip = VTOI(ap->a_dvp); 1601 1602 if ((ip = dip->pip) == NULL) { 1603 *ap->a_vpp = NULL; 1604 return ENOENT; 1605 } 1606 parent = hammer2_inode_lock_ex(ip); 1607 *ap->a_vpp = hammer2_igetv(ip, &error); 1608 hammer2_inode_unlock_ex(ip, parent); 1609 1610 return error; 1611 } 1612 1613 static 1614 int 1615 hammer2_vop_nmkdir(struct vop_nmkdir_args *ap) 1616 { 1617 hammer2_inode_t *dip; 1618 hammer2_inode_t *nip; 1619 hammer2_trans_t trans; 1620 hammer2_chain_t *chain; 1621 struct namecache *ncp; 1622 const uint8_t *name; 1623 size_t name_len; 1624 int error; 1625 1626 dip = VTOI(ap->a_dvp); 1627 if (dip->pmp->ronly) 1628 return (EROFS); 1629 1630 ncp = ap->a_nch->ncp; 1631 name = ncp->nc_name; 1632 name_len = ncp->nc_nlen; 1633 1634 hammer2_trans_init(&trans, dip->pmp, 0); 1635 nip = hammer2_inode_create(&trans, dip, ap->a_vap, ap->a_cred, 1636 name, name_len, &chain, &error); 1637 if (error) { 1638 KKASSERT(nip == NULL); 1639 *ap->a_vpp = NULL; 1640 } else { 1641 *ap->a_vpp = hammer2_igetv(nip, &error); 1642 hammer2_inode_unlock_ex(nip, chain); 1643 } 1644 hammer2_trans_done(&trans); 1645 1646 if (error == 0) { 1647 cache_setunresolved(ap->a_nch); 1648 cache_setvp(ap->a_nch, *ap->a_vpp); 1649 } 1650 return error; 1651 } 1652 1653 /* 1654 * Return the largest contiguous physical disk range for the logical 1655 * request, in bytes. 1656 * 1657 * (struct vnode *vp, off_t loffset, off_t *doffsetp, int *runp, int *runb) 1658 */ 1659 static 1660 int 1661 hammer2_vop_bmap(struct vop_bmap_args *ap) 1662 { 1663 *ap->a_doffsetp = NOOFFSET; 1664 if (ap->a_runp) 1665 *ap->a_runp = 0; 1666 if (ap->a_runb) 1667 *ap->a_runb = 0; 1668 return (EOPNOTSUPP); 1669 #if 0 1670 struct vnode *vp; 1671 hammer2_inode_t *ip; 1672 hammer2_chain_t *parent; 1673 hammer2_chain_t *chain; 1674 hammer2_key_t lbeg; 1675 hammer2_key_t lend; 1676 hammer2_off_t pbeg; 1677 hammer2_off_t pbytes; 1678 hammer2_off_t array[HAMMER2_BMAP_COUNT][2]; 1679 int loff; 1680 int ai; 1681 1682 /* 1683 * Only supported on regular files 1684 * 1685 * Only supported for read operations (required for cluster_read). 1686 * The block allocation is delayed for write operations. 1687 */ 1688 vp = ap->a_vp; 1689 if (vp->v_type != VREG) 1690 return (EOPNOTSUPP); 1691 if (ap->a_cmd != BUF_CMD_READ) 1692 return (EOPNOTSUPP); 1693 1694 ip = VTOI(vp); 1695 bzero(array, sizeof(array)); 1696 1697 /* 1698 * Calculate logical range 1699 */ 1700 KKASSERT((ap->a_loffset & HAMMER2_LBUFMASK64) == 0); 1701 lbeg = ap->a_loffset & HAMMER2_OFF_MASK_HI; 1702 lend = lbeg + HAMMER2_BMAP_COUNT * HAMMER2_PBUFSIZE - 1; 1703 if (lend < lbeg) 1704 lend = lbeg; 1705 loff = ap->a_loffset & HAMMER2_OFF_MASK_LO; 1706 1707 parent = hammer2_inode_lock_sh(ip); 1708 chain = hammer2_chain_lookup(&parent, 1709 lbeg, lend, 1710 HAMMER2_LOOKUP_NODATA | 1711 HAMMER2_LOOKUP_SHARED); 1712 if (chain == NULL) { 1713 *ap->a_doffsetp = ZFOFFSET; 1714 hammer2_inode_unlock_sh(ip, parent); 1715 return (0); 1716 } 1717 1718 while (chain) { 1719 if (chain->bref.type == HAMMER2_BREF_TYPE_DATA) { 1720 ai = (chain->bref.key - lbeg) / HAMMER2_PBUFSIZE; 1721 KKASSERT(ai >= 0 && ai < HAMMER2_BMAP_COUNT); 1722 array[ai][0] = chain->bref.data_off & HAMMER2_OFF_MASK; 1723 array[ai][1] = chain->bytes; 1724 } 1725 chain = hammer2_chain_next(&parent, chain, 1726 lbeg, lend, 1727 HAMMER2_LOOKUP_NODATA | 1728 HAMMER2_LOOKUP_SHARED); 1729 } 1730 hammer2_inode_unlock_sh(ip, parent); 1731 1732 /* 1733 * If the requested loffset is not mappable physically we can't 1734 * bmap. The caller will have to access the file data via a 1735 * device buffer. 1736 */ 1737 if (array[0][0] == 0 || array[0][1] < loff + HAMMER2_MINIOSIZE) { 1738 *ap->a_doffsetp = NOOFFSET; 1739 return (0); 1740 } 1741 1742 /* 1743 * Calculate the physical disk offset range for array[0] 1744 */ 1745 pbeg = array[0][0] + loff; 1746 pbytes = array[0][1] - loff; 1747 1748 for (ai = 1; ai < HAMMER2_BMAP_COUNT; ++ai) { 1749 if (array[ai][0] != pbeg + pbytes) 1750 break; 1751 pbytes += array[ai][1]; 1752 } 1753 1754 *ap->a_doffsetp = pbeg; 1755 if (ap->a_runp) 1756 *ap->a_runp = pbytes; 1757 return (0); 1758 #endif 1759 } 1760 1761 static 1762 int 1763 hammer2_vop_open(struct vop_open_args *ap) 1764 { 1765 return vop_stdopen(ap); 1766 } 1767 1768 /* 1769 * hammer2_vop_advlock { vp, id, op, fl, flags } 1770 */ 1771 static 1772 int 1773 hammer2_vop_advlock(struct vop_advlock_args *ap) 1774 { 1775 hammer2_inode_t *ip = VTOI(ap->a_vp); 1776 hammer2_chain_t *parent; 1777 hammer2_off_t size; 1778 1779 parent = hammer2_inode_lock_sh(ip); 1780 size = parent->data->ipdata.size; 1781 hammer2_inode_unlock_sh(ip, parent); 1782 return (lf_advlock(ap, &ip->advlock, size)); 1783 } 1784 1785 1786 static 1787 int 1788 hammer2_vop_close(struct vop_close_args *ap) 1789 { 1790 return vop_stdclose(ap); 1791 } 1792 1793 /* 1794 * hammer2_vop_nlink { nch, dvp, vp, cred } 1795 * 1796 * Create a hardlink from (vp) to {dvp, nch}. 1797 */ 1798 static 1799 int 1800 hammer2_vop_nlink(struct vop_nlink_args *ap) 1801 { 1802 hammer2_inode_t *dip; /* target directory to create link in */ 1803 hammer2_inode_t *ip; /* inode we are hardlinking to */ 1804 hammer2_chain_t *chain; 1805 hammer2_trans_t trans; 1806 struct namecache *ncp; 1807 const uint8_t *name; 1808 size_t name_len; 1809 int error; 1810 1811 dip = VTOI(ap->a_dvp); 1812 if (dip->pmp->ronly) 1813 return (EROFS); 1814 1815 ncp = ap->a_nch->ncp; 1816 name = ncp->nc_name; 1817 name_len = ncp->nc_nlen; 1818 1819 /* 1820 * ip represents the file being hardlinked. The file could be a 1821 * normal file or a hardlink target if it has already been hardlinked. 1822 * If ip is a hardlinked target then ip->pip represents the location 1823 * of the hardlinked target, NOT the location of the hardlink pointer. 1824 * 1825 * Bump nlinks and potentially also create or move the hardlink 1826 * target in the parent directory common to (ip) and (dip). The 1827 * consolidation code can modify ip->chain and ip->pip. The 1828 * returned chain is locked. 1829 */ 1830 ip = VTOI(ap->a_vp); 1831 hammer2_trans_init(&trans, ip->pmp, 0); 1832 1833 chain = hammer2_inode_lock_ex(ip); 1834 error = hammer2_hardlink_consolidate(&trans, ip, &chain, dip, 1); 1835 if (error) 1836 goto done; 1837 1838 /* 1839 * Create a directory entry connected to the specified chain. 1840 * The hardlink consolidation code has already adjusted ip->pip 1841 * to the common parent directory containing the actual hardlink 1842 * 1843 * (which may be different from dip where we created our hardlink 1844 * entry. ip->chain always represents the actual hardlink and not 1845 * any of the pointers to the actual hardlink). 1846 */ 1847 error = hammer2_inode_connect(&trans, 1, 1848 dip, &chain, 1849 name, name_len); 1850 if (error == 0) { 1851 cache_setunresolved(ap->a_nch); 1852 cache_setvp(ap->a_nch, ap->a_vp); 1853 } 1854 done: 1855 hammer2_inode_unlock_ex(ip, chain); 1856 hammer2_trans_done(&trans); 1857 1858 return error; 1859 } 1860 1861 /* 1862 * hammer2_vop_ncreate { nch, dvp, vpp, cred, vap } 1863 * 1864 * The operating system has already ensured that the directory entry 1865 * does not exist and done all appropriate namespace locking. 1866 */ 1867 static 1868 int 1869 hammer2_vop_ncreate(struct vop_ncreate_args *ap) 1870 { 1871 hammer2_inode_t *dip; 1872 hammer2_inode_t *nip; 1873 hammer2_trans_t trans; 1874 hammer2_chain_t *nchain; 1875 struct namecache *ncp; 1876 const uint8_t *name; 1877 size_t name_len; 1878 int error; 1879 1880 dip = VTOI(ap->a_dvp); 1881 if (dip->pmp->ronly) 1882 return (EROFS); 1883 1884 ncp = ap->a_nch->ncp; 1885 name = ncp->nc_name; 1886 name_len = ncp->nc_nlen; 1887 hammer2_trans_init(&trans, dip->pmp, 0); 1888 1889 nip = hammer2_inode_create(&trans, dip, ap->a_vap, ap->a_cred, 1890 name, name_len, &nchain, &error); 1891 if (error) { 1892 KKASSERT(nip == NULL); 1893 *ap->a_vpp = NULL; 1894 } else { 1895 *ap->a_vpp = hammer2_igetv(nip, &error); 1896 hammer2_inode_unlock_ex(nip, nchain); 1897 } 1898 hammer2_trans_done(&trans); 1899 1900 if (error == 0) { 1901 cache_setunresolved(ap->a_nch); 1902 cache_setvp(ap->a_nch, *ap->a_vpp); 1903 } 1904 return error; 1905 } 1906 1907 /* 1908 * hammer2_vop_nsymlink { nch, dvp, vpp, cred, vap, target } 1909 */ 1910 static 1911 int 1912 hammer2_vop_nsymlink(struct vop_nsymlink_args *ap) 1913 { 1914 hammer2_inode_t *dip; 1915 hammer2_inode_t *nip; 1916 hammer2_chain_t *nparent; 1917 hammer2_trans_t trans; 1918 struct namecache *ncp; 1919 const uint8_t *name; 1920 size_t name_len; 1921 int error; 1922 1923 dip = VTOI(ap->a_dvp); 1924 if (dip->pmp->ronly) 1925 return (EROFS); 1926 1927 ncp = ap->a_nch->ncp; 1928 name = ncp->nc_name; 1929 name_len = ncp->nc_nlen; 1930 hammer2_trans_init(&trans, dip->pmp, 0); 1931 1932 ap->a_vap->va_type = VLNK; /* enforce type */ 1933 1934 nip = hammer2_inode_create(&trans, dip, ap->a_vap, ap->a_cred, 1935 name, name_len, &nparent, &error); 1936 if (error) { 1937 KKASSERT(nip == NULL); 1938 *ap->a_vpp = NULL; 1939 hammer2_trans_done(&trans); 1940 return error; 1941 } 1942 *ap->a_vpp = hammer2_igetv(nip, &error); 1943 1944 /* 1945 * Build the softlink (~like file data) and finalize the namecache. 1946 */ 1947 if (error == 0) { 1948 size_t bytes; 1949 struct uio auio; 1950 struct iovec aiov; 1951 hammer2_inode_data_t *nipdata; 1952 1953 nipdata = &nip->chain->data->ipdata; 1954 bytes = strlen(ap->a_target); 1955 1956 if (bytes <= HAMMER2_EMBEDDED_BYTES) { 1957 KKASSERT(nipdata->op_flags & 1958 HAMMER2_OPFLAG_DIRECTDATA); 1959 bcopy(ap->a_target, nipdata->u.data, bytes); 1960 nipdata->size = bytes; 1961 } else { 1962 bzero(&auio, sizeof(auio)); 1963 bzero(&aiov, sizeof(aiov)); 1964 auio.uio_iov = &aiov; 1965 auio.uio_segflg = UIO_SYSSPACE; 1966 auio.uio_rw = UIO_WRITE; 1967 auio.uio_resid = bytes; 1968 auio.uio_iovcnt = 1; 1969 auio.uio_td = curthread; 1970 aiov.iov_base = ap->a_target; 1971 aiov.iov_len = bytes; 1972 error = hammer2_write_file(&trans, nip, &nparent, 1973 &auio, IO_APPEND, 0); 1974 nipdata = &nip->chain->data->ipdata; /* RELOAD */ 1975 /* XXX handle error */ 1976 error = 0; 1977 } 1978 } 1979 hammer2_inode_unlock_ex(nip, nparent); 1980 hammer2_trans_done(&trans); 1981 1982 /* 1983 * Finalize namecache 1984 */ 1985 if (error == 0) { 1986 cache_setunresolved(ap->a_nch); 1987 cache_setvp(ap->a_nch, *ap->a_vpp); 1988 /* hammer2_knote(ap->a_dvp, NOTE_WRITE); */ 1989 } 1990 return error; 1991 } 1992 1993 /* 1994 * hammer2_vop_nremove { nch, dvp, cred } 1995 */ 1996 static 1997 int 1998 hammer2_vop_nremove(struct vop_nremove_args *ap) 1999 { 2000 hammer2_inode_t *dip; 2001 hammer2_trans_t trans; 2002 struct namecache *ncp; 2003 const uint8_t *name; 2004 size_t name_len; 2005 int error; 2006 2007 dip = VTOI(ap->a_dvp); 2008 if (dip->pmp->ronly) 2009 return(EROFS); 2010 2011 ncp = ap->a_nch->ncp; 2012 name = ncp->nc_name; 2013 name_len = ncp->nc_nlen; 2014 hammer2_trans_init(&trans, dip->pmp, 0); 2015 error = hammer2_unlink_file(&trans, dip, name, name_len, 0, NULL); 2016 hammer2_trans_done(&trans); 2017 if (error == 0) { 2018 cache_unlink(ap->a_nch); 2019 } 2020 return (error); 2021 } 2022 2023 /* 2024 * hammer2_vop_nrmdir { nch, dvp, cred } 2025 */ 2026 static 2027 int 2028 hammer2_vop_nrmdir(struct vop_nrmdir_args *ap) 2029 { 2030 hammer2_inode_t *dip; 2031 hammer2_trans_t trans; 2032 struct namecache *ncp; 2033 const uint8_t *name; 2034 size_t name_len; 2035 int error; 2036 2037 dip = VTOI(ap->a_dvp); 2038 if (dip->pmp->ronly) 2039 return(EROFS); 2040 2041 ncp = ap->a_nch->ncp; 2042 name = ncp->nc_name; 2043 name_len = ncp->nc_nlen; 2044 2045 hammer2_trans_init(&trans, dip->pmp, 0); 2046 error = hammer2_unlink_file(&trans, dip, name, name_len, 1, NULL); 2047 hammer2_trans_done(&trans); 2048 if (error == 0) { 2049 cache_unlink(ap->a_nch); 2050 } 2051 return (error); 2052 } 2053 2054 /* 2055 * hammer2_vop_nrename { fnch, tnch, fdvp, tdvp, cred } 2056 */ 2057 static 2058 int 2059 hammer2_vop_nrename(struct vop_nrename_args *ap) 2060 { 2061 struct namecache *fncp; 2062 struct namecache *tncp; 2063 hammer2_inode_t *fdip; 2064 hammer2_inode_t *tdip; 2065 hammer2_inode_t *ip; 2066 hammer2_chain_t *chain; 2067 hammer2_trans_t trans; 2068 const uint8_t *fname; 2069 size_t fname_len; 2070 const uint8_t *tname; 2071 size_t tname_len; 2072 int error; 2073 int hlink; 2074 2075 if (ap->a_fdvp->v_mount != ap->a_tdvp->v_mount) 2076 return(EXDEV); 2077 if (ap->a_fdvp->v_mount != ap->a_fnch->ncp->nc_vp->v_mount) 2078 return(EXDEV); 2079 2080 fdip = VTOI(ap->a_fdvp); /* source directory */ 2081 tdip = VTOI(ap->a_tdvp); /* target directory */ 2082 2083 if (fdip->pmp->ronly) 2084 return(EROFS); 2085 2086 fncp = ap->a_fnch->ncp; /* entry name in source */ 2087 fname = fncp->nc_name; 2088 fname_len = fncp->nc_nlen; 2089 2090 tncp = ap->a_tnch->ncp; /* entry name in target */ 2091 tname = tncp->nc_name; 2092 tname_len = tncp->nc_nlen; 2093 2094 hammer2_trans_init(&trans, tdip->pmp, 0); 2095 2096 /* 2097 * ip is the inode being renamed. If this is a hardlink then 2098 * ip represents the actual file and not the hardlink marker. 2099 */ 2100 ip = VTOI(fncp->nc_vp); 2101 chain = NULL; 2102 2103 /* 2104 * Keep a tight grip on the inode so the temporary unlinking from 2105 * the source location prior to linking to the target location 2106 * does not cause the chain to be destroyed. 2107 * 2108 * NOTE: To avoid deadlocks we cannot lock (ip) while we are 2109 * unlinking elements from their directories. Locking 2110 * the nlinks field does not lock the whole inode. 2111 */ 2112 hammer2_inode_ref(ip); 2113 2114 /* 2115 * Remove target if it exists 2116 */ 2117 error = hammer2_unlink_file(&trans, tdip, tname, tname_len, -1, NULL); 2118 if (error && error != ENOENT) 2119 goto done; 2120 cache_setunresolved(ap->a_tnch); 2121 2122 /* 2123 * When renaming a hardlinked file we may have to re-consolidate 2124 * the location of the hardlink target. Since the element is simply 2125 * being moved, nlinks is not modified in this case. 2126 * 2127 * If ip represents a regular file the consolidation code essentially 2128 * does nothing other than return the same locked chain that was 2129 * passed in. 2130 * 2131 * The returned chain will be locked. 2132 * 2133 * WARNING! We do not currently have a local copy of ipdata but 2134 * we do use one later remember that it must be reloaded 2135 * on any modification to the inode, including connects. 2136 */ 2137 chain = hammer2_inode_lock_ex(ip); 2138 error = hammer2_hardlink_consolidate(&trans, ip, &chain, tdip, 0); 2139 if (error) 2140 goto done; 2141 2142 /* 2143 * Disconnect (fdip, fname) from the source directory. This will 2144 * disconnect (ip) if it represents a direct file. If (ip) represents 2145 * a hardlink the HARDLINK pointer object will be removed but the 2146 * hardlink will stay intact. 2147 * 2148 * The target chain may be marked DELETED but will not be destroyed 2149 * since we retain our hold on ip and chain. 2150 */ 2151 error = hammer2_unlink_file(&trans, fdip, fname, fname_len, -1, &hlink); 2152 KKASSERT(error != EAGAIN); 2153 if (error) 2154 goto done; 2155 2156 /* 2157 * Reconnect ip to target directory using chain. Chains cannot 2158 * actually be moved, so this will duplicate the chain in the new 2159 * spot and assign it to the ip, replacing the old chain. 2160 * 2161 * WARNING: chain locks can lock buffer cache buffers, to avoid 2162 * deadlocks we want to unlock before issuing a cache_*() 2163 * op (that might have to lock a vnode). 2164 */ 2165 error = hammer2_inode_connect(&trans, hlink, 2166 tdip, &chain, 2167 tname, tname_len); 2168 if (error == 0) { 2169 KKASSERT(chain != NULL); 2170 hammer2_inode_repoint(ip, (hlink ? ip->pip : tdip), chain); 2171 cache_rename(ap->a_fnch, ap->a_tnch); 2172 } 2173 done: 2174 hammer2_inode_unlock_ex(ip, chain); 2175 hammer2_inode_drop(ip); 2176 hammer2_trans_done(&trans); 2177 2178 return (error); 2179 } 2180 2181 /* 2182 * Strategy code 2183 * 2184 * WARNING: The strategy code cannot safely use hammer2 transactions 2185 * as this can deadlock against vfs_sync's vfsync() call 2186 * if multiple flushes are queued. 2187 */ 2188 static int hammer2_strategy_read(struct vop_strategy_args *ap); 2189 static int hammer2_strategy_write(struct vop_strategy_args *ap); 2190 static void hammer2_strategy_read_callback(hammer2_chain_t *chain, 2191 struct buf *dbp, char *data, void *arg); 2192 2193 static 2194 int 2195 hammer2_vop_strategy(struct vop_strategy_args *ap) 2196 { 2197 struct bio *biop; 2198 struct buf *bp; 2199 int error; 2200 2201 biop = ap->a_bio; 2202 bp = biop->bio_buf; 2203 2204 switch(bp->b_cmd) { 2205 case BUF_CMD_READ: 2206 error = hammer2_strategy_read(ap); 2207 ++hammer2_iod_file_read; 2208 break; 2209 case BUF_CMD_WRITE: 2210 error = hammer2_strategy_write(ap); 2211 ++hammer2_iod_file_write; 2212 break; 2213 default: 2214 bp->b_error = error = EINVAL; 2215 bp->b_flags |= B_ERROR; 2216 biodone(biop); 2217 break; 2218 } 2219 2220 return (error); 2221 } 2222 2223 static 2224 int 2225 hammer2_strategy_read(struct vop_strategy_args *ap) 2226 { 2227 struct buf *bp; 2228 struct bio *bio; 2229 struct bio *nbio; 2230 hammer2_inode_t *ip; 2231 hammer2_chain_t *parent; 2232 hammer2_chain_t *chain; 2233 hammer2_key_t lbase; 2234 2235 bio = ap->a_bio; 2236 bp = bio->bio_buf; 2237 ip = VTOI(ap->a_vp); 2238 nbio = push_bio(bio); 2239 2240 lbase = bio->bio_offset; 2241 chain = NULL; 2242 KKASSERT(((int)lbase & HAMMER2_PBUFMASK) == 0); 2243 2244 #if 0 2245 kprintf("read lbase %jd cached %016jx\n", 2246 lbase, nbio->bio_offset); 2247 #endif 2248 2249 parent = hammer2_inode_lock_sh(ip); 2250 chain = hammer2_chain_lookup(&parent, lbase, lbase, 2251 HAMMER2_LOOKUP_NODATA | 2252 HAMMER2_LOOKUP_SHARED); 2253 2254 if (chain == NULL) { 2255 /* 2256 * Data is zero-fill 2257 */ 2258 bp->b_resid = 0; 2259 bp->b_error = 0; 2260 bzero(bp->b_data, bp->b_bcount); 2261 biodone(nbio); 2262 } else if (chain->bref.type == HAMMER2_BREF_TYPE_INODE) { 2263 /* 2264 * Data is embedded in the inode (copy from inode). 2265 */ 2266 hammer2_chain_load_async(chain, hammer2_strategy_read_callback, 2267 nbio); 2268 } else if (chain->bref.type == HAMMER2_BREF_TYPE_DATA) { 2269 /* 2270 * Data is on-media, issue device I/O and copy. 2271 * 2272 * XXX direct-IO shortcut could go here XXX. 2273 */ 2274 hammer2_chain_load_async(chain, hammer2_strategy_read_callback, 2275 nbio); 2276 } else { 2277 panic("hammer2_strategy_read: unknown bref type"); 2278 chain = NULL; 2279 } 2280 hammer2_inode_unlock_sh(ip, parent); 2281 return (0); 2282 } 2283 2284 static 2285 void 2286 hammer2_strategy_read_callback(hammer2_chain_t *chain, struct buf *dbp, 2287 char *data, void *arg) 2288 { 2289 struct bio *nbio = arg; 2290 struct buf *bp = nbio->bio_buf; 2291 2292 if (chain->bref.type == HAMMER2_BREF_TYPE_INODE) { 2293 /* 2294 * Data is embedded in the inode (copy from inode). 2295 */ 2296 bcopy(((hammer2_inode_data_t *)data)->u.data, 2297 bp->b_data, HAMMER2_EMBEDDED_BYTES); 2298 bzero(bp->b_data + HAMMER2_EMBEDDED_BYTES, 2299 bp->b_bcount - HAMMER2_EMBEDDED_BYTES); 2300 bp->b_resid = 0; 2301 bp->b_error = 0; 2302 hammer2_chain_unlock(chain); 2303 biodone(nbio); 2304 } else if (chain->bref.type == HAMMER2_BREF_TYPE_DATA) { 2305 /* 2306 * Data is on-media, issue device I/O and copy. 2307 * 2308 * XXX direct-IO shortcut could go here XXX. 2309 */ 2310 bcopy(data, bp->b_data, bp->b_bcount); 2311 bp->b_flags |= B_NOTMETA; 2312 bp->b_resid = 0; 2313 bp->b_error = 0; 2314 hammer2_chain_unlock(chain); 2315 biodone(nbio); 2316 } else { 2317 if (dbp) 2318 bqrelse(dbp); 2319 panic("hammer2_strategy_read: unknown bref type"); 2320 chain = NULL; 2321 } 2322 } 2323 2324 static 2325 int 2326 hammer2_strategy_write(struct vop_strategy_args *ap) 2327 { 2328 KKASSERT(0); 2329 #if 0 2330 struct buf *bp; 2331 struct bio *bio; 2332 struct bio *nbio; 2333 hammer2_chain_t *chain; 2334 hammer2_mount_t *hmp; 2335 hammer2_inode_t *ip; 2336 2337 bio = ap->a_bio; 2338 bp = bio->bio_buf; 2339 ip = VTOI(ap->a_vp); 2340 nbio = push_bio(bio); 2341 2342 KKASSERT((bio->bio_offset & HAMMER2_PBUFMASK64) == 0); 2343 KKASSERT(nbio->bio_offset != 0 && nbio->bio_offset != ZFOFFSET); 2344 2345 if (nbio->bio_offset == NOOFFSET) { 2346 /* 2347 * The data is embedded in the inode. Note that strategy 2348 * calls for embedded data are synchronous in order to 2349 * ensure that ip->chain is stable. Chain modification 2350 * status is handled by the caller. 2351 */ 2352 KKASSERT(ip->chain->flags & HAMMER2_CHAIN_MODIFIED); 2353 KKASSERT(bio->bio_offset == 0); 2354 KKASSERT(ip->chain && ip->chain->data); 2355 chain = ip->chain; 2356 bcopy(bp->b_data, chain->data->ipdata.u.data, 2357 HAMMER2_EMBEDDED_BYTES); 2358 bp->b_resid = 0; 2359 bp->b_error = 0; 2360 biodone(nbio); 2361 } else { 2362 /* 2363 * Forward direct IO to the device 2364 */ 2365 hmp = nbio->bio_caller_info1.ptr; 2366 KKASSERT(hmp); 2367 vn_strategy(hmp->devvp, nbio); 2368 } 2369 return (0); 2370 #endif 2371 } 2372 2373 /* 2374 * hammer2_vop_ioctl { vp, command, data, fflag, cred } 2375 */ 2376 static 2377 int 2378 hammer2_vop_ioctl(struct vop_ioctl_args *ap) 2379 { 2380 hammer2_inode_t *ip; 2381 int error; 2382 2383 ip = VTOI(ap->a_vp); 2384 2385 error = hammer2_ioctl(ip, ap->a_command, (void *)ap->a_data, 2386 ap->a_fflag, ap->a_cred); 2387 return (error); 2388 } 2389 2390 static 2391 int 2392 hammer2_vop_mountctl(struct vop_mountctl_args *ap) 2393 { 2394 struct mount *mp; 2395 hammer2_pfsmount_t *pmp; 2396 int rc; 2397 2398 switch (ap->a_op) { 2399 case (MOUNTCTL_SET_EXPORT): 2400 mp = ap->a_head.a_ops->head.vv_mount; 2401 pmp = MPTOPMP(mp); 2402 2403 if (ap->a_ctllen != sizeof(struct export_args)) 2404 rc = (EINVAL); 2405 else 2406 rc = vfs_export(mp, &pmp->export, 2407 (const struct export_args *)ap->a_ctl); 2408 break; 2409 default: 2410 rc = vop_stdmountctl(ap); 2411 break; 2412 } 2413 return (rc); 2414 } 2415 2416 struct vop_ops hammer2_vnode_vops = { 2417 .vop_default = vop_defaultop, 2418 .vop_fsync = hammer2_vop_fsync, 2419 .vop_getpages = vop_stdgetpages, 2420 .vop_putpages = vop_stdputpages, 2421 .vop_access = hammer2_vop_access, 2422 .vop_advlock = hammer2_vop_advlock, 2423 .vop_close = hammer2_vop_close, 2424 .vop_nlink = hammer2_vop_nlink, 2425 .vop_ncreate = hammer2_vop_ncreate, 2426 .vop_nsymlink = hammer2_vop_nsymlink, 2427 .vop_nremove = hammer2_vop_nremove, 2428 .vop_nrmdir = hammer2_vop_nrmdir, 2429 .vop_nrename = hammer2_vop_nrename, 2430 .vop_getattr = hammer2_vop_getattr, 2431 .vop_setattr = hammer2_vop_setattr, 2432 .vop_readdir = hammer2_vop_readdir, 2433 .vop_readlink = hammer2_vop_readlink, 2434 .vop_getpages = vop_stdgetpages, 2435 .vop_putpages = vop_stdputpages, 2436 .vop_read = hammer2_vop_read, 2437 .vop_write = hammer2_vop_write, 2438 .vop_open = hammer2_vop_open, 2439 .vop_inactive = hammer2_vop_inactive, 2440 .vop_reclaim = hammer2_vop_reclaim, 2441 .vop_nresolve = hammer2_vop_nresolve, 2442 .vop_nlookupdotdot = hammer2_vop_nlookupdotdot, 2443 .vop_nmkdir = hammer2_vop_nmkdir, 2444 .vop_ioctl = hammer2_vop_ioctl, 2445 .vop_mountctl = hammer2_vop_mountctl, 2446 .vop_bmap = hammer2_vop_bmap, 2447 .vop_strategy = hammer2_vop_strategy, 2448 }; 2449 2450 struct vop_ops hammer2_spec_vops = { 2451 2452 }; 2453 2454 struct vop_ops hammer2_fifo_vops = { 2455 2456 }; 2457