1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/param.h> 30 #include <sys/t_lock.h> 31 #include <sys/systm.h> 32 #include <sys/sysmacros.h> 33 #include <sys/user.h> 34 #include <sys/time.h> 35 #include <sys/vfs.h> 36 #include <sys/vnode.h> 37 #include <sys/file.h> 38 #include <sys/fcntl.h> 39 #include <sys/flock.h> 40 #include <sys/kmem.h> 41 #include <sys/uio.h> 42 #include <sys/errno.h> 43 #include <sys/stat.h> 44 #include <sys/cred.h> 45 #include <sys/dirent.h> 46 #include <sys/pathname.h> 47 #include <sys/vmsystm.h> 48 #include <sys/fs/tmp.h> 49 #include <sys/fs/tmpnode.h> 50 #include <sys/mman.h> 51 #include <vm/hat.h> 52 #include <vm/seg_vn.h> 53 #include <vm/seg_map.h> 54 #include <vm/seg.h> 55 #include <vm/anon.h> 56 #include <vm/as.h> 57 #include <vm/page.h> 58 #include <vm/pvn.h> 59 #include <sys/cmn_err.h> 60 #include <sys/debug.h> 61 #include <sys/swap.h> 62 #include <sys/buf.h> 63 #include <sys/vm.h> 64 #include <sys/vtrace.h> 65 #include <sys/policy.h> 66 #include <fs/fs_subr.h> 67 68 static int tmp_getapage(struct vnode *, u_offset_t, size_t, uint_t *, 69 page_t **, size_t, struct seg *, caddr_t, enum seg_rw, struct cred *); 70 static int tmp_putapage(struct vnode *, page_t *, u_offset_t *, size_t *, 71 int, struct cred *); 72 73 /* ARGSUSED1 */ 74 static int 75 tmp_open(struct vnode **vpp, int flag, struct cred *cred) 76 { 77 /* 78 * swapon to a tmpfs file is not supported so access 79 * is denied on open if VISSWAP is set. 80 */ 81 if ((*vpp)->v_flag & VISSWAP) 82 return (EINVAL); 83 return (0); 84 } 85 86 /* ARGSUSED1 */ 87 static int 88 tmp_close(struct vnode *vp, int flag, int count, 89 offset_t offset, struct cred *cred) 90 { 91 cleanlocks(vp, ttoproc(curthread)->p_pid, 0); 92 cleanshares(vp, ttoproc(curthread)->p_pid); 93 return (0); 94 } 95 96 /* 97 * wrtmp does the real work of write requests for tmpfs. 98 */ 99 static int 100 wrtmp( 101 struct tmount *tm, 102 struct tmpnode *tp, 103 struct uio *uio, 104 struct cred *cr, 105 struct caller_context *ct) 106 { 107 pgcnt_t pageoffset; /* offset in pages */ 108 ulong_t segmap_offset; /* pagesize byte offset into segmap */ 109 caddr_t base; /* base of segmap */ 110 ssize_t bytes; /* bytes to uiomove */ 111 pfn_t pagenumber; /* offset in pages into tmp file */ 112 struct vnode *vp; 113 int error = 0; 114 int pagecreate; /* == 1 if we allocated a page */ 115 int newpage; 116 rlim64_t limit = uio->uio_llimit; 117 long oresid = uio->uio_resid; 118 timestruc_t now; 119 120 /* 121 * tp->tn_size is incremented before the uiomove 122 * is done on a write. If the move fails (bad user 123 * address) reset tp->tn_size. 124 * The better way would be to increment tp->tn_size 125 * only if the uiomove succeeds. 126 */ 127 long tn_size_changed = 0; 128 long old_tn_size; 129 130 vp = TNTOV(tp); 131 ASSERT(vp->v_type == VREG); 132 133 TRACE_1(TR_FAC_TMPFS, TR_TMPFS_RWTMP_START, 134 "tmp_wrtmp_start:vp %p", vp); 135 136 ASSERT(RW_WRITE_HELD(&tp->tn_contents)); 137 ASSERT(RW_WRITE_HELD(&tp->tn_rwlock)); 138 139 if (MANDLOCK(vp, tp->tn_mode)) { 140 rw_exit(&tp->tn_contents); 141 /* 142 * tmp_getattr ends up being called by chklock 143 */ 144 error = chklock(vp, FWRITE, 145 uio->uio_loffset, uio->uio_resid, uio->uio_fmode, ct); 146 rw_enter(&tp->tn_contents, RW_WRITER); 147 if (error != 0) { 148 TRACE_2(TR_FAC_TMPFS, TR_TMPFS_RWTMP_END, 149 "tmp_wrtmp_end:vp %p error %d", vp, error); 150 return (error); 151 } 152 } 153 154 if (uio->uio_loffset < 0) 155 return (EINVAL); 156 157 if (limit == RLIM64_INFINITY || limit > MAXOFFSET_T) 158 limit = MAXOFFSET_T; 159 160 if (uio->uio_loffset >= limit) { 161 proc_t *p = ttoproc(curthread); 162 163 mutex_enter(&p->p_lock); 164 (void) rctl_action(rctlproc_legacy[RLIMIT_FSIZE], p->p_rctls, 165 p, RCA_UNSAFE_SIGINFO); 166 mutex_exit(&p->p_lock); 167 return (EFBIG); 168 } 169 170 if (uio->uio_loffset >= MAXOFF_T) { 171 TRACE_2(TR_FAC_TMPFS, TR_TMPFS_RWTMP_END, 172 "tmp_wrtmp_end:vp %p error %d", vp, EINVAL); 173 return (EFBIG); 174 } 175 176 if (uio->uio_resid == 0) { 177 TRACE_2(TR_FAC_TMPFS, TR_TMPFS_RWTMP_END, 178 "tmp_wrtmp_end:vp %p error %d", vp, 0); 179 return (0); 180 } 181 182 if (limit > MAXOFF_T) 183 limit = MAXOFF_T; 184 185 do { 186 long offset; 187 long delta; 188 189 offset = (long)uio->uio_offset; 190 pageoffset = offset & PAGEOFFSET; 191 /* 192 * A maximum of PAGESIZE bytes of data is transferred 193 * each pass through this loop 194 */ 195 bytes = MIN(PAGESIZE - pageoffset, uio->uio_resid); 196 197 if (offset + bytes >= limit) { 198 if (offset >= limit) { 199 error = EFBIG; 200 goto out; 201 } 202 bytes = limit - offset; 203 } 204 pagenumber = btop(offset); 205 206 /* 207 * delta is the amount of anonymous memory 208 * to reserve for the file. 209 * We always reserve in pagesize increments so 210 * unless we're extending the file into a new page, 211 * we don't need to call tmp_resv. 212 */ 213 delta = offset + bytes - 214 P2ROUNDUP_TYPED(tp->tn_size, PAGESIZE, u_offset_t); 215 if (delta > 0) { 216 pagecreate = 1; 217 if (tmp_resv(tm, tp, delta, pagecreate)) { 218 cmn_err(CE_WARN, 219 "%s: File system full, swap space limit exceeded", 220 tm->tm_mntpath); 221 error = ENOSPC; 222 break; 223 } 224 tmpnode_growmap(tp, (ulong_t)offset + bytes); 225 } 226 /* grow the file to the new length */ 227 if (offset + bytes > tp->tn_size) { 228 tn_size_changed = 1; 229 old_tn_size = tp->tn_size; 230 tp->tn_size = offset + bytes; 231 } 232 if (bytes == PAGESIZE) { 233 /* 234 * Writing whole page so reading from disk 235 * is a waste 236 */ 237 pagecreate = 1; 238 } else { 239 pagecreate = 0; 240 } 241 /* 242 * If writing past EOF or filling in a hole 243 * we need to allocate an anon slot. 244 */ 245 if (anon_get_ptr(tp->tn_anon, pagenumber) == NULL) { 246 (void) anon_set_ptr(tp->tn_anon, pagenumber, 247 anon_alloc(vp, ptob(pagenumber)), ANON_SLEEP); 248 pagecreate = 1; 249 tp->tn_nblocks++; 250 } 251 252 /* 253 * We have to drop the contents lock to prevent the VM 254 * system from trying to reaquire it in tmp_getpage() 255 * should the uiomove cause a pagefault. If we're doing 256 * a pagecreate segmap creates the page without calling 257 * the filesystem so we need to hold onto the lock until 258 * the page is created. 259 */ 260 if (!pagecreate) 261 rw_exit(&tp->tn_contents); 262 263 newpage = 0; 264 if (vpm_enable) { 265 /* 266 * XXX Why do we need to hold the contents lock? 267 * The kpm mappings will not cause a fault. 268 * 269 * Copy data. If new pages are created, part of 270 * the page that is not written will be initizliazed 271 * with zeros. 272 */ 273 error = vpm_data_copy(vp, offset, bytes, uio, 274 !pagecreate, &newpage, 1, S_WRITE); 275 276 if (pagecreate) { 277 rw_exit(&tp->tn_contents); 278 } 279 } else { 280 /* Get offset within the segmap mapping */ 281 segmap_offset = (offset & PAGEMASK) & MAXBOFFSET; 282 base = segmap_getmapflt(segkmap, vp, 283 (offset & MAXBMASK), 284 PAGESIZE, !pagecreate, S_WRITE); 285 } 286 287 288 if (!vpm_enable && pagecreate) { 289 rw_downgrade(&tp->tn_contents); 290 291 /* 292 * segmap_pagecreate() returns 1 if it calls 293 * page_create_va() to allocate any pages. 294 */ 295 newpage = segmap_pagecreate(segkmap, 296 base + segmap_offset, (size_t)PAGESIZE, 0); 297 rw_exit(&tp->tn_contents); 298 /* 299 * Clear from the beginning of the page to the starting 300 * offset of the data. 301 */ 302 if (pageoffset != 0) 303 (void) kzero(base + segmap_offset, 304 (size_t)pageoffset); 305 } 306 307 if (!vpm_enable) { 308 error = uiomove(base + segmap_offset + pageoffset, 309 (long)bytes, UIO_WRITE, uio); 310 } 311 312 if (!vpm_enable && pagecreate && 313 uio->uio_offset < P2ROUNDUP(offset + bytes, PAGESIZE)) { 314 long zoffset; /* zero from offset into page */ 315 /* 316 * We created pages w/o initializing them completely, 317 * thus we need to zero the part that wasn't set up. 318 * This happens on most EOF write cases and if 319 * we had some sort of error during the uiomove. 320 */ 321 long nmoved; 322 323 nmoved = uio->uio_offset - offset; 324 ASSERT((nmoved + pageoffset) <= PAGESIZE); 325 326 /* 327 * Zero from the end of data in the page to the 328 * end of the page. 329 */ 330 if ((zoffset = pageoffset + nmoved) < PAGESIZE) 331 (void) kzero(base + segmap_offset + zoffset, 332 (size_t)PAGESIZE - zoffset); 333 } 334 335 /* 336 * Unlock the pages which have been allocated by 337 * page_create_va() in segmap_pagecreate() 338 */ 339 if (!vpm_enable && newpage) { 340 segmap_pageunlock(segkmap, base + segmap_offset, 341 (size_t)PAGESIZE, S_WRITE); 342 } 343 344 if (error) { 345 /* 346 * If we failed on a write, we must 347 * be sure to invalidate any pages that may have 348 * been allocated. 349 */ 350 if (vpm_enable) { 351 (void) vpm_sync_pages(vp, offset, 352 PAGESIZE, SM_INVAL); 353 } else { 354 (void) segmap_release(segkmap, base, SM_INVAL); 355 } 356 } else { 357 if (vpm_enable) { 358 error = vpm_sync_pages(vp, offset, 359 PAGESIZE, 0); 360 } else { 361 error = segmap_release(segkmap, base, 0); 362 } 363 } 364 365 /* 366 * Re-acquire contents lock. 367 */ 368 rw_enter(&tp->tn_contents, RW_WRITER); 369 /* 370 * If the uiomove failed, fix up tn_size. 371 */ 372 if (error) { 373 if (tn_size_changed) { 374 /* 375 * The uiomove failed, and we 376 * allocated blocks,so get rid 377 * of them. 378 */ 379 (void) tmpnode_trunc(tm, tp, 380 (ulong_t)old_tn_size); 381 } 382 } else { 383 /* 384 * XXX - Can this be out of the loop? 385 */ 386 if ((tp->tn_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) && 387 (tp->tn_mode & (S_ISUID | S_ISGID)) && 388 secpolicy_vnode_setid_retain(cr, 389 (tp->tn_mode & S_ISUID) != 0 && tp->tn_uid == 0)) { 390 /* 391 * Clear Set-UID & Set-GID bits on 392 * successful write if not privileged 393 * and at least one of the execute bits 394 * is set. If we always clear Set-GID, 395 * mandatory file and record locking is 396 * unuseable. 397 */ 398 tp->tn_mode &= ~(S_ISUID | S_ISGID); 399 } 400 gethrestime(&now); 401 tp->tn_mtime = now; 402 tp->tn_ctime = now; 403 } 404 } while (error == 0 && uio->uio_resid > 0 && bytes != 0); 405 406 out: 407 /* 408 * If we've already done a partial-write, terminate 409 * the write but return no error. 410 */ 411 if (oresid != uio->uio_resid) 412 error = 0; 413 TRACE_2(TR_FAC_TMPFS, TR_TMPFS_RWTMP_END, 414 "tmp_wrtmp_end:vp %p error %d", vp, error); 415 return (error); 416 } 417 418 /* 419 * rdtmp does the real work of read requests for tmpfs. 420 */ 421 static int 422 rdtmp( 423 struct tmount *tm, 424 struct tmpnode *tp, 425 struct uio *uio, 426 struct caller_context *ct) 427 { 428 ulong_t pageoffset; /* offset in tmpfs file (uio_offset) */ 429 ulong_t segmap_offset; /* pagesize byte offset into segmap */ 430 caddr_t base; /* base of segmap */ 431 ssize_t bytes; /* bytes to uiomove */ 432 struct vnode *vp; 433 int error; 434 long oresid = uio->uio_resid; 435 436 #if defined(lint) 437 tm = tm; 438 #endif 439 vp = TNTOV(tp); 440 441 TRACE_1(TR_FAC_TMPFS, TR_TMPFS_RWTMP_START, 442 "tmp_rdtmp_start:vp %p", vp); 443 444 ASSERT(RW_LOCK_HELD(&tp->tn_contents)); 445 446 if (MANDLOCK(vp, tp->tn_mode)) { 447 rw_exit(&tp->tn_contents); 448 /* 449 * tmp_getattr ends up being called by chklock 450 */ 451 error = chklock(vp, FREAD, 452 uio->uio_loffset, uio->uio_resid, uio->uio_fmode, ct); 453 rw_enter(&tp->tn_contents, RW_READER); 454 if (error != 0) { 455 TRACE_2(TR_FAC_TMPFS, TR_TMPFS_RWTMP_END, 456 "tmp_rdtmp_end:vp %p error %d", vp, error); 457 return (error); 458 } 459 } 460 ASSERT(tp->tn_type == VREG); 461 462 if (uio->uio_loffset >= MAXOFF_T) { 463 TRACE_2(TR_FAC_TMPFS, TR_TMPFS_RWTMP_END, 464 "tmp_rdtmp_end:vp %p error %d", vp, EINVAL); 465 return (0); 466 } 467 if (uio->uio_loffset < 0) 468 return (EINVAL); 469 if (uio->uio_resid == 0) { 470 TRACE_2(TR_FAC_TMPFS, TR_TMPFS_RWTMP_END, 471 "tmp_rdtmp_end:vp %p error %d", vp, 0); 472 return (0); 473 } 474 475 vp = TNTOV(tp); 476 477 do { 478 long diff; 479 long offset; 480 481 offset = uio->uio_offset; 482 pageoffset = offset & PAGEOFFSET; 483 bytes = MIN(PAGESIZE - pageoffset, uio->uio_resid); 484 485 diff = tp->tn_size - offset; 486 487 if (diff <= 0) { 488 error = 0; 489 goto out; 490 } 491 if (diff < bytes) 492 bytes = diff; 493 494 /* 495 * We have to drop the contents lock to prevent the VM 496 * system from trying to reaquire it in tmp_getpage() 497 * should the uiomove cause a pagefault. 498 */ 499 rw_exit(&tp->tn_contents); 500 501 if (vpm_enable) { 502 /* 503 * Copy data. 504 */ 505 error = vpm_data_copy(vp, offset, bytes, uio, 506 1, NULL, 0, S_READ); 507 } else { 508 segmap_offset = (offset & PAGEMASK) & MAXBOFFSET; 509 base = segmap_getmapflt(segkmap, vp, offset & MAXBMASK, 510 bytes, 1, S_READ); 511 512 error = uiomove(base + segmap_offset + pageoffset, 513 (long)bytes, UIO_READ, uio); 514 } 515 516 if (error) { 517 if (vpm_enable) { 518 (void) vpm_sync_pages(vp, offset, 519 PAGESIZE, 0); 520 } else { 521 (void) segmap_release(segkmap, base, 0); 522 } 523 } else { 524 if (vpm_enable) { 525 error = vpm_sync_pages(vp, offset, 526 PAGESIZE, 0); 527 } else { 528 error = segmap_release(segkmap, base, 0); 529 } 530 } 531 532 /* 533 * Re-acquire contents lock. 534 */ 535 rw_enter(&tp->tn_contents, RW_READER); 536 537 } while (error == 0 && uio->uio_resid > 0); 538 539 out: 540 gethrestime(&tp->tn_atime); 541 542 /* 543 * If we've already done a partial read, terminate 544 * the read but return no error. 545 */ 546 if (oresid != uio->uio_resid) 547 error = 0; 548 549 TRACE_2(TR_FAC_TMPFS, TR_TMPFS_RWTMP_END, 550 "tmp_rdtmp_end:vp %x error %d", vp, error); 551 return (error); 552 } 553 554 /* ARGSUSED2 */ 555 static int 556 tmp_read(struct vnode *vp, struct uio *uiop, int ioflag, cred_t *cred, 557 struct caller_context *ct) 558 { 559 struct tmpnode *tp = (struct tmpnode *)VTOTN(vp); 560 struct tmount *tm = (struct tmount *)VTOTM(vp); 561 int error; 562 563 /* 564 * We don't currently support reading non-regular files 565 */ 566 if (vp->v_type == VDIR) 567 return (EISDIR); 568 if (vp->v_type != VREG) 569 return (EINVAL); 570 /* 571 * tmp_rwlock should have already been called from layers above 572 */ 573 ASSERT(RW_READ_HELD(&tp->tn_rwlock)); 574 575 rw_enter(&tp->tn_contents, RW_READER); 576 577 error = rdtmp(tm, tp, uiop, ct); 578 579 rw_exit(&tp->tn_contents); 580 581 return (error); 582 } 583 584 static int 585 tmp_write(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cred, 586 struct caller_context *ct) 587 { 588 struct tmpnode *tp = (struct tmpnode *)VTOTN(vp); 589 struct tmount *tm = (struct tmount *)VTOTM(vp); 590 int error; 591 592 /* 593 * We don't currently support writing to non-regular files 594 */ 595 if (vp->v_type != VREG) 596 return (EINVAL); /* XXX EISDIR? */ 597 598 /* 599 * tmp_rwlock should have already been called from layers above 600 */ 601 ASSERT(RW_WRITE_HELD(&tp->tn_rwlock)); 602 603 rw_enter(&tp->tn_contents, RW_WRITER); 604 605 if (ioflag & FAPPEND) { 606 /* 607 * In append mode start at end of file. 608 */ 609 uiop->uio_loffset = tp->tn_size; 610 } 611 612 error = wrtmp(tm, tp, uiop, cred, ct); 613 614 rw_exit(&tp->tn_contents); 615 616 return (error); 617 } 618 619 /* ARGSUSED */ 620 static int 621 tmp_ioctl(struct vnode *vp, int com, intptr_t data, int flag, 622 struct cred *cred, int *rvalp) 623 { 624 return (ENOTTY); 625 } 626 627 /* ARGSUSED2 */ 628 static int 629 tmp_getattr(struct vnode *vp, struct vattr *vap, int flags, struct cred *cred) 630 { 631 struct tmpnode *tp = (struct tmpnode *)VTOTN(vp); 632 struct vnode *mvp; 633 struct vattr va; 634 int attrs = 1; 635 636 /* 637 * A special case to handle the root tnode on a diskless nfs 638 * client who may have had its uid and gid inherited 639 * from an nfs vnode with nobody ownership. Likely the 640 * root filesystem. After nfs is fully functional the uid/gid 641 * may be mapable so ask again. 642 * vfsp can't get unmounted because we hold vp. 643 */ 644 if (vp->v_flag & VROOT && 645 (mvp = vp->v_vfsp->vfs_vnodecovered) != NULL) { 646 mutex_enter(&tp->tn_tlock); 647 if (tp->tn_uid == UID_NOBODY || tp->tn_gid == GID_NOBODY) { 648 mutex_exit(&tp->tn_tlock); 649 bzero(&va, sizeof (struct vattr)); 650 va.va_mask = AT_UID|AT_GID; 651 attrs = VOP_GETATTR(mvp, &va, 0, cred); 652 } else { 653 mutex_exit(&tp->tn_tlock); 654 } 655 } 656 mutex_enter(&tp->tn_tlock); 657 if (attrs == 0) { 658 tp->tn_uid = va.va_uid; 659 tp->tn_gid = va.va_gid; 660 } 661 vap->va_type = vp->v_type; 662 vap->va_mode = tp->tn_mode & MODEMASK; 663 vap->va_uid = tp->tn_uid; 664 vap->va_gid = tp->tn_gid; 665 vap->va_fsid = tp->tn_fsid; 666 vap->va_nodeid = (ino64_t)tp->tn_nodeid; 667 vap->va_nlink = tp->tn_nlink; 668 vap->va_size = (u_offset_t)tp->tn_size; 669 vap->va_atime = tp->tn_atime; 670 vap->va_mtime = tp->tn_mtime; 671 vap->va_ctime = tp->tn_ctime; 672 vap->va_blksize = PAGESIZE; 673 vap->va_rdev = tp->tn_rdev; 674 vap->va_seq = tp->tn_seq; 675 676 /* 677 * XXX Holes are not taken into account. We could take the time to 678 * run through the anon array looking for allocated slots... 679 */ 680 vap->va_nblocks = (fsblkcnt64_t)btodb(ptob(btopr(vap->va_size))); 681 mutex_exit(&tp->tn_tlock); 682 return (0); 683 } 684 685 /*ARGSUSED4*/ 686 static int 687 tmp_setattr( 688 struct vnode *vp, 689 struct vattr *vap, 690 int flags, 691 struct cred *cred, 692 caller_context_t *ct) 693 { 694 struct tmount *tm = (struct tmount *)VTOTM(vp); 695 struct tmpnode *tp = (struct tmpnode *)VTOTN(vp); 696 int error = 0; 697 struct vattr *get; 698 long mask; 699 700 /* 701 * Cannot set these attributes 702 */ 703 if (vap->va_mask & AT_NOSET) 704 return (EINVAL); 705 706 mutex_enter(&tp->tn_tlock); 707 708 get = &tp->tn_attr; 709 /* 710 * Change file access modes. Must be owner or have sufficient 711 * privileges. 712 */ 713 error = secpolicy_vnode_setattr(cred, vp, vap, get, flags, 714 tmp_taccess, tp); 715 716 if (error) 717 goto out; 718 719 mask = vap->va_mask; 720 721 if (mask & AT_MODE) { 722 get->va_mode &= S_IFMT; 723 get->va_mode |= vap->va_mode & ~S_IFMT; 724 } 725 726 if (mask & AT_UID) 727 get->va_uid = vap->va_uid; 728 if (mask & AT_GID) 729 get->va_gid = vap->va_gid; 730 if (mask & AT_ATIME) 731 get->va_atime = vap->va_atime; 732 if (mask & AT_MTIME) 733 get->va_mtime = vap->va_mtime; 734 735 if (mask & (AT_UID | AT_GID | AT_MODE | AT_MTIME)) 736 gethrestime(&tp->tn_ctime); 737 738 if (mask & AT_SIZE) { 739 ASSERT(vp->v_type != VDIR); 740 741 /* Don't support large files. */ 742 if (vap->va_size > MAXOFF_T) { 743 error = EFBIG; 744 goto out; 745 } 746 mutex_exit(&tp->tn_tlock); 747 748 rw_enter(&tp->tn_rwlock, RW_WRITER); 749 rw_enter(&tp->tn_contents, RW_WRITER); 750 error = tmpnode_trunc(tm, tp, (ulong_t)vap->va_size); 751 rw_exit(&tp->tn_contents); 752 rw_exit(&tp->tn_rwlock); 753 goto out1; 754 } 755 out: 756 mutex_exit(&tp->tn_tlock); 757 out1: 758 return (error); 759 } 760 761 /* ARGSUSED2 */ 762 static int 763 tmp_access(struct vnode *vp, int mode, int flags, struct cred *cred) 764 { 765 struct tmpnode *tp = (struct tmpnode *)VTOTN(vp); 766 int error; 767 768 mutex_enter(&tp->tn_tlock); 769 error = tmp_taccess(tp, mode, cred); 770 mutex_exit(&tp->tn_tlock); 771 return (error); 772 } 773 774 /* ARGSUSED3 */ 775 static int 776 tmp_lookup( 777 struct vnode *dvp, 778 char *nm, 779 struct vnode **vpp, 780 struct pathname *pnp, 781 int flags, 782 struct vnode *rdir, 783 struct cred *cred) 784 { 785 struct tmpnode *tp = (struct tmpnode *)VTOTN(dvp); 786 struct tmpnode *ntp = NULL; 787 int error; 788 789 790 /* allow cd into @ dir */ 791 if (flags & LOOKUP_XATTR) { 792 struct tmpnode *xdp; 793 struct tmount *tm; 794 795 if (tp->tn_flags & ISXATTR) 796 /* No attributes on attributes */ 797 return (EINVAL); 798 799 rw_enter(&tp->tn_rwlock, RW_WRITER); 800 if (tp->tn_xattrdp == NULL) { 801 if (!(flags & CREATE_XATTR_DIR)) { 802 rw_exit(&tp->tn_rwlock); 803 return (ENOENT); 804 } 805 806 /* 807 * No attribute directory exists for this 808 * node - create the attr dir as a side effect 809 * of this lookup. 810 */ 811 812 /* 813 * Make sure we have adequate permission... 814 */ 815 816 if ((error = tmp_taccess(tp, VWRITE, cred)) != 0) { 817 rw_exit(&tp->tn_rwlock); 818 return (error); 819 } 820 821 xdp = tmp_memalloc(sizeof (struct tmpnode), 822 TMP_MUSTHAVE); 823 tm = VTOTM(dvp); 824 tmpnode_init(tm, xdp, &tp->tn_attr, NULL); 825 /* 826 * Fix-up fields unique to attribute directories. 827 */ 828 xdp->tn_flags = ISXATTR; 829 xdp->tn_type = VDIR; 830 if (tp->tn_type == VDIR) { 831 xdp->tn_mode = tp->tn_attr.va_mode; 832 } else { 833 xdp->tn_mode = 0700; 834 if (tp->tn_attr.va_mode & 0040) 835 xdp->tn_mode |= 0750; 836 if (tp->tn_attr.va_mode & 0004) 837 xdp->tn_mode |= 0705; 838 } 839 xdp->tn_vnode->v_type = VDIR; 840 xdp->tn_vnode->v_flag |= V_XATTRDIR; 841 tdirinit(tp, xdp); 842 tp->tn_xattrdp = xdp; 843 } else { 844 VN_HOLD(tp->tn_xattrdp->tn_vnode); 845 } 846 *vpp = TNTOV(tp->tn_xattrdp); 847 rw_exit(&tp->tn_rwlock); 848 return (0); 849 } 850 851 /* 852 * Null component name is a synonym for directory being searched. 853 */ 854 if (*nm == '\0') { 855 VN_HOLD(dvp); 856 *vpp = dvp; 857 return (0); 858 } 859 ASSERT(tp); 860 861 error = tdirlookup(tp, nm, &ntp, cred); 862 863 if (error == 0) { 864 ASSERT(ntp); 865 *vpp = TNTOV(ntp); 866 /* 867 * If vnode is a device return special vnode instead 868 */ 869 if (IS_DEVVP(*vpp)) { 870 struct vnode *newvp; 871 872 newvp = specvp(*vpp, (*vpp)->v_rdev, (*vpp)->v_type, 873 cred); 874 VN_RELE(*vpp); 875 *vpp = newvp; 876 } 877 } 878 TRACE_4(TR_FAC_TMPFS, TR_TMPFS_LOOKUP, 879 "tmpfs lookup:vp %p name %s vpp %p error %d", 880 dvp, nm, vpp, error); 881 return (error); 882 } 883 884 /*ARGSUSED7*/ 885 static int 886 tmp_create( 887 struct vnode *dvp, 888 char *nm, 889 struct vattr *vap, 890 enum vcexcl exclusive, 891 int mode, 892 struct vnode **vpp, 893 struct cred *cred, 894 int flag) 895 { 896 struct tmpnode *parent; 897 struct tmount *tm; 898 struct tmpnode *self; 899 int error; 900 struct tmpnode *oldtp; 901 902 again: 903 parent = (struct tmpnode *)VTOTN(dvp); 904 tm = (struct tmount *)VTOTM(dvp); 905 self = NULL; 906 error = 0; 907 oldtp = NULL; 908 909 /* device files not allowed in ext. attr dirs */ 910 if ((parent->tn_flags & ISXATTR) && 911 (vap->va_type == VBLK || vap->va_type == VCHR || 912 vap->va_type == VFIFO || vap->va_type == VDOOR || 913 vap->va_type == VSOCK || vap->va_type == VPORT)) 914 return (EINVAL); 915 916 if (vap->va_type == VREG && (vap->va_mode & VSVTX)) { 917 /* Must be privileged to set sticky bit */ 918 if (secpolicy_vnode_stky_modify(cred)) 919 vap->va_mode &= ~VSVTX; 920 } else if (vap->va_type == VNON) { 921 return (EINVAL); 922 } 923 924 /* 925 * Null component name is a synonym for directory being searched. 926 */ 927 if (*nm == '\0') { 928 VN_HOLD(dvp); 929 oldtp = parent; 930 } else { 931 error = tdirlookup(parent, nm, &oldtp, cred); 932 } 933 934 if (error == 0) { /* name found */ 935 ASSERT(oldtp); 936 937 rw_enter(&oldtp->tn_rwlock, RW_WRITER); 938 939 /* 940 * if create/read-only an existing 941 * directory, allow it 942 */ 943 if (exclusive == EXCL) 944 error = EEXIST; 945 else if ((oldtp->tn_type == VDIR) && (mode & VWRITE)) 946 error = EISDIR; 947 else { 948 error = tmp_taccess(oldtp, mode, cred); 949 } 950 951 if (error) { 952 rw_exit(&oldtp->tn_rwlock); 953 tmpnode_rele(oldtp); 954 return (error); 955 } 956 *vpp = TNTOV(oldtp); 957 if ((*vpp)->v_type == VREG && (vap->va_mask & AT_SIZE) && 958 vap->va_size == 0) { 959 rw_enter(&oldtp->tn_contents, RW_WRITER); 960 (void) tmpnode_trunc(tm, oldtp, 0); 961 rw_exit(&oldtp->tn_contents); 962 } 963 rw_exit(&oldtp->tn_rwlock); 964 if (IS_DEVVP(*vpp)) { 965 struct vnode *newvp; 966 967 newvp = specvp(*vpp, (*vpp)->v_rdev, (*vpp)->v_type, 968 cred); 969 VN_RELE(*vpp); 970 if (newvp == NULL) { 971 return (ENOSYS); 972 } 973 *vpp = newvp; 974 } 975 return (0); 976 } 977 978 if (error != ENOENT) 979 return (error); 980 981 rw_enter(&parent->tn_rwlock, RW_WRITER); 982 error = tdirenter(tm, parent, nm, DE_CREATE, 983 (struct tmpnode *)NULL, (struct tmpnode *)NULL, 984 vap, &self, cred); 985 rw_exit(&parent->tn_rwlock); 986 987 if (error) { 988 if (self) 989 tmpnode_rele(self); 990 991 if (error == EEXIST) { 992 /* 993 * This means that the file was created sometime 994 * after we checked and did not find it and when 995 * we went to create it. 996 * Since creat() is supposed to truncate a file 997 * that already exits go back to the begining 998 * of the function. This time we will find it 999 * and go down the tmp_trunc() path 1000 */ 1001 goto again; 1002 } 1003 return (error); 1004 } 1005 1006 *vpp = TNTOV(self); 1007 1008 if (!error && IS_DEVVP(*vpp)) { 1009 struct vnode *newvp; 1010 1011 newvp = specvp(*vpp, (*vpp)->v_rdev, (*vpp)->v_type, cred); 1012 VN_RELE(*vpp); 1013 if (newvp == NULL) 1014 return (ENOSYS); 1015 *vpp = newvp; 1016 } 1017 TRACE_3(TR_FAC_TMPFS, TR_TMPFS_CREATE, 1018 "tmpfs create:dvp %p nm %s vpp %p", dvp, nm, vpp); 1019 return (0); 1020 } 1021 1022 static int 1023 tmp_remove(struct vnode *dvp, char *nm, struct cred *cred) 1024 { 1025 struct tmpnode *parent = (struct tmpnode *)VTOTN(dvp); 1026 int error; 1027 struct tmpnode *tp = NULL; 1028 1029 error = tdirlookup(parent, nm, &tp, cred); 1030 if (error) 1031 return (error); 1032 1033 ASSERT(tp); 1034 rw_enter(&parent->tn_rwlock, RW_WRITER); 1035 rw_enter(&tp->tn_rwlock, RW_WRITER); 1036 1037 if (tp->tn_type != VDIR || 1038 (error = secpolicy_fs_linkdir(cred, dvp->v_vfsp)) == 0) 1039 error = tdirdelete(parent, tp, nm, DR_REMOVE, cred); 1040 1041 rw_exit(&tp->tn_rwlock); 1042 rw_exit(&parent->tn_rwlock); 1043 vnevent_remove(TNTOV(tp)); 1044 tmpnode_rele(tp); 1045 1046 TRACE_3(TR_FAC_TMPFS, TR_TMPFS_REMOVE, 1047 "tmpfs remove:dvp %p nm %s error %d", dvp, nm, error); 1048 return (error); 1049 } 1050 1051 static int 1052 tmp_link(struct vnode *dvp, struct vnode *srcvp, char *tnm, struct cred *cred) 1053 { 1054 struct tmpnode *parent; 1055 struct tmpnode *from; 1056 struct tmount *tm = (struct tmount *)VTOTM(dvp); 1057 int error; 1058 struct tmpnode *found = NULL; 1059 struct vnode *realvp; 1060 1061 if (VOP_REALVP(srcvp, &realvp) == 0) 1062 srcvp = realvp; 1063 1064 parent = (struct tmpnode *)VTOTN(dvp); 1065 from = (struct tmpnode *)VTOTN(srcvp); 1066 1067 if ((srcvp->v_type == VDIR && 1068 secpolicy_fs_linkdir(cred, dvp->v_vfsp)) || 1069 (from->tn_uid != crgetuid(cred) && secpolicy_basic_link(cred))) 1070 return (EPERM); 1071 1072 /* 1073 * Make sure link for extended attributes is valid 1074 * We only support hard linking of xattr's in xattrdir to an xattrdir 1075 */ 1076 if ((from->tn_flags & ISXATTR) != (parent->tn_flags & ISXATTR)) 1077 return (EINVAL); 1078 1079 error = tdirlookup(parent, tnm, &found, cred); 1080 if (error == 0) { 1081 ASSERT(found); 1082 tmpnode_rele(found); 1083 return (EEXIST); 1084 } 1085 1086 if (error != ENOENT) 1087 return (error); 1088 1089 rw_enter(&parent->tn_rwlock, RW_WRITER); 1090 error = tdirenter(tm, parent, tnm, DE_LINK, (struct tmpnode *)NULL, 1091 from, NULL, (struct tmpnode **)NULL, cred); 1092 rw_exit(&parent->tn_rwlock); 1093 return (error); 1094 } 1095 1096 static int 1097 tmp_rename( 1098 struct vnode *odvp, /* source parent vnode */ 1099 char *onm, /* source name */ 1100 struct vnode *ndvp, /* destination parent vnode */ 1101 char *nnm, /* destination name */ 1102 struct cred *cred) 1103 { 1104 struct tmpnode *fromparent; 1105 struct tmpnode *toparent; 1106 struct tmpnode *fromtp = NULL; /* source tmpnode */ 1107 struct tmount *tm = (struct tmount *)VTOTM(odvp); 1108 int error; 1109 int samedir = 0; /* set if odvp == ndvp */ 1110 struct vnode *realvp; 1111 1112 if (VOP_REALVP(ndvp, &realvp) == 0) 1113 ndvp = realvp; 1114 1115 fromparent = (struct tmpnode *)VTOTN(odvp); 1116 toparent = (struct tmpnode *)VTOTN(ndvp); 1117 1118 if ((fromparent->tn_flags & ISXATTR) != (toparent->tn_flags & ISXATTR)) 1119 return (EINVAL); 1120 1121 mutex_enter(&tm->tm_renamelck); 1122 1123 /* 1124 * Look up tmpnode of file we're supposed to rename. 1125 */ 1126 error = tdirlookup(fromparent, onm, &fromtp, cred); 1127 if (error) { 1128 mutex_exit(&tm->tm_renamelck); 1129 return (error); 1130 } 1131 1132 /* 1133 * Make sure we can delete the old (source) entry. This 1134 * requires write permission on the containing directory. If 1135 * that directory is "sticky" it requires further checks. 1136 */ 1137 if (((error = tmp_taccess(fromparent, VWRITE, cred)) != 0) || 1138 (error = tmp_sticky_remove_access(fromparent, fromtp, cred)) != 0) 1139 goto done; 1140 1141 /* 1142 * Check for renaming to or from '.' or '..' or that 1143 * fromtp == fromparent 1144 */ 1145 if ((onm[0] == '.' && 1146 (onm[1] == '\0' || (onm[1] == '.' && onm[2] == '\0'))) || 1147 (nnm[0] == '.' && 1148 (nnm[1] == '\0' || (nnm[1] == '.' && nnm[2] == '\0'))) || 1149 (fromparent == fromtp)) { 1150 error = EINVAL; 1151 goto done; 1152 } 1153 1154 samedir = (fromparent == toparent); 1155 /* 1156 * Make sure we can search and rename into the new 1157 * (destination) directory. 1158 */ 1159 if (!samedir) { 1160 error = tmp_taccess(toparent, VEXEC|VWRITE, cred); 1161 if (error) 1162 goto done; 1163 } 1164 1165 /* 1166 * Link source to new target 1167 */ 1168 rw_enter(&toparent->tn_rwlock, RW_WRITER); 1169 error = tdirenter(tm, toparent, nnm, DE_RENAME, 1170 fromparent, fromtp, (struct vattr *)NULL, 1171 (struct tmpnode **)NULL, cred); 1172 rw_exit(&toparent->tn_rwlock); 1173 1174 if (error) { 1175 /* 1176 * ESAME isn't really an error; it indicates that the 1177 * operation should not be done because the source and target 1178 * are the same file, but that no error should be reported. 1179 */ 1180 if (error == ESAME) 1181 error = 0; 1182 goto done; 1183 } 1184 1185 /* 1186 * Unlink from source. 1187 */ 1188 rw_enter(&fromparent->tn_rwlock, RW_WRITER); 1189 rw_enter(&fromtp->tn_rwlock, RW_WRITER); 1190 1191 error = tdirdelete(fromparent, fromtp, onm, DR_RENAME, cred); 1192 1193 /* 1194 * The following handles the case where our source tmpnode was 1195 * removed before we got to it. 1196 * 1197 * XXX We should also cleanup properly in the case where tdirdelete 1198 * fails for some other reason. Currently this case shouldn't happen. 1199 * (see 1184991). 1200 */ 1201 if (error == ENOENT) 1202 error = 0; 1203 1204 rw_exit(&fromtp->tn_rwlock); 1205 rw_exit(&fromparent->tn_rwlock); 1206 done: 1207 tmpnode_rele(fromtp); 1208 mutex_exit(&tm->tm_renamelck); 1209 1210 TRACE_5(TR_FAC_TMPFS, TR_TMPFS_RENAME, 1211 "tmpfs rename:ovp %p onm %s nvp %p nnm %s error %d", 1212 odvp, onm, ndvp, nnm, error); 1213 return (error); 1214 } 1215 1216 static int 1217 tmp_mkdir( 1218 struct vnode *dvp, 1219 char *nm, 1220 struct vattr *va, 1221 struct vnode **vpp, 1222 struct cred *cred) 1223 { 1224 struct tmpnode *parent = (struct tmpnode *)VTOTN(dvp); 1225 struct tmpnode *self = NULL; 1226 struct tmount *tm = (struct tmount *)VTOTM(dvp); 1227 int error; 1228 1229 /* no new dirs allowed in xattr dirs */ 1230 if (parent->tn_flags & ISXATTR) 1231 return (EINVAL); 1232 1233 /* 1234 * Might be dangling directory. Catch it here, 1235 * because a ENOENT return from tdirlookup() is 1236 * an "o.k. return". 1237 */ 1238 if (parent->tn_nlink == 0) 1239 return (ENOENT); 1240 1241 error = tdirlookup(parent, nm, &self, cred); 1242 if (error == 0) { 1243 ASSERT(self); 1244 tmpnode_rele(self); 1245 return (EEXIST); 1246 } 1247 if (error != ENOENT) 1248 return (error); 1249 1250 rw_enter(&parent->tn_rwlock, RW_WRITER); 1251 error = tdirenter(tm, parent, nm, DE_MKDIR, 1252 (struct tmpnode *)NULL, (struct tmpnode *)NULL, va, 1253 &self, cred); 1254 if (error) { 1255 rw_exit(&parent->tn_rwlock); 1256 if (self) 1257 tmpnode_rele(self); 1258 return (error); 1259 } 1260 rw_exit(&parent->tn_rwlock); 1261 *vpp = TNTOV(self); 1262 return (0); 1263 } 1264 1265 static int 1266 tmp_rmdir( 1267 struct vnode *dvp, 1268 char *nm, 1269 struct vnode *cdir, 1270 struct cred *cred) 1271 { 1272 struct tmpnode *parent = (struct tmpnode *)VTOTN(dvp); 1273 struct tmpnode *self = NULL; 1274 struct vnode *vp; 1275 int error = 0; 1276 1277 /* 1278 * Return error when removing . and .. 1279 */ 1280 if (strcmp(nm, ".") == 0) 1281 return (EINVAL); 1282 if (strcmp(nm, "..") == 0) 1283 return (EEXIST); /* Should be ENOTEMPTY */ 1284 error = tdirlookup(parent, nm, &self, cred); 1285 if (error) 1286 return (error); 1287 1288 rw_enter(&parent->tn_rwlock, RW_WRITER); 1289 rw_enter(&self->tn_rwlock, RW_WRITER); 1290 1291 vp = TNTOV(self); 1292 if (vp == dvp || vp == cdir) { 1293 error = EINVAL; 1294 goto done1; 1295 } 1296 if (self->tn_type != VDIR) { 1297 error = ENOTDIR; 1298 goto done1; 1299 } 1300 1301 mutex_enter(&self->tn_tlock); 1302 if (self->tn_nlink > 2) { 1303 mutex_exit(&self->tn_tlock); 1304 error = EEXIST; 1305 goto done1; 1306 } 1307 mutex_exit(&self->tn_tlock); 1308 1309 if (vn_vfswlock(vp)) { 1310 error = EBUSY; 1311 goto done1; 1312 } 1313 if (vn_mountedvfs(vp) != NULL) { 1314 error = EBUSY; 1315 goto done; 1316 } 1317 1318 /* 1319 * Check for an empty directory 1320 * i.e. only includes entries for "." and ".." 1321 */ 1322 if (self->tn_dirents > 2) { 1323 error = EEXIST; /* SIGH should be ENOTEMPTY */ 1324 /* 1325 * Update atime because checking tn_dirents is logically 1326 * equivalent to reading the directory 1327 */ 1328 gethrestime(&self->tn_atime); 1329 goto done; 1330 } 1331 1332 error = tdirdelete(parent, self, nm, DR_RMDIR, cred); 1333 done: 1334 vn_vfsunlock(vp); 1335 done1: 1336 rw_exit(&self->tn_rwlock); 1337 rw_exit(&parent->tn_rwlock); 1338 vnevent_rmdir(TNTOV(self)); 1339 tmpnode_rele(self); 1340 1341 return (error); 1342 } 1343 1344 /* ARGSUSED2 */ 1345 1346 static int 1347 tmp_readdir(struct vnode *vp, struct uio *uiop, struct cred *cred, int *eofp) 1348 { 1349 struct tmpnode *tp = (struct tmpnode *)VTOTN(vp); 1350 struct tdirent *tdp; 1351 int error = 0; 1352 size_t namelen; 1353 struct dirent64 *dp; 1354 ulong_t offset; 1355 ulong_t total_bytes_wanted; 1356 long outcount = 0; 1357 long bufsize; 1358 int reclen; 1359 caddr_t outbuf; 1360 1361 if (uiop->uio_loffset >= MAXOFF_T) { 1362 if (eofp) 1363 *eofp = 1; 1364 return (0); 1365 } 1366 /* 1367 * assuming system call has already called tmp_rwlock 1368 */ 1369 ASSERT(RW_READ_HELD(&tp->tn_rwlock)); 1370 1371 if (uiop->uio_iovcnt != 1) 1372 return (EINVAL); 1373 1374 if (vp->v_type != VDIR) 1375 return (ENOTDIR); 1376 1377 /* 1378 * There's a window here where someone could have removed 1379 * all the entries in the directory after we put a hold on the 1380 * vnode but before we grabbed the rwlock. Just return. 1381 */ 1382 if (tp->tn_dir == NULL) { 1383 if (tp->tn_nlink) { 1384 panic("empty directory 0x%p", (void *)tp); 1385 /*NOTREACHED*/ 1386 } 1387 return (0); 1388 } 1389 1390 /* 1391 * Get space for multiple directory entries 1392 */ 1393 total_bytes_wanted = uiop->uio_iov->iov_len; 1394 bufsize = total_bytes_wanted + sizeof (struct dirent64); 1395 outbuf = kmem_alloc(bufsize, KM_SLEEP); 1396 1397 dp = (struct dirent64 *)outbuf; 1398 1399 1400 offset = 0; 1401 tdp = tp->tn_dir; 1402 while (tdp) { 1403 namelen = strlen(tdp->td_name); /* no +1 needed */ 1404 offset = tdp->td_offset; 1405 if (offset >= uiop->uio_offset) { 1406 reclen = (int)DIRENT64_RECLEN(namelen); 1407 if (outcount + reclen > total_bytes_wanted) { 1408 if (!outcount) 1409 /* 1410 * Buffer too small for any entries. 1411 */ 1412 error = EINVAL; 1413 break; 1414 } 1415 ASSERT(tdp->td_tmpnode != NULL); 1416 1417 /* use strncpy(9f) to zero out uninitialized bytes */ 1418 1419 (void) strncpy(dp->d_name, tdp->td_name, 1420 DIRENT64_NAMELEN(reclen)); 1421 dp->d_reclen = (ushort_t)reclen; 1422 dp->d_ino = (ino64_t)tdp->td_tmpnode->tn_nodeid; 1423 dp->d_off = (offset_t)tdp->td_offset + 1; 1424 dp = (struct dirent64 *) 1425 ((uintptr_t)dp + dp->d_reclen); 1426 outcount += reclen; 1427 ASSERT(outcount <= bufsize); 1428 } 1429 tdp = tdp->td_next; 1430 } 1431 1432 if (!error) 1433 error = uiomove(outbuf, outcount, UIO_READ, uiop); 1434 1435 if (!error) { 1436 /* If we reached the end of the list our offset */ 1437 /* should now be just past the end. */ 1438 if (!tdp) { 1439 offset += 1; 1440 if (eofp) 1441 *eofp = 1; 1442 } else if (eofp) 1443 *eofp = 0; 1444 uiop->uio_offset = offset; 1445 } 1446 gethrestime(&tp->tn_atime); 1447 kmem_free(outbuf, bufsize); 1448 return (error); 1449 } 1450 1451 static int 1452 tmp_symlink( 1453 struct vnode *dvp, 1454 char *lnm, 1455 struct vattr *tva, 1456 char *tnm, 1457 struct cred *cred) 1458 { 1459 struct tmpnode *parent = (struct tmpnode *)VTOTN(dvp); 1460 struct tmpnode *self = (struct tmpnode *)NULL; 1461 struct tmount *tm = (struct tmount *)VTOTM(dvp); 1462 char *cp = NULL; 1463 int error; 1464 size_t len; 1465 1466 /* no symlinks allowed to files in xattr dirs */ 1467 if (parent->tn_flags & ISXATTR) 1468 return (EINVAL); 1469 1470 error = tdirlookup(parent, lnm, &self, cred); 1471 if (error == 0) { 1472 /* 1473 * The entry already exists 1474 */ 1475 tmpnode_rele(self); 1476 return (EEXIST); /* was 0 */ 1477 } 1478 1479 if (error != ENOENT) { 1480 if (self != NULL) 1481 tmpnode_rele(self); 1482 return (error); 1483 } 1484 1485 rw_enter(&parent->tn_rwlock, RW_WRITER); 1486 error = tdirenter(tm, parent, lnm, DE_CREATE, (struct tmpnode *)NULL, 1487 (struct tmpnode *)NULL, tva, &self, cred); 1488 rw_exit(&parent->tn_rwlock); 1489 1490 if (error) { 1491 if (self) 1492 tmpnode_rele(self); 1493 return (error); 1494 } 1495 len = strlen(tnm) + 1; 1496 cp = tmp_memalloc(len, 0); 1497 if (cp == NULL) { 1498 tmpnode_rele(self); 1499 return (ENOSPC); 1500 } 1501 (void) strcpy(cp, tnm); 1502 1503 self->tn_symlink = cp; 1504 self->tn_size = len - 1; 1505 tmpnode_rele(self); 1506 return (error); 1507 } 1508 1509 /* ARGSUSED2 */ 1510 static int 1511 tmp_readlink(struct vnode *vp, struct uio *uiop, struct cred *cred) 1512 { 1513 struct tmpnode *tp = (struct tmpnode *)VTOTN(vp); 1514 int error = 0; 1515 1516 if (vp->v_type != VLNK) 1517 return (EINVAL); 1518 1519 rw_enter(&tp->tn_rwlock, RW_READER); 1520 rw_enter(&tp->tn_contents, RW_READER); 1521 error = uiomove(tp->tn_symlink, tp->tn_size, UIO_READ, uiop); 1522 gethrestime(&tp->tn_atime); 1523 rw_exit(&tp->tn_contents); 1524 rw_exit(&tp->tn_rwlock); 1525 return (error); 1526 } 1527 1528 /* ARGSUSED */ 1529 static int 1530 tmp_fsync(struct vnode *vp, int syncflag, struct cred *cred) 1531 { 1532 return (0); 1533 } 1534 1535 /* ARGSUSED */ 1536 static void 1537 tmp_inactive(struct vnode *vp, struct cred *cred) 1538 { 1539 struct tmpnode *tp = (struct tmpnode *)VTOTN(vp); 1540 struct tmount *tm = (struct tmount *)VFSTOTM(vp->v_vfsp); 1541 1542 rw_enter(&tp->tn_rwlock, RW_WRITER); 1543 top: 1544 mutex_enter(&tp->tn_tlock); 1545 mutex_enter(&vp->v_lock); 1546 ASSERT(vp->v_count >= 1); 1547 1548 /* 1549 * If we don't have the last hold or the link count is non-zero, 1550 * there's little to do -- just drop our hold. 1551 */ 1552 if (vp->v_count > 1 || tp->tn_nlink != 0) { 1553 vp->v_count--; 1554 mutex_exit(&vp->v_lock); 1555 mutex_exit(&tp->tn_tlock); 1556 rw_exit(&tp->tn_rwlock); 1557 return; 1558 } 1559 1560 /* 1561 * We have the last hold *and* the link count is zero, so this 1562 * tmpnode is dead from the filesystem's viewpoint. However, 1563 * if the tmpnode has any pages associated with it (i.e. if it's 1564 * a normal file with non-zero size), the tmpnode can still be 1565 * discovered by pageout or fsflush via the page vnode pointers. 1566 * In this case we must drop all our locks, truncate the tmpnode, 1567 * and try the whole dance again. 1568 */ 1569 if (tp->tn_size != 0) { 1570 if (tp->tn_type == VREG) { 1571 mutex_exit(&vp->v_lock); 1572 mutex_exit(&tp->tn_tlock); 1573 rw_enter(&tp->tn_contents, RW_WRITER); 1574 (void) tmpnode_trunc(tm, tp, 0); 1575 rw_exit(&tp->tn_contents); 1576 ASSERT(tp->tn_size == 0); 1577 ASSERT(tp->tn_nblocks == 0); 1578 goto top; 1579 } 1580 if (tp->tn_type == VLNK) 1581 tmp_memfree(tp->tn_symlink, tp->tn_size + 1); 1582 } 1583 1584 /* 1585 * Remove normal file/dir's xattr dir and xattrs. 1586 */ 1587 if (tp->tn_xattrdp) { 1588 struct tmpnode *xtp = tp->tn_xattrdp; 1589 1590 ASSERT(xtp->tn_flags & ISXATTR); 1591 tmpnode_hold(xtp); 1592 rw_enter(&xtp->tn_rwlock, RW_WRITER); 1593 tdirtrunc(xtp); 1594 DECR_COUNT(&xtp->tn_nlink, &xtp->tn_tlock); 1595 tp->tn_xattrdp = NULL; 1596 rw_exit(&xtp->tn_rwlock); 1597 tmpnode_rele(xtp); 1598 } 1599 1600 mutex_exit(&vp->v_lock); 1601 mutex_exit(&tp->tn_tlock); 1602 /* Here's our chance to send invalid event while we're between locks */ 1603 vn_invalid(TNTOV(tp)); 1604 mutex_enter(&tm->tm_contents); 1605 if (tp->tn_forw == NULL) 1606 tm->tm_rootnode->tn_back = tp->tn_back; 1607 else 1608 tp->tn_forw->tn_back = tp->tn_back; 1609 tp->tn_back->tn_forw = tp->tn_forw; 1610 mutex_exit(&tm->tm_contents); 1611 rw_exit(&tp->tn_rwlock); 1612 rw_destroy(&tp->tn_rwlock); 1613 mutex_destroy(&tp->tn_tlock); 1614 vn_free(TNTOV(tp)); 1615 tmp_memfree(tp, sizeof (struct tmpnode)); 1616 } 1617 1618 static int 1619 tmp_fid(struct vnode *vp, struct fid *fidp) 1620 { 1621 struct tmpnode *tp = (struct tmpnode *)VTOTN(vp); 1622 struct tfid *tfid; 1623 1624 if (fidp->fid_len < (sizeof (struct tfid) - sizeof (ushort_t))) { 1625 fidp->fid_len = sizeof (struct tfid) - sizeof (ushort_t); 1626 return (ENOSPC); 1627 } 1628 1629 tfid = (struct tfid *)fidp; 1630 bzero(tfid, sizeof (struct tfid)); 1631 tfid->tfid_len = (int)sizeof (struct tfid) - sizeof (ushort_t); 1632 1633 tfid->tfid_ino = tp->tn_nodeid; 1634 tfid->tfid_gen = tp->tn_gen; 1635 1636 return (0); 1637 } 1638 1639 1640 /* 1641 * Return all the pages from [off..off+len] in given file 1642 */ 1643 static int 1644 tmp_getpage( 1645 struct vnode *vp, 1646 offset_t off, 1647 size_t len, 1648 uint_t *protp, 1649 page_t *pl[], 1650 size_t plsz, 1651 struct seg *seg, 1652 caddr_t addr, 1653 enum seg_rw rw, 1654 struct cred *cr) 1655 { 1656 int err = 0; 1657 struct tmpnode *tp = VTOTN(vp); 1658 anoff_t toff = (anoff_t)off; 1659 size_t tlen = len; 1660 u_offset_t tmpoff; 1661 timestruc_t now; 1662 1663 rw_enter(&tp->tn_contents, RW_READER); 1664 1665 if (off + len > tp->tn_size + PAGEOFFSET) { 1666 err = EFAULT; 1667 goto out; 1668 } 1669 /* 1670 * Look for holes (no anon slot) in faulting range. If there are 1671 * holes we have to switch to a write lock and fill them in. Swap 1672 * space for holes was already reserved when the file was grown. 1673 */ 1674 tmpoff = toff; 1675 if (non_anon(tp->tn_anon, btop(off), &tmpoff, &tlen)) { 1676 if (!rw_tryupgrade(&tp->tn_contents)) { 1677 rw_exit(&tp->tn_contents); 1678 rw_enter(&tp->tn_contents, RW_WRITER); 1679 /* Size may have changed when lock was dropped */ 1680 if (off + len > tp->tn_size + PAGEOFFSET) { 1681 err = EFAULT; 1682 goto out; 1683 } 1684 } 1685 for (toff = (anoff_t)off; toff < (anoff_t)off + len; 1686 toff += PAGESIZE) { 1687 if (anon_get_ptr(tp->tn_anon, btop(toff)) == NULL) { 1688 /* XXX - may allocate mem w. write lock held */ 1689 (void) anon_set_ptr(tp->tn_anon, btop(toff), 1690 anon_alloc(vp, toff), 1691 ANON_SLEEP); 1692 tp->tn_nblocks++; 1693 } 1694 } 1695 rw_downgrade(&tp->tn_contents); 1696 } 1697 1698 1699 if (len <= PAGESIZE) 1700 err = tmp_getapage(vp, (u_offset_t)off, len, protp, pl, plsz, 1701 seg, addr, rw, cr); 1702 else 1703 err = pvn_getpages(tmp_getapage, vp, (u_offset_t)off, len, 1704 protp, pl, plsz, seg, addr, rw, cr); 1705 1706 gethrestime(&now); 1707 tp->tn_atime = now; 1708 if (rw == S_WRITE) 1709 tp->tn_mtime = now; 1710 1711 out: 1712 rw_exit(&tp->tn_contents); 1713 return (err); 1714 } 1715 1716 /* 1717 * Called from pvn_getpages or swap_getpage to get a particular page. 1718 */ 1719 /*ARGSUSED*/ 1720 static int 1721 tmp_getapage( 1722 struct vnode *vp, 1723 u_offset_t off, 1724 size_t len, 1725 uint_t *protp, 1726 page_t *pl[], 1727 size_t plsz, 1728 struct seg *seg, 1729 caddr_t addr, 1730 enum seg_rw rw, 1731 struct cred *cr) 1732 { 1733 struct page *pp; 1734 int flags; 1735 int err = 0; 1736 struct vnode *pvp; 1737 u_offset_t poff; 1738 1739 if (protp != NULL) 1740 *protp = PROT_ALL; 1741 again: 1742 if (pp = page_lookup(vp, off, rw == S_CREATE ? SE_EXCL : SE_SHARED)) { 1743 if (pl) { 1744 pl[0] = pp; 1745 pl[1] = NULL; 1746 } else { 1747 page_unlock(pp); 1748 } 1749 } else { 1750 pp = page_create_va(vp, off, PAGESIZE, 1751 PG_WAIT | PG_EXCL, seg, addr); 1752 /* 1753 * Someone raced in and created the page after we did the 1754 * lookup but before we did the create, so go back and 1755 * try to look it up again. 1756 */ 1757 if (pp == NULL) 1758 goto again; 1759 /* 1760 * Fill page from backing store, if any. If none, then 1761 * either this is a newly filled hole or page must have 1762 * been unmodified and freed so just zero it out. 1763 */ 1764 err = swap_getphysname(vp, off, &pvp, &poff); 1765 if (err) { 1766 panic("tmp_getapage: no anon slot vp %p " 1767 "off %llx pp %p\n", (void *)vp, off, (void *)pp); 1768 } 1769 if (pvp) { 1770 flags = (pl == NULL ? B_ASYNC|B_READ : B_READ); 1771 err = VOP_PAGEIO(pvp, pp, (u_offset_t)poff, PAGESIZE, 1772 flags, cr); 1773 if (flags & B_ASYNC) 1774 pp = NULL; 1775 } else if (rw != S_CREATE) { 1776 pagezero(pp, 0, PAGESIZE); 1777 } 1778 if (err && pp) 1779 pvn_read_done(pp, B_ERROR); 1780 if (err == 0) { 1781 if (pl) 1782 pvn_plist_init(pp, pl, plsz, off, PAGESIZE, rw); 1783 else 1784 pvn_io_done(pp); 1785 } 1786 } 1787 return (err); 1788 } 1789 1790 1791 /* 1792 * Flags are composed of {B_INVAL, B_DIRTY B_FREE, B_DONTNEED}. 1793 * If len == 0, do from off to EOF. 1794 */ 1795 static int tmp_nopage = 0; /* Don't do tmp_putpage's if set */ 1796 1797 /* ARGSUSED */ 1798 int 1799 tmp_putpage( 1800 register struct vnode *vp, 1801 offset_t off, 1802 size_t len, 1803 int flags, 1804 struct cred *cr) 1805 { 1806 register page_t *pp; 1807 u_offset_t io_off; 1808 size_t io_len = 0; 1809 int err = 0; 1810 struct tmpnode *tp = VTOTN(vp); 1811 int dolock; 1812 1813 if (tmp_nopage) 1814 return (0); 1815 1816 ASSERT(vp->v_count != 0); 1817 1818 if (vp->v_flag & VNOMAP) 1819 return (ENOSYS); 1820 1821 /* 1822 * This being tmpfs, we don't ever do i/o unless we really 1823 * have to (when we're low on memory and pageout calls us 1824 * with B_ASYNC | B_FREE or the user explicitly asks for it with 1825 * B_DONTNEED). 1826 * XXX to approximately track the mod time like ufs we should 1827 * update the times here. The problem is, once someone does a 1828 * store we never clear the mod bit and do i/o, thus fsflush 1829 * will keep calling us every 30 seconds to do the i/o and we'll 1830 * continually update the mod time. At least we update the mod 1831 * time on the first store because this results in a call to getpage. 1832 */ 1833 if (flags != (B_ASYNC | B_FREE) && (flags & B_INVAL) == 0 && 1834 (flags & B_DONTNEED) == 0) 1835 return (0); 1836 /* 1837 * If this thread owns the lock, i.e., this thread grabbed it 1838 * as writer somewhere above, then we don't need to grab the 1839 * lock as reader in this routine. 1840 */ 1841 dolock = (rw_owner(&tp->tn_contents) != curthread); 1842 1843 /* 1844 * If this is pageout don't block on the lock as you could deadlock 1845 * when freemem == 0 (another thread has the read lock and is blocked 1846 * creating a page, and a third thread is waiting to get the writers 1847 * lock - waiting writers priority blocks us from getting the read 1848 * lock). Of course, if the only freeable pages are on this tmpnode 1849 * we're hosed anyways. A better solution might be a new lock type. 1850 * Note: ufs has the same problem. 1851 */ 1852 if (curproc == proc_pageout) { 1853 if (!rw_tryenter(&tp->tn_contents, RW_READER)) 1854 return (ENOMEM); 1855 } else if (dolock) 1856 rw_enter(&tp->tn_contents, RW_READER); 1857 1858 if (!vn_has_cached_data(vp)) 1859 goto out; 1860 1861 if (len == 0) { 1862 if (curproc == proc_pageout) { 1863 panic("tmp: pageout can't block"); 1864 /*NOTREACHED*/ 1865 } 1866 1867 /* Search the entire vp list for pages >= off. */ 1868 err = pvn_vplist_dirty(vp, (u_offset_t)off, tmp_putapage, 1869 flags, cr); 1870 } else { 1871 u_offset_t eoff; 1872 1873 /* 1874 * Loop over all offsets in the range [off...off + len] 1875 * looking for pages to deal with. 1876 */ 1877 eoff = MIN(off + len, tp->tn_size); 1878 for (io_off = off; io_off < eoff; io_off += io_len) { 1879 /* 1880 * If we are not invalidating, synchronously 1881 * freeing or writing pages use the routine 1882 * page_lookup_nowait() to prevent reclaiming 1883 * them from the free list. 1884 */ 1885 if ((flags & B_INVAL) || ((flags & B_ASYNC) == 0)) { 1886 pp = page_lookup(vp, io_off, 1887 (flags & (B_INVAL | B_FREE)) ? 1888 SE_EXCL : SE_SHARED); 1889 } else { 1890 pp = page_lookup_nowait(vp, io_off, 1891 (flags & B_FREE) ? SE_EXCL : SE_SHARED); 1892 } 1893 1894 if (pp == NULL || pvn_getdirty(pp, flags) == 0) 1895 io_len = PAGESIZE; 1896 else { 1897 err = tmp_putapage(vp, pp, &io_off, &io_len, 1898 flags, cr); 1899 if (err != 0) 1900 break; 1901 } 1902 } 1903 } 1904 /* If invalidating, verify all pages on vnode list are gone. */ 1905 if (err == 0 && off == 0 && len == 0 && 1906 (flags & B_INVAL) && vn_has_cached_data(vp)) { 1907 panic("tmp_putpage: B_INVAL, pages not gone"); 1908 /*NOTREACHED*/ 1909 } 1910 out: 1911 if ((curproc == proc_pageout) || dolock) 1912 rw_exit(&tp->tn_contents); 1913 /* 1914 * Only reason putapage is going to give us SE_NOSWAP as error 1915 * is when we ask a page to be written to physical backing store 1916 * and there is none. Ignore this because we might be dealing 1917 * with a swap page which does not have any backing store 1918 * on disk. In any other case we won't get this error over here. 1919 */ 1920 if (err == SE_NOSWAP) 1921 err = 0; 1922 return (err); 1923 } 1924 1925 long tmp_putpagecnt, tmp_pagespushed; 1926 1927 /* 1928 * Write out a single page. 1929 * For tmpfs this means choose a physical swap slot and write the page 1930 * out using VOP_PAGEIO. For performance, we attempt to kluster; i.e., 1931 * we try to find a bunch of other dirty pages adjacent in the file 1932 * and a bunch of contiguous swap slots, and then write all the pages 1933 * out in a single i/o. 1934 */ 1935 /*ARGSUSED*/ 1936 static int 1937 tmp_putapage( 1938 struct vnode *vp, 1939 page_t *pp, 1940 u_offset_t *offp, 1941 size_t *lenp, 1942 int flags, 1943 struct cred *cr) 1944 { 1945 int err; 1946 ulong_t klstart, kllen; 1947 page_t *pplist, *npplist; 1948 extern int klustsize; 1949 long tmp_klustsize; 1950 struct tmpnode *tp; 1951 size_t pp_off, pp_len; 1952 u_offset_t io_off; 1953 size_t io_len; 1954 struct vnode *pvp; 1955 u_offset_t pstart; 1956 u_offset_t offset; 1957 u_offset_t tmpoff; 1958 1959 ASSERT(PAGE_LOCKED(pp)); 1960 1961 /* Kluster in tmp_klustsize chunks */ 1962 tp = VTOTN(vp); 1963 tmp_klustsize = klustsize; 1964 offset = pp->p_offset; 1965 klstart = (offset / tmp_klustsize) * tmp_klustsize; 1966 kllen = MIN(tmp_klustsize, tp->tn_size - klstart); 1967 1968 /* Get a kluster of pages */ 1969 pplist = 1970 pvn_write_kluster(vp, pp, &tmpoff, &pp_len, klstart, kllen, flags); 1971 1972 pp_off = (size_t)tmpoff; 1973 1974 /* 1975 * Get a cluster of physical offsets for the pages; the amount we 1976 * get may be some subrange of what we ask for (io_off, io_len). 1977 */ 1978 io_off = pp_off; 1979 io_len = pp_len; 1980 err = swap_newphysname(vp, offset, &io_off, &io_len, &pvp, &pstart); 1981 ASSERT(err != SE_NOANON); /* anon slot must have been filled */ 1982 if (err) { 1983 pvn_write_done(pplist, B_ERROR | B_WRITE | flags); 1984 /* 1985 * If this routine is called as a result of segvn_sync 1986 * operation and we have no physical swap then we can get an 1987 * error here. In such case we would return SE_NOSWAP as error. 1988 * At this point, we expect only SE_NOSWAP. 1989 */ 1990 ASSERT(err == SE_NOSWAP); 1991 if (flags & B_INVAL) 1992 err = ENOMEM; 1993 goto out; 1994 } 1995 ASSERT(pp_off <= io_off && io_off + io_len <= pp_off + pp_len); 1996 ASSERT(io_off <= offset && offset < io_off + io_len); 1997 1998 /* Toss pages at front/rear that we couldn't get physical backing for */ 1999 if (io_off != pp_off) { 2000 npplist = NULL; 2001 page_list_break(&pplist, &npplist, btop(io_off - pp_off)); 2002 ASSERT(pplist->p_offset == pp_off); 2003 ASSERT(pplist->p_prev->p_offset == io_off - PAGESIZE); 2004 pvn_write_done(pplist, B_ERROR | B_WRITE | flags); 2005 pplist = npplist; 2006 } 2007 if (io_off + io_len < pp_off + pp_len) { 2008 npplist = NULL; 2009 page_list_break(&pplist, &npplist, btop(io_len)); 2010 ASSERT(npplist->p_offset == io_off + io_len); 2011 ASSERT(npplist->p_prev->p_offset == pp_off + pp_len - PAGESIZE); 2012 pvn_write_done(npplist, B_ERROR | B_WRITE | flags); 2013 } 2014 2015 ASSERT(pplist->p_offset == io_off); 2016 ASSERT(pplist->p_prev->p_offset == io_off + io_len - PAGESIZE); 2017 ASSERT(btopr(io_len) <= btopr(kllen)); 2018 2019 /* Do i/o on the remaining kluster */ 2020 err = VOP_PAGEIO(pvp, pplist, (u_offset_t)pstart, io_len, 2021 B_WRITE | flags, cr); 2022 2023 if ((flags & B_ASYNC) == 0) { 2024 pvn_write_done(pplist, ((err) ? B_ERROR : 0) | B_WRITE | flags); 2025 } 2026 out: 2027 if (!err) { 2028 if (offp) 2029 *offp = io_off; 2030 if (lenp) 2031 *lenp = io_len; 2032 tmp_putpagecnt++; 2033 tmp_pagespushed += btop(io_len); 2034 } 2035 if (err && err != ENOMEM && err != SE_NOSWAP) 2036 cmn_err(CE_WARN, "tmp_putapage: err %d\n", err); 2037 return (err); 2038 } 2039 2040 static int 2041 tmp_map( 2042 struct vnode *vp, 2043 offset_t off, 2044 struct as *as, 2045 caddr_t *addrp, 2046 size_t len, 2047 uchar_t prot, 2048 uchar_t maxprot, 2049 uint_t flags, 2050 struct cred *cred) 2051 { 2052 struct segvn_crargs vn_a; 2053 struct tmpnode *tp = (struct tmpnode *)VTOTN(vp); 2054 int error; 2055 2056 #ifdef _ILP32 2057 if (len > MAXOFF_T) 2058 return (ENOMEM); 2059 #endif 2060 2061 if (vp->v_flag & VNOMAP) 2062 return (ENOSYS); 2063 2064 if (off < 0 || (off + len) < 0 || 2065 off > MAXOFF_T || (off + len) > MAXOFF_T) 2066 return (ENXIO); 2067 2068 if (vp->v_type != VREG) 2069 return (ENODEV); 2070 2071 /* 2072 * Don't allow mapping to locked file 2073 */ 2074 if (vn_has_mandatory_locks(vp, tp->tn_mode)) { 2075 return (EAGAIN); 2076 } 2077 2078 as_rangelock(as); 2079 if ((flags & MAP_FIXED) == 0) { 2080 map_addr(addrp, len, (offset_t)off, 1, flags); 2081 if (*addrp == NULL) { 2082 as_rangeunlock(as); 2083 return (ENOMEM); 2084 } 2085 } else { 2086 /* 2087 * User specified address - blow away any previous mappings 2088 */ 2089 (void) as_unmap(as, *addrp, len); 2090 } 2091 2092 vn_a.vp = vp; 2093 vn_a.offset = (u_offset_t)off; 2094 vn_a.type = flags & MAP_TYPE; 2095 vn_a.prot = prot; 2096 vn_a.maxprot = maxprot; 2097 vn_a.flags = flags & ~MAP_TYPE; 2098 vn_a.cred = cred; 2099 vn_a.amp = NULL; 2100 vn_a.szc = 0; 2101 vn_a.lgrp_mem_policy_flags = 0; 2102 2103 error = as_map(as, *addrp, len, segvn_create, &vn_a); 2104 as_rangeunlock(as); 2105 return (error); 2106 } 2107 2108 /* 2109 * tmp_addmap and tmp_delmap can't be called since the vp 2110 * maintained in the segvn mapping is NULL. 2111 */ 2112 /* ARGSUSED */ 2113 static int 2114 tmp_addmap( 2115 struct vnode *vp, 2116 offset_t off, 2117 struct as *as, 2118 caddr_t addr, 2119 size_t len, 2120 uchar_t prot, 2121 uchar_t maxprot, 2122 uint_t flags, 2123 struct cred *cred) 2124 { 2125 return (0); 2126 } 2127 2128 /* ARGSUSED */ 2129 static int 2130 tmp_delmap( 2131 struct vnode *vp, 2132 offset_t off, 2133 struct as *as, 2134 caddr_t addr, 2135 size_t len, 2136 uint_t prot, 2137 uint_t maxprot, 2138 uint_t flags, 2139 struct cred *cred) 2140 { 2141 return (0); 2142 } 2143 2144 static int 2145 tmp_freesp(struct vnode *vp, struct flock64 *lp, int flag) 2146 { 2147 register int i; 2148 register struct tmpnode *tp = VTOTN(vp); 2149 int error; 2150 2151 ASSERT(vp->v_type == VREG); 2152 ASSERT(lp->l_start >= 0); 2153 2154 if (lp->l_len != 0) 2155 return (EINVAL); 2156 2157 rw_enter(&tp->tn_rwlock, RW_WRITER); 2158 if (tp->tn_size == lp->l_start) { 2159 rw_exit(&tp->tn_rwlock); 2160 return (0); 2161 } 2162 2163 /* 2164 * Check for any mandatory locks on the range 2165 */ 2166 if (MANDLOCK(vp, tp->tn_mode)) { 2167 long save_start; 2168 2169 save_start = lp->l_start; 2170 2171 if (tp->tn_size < lp->l_start) { 2172 /* 2173 * "Truncate up" case: need to make sure there 2174 * is no lock beyond current end-of-file. To 2175 * do so, we need to set l_start to the size 2176 * of the file temporarily. 2177 */ 2178 lp->l_start = tp->tn_size; 2179 } 2180 lp->l_type = F_WRLCK; 2181 lp->l_sysid = 0; 2182 lp->l_pid = ttoproc(curthread)->p_pid; 2183 i = (flag & (FNDELAY|FNONBLOCK)) ? 0 : SLPFLCK; 2184 if ((i = reclock(vp, lp, i, 0, lp->l_start, NULL)) != 0 || 2185 lp->l_type != F_UNLCK) { 2186 rw_exit(&tp->tn_rwlock); 2187 return (i ? i : EAGAIN); 2188 } 2189 2190 lp->l_start = save_start; 2191 } 2192 VFSTOTM(vp->v_vfsp); 2193 2194 rw_enter(&tp->tn_contents, RW_WRITER); 2195 error = tmpnode_trunc((struct tmount *)VFSTOTM(vp->v_vfsp), 2196 tp, (ulong_t)lp->l_start); 2197 rw_exit(&tp->tn_contents); 2198 rw_exit(&tp->tn_rwlock); 2199 return (error); 2200 } 2201 2202 /* ARGSUSED */ 2203 static int 2204 tmp_space( 2205 struct vnode *vp, 2206 int cmd, 2207 struct flock64 *bfp, 2208 int flag, 2209 offset_t offset, 2210 cred_t *cred, 2211 caller_context_t *ct) 2212 { 2213 int error; 2214 2215 if (cmd != F_FREESP) 2216 return (EINVAL); 2217 if ((error = convoff(vp, bfp, 0, (offset_t)offset)) == 0) { 2218 if ((bfp->l_start > MAXOFF_T) || (bfp->l_len > MAXOFF_T)) 2219 return (EFBIG); 2220 error = tmp_freesp(vp, bfp, flag); 2221 } 2222 return (error); 2223 } 2224 2225 /* ARGSUSED */ 2226 static int 2227 tmp_seek(struct vnode *vp, offset_t ooff, offset_t *noffp) 2228 { 2229 return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0); 2230 } 2231 2232 /* ARGSUSED2 */ 2233 static int 2234 tmp_rwlock(struct vnode *vp, int write_lock, caller_context_t *ctp) 2235 { 2236 struct tmpnode *tp = VTOTN(vp); 2237 2238 if (write_lock) { 2239 rw_enter(&tp->tn_rwlock, RW_WRITER); 2240 } else { 2241 rw_enter(&tp->tn_rwlock, RW_READER); 2242 } 2243 return (write_lock); 2244 } 2245 2246 /* ARGSUSED1 */ 2247 static void 2248 tmp_rwunlock(struct vnode *vp, int write_lock, caller_context_t *ctp) 2249 { 2250 struct tmpnode *tp = VTOTN(vp); 2251 2252 rw_exit(&tp->tn_rwlock); 2253 } 2254 2255 static int 2256 tmp_pathconf(struct vnode *vp, int cmd, ulong_t *valp, cred_t *cr) 2257 { 2258 struct tmpnode *tp = NULL; 2259 int error; 2260 2261 switch (cmd) { 2262 case _PC_XATTR_EXISTS: 2263 if (vp->v_vfsp->vfs_flag & VFS_XATTR) { 2264 *valp = 0; /* assume no attributes */ 2265 error = 0; /* okay to ask */ 2266 tp = VTOTN(vp); 2267 rw_enter(&tp->tn_rwlock, RW_READER); 2268 if (tp->tn_xattrdp) { 2269 rw_enter(&tp->tn_xattrdp->tn_rwlock, RW_READER); 2270 /* do not count "." and ".." */ 2271 if (tp->tn_xattrdp->tn_dirents > 2) 2272 *valp = 1; 2273 rw_exit(&tp->tn_xattrdp->tn_rwlock); 2274 } 2275 rw_exit(&tp->tn_rwlock); 2276 } else { 2277 error = EINVAL; 2278 } 2279 break; 2280 default: 2281 error = fs_pathconf(vp, cmd, valp, cr); 2282 } 2283 return (error); 2284 } 2285 2286 2287 struct vnodeops *tmp_vnodeops; 2288 2289 const fs_operation_def_t tmp_vnodeops_template[] = { 2290 VOPNAME_OPEN, tmp_open, 2291 VOPNAME_CLOSE, tmp_close, 2292 VOPNAME_READ, tmp_read, 2293 VOPNAME_WRITE, tmp_write, 2294 VOPNAME_IOCTL, tmp_ioctl, 2295 VOPNAME_GETATTR, tmp_getattr, 2296 VOPNAME_SETATTR, tmp_setattr, 2297 VOPNAME_ACCESS, tmp_access, 2298 VOPNAME_LOOKUP, tmp_lookup, 2299 VOPNAME_CREATE, tmp_create, 2300 VOPNAME_REMOVE, tmp_remove, 2301 VOPNAME_LINK, tmp_link, 2302 VOPNAME_RENAME, tmp_rename, 2303 VOPNAME_MKDIR, tmp_mkdir, 2304 VOPNAME_RMDIR, tmp_rmdir, 2305 VOPNAME_READDIR, tmp_readdir, 2306 VOPNAME_SYMLINK, tmp_symlink, 2307 VOPNAME_READLINK, tmp_readlink, 2308 VOPNAME_FSYNC, tmp_fsync, 2309 VOPNAME_INACTIVE, (fs_generic_func_p) tmp_inactive, 2310 VOPNAME_FID, tmp_fid, 2311 VOPNAME_RWLOCK, tmp_rwlock, 2312 VOPNAME_RWUNLOCK, (fs_generic_func_p) tmp_rwunlock, 2313 VOPNAME_SEEK, tmp_seek, 2314 VOPNAME_SPACE, tmp_space, 2315 VOPNAME_GETPAGE, tmp_getpage, 2316 VOPNAME_PUTPAGE, tmp_putpage, 2317 VOPNAME_MAP, (fs_generic_func_p) tmp_map, 2318 VOPNAME_ADDMAP, (fs_generic_func_p) tmp_addmap, 2319 VOPNAME_DELMAP, tmp_delmap, 2320 VOPNAME_PATHCONF, tmp_pathconf, 2321 VOPNAME_VNEVENT, fs_vnevent_support, 2322 NULL, NULL 2323 }; 2324