1 /* 2 * Copyright (c) 2011-2015 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 * by Daniel Flores (GSOC 2013 - mentored by Matthew Dillon, compression) 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 3. Neither the name of The DragonFly Project nor the names of its 20 * contributors may be used to endorse or promote products derived 21 * from this software without specific, prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 31 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 /* 37 * Kernel Filesystem interface 38 * 39 * NOTE! local ipdata pointers must be reloaded on any modifying operation 40 * to the inode as its underlying chain may have changed. 41 */ 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/kernel.h> 46 #include <sys/fcntl.h> 47 #include <sys/buf.h> 48 #include <sys/proc.h> 49 #include <sys/namei.h> 50 #include <sys/mount.h> 51 #include <sys/vnode.h> 52 #include <sys/mountctl.h> 53 #include <sys/dirent.h> 54 #include <sys/uio.h> 55 #include <sys/objcache.h> 56 #include <sys/event.h> 57 #include <sys/file.h> 58 #include <vfs/fifofs/fifo.h> 59 60 #include "hammer2.h" 61 62 static int hammer2_read_file(hammer2_inode_t *ip, struct uio *uio, 63 int seqcount); 64 static int hammer2_write_file(hammer2_inode_t *ip, struct uio *uio, 65 int ioflag, int seqcount); 66 static void hammer2_extend_file(hammer2_inode_t *ip, hammer2_key_t nsize); 67 static void hammer2_truncate_file(hammer2_inode_t *ip, hammer2_key_t nsize); 68 69 struct objcache *cache_xops; 70 71 static __inline 72 void 73 hammer2_knote(struct vnode *vp, int flags) 74 { 75 if (flags) 76 KNOTE(&vp->v_pollinfo.vpi_kqinfo.ki_note, flags); 77 } 78 79 /* 80 * Last reference to a vnode is going away but it is still cached. 81 */ 82 static 83 int 84 hammer2_vop_inactive(struct vop_inactive_args *ap) 85 { 86 hammer2_inode_t *ip; 87 struct vnode *vp; 88 89 LOCKSTART; 90 vp = ap->a_vp; 91 ip = VTOI(vp); 92 93 /* 94 * Degenerate case 95 */ 96 if (ip == NULL) { 97 vrecycle(vp); 98 LOCKSTOP; 99 return (0); 100 } 101 102 /* 103 * Check for deleted inodes and recycle immediately on the last 104 * release. Be sure to destroy any left-over buffer cache buffers 105 * so we do not waste time trying to flush them. 106 * 107 * Note that deleting the file block chains under the inode chain 108 * would just be a waste of energy, so don't do it. 109 * 110 * WARNING: nvtruncbuf() can only be safely called without the inode 111 * lock held due to the way our write thread works. 112 */ 113 if (ip->flags & HAMMER2_INODE_ISUNLINKED) { 114 hammer2_key_t lbase; 115 int nblksize; 116 117 /* 118 * Detect updates to the embedded data which may be 119 * synchronized by the strategy code. Simply mark the 120 * inode modified so it gets picked up by our normal flush. 121 */ 122 nblksize = hammer2_calc_logical(ip, 0, &lbase, NULL); 123 nvtruncbuf(vp, 0, nblksize, 0, 0); 124 vrecycle(vp); 125 } 126 LOCKSTOP; 127 return (0); 128 } 129 130 /* 131 * Reclaim a vnode so that it can be reused; after the inode is 132 * disassociated, the filesystem must manage it alone. 133 */ 134 static 135 int 136 hammer2_vop_reclaim(struct vop_reclaim_args *ap) 137 { 138 hammer2_inode_t *ip; 139 hammer2_pfs_t *pmp; 140 struct vnode *vp; 141 142 LOCKSTART; 143 vp = ap->a_vp; 144 ip = VTOI(vp); 145 if (ip == NULL) { 146 LOCKSTOP; 147 return(0); 148 } 149 pmp = ip->pmp; 150 151 /* 152 * The final close of a deleted file or directory marks it for 153 * destruction. The DELETED flag allows the flusher to shortcut 154 * any modified blocks still unflushed (that is, just ignore them). 155 * 156 * HAMMER2 usually does not try to optimize the freemap by returning 157 * deleted blocks to it as it does not usually know how many snapshots 158 * might be referencing portions of the file/dir. 159 */ 160 vp->v_data = NULL; 161 ip->vp = NULL; 162 163 /* 164 * NOTE! We do not attempt to flush chains here, flushing is 165 * really fragile and could also deadlock. 166 */ 167 vclrisdirty(vp); 168 169 /* 170 * An unlinked inode may have been relinked to the ihidden directory. 171 * This occurs if the inode was unlinked while open. Reclamation of 172 * these inodes requires processing we cannot safely do here so add 173 * the inode to the sideq in that situation. 174 * 175 * A modified inode may require chain synchronization which will no 176 * longer be driven by a sync or fsync without the vnode, also use 177 * the sideq for that. 178 * 179 * A reclaim can occur at any time so we cannot safely start a 180 * transaction to handle reclamation of unlinked files. Instead, 181 * the ip is left with a reference and placed on a linked list and 182 * handled later on. 183 */ 184 185 if ((ip->flags & (HAMMER2_INODE_ISUNLINKED | 186 HAMMER2_INODE_MODIFIED | 187 HAMMER2_INODE_RESIZED)) && 188 (ip->flags & HAMMER2_INODE_ISDELETED) == 0) { 189 hammer2_inode_sideq_t *ipul; 190 191 ipul = kmalloc(sizeof(*ipul), pmp->minode, M_WAITOK | M_ZERO); 192 ipul->ip = ip; 193 194 hammer2_spin_ex(&pmp->list_spin); 195 if ((ip->flags & HAMMER2_INODE_ONSIDEQ) == 0) { 196 /* ref -> sideq */ 197 atomic_set_int(&ip->flags, HAMMER2_INODE_ONSIDEQ); 198 TAILQ_INSERT_TAIL(&pmp->sideq, ipul, entry); 199 hammer2_spin_unex(&pmp->list_spin); 200 } else { 201 hammer2_spin_unex(&pmp->list_spin); 202 kfree(ipul, pmp->minode); 203 hammer2_inode_drop(ip); /* vp ref */ 204 } 205 /* retain ref from vp for ipul */ 206 } else { 207 hammer2_inode_drop(ip); /* vp ref */ 208 } 209 210 /* 211 * XXX handle background sync when ip dirty, kernel will no longer 212 * notify us regarding this inode because there is no longer a 213 * vnode attached to it. 214 */ 215 216 LOCKSTOP; 217 return (0); 218 } 219 220 static 221 int 222 hammer2_vop_fsync(struct vop_fsync_args *ap) 223 { 224 hammer2_inode_t *ip; 225 struct vnode *vp; 226 227 LOCKSTART; 228 vp = ap->a_vp; 229 ip = VTOI(vp); 230 231 #if 0 232 /* XXX can't do this yet */ 233 hammer2_trans_init(ip->pmp, HAMMER2_TRANS_ISFLUSH); 234 vfsync(vp, ap->a_waitfor, 1, NULL, NULL); 235 #endif 236 hammer2_trans_init(ip->pmp, 0); 237 vfsync(vp, ap->a_waitfor, 1, NULL, NULL); 238 239 /* 240 * Calling chain_flush here creates a lot of duplicative 241 * COW operations due to non-optimal vnode ordering. 242 * 243 * Only do it for an actual fsync() syscall. The other forms 244 * which call this function will eventually call chain_flush 245 * on the volume root as a catch-all, which is far more optimal. 246 */ 247 hammer2_inode_lock(ip, 0); 248 if (ip->flags & HAMMER2_INODE_MODIFIED) 249 hammer2_inode_chain_sync(ip); 250 hammer2_inode_unlock(ip); 251 hammer2_trans_done(ip->pmp); 252 253 LOCKSTOP; 254 return (0); 255 } 256 257 static 258 int 259 hammer2_vop_access(struct vop_access_args *ap) 260 { 261 hammer2_inode_t *ip = VTOI(ap->a_vp); 262 uid_t uid; 263 gid_t gid; 264 int error; 265 266 LOCKSTART; 267 hammer2_inode_lock(ip, HAMMER2_RESOLVE_SHARED); 268 uid = hammer2_to_unix_xid(&ip->meta.uid); 269 gid = hammer2_to_unix_xid(&ip->meta.gid); 270 error = vop_helper_access(ap, uid, gid, ip->meta.mode, ip->meta.uflags); 271 hammer2_inode_unlock(ip); 272 273 LOCKSTOP; 274 return (error); 275 } 276 277 static 278 int 279 hammer2_vop_getattr(struct vop_getattr_args *ap) 280 { 281 hammer2_pfs_t *pmp; 282 hammer2_inode_t *ip; 283 struct vnode *vp; 284 struct vattr *vap; 285 hammer2_chain_t *chain; 286 int i; 287 288 LOCKSTART; 289 vp = ap->a_vp; 290 vap = ap->a_vap; 291 292 ip = VTOI(vp); 293 pmp = ip->pmp; 294 295 hammer2_inode_lock(ip, HAMMER2_RESOLVE_SHARED); 296 297 vap->va_fsid = pmp->mp->mnt_stat.f_fsid.val[0]; 298 vap->va_fileid = ip->meta.inum; 299 vap->va_mode = ip->meta.mode; 300 vap->va_nlink = ip->meta.nlinks; 301 vap->va_uid = hammer2_to_unix_xid(&ip->meta.uid); 302 vap->va_gid = hammer2_to_unix_xid(&ip->meta.gid); 303 vap->va_rmajor = 0; 304 vap->va_rminor = 0; 305 vap->va_size = ip->meta.size; /* protected by shared lock */ 306 vap->va_blocksize = HAMMER2_PBUFSIZE; 307 vap->va_flags = ip->meta.uflags; 308 hammer2_time_to_timespec(ip->meta.ctime, &vap->va_ctime); 309 hammer2_time_to_timespec(ip->meta.mtime, &vap->va_mtime); 310 hammer2_time_to_timespec(ip->meta.mtime, &vap->va_atime); 311 vap->va_gen = 1; 312 vap->va_bytes = 0; 313 if (ip->meta.type == HAMMER2_OBJTYPE_DIRECTORY) { 314 /* 315 * Can't really calculate directory use sans the files under 316 * it, just assume one block for now. 317 */ 318 vap->va_bytes += HAMMER2_INODE_BYTES; 319 } else { 320 for (i = 0; i < ip->cluster.nchains; ++i) { 321 if ((chain = ip->cluster.array[i].chain) != NULL) { 322 if (vap->va_bytes < chain->bref.data_count) 323 vap->va_bytes = chain->bref.data_count; 324 } 325 } 326 } 327 vap->va_type = hammer2_get_vtype(ip->meta.type); 328 vap->va_filerev = 0; 329 vap->va_uid_uuid = ip->meta.uid; 330 vap->va_gid_uuid = ip->meta.gid; 331 vap->va_vaflags = VA_UID_UUID_VALID | VA_GID_UUID_VALID | 332 VA_FSID_UUID_VALID; 333 334 hammer2_inode_unlock(ip); 335 336 LOCKSTOP; 337 return (0); 338 } 339 340 static 341 int 342 hammer2_vop_setattr(struct vop_setattr_args *ap) 343 { 344 hammer2_inode_t *ip; 345 struct vnode *vp; 346 struct vattr *vap; 347 int error; 348 int kflags = 0; 349 uint64_t ctime; 350 351 LOCKSTART; 352 vp = ap->a_vp; 353 vap = ap->a_vap; 354 hammer2_update_time(&ctime); 355 356 ip = VTOI(vp); 357 358 if (ip->pmp->ronly) { 359 LOCKSTOP; 360 return(EROFS); 361 } 362 363 hammer2_pfs_memory_wait(ip->pmp); 364 hammer2_trans_init(ip->pmp, 0); 365 hammer2_inode_lock(ip, 0); 366 error = 0; 367 368 if (vap->va_flags != VNOVAL) { 369 u_int32_t flags; 370 371 flags = ip->meta.uflags; 372 error = vop_helper_setattr_flags(&flags, vap->va_flags, 373 hammer2_to_unix_xid(&ip->meta.uid), 374 ap->a_cred); 375 if (error == 0) { 376 if (ip->meta.uflags != flags) { 377 hammer2_inode_modify(ip); 378 ip->meta.uflags = flags; 379 ip->meta.ctime = ctime; 380 kflags |= NOTE_ATTRIB; 381 } 382 if (ip->meta.uflags & (IMMUTABLE | APPEND)) { 383 error = 0; 384 goto done; 385 } 386 } 387 goto done; 388 } 389 if (ip->meta.uflags & (IMMUTABLE | APPEND)) { 390 error = EPERM; 391 goto done; 392 } 393 if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) { 394 mode_t cur_mode = ip->meta.mode; 395 uid_t cur_uid = hammer2_to_unix_xid(&ip->meta.uid); 396 gid_t cur_gid = hammer2_to_unix_xid(&ip->meta.gid); 397 uuid_t uuid_uid; 398 uuid_t uuid_gid; 399 400 error = vop_helper_chown(ap->a_vp, vap->va_uid, vap->va_gid, 401 ap->a_cred, 402 &cur_uid, &cur_gid, &cur_mode); 403 if (error == 0) { 404 hammer2_guid_to_uuid(&uuid_uid, cur_uid); 405 hammer2_guid_to_uuid(&uuid_gid, cur_gid); 406 if (bcmp(&uuid_uid, &ip->meta.uid, sizeof(uuid_uid)) || 407 bcmp(&uuid_gid, &ip->meta.gid, sizeof(uuid_gid)) || 408 ip->meta.mode != cur_mode 409 ) { 410 hammer2_inode_modify(ip); 411 ip->meta.uid = uuid_uid; 412 ip->meta.gid = uuid_gid; 413 ip->meta.mode = cur_mode; 414 ip->meta.ctime = ctime; 415 } 416 kflags |= NOTE_ATTRIB; 417 } 418 } 419 420 /* 421 * Resize the file 422 */ 423 if (vap->va_size != VNOVAL && ip->meta.size != vap->va_size) { 424 switch(vp->v_type) { 425 case VREG: 426 if (vap->va_size == ip->meta.size) 427 break; 428 if (vap->va_size < ip->meta.size) { 429 hammer2_truncate_file(ip, vap->va_size); 430 } else { 431 hammer2_extend_file(ip, vap->va_size); 432 } 433 hammer2_inode_modify(ip); 434 ip->meta.mtime = ctime; 435 break; 436 default: 437 error = EINVAL; 438 goto done; 439 } 440 } 441 #if 0 442 /* atime not supported */ 443 if (vap->va_atime.tv_sec != VNOVAL) { 444 hammer2_inode_modify(ip); 445 ip->meta.atime = hammer2_timespec_to_time(&vap->va_atime); 446 kflags |= NOTE_ATTRIB; 447 } 448 #endif 449 if (vap->va_mode != (mode_t)VNOVAL) { 450 mode_t cur_mode = ip->meta.mode; 451 uid_t cur_uid = hammer2_to_unix_xid(&ip->meta.uid); 452 gid_t cur_gid = hammer2_to_unix_xid(&ip->meta.gid); 453 454 error = vop_helper_chmod(ap->a_vp, vap->va_mode, ap->a_cred, 455 cur_uid, cur_gid, &cur_mode); 456 if (error == 0 && ip->meta.mode != cur_mode) { 457 hammer2_inode_modify(ip); 458 ip->meta.mode = cur_mode; 459 ip->meta.ctime = ctime; 460 kflags |= NOTE_ATTRIB; 461 } 462 } 463 464 if (vap->va_mtime.tv_sec != VNOVAL) { 465 hammer2_inode_modify(ip); 466 ip->meta.mtime = hammer2_timespec_to_time(&vap->va_mtime); 467 kflags |= NOTE_ATTRIB; 468 } 469 470 done: 471 /* 472 * If a truncation occurred we must call inode_fsync() now in order 473 * to trim the related data chains, otherwise a later expansion can 474 * cause havoc. 475 * 476 * If an extend occured that changed the DIRECTDATA state, we must 477 * call inode_fsync now in order to prepare the inode's indirect 478 * block table. 479 */ 480 if (ip->flags & HAMMER2_INODE_RESIZED) 481 hammer2_inode_chain_sync(ip); 482 483 /* 484 * Cleanup. 485 */ 486 hammer2_inode_unlock(ip); 487 hammer2_trans_done(ip->pmp); 488 hammer2_knote(ip->vp, kflags); 489 490 LOCKSTOP; 491 return (error); 492 } 493 494 static 495 int 496 hammer2_vop_readdir(struct vop_readdir_args *ap) 497 { 498 hammer2_xop_readdir_t *xop; 499 hammer2_blockref_t bref; 500 hammer2_inode_t *ip; 501 hammer2_tid_t inum; 502 hammer2_key_t lkey; 503 struct uio *uio; 504 off_t *cookies; 505 off_t saveoff; 506 int cookie_index; 507 int ncookies; 508 int error; 509 int eofflag; 510 int dtype; 511 int r; 512 513 LOCKSTART; 514 ip = VTOI(ap->a_vp); 515 uio = ap->a_uio; 516 saveoff = uio->uio_offset; 517 eofflag = 0; 518 error = 0; 519 520 /* 521 * Setup cookies directory entry cookies if requested 522 */ 523 if (ap->a_ncookies) { 524 ncookies = uio->uio_resid / 16 + 1; 525 if (ncookies > 1024) 526 ncookies = 1024; 527 cookies = kmalloc(ncookies * sizeof(off_t), M_TEMP, M_WAITOK); 528 } else { 529 ncookies = -1; 530 cookies = NULL; 531 } 532 cookie_index = 0; 533 534 hammer2_inode_lock(ip, HAMMER2_RESOLVE_SHARED); 535 536 /* 537 * Handle artificial entries. To ensure that only positive 64 bit 538 * quantities are returned to userland we always strip off bit 63. 539 * The hash code is designed such that codes 0x0000-0x7FFF are not 540 * used, allowing us to use these codes for articial entries. 541 * 542 * Entry 0 is used for '.' and entry 1 is used for '..'. Do not 543 * allow '..' to cross the mount point into (e.g.) the super-root. 544 */ 545 if (saveoff == 0) { 546 inum = ip->meta.inum & HAMMER2_DIRHASH_USERMSK; 547 r = vop_write_dirent(&error, uio, inum, DT_DIR, 1, "."); 548 if (r) 549 goto done; 550 if (cookies) 551 cookies[cookie_index] = saveoff; 552 ++saveoff; 553 ++cookie_index; 554 if (cookie_index == ncookies) 555 goto done; 556 } 557 558 if (saveoff == 1) { 559 /* 560 * Be careful with lockorder when accessing ".." 561 * 562 * (ip is the current dir. xip is the parent dir). 563 */ 564 inum = ip->meta.inum & HAMMER2_DIRHASH_USERMSK; 565 if (ip->pip && ip != ip->pmp->iroot) 566 inum = ip->pip->meta.inum & HAMMER2_DIRHASH_USERMSK; 567 r = vop_write_dirent(&error, uio, inum, DT_DIR, 2, ".."); 568 if (r) 569 goto done; 570 if (cookies) 571 cookies[cookie_index] = saveoff; 572 ++saveoff; 573 ++cookie_index; 574 if (cookie_index == ncookies) 575 goto done; 576 } 577 578 lkey = saveoff | HAMMER2_DIRHASH_VISIBLE; 579 if (hammer2_debug & 0x0020) 580 kprintf("readdir: lkey %016jx\n", lkey); 581 if (error) 582 goto done; 583 584 /* 585 * Use XOP for cluster scan. 586 * 587 * parent is the inode cluster, already locked for us. Don't 588 * double lock shared locks as this will screw up upgrades. 589 */ 590 xop = hammer2_xop_alloc(ip, 0); 591 xop->lkey = lkey; 592 hammer2_xop_start(&xop->head, hammer2_xop_readdir); 593 594 for (;;) { 595 const hammer2_inode_data_t *ripdata; 596 597 error = hammer2_xop_collect(&xop->head, 0); 598 if (error) 599 break; 600 if (cookie_index == ncookies) 601 break; 602 if (hammer2_debug & 0x0020) 603 kprintf("cluster chain %p %p\n", 604 xop->head.cluster.focus, 605 (xop->head.cluster.focus ? 606 xop->head.cluster.focus->data : (void *)-1)); 607 ripdata = &hammer2_cluster_rdata(&xop->head.cluster)->ipdata; 608 hammer2_cluster_bref(&xop->head.cluster, &bref); 609 if (bref.type == HAMMER2_BREF_TYPE_INODE) { 610 dtype = hammer2_get_dtype(ripdata); 611 saveoff = bref.key & HAMMER2_DIRHASH_USERMSK; 612 r = vop_write_dirent(&error, uio, 613 ripdata->meta.inum & 614 HAMMER2_DIRHASH_USERMSK, 615 dtype, 616 ripdata->meta.name_len, 617 ripdata->filename); 618 if (r) 619 break; 620 if (cookies) 621 cookies[cookie_index] = saveoff; 622 ++cookie_index; 623 } else { 624 /* XXX chain error */ 625 kprintf("bad chain type readdir %d\n", bref.type); 626 } 627 } 628 hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP); 629 if (error == ENOENT) { 630 error = 0; 631 eofflag = 1; 632 saveoff = (hammer2_key_t)-1; 633 } else { 634 saveoff = bref.key & HAMMER2_DIRHASH_USERMSK; 635 } 636 done: 637 hammer2_inode_unlock(ip); 638 if (ap->a_eofflag) 639 *ap->a_eofflag = eofflag; 640 if (hammer2_debug & 0x0020) 641 kprintf("readdir: done at %016jx\n", saveoff); 642 uio->uio_offset = saveoff & ~HAMMER2_DIRHASH_VISIBLE; 643 if (error && cookie_index == 0) { 644 if (cookies) { 645 kfree(cookies, M_TEMP); 646 *ap->a_ncookies = 0; 647 *ap->a_cookies = NULL; 648 } 649 } else { 650 if (cookies) { 651 *ap->a_ncookies = cookie_index; 652 *ap->a_cookies = cookies; 653 } 654 } 655 LOCKSTOP; 656 return (error); 657 } 658 659 /* 660 * hammer2_vop_readlink { vp, uio, cred } 661 */ 662 static 663 int 664 hammer2_vop_readlink(struct vop_readlink_args *ap) 665 { 666 struct vnode *vp; 667 hammer2_inode_t *ip; 668 int error; 669 670 vp = ap->a_vp; 671 if (vp->v_type != VLNK) 672 return (EINVAL); 673 ip = VTOI(vp); 674 675 error = hammer2_read_file(ip, ap->a_uio, 0); 676 return (error); 677 } 678 679 static 680 int 681 hammer2_vop_read(struct vop_read_args *ap) 682 { 683 struct vnode *vp; 684 hammer2_inode_t *ip; 685 struct uio *uio; 686 int error; 687 int seqcount; 688 int bigread; 689 690 /* 691 * Read operations supported on this vnode? 692 */ 693 vp = ap->a_vp; 694 if (vp->v_type != VREG) 695 return (EINVAL); 696 697 /* 698 * Misc 699 */ 700 ip = VTOI(vp); 701 uio = ap->a_uio; 702 error = 0; 703 704 seqcount = ap->a_ioflag >> 16; 705 bigread = (uio->uio_resid > 100 * 1024 * 1024); 706 707 error = hammer2_read_file(ip, uio, seqcount); 708 return (error); 709 } 710 711 static 712 int 713 hammer2_vop_write(struct vop_write_args *ap) 714 { 715 hammer2_inode_t *ip; 716 thread_t td; 717 struct vnode *vp; 718 struct uio *uio; 719 int error; 720 int seqcount; 721 722 /* 723 * Read operations supported on this vnode? 724 */ 725 vp = ap->a_vp; 726 if (vp->v_type != VREG) 727 return (EINVAL); 728 729 /* 730 * Misc 731 */ 732 ip = VTOI(vp); 733 uio = ap->a_uio; 734 error = 0; 735 if (ip->pmp->ronly) { 736 return (EROFS); 737 } 738 739 seqcount = ap->a_ioflag >> 16; 740 741 /* 742 * Check resource limit 743 */ 744 if (uio->uio_resid > 0 && (td = uio->uio_td) != NULL && td->td_proc && 745 uio->uio_offset + uio->uio_resid > 746 td->td_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur) { 747 lwpsignal(td->td_proc, td->td_lwp, SIGXFSZ); 748 return (EFBIG); 749 } 750 751 /* 752 * The transaction interlocks against flushes initiations 753 * (note: but will run concurrently with the actual flush). 754 */ 755 hammer2_trans_init(ip->pmp, 0); 756 error = hammer2_write_file(ip, uio, ap->a_ioflag, seqcount); 757 hammer2_trans_done(ip->pmp); 758 759 return (error); 760 } 761 762 /* 763 * Perform read operations on a file or symlink given an UNLOCKED 764 * inode and uio. 765 * 766 * The passed ip is not locked. 767 */ 768 static 769 int 770 hammer2_read_file(hammer2_inode_t *ip, struct uio *uio, int seqcount) 771 { 772 hammer2_off_t size; 773 struct buf *bp; 774 int error; 775 776 error = 0; 777 778 /* 779 * UIO read loop. 780 * 781 * WARNING! Assumes that the kernel interlocks size changes at the 782 * vnode level. 783 */ 784 hammer2_mtx_sh(&ip->lock); 785 size = ip->meta.size; 786 hammer2_mtx_unlock(&ip->lock); 787 788 while (uio->uio_resid > 0 && uio->uio_offset < size) { 789 hammer2_key_t lbase; 790 hammer2_key_t leof; 791 int lblksize; 792 int loff; 793 int n; 794 795 lblksize = hammer2_calc_logical(ip, uio->uio_offset, 796 &lbase, &leof); 797 798 error = cluster_read(ip->vp, leof, lbase, lblksize, 799 uio->uio_resid, seqcount * BKVASIZE, 800 &bp); 801 802 if (error) 803 break; 804 loff = (int)(uio->uio_offset - lbase); 805 n = lblksize - loff; 806 if (n > uio->uio_resid) 807 n = uio->uio_resid; 808 if (n > size - uio->uio_offset) 809 n = (int)(size - uio->uio_offset); 810 bp->b_flags |= B_AGE; 811 uiomove((char *)bp->b_data + loff, n, uio); 812 bqrelse(bp); 813 } 814 return (error); 815 } 816 817 /* 818 * Write to the file represented by the inode via the logical buffer cache. 819 * The inode may represent a regular file or a symlink. 820 * 821 * The inode must not be locked. 822 */ 823 static 824 int 825 hammer2_write_file(hammer2_inode_t *ip, struct uio *uio, 826 int ioflag, int seqcount) 827 { 828 hammer2_key_t old_eof; 829 hammer2_key_t new_eof; 830 struct buf *bp; 831 int kflags; 832 int error; 833 int modified; 834 835 /* 836 * Setup if append 837 * 838 * WARNING! Assumes that the kernel interlocks size changes at the 839 * vnode level. 840 */ 841 hammer2_mtx_ex(&ip->lock); 842 if (ioflag & IO_APPEND) 843 uio->uio_offset = ip->meta.size; 844 old_eof = ip->meta.size; 845 846 /* 847 * Extend the file if necessary. If the write fails at some point 848 * we will truncate it back down to cover as much as we were able 849 * to write. 850 * 851 * Doing this now makes it easier to calculate buffer sizes in 852 * the loop. 853 */ 854 kflags = 0; 855 error = 0; 856 modified = 0; 857 858 if (uio->uio_offset + uio->uio_resid > old_eof) { 859 new_eof = uio->uio_offset + uio->uio_resid; 860 modified = 1; 861 hammer2_extend_file(ip, new_eof); 862 kflags |= NOTE_EXTEND; 863 } else { 864 new_eof = old_eof; 865 } 866 hammer2_mtx_unlock(&ip->lock); 867 868 /* 869 * UIO write loop 870 */ 871 while (uio->uio_resid > 0) { 872 hammer2_key_t lbase; 873 int trivial; 874 int endofblk; 875 int lblksize; 876 int loff; 877 int n; 878 879 /* 880 * Don't allow the buffer build to blow out the buffer 881 * cache. 882 */ 883 if ((ioflag & IO_RECURSE) == 0) 884 bwillwrite(HAMMER2_PBUFSIZE); 885 886 /* 887 * This nominally tells us how much we can cluster and 888 * what the logical buffer size needs to be. Currently 889 * we don't try to cluster the write and just handle one 890 * block at a time. 891 */ 892 lblksize = hammer2_calc_logical(ip, uio->uio_offset, 893 &lbase, NULL); 894 loff = (int)(uio->uio_offset - lbase); 895 896 KKASSERT(lblksize <= 65536); 897 898 /* 899 * Calculate bytes to copy this transfer and whether the 900 * copy completely covers the buffer or not. 901 */ 902 trivial = 0; 903 n = lblksize - loff; 904 if (n > uio->uio_resid) { 905 n = uio->uio_resid; 906 if (loff == lbase && uio->uio_offset + n == new_eof) 907 trivial = 1; 908 endofblk = 0; 909 } else { 910 if (loff == 0) 911 trivial = 1; 912 endofblk = 1; 913 } 914 915 /* 916 * Get the buffer 917 */ 918 if (uio->uio_segflg == UIO_NOCOPY) { 919 /* 920 * Issuing a write with the same data backing the 921 * buffer. Instantiate the buffer to collect the 922 * backing vm pages, then read-in any missing bits. 923 * 924 * This case is used by vop_stdputpages(). 925 */ 926 bp = getblk(ip->vp, lbase, lblksize, GETBLK_BHEAVY, 0); 927 if ((bp->b_flags & B_CACHE) == 0) { 928 bqrelse(bp); 929 error = bread(ip->vp, lbase, lblksize, &bp); 930 } 931 } else if (trivial) { 932 /* 933 * Even though we are entirely overwriting the buffer 934 * we may still have to zero it out to avoid a 935 * mmap/write visibility issue. 936 */ 937 bp = getblk(ip->vp, lbase, lblksize, GETBLK_BHEAVY, 0); 938 if ((bp->b_flags & B_CACHE) == 0) 939 vfs_bio_clrbuf(bp); 940 } else { 941 /* 942 * Partial overwrite, read in any missing bits then 943 * replace the portion being written. 944 * 945 * (The strategy code will detect zero-fill physical 946 * blocks for this case). 947 */ 948 error = bread(ip->vp, lbase, lblksize, &bp); 949 if (error == 0) 950 bheavy(bp); 951 } 952 953 if (error) { 954 brelse(bp); 955 break; 956 } 957 958 /* 959 * Ok, copy the data in 960 */ 961 error = uiomove(bp->b_data + loff, n, uio); 962 kflags |= NOTE_WRITE; 963 modified = 1; 964 if (error) { 965 brelse(bp); 966 break; 967 } 968 969 /* 970 * WARNING: Pageout daemon will issue UIO_NOCOPY writes 971 * with IO_SYNC or IO_ASYNC set. These writes 972 * must be handled as the pageout daemon expects. 973 */ 974 if (ioflag & IO_SYNC) { 975 bwrite(bp); 976 } else if ((ioflag & IO_DIRECT) && endofblk) { 977 bawrite(bp); 978 } else if (ioflag & IO_ASYNC) { 979 bawrite(bp); 980 } else { 981 bdwrite(bp); 982 } 983 } 984 985 /* 986 * Cleanup. If we extended the file EOF but failed to write through 987 * the entire write is a failure and we have to back-up. 988 */ 989 if (error && new_eof != old_eof) { 990 hammer2_mtx_ex(&ip->lock); 991 hammer2_truncate_file(ip, old_eof); 992 if (ip->flags & HAMMER2_INODE_MODIFIED) 993 hammer2_inode_chain_sync(ip); 994 hammer2_mtx_unlock(&ip->lock); 995 } else if (modified) { 996 hammer2_mtx_ex(&ip->lock); 997 hammer2_inode_modify(ip); 998 hammer2_update_time(&ip->meta.mtime); 999 if (ip->flags & HAMMER2_INODE_MODIFIED) 1000 hammer2_inode_chain_sync(ip); 1001 hammer2_mtx_unlock(&ip->lock); 1002 hammer2_knote(ip->vp, kflags); 1003 } 1004 hammer2_trans_assert_strategy(ip->pmp); 1005 1006 return error; 1007 } 1008 1009 /* 1010 * Truncate the size of a file. The inode must not be locked. 1011 * 1012 * We must unconditionally set HAMMER2_INODE_RESIZED to properly 1013 * ensure that any on-media data beyond the new file EOF has been destroyed. 1014 * 1015 * WARNING: nvtruncbuf() can only be safely called without the inode lock 1016 * held due to the way our write thread works. If the truncation 1017 * occurs in the middle of a buffer, nvtruncbuf() is responsible 1018 * for dirtying that buffer and zeroing out trailing bytes. 1019 * 1020 * WARNING! Assumes that the kernel interlocks size changes at the 1021 * vnode level. 1022 * 1023 * WARNING! Caller assumes responsibility for removing dead blocks 1024 * if INODE_RESIZED is set. 1025 */ 1026 static 1027 void 1028 hammer2_truncate_file(hammer2_inode_t *ip, hammer2_key_t nsize) 1029 { 1030 hammer2_key_t lbase; 1031 int nblksize; 1032 1033 LOCKSTART; 1034 hammer2_mtx_unlock(&ip->lock); 1035 if (ip->vp) { 1036 nblksize = hammer2_calc_logical(ip, nsize, &lbase, NULL); 1037 nvtruncbuf(ip->vp, nsize, 1038 nblksize, (int)nsize & (nblksize - 1), 1039 0); 1040 } 1041 hammer2_mtx_ex(&ip->lock); 1042 KKASSERT((ip->flags & HAMMER2_INODE_RESIZED) == 0); 1043 ip->osize = ip->meta.size; 1044 ip->meta.size = nsize; 1045 atomic_set_int(&ip->flags, HAMMER2_INODE_RESIZED); 1046 hammer2_inode_modify(ip); 1047 LOCKSTOP; 1048 } 1049 1050 /* 1051 * Extend the size of a file. The inode must not be locked. 1052 * 1053 * Even though the file size is changing, we do not have to set the 1054 * INODE_RESIZED bit unless the file size crosses the EMBEDDED_BYTES 1055 * boundary. When this occurs a hammer2_inode_chain_sync() is required 1056 * to prepare the inode cluster's indirect block table, otherwise 1057 * async execution of the strategy code will implode on us. 1058 * 1059 * WARNING! Assumes that the kernel interlocks size changes at the 1060 * vnode level. 1061 * 1062 * WARNING! Caller assumes responsibility for transitioning out 1063 * of the inode DIRECTDATA mode if INODE_RESIZED is set. 1064 */ 1065 static 1066 void 1067 hammer2_extend_file(hammer2_inode_t *ip, hammer2_key_t nsize) 1068 { 1069 hammer2_key_t lbase; 1070 hammer2_key_t osize; 1071 int oblksize; 1072 int nblksize; 1073 1074 LOCKSTART; 1075 1076 KKASSERT((ip->flags & HAMMER2_INODE_RESIZED) == 0); 1077 hammer2_inode_modify(ip); 1078 osize = ip->meta.size; 1079 ip->osize = osize; 1080 ip->meta.size = nsize; 1081 1082 if (osize <= HAMMER2_EMBEDDED_BYTES && nsize > HAMMER2_EMBEDDED_BYTES) { 1083 atomic_set_int(&ip->flags, HAMMER2_INODE_RESIZED); 1084 hammer2_inode_chain_sync(ip); 1085 } 1086 1087 hammer2_mtx_unlock(&ip->lock); 1088 if (ip->vp) { 1089 oblksize = hammer2_calc_logical(ip, osize, &lbase, NULL); 1090 nblksize = hammer2_calc_logical(ip, nsize, &lbase, NULL); 1091 nvextendbuf(ip->vp, 1092 osize, nsize, 1093 oblksize, nblksize, 1094 -1, -1, 0); 1095 } 1096 hammer2_mtx_ex(&ip->lock); 1097 1098 LOCKSTOP; 1099 } 1100 1101 static 1102 int 1103 hammer2_vop_nresolve(struct vop_nresolve_args *ap) 1104 { 1105 hammer2_xop_nresolve_t *xop; 1106 hammer2_inode_t *ip; 1107 hammer2_inode_t *dip; 1108 struct namecache *ncp; 1109 struct vnode *vp; 1110 int error; 1111 1112 LOCKSTART; 1113 dip = VTOI(ap->a_dvp); 1114 xop = hammer2_xop_alloc(dip, 0); 1115 1116 ncp = ap->a_nch->ncp; 1117 hammer2_xop_setname(&xop->head, ncp->nc_name, ncp->nc_nlen); 1118 1119 /* 1120 * Note: In DragonFly the kernel handles '.' and '..'. 1121 */ 1122 hammer2_inode_lock(dip, HAMMER2_RESOLVE_SHARED); 1123 hammer2_xop_start(&xop->head, hammer2_xop_nresolve); 1124 1125 error = hammer2_xop_collect(&xop->head, 0); 1126 if (error) { 1127 ip = NULL; 1128 } else { 1129 ip = hammer2_inode_get(dip->pmp, dip, &xop->head.cluster, -1); 1130 } 1131 hammer2_inode_unlock(dip); 1132 1133 /* 1134 * Acquire the related vnode 1135 * 1136 * NOTE: For error processing, only ENOENT resolves the namecache 1137 * entry to NULL, otherwise we just return the error and 1138 * leave the namecache unresolved. 1139 * 1140 * NOTE: multiple hammer2_inode structures can be aliased to the 1141 * same chain element, for example for hardlinks. This 1142 * use case does not 'reattach' inode associations that 1143 * might already exist, but always allocates a new one. 1144 * 1145 * WARNING: inode structure is locked exclusively via inode_get 1146 * but chain was locked shared. inode_unlock() 1147 * will handle it properly. 1148 */ 1149 if (ip) { 1150 vp = hammer2_igetv(ip, &error); 1151 if (error == 0) { 1152 vn_unlock(vp); 1153 cache_setvp(ap->a_nch, vp); 1154 } else if (error == ENOENT) { 1155 cache_setvp(ap->a_nch, NULL); 1156 } 1157 hammer2_inode_unlock(ip); 1158 1159 /* 1160 * The vp should not be released until after we've disposed 1161 * of our locks, because it might cause vop_inactive() to 1162 * be called. 1163 */ 1164 if (vp) 1165 vrele(vp); 1166 } else { 1167 error = ENOENT; 1168 cache_setvp(ap->a_nch, NULL); 1169 } 1170 hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP); 1171 KASSERT(error || ap->a_nch->ncp->nc_vp != NULL, 1172 ("resolve error %d/%p ap %p\n", 1173 error, ap->a_nch->ncp->nc_vp, ap)); 1174 LOCKSTOP; 1175 1176 return error; 1177 } 1178 1179 static 1180 int 1181 hammer2_vop_nlookupdotdot(struct vop_nlookupdotdot_args *ap) 1182 { 1183 hammer2_inode_t *dip; 1184 hammer2_inode_t *ip; 1185 int error; 1186 1187 LOCKSTART; 1188 dip = VTOI(ap->a_dvp); 1189 1190 if ((ip = dip->pip) == NULL) { 1191 *ap->a_vpp = NULL; 1192 LOCKSTOP; 1193 return ENOENT; 1194 } 1195 hammer2_inode_lock(ip, 0); 1196 *ap->a_vpp = hammer2_igetv(ip, &error); 1197 hammer2_inode_unlock(ip); 1198 1199 LOCKSTOP; 1200 return error; 1201 } 1202 1203 static 1204 int 1205 hammer2_vop_nmkdir(struct vop_nmkdir_args *ap) 1206 { 1207 hammer2_inode_t *dip; 1208 hammer2_inode_t *nip; 1209 struct namecache *ncp; 1210 const uint8_t *name; 1211 size_t name_len; 1212 int error; 1213 1214 LOCKSTART; 1215 dip = VTOI(ap->a_dvp); 1216 if (dip->pmp->ronly) { 1217 LOCKSTOP; 1218 return (EROFS); 1219 } 1220 1221 ncp = ap->a_nch->ncp; 1222 name = ncp->nc_name; 1223 name_len = ncp->nc_nlen; 1224 1225 hammer2_pfs_memory_wait(dip->pmp); 1226 hammer2_trans_init(dip->pmp, 0); 1227 nip = hammer2_inode_create(dip, ap->a_vap, ap->a_cred, 1228 name, name_len, 0, 1229 hammer2_trans_newinum(dip->pmp), 0, 0, 1230 0, &error); 1231 if (error) { 1232 KKASSERT(nip == NULL); 1233 *ap->a_vpp = NULL; 1234 } else { 1235 *ap->a_vpp = hammer2_igetv(nip, &error); 1236 hammer2_inode_unlock(nip); 1237 } 1238 hammer2_trans_done(dip->pmp); 1239 1240 if (error == 0) { 1241 cache_setunresolved(ap->a_nch); 1242 cache_setvp(ap->a_nch, *ap->a_vpp); 1243 } 1244 LOCKSTOP; 1245 return error; 1246 } 1247 1248 static 1249 int 1250 hammer2_vop_open(struct vop_open_args *ap) 1251 { 1252 return vop_stdopen(ap); 1253 } 1254 1255 /* 1256 * hammer2_vop_advlock { vp, id, op, fl, flags } 1257 */ 1258 static 1259 int 1260 hammer2_vop_advlock(struct vop_advlock_args *ap) 1261 { 1262 hammer2_inode_t *ip = VTOI(ap->a_vp); 1263 hammer2_off_t size; 1264 1265 size = ip->meta.size; 1266 return (lf_advlock(ap, &ip->advlock, size)); 1267 } 1268 1269 static 1270 int 1271 hammer2_vop_close(struct vop_close_args *ap) 1272 { 1273 return vop_stdclose(ap); 1274 } 1275 1276 /* 1277 * hammer2_vop_nlink { nch, dvp, vp, cred } 1278 * 1279 * Create a hardlink from (vp) to {dvp, nch}. 1280 */ 1281 static 1282 int 1283 hammer2_vop_nlink(struct vop_nlink_args *ap) 1284 { 1285 hammer2_xop_nlink_t *xop1; 1286 hammer2_inode_t *fdip; /* target directory to create link in */ 1287 hammer2_inode_t *tdip; /* target directory to create link in */ 1288 hammer2_inode_t *cdip; /* common parent directory */ 1289 hammer2_inode_t *ip; /* inode we are hardlinking to */ 1290 struct namecache *ncp; 1291 const uint8_t *name; 1292 size_t name_len; 1293 int nlink_locked; 1294 int error; 1295 1296 LOCKSTART; 1297 tdip = VTOI(ap->a_dvp); 1298 if (tdip->pmp->ronly) { 1299 LOCKSTOP; 1300 return (EROFS); 1301 } 1302 1303 ncp = ap->a_nch->ncp; 1304 name = ncp->nc_name; 1305 name_len = ncp->nc_nlen; 1306 1307 /* 1308 * ip represents the file being hardlinked. The file could be a 1309 * normal file or a hardlink target if it has already been hardlinked. 1310 * If ip is a hardlinked target then ip->pip represents the location 1311 * of the hardlinked target, NOT the location of the hardlink pointer. 1312 * 1313 * Bump nlinks and potentially also create or move the hardlink 1314 * target in the parent directory common to (ip) and (tdip). The 1315 * consolidation code can modify ip->cluster and ip->pip. The 1316 * returned cluster is locked. 1317 */ 1318 ip = VTOI(ap->a_vp); 1319 hammer2_pfs_memory_wait(ip->pmp); 1320 hammer2_trans_init(ip->pmp, 0); 1321 1322 /* 1323 * The common parent directory must be locked first to avoid deadlocks. 1324 * Also note that fdip and/or tdip might match cdip. 1325 * 1326 * WARNING! The kernel's namecache locks are insufficient for 1327 * protecting us from hardlink shifts, since unrelated 1328 * rename() or link() calls on parent directories might 1329 * cause a shift. A PFS-wide lock is required for this 1330 * situation. 1331 */ 1332 if (ip->meta.type == HAMMER2_OBJTYPE_DIRECTORY || 1333 (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE) == 0) { 1334 lockmgr(&ip->pmp->lock_nlink, LK_EXCLUSIVE); 1335 nlink_locked = 1; 1336 } else { 1337 nlink_locked = 0; 1338 } 1339 fdip = ip->pip; 1340 cdip = hammer2_inode_common_parent(fdip, tdip); 1341 hammer2_inode_lock(cdip, 0); 1342 hammer2_inode_lock(fdip, 0); 1343 hammer2_inode_lock(tdip, 0); 1344 hammer2_inode_lock(ip, 0); 1345 error = 0; 1346 1347 /* 1348 * Dispatch xop_nlink unconditionally since we have to update nlinks. 1349 * 1350 * Otherwise we'd be able to avoid the XOP if the ip does not have 1351 * to be converted or moved. 1352 * If ip is not a hardlink target we must convert it to a hardlink. 1353 * If fdip != cdip we must shift the inode to cdip. 1354 * 1355 * XXX this and other nlink update usage should be passed top-down 1356 * and not updated with a delta bottom-up. 1357 */ 1358 #if 0 1359 if (fdip != cdip || (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE)) 1360 #endif 1361 { 1362 xop1 = hammer2_xop_alloc(fdip, HAMMER2_XOP_MODIFYING); 1363 hammer2_xop_setip2(&xop1->head, ip); 1364 hammer2_xop_setip3(&xop1->head, cdip); 1365 xop1->nlinks_delta = 1; 1366 1367 hammer2_xop_start(&xop1->head, hammer2_xop_nlink); 1368 error = hammer2_xop_collect(&xop1->head, 0); 1369 hammer2_xop_retire(&xop1->head, HAMMER2_XOPMASK_VOP); 1370 if (error == ENOENT) 1371 error = 0; 1372 } 1373 1374 /* 1375 * Must synchronize original inode whos chains are now a hardlink 1376 * target. We must match what the backend XOP did to the 1377 * chains. 1378 */ 1379 if (error == 0 && (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE)) { 1380 hammer2_inode_modify(ip); 1381 ip->meta.name_key = ip->meta.inum; 1382 ip->meta.name_len = 18; /* "0x%016jx" */ 1383 } 1384 1385 /* 1386 * Create the hardlink target and bump nlinks. 1387 */ 1388 if (error == 0) { 1389 hammer2_inode_create(tdip, NULL, NULL, 1390 name, name_len, 0, 1391 ip->meta.inum, 1392 HAMMER2_OBJTYPE_HARDLINK, ip->meta.type, 1393 0, &error); 1394 hammer2_inode_modify(ip); 1395 ++ip->meta.nlinks; 1396 } 1397 if (error == 0) { 1398 cache_setunresolved(ap->a_nch); 1399 cache_setvp(ap->a_nch, ap->a_vp); 1400 } 1401 hammer2_inode_unlock(ip); 1402 hammer2_inode_unlock(tdip); 1403 hammer2_inode_unlock(fdip); 1404 hammer2_inode_unlock(cdip); 1405 hammer2_inode_drop(cdip); 1406 1407 if (nlink_locked) 1408 lockmgr(&ip->pmp->lock_nlink, LK_RELEASE); 1409 hammer2_trans_done(ip->pmp); 1410 1411 LOCKSTOP; 1412 return error; 1413 } 1414 1415 /* 1416 * hammer2_vop_ncreate { nch, dvp, vpp, cred, vap } 1417 * 1418 * The operating system has already ensured that the directory entry 1419 * does not exist and done all appropriate namespace locking. 1420 */ 1421 static 1422 int 1423 hammer2_vop_ncreate(struct vop_ncreate_args *ap) 1424 { 1425 hammer2_inode_t *dip; 1426 hammer2_inode_t *nip; 1427 struct namecache *ncp; 1428 const uint8_t *name; 1429 size_t name_len; 1430 int error; 1431 1432 LOCKSTART; 1433 dip = VTOI(ap->a_dvp); 1434 if (dip->pmp->ronly) { 1435 LOCKSTOP; 1436 return (EROFS); 1437 } 1438 1439 ncp = ap->a_nch->ncp; 1440 name = ncp->nc_name; 1441 name_len = ncp->nc_nlen; 1442 hammer2_pfs_memory_wait(dip->pmp); 1443 hammer2_trans_init(dip->pmp, 0); 1444 1445 nip = hammer2_inode_create(dip, ap->a_vap, ap->a_cred, 1446 name, name_len, 0, 1447 hammer2_trans_newinum(dip->pmp), 0, 0, 1448 0, &error); 1449 if (error) { 1450 KKASSERT(nip == NULL); 1451 *ap->a_vpp = NULL; 1452 } else { 1453 *ap->a_vpp = hammer2_igetv(nip, &error); 1454 hammer2_inode_unlock(nip); 1455 } 1456 hammer2_trans_done(dip->pmp); 1457 1458 if (error == 0) { 1459 cache_setunresolved(ap->a_nch); 1460 cache_setvp(ap->a_nch, *ap->a_vpp); 1461 } 1462 LOCKSTOP; 1463 return error; 1464 } 1465 1466 /* 1467 * Make a device node (typically a fifo) 1468 */ 1469 static 1470 int 1471 hammer2_vop_nmknod(struct vop_nmknod_args *ap) 1472 { 1473 hammer2_inode_t *dip; 1474 hammer2_inode_t *nip; 1475 struct namecache *ncp; 1476 const uint8_t *name; 1477 size_t name_len; 1478 int error; 1479 1480 LOCKSTART; 1481 dip = VTOI(ap->a_dvp); 1482 if (dip->pmp->ronly) { 1483 LOCKSTOP; 1484 return (EROFS); 1485 } 1486 1487 ncp = ap->a_nch->ncp; 1488 name = ncp->nc_name; 1489 name_len = ncp->nc_nlen; 1490 hammer2_pfs_memory_wait(dip->pmp); 1491 hammer2_trans_init(dip->pmp, 0); 1492 1493 nip = hammer2_inode_create(dip, ap->a_vap, ap->a_cred, 1494 name, name_len, 0, 1495 hammer2_trans_newinum(dip->pmp), 0, 0, 1496 0, &error); 1497 if (error) { 1498 KKASSERT(nip == NULL); 1499 *ap->a_vpp = NULL; 1500 } else { 1501 *ap->a_vpp = hammer2_igetv(nip, &error); 1502 hammer2_inode_unlock(nip); 1503 } 1504 hammer2_trans_done(dip->pmp); 1505 1506 if (error == 0) { 1507 cache_setunresolved(ap->a_nch); 1508 cache_setvp(ap->a_nch, *ap->a_vpp); 1509 } 1510 LOCKSTOP; 1511 return error; 1512 } 1513 1514 /* 1515 * hammer2_vop_nsymlink { nch, dvp, vpp, cred, vap, target } 1516 */ 1517 static 1518 int 1519 hammer2_vop_nsymlink(struct vop_nsymlink_args *ap) 1520 { 1521 hammer2_inode_t *dip; 1522 hammer2_inode_t *nip; 1523 struct namecache *ncp; 1524 const uint8_t *name; 1525 size_t name_len; 1526 int error; 1527 1528 dip = VTOI(ap->a_dvp); 1529 if (dip->pmp->ronly) 1530 return (EROFS); 1531 1532 ncp = ap->a_nch->ncp; 1533 name = ncp->nc_name; 1534 name_len = ncp->nc_nlen; 1535 hammer2_pfs_memory_wait(dip->pmp); 1536 hammer2_trans_init(dip->pmp, 0); 1537 1538 ap->a_vap->va_type = VLNK; /* enforce type */ 1539 1540 nip = hammer2_inode_create(dip, ap->a_vap, ap->a_cred, 1541 name, name_len, 0, 1542 hammer2_trans_newinum(dip->pmp), 0, 0, 1543 0, &error); 1544 if (error) { 1545 KKASSERT(nip == NULL); 1546 *ap->a_vpp = NULL; 1547 hammer2_trans_done(dip->pmp); 1548 return error; 1549 } 1550 *ap->a_vpp = hammer2_igetv(nip, &error); 1551 1552 /* 1553 * Build the softlink (~like file data) and finalize the namecache. 1554 */ 1555 if (error == 0) { 1556 size_t bytes; 1557 struct uio auio; 1558 struct iovec aiov; 1559 1560 bytes = strlen(ap->a_target); 1561 1562 hammer2_inode_unlock(nip); 1563 bzero(&auio, sizeof(auio)); 1564 bzero(&aiov, sizeof(aiov)); 1565 auio.uio_iov = &aiov; 1566 auio.uio_segflg = UIO_SYSSPACE; 1567 auio.uio_rw = UIO_WRITE; 1568 auio.uio_resid = bytes; 1569 auio.uio_iovcnt = 1; 1570 auio.uio_td = curthread; 1571 aiov.iov_base = ap->a_target; 1572 aiov.iov_len = bytes; 1573 error = hammer2_write_file(nip, &auio, IO_APPEND, 0); 1574 /* XXX handle error */ 1575 error = 0; 1576 } else { 1577 hammer2_inode_unlock(nip); 1578 } 1579 hammer2_trans_done(dip->pmp); 1580 1581 /* 1582 * Finalize namecache 1583 */ 1584 if (error == 0) { 1585 cache_setunresolved(ap->a_nch); 1586 cache_setvp(ap->a_nch, *ap->a_vpp); 1587 /* hammer2_knote(ap->a_dvp, NOTE_WRITE); */ 1588 } 1589 return error; 1590 } 1591 1592 /* 1593 * hammer2_vop_nremove { nch, dvp, cred } 1594 */ 1595 static 1596 int 1597 hammer2_vop_nremove(struct vop_nremove_args *ap) 1598 { 1599 hammer2_xop_unlink_t *xop; 1600 hammer2_inode_t *dip; 1601 hammer2_inode_t *ip; 1602 struct namecache *ncp; 1603 int error; 1604 int isopen; 1605 1606 LOCKSTART; 1607 dip = VTOI(ap->a_dvp); 1608 if (dip->pmp->ronly) { 1609 LOCKSTOP; 1610 return(EROFS); 1611 } 1612 1613 ncp = ap->a_nch->ncp; 1614 1615 hammer2_pfs_memory_wait(dip->pmp); 1616 hammer2_trans_init(dip->pmp, 0); 1617 hammer2_inode_lock(dip, 0); 1618 1619 /* 1620 * The unlink XOP unlinks the path from the directory and 1621 * locates and returns the cluster associated with the real inode. 1622 * We have to handle nlinks here on the frontend. 1623 */ 1624 xop = hammer2_xop_alloc(dip, HAMMER2_XOP_MODIFYING); 1625 hammer2_xop_setname(&xop->head, ncp->nc_name, ncp->nc_nlen); 1626 isopen = cache_isopen(ap->a_nch); 1627 xop->isdir = 0; 1628 xop->dopermanent = isopen ? 0 : HAMMER2_DELETE_PERMANENT; 1629 hammer2_xop_start(&xop->head, hammer2_xop_unlink); 1630 1631 /* 1632 * Collect the real inode and adjust nlinks, destroy the real 1633 * inode if nlinks transitions to 0 and it was the real inode 1634 * (else it has already been removed). 1635 */ 1636 error = hammer2_xop_collect(&xop->head, 0); 1637 hammer2_inode_unlock(dip); 1638 1639 if (error == 0) { 1640 ip = hammer2_inode_get(dip->pmp, dip, &xop->head.cluster, -1); 1641 hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP); 1642 if (ip) { 1643 hammer2_inode_unlink_finisher(ip, isopen); 1644 hammer2_inode_unlock(ip); 1645 } 1646 } else { 1647 hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP); 1648 } 1649 1650 hammer2_inode_run_sideq(dip->pmp); 1651 hammer2_trans_done(dip->pmp); 1652 if (error == 0) 1653 cache_unlink(ap->a_nch); 1654 LOCKSTOP; 1655 return (error); 1656 } 1657 1658 /* 1659 * hammer2_vop_nrmdir { nch, dvp, cred } 1660 */ 1661 static 1662 int 1663 hammer2_vop_nrmdir(struct vop_nrmdir_args *ap) 1664 { 1665 hammer2_xop_unlink_t *xop; 1666 hammer2_inode_t *dip; 1667 hammer2_inode_t *ip; 1668 struct namecache *ncp; 1669 int isopen; 1670 int error; 1671 1672 LOCKSTART; 1673 dip = VTOI(ap->a_dvp); 1674 if (dip->pmp->ronly) { 1675 LOCKSTOP; 1676 return(EROFS); 1677 } 1678 1679 hammer2_pfs_memory_wait(dip->pmp); 1680 hammer2_trans_init(dip->pmp, 0); 1681 hammer2_inode_lock(dip, 0); 1682 1683 xop = hammer2_xop_alloc(dip, HAMMER2_XOP_MODIFYING); 1684 1685 ncp = ap->a_nch->ncp; 1686 hammer2_xop_setname(&xop->head, ncp->nc_name, ncp->nc_nlen); 1687 isopen = cache_isopen(ap->a_nch); 1688 xop->isdir = 1; 1689 xop->dopermanent = isopen ? 0 : HAMMER2_DELETE_PERMANENT; 1690 hammer2_xop_start(&xop->head, hammer2_xop_unlink); 1691 1692 /* 1693 * Collect the real inode and adjust nlinks, destroy the real 1694 * inode if nlinks transitions to 0 and it was the real inode 1695 * (else it has already been removed). 1696 */ 1697 error = hammer2_xop_collect(&xop->head, 0); 1698 hammer2_inode_unlock(dip); 1699 1700 if (error == 0) { 1701 ip = hammer2_inode_get(dip->pmp, dip, &xop->head.cluster, -1); 1702 hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP); 1703 if (ip) { 1704 hammer2_inode_unlink_finisher(ip, isopen); 1705 hammer2_inode_unlock(ip); 1706 } 1707 } else { 1708 hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP); 1709 } 1710 hammer2_inode_run_sideq(dip->pmp); 1711 hammer2_trans_done(dip->pmp); 1712 if (error == 0) 1713 cache_unlink(ap->a_nch); 1714 LOCKSTOP; 1715 return (error); 1716 } 1717 1718 /* 1719 * hammer2_vop_nrename { fnch, tnch, fdvp, tdvp, cred } 1720 */ 1721 static 1722 int 1723 hammer2_vop_nrename(struct vop_nrename_args *ap) 1724 { 1725 struct namecache *fncp; 1726 struct namecache *tncp; 1727 hammer2_inode_t *cdip; 1728 hammer2_inode_t *fdip; 1729 hammer2_inode_t *tdip; 1730 hammer2_inode_t *ip; 1731 const uint8_t *fname; 1732 size_t fname_len; 1733 const uint8_t *tname; 1734 size_t tname_len; 1735 int error; 1736 int tnch_error; 1737 int nlink_locked; 1738 hammer2_key_t tlhc; 1739 1740 if (ap->a_fdvp->v_mount != ap->a_tdvp->v_mount) 1741 return(EXDEV); 1742 if (ap->a_fdvp->v_mount != ap->a_fnch->ncp->nc_vp->v_mount) 1743 return(EXDEV); 1744 1745 fdip = VTOI(ap->a_fdvp); /* source directory */ 1746 tdip = VTOI(ap->a_tdvp); /* target directory */ 1747 1748 if (fdip->pmp->ronly) 1749 return(EROFS); 1750 1751 LOCKSTART; 1752 fncp = ap->a_fnch->ncp; /* entry name in source */ 1753 fname = fncp->nc_name; 1754 fname_len = fncp->nc_nlen; 1755 1756 tncp = ap->a_tnch->ncp; /* entry name in target */ 1757 tname = tncp->nc_name; 1758 tname_len = tncp->nc_nlen; 1759 1760 hammer2_pfs_memory_wait(tdip->pmp); 1761 hammer2_trans_init(tdip->pmp, 0); 1762 1763 /* 1764 * ip is the inode being renamed. If this is a hardlink then 1765 * ip represents the actual file and not the hardlink marker. 1766 */ 1767 ip = VTOI(fncp->nc_vp); 1768 1769 /* 1770 * The common parent directory must be locked first to avoid deadlocks. 1771 * Also note that fdip and/or tdip might match cdip. 1772 * 1773 * WARNING! The kernel's namecache locks are insufficient for 1774 * protecting us from hardlink shifts, since unrelated 1775 * rename() or link() calls on parent directories might 1776 * cause a shift. A PFS-wide lock is required for this 1777 * situation. 1778 */ 1779 if (ip->meta.type == HAMMER2_OBJTYPE_DIRECTORY || 1780 (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE) == 0) { 1781 lockmgr(&ip->pmp->lock_nlink, LK_EXCLUSIVE); 1782 nlink_locked = 1; 1783 } else { 1784 nlink_locked = 0; 1785 } 1786 1787 cdip = hammer2_inode_common_parent(ip->pip, tdip); 1788 hammer2_inode_lock(cdip, 0); 1789 hammer2_inode_lock(fdip, 0); 1790 hammer2_inode_lock(tdip, 0); 1791 hammer2_inode_ref(ip); /* extra ref */ 1792 error = 0; 1793 1794 /* 1795 * If ip is a hardlink target and fdip != cdip we must shift the 1796 * inode to cdip. 1797 */ 1798 hammer2_inode_lock(ip, 0); 1799 1800 if (fdip != cdip && 1801 (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE) == 0) { 1802 hammer2_xop_nlink_t *xop1; 1803 1804 xop1 = hammer2_xop_alloc(fdip, HAMMER2_XOP_MODIFYING); 1805 hammer2_xop_setip2(&xop1->head, ip); 1806 hammer2_xop_setip3(&xop1->head, cdip); 1807 xop1->nlinks_delta = 0; 1808 1809 hammer2_xop_start(&xop1->head, hammer2_xop_nlink); 1810 error = hammer2_xop_collect(&xop1->head, 0); 1811 hammer2_xop_retire(&xop1->head, HAMMER2_XOPMASK_VOP); 1812 } 1813 /* hammer2_inode_unlock(ip); */ 1814 1815 /* 1816 * Delete the target namespace. 1817 */ 1818 { 1819 hammer2_xop_unlink_t *xop2; 1820 hammer2_inode_t *tip; 1821 int isopen; 1822 1823 /* 1824 * The unlink XOP unlinks the path from the directory and 1825 * locates and returns the cluster associated with the real 1826 * inode. We have to handle nlinks here on the frontend. 1827 */ 1828 xop2 = hammer2_xop_alloc(tdip, HAMMER2_XOP_MODIFYING); 1829 hammer2_xop_setname(&xop2->head, tname, tname_len); 1830 isopen = cache_isopen(ap->a_tnch); 1831 xop2->isdir = -1; 1832 xop2->dopermanent = isopen ? 0 : HAMMER2_DELETE_PERMANENT; 1833 hammer2_xop_start(&xop2->head, hammer2_xop_unlink); 1834 1835 /* 1836 * Collect the real inode and adjust nlinks, destroy the real 1837 * inode if nlinks transitions to 0 and it was the real inode 1838 * (else it has already been removed). 1839 */ 1840 tnch_error = hammer2_xop_collect(&xop2->head, 0); 1841 /* hammer2_inode_unlock(tdip); */ 1842 1843 if (tnch_error == 0) { 1844 tip = hammer2_inode_get(tdip->pmp, NULL, 1845 &xop2->head.cluster, -1); 1846 hammer2_xop_retire(&xop2->head, HAMMER2_XOPMASK_VOP); 1847 if (tip) { 1848 hammer2_inode_unlink_finisher(tip, isopen); 1849 hammer2_inode_unlock(tip); 1850 } 1851 } else { 1852 hammer2_xop_retire(&xop2->head, HAMMER2_XOPMASK_VOP); 1853 } 1854 /* hammer2_inode_lock(tdip, 0); */ 1855 1856 if (tnch_error && tnch_error != ENOENT) { 1857 error = tnch_error; 1858 goto done2; 1859 } 1860 } 1861 1862 /* 1863 * Resolve the collision space for (tdip, tname, tname_len) 1864 * 1865 * tdip must be held exclusively locked to prevent races. 1866 */ 1867 { 1868 hammer2_xop_scanlhc_t *sxop; 1869 hammer2_tid_t lhcbase; 1870 1871 tlhc = hammer2_dirhash(tname, tname_len); 1872 lhcbase = tlhc; 1873 sxop = hammer2_xop_alloc(tdip, HAMMER2_XOP_MODIFYING); 1874 sxop->lhc = tlhc; 1875 hammer2_xop_start(&sxop->head, hammer2_xop_scanlhc); 1876 while ((error = hammer2_xop_collect(&sxop->head, 0)) == 0) { 1877 if (tlhc != sxop->head.cluster.focus->bref.key) 1878 break; 1879 ++tlhc; 1880 } 1881 hammer2_xop_retire(&sxop->head, HAMMER2_XOPMASK_VOP); 1882 1883 if (error) { 1884 if (error != ENOENT) 1885 goto done2; 1886 ++tlhc; 1887 error = 0; 1888 } 1889 if ((lhcbase ^ tlhc) & ~HAMMER2_DIRHASH_LOMASK) { 1890 error = ENOSPC; 1891 goto done2; 1892 } 1893 } 1894 1895 /* 1896 * Everything is setup, do the rename. 1897 * 1898 * We have to synchronize ip->meta to the underlying operation. 1899 * 1900 * NOTE: To avoid deadlocks we cannot lock (ip) while we are 1901 * unlinking elements from their directories. Locking 1902 * the nlinks field does not lock the whole inode. 1903 */ 1904 /* hammer2_inode_lock(ip, 0); */ 1905 if (error == 0) { 1906 hammer2_xop_nrename_t *xop4; 1907 1908 xop4 = hammer2_xop_alloc(fdip, HAMMER2_XOP_MODIFYING); 1909 xop4->lhc = tlhc; 1910 xop4->ip_key = ip->meta.name_key; 1911 hammer2_xop_setip2(&xop4->head, ip); 1912 hammer2_xop_setip3(&xop4->head, tdip); 1913 hammer2_xop_setname(&xop4->head, fname, fname_len); 1914 hammer2_xop_setname2(&xop4->head, tname, tname_len); 1915 hammer2_xop_start(&xop4->head, hammer2_xop_nrename); 1916 1917 error = hammer2_xop_collect(&xop4->head, 0); 1918 hammer2_xop_retire(&xop4->head, HAMMER2_XOPMASK_VOP); 1919 1920 if (error == ENOENT) 1921 error = 0; 1922 if (error == 0 && 1923 (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE)) { 1924 hammer2_inode_modify(ip); 1925 ip->meta.name_len = tname_len; 1926 ip->meta.name_key = tlhc; 1927 1928 } 1929 } 1930 1931 /* 1932 * Fixup ip->pip if we were renaming the actual file and not a 1933 * hardlink pointer. 1934 */ 1935 if (error == 0 && (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE)) { 1936 hammer2_inode_t *opip; 1937 1938 if (ip->pip != tdip) { 1939 hammer2_inode_ref(tdip); 1940 opip = ip->pip; 1941 ip->pip = tdip; 1942 if (opip) 1943 hammer2_inode_drop(opip); 1944 } 1945 } 1946 done2: 1947 hammer2_inode_unlock(ip); 1948 hammer2_inode_unlock(tdip); 1949 hammer2_inode_unlock(fdip); 1950 hammer2_inode_unlock(cdip); 1951 hammer2_inode_drop(ip); 1952 hammer2_inode_drop(cdip); 1953 hammer2_inode_run_sideq(fdip->pmp); 1954 1955 if (nlink_locked) 1956 lockmgr(&ip->pmp->lock_nlink, LK_RELEASE); 1957 hammer2_trans_done(tdip->pmp); 1958 1959 /* 1960 * Issue the namecache update after unlocking all the internal 1961 * hammer structures, otherwise we might deadlock. 1962 */ 1963 if (tnch_error == 0) { 1964 cache_unlink(ap->a_tnch); 1965 cache_setunresolved(ap->a_tnch); 1966 } 1967 if (error == 0) 1968 cache_rename(ap->a_fnch, ap->a_tnch); 1969 1970 LOCKSTOP; 1971 return (error); 1972 } 1973 1974 /* 1975 * hammer2_vop_ioctl { vp, command, data, fflag, cred } 1976 */ 1977 static 1978 int 1979 hammer2_vop_ioctl(struct vop_ioctl_args *ap) 1980 { 1981 hammer2_inode_t *ip; 1982 int error; 1983 1984 LOCKSTART; 1985 ip = VTOI(ap->a_vp); 1986 1987 error = hammer2_ioctl(ip, ap->a_command, (void *)ap->a_data, 1988 ap->a_fflag, ap->a_cred); 1989 LOCKSTOP; 1990 return (error); 1991 } 1992 1993 static 1994 int 1995 hammer2_vop_mountctl(struct vop_mountctl_args *ap) 1996 { 1997 struct mount *mp; 1998 hammer2_pfs_t *pmp; 1999 int rc; 2000 2001 LOCKSTART; 2002 switch (ap->a_op) { 2003 case (MOUNTCTL_SET_EXPORT): 2004 mp = ap->a_head.a_ops->head.vv_mount; 2005 pmp = MPTOPMP(mp); 2006 2007 if (ap->a_ctllen != sizeof(struct export_args)) 2008 rc = (EINVAL); 2009 else 2010 rc = vfs_export(mp, &pmp->export, 2011 (const struct export_args *)ap->a_ctl); 2012 break; 2013 default: 2014 rc = vop_stdmountctl(ap); 2015 break; 2016 } 2017 LOCKSTOP; 2018 return (rc); 2019 } 2020 2021 /* 2022 * KQFILTER 2023 */ 2024 static void filt_hammer2detach(struct knote *kn); 2025 static int filt_hammer2read(struct knote *kn, long hint); 2026 static int filt_hammer2write(struct knote *kn, long hint); 2027 static int filt_hammer2vnode(struct knote *kn, long hint); 2028 2029 static struct filterops hammer2read_filtops = 2030 { FILTEROP_ISFD | FILTEROP_MPSAFE, 2031 NULL, filt_hammer2detach, filt_hammer2read }; 2032 static struct filterops hammer2write_filtops = 2033 { FILTEROP_ISFD | FILTEROP_MPSAFE, 2034 NULL, filt_hammer2detach, filt_hammer2write }; 2035 static struct filterops hammer2vnode_filtops = 2036 { FILTEROP_ISFD | FILTEROP_MPSAFE, 2037 NULL, filt_hammer2detach, filt_hammer2vnode }; 2038 2039 static 2040 int 2041 hammer2_vop_kqfilter(struct vop_kqfilter_args *ap) 2042 { 2043 struct vnode *vp = ap->a_vp; 2044 struct knote *kn = ap->a_kn; 2045 2046 switch (kn->kn_filter) { 2047 case EVFILT_READ: 2048 kn->kn_fop = &hammer2read_filtops; 2049 break; 2050 case EVFILT_WRITE: 2051 kn->kn_fop = &hammer2write_filtops; 2052 break; 2053 case EVFILT_VNODE: 2054 kn->kn_fop = &hammer2vnode_filtops; 2055 break; 2056 default: 2057 return (EOPNOTSUPP); 2058 } 2059 2060 kn->kn_hook = (caddr_t)vp; 2061 2062 knote_insert(&vp->v_pollinfo.vpi_kqinfo.ki_note, kn); 2063 2064 return(0); 2065 } 2066 2067 static void 2068 filt_hammer2detach(struct knote *kn) 2069 { 2070 struct vnode *vp = (void *)kn->kn_hook; 2071 2072 knote_remove(&vp->v_pollinfo.vpi_kqinfo.ki_note, kn); 2073 } 2074 2075 static int 2076 filt_hammer2read(struct knote *kn, long hint) 2077 { 2078 struct vnode *vp = (void *)kn->kn_hook; 2079 hammer2_inode_t *ip = VTOI(vp); 2080 off_t off; 2081 2082 if (hint == NOTE_REVOKE) { 2083 kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT); 2084 return(1); 2085 } 2086 off = ip->meta.size - kn->kn_fp->f_offset; 2087 kn->kn_data = (off < INTPTR_MAX) ? off : INTPTR_MAX; 2088 if (kn->kn_sfflags & NOTE_OLDAPI) 2089 return(1); 2090 return (kn->kn_data != 0); 2091 } 2092 2093 2094 static int 2095 filt_hammer2write(struct knote *kn, long hint) 2096 { 2097 if (hint == NOTE_REVOKE) 2098 kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT); 2099 kn->kn_data = 0; 2100 return (1); 2101 } 2102 2103 static int 2104 filt_hammer2vnode(struct knote *kn, long hint) 2105 { 2106 if (kn->kn_sfflags & hint) 2107 kn->kn_fflags |= hint; 2108 if (hint == NOTE_REVOKE) { 2109 kn->kn_flags |= (EV_EOF | EV_NODATA); 2110 return (1); 2111 } 2112 return (kn->kn_fflags != 0); 2113 } 2114 2115 /* 2116 * FIFO VOPS 2117 */ 2118 static 2119 int 2120 hammer2_vop_markatime(struct vop_markatime_args *ap) 2121 { 2122 hammer2_inode_t *ip; 2123 struct vnode *vp; 2124 2125 vp = ap->a_vp; 2126 ip = VTOI(vp); 2127 2128 if (ip->pmp->ronly) 2129 return(EROFS); 2130 return(0); 2131 } 2132 2133 static 2134 int 2135 hammer2_vop_fifokqfilter(struct vop_kqfilter_args *ap) 2136 { 2137 int error; 2138 2139 error = VOCALL(&fifo_vnode_vops, &ap->a_head); 2140 if (error) 2141 error = hammer2_vop_kqfilter(ap); 2142 return(error); 2143 } 2144 2145 /* 2146 * VOPS vector 2147 */ 2148 struct vop_ops hammer2_vnode_vops = { 2149 .vop_default = vop_defaultop, 2150 .vop_fsync = hammer2_vop_fsync, 2151 .vop_getpages = vop_stdgetpages, 2152 .vop_putpages = vop_stdputpages, 2153 .vop_access = hammer2_vop_access, 2154 .vop_advlock = hammer2_vop_advlock, 2155 .vop_close = hammer2_vop_close, 2156 .vop_nlink = hammer2_vop_nlink, 2157 .vop_ncreate = hammer2_vop_ncreate, 2158 .vop_nsymlink = hammer2_vop_nsymlink, 2159 .vop_nremove = hammer2_vop_nremove, 2160 .vop_nrmdir = hammer2_vop_nrmdir, 2161 .vop_nrename = hammer2_vop_nrename, 2162 .vop_getattr = hammer2_vop_getattr, 2163 .vop_setattr = hammer2_vop_setattr, 2164 .vop_readdir = hammer2_vop_readdir, 2165 .vop_readlink = hammer2_vop_readlink, 2166 .vop_getpages = vop_stdgetpages, 2167 .vop_putpages = vop_stdputpages, 2168 .vop_read = hammer2_vop_read, 2169 .vop_write = hammer2_vop_write, 2170 .vop_open = hammer2_vop_open, 2171 .vop_inactive = hammer2_vop_inactive, 2172 .vop_reclaim = hammer2_vop_reclaim, 2173 .vop_nresolve = hammer2_vop_nresolve, 2174 .vop_nlookupdotdot = hammer2_vop_nlookupdotdot, 2175 .vop_nmkdir = hammer2_vop_nmkdir, 2176 .vop_nmknod = hammer2_vop_nmknod, 2177 .vop_ioctl = hammer2_vop_ioctl, 2178 .vop_mountctl = hammer2_vop_mountctl, 2179 .vop_bmap = hammer2_vop_bmap, 2180 .vop_strategy = hammer2_vop_strategy, 2181 .vop_kqfilter = hammer2_vop_kqfilter 2182 }; 2183 2184 struct vop_ops hammer2_spec_vops = { 2185 .vop_default = vop_defaultop, 2186 .vop_fsync = hammer2_vop_fsync, 2187 .vop_read = vop_stdnoread, 2188 .vop_write = vop_stdnowrite, 2189 .vop_access = hammer2_vop_access, 2190 .vop_close = hammer2_vop_close, 2191 .vop_markatime = hammer2_vop_markatime, 2192 .vop_getattr = hammer2_vop_getattr, 2193 .vop_inactive = hammer2_vop_inactive, 2194 .vop_reclaim = hammer2_vop_reclaim, 2195 .vop_setattr = hammer2_vop_setattr 2196 }; 2197 2198 struct vop_ops hammer2_fifo_vops = { 2199 .vop_default = fifo_vnoperate, 2200 .vop_fsync = hammer2_vop_fsync, 2201 #if 0 2202 .vop_read = hammer2_vop_fiforead, 2203 .vop_write = hammer2_vop_fifowrite, 2204 #endif 2205 .vop_access = hammer2_vop_access, 2206 #if 0 2207 .vop_close = hammer2_vop_fifoclose, 2208 #endif 2209 .vop_markatime = hammer2_vop_markatime, 2210 .vop_getattr = hammer2_vop_getattr, 2211 .vop_inactive = hammer2_vop_inactive, 2212 .vop_reclaim = hammer2_vop_reclaim, 2213 .vop_setattr = hammer2_vop_setattr, 2214 .vop_kqfilter = hammer2_vop_fifokqfilter 2215 }; 2216 2217