1 /* 2 * Copyright (c) 2000-2001 Boris Popov 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Boris Popov. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $Id: smbfs_vnops.c,v 1.128.36.1 2005/05/27 02:35:28 lindak Exp $ 33 */ 34 35 /* 36 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 37 * Copyright 2021 Tintri by DDN, Inc. All rights reserved. 38 */ 39 40 /* 41 * Vnode operations 42 * 43 * This file is similar to nfs3_vnops.c 44 */ 45 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/cred.h> 49 #include <sys/vnode.h> 50 #include <sys/vfs.h> 51 #include <sys/filio.h> 52 #include <sys/uio.h> 53 #include <sys/dirent.h> 54 #include <sys/errno.h> 55 #include <sys/sunddi.h> 56 #include <sys/sysmacros.h> 57 #include <sys/kmem.h> 58 #include <sys/cmn_err.h> 59 #include <sys/vfs_opreg.h> 60 #include <sys/policy.h> 61 #include <sys/sdt.h> 62 #include <sys/taskq_impl.h> 63 #include <sys/zone.h> 64 65 #ifdef _KERNEL 66 #include <sys/vmsystm.h> // for desfree 67 #include <vm/hat.h> 68 #include <vm/as.h> 69 #include <vm/page.h> 70 #include <vm/pvn.h> 71 #include <vm/seg.h> 72 #include <vm/seg_map.h> 73 #include <vm/seg_kpm.h> 74 #include <vm/seg_vn.h> 75 #endif // _KERNEL 76 77 #include <netsmb/smb_osdep.h> 78 #include <netsmb/smb.h> 79 #include <netsmb/smb_conn.h> 80 #include <netsmb/smb_subr.h> 81 82 #include <smbfs/smbfs.h> 83 #include <smbfs/smbfs_node.h> 84 #include <smbfs/smbfs_subr.h> 85 86 #include <sys/fs/smbfs_ioctl.h> 87 #include <fs/fs_subr.h> 88 89 #ifndef MAXOFF32_T 90 #define MAXOFF32_T 0x7fffffff 91 #endif 92 93 /* 94 * We assign directory offsets like the NFS client, where the 95 * offset increments by _one_ after each directory entry. 96 * Further, the entries "." and ".." are always at offsets 97 * zero and one (respectively) and the "real" entries from 98 * the server appear at offsets starting with two. This 99 * macro is used to initialize the n_dirofs field after 100 * setting n_dirseq with a _findopen call. 101 */ 102 #define FIRST_DIROFS 2 103 104 /* 105 * These characters are illegal in NTFS file names. 106 * ref: http://support.microsoft.com/kb/147438 107 * 108 * Careful! The check in the XATTR case skips the 109 * first character to allow colon in XATTR names. 110 */ 111 static const char illegal_chars[] = { 112 ':', /* colon - keep this first! */ 113 '\\', /* back slash */ 114 '/', /* slash */ 115 '*', /* asterisk */ 116 '?', /* question mark */ 117 '"', /* double quote */ 118 '<', /* less than sign */ 119 '>', /* greater than sign */ 120 '|', /* vertical bar */ 121 0 122 }; 123 124 /* 125 * Turning this on causes nodes to be created in the cache 126 * during directory listings, normally avoiding a second 127 * OtW attribute fetch just after a readdir. 128 */ 129 int smbfs_fastlookup = 1; 130 131 struct vnodeops *smbfs_vnodeops = NULL; 132 133 /* local static function defines */ 134 135 static int smbfslookup_cache(vnode_t *, char *, int, vnode_t **, 136 cred_t *); 137 static int smbfslookup(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr, 138 int cache_ok, caller_context_t *); 139 static int smbfsremove(vnode_t *dvp, vnode_t *vp, struct smb_cred *scred, 140 int flags); 141 static int smbfsrename(vnode_t *odvp, vnode_t *ovp, vnode_t *ndvp, 142 char *nnm, struct smb_cred *scred, int flags); 143 static int smbfssetattr(vnode_t *, struct vattr *, int, cred_t *); 144 static int smbfs_accessx(void *, int, cred_t *); 145 static int smbfs_readvdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp, 146 caller_context_t *); 147 static int smbfsflush(smbnode_t *, struct smb_cred *); 148 static void smbfs_rele_fid(smbnode_t *, struct smb_cred *); 149 static uint32_t xvattr_to_dosattr(smbnode_t *, struct vattr *); 150 151 static int smbfs_fsync(vnode_t *, int, cred_t *, caller_context_t *); 152 153 static int smbfs_putpage(vnode_t *, offset_t, size_t, int, cred_t *, 154 caller_context_t *); 155 #ifdef _KERNEL 156 static int smbfs_getapage(vnode_t *, u_offset_t, size_t, uint_t *, 157 page_t *[], size_t, struct seg *, caddr_t, 158 enum seg_rw, cred_t *); 159 static int smbfs_putapage(vnode_t *, page_t *, u_offset_t *, size_t *, 160 int, cred_t *); 161 static void smbfs_delmap_async(void *); 162 163 static int smbfs_rdwrlbn(vnode_t *, page_t *, u_offset_t, size_t, int, 164 cred_t *); 165 static int smbfs_bio(struct buf *, int, cred_t *); 166 static int smbfs_writenp(smbnode_t *np, caddr_t base, int tcount, 167 struct uio *uiop, int pgcreated); 168 #endif // _KERNEL 169 170 /* 171 * Error flags used to pass information about certain special errors 172 * which need to be handled specially. 173 */ 174 #define SMBFS_EOF -98 175 176 /* When implementing OtW locks, make this a real function. */ 177 #define smbfs_lm_has_sleep(vp) 0 178 179 /* 180 * These are the vnode ops routines which implement the vnode interface to 181 * the networked file system. These routines just take their parameters, 182 * make them look networkish by putting the right info into interface structs, 183 * and then calling the appropriate remote routine(s) to do the work. 184 * 185 * Note on directory name lookup cacheing: If we detect a stale fhandle, 186 * we purge the directory cache relative to that vnode. This way, the 187 * user won't get burned by the cache repeatedly. See <smbfs/smbnode.h> for 188 * more details on smbnode locking. 189 */ 190 191 192 /* 193 * XXX 194 * When new and relevant functionality is enabled, we should be 195 * calling vfs_set_feature() to inform callers that pieces of 196 * functionality are available, per PSARC 2007/227. 197 */ 198 /* ARGSUSED */ 199 static int 200 smbfs_open(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct) 201 { 202 smbnode_t *np; 203 vnode_t *vp; 204 smbfattr_t fa; 205 smb_fh_t *fid = NULL; 206 smb_fh_t *oldfid; 207 uint32_t rights; 208 struct smb_cred scred; 209 smbmntinfo_t *smi; 210 smb_share_t *ssp; 211 cred_t *oldcr; 212 int error = 0; 213 214 vp = *vpp; 215 np = VTOSMB(vp); 216 smi = VTOSMI(vp); 217 ssp = smi->smi_share; 218 219 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 220 return (EIO); 221 222 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 223 return (EIO); 224 225 if (vp->v_type != VREG && vp->v_type != VDIR) { /* XXX VLNK? */ 226 SMBVDEBUG("open eacces vtype=%d\n", vp->v_type); 227 return (EACCES); 228 } 229 230 /* 231 * Get exclusive access to n_fid and related stuff. 232 * No returns after this until out. 233 */ 234 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, SMBINTR(vp))) 235 return (EINTR); 236 smb_credinit(&scred, cr); 237 238 /* 239 * Keep track of the vnode type at first open. 240 * It may change later, and we need close to do 241 * cleanup for the type we opened. Also deny 242 * open of new types until old type is closed. 243 */ 244 if (np->n_ovtype == VNON) { 245 ASSERT(np->n_dirrefs == 0); 246 ASSERT(np->n_fidrefs == 0); 247 } else if (np->n_ovtype != vp->v_type) { 248 SMBVDEBUG("open n_ovtype=%d v_type=%d\n", 249 np->n_ovtype, vp->v_type); 250 error = EACCES; 251 goto out; 252 } 253 254 /* 255 * Directory open. See smbfs_readvdir() 256 */ 257 if (vp->v_type == VDIR) { 258 if (np->n_dirseq == NULL) { 259 /* first open */ 260 error = smbfs_smb_findopen(np, "*", 1, 261 SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR, 262 &scred, &np->n_dirseq); 263 if (error != 0) 264 goto out; 265 } 266 np->n_dirofs = FIRST_DIROFS; 267 np->n_dirrefs++; 268 goto have_fid; 269 } 270 271 /* 272 * If caller specified O_TRUNC/FTRUNC, then be sure to set 273 * FWRITE (to drive successful setattr(size=0) after open) 274 */ 275 if (flag & FTRUNC) 276 flag |= FWRITE; 277 278 /* 279 * If we already have it open, and the FID is still valid, 280 * check whether the rights are sufficient for FID reuse. 281 */ 282 if (np->n_fidrefs > 0 && 283 (fid = np->n_fid) != NULL && 284 fid->fh_vcgenid == ssp->ss_vcgenid) { 285 int upgrade = 0; 286 287 if ((flag & FWRITE) && 288 !(fid->fh_rights & SA_RIGHT_FILE_WRITE_DATA)) 289 upgrade = 1; 290 if ((flag & FREAD) && 291 !(fid->fh_rights & SA_RIGHT_FILE_READ_DATA)) 292 upgrade = 1; 293 if (!upgrade) { 294 /* 295 * the existing open is good enough 296 */ 297 np->n_fidrefs++; 298 goto have_fid; 299 } 300 fid = NULL; 301 } 302 rights = (fid != NULL) ? fid->fh_rights : 0; 303 304 /* 305 * we always ask for READ_CONTROL so we can always get the 306 * owner/group IDs to satisfy a stat. Ditto attributes. 307 */ 308 rights |= (STD_RIGHT_READ_CONTROL_ACCESS | 309 SA_RIGHT_FILE_READ_ATTRIBUTES); 310 if ((flag & FREAD)) 311 rights |= SA_RIGHT_FILE_READ_DATA; 312 if ((flag & FWRITE)) 313 rights |= SA_RIGHT_FILE_WRITE_DATA | 314 SA_RIGHT_FILE_APPEND_DATA | 315 SA_RIGHT_FILE_WRITE_ATTRIBUTES; 316 317 bzero(&fa, sizeof (fa)); 318 error = smbfs_smb_open(np, 319 NULL, 0, 0, /* name nmlen xattr */ 320 rights, &scred, 321 &fid, &fa); 322 if (error) 323 goto out; 324 smbfs_attrcache_fa(vp, &fa); 325 326 /* 327 * We have a new FID and access rights. 328 */ 329 VERIFY(fid != NULL); 330 oldfid = np->n_fid; 331 np->n_fid = fid; 332 np->n_fidrefs++; 333 if (oldfid != NULL) 334 smb_fh_rele(oldfid); 335 336 /* 337 * This thread did the open. 338 * Save our credentials too. 339 */ 340 mutex_enter(&np->r_statelock); 341 oldcr = np->r_cred; 342 np->r_cred = cr; 343 crhold(cr); 344 if (oldcr) 345 crfree(oldcr); 346 mutex_exit(&np->r_statelock); 347 348 have_fid: 349 /* 350 * Keep track of the vnode type at first open. 351 * (see comments above) 352 */ 353 if (np->n_ovtype == VNON) 354 np->n_ovtype = vp->v_type; 355 356 out: 357 smb_credrele(&scred); 358 smbfs_rw_exit(&np->r_lkserlock); 359 return (error); 360 } 361 362 /*ARGSUSED*/ 363 static int 364 smbfs_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr, 365 caller_context_t *ct) 366 { 367 smbnode_t *np; 368 smbmntinfo_t *smi; 369 struct smb_cred scred; 370 int error = 0; 371 372 np = VTOSMB(vp); 373 smi = VTOSMI(vp); 374 375 /* 376 * Don't "bail out" for VFS_UNMOUNTED here, 377 * as we want to do cleanup, etc. 378 */ 379 380 /* 381 * zone_enter(2) prevents processes from changing zones with SMBFS files 382 * open; if we happen to get here from the wrong zone we can't do 383 * anything over the wire. 384 */ 385 if (smi->smi_zone_ref.zref_zone != curproc->p_zone) { 386 /* 387 * We could attempt to clean up locks, except we're sure 388 * that the current process didn't acquire any locks on 389 * the file: any attempt to lock a file belong to another zone 390 * will fail, and one can't lock an SMBFS file and then change 391 * zones, as that fails too. 392 * 393 * Returning an error here is the sane thing to do. A 394 * subsequent call to VN_RELE() which translates to a 395 * smbfs_inactive() will clean up state: if the zone of the 396 * vnode's origin is still alive and kicking, an async worker 397 * thread will handle the request (from the correct zone), and 398 * everything (minus the final smbfs_getattr_otw() call) should 399 * be OK. If the zone is going away smbfs_async_inactive() will 400 * throw away cached pages inline. 401 */ 402 return (EIO); 403 } 404 405 /* 406 * If we are using local locking for this filesystem, then 407 * release all of the SYSV style record locks. Otherwise, 408 * we are doing network locking and we need to release all 409 * of the network locks. All of the locks held by this 410 * process on this file are released no matter what the 411 * incoming reference count is. 412 */ 413 if (smi->smi_flags & SMI_LLOCK) { 414 pid_t pid = ddi_get_pid(); 415 cleanlocks(vp, pid, 0); 416 cleanshares(vp, pid); 417 } 418 /* 419 * else doing OtW locking. SMB servers drop all locks 420 * on the file ID we close here, so no _lockrelease() 421 */ 422 423 /* 424 * This (passed in) count is the ref. count from the 425 * user's file_t before the closef call (fio.c). 426 * The rest happens only on last close. 427 */ 428 if (count > 1) 429 return (0); 430 431 /* NFS has DNLC purge here. */ 432 433 /* 434 * If the file was open for write and there are pages, 435 * then make sure dirty pages written back. 436 * 437 * NFS does this async when "close-to-open" is off 438 * (MI_NOCTO flag is set) to avoid blocking the caller. 439 * For now, always do this synchronously (no B_ASYNC). 440 */ 441 if ((flag & FWRITE) && vn_has_cached_data(vp)) { 442 error = smbfs_putpage(vp, (offset_t)0, 0, 0, cr, ct); 443 if (error == EAGAIN) 444 error = 0; 445 } 446 if (error == 0) { 447 mutex_enter(&np->r_statelock); 448 np->r_flags &= ~RSTALE; 449 np->r_error = 0; 450 mutex_exit(&np->r_statelock); 451 } 452 453 /* 454 * Decrement the reference count for the FID 455 * and possibly do the OtW close. 456 * 457 * Exclusive lock for modifying n_fid stuff. 458 * Don't want this one ever interruptible. 459 */ 460 (void) smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, 0); 461 smb_credinit(&scred, cr); 462 463 smbfs_rele_fid(np, &scred); 464 465 smb_credrele(&scred); 466 smbfs_rw_exit(&np->r_lkserlock); 467 468 return (0); 469 } 470 471 /* 472 * Helper for smbfs_close. Decrement the reference count 473 * for an SMB-level file or directory ID, and when the last 474 * reference for the fid goes away, do the OtW close. 475 * Also called in smbfs_inactive (defensive cleanup). 476 */ 477 static void 478 smbfs_rele_fid(smbnode_t *np, struct smb_cred *scred) 479 { 480 cred_t *oldcr; 481 struct smbfs_fctx *fctx; 482 int error; 483 smb_fh_t *ofid; 484 485 error = 0; 486 487 /* Make sure we serialize for n_dirseq use. */ 488 ASSERT(smbfs_rw_lock_held(&np->r_lkserlock, RW_WRITER)); 489 490 /* 491 * Note that vp->v_type may change if a remote node 492 * is deleted and recreated as a different type, and 493 * our getattr may change v_type accordingly. 494 * Now use n_ovtype to keep track of the v_type 495 * we had during open (see comments above). 496 */ 497 switch (np->n_ovtype) { 498 case VDIR: 499 ASSERT(np->n_dirrefs > 0); 500 if (--np->n_dirrefs) 501 return; 502 if ((fctx = np->n_dirseq) != NULL) { 503 np->n_dirseq = NULL; 504 np->n_dirofs = 0; 505 error = smbfs_smb_findclose(fctx, scred); 506 } 507 break; 508 509 case VREG: 510 ASSERT(np->n_fidrefs > 0); 511 if (--np->n_fidrefs) 512 return; 513 if ((ofid = np->n_fid) != NULL) { 514 np->n_fid = NULL; 515 smb_fh_rele(ofid); 516 } 517 break; 518 519 default: 520 SMBVDEBUG("bad n_ovtype %d\n", np->n_ovtype); 521 break; 522 } 523 if (error) { 524 SMBVDEBUG("error %d closing %s\n", 525 error, np->n_rpath); 526 } 527 528 /* Allow next open to use any v_type. */ 529 np->n_ovtype = VNON; 530 531 /* 532 * Other "last close" stuff. 533 */ 534 mutex_enter(&np->r_statelock); 535 if (np->n_flag & NATTRCHANGED) 536 smbfs_attrcache_rm_locked(np); 537 oldcr = np->r_cred; 538 np->r_cred = NULL; 539 mutex_exit(&np->r_statelock); 540 if (oldcr != NULL) 541 crfree(oldcr); 542 } 543 544 /* ARGSUSED */ 545 static int 546 smbfs_read(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr, 547 caller_context_t *ct) 548 { 549 struct smb_cred scred; 550 struct vattr va; 551 smbnode_t *np; 552 smbmntinfo_t *smi; 553 offset_t endoff; 554 ssize_t past_eof; 555 int error; 556 557 np = VTOSMB(vp); 558 smi = VTOSMI(vp); 559 560 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 561 return (EIO); 562 563 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 564 return (EIO); 565 566 /* Sanity check: should have a valid open */ 567 if (np->n_fid == NULL) 568 return (EIO); 569 570 ASSERT(smbfs_rw_lock_held(&np->r_rwlock, RW_READER)); 571 572 if (vp->v_type != VREG) 573 return (EISDIR); 574 575 if (uiop->uio_resid == 0) 576 return (0); 577 578 /* 579 * Like NFS3, just check for 63-bit overflow. 580 * Our SMB layer takes care to return EFBIG 581 * when it has to fallback to a 32-bit call. 582 */ 583 endoff = uiop->uio_loffset + uiop->uio_resid; 584 if (uiop->uio_loffset < 0 || endoff < 0) 585 return (EINVAL); 586 587 /* get vnode attributes from server */ 588 va.va_mask = AT_SIZE | AT_MTIME; 589 if (error = smbfsgetattr(vp, &va, cr)) 590 return (error); 591 592 /* Update mtime with mtime from server here? */ 593 594 /* if offset is beyond EOF, read nothing */ 595 if (uiop->uio_loffset >= va.va_size) 596 return (0); 597 598 /* 599 * Limit the read to the remaining file size. 600 * Do this by temporarily reducing uio_resid 601 * by the amount the lies beyoned the EOF. 602 */ 603 if (endoff > va.va_size) { 604 past_eof = (ssize_t)(endoff - va.va_size); 605 uiop->uio_resid -= past_eof; 606 } else 607 past_eof = 0; 608 609 /* 610 * Bypass VM if caching has been disabled (e.g., locking) or if 611 * using client-side direct I/O and the file is not mmap'd and 612 * there are no cached pages. 613 */ 614 if ((vp->v_flag & VNOCACHE) || 615 (((np->r_flags & RDIRECTIO) || (smi->smi_flags & SMI_DIRECTIO)) && 616 np->r_mapcnt == 0 && np->r_inmap == 0 && 617 !vn_has_cached_data(vp))) { 618 619 /* Shared lock for n_fid use in smb_rwuio */ 620 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp))) 621 return (EINTR); 622 smb_credinit(&scred, cr); 623 624 error = smb_rwuio(np->n_fid, UIO_READ, 625 uiop, &scred, smb_timo_read); 626 627 smb_credrele(&scred); 628 smbfs_rw_exit(&np->r_lkserlock); 629 630 /* undo adjustment of resid */ 631 uiop->uio_resid += past_eof; 632 633 return (error); 634 } 635 636 #ifdef _KERNEL 637 /* (else) Do I/O through segmap. */ 638 do { 639 caddr_t base; 640 u_offset_t off; 641 size_t n; 642 int on; 643 uint_t flags; 644 645 off = uiop->uio_loffset & MAXBMASK; /* mapping offset */ 646 on = uiop->uio_loffset & MAXBOFFSET; /* Relative offset */ 647 n = MIN(MAXBSIZE - on, uiop->uio_resid); 648 649 error = smbfs_validate_caches(vp, cr); 650 if (error) 651 break; 652 653 /* NFS waits for RINCACHEPURGE here. */ 654 655 if (vpm_enable) { 656 /* 657 * Copy data. 658 */ 659 error = vpm_data_copy(vp, off + on, n, uiop, 660 1, NULL, 0, S_READ); 661 } else { 662 base = segmap_getmapflt(segkmap, vp, off + on, n, 1, 663 S_READ); 664 665 error = uiomove(base + on, n, UIO_READ, uiop); 666 } 667 668 if (!error) { 669 /* 670 * If read a whole block or read to eof, 671 * won't need this buffer again soon. 672 */ 673 mutex_enter(&np->r_statelock); 674 if (n + on == MAXBSIZE || 675 uiop->uio_loffset == np->r_size) 676 flags = SM_DONTNEED; 677 else 678 flags = 0; 679 mutex_exit(&np->r_statelock); 680 if (vpm_enable) { 681 error = vpm_sync_pages(vp, off, n, flags); 682 } else { 683 error = segmap_release(segkmap, base, flags); 684 } 685 } else { 686 if (vpm_enable) { 687 (void) vpm_sync_pages(vp, off, n, 0); 688 } else { 689 (void) segmap_release(segkmap, base, 0); 690 } 691 } 692 } while (!error && uiop->uio_resid > 0); 693 #else // _KERNEL 694 error = ENOSYS; 695 #endif // _KERNEL 696 697 /* undo adjustment of resid */ 698 uiop->uio_resid += past_eof; 699 700 return (error); 701 } 702 703 704 /* ARGSUSED */ 705 static int 706 smbfs_write(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr, 707 caller_context_t *ct) 708 { 709 struct smb_cred scred; 710 struct vattr va; 711 smbnode_t *np; 712 smbmntinfo_t *smi; 713 offset_t endoff, limit; 714 ssize_t past_limit; 715 int error, timo; 716 u_offset_t last_off; 717 size_t last_resid; 718 #ifdef _KERNEL 719 uint_t bsize; 720 #endif 721 722 np = VTOSMB(vp); 723 smi = VTOSMI(vp); 724 725 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 726 return (EIO); 727 728 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 729 return (EIO); 730 731 /* Sanity check: should have a valid open */ 732 if (np->n_fid == NULL) 733 return (EIO); 734 735 ASSERT(smbfs_rw_lock_held(&np->r_rwlock, RW_WRITER)); 736 737 if (vp->v_type != VREG) 738 return (EISDIR); 739 740 if (uiop->uio_resid == 0) 741 return (0); 742 743 /* 744 * Handle ioflag bits: (FAPPEND|FSYNC|FDSYNC) 745 */ 746 if (ioflag & (FAPPEND | FSYNC)) { 747 if (np->n_flag & NMODIFIED) { 748 smbfs_attrcache_remove(np); 749 } 750 } 751 if (ioflag & FAPPEND) { 752 /* 753 * File size can be changed by another client 754 * 755 * Todo: Consider redesigning this to use a 756 * handle opened for append instead. 757 */ 758 va.va_mask = AT_SIZE; 759 if (error = smbfsgetattr(vp, &va, cr)) 760 return (error); 761 uiop->uio_loffset = va.va_size; 762 } 763 764 /* 765 * Like NFS3, just check for 63-bit overflow. 766 */ 767 endoff = uiop->uio_loffset + uiop->uio_resid; 768 if (uiop->uio_loffset < 0 || endoff < 0) 769 return (EINVAL); 770 771 /* 772 * Check to make sure that the process will not exceed 773 * its limit on file size. It is okay to write up to 774 * the limit, but not beyond. Thus, the write which 775 * reaches the limit will be short and the next write 776 * will return an error. 777 * 778 * So if we're starting at or beyond the limit, EFBIG. 779 * Otherwise, temporarily reduce resid to the amount 780 * that is after the limit. 781 */ 782 limit = uiop->uio_llimit; 783 if (limit == RLIM64_INFINITY || limit > MAXOFFSET_T) 784 limit = MAXOFFSET_T; 785 if (uiop->uio_loffset >= limit) { 786 #ifdef _KERNEL 787 proc_t *p = ttoproc(curthread); 788 789 mutex_enter(&p->p_lock); 790 (void) rctl_action(rctlproc_legacy[RLIMIT_FSIZE], 791 p->p_rctls, p, RCA_UNSAFE_SIGINFO); 792 mutex_exit(&p->p_lock); 793 #endif // _KERNEL 794 return (EFBIG); 795 } 796 if (endoff > limit) { 797 past_limit = (ssize_t)(endoff - limit); 798 uiop->uio_resid -= past_limit; 799 } else 800 past_limit = 0; 801 802 /* 803 * Bypass VM if caching has been disabled (e.g., locking) or if 804 * using client-side direct I/O and the file is not mmap'd and 805 * there are no cached pages. 806 */ 807 if ((vp->v_flag & VNOCACHE) || 808 (((np->r_flags & RDIRECTIO) || (smi->smi_flags & SMI_DIRECTIO)) && 809 np->r_mapcnt == 0 && np->r_inmap == 0 && 810 !vn_has_cached_data(vp))) { 811 812 #ifdef _KERNEL 813 smbfs_fwrite: 814 #endif // _KERNEL 815 if (np->r_flags & RSTALE) { 816 last_resid = uiop->uio_resid; 817 last_off = uiop->uio_loffset; 818 error = np->r_error; 819 /* 820 * A close may have cleared r_error, if so, 821 * propagate ESTALE error return properly 822 */ 823 if (error == 0) 824 error = ESTALE; 825 goto bottom; 826 } 827 828 /* Timeout: longer for append. */ 829 timo = smb_timo_write; 830 if (endoff > np->r_size) 831 timo = smb_timo_append; 832 833 /* Shared lock for n_fid use in smb_rwuio */ 834 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp))) 835 return (EINTR); 836 smb_credinit(&scred, cr); 837 838 error = smb_rwuio(np->n_fid, UIO_WRITE, 839 uiop, &scred, timo); 840 841 if (error == 0) { 842 mutex_enter(&np->r_statelock); 843 np->n_flag |= (NFLUSHWIRE | NATTRCHANGED); 844 if (uiop->uio_loffset > (offset_t)np->r_size) 845 np->r_size = (len_t)uiop->uio_loffset; 846 mutex_exit(&np->r_statelock); 847 if (ioflag & (FSYNC | FDSYNC)) { 848 /* Don't error the I/O if this fails. */ 849 (void) smbfsflush(np, &scred); 850 } 851 } 852 853 smb_credrele(&scred); 854 smbfs_rw_exit(&np->r_lkserlock); 855 856 /* undo adjustment of resid */ 857 uiop->uio_resid += past_limit; 858 859 return (error); 860 } 861 862 #ifdef _KERNEL 863 /* (else) Do I/O through segmap. */ 864 bsize = vp->v_vfsp->vfs_bsize; 865 866 do { 867 caddr_t base; 868 u_offset_t off; 869 size_t n; 870 int on; 871 uint_t flags; 872 873 off = uiop->uio_loffset & MAXBMASK; /* mapping offset */ 874 on = uiop->uio_loffset & MAXBOFFSET; /* Relative offset */ 875 n = MIN(MAXBSIZE - on, uiop->uio_resid); 876 877 last_resid = uiop->uio_resid; 878 last_off = uiop->uio_loffset; 879 880 if (np->r_flags & RSTALE) { 881 error = np->r_error; 882 /* 883 * A close may have cleared r_error, if so, 884 * propagate ESTALE error return properly 885 */ 886 if (error == 0) 887 error = ESTALE; 888 break; 889 } 890 891 /* 892 * From NFS: Don't create dirty pages faster than they 893 * can be cleaned. 894 * 895 * Here NFS also checks for async writes (np->r_awcount) 896 */ 897 mutex_enter(&np->r_statelock); 898 while (np->r_gcount > 0) { 899 if (SMBINTR(vp)) { 900 klwp_t *lwp = ttolwp(curthread); 901 902 if (lwp != NULL) 903 lwp->lwp_nostop++; 904 if (!cv_wait_sig(&np->r_cv, &np->r_statelock)) { 905 mutex_exit(&np->r_statelock); 906 if (lwp != NULL) 907 lwp->lwp_nostop--; 908 error = EINTR; 909 goto bottom; 910 } 911 if (lwp != NULL) 912 lwp->lwp_nostop--; 913 } else 914 cv_wait(&np->r_cv, &np->r_statelock); 915 } 916 mutex_exit(&np->r_statelock); 917 918 /* 919 * Touch the page and fault it in if it is not in core 920 * before segmap_getmapflt or vpm_data_copy can lock it. 921 * This is to avoid the deadlock if the buffer is mapped 922 * to the same file through mmap which we want to write. 923 */ 924 uio_prefaultpages((long)n, uiop); 925 926 if (vpm_enable) { 927 /* 928 * It will use kpm mappings, so no need to 929 * pass an address. 930 */ 931 error = smbfs_writenp(np, NULL, n, uiop, 0); 932 } else { 933 if (segmap_kpm) { 934 int pon = uiop->uio_loffset & PAGEOFFSET; 935 size_t pn = MIN(PAGESIZE - pon, 936 uiop->uio_resid); 937 int pagecreate; 938 939 mutex_enter(&np->r_statelock); 940 pagecreate = (pon == 0) && (pn == PAGESIZE || 941 uiop->uio_loffset + pn >= np->r_size); 942 mutex_exit(&np->r_statelock); 943 944 base = segmap_getmapflt(segkmap, vp, off + on, 945 pn, !pagecreate, S_WRITE); 946 947 error = smbfs_writenp(np, base + pon, n, uiop, 948 pagecreate); 949 950 } else { 951 base = segmap_getmapflt(segkmap, vp, off + on, 952 n, 0, S_READ); 953 error = smbfs_writenp(np, base + on, n, uiop, 0); 954 } 955 } 956 957 if (!error) { 958 if (smi->smi_flags & SMI_NOAC) 959 flags = SM_WRITE; 960 else if ((uiop->uio_loffset % bsize) == 0 || 961 IS_SWAPVP(vp)) { 962 /* 963 * Have written a whole block. 964 * Start an asynchronous write 965 * and mark the buffer to 966 * indicate that it won't be 967 * needed again soon. 968 */ 969 flags = SM_WRITE | SM_ASYNC | SM_DONTNEED; 970 } else 971 flags = 0; 972 if ((ioflag & (FSYNC|FDSYNC)) || 973 (np->r_flags & ROUTOFSPACE)) { 974 flags &= ~SM_ASYNC; 975 flags |= SM_WRITE; 976 } 977 if (vpm_enable) { 978 error = vpm_sync_pages(vp, off, n, flags); 979 } else { 980 error = segmap_release(segkmap, base, flags); 981 } 982 } else { 983 if (vpm_enable) { 984 (void) vpm_sync_pages(vp, off, n, 0); 985 } else { 986 (void) segmap_release(segkmap, base, 0); 987 } 988 /* 989 * In the event that we got an access error while 990 * faulting in a page for a write-only file just 991 * force a write. 992 */ 993 if (error == EACCES) 994 goto smbfs_fwrite; 995 } 996 } while (!error && uiop->uio_resid > 0); 997 #else // _KERNEL 998 last_resid = uiop->uio_resid; 999 last_off = uiop->uio_loffset; 1000 error = ENOSYS; 1001 #endif // _KERNEL 1002 1003 bottom: 1004 /* undo adjustment of resid */ 1005 if (error) { 1006 uiop->uio_resid = last_resid + past_limit; 1007 uiop->uio_loffset = last_off; 1008 } else { 1009 uiop->uio_resid += past_limit; 1010 } 1011 1012 return (error); 1013 } 1014 1015 #ifdef _KERNEL 1016 1017 /* 1018 * Like nfs_client.c: writerp() 1019 * 1020 * Write by creating pages and uiomove data onto them. 1021 */ 1022 1023 int 1024 smbfs_writenp(smbnode_t *np, caddr_t base, int tcount, struct uio *uio, 1025 int pgcreated) 1026 { 1027 int pagecreate; 1028 int n; 1029 int saved_n; 1030 caddr_t saved_base; 1031 u_offset_t offset; 1032 int error; 1033 int sm_error; 1034 vnode_t *vp = SMBTOV(np); 1035 1036 ASSERT(tcount <= MAXBSIZE && tcount <= uio->uio_resid); 1037 ASSERT(smbfs_rw_lock_held(&np->r_rwlock, RW_WRITER)); 1038 if (!vpm_enable) { 1039 ASSERT(((uintptr_t)base & MAXBOFFSET) + tcount <= MAXBSIZE); 1040 } 1041 1042 /* 1043 * Move bytes in at most PAGESIZE chunks. We must avoid 1044 * spanning pages in uiomove() because page faults may cause 1045 * the cache to be invalidated out from under us. The r_size is not 1046 * updated until after the uiomove. If we push the last page of a 1047 * file before r_size is correct, we will lose the data written past 1048 * the current (and invalid) r_size. 1049 */ 1050 do { 1051 offset = uio->uio_loffset; 1052 pagecreate = 0; 1053 1054 /* 1055 * n is the number of bytes required to satisfy the request 1056 * or the number of bytes to fill out the page. 1057 */ 1058 n = (int)MIN((PAGESIZE - (offset & PAGEOFFSET)), tcount); 1059 1060 /* 1061 * Check to see if we can skip reading in the page 1062 * and just allocate the memory. We can do this 1063 * if we are going to rewrite the entire mapping 1064 * or if we are going to write to or beyond the current 1065 * end of file from the beginning of the mapping. 1066 * 1067 * The read of r_size is now protected by r_statelock. 1068 */ 1069 mutex_enter(&np->r_statelock); 1070 /* 1071 * When pgcreated is nonzero the caller has already done 1072 * a segmap_getmapflt with forcefault 0 and S_WRITE. With 1073 * segkpm this means we already have at least one page 1074 * created and mapped at base. 1075 */ 1076 pagecreate = pgcreated || 1077 ((offset & PAGEOFFSET) == 0 && 1078 (n == PAGESIZE || ((offset + n) >= np->r_size))); 1079 1080 mutex_exit(&np->r_statelock); 1081 if (!vpm_enable && pagecreate) { 1082 /* 1083 * The last argument tells segmap_pagecreate() to 1084 * always lock the page, as opposed to sometimes 1085 * returning with the page locked. This way we avoid a 1086 * fault on the ensuing uiomove(), but also 1087 * more importantly (to fix bug 1094402) we can 1088 * call segmap_fault() to unlock the page in all 1089 * cases. An alternative would be to modify 1090 * segmap_pagecreate() to tell us when it is 1091 * locking a page, but that's a fairly major 1092 * interface change. 1093 */ 1094 if (pgcreated == 0) 1095 (void) segmap_pagecreate(segkmap, base, 1096 (uint_t)n, 1); 1097 saved_base = base; 1098 saved_n = n; 1099 } 1100 1101 /* 1102 * The number of bytes of data in the last page can not 1103 * be accurately be determined while page is being 1104 * uiomove'd to and the size of the file being updated. 1105 * Thus, inform threads which need to know accurately 1106 * how much data is in the last page of the file. They 1107 * will not do the i/o immediately, but will arrange for 1108 * the i/o to happen later when this modify operation 1109 * will have finished. 1110 */ 1111 ASSERT(!(np->r_flags & RMODINPROGRESS)); 1112 mutex_enter(&np->r_statelock); 1113 np->r_flags |= RMODINPROGRESS; 1114 np->r_modaddr = (offset & MAXBMASK); 1115 mutex_exit(&np->r_statelock); 1116 1117 if (vpm_enable) { 1118 /* 1119 * Copy data. If new pages are created, part of 1120 * the page that is not written will be initizliazed 1121 * with zeros. 1122 */ 1123 error = vpm_data_copy(vp, offset, n, uio, 1124 !pagecreate, NULL, 0, S_WRITE); 1125 } else { 1126 error = uiomove(base, n, UIO_WRITE, uio); 1127 } 1128 1129 /* 1130 * r_size is the maximum number of 1131 * bytes known to be in the file. 1132 * Make sure it is at least as high as the 1133 * first unwritten byte pointed to by uio_loffset. 1134 */ 1135 mutex_enter(&np->r_statelock); 1136 if (np->r_size < uio->uio_loffset) 1137 np->r_size = uio->uio_loffset; 1138 np->r_flags &= ~RMODINPROGRESS; 1139 np->r_flags |= RDIRTY; 1140 mutex_exit(&np->r_statelock); 1141 1142 /* n = # of bytes written */ 1143 n = (int)(uio->uio_loffset - offset); 1144 1145 if (!vpm_enable) { 1146 base += n; 1147 } 1148 tcount -= n; 1149 /* 1150 * If we created pages w/o initializing them completely, 1151 * we need to zero the part that wasn't set up. 1152 * This happens on a most EOF write cases and if 1153 * we had some sort of error during the uiomove. 1154 */ 1155 if (!vpm_enable && pagecreate) { 1156 if ((uio->uio_loffset & PAGEOFFSET) || n == 0) 1157 (void) kzero(base, PAGESIZE - n); 1158 1159 if (pgcreated) { 1160 /* 1161 * Caller is responsible for this page, 1162 * it was not created in this loop. 1163 */ 1164 pgcreated = 0; 1165 } else { 1166 /* 1167 * For bug 1094402: segmap_pagecreate locks 1168 * page. Unlock it. This also unlocks the 1169 * pages allocated by page_create_va() in 1170 * segmap_pagecreate(). 1171 */ 1172 sm_error = segmap_fault(kas.a_hat, segkmap, 1173 saved_base, saved_n, 1174 F_SOFTUNLOCK, S_WRITE); 1175 if (error == 0) 1176 error = sm_error; 1177 } 1178 } 1179 } while (tcount > 0 && error == 0); 1180 1181 return (error); 1182 } 1183 1184 /* 1185 * Flags are composed of {B_ASYNC, B_INVAL, B_FREE, B_DONTNEED} 1186 * Like nfs3_rdwrlbn() 1187 */ 1188 static int 1189 smbfs_rdwrlbn(vnode_t *vp, page_t *pp, u_offset_t off, size_t len, 1190 int flags, cred_t *cr) 1191 { 1192 smbmntinfo_t *smi = VTOSMI(vp); 1193 struct buf *bp; 1194 int error; 1195 int sync; 1196 1197 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 1198 return (EIO); 1199 1200 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 1201 return (EIO); 1202 1203 bp = pageio_setup(pp, len, vp, flags); 1204 ASSERT(bp != NULL); 1205 1206 /* 1207 * pageio_setup should have set b_addr to 0. This 1208 * is correct since we want to do I/O on a page 1209 * boundary. bp_mapin will use this addr to calculate 1210 * an offset, and then set b_addr to the kernel virtual 1211 * address it allocated for us. 1212 */ 1213 ASSERT(bp->b_un.b_addr == 0); 1214 1215 bp->b_edev = 0; 1216 bp->b_dev = 0; 1217 bp->b_lblkno = lbtodb(off); 1218 bp->b_file = vp; 1219 bp->b_offset = (offset_t)off; 1220 bp_mapin(bp); 1221 1222 /* 1223 * Calculate the desired level of stability to write data. 1224 */ 1225 if ((flags & (B_WRITE|B_ASYNC)) == (B_WRITE|B_ASYNC) && 1226 freemem > desfree) { 1227 sync = 0; 1228 } else { 1229 sync = 1; 1230 } 1231 1232 error = smbfs_bio(bp, sync, cr); 1233 1234 bp_mapout(bp); 1235 pageio_done(bp); 1236 1237 return (error); 1238 } 1239 1240 1241 /* 1242 * Corresponds to nfs3_vnopc.c : nfs3_bio(), though the NFS code 1243 * uses nfs3read()/nfs3write() where we use smb_rwuio(). Also, 1244 * NFS has this later in the file. Move it up here closer to 1245 * the one call site just above. 1246 */ 1247 1248 static int 1249 smbfs_bio(struct buf *bp, int sync, cred_t *cr) 1250 { 1251 struct iovec aiov[1]; 1252 struct uio auio; 1253 struct smb_cred scred; 1254 smbnode_t *np = VTOSMB(bp->b_vp); 1255 smbmntinfo_t *smi = np->n_mount; 1256 offset_t offset; 1257 offset_t endoff; 1258 size_t count; 1259 size_t past_eof; 1260 int error; 1261 1262 ASSERT(curproc->p_zone == smi->smi_zone_ref.zref_zone); 1263 1264 offset = ldbtob(bp->b_lblkno); 1265 count = bp->b_bcount; 1266 endoff = offset + count; 1267 if (offset < 0 || endoff < 0) 1268 return (EINVAL); 1269 1270 /* 1271 * Limit file I/O to the remaining file size, but see 1272 * the notes in smbfs_getpage about SMBFS_EOF. 1273 */ 1274 mutex_enter(&np->r_statelock); 1275 if (offset >= np->r_size) { 1276 mutex_exit(&np->r_statelock); 1277 if (bp->b_flags & B_READ) { 1278 return (SMBFS_EOF); 1279 } else { 1280 return (EINVAL); 1281 } 1282 } 1283 if (endoff > np->r_size) { 1284 past_eof = (size_t)(endoff - np->r_size); 1285 count -= past_eof; 1286 } else 1287 past_eof = 0; 1288 mutex_exit(&np->r_statelock); 1289 ASSERT(count > 0); 1290 1291 /* Caller did bpmapin(). Mapped address is... */ 1292 aiov[0].iov_base = bp->b_un.b_addr; 1293 aiov[0].iov_len = count; 1294 auio.uio_iov = aiov; 1295 auio.uio_iovcnt = 1; 1296 auio.uio_loffset = offset; 1297 auio.uio_segflg = UIO_SYSSPACE; 1298 auio.uio_fmode = 0; 1299 auio.uio_resid = count; 1300 1301 /* Shared lock for n_fid use in smb_rwuio */ 1302 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, 1303 smi->smi_flags & SMI_INT)) 1304 return (EINTR); 1305 smb_credinit(&scred, cr); 1306 1307 DTRACE_IO1(start, struct buf *, bp); 1308 1309 if (bp->b_flags & B_READ) { 1310 1311 error = smb_rwuio(np->n_fid, UIO_READ, 1312 &auio, &scred, smb_timo_read); 1313 1314 /* Like NFS, only set b_error here. */ 1315 bp->b_error = error; 1316 bp->b_resid = auio.uio_resid; 1317 1318 if (!error && auio.uio_resid != 0) 1319 error = EIO; 1320 if (!error && past_eof != 0) { 1321 /* Zero the memory beyond EOF. */ 1322 bzero(bp->b_un.b_addr + count, past_eof); 1323 } 1324 } else { 1325 1326 error = smb_rwuio(np->n_fid, UIO_WRITE, 1327 &auio, &scred, smb_timo_write); 1328 1329 /* Like NFS, only set b_error here. */ 1330 bp->b_error = error; 1331 bp->b_resid = auio.uio_resid; 1332 1333 if (!error && auio.uio_resid != 0) 1334 error = EIO; 1335 if (!error && sync) { 1336 (void) smbfsflush(np, &scred); 1337 } 1338 } 1339 1340 /* 1341 * This comes from nfs3_commit() 1342 */ 1343 if (error != 0) { 1344 mutex_enter(&np->r_statelock); 1345 if (error == ESTALE) 1346 np->r_flags |= RSTALE; 1347 if (!np->r_error) 1348 np->r_error = error; 1349 mutex_exit(&np->r_statelock); 1350 bp->b_flags |= B_ERROR; 1351 } 1352 1353 DTRACE_IO1(done, struct buf *, bp); 1354 1355 smb_credrele(&scred); 1356 smbfs_rw_exit(&np->r_lkserlock); 1357 1358 if (error == ESTALE) 1359 smbfs_attrcache_remove(np); 1360 1361 return (error); 1362 } 1363 #endif // _KERNEL 1364 1365 /* 1366 * Here NFS has: nfs3write, nfs3read 1367 * We use smb_rwuio instead. 1368 */ 1369 1370 /* ARGSUSED */ 1371 static int 1372 smbfs_ioctl(vnode_t *vp, int cmd, intptr_t arg, int flag, 1373 cred_t *cr, int *rvalp, caller_context_t *ct) 1374 { 1375 int error; 1376 smbmntinfo_t *smi; 1377 1378 smi = VTOSMI(vp); 1379 1380 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 1381 return (EIO); 1382 1383 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 1384 return (EIO); 1385 1386 switch (cmd) { 1387 1388 case _FIOFFS: 1389 error = smbfs_fsync(vp, 0, cr, ct); 1390 break; 1391 1392 /* 1393 * The following two ioctls are used by bfu. 1394 * Silently ignore to avoid bfu errors. 1395 */ 1396 case _FIOGDIO: 1397 case _FIOSDIO: 1398 error = 0; 1399 break; 1400 1401 #if 0 /* Todo - SMB ioctl query regions */ 1402 case _FIO_SEEK_DATA: 1403 case _FIO_SEEK_HOLE: 1404 #endif 1405 1406 case _FIODIRECTIO: 1407 error = smbfs_directio(vp, (int)arg, cr); 1408 break; 1409 1410 /* 1411 * Allow get/set with "raw" security descriptor (SD) data. 1412 * Useful for testing, diagnosing idmap problems, etc. 1413 */ 1414 case SMBFSIO_GETSD: 1415 error = smbfs_acl_iocget(vp, arg, flag, cr); 1416 break; 1417 1418 case SMBFSIO_SETSD: 1419 error = smbfs_acl_iocset(vp, arg, flag, cr); 1420 break; 1421 1422 default: 1423 error = ENOTTY; 1424 break; 1425 } 1426 1427 return (error); 1428 } 1429 1430 1431 /* 1432 * Return either cached or remote attributes. If get remote attr 1433 * use them to check and invalidate caches, then cache the new attributes. 1434 */ 1435 /* ARGSUSED */ 1436 static int 1437 smbfs_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr, 1438 caller_context_t *ct) 1439 { 1440 smbnode_t *np; 1441 smbmntinfo_t *smi; 1442 int error; 1443 1444 smi = VTOSMI(vp); 1445 1446 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 1447 return (EIO); 1448 1449 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 1450 return (EIO); 1451 1452 /* 1453 * If it has been specified that the return value will 1454 * just be used as a hint, and we are only being asked 1455 * for size, fsid or rdevid, then return the client's 1456 * notion of these values without checking to make sure 1457 * that the attribute cache is up to date. 1458 * The whole point is to avoid an over the wire GETATTR 1459 * call. 1460 */ 1461 np = VTOSMB(vp); 1462 if (flags & ATTR_HINT) { 1463 if (vap->va_mask == 1464 (vap->va_mask & (AT_SIZE | AT_FSID | AT_RDEV))) { 1465 mutex_enter(&np->r_statelock); 1466 if (vap->va_mask | AT_SIZE) 1467 vap->va_size = np->r_size; 1468 if (vap->va_mask | AT_FSID) 1469 vap->va_fsid = vp->v_vfsp->vfs_dev; 1470 if (vap->va_mask | AT_RDEV) 1471 vap->va_rdev = vp->v_rdev; 1472 mutex_exit(&np->r_statelock); 1473 return (0); 1474 } 1475 } 1476 1477 /* 1478 * Only need to flush pages if asking for the mtime 1479 * and if there any dirty pages. 1480 * 1481 * Here NFS also checks for async writes (np->r_awcount) 1482 */ 1483 if (vap->va_mask & AT_MTIME) { 1484 if (vn_has_cached_data(vp) && 1485 ((np->r_flags & RDIRTY) != 0)) { 1486 mutex_enter(&np->r_statelock); 1487 np->r_gcount++; 1488 mutex_exit(&np->r_statelock); 1489 error = smbfs_putpage(vp, (offset_t)0, 0, 0, cr, ct); 1490 mutex_enter(&np->r_statelock); 1491 if (error && (error == ENOSPC || error == EDQUOT)) { 1492 if (!np->r_error) 1493 np->r_error = error; 1494 } 1495 if (--np->r_gcount == 0) 1496 cv_broadcast(&np->r_cv); 1497 mutex_exit(&np->r_statelock); 1498 } 1499 } 1500 1501 return (smbfsgetattr(vp, vap, cr)); 1502 } 1503 1504 /* smbfsgetattr() in smbfs_client.c */ 1505 1506 /*ARGSUSED4*/ 1507 static int 1508 smbfs_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr, 1509 caller_context_t *ct) 1510 { 1511 vfs_t *vfsp; 1512 smbmntinfo_t *smi; 1513 int error; 1514 uint_t mask; 1515 struct vattr oldva; 1516 1517 vfsp = vp->v_vfsp; 1518 smi = VFTOSMI(vfsp); 1519 1520 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 1521 return (EIO); 1522 1523 if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED) 1524 return (EIO); 1525 1526 mask = vap->va_mask; 1527 if (mask & AT_NOSET) 1528 return (EINVAL); 1529 1530 if (vfsp->vfs_flag & VFS_RDONLY) 1531 return (EROFS); 1532 1533 /* 1534 * This is a _local_ access check so that only the owner of 1535 * this mount can set attributes. With ACLs enabled, the 1536 * file owner can be different from the mount owner, and we 1537 * need to check the _mount_ owner here. See _access_rwx 1538 */ 1539 bzero(&oldva, sizeof (oldva)); 1540 oldva.va_mask = AT_TYPE | AT_MODE; 1541 error = smbfsgetattr(vp, &oldva, cr); 1542 if (error) 1543 return (error); 1544 oldva.va_mask |= AT_UID | AT_GID; 1545 oldva.va_uid = smi->smi_uid; 1546 oldva.va_gid = smi->smi_gid; 1547 1548 error = secpolicy_vnode_setattr(cr, vp, vap, &oldva, flags, 1549 smbfs_accessx, vp); 1550 if (error) 1551 return (error); 1552 1553 if (mask & (AT_UID | AT_GID)) { 1554 if (smi->smi_flags & SMI_ACL) 1555 error = smbfs_acl_setids(vp, vap, cr); 1556 else 1557 error = ENOSYS; 1558 if (error != 0) { 1559 SMBVDEBUG("error %d seting UID/GID on %s", 1560 error, VTOSMB(vp)->n_rpath); 1561 /* 1562 * It might be more correct to return the 1563 * error here, but that causes complaints 1564 * when root extracts a cpio archive, etc. 1565 * So ignore this error, and go ahead with 1566 * the rest of the setattr work. 1567 */ 1568 } 1569 } 1570 1571 error = smbfssetattr(vp, vap, flags, cr); 1572 1573 #ifdef SMBFS_VNEVENT 1574 if (error == 0 && (vap->va_mask & AT_SIZE) && vap->va_size == 0) 1575 vnevent_truncate(vp, ct); 1576 #endif 1577 1578 return (error); 1579 } 1580 1581 /* 1582 * Mostly from Darwin smbfs_setattr() 1583 * but then modified a lot. 1584 */ 1585 /* ARGSUSED */ 1586 static int 1587 smbfssetattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr) 1588 { 1589 int error = 0; 1590 smbnode_t *np = VTOSMB(vp); 1591 smbmntinfo_t *smi = np->n_mount; 1592 uint_t mask = vap->va_mask; 1593 struct timespec *mtime, *atime; 1594 struct smb_cred scred; 1595 int modified = 0; 1596 smb_fh_t *fid = NULL; 1597 uint32_t rights = 0; 1598 uint32_t dosattr = 0; 1599 1600 ASSERT(curproc->p_zone == VTOSMI(vp)->smi_zone_ref.zref_zone); 1601 1602 /* 1603 * There are no settable attributes on the XATTR dir, 1604 * so just silently ignore these. On XATTR files, 1605 * you can set the size but nothing else. 1606 */ 1607 if (vp->v_flag & V_XATTRDIR) 1608 return (0); 1609 if (np->n_flag & N_XATTR) { 1610 if (mask & AT_TIMES) 1611 SMBVDEBUG("ignore set time on xattr\n"); 1612 mask &= AT_SIZE; 1613 } 1614 1615 /* 1616 * Only need to flush pages if there are any pages and 1617 * if the file is marked as dirty in some fashion. The 1618 * file must be flushed so that we can accurately 1619 * determine the size of the file and the cached data 1620 * after the SETATTR returns. A file is considered to 1621 * be dirty if it is either marked with RDIRTY, has 1622 * outstanding i/o's active, or is mmap'd. In this 1623 * last case, we can't tell whether there are dirty 1624 * pages, so we flush just to be sure. 1625 */ 1626 if (vn_has_cached_data(vp) && 1627 ((np->r_flags & RDIRTY) || 1628 np->r_count > 0 || 1629 np->r_mapcnt > 0)) { 1630 ASSERT(vp->v_type != VCHR); 1631 error = smbfs_putpage(vp, (offset_t)0, 0, 0, cr, NULL); 1632 if (error && (error == ENOSPC || error == EDQUOT)) { 1633 mutex_enter(&np->r_statelock); 1634 if (!np->r_error) 1635 np->r_error = error; 1636 mutex_exit(&np->r_statelock); 1637 } 1638 } 1639 1640 /* 1641 * If our caller is trying to set multiple attributes, they 1642 * can make no assumption about what order they are done in. 1643 * Here we try to do them in order of decreasing likelihood 1644 * of failure, just to minimize the chance we'll wind up 1645 * with a partially complete request. 1646 */ 1647 1648 smb_credinit(&scred, cr); 1649 1650 /* 1651 * If the caller has provided extensible attributes, 1652 * map those into DOS attributes supported by SMB. 1653 * Note: zero means "no change". 1654 */ 1655 if (mask & AT_XVATTR) 1656 dosattr = xvattr_to_dosattr(np, vap); 1657 1658 /* 1659 * Will we need an open handle for this setattr? 1660 * If so, what rights will we need? 1661 */ 1662 if (dosattr || (mask & (AT_ATIME | AT_MTIME))) { 1663 rights |= 1664 SA_RIGHT_FILE_WRITE_ATTRIBUTES; 1665 } 1666 if (mask & AT_SIZE) { 1667 rights |= 1668 SA_RIGHT_FILE_WRITE_DATA | 1669 SA_RIGHT_FILE_APPEND_DATA; 1670 } 1671 1672 /* 1673 * Only SIZE really requires a handle, but it's 1674 * simpler and more reliable to set via a handle. 1675 * Some servers like NT4 won't set times by path. 1676 * Also, we're usually setting everything anyway. 1677 */ 1678 if (rights != 0) { 1679 error = smbfs_smb_tmpopen(np, rights, &scred, &fid); 1680 if (error) { 1681 SMBVDEBUG("error %d opening %s\n", 1682 error, np->n_rpath); 1683 goto out; 1684 } 1685 ASSERT(fid != NULL); 1686 } 1687 1688 /* 1689 * If the server supports the UNIX extensions, right here is where 1690 * we'd support changes to uid, gid, mode, and possibly va_flags. 1691 * For now we claim to have made any such changes. 1692 */ 1693 1694 if (mask & AT_SIZE) { 1695 /* 1696 * If the new file size is less than what the client sees as 1697 * the file size, then just change the size and invalidate 1698 * the pages. 1699 */ 1700 1701 /* 1702 * Set the file size to vap->va_size. 1703 */ 1704 ASSERT(fid != NULL); 1705 error = smbfs_smb_setfsize(smi->smi_share, fid, 1706 vap->va_size, &scred); 1707 if (error) { 1708 SMBVDEBUG("setsize error %d file %s\n", 1709 error, np->n_rpath); 1710 } else { 1711 /* 1712 * Darwin had code here to zero-extend. 1713 * Tests indicate the server will zero-fill, 1714 * so looks like we don't need to do that. 1715 */ 1716 mutex_enter(&np->r_statelock); 1717 np->r_size = vap->va_size; 1718 np->n_flag |= (NFLUSHWIRE | NATTRCHANGED); 1719 mutex_exit(&np->r_statelock); 1720 modified = 1; 1721 } 1722 } 1723 1724 /* 1725 * Todo: Implement setting create_time (which is 1726 * different from ctime). 1727 */ 1728 mtime = ((mask & AT_MTIME) ? &vap->va_mtime : 0); 1729 atime = ((mask & AT_ATIME) ? &vap->va_atime : 0); 1730 1731 if (dosattr || mtime || atime) { 1732 /* 1733 * Always use the handle-based set attr call now. 1734 */ 1735 ASSERT(fid != NULL); 1736 error = smbfs_smb_setfattr(smi->smi_share, fid, 1737 dosattr, mtime, atime, &scred); 1738 if (error) { 1739 SMBVDEBUG("set times error %d file %s\n", 1740 error, np->n_rpath); 1741 } else { 1742 modified = 1; 1743 } 1744 } 1745 1746 out: 1747 if (fid != NULL) 1748 smbfs_smb_tmpclose(np, fid); 1749 1750 smb_credrele(&scred); 1751 1752 if (modified) { 1753 /* 1754 * Invalidate attribute cache in case the server 1755 * doesn't set exactly the attributes we asked. 1756 */ 1757 smbfs_attrcache_remove(np); 1758 1759 /* 1760 * If changing the size of the file, invalidate 1761 * any local cached data which is no longer part 1762 * of the file. We also possibly invalidate the 1763 * last page in the file. We could use 1764 * pvn_vpzero(), but this would mark the page as 1765 * modified and require it to be written back to 1766 * the server for no particularly good reason. 1767 * This way, if we access it, then we bring it 1768 * back in. A read should be cheaper than a 1769 * write. 1770 */ 1771 if (mask & AT_SIZE) { 1772 smbfs_invalidate_pages(vp, 1773 (vap->va_size & PAGEMASK), cr); 1774 } 1775 } 1776 1777 return (error); 1778 } 1779 1780 /* 1781 * Helper function for extensible system attributes (PSARC 2007/315) 1782 * Compute the DOS attribute word to pass to _setfattr (see above). 1783 * This returns zero IFF no change is being made to attributes. 1784 * Otherwise return the new attributes or SMB_EFA_NORMAL. 1785 */ 1786 static uint32_t 1787 xvattr_to_dosattr(smbnode_t *np, struct vattr *vap) 1788 { 1789 xvattr_t *xvap = (xvattr_t *)vap; 1790 xoptattr_t *xoap = NULL; 1791 uint32_t attr = np->r_attr.fa_attr; 1792 boolean_t anyset = B_FALSE; 1793 1794 if ((xoap = xva_getxoptattr(xvap)) == NULL) 1795 return (0); 1796 1797 if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE)) { 1798 if (xoap->xoa_archive) 1799 attr |= SMB_FA_ARCHIVE; 1800 else 1801 attr &= ~SMB_FA_ARCHIVE; 1802 XVA_SET_RTN(xvap, XAT_ARCHIVE); 1803 anyset = B_TRUE; 1804 } 1805 if (XVA_ISSET_REQ(xvap, XAT_SYSTEM)) { 1806 if (xoap->xoa_system) 1807 attr |= SMB_FA_SYSTEM; 1808 else 1809 attr &= ~SMB_FA_SYSTEM; 1810 XVA_SET_RTN(xvap, XAT_SYSTEM); 1811 anyset = B_TRUE; 1812 } 1813 if (XVA_ISSET_REQ(xvap, XAT_READONLY)) { 1814 if (xoap->xoa_readonly) 1815 attr |= SMB_FA_RDONLY; 1816 else 1817 attr &= ~SMB_FA_RDONLY; 1818 XVA_SET_RTN(xvap, XAT_READONLY); 1819 anyset = B_TRUE; 1820 } 1821 if (XVA_ISSET_REQ(xvap, XAT_HIDDEN)) { 1822 if (xoap->xoa_hidden) 1823 attr |= SMB_FA_HIDDEN; 1824 else 1825 attr &= ~SMB_FA_HIDDEN; 1826 XVA_SET_RTN(xvap, XAT_HIDDEN); 1827 anyset = B_TRUE; 1828 } 1829 1830 if (anyset == B_FALSE) 1831 return (0); /* no change */ 1832 if (attr == 0) 1833 attr = SMB_EFA_NORMAL; 1834 1835 return (attr); 1836 } 1837 1838 /* 1839 * smbfs_access_rwx() 1840 * Common function for smbfs_access, etc. 1841 * 1842 * The security model implemented by the FS is unusual 1843 * due to the current "single user mounts" restriction: 1844 * All access under a given mount point uses the CIFS 1845 * credentials established by the owner of the mount. 1846 * 1847 * Most access checking is handled by the CIFS server, 1848 * but we need sufficient Unix access checks here to 1849 * prevent other local Unix users from having access 1850 * to objects under this mount that the uid/gid/mode 1851 * settings in the mount would not allow. 1852 * 1853 * With this model, there is a case where we need the 1854 * ability to do an access check before we have the 1855 * vnode for an object. This function takes advantage 1856 * of the fact that the uid/gid/mode is per mount, and 1857 * avoids the need for a vnode. 1858 * 1859 * We still (sort of) need a vnode when we call 1860 * secpolicy_vnode_access, but that only uses 1861 * the vtype field, so we can use a pair of fake 1862 * vnodes that have only v_type filled in. 1863 */ 1864 static int 1865 smbfs_access_rwx(vfs_t *vfsp, int vtype, int mode, cred_t *cr) 1866 { 1867 /* See the secpolicy call below. */ 1868 static const vnode_t tmpl_vdir = { .v_type = VDIR }; 1869 static const vnode_t tmpl_vreg = { .v_type = VREG }; 1870 vattr_t va; 1871 vnode_t *tvp; 1872 struct smbmntinfo *smi = VFTOSMI(vfsp); 1873 int shift = 0; 1874 1875 /* 1876 * Build our (fabricated) vnode attributes. 1877 */ 1878 bzero(&va, sizeof (va)); 1879 va.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID; 1880 va.va_type = vtype; 1881 va.va_mode = (vtype == VDIR) ? 1882 smi->smi_dmode : smi->smi_fmode; 1883 va.va_uid = smi->smi_uid; 1884 va.va_gid = smi->smi_gid; 1885 1886 /* 1887 * Disallow write attempts on read-only file systems, 1888 * unless the file is a device or fifo node. Note: 1889 * Inline vn_is_readonly and IS_DEVVP here because 1890 * we may not have a vnode ptr. Original expr. was: 1891 * (mode & VWRITE) && vn_is_readonly(vp) && !IS_DEVVP(vp)) 1892 */ 1893 if ((mode & VWRITE) && 1894 (vfsp->vfs_flag & VFS_RDONLY) && 1895 !(vtype == VCHR || vtype == VBLK || vtype == VFIFO)) 1896 return (EROFS); 1897 1898 /* 1899 * Disallow attempts to access mandatory lock files. 1900 * Similarly, expand MANDLOCK here. 1901 */ 1902 if ((mode & (VWRITE | VREAD | VEXEC)) && 1903 va.va_type == VREG && MANDMODE(va.va_mode)) 1904 return (EACCES); 1905 1906 /* 1907 * Access check is based on only 1908 * one of owner, group, public. 1909 * If not owner, then check group. 1910 * If not a member of the group, 1911 * then check public access. 1912 */ 1913 if (crgetuid(cr) != va.va_uid) { 1914 shift += 3; 1915 if (!groupmember(va.va_gid, cr)) 1916 shift += 3; 1917 } 1918 1919 /* 1920 * We need a vnode for secpolicy_vnode_access, 1921 * but the only thing it looks at is v_type, 1922 * so pass one of the templates above. 1923 */ 1924 tvp = (va.va_type == VDIR) ? 1925 (vnode_t *)&tmpl_vdir : 1926 (vnode_t *)&tmpl_vreg; 1927 1928 return (secpolicy_vnode_access2(cr, tvp, va.va_uid, 1929 va.va_mode << shift, mode)); 1930 } 1931 1932 /* 1933 * See smbfs_setattr 1934 */ 1935 static int 1936 smbfs_accessx(void *arg, int mode, cred_t *cr) 1937 { 1938 vnode_t *vp = arg; 1939 /* 1940 * Note: The caller has checked the current zone, 1941 * the SMI_DEAD and VFS_UNMOUNTED flags, etc. 1942 */ 1943 return (smbfs_access_rwx(vp->v_vfsp, vp->v_type, mode, cr)); 1944 } 1945 1946 /* 1947 * XXX 1948 * This op should support PSARC 2007/403, Modified Access Checks for CIFS 1949 */ 1950 /* ARGSUSED */ 1951 static int 1952 smbfs_access(vnode_t *vp, int mode, int flags, cred_t *cr, caller_context_t *ct) 1953 { 1954 vfs_t *vfsp; 1955 smbmntinfo_t *smi; 1956 1957 vfsp = vp->v_vfsp; 1958 smi = VFTOSMI(vfsp); 1959 1960 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 1961 return (EIO); 1962 1963 if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED) 1964 return (EIO); 1965 1966 return (smbfs_access_rwx(vfsp, vp->v_type, mode, cr)); 1967 } 1968 1969 1970 /* ARGSUSED */ 1971 static int 1972 smbfs_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr, caller_context_t *ct) 1973 { 1974 /* Not yet... */ 1975 return (ENOSYS); 1976 } 1977 1978 1979 /* 1980 * Flush local dirty pages to stable storage on the server. 1981 * 1982 * If FNODSYNC is specified, then there is nothing to do because 1983 * metadata changes are not cached on the client before being 1984 * sent to the server. 1985 */ 1986 /* ARGSUSED */ 1987 static int 1988 smbfs_fsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct) 1989 { 1990 int error = 0; 1991 smbmntinfo_t *smi; 1992 smbnode_t *np; 1993 struct smb_cred scred; 1994 1995 np = VTOSMB(vp); 1996 smi = VTOSMI(vp); 1997 1998 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 1999 return (EIO); 2000 2001 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 2002 return (EIO); 2003 2004 if ((syncflag & FNODSYNC) || IS_SWAPVP(vp)) 2005 return (0); 2006 2007 if ((syncflag & (FSYNC|FDSYNC)) == 0) 2008 return (0); 2009 2010 error = smbfs_putpage(vp, (offset_t)0, 0, 0, cr, ct); 2011 if (error) 2012 return (error); 2013 2014 /* Shared lock for n_fid use in _flush */ 2015 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp))) 2016 return (EINTR); 2017 smb_credinit(&scred, cr); 2018 2019 error = smbfsflush(np, &scred); 2020 2021 smb_credrele(&scred); 2022 smbfs_rw_exit(&np->r_lkserlock); 2023 2024 return (error); 2025 } 2026 2027 static int 2028 smbfsflush(smbnode_t *np, struct smb_cred *scrp) 2029 { 2030 struct smb_share *ssp = np->n_mount->smi_share; 2031 smb_fh_t *fhp; 2032 int error; 2033 2034 /* Shared lock for n_fid use below. */ 2035 ASSERT(smbfs_rw_lock_held(&np->r_lkserlock, RW_READER)); 2036 2037 if (!(np->n_flag & NFLUSHWIRE)) 2038 return (0); 2039 if (np->n_fidrefs == 0) 2040 return (0); /* not open */ 2041 if ((fhp = np->n_fid) == NULL) 2042 return (0); 2043 2044 /* After reconnect, n_fid is invalid */ 2045 if (fhp->fh_vcgenid != ssp->ss_vcgenid) 2046 return (ESTALE); 2047 2048 error = smbfs_smb_flush(ssp, fhp, scrp); 2049 2050 if (!error) { 2051 mutex_enter(&np->r_statelock); 2052 np->n_flag &= ~NFLUSHWIRE; 2053 mutex_exit(&np->r_statelock); 2054 } 2055 return (error); 2056 } 2057 2058 /* 2059 * Last reference to vnode went away. 2060 */ 2061 /* ARGSUSED */ 2062 static void 2063 smbfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) 2064 { 2065 struct smb_cred scred; 2066 smbnode_t *np = VTOSMB(vp); 2067 int error; 2068 2069 /* 2070 * Don't "bail out" for VFS_UNMOUNTED here, 2071 * as we want to do cleanup, etc. 2072 * See also pcfs_inactive 2073 */ 2074 2075 /* 2076 * If this is coming from the wrong zone, we let someone in the right 2077 * zone take care of it asynchronously. We can get here due to 2078 * VN_RELE() being called from pageout() or fsflush(). This call may 2079 * potentially turn into an expensive no-op if, for instance, v_count 2080 * gets incremented in the meantime, but it's still correct. 2081 */ 2082 2083 /* 2084 * From NFS:rinactive() 2085 * 2086 * Before freeing anything, wait until all asynchronous 2087 * activity is done on this rnode. This will allow all 2088 * asynchronous read ahead and write behind i/o's to 2089 * finish. 2090 */ 2091 mutex_enter(&np->r_statelock); 2092 while (np->r_count > 0) 2093 cv_wait(&np->r_cv, &np->r_statelock); 2094 mutex_exit(&np->r_statelock); 2095 2096 /* 2097 * Flush and invalidate all pages associated with the vnode. 2098 */ 2099 if (vn_has_cached_data(vp)) { 2100 if ((np->r_flags & RDIRTY) && !np->r_error) { 2101 error = smbfs_putpage(vp, (u_offset_t)0, 0, 0, cr, ct); 2102 if (error && (error == ENOSPC || error == EDQUOT)) { 2103 mutex_enter(&np->r_statelock); 2104 if (!np->r_error) 2105 np->r_error = error; 2106 mutex_exit(&np->r_statelock); 2107 } 2108 } 2109 smbfs_invalidate_pages(vp, (u_offset_t)0, cr); 2110 } 2111 /* 2112 * This vnode should have lost all cached data. 2113 */ 2114 ASSERT(vn_has_cached_data(vp) == 0); 2115 2116 /* 2117 * Defend against the possibility that higher-level callers 2118 * might not correctly balance open and close calls. If we 2119 * get here with open references remaining, it means there 2120 * was a missing VOP_CLOSE somewhere. If that happens, do 2121 * the close here so we don't "leak" FIDs on the server. 2122 * 2123 * Exclusive lock for modifying n_fid stuff. 2124 * Don't want this one ever interruptible. 2125 */ 2126 (void) smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, 0); 2127 smb_credinit(&scred, cr); 2128 2129 switch (np->n_ovtype) { 2130 case VNON: 2131 /* not open (OK) */ 2132 break; 2133 2134 case VDIR: 2135 if (np->n_dirrefs == 0) 2136 break; 2137 SMBVDEBUG("open dir: refs %d path %s\n", 2138 np->n_dirrefs, np->n_rpath); 2139 /* Force last close. */ 2140 np->n_dirrefs = 1; 2141 smbfs_rele_fid(np, &scred); 2142 break; 2143 2144 case VREG: 2145 if (np->n_fidrefs == 0) 2146 break; 2147 SMBVDEBUG("open file: refs %d path %s\n", 2148 np->n_fidrefs, np->n_rpath); 2149 /* Force last close. */ 2150 np->n_fidrefs = 1; 2151 smbfs_rele_fid(np, &scred); 2152 break; 2153 2154 default: 2155 SMBVDEBUG("bad n_ovtype %d\n", np->n_ovtype); 2156 np->n_ovtype = VNON; 2157 break; 2158 } 2159 2160 smb_credrele(&scred); 2161 smbfs_rw_exit(&np->r_lkserlock); 2162 2163 /* 2164 * XATTR directories (and the files under them) have 2165 * little value for reclaim, so just remove them from 2166 * the "hash" (AVL) as soon as they go inactive. 2167 * Note that the node may already have been removed 2168 * from the hash by smbfsremove. 2169 */ 2170 if ((np->n_flag & N_XATTR) != 0 && 2171 (np->r_flags & RHASHED) != 0) 2172 smbfs_rmhash(np); 2173 2174 smbfs_addfree(np); 2175 } 2176 2177 /* 2178 * Remote file system operations having to do with directory manipulation. 2179 */ 2180 /* ARGSUSED */ 2181 static int 2182 smbfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp, 2183 int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct, 2184 int *direntflags, pathname_t *realpnp) 2185 { 2186 vfs_t *vfs; 2187 smbmntinfo_t *smi; 2188 smbnode_t *dnp; 2189 int error; 2190 2191 vfs = dvp->v_vfsp; 2192 smi = VFTOSMI(vfs); 2193 2194 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 2195 return (EPERM); 2196 2197 if (smi->smi_flags & SMI_DEAD || vfs->vfs_flag & VFS_UNMOUNTED) 2198 return (EIO); 2199 2200 dnp = VTOSMB(dvp); 2201 2202 /* 2203 * Are we looking up extended attributes? If so, "dvp" is 2204 * the file or directory for which we want attributes, and 2205 * we need a lookup of the (faked up) attribute directory 2206 * before we lookup the rest of the path. 2207 */ 2208 if (flags & LOOKUP_XATTR) { 2209 /* 2210 * Require the xattr mount option. 2211 */ 2212 if ((vfs->vfs_flag & VFS_XATTR) == 0) 2213 return (EINVAL); 2214 2215 error = smbfs_get_xattrdir(dvp, vpp, cr, flags); 2216 return (error); 2217 } 2218 2219 if (smbfs_rw_enter_sig(&dnp->r_rwlock, RW_READER, SMBINTR(dvp))) 2220 return (EINTR); 2221 2222 error = smbfslookup(dvp, nm, vpp, cr, 1, ct); 2223 2224 smbfs_rw_exit(&dnp->r_rwlock); 2225 2226 /* 2227 * If the caller passes an invalid name here, we'll have 2228 * error == EINVAL but want to return ENOENT. This is 2229 * common with things like "ls foo*" with no matches. 2230 */ 2231 if (error == EINVAL) 2232 error = ENOENT; 2233 2234 return (error); 2235 } 2236 2237 /* ARGSUSED */ 2238 static int 2239 smbfslookup(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr, 2240 int cache_ok, caller_context_t *ct) 2241 { 2242 int error; 2243 int supplen; /* supported length */ 2244 vnode_t *vp; 2245 smbnode_t *np; 2246 smbnode_t *dnp; 2247 smbmntinfo_t *smi; 2248 /* struct smb_vc *vcp; */ 2249 const char *ill; 2250 const char *name = (const char *)nm; 2251 int nmlen = strlen(nm); 2252 int rplen; 2253 struct smb_cred scred; 2254 struct smbfattr fa; 2255 2256 smi = VTOSMI(dvp); 2257 dnp = VTOSMB(dvp); 2258 2259 ASSERT(curproc->p_zone == smi->smi_zone_ref.zref_zone); 2260 2261 supplen = 255; 2262 2263 /* 2264 * RWlock must be held, either reader or writer. 2265 */ 2266 ASSERT(dnp->r_rwlock.count != 0); 2267 2268 /* 2269 * If lookup is for "", just return dvp. 2270 * No need to perform any access checks. 2271 */ 2272 if (nmlen == 0) { 2273 VN_HOLD(dvp); 2274 *vpp = dvp; 2275 return (0); 2276 } 2277 2278 /* 2279 * Can't do lookups in non-directories. 2280 */ 2281 if (dvp->v_type != VDIR) 2282 return (ENOTDIR); 2283 2284 /* 2285 * Need search permission in the directory. 2286 */ 2287 error = smbfs_access(dvp, VEXEC, 0, cr, ct); 2288 if (error) 2289 return (error); 2290 2291 /* 2292 * If lookup is for ".", just return dvp. 2293 * Access check was done above. 2294 */ 2295 if (nmlen == 1 && name[0] == '.') { 2296 VN_HOLD(dvp); 2297 *vpp = dvp; 2298 return (0); 2299 } 2300 2301 /* 2302 * Now some sanity checks on the name. 2303 * First check the length. 2304 */ 2305 if (nmlen > supplen) 2306 return (ENAMETOOLONG); 2307 2308 /* 2309 * Avoid surprises with characters that are 2310 * illegal in Windows file names. 2311 * Todo: CATIA mappings? 2312 */ 2313 ill = illegal_chars; 2314 if (dnp->n_flag & N_XATTR) 2315 ill++; /* allow colon */ 2316 if (strpbrk(nm, ill)) 2317 return (EINVAL); 2318 2319 /* 2320 * Special handling for lookup of ".." 2321 * 2322 * We keep full pathnames (as seen on the server) 2323 * so we can just trim off the last component to 2324 * get the full pathname of the parent. Note: 2325 * We don't actually copy and modify, but just 2326 * compute the trimmed length and pass that with 2327 * the current dir path (not null terminated). 2328 * 2329 * We don't go over-the-wire to get attributes 2330 * for ".." because we know it's a directory, 2331 * and we can just leave the rest "stale" 2332 * until someone does a getattr. 2333 */ 2334 if (nmlen == 2 && name[0] == '.' && name[1] == '.') { 2335 if (dvp->v_flag & VROOT) { 2336 /* 2337 * Already at the root. This can happen 2338 * with directory listings at the root, 2339 * which lookup "." and ".." to get the 2340 * inode numbers. Let ".." be the same 2341 * as "." in the FS root. 2342 */ 2343 VN_HOLD(dvp); 2344 *vpp = dvp; 2345 return (0); 2346 } 2347 2348 /* 2349 * Special case for XATTR directory 2350 */ 2351 if (dvp->v_flag & V_XATTRDIR) { 2352 error = smbfs_xa_parent(dvp, vpp); 2353 return (error); 2354 } 2355 2356 /* 2357 * Find the parent path length. 2358 */ 2359 rplen = dnp->n_rplen; 2360 ASSERT(rplen > 0); 2361 while (--rplen >= 0) { 2362 if (dnp->n_rpath[rplen] == '\\') 2363 break; 2364 } 2365 if (rplen <= 0) { 2366 /* Found our way to the root. */ 2367 vp = SMBTOV(smi->smi_root); 2368 VN_HOLD(vp); 2369 *vpp = vp; 2370 return (0); 2371 } 2372 np = smbfs_node_findcreate(smi, 2373 dnp->n_rpath, rplen, NULL, 0, 0, 2374 &smbfs_fattr0); /* force create */ 2375 ASSERT(np != NULL); 2376 vp = SMBTOV(np); 2377 vp->v_type = VDIR; 2378 2379 /* Success! */ 2380 *vpp = vp; 2381 return (0); 2382 } 2383 2384 /* 2385 * Normal lookup of a name under this directory. 2386 * Note we handled "", ".", ".." above. 2387 */ 2388 if (cache_ok) { 2389 /* 2390 * The caller indicated that it's OK to use a 2391 * cached result for this lookup, so try to 2392 * reclaim a node from the smbfs node cache. 2393 */ 2394 error = smbfslookup_cache(dvp, nm, nmlen, &vp, cr); 2395 if (error) 2396 return (error); 2397 if (vp != NULL) { 2398 /* hold taken in lookup_cache */ 2399 *vpp = vp; 2400 return (0); 2401 } 2402 } 2403 2404 /* 2405 * OK, go over-the-wire to get the attributes, 2406 * then create the node. 2407 */ 2408 smb_credinit(&scred, cr); 2409 /* Note: this can allocate a new "name" */ 2410 error = smbfs_smb_lookup(dnp, &name, &nmlen, &fa, &scred); 2411 smb_credrele(&scred); 2412 if (error == ENOTDIR) { 2413 /* 2414 * Lookup failed because this directory was 2415 * removed or renamed by another client. 2416 * Remove any cached attributes under it. 2417 */ 2418 smbfs_attrcache_remove(dnp); 2419 smbfs_attrcache_prune(dnp); 2420 } 2421 if (error) 2422 goto out; 2423 2424 error = smbfs_nget(dvp, name, nmlen, &fa, &vp); 2425 if (error) 2426 goto out; 2427 2428 /* Success! */ 2429 *vpp = vp; 2430 2431 out: 2432 /* smbfs_smb_lookup may have allocated name. */ 2433 if (name != nm) 2434 smbfs_name_free(name, nmlen); 2435 2436 return (error); 2437 } 2438 2439 /* 2440 * smbfslookup_cache 2441 * 2442 * Try to reclaim a node from the smbfs node cache. 2443 * Some statistics for DEBUG. 2444 * 2445 * This mechanism lets us avoid many of the five (or more) 2446 * OtW lookup calls per file seen with "ls -l" if we search 2447 * the smbfs node cache for recently inactive(ated) nodes. 2448 */ 2449 #ifdef DEBUG 2450 int smbfs_lookup_cache_calls = 0; 2451 int smbfs_lookup_cache_error = 0; 2452 int smbfs_lookup_cache_miss = 0; 2453 int smbfs_lookup_cache_stale = 0; 2454 int smbfs_lookup_cache_hits = 0; 2455 #endif /* DEBUG */ 2456 2457 /* ARGSUSED */ 2458 static int 2459 smbfslookup_cache(vnode_t *dvp, char *nm, int nmlen, 2460 vnode_t **vpp, cred_t *cr) 2461 { 2462 struct vattr va; 2463 smbnode_t *dnp; 2464 smbnode_t *np; 2465 vnode_t *vp; 2466 int error; 2467 char sep; 2468 2469 dnp = VTOSMB(dvp); 2470 *vpp = NULL; 2471 2472 #ifdef DEBUG 2473 smbfs_lookup_cache_calls++; 2474 #endif 2475 2476 /* 2477 * First make sure we can get attributes for the 2478 * directory. Cached attributes are OK here. 2479 * If we removed or renamed the directory, this 2480 * will return ENOENT. If someone else removed 2481 * this directory or file, we'll find out when we 2482 * try to open or get attributes. 2483 */ 2484 va.va_mask = AT_TYPE | AT_MODE; 2485 error = smbfsgetattr(dvp, &va, cr); 2486 if (error) { 2487 #ifdef DEBUG 2488 smbfs_lookup_cache_error++; 2489 #endif 2490 return (error); 2491 } 2492 2493 /* 2494 * Passing NULL smbfattr here so we will 2495 * just look, not create. 2496 */ 2497 sep = SMBFS_DNP_SEP(dnp); 2498 np = smbfs_node_findcreate(dnp->n_mount, 2499 dnp->n_rpath, dnp->n_rplen, 2500 nm, nmlen, sep, NULL); 2501 if (np == NULL) { 2502 #ifdef DEBUG 2503 smbfs_lookup_cache_miss++; 2504 #endif 2505 return (0); 2506 } 2507 2508 /* 2509 * Found it. Attributes still valid? 2510 */ 2511 vp = SMBTOV(np); 2512 if (np->r_attrtime <= gethrtime()) { 2513 /* stale */ 2514 #ifdef DEBUG 2515 smbfs_lookup_cache_stale++; 2516 #endif 2517 VN_RELE(vp); 2518 return (0); 2519 } 2520 2521 /* 2522 * Success! 2523 * Caller gets hold from smbfs_node_findcreate 2524 */ 2525 #ifdef DEBUG 2526 smbfs_lookup_cache_hits++; 2527 #endif 2528 *vpp = vp; 2529 return (0); 2530 } 2531 2532 2533 /* 2534 * XXX 2535 * vsecattr_t is new to build 77, and we need to eventually support 2536 * it in order to create an ACL when an object is created. 2537 * 2538 * This op should support the new FIGNORECASE flag for case-insensitive 2539 * lookups, per PSARC 2007/244. 2540 */ 2541 /* ARGSUSED */ 2542 static int 2543 smbfs_create(vnode_t *dvp, char *nm, struct vattr *va, enum vcexcl exclusive, 2544 int mode, vnode_t **vpp, cred_t *cr, int lfaware, caller_context_t *ct, 2545 vsecattr_t *vsecp) 2546 { 2547 int error; 2548 vfs_t *vfsp; 2549 vnode_t *vp; 2550 smbnode_t *np; 2551 smbnode_t *dnp; 2552 smbmntinfo_t *smi; 2553 struct vattr vattr; 2554 struct smbfattr fattr; 2555 struct smb_cred scred; 2556 const char *name = (const char *)nm; 2557 int nmlen = strlen(nm); 2558 uint32_t disp; 2559 smb_fh_t *fid = NULL; 2560 int xattr; 2561 2562 vfsp = dvp->v_vfsp; 2563 smi = VFTOSMI(vfsp); 2564 dnp = VTOSMB(dvp); 2565 vp = NULL; 2566 2567 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 2568 return (EPERM); 2569 2570 if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED) 2571 return (EIO); 2572 2573 /* 2574 * Note: this may break mknod(2) calls to create a directory, 2575 * but that's obscure use. Some other filesystems do this. 2576 * Todo: redirect VDIR type here to _mkdir. 2577 */ 2578 if (va->va_type != VREG) 2579 return (EINVAL); 2580 2581 /* 2582 * If the pathname is "", just use dvp, no checks. 2583 * Do this outside of the rwlock (like zfs). 2584 */ 2585 if (nmlen == 0) { 2586 VN_HOLD(dvp); 2587 *vpp = dvp; 2588 return (0); 2589 } 2590 2591 /* Don't allow "." or ".." through here. */ 2592 if ((nmlen == 1 && name[0] == '.') || 2593 (nmlen == 2 && name[0] == '.' && name[1] == '.')) 2594 return (EISDIR); 2595 2596 /* 2597 * We make a copy of the attributes because the caller does not 2598 * expect us to change what va points to. 2599 */ 2600 vattr = *va; 2601 2602 if (smbfs_rw_enter_sig(&dnp->r_rwlock, RW_WRITER, SMBINTR(dvp))) 2603 return (EINTR); 2604 smb_credinit(&scred, cr); 2605 2606 /* 2607 * NFS needs to go over the wire, just to be sure whether the 2608 * file exists or not. Using a cached result is dangerous in 2609 * this case when making a decision regarding existence. 2610 * 2611 * The SMB protocol does NOT really need to go OTW here 2612 * thanks to the expressive NTCREATE disposition values. 2613 * Unfortunately, to do Unix access checks correctly, 2614 * we need to know if the object already exists. 2615 * When the object does not exist, we need VWRITE on 2616 * the directory. Note: smbfslookup() checks VEXEC. 2617 */ 2618 error = smbfslookup(dvp, nm, &vp, cr, 0, ct); 2619 if (error == 0) { 2620 /* 2621 * The file already exists. Error? 2622 * NB: have a hold from smbfslookup 2623 */ 2624 if (exclusive == EXCL) { 2625 error = EEXIST; 2626 VN_RELE(vp); 2627 goto out; 2628 } 2629 /* 2630 * Verify requested access. 2631 */ 2632 error = smbfs_access(vp, mode, 0, cr, ct); 2633 if (error) { 2634 VN_RELE(vp); 2635 goto out; 2636 } 2637 2638 /* 2639 * Truncate (if requested). 2640 */ 2641 if ((vattr.va_mask & AT_SIZE) && vp->v_type == VREG) { 2642 np = VTOSMB(vp); 2643 /* 2644 * Check here for large file truncation by 2645 * LF-unaware process, like ufs_create(). 2646 */ 2647 if (!(lfaware & FOFFMAX)) { 2648 mutex_enter(&np->r_statelock); 2649 if (np->r_size > MAXOFF32_T) 2650 error = EOVERFLOW; 2651 mutex_exit(&np->r_statelock); 2652 } 2653 if (error) { 2654 VN_RELE(vp); 2655 goto out; 2656 } 2657 vattr.va_mask = AT_SIZE; 2658 error = smbfssetattr(vp, &vattr, 0, cr); 2659 if (error) { 2660 VN_RELE(vp); 2661 goto out; 2662 } 2663 #ifdef SMBFS_VNEVENT 2664 /* Existing file was truncated */ 2665 vnevent_create(vp, ct); 2666 #endif 2667 /* invalidate pages done in smbfssetattr() */ 2668 } 2669 /* Success! */ 2670 *vpp = vp; 2671 goto out; 2672 } 2673 2674 /* 2675 * The file did not exist. Need VWRITE in the directory. 2676 */ 2677 error = smbfs_access(dvp, VWRITE, 0, cr, ct); 2678 if (error) 2679 goto out; 2680 2681 /* 2682 * Now things get tricky. We also need to check the 2683 * requested open mode against the file we may create. 2684 * See comments at smbfs_access_rwx 2685 */ 2686 error = smbfs_access_rwx(vfsp, VREG, mode, cr); 2687 if (error) 2688 goto out; 2689 2690 /* 2691 * Now the code derived from Darwin, 2692 * but with greater use of NT_CREATE 2693 * disposition options. Much changed. 2694 * 2695 * Create (or open) a new child node. 2696 * Note we handled "." and ".." above. 2697 */ 2698 2699 if (exclusive == EXCL) 2700 disp = NTCREATEX_DISP_CREATE; 2701 else { 2702 /* Truncate regular files if requested. */ 2703 if ((va->va_type == VREG) && 2704 (va->va_mask & AT_SIZE) && 2705 (va->va_size == 0)) 2706 disp = NTCREATEX_DISP_OVERWRITE_IF; 2707 else 2708 disp = NTCREATEX_DISP_OPEN_IF; 2709 } 2710 xattr = (dnp->n_flag & N_XATTR) ? 1 : 0; 2711 error = smbfs_smb_create(dnp, 2712 name, nmlen, xattr, 2713 disp, &scred, &fid); 2714 if (error) 2715 goto out; 2716 2717 /* 2718 * Should use the fid to get/set the size 2719 * while we have it opened here. See above. 2720 */ 2721 smbfs_smb_close(fid); 2722 2723 /* 2724 * In the open case, the name may differ a little 2725 * from what we passed to create (case, etc.) 2726 * so call lookup to get the (opened) name. 2727 * 2728 * XXX: Could avoid this extra lookup if the 2729 * "createact" result from NT_CREATE says we 2730 * created the object. 2731 */ 2732 error = smbfs_smb_lookup(dnp, &name, &nmlen, &fattr, &scred); 2733 if (error) 2734 goto out; 2735 2736 /* update attr and directory cache */ 2737 smbfs_attr_touchdir(dnp); 2738 2739 error = smbfs_nget(dvp, name, nmlen, &fattr, &vp); 2740 if (error) 2741 goto out; 2742 2743 /* Success! */ 2744 *vpp = vp; 2745 error = 0; 2746 2747 out: 2748 smb_credrele(&scred); 2749 smbfs_rw_exit(&dnp->r_rwlock); 2750 if (name != nm) 2751 smbfs_name_free(name, nmlen); 2752 return (error); 2753 } 2754 2755 /* 2756 * XXX 2757 * This op should support the new FIGNORECASE flag for case-insensitive 2758 * lookups, per PSARC 2007/244. 2759 */ 2760 /* ARGSUSED */ 2761 static int 2762 smbfs_remove(vnode_t *dvp, char *nm, cred_t *cr, caller_context_t *ct, 2763 int flags) 2764 { 2765 struct smb_cred scred; 2766 vnode_t *vp = NULL; 2767 smbnode_t *dnp = VTOSMB(dvp); 2768 smbmntinfo_t *smi = VTOSMI(dvp); 2769 int error; 2770 2771 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 2772 return (EPERM); 2773 2774 if (smi->smi_flags & SMI_DEAD || dvp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 2775 return (EIO); 2776 2777 /* 2778 * Verify access to the dirctory. 2779 */ 2780 error = smbfs_access(dvp, VWRITE|VEXEC, 0, cr, ct); 2781 if (error) 2782 return (error); 2783 2784 if (smbfs_rw_enter_sig(&dnp->r_rwlock, RW_WRITER, SMBINTR(dvp))) 2785 return (EINTR); 2786 smb_credinit(&scred, cr); 2787 2788 /* Lookup the file to remove. */ 2789 error = smbfslookup(dvp, nm, &vp, cr, 0, ct); 2790 if (error != 0) 2791 goto out; 2792 2793 /* Don't allow unlink of a directory. */ 2794 if (vp->v_type == VDIR) { 2795 error = EPERM; 2796 goto out; 2797 } 2798 2799 /* 2800 * Do the real remove work 2801 */ 2802 error = smbfsremove(dvp, vp, &scred, flags); 2803 if (error != 0) 2804 goto out; 2805 2806 #ifdef SMBFS_VNEVENT 2807 vnevent_remove(vp, dvp, nm, ct); 2808 #endif 2809 2810 out: 2811 if (vp != NULL) 2812 VN_RELE(vp); 2813 2814 smb_credrele(&scred); 2815 smbfs_rw_exit(&dnp->r_rwlock); 2816 2817 return (error); 2818 } 2819 2820 /* 2821 * smbfsremove does the real work of removing in SMBFS 2822 * Caller has done dir access checks etc. 2823 * 2824 * The normal way to delete a file over SMB is open it (with DELETE access), 2825 * set the "delete-on-close" flag, and close the file. The problem for Unix 2826 * applications is that they expect the file name to be gone once the unlink 2827 * completes, and the SMB server does not actually delete the file until ALL 2828 * opens of that file are closed. We can't assume our open handles are the 2829 * only open handles on a file we're deleting, so to be safe we'll try to 2830 * rename the file to a temporary name and then set delete-on-close. If we 2831 * fail to set delete-on-close (i.e. because other opens prevent it) then 2832 * undo the changes we made and give up with EBUSY. Note that we might have 2833 * permission to delete a file but lack permission to rename, so we want to 2834 * continue in cases where rename fails. As an optimization, only do the 2835 * rename when we have the file open. 2836 * 2837 * This is similar to what NFS does when deleting a file that has local opens, 2838 * but thanks to SMB delete-on-close, we don't need to keep track of when the 2839 * last local open goes away and send a delete. The server does that for us. 2840 */ 2841 /* ARGSUSED */ 2842 static int 2843 smbfsremove(vnode_t *dvp, vnode_t *vp, struct smb_cred *scred, 2844 int flags) 2845 { 2846 smbnode_t *dnp = VTOSMB(dvp); 2847 smbnode_t *np = VTOSMB(vp); 2848 smbmntinfo_t *smi = np->n_mount; 2849 char *tmpname = NULL; 2850 int tnlen; 2851 int error; 2852 smb_fh_t *fid = NULL; 2853 boolean_t renamed = B_FALSE; 2854 2855 /* 2856 * The dvp RWlock must be held as writer. 2857 */ 2858 ASSERT(dnp->r_rwlock.owner == curthread); 2859 2860 /* 2861 * We need to flush any dirty pages which happen to 2862 * be hanging around before removing the file. This 2863 * shouldn't happen very often and mostly on file 2864 * systems mounted "nocto". 2865 */ 2866 if (vn_has_cached_data(vp) && 2867 ((np->r_flags & RDIRTY) || np->r_count > 0)) { 2868 error = smbfs_putpage(vp, (offset_t)0, 0, 0, 2869 scred->scr_cred, NULL); 2870 if (error && (error == ENOSPC || error == EDQUOT)) { 2871 mutex_enter(&np->r_statelock); 2872 if (!np->r_error) 2873 np->r_error = error; 2874 mutex_exit(&np->r_statelock); 2875 } 2876 } 2877 2878 /* 2879 * Get a file handle with delete access. 2880 * Close this FID before return. 2881 */ 2882 error = smbfs_smb_tmpopen(np, STD_RIGHT_DELETE_ACCESS, 2883 scred, &fid); 2884 if (error) { 2885 SMBVDEBUG("error %d opening %s\n", 2886 error, np->n_rpath); 2887 goto out; 2888 } 2889 ASSERT(fid != NULL); 2890 2891 /* 2892 * If we have the file open, try to rename it to a temporary name. 2893 * If we can't rename, continue on and try setting DoC anyway. 2894 * Unnecessary for directories. 2895 */ 2896 if (vp->v_type != VDIR && vp->v_count > 1 && np->n_fidrefs > 0) { 2897 tmpname = kmem_alloc(MAXNAMELEN, KM_SLEEP); 2898 tnlen = smbfs_newname(tmpname, MAXNAMELEN); 2899 error = smbfs_smb_rename(dnp, np, dnp, tmpname, tnlen, 2900 fid, scred); 2901 if (error != 0) { 2902 SMBVDEBUG("error %d renaming %s -> %s\n", 2903 error, np->n_rpath, tmpname); 2904 /* Keep going without the rename. */ 2905 } else { 2906 renamed = B_TRUE; 2907 } 2908 } 2909 2910 /* 2911 * Mark the file as delete-on-close. If we can't, 2912 * undo what we did and err out. 2913 */ 2914 error = smbfs_smb_setdisp(smi->smi_share, fid, 1, scred); 2915 if (error != 0) { 2916 SMBVDEBUG("error %d setting DoC on %s\n", 2917 error, np->n_rpath); 2918 /* 2919 * Failed to set DoC. If we renamed, undo that. 2920 * Need np->n_rpath relative to parent (dnp). 2921 * Use parent path name length plus one for 2922 * the separator ('/' or ':') 2923 */ 2924 if (renamed) { 2925 char *oldname; 2926 int oldnlen; 2927 int err2; 2928 2929 oldname = np->n_rpath + (dnp->n_rplen + 1); 2930 oldnlen = np->n_rplen - (dnp->n_rplen + 1); 2931 err2 = smbfs_smb_rename(dnp, np, dnp, oldname, oldnlen, 2932 fid, scred); 2933 SMBVDEBUG("error %d un-renaming %s -> %s\n", 2934 err2, tmpname, np->n_rpath); 2935 } 2936 error = EBUSY; 2937 goto out; 2938 } 2939 /* Done! */ 2940 smbfs_attrcache_remove(np); 2941 smbfs_attrcache_prune(np); 2942 2943 out: 2944 if (tmpname != NULL) 2945 kmem_free(tmpname, MAXNAMELEN); 2946 if (fid != NULL) 2947 smbfs_smb_tmpclose(np, fid); 2948 2949 if (error == 0) { 2950 /* Keep lookup from finding this node anymore. */ 2951 smbfs_rmhash(np); 2952 } 2953 2954 return (error); 2955 } 2956 2957 2958 /* ARGSUSED */ 2959 static int 2960 smbfs_link(vnode_t *tdvp, vnode_t *svp, char *tnm, cred_t *cr, 2961 caller_context_t *ct, int flags) 2962 { 2963 /* Not yet... */ 2964 return (ENOSYS); 2965 } 2966 2967 2968 /* 2969 * XXX 2970 * This op should support the new FIGNORECASE flag for case-insensitive 2971 * lookups, per PSARC 2007/244. 2972 */ 2973 /* ARGSUSED */ 2974 static int 2975 smbfs_rename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm, cred_t *cr, 2976 caller_context_t *ct, int flags) 2977 { 2978 struct smb_cred scred; 2979 smbnode_t *odnp = VTOSMB(odvp); 2980 smbnode_t *ndnp = VTOSMB(ndvp); 2981 vnode_t *ovp; 2982 int error; 2983 2984 if (curproc->p_zone != VTOSMI(odvp)->smi_zone_ref.zref_zone || 2985 curproc->p_zone != VTOSMI(ndvp)->smi_zone_ref.zref_zone) 2986 return (EPERM); 2987 2988 if (VTOSMI(odvp)->smi_flags & SMI_DEAD || 2989 VTOSMI(ndvp)->smi_flags & SMI_DEAD || 2990 odvp->v_vfsp->vfs_flag & VFS_UNMOUNTED || 2991 ndvp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 2992 return (EIO); 2993 2994 if (strcmp(onm, ".") == 0 || strcmp(onm, "..") == 0 || 2995 strcmp(nnm, ".") == 0 || strcmp(nnm, "..") == 0) 2996 return (EINVAL); 2997 2998 /* 2999 * Check that everything is on the same filesystem. 3000 * vn_rename checks the fsid's, but in case we don't 3001 * fill those in correctly, check here too. 3002 */ 3003 if (odvp->v_vfsp != ndvp->v_vfsp) 3004 return (EXDEV); 3005 3006 /* 3007 * Need write access on source and target. 3008 * Server takes care of most checks. 3009 */ 3010 error = smbfs_access(odvp, VWRITE|VEXEC, 0, cr, ct); 3011 if (error) 3012 return (error); 3013 if (odvp != ndvp) { 3014 error = smbfs_access(ndvp, VWRITE, 0, cr, ct); 3015 if (error) 3016 return (error); 3017 } 3018 3019 /* 3020 * Need to lock both old/new dirs as writer. 3021 * 3022 * Avoid deadlock here on old vs new directory nodes 3023 * by always taking the locks in order of address. 3024 * The order is arbitrary, but must be consistent. 3025 */ 3026 if (odnp < ndnp) { 3027 if (smbfs_rw_enter_sig(&odnp->r_rwlock, RW_WRITER, 3028 SMBINTR(odvp))) 3029 return (EINTR); 3030 if (smbfs_rw_enter_sig(&ndnp->r_rwlock, RW_WRITER, 3031 SMBINTR(ndvp))) { 3032 smbfs_rw_exit(&odnp->r_rwlock); 3033 return (EINTR); 3034 } 3035 } else { 3036 if (smbfs_rw_enter_sig(&ndnp->r_rwlock, RW_WRITER, 3037 SMBINTR(ndvp))) 3038 return (EINTR); 3039 if (smbfs_rw_enter_sig(&odnp->r_rwlock, RW_WRITER, 3040 SMBINTR(odvp))) { 3041 smbfs_rw_exit(&ndnp->r_rwlock); 3042 return (EINTR); 3043 } 3044 } 3045 smb_credinit(&scred, cr); 3046 3047 /* Lookup the "old" name */ 3048 error = smbfslookup(odvp, onm, &ovp, cr, 0, ct); 3049 if (error == 0) { 3050 /* 3051 * Do the real rename work 3052 */ 3053 error = smbfsrename(odvp, ovp, ndvp, nnm, &scred, flags); 3054 VN_RELE(ovp); 3055 } 3056 3057 smb_credrele(&scred); 3058 smbfs_rw_exit(&odnp->r_rwlock); 3059 smbfs_rw_exit(&ndnp->r_rwlock); 3060 3061 return (error); 3062 } 3063 3064 /* 3065 * smbfsrename does the real work of renaming in SMBFS 3066 * Caller has done dir access checks etc. 3067 */ 3068 /* ARGSUSED */ 3069 static int 3070 smbfsrename(vnode_t *odvp, vnode_t *ovp, vnode_t *ndvp, char *nnm, 3071 struct smb_cred *scred, int flags) 3072 { 3073 smbnode_t *odnp = VTOSMB(odvp); 3074 smbnode_t *onp = VTOSMB(ovp); 3075 smbnode_t *ndnp = VTOSMB(ndvp); 3076 vnode_t *nvp = NULL; 3077 int error; 3078 int nvp_locked = 0; 3079 smb_fh_t *fid = NULL; 3080 3081 /* Things our caller should have checked. */ 3082 ASSERT(curproc->p_zone == VTOSMI(odvp)->smi_zone_ref.zref_zone); 3083 ASSERT(odvp->v_vfsp == ndvp->v_vfsp); 3084 ASSERT(odnp->r_rwlock.owner == curthread); 3085 ASSERT(ndnp->r_rwlock.owner == curthread); 3086 3087 /* 3088 * Lookup the target file. If it exists, it needs to be 3089 * checked to see whether it is a mount point and whether 3090 * it is active (open). 3091 */ 3092 error = smbfslookup(ndvp, nnm, &nvp, scred->scr_cred, 0, NULL); 3093 if (!error) { 3094 /* 3095 * Target (nvp) already exists. Check that it 3096 * has the same type as the source. The server 3097 * will check this also, (and more reliably) but 3098 * this lets us return the correct error codes. 3099 */ 3100 if (ovp->v_type == VDIR) { 3101 if (nvp->v_type != VDIR) { 3102 error = ENOTDIR; 3103 goto out; 3104 } 3105 } else { 3106 if (nvp->v_type == VDIR) { 3107 error = EISDIR; 3108 goto out; 3109 } 3110 } 3111 3112 /* 3113 * POSIX dictates that when the source and target 3114 * entries refer to the same file object, rename 3115 * must do nothing and exit without error. 3116 */ 3117 if (ovp == nvp) { 3118 error = 0; 3119 goto out; 3120 } 3121 3122 /* 3123 * Also must ensure the target is not a mount point, 3124 * and keep mount/umount away until we're done. 3125 */ 3126 if (vn_vfsrlock(nvp)) { 3127 error = EBUSY; 3128 goto out; 3129 } 3130 nvp_locked = 1; 3131 if (vn_mountedvfs(nvp) != NULL) { 3132 error = EBUSY; 3133 goto out; 3134 } 3135 3136 /* 3137 * CIFS may give a SHARING_VIOLATION error when 3138 * trying to rename onto an exising object, 3139 * so try to remove the target first. 3140 * (Only for files, not directories.) 3141 */ 3142 if (nvp->v_type == VDIR) { 3143 error = EEXIST; 3144 goto out; 3145 } 3146 error = smbfsremove(ndvp, nvp, scred, flags); 3147 if (error != 0) 3148 goto out; 3149 3150 /* 3151 * OK, removed the target file. Continue as if 3152 * lookup target had failed (nvp == NULL). 3153 */ 3154 vn_vfsunlock(nvp); 3155 nvp_locked = 0; 3156 VN_RELE(nvp); 3157 nvp = NULL; 3158 } /* nvp */ 3159 3160 /* 3161 * Get a file handle with delete access. 3162 * Close this FID before return. 3163 */ 3164 error = smbfs_smb_tmpopen(onp, STD_RIGHT_DELETE_ACCESS, 3165 scred, &fid); 3166 if (error) { 3167 SMBVDEBUG("error %d opening %s\n", 3168 error, onp->n_rpath); 3169 goto out; 3170 } 3171 3172 smbfs_attrcache_remove(onp); 3173 error = smbfs_smb_rename(odnp, onp, ndnp, nnm, strlen(nnm), 3174 fid, scred); 3175 3176 smbfs_smb_tmpclose(onp, fid); 3177 3178 /* 3179 * If the old name should no longer exist, 3180 * discard any cached attributes under it. 3181 */ 3182 if (error == 0) { 3183 smbfs_attrcache_prune(onp); 3184 /* SMBFS_VNEVENT... */ 3185 } 3186 3187 out: 3188 if (nvp) { 3189 if (nvp_locked) 3190 vn_vfsunlock(nvp); 3191 VN_RELE(nvp); 3192 } 3193 3194 return (error); 3195 } 3196 3197 /* 3198 * XXX 3199 * vsecattr_t is new to build 77, and we need to eventually support 3200 * it in order to create an ACL when an object is created. 3201 * 3202 * This op should support the new FIGNORECASE flag for case-insensitive 3203 * lookups, per PSARC 2007/244. 3204 */ 3205 /* ARGSUSED */ 3206 static int 3207 smbfs_mkdir(vnode_t *dvp, char *nm, struct vattr *va, vnode_t **vpp, 3208 cred_t *cr, caller_context_t *ct, int flags, vsecattr_t *vsecp) 3209 { 3210 vnode_t *vp; 3211 struct smbnode *dnp = VTOSMB(dvp); 3212 struct smbmntinfo *smi = VTOSMI(dvp); 3213 struct smb_cred scred; 3214 struct smbfattr fattr; 3215 const char *name = (const char *) nm; 3216 int nmlen = strlen(name); 3217 int error; 3218 3219 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 3220 return (EPERM); 3221 3222 if (smi->smi_flags & SMI_DEAD || dvp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 3223 return (EIO); 3224 3225 if ((nmlen == 1 && name[0] == '.') || 3226 (nmlen == 2 && name[0] == '.' && name[1] == '.')) 3227 return (EEXIST); 3228 3229 /* Only plain files are allowed in V_XATTRDIR. */ 3230 if (dvp->v_flag & V_XATTRDIR) 3231 return (EINVAL); 3232 3233 if (smbfs_rw_enter_sig(&dnp->r_rwlock, RW_WRITER, SMBINTR(dvp))) 3234 return (EINTR); 3235 smb_credinit(&scred, cr); 3236 3237 /* 3238 * Require write access in the containing directory. 3239 */ 3240 error = smbfs_access(dvp, VWRITE, 0, cr, ct); 3241 if (error) 3242 goto out; 3243 3244 error = smbfs_smb_mkdir(dnp, name, nmlen, &scred); 3245 if (error) 3246 goto out; 3247 3248 error = smbfs_smb_lookup(dnp, &name, &nmlen, &fattr, &scred); 3249 if (error) 3250 goto out; 3251 3252 smbfs_attr_touchdir(dnp); 3253 3254 error = smbfs_nget(dvp, name, nmlen, &fattr, &vp); 3255 if (error) 3256 goto out; 3257 3258 /* Success! */ 3259 *vpp = vp; 3260 error = 0; 3261 out: 3262 smb_credrele(&scred); 3263 smbfs_rw_exit(&dnp->r_rwlock); 3264 3265 if (name != nm) 3266 smbfs_name_free(name, nmlen); 3267 3268 return (error); 3269 } 3270 3271 /* 3272 * XXX 3273 * This op should support the new FIGNORECASE flag for case-insensitive 3274 * lookups, per PSARC 2007/244. 3275 */ 3276 /* ARGSUSED */ 3277 static int 3278 smbfs_rmdir(vnode_t *dvp, char *nm, vnode_t *cdir, cred_t *cr, 3279 caller_context_t *ct, int flags) 3280 { 3281 struct smb_cred scred; 3282 vnode_t *vp = NULL; 3283 int vp_locked = 0; 3284 struct smbmntinfo *smi = VTOSMI(dvp); 3285 struct smbnode *dnp = VTOSMB(dvp); 3286 struct smbnode *np; 3287 int error; 3288 3289 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 3290 return (EPERM); 3291 3292 if (smi->smi_flags & SMI_DEAD || dvp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 3293 return (EIO); 3294 3295 /* 3296 * Verify access to the dirctory. 3297 */ 3298 error = smbfs_access(dvp, VWRITE|VEXEC, 0, cr, ct); 3299 if (error) 3300 return (error); 3301 3302 if (smbfs_rw_enter_sig(&dnp->r_rwlock, RW_WRITER, SMBINTR(dvp))) 3303 return (EINTR); 3304 smb_credinit(&scred, cr); 3305 3306 /* 3307 * First lookup the entry to be removed. 3308 */ 3309 error = smbfslookup(dvp, nm, &vp, cr, 0, ct); 3310 if (error) 3311 goto out; 3312 np = VTOSMB(vp); 3313 3314 /* 3315 * Disallow rmdir of "." or current dir, or the FS root. 3316 * Also make sure it's a directory, not a mount point, 3317 * and lock to keep mount/umount away until we're done. 3318 */ 3319 if ((vp == dvp) || (vp == cdir) || (vp->v_flag & VROOT)) { 3320 error = EINVAL; 3321 goto out; 3322 } 3323 if (vp->v_type != VDIR) { 3324 error = ENOTDIR; 3325 goto out; 3326 } 3327 if (vn_vfsrlock(vp)) { 3328 error = EBUSY; 3329 goto out; 3330 } 3331 vp_locked = 1; 3332 if (vn_mountedvfs(vp) != NULL) { 3333 error = EBUSY; 3334 goto out; 3335 } 3336 3337 /* 3338 * Do the real rmdir work 3339 */ 3340 error = smbfsremove(dvp, vp, &scred, flags); 3341 if (error) 3342 goto out; 3343 3344 #ifdef SMBFS_VNEVENT 3345 vnevent_rmdir(vp, dvp, nm, ct); 3346 #endif 3347 3348 mutex_enter(&np->r_statelock); 3349 dnp->n_flag |= NMODIFIED; 3350 mutex_exit(&np->r_statelock); 3351 smbfs_attr_touchdir(dnp); 3352 smbfs_rmhash(np); 3353 3354 out: 3355 if (vp) { 3356 if (vp_locked) 3357 vn_vfsunlock(vp); 3358 VN_RELE(vp); 3359 } 3360 smb_credrele(&scred); 3361 smbfs_rw_exit(&dnp->r_rwlock); 3362 3363 return (error); 3364 } 3365 3366 3367 /* ARGSUSED */ 3368 static int 3369 smbfs_symlink(vnode_t *dvp, char *lnm, struct vattr *tva, char *tnm, cred_t *cr, 3370 caller_context_t *ct, int flags) 3371 { 3372 /* Not yet... */ 3373 return (ENOSYS); 3374 } 3375 3376 3377 /* ARGSUSED */ 3378 static int 3379 smbfs_readdir(vnode_t *vp, struct uio *uiop, cred_t *cr, int *eofp, 3380 caller_context_t *ct, int flags) 3381 { 3382 struct smbnode *np = VTOSMB(vp); 3383 int error = 0; 3384 smbmntinfo_t *smi; 3385 3386 smi = VTOSMI(vp); 3387 3388 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 3389 return (EIO); 3390 3391 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 3392 return (EIO); 3393 3394 /* 3395 * Require read access in the directory. 3396 */ 3397 error = smbfs_access(vp, VREAD, 0, cr, ct); 3398 if (error) 3399 return (error); 3400 3401 ASSERT(smbfs_rw_lock_held(&np->r_rwlock, RW_READER)); 3402 3403 /* 3404 * Todo readdir cache here 3405 * 3406 * I am serializing the entire readdir opreation 3407 * now since we have not yet implemented readdir 3408 * cache. This fix needs to be revisited once 3409 * we implement readdir cache. 3410 */ 3411 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, SMBINTR(vp))) 3412 return (EINTR); 3413 3414 error = smbfs_readvdir(vp, uiop, cr, eofp, ct); 3415 3416 smbfs_rw_exit(&np->r_lkserlock); 3417 3418 return (error); 3419 } 3420 3421 /* ARGSUSED */ 3422 static int 3423 smbfs_readvdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp, 3424 caller_context_t *ct) 3425 { 3426 /* 3427 * Note: "limit" tells the SMB-level FindFirst/FindNext 3428 * functions how many directory entries to request in 3429 * each OtW call. It needs to be large enough so that 3430 * we don't make lots of tiny OtW requests, but there's 3431 * no point making it larger than the maximum number of 3432 * OtW entries that would fit in a maximum sized trans2 3433 * response (64k / 48). Beyond that, it's just tuning. 3434 * WinNT used 512, Win2k used 1366. We use 1000. 3435 */ 3436 static const int limit = 1000; 3437 /* Largest possible dirent size. */ 3438 static const size_t dbufsiz = DIRENT64_RECLEN(SMB_MAXFNAMELEN); 3439 struct smb_cred scred; 3440 vnode_t *newvp; 3441 struct smbnode *np = VTOSMB(vp); 3442 struct smbfs_fctx *ctx; 3443 struct dirent64 *dp; 3444 ssize_t save_resid; 3445 offset_t save_offset; /* 64 bits */ 3446 int offset; /* yes, 32 bits */ 3447 int nmlen, error; 3448 ushort_t reclen; 3449 3450 ASSERT(curproc->p_zone == VTOSMI(vp)->smi_zone_ref.zref_zone); 3451 3452 /* Make sure we serialize for n_dirseq use. */ 3453 ASSERT(smbfs_rw_lock_held(&np->r_lkserlock, RW_WRITER)); 3454 3455 /* 3456 * Make sure smbfs_open filled in n_dirseq 3457 */ 3458 if (np->n_dirseq == NULL) 3459 return (EBADF); 3460 3461 /* Check for overflow of (32-bit) directory offset. */ 3462 if (uio->uio_loffset < 0 || uio->uio_loffset > INT32_MAX || 3463 (uio->uio_loffset + uio->uio_resid) > INT32_MAX) 3464 return (EINVAL); 3465 3466 /* Require space for at least one dirent. */ 3467 if (uio->uio_resid < dbufsiz) 3468 return (EINVAL); 3469 3470 SMBVDEBUG("dirname='%s'\n", np->n_rpath); 3471 smb_credinit(&scred, cr); 3472 dp = kmem_alloc(dbufsiz, KM_SLEEP); 3473 3474 save_resid = uio->uio_resid; 3475 save_offset = uio->uio_loffset; 3476 offset = uio->uio_offset; 3477 SMBVDEBUG("in: offset=%d, resid=%d\n", 3478 (int)uio->uio_offset, (int)uio->uio_resid); 3479 error = 0; 3480 3481 /* 3482 * Generate the "." and ".." entries here so we can 3483 * (1) make sure they appear (but only once), and 3484 * (2) deal with getting their I numbers which the 3485 * findnext below does only for normal names. 3486 */ 3487 while (offset < FIRST_DIROFS) { 3488 /* 3489 * Tricky bit filling in the first two: 3490 * offset 0 is ".", offset 1 is ".." 3491 * so strlen of these is offset+1. 3492 */ 3493 reclen = DIRENT64_RECLEN(offset + 1); 3494 if (uio->uio_resid < reclen) 3495 goto out; 3496 bzero(dp, reclen); 3497 dp->d_reclen = reclen; 3498 dp->d_name[0] = '.'; 3499 dp->d_name[1] = '.'; 3500 dp->d_name[offset + 1] = '\0'; 3501 /* 3502 * Want the real I-numbers for the "." and ".." 3503 * entries. For these two names, we know that 3504 * smbfslookup can get the nodes efficiently. 3505 */ 3506 error = smbfslookup(vp, dp->d_name, &newvp, cr, 1, ct); 3507 if (error) { 3508 dp->d_ino = np->n_ino + offset; /* fiction */ 3509 } else { 3510 dp->d_ino = VTOSMB(newvp)->n_ino; 3511 VN_RELE(newvp); 3512 } 3513 /* 3514 * Note: d_off is the offset that a user-level program 3515 * should seek to for reading the NEXT directory entry. 3516 * See libc: readdir, telldir, seekdir 3517 */ 3518 dp->d_off = offset + 1; 3519 error = uiomove(dp, reclen, UIO_READ, uio); 3520 if (error) 3521 goto out; 3522 /* 3523 * Note: uiomove updates uio->uio_offset, 3524 * but we want it to be our "cookie" value, 3525 * which just counts dirents ignoring size. 3526 */ 3527 uio->uio_offset = ++offset; 3528 } 3529 3530 /* 3531 * If there was a backward seek, we have to reopen. 3532 */ 3533 if (offset < np->n_dirofs) { 3534 SMBVDEBUG("Reopening search %d:%d\n", 3535 offset, np->n_dirofs); 3536 error = smbfs_smb_findopen(np, "*", 1, 3537 SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR, 3538 &scred, &ctx); 3539 if (error) { 3540 SMBVDEBUG("can not open search, error = %d", error); 3541 goto out; 3542 } 3543 /* free the old one */ 3544 (void) smbfs_smb_findclose(np->n_dirseq, &scred); 3545 /* save the new one */ 3546 np->n_dirseq = ctx; 3547 np->n_dirofs = FIRST_DIROFS; 3548 } else { 3549 ctx = np->n_dirseq; 3550 } 3551 3552 /* 3553 * Skip entries before the requested offset. 3554 */ 3555 while (np->n_dirofs < offset) { 3556 error = smbfs_smb_findnext(ctx, limit, &scred); 3557 if (error != 0) 3558 goto out; 3559 np->n_dirofs++; 3560 } 3561 3562 /* 3563 * While there's room in the caller's buffer: 3564 * get a directory entry from SMB, 3565 * convert to a dirent, copyout. 3566 * We stop when there is no longer room for a 3567 * maximum sized dirent because we must decide 3568 * before we know anything about the next entry. 3569 */ 3570 while (uio->uio_resid >= dbufsiz) { 3571 error = smbfs_smb_findnext(ctx, limit, &scred); 3572 if (error != 0) 3573 goto out; 3574 np->n_dirofs++; 3575 3576 /* Sanity check the name length. */ 3577 nmlen = ctx->f_nmlen; 3578 if (nmlen > SMB_MAXFNAMELEN) { 3579 nmlen = SMB_MAXFNAMELEN; 3580 SMBVDEBUG("Truncating name: %s\n", ctx->f_name); 3581 } 3582 if (smbfs_fastlookup) { 3583 /* See comment at smbfs_fastlookup above. */ 3584 if (smbfs_nget(vp, ctx->f_name, nmlen, 3585 &ctx->f_attr, &newvp) == 0) 3586 VN_RELE(newvp); 3587 } 3588 3589 reclen = DIRENT64_RECLEN(nmlen); 3590 bzero(dp, reclen); 3591 dp->d_reclen = reclen; 3592 bcopy(ctx->f_name, dp->d_name, nmlen); 3593 dp->d_name[nmlen] = '\0'; 3594 dp->d_ino = ctx->f_inum; 3595 dp->d_off = offset + 1; /* See d_off comment above */ 3596 error = uiomove(dp, reclen, UIO_READ, uio); 3597 if (error) 3598 goto out; 3599 /* See comment re. uio_offset above. */ 3600 uio->uio_offset = ++offset; 3601 } 3602 3603 out: 3604 /* 3605 * When we come to the end of a directory, the 3606 * SMB-level functions return ENOENT, but the 3607 * caller is not expecting an error return. 3608 * 3609 * Also note that we must delay the call to 3610 * smbfs_smb_findclose(np->n_dirseq, ...) 3611 * until smbfs_close so that all reads at the 3612 * end of the directory will return no data. 3613 */ 3614 if (error == ENOENT) { 3615 error = 0; 3616 if (eofp) 3617 *eofp = 1; 3618 } 3619 /* 3620 * If we encountered an error (i.e. "access denied") 3621 * from the FindFirst call, we will have copied out 3622 * the "." and ".." entries leaving offset == 2. 3623 * In that case, restore the original offset/resid 3624 * so the caller gets no data with the error. 3625 */ 3626 if (error != 0 && offset == FIRST_DIROFS) { 3627 uio->uio_loffset = save_offset; 3628 uio->uio_resid = save_resid; 3629 } 3630 SMBVDEBUG("out: offset=%d, resid=%d\n", 3631 (int)uio->uio_offset, (int)uio->uio_resid); 3632 3633 kmem_free(dp, dbufsiz); 3634 smb_credrele(&scred); 3635 return (error); 3636 } 3637 3638 /* 3639 * Here NFS has: nfs3_bio 3640 * See smbfs_bio above. 3641 */ 3642 3643 /* ARGSUSED */ 3644 static int 3645 smbfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct) 3646 { 3647 return (ENOSYS); 3648 } 3649 3650 3651 /* 3652 * The pair of functions VOP_RWLOCK, VOP_RWUNLOCK 3653 * are optional functions that are called by: 3654 * getdents, before/after VOP_READDIR 3655 * pread, before/after ... VOP_READ 3656 * pwrite, before/after ... VOP_WRITE 3657 * (other places) 3658 * 3659 * Careful here: None of the above check for any 3660 * error returns from VOP_RWLOCK / VOP_RWUNLOCK! 3661 * In fact, the return value from _rwlock is NOT 3662 * an error code, but V_WRITELOCK_TRUE / _FALSE. 3663 * 3664 * Therefore, it's up to _this_ code to make sure 3665 * the lock state remains balanced, which means 3666 * we can't "bail out" on interrupts, etc. 3667 */ 3668 3669 /* ARGSUSED2 */ 3670 static int 3671 smbfs_rwlock(vnode_t *vp, int write_lock, caller_context_t *ctp) 3672 { 3673 smbnode_t *np = VTOSMB(vp); 3674 3675 if (!write_lock) { 3676 (void) smbfs_rw_enter_sig(&np->r_rwlock, RW_READER, FALSE); 3677 return (V_WRITELOCK_FALSE); 3678 } 3679 3680 3681 (void) smbfs_rw_enter_sig(&np->r_rwlock, RW_WRITER, FALSE); 3682 return (V_WRITELOCK_TRUE); 3683 } 3684 3685 /* ARGSUSED */ 3686 static void 3687 smbfs_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ctp) 3688 { 3689 smbnode_t *np = VTOSMB(vp); 3690 3691 smbfs_rw_exit(&np->r_rwlock); 3692 } 3693 3694 3695 /* ARGSUSED */ 3696 static int 3697 smbfs_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct) 3698 { 3699 smbmntinfo_t *smi; 3700 3701 smi = VTOSMI(vp); 3702 3703 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 3704 return (EPERM); 3705 3706 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 3707 return (EIO); 3708 3709 /* 3710 * Because we stuff the readdir cookie into the offset field 3711 * someone may attempt to do an lseek with the cookie which 3712 * we want to succeed. 3713 */ 3714 if (vp->v_type == VDIR) 3715 return (0); 3716 3717 /* Like NFS3, just check for 63-bit overflow. */ 3718 if (*noffp < 0) 3719 return (EINVAL); 3720 3721 return (0); 3722 } 3723 3724 /* mmap support ******************************************************** */ 3725 3726 #ifdef _KERNEL 3727 3728 #ifdef DEBUG 3729 static int smbfs_lostpage = 0; /* number of times we lost original page */ 3730 #endif 3731 3732 /* 3733 * Return all the pages from [off..off+len) in file 3734 * Like nfs3_getpage 3735 */ 3736 /* ARGSUSED */ 3737 static int 3738 smbfs_getpage(vnode_t *vp, offset_t off, size_t len, uint_t *protp, 3739 page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr, 3740 enum seg_rw rw, cred_t *cr, caller_context_t *ct) 3741 { 3742 smbnode_t *np; 3743 smbmntinfo_t *smi; 3744 int error; 3745 3746 np = VTOSMB(vp); 3747 smi = VTOSMI(vp); 3748 3749 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 3750 return (EIO); 3751 3752 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 3753 return (EIO); 3754 3755 if (vp->v_flag & VNOMAP) 3756 return (ENOSYS); 3757 3758 if (protp != NULL) 3759 *protp = PROT_ALL; 3760 3761 /* 3762 * Now valididate that the caches are up to date. 3763 */ 3764 error = smbfs_validate_caches(vp, cr); 3765 if (error) 3766 return (error); 3767 3768 retry: 3769 mutex_enter(&np->r_statelock); 3770 3771 /* 3772 * Don't create dirty pages faster than they 3773 * can be cleaned ... (etc. see nfs) 3774 * 3775 * Here NFS also tests: 3776 * (mi->mi_max_threads != 0 && 3777 * rp->r_awcount > 2 * mi->mi_max_threads) 3778 */ 3779 if (rw == S_CREATE) { 3780 while (np->r_gcount > 0) 3781 cv_wait(&np->r_cv, &np->r_statelock); 3782 } 3783 3784 /* 3785 * If we are getting called as a side effect of a write 3786 * operation the local file size might not be extended yet. 3787 * In this case we want to be able to return pages of zeroes. 3788 */ 3789 if (off + len > np->r_size + PAGEOFFSET && seg != segkmap) { 3790 mutex_exit(&np->r_statelock); 3791 return (EFAULT); /* beyond EOF */ 3792 } 3793 3794 mutex_exit(&np->r_statelock); 3795 3796 error = pvn_getpages(smbfs_getapage, vp, off, len, protp, 3797 pl, plsz, seg, addr, rw, cr); 3798 3799 switch (error) { 3800 case SMBFS_EOF: 3801 smbfs_purge_caches(vp, cr); 3802 goto retry; 3803 case ESTALE: 3804 /* 3805 * Here NFS has: PURGE_STALE_FH(error, vp, cr); 3806 * In-line here as we only use it once. 3807 */ 3808 mutex_enter(&np->r_statelock); 3809 np->r_flags |= RSTALE; 3810 if (!np->r_error) 3811 np->r_error = (error); 3812 mutex_exit(&np->r_statelock); 3813 if (vn_has_cached_data(vp)) 3814 smbfs_invalidate_pages(vp, (u_offset_t)0, cr); 3815 smbfs_purge_caches(vp, cr); 3816 break; 3817 default: 3818 break; 3819 } 3820 3821 return (error); 3822 } 3823 3824 /* 3825 * Called from pvn_getpages to get a particular page. 3826 * Like nfs3_getapage 3827 */ 3828 /* ARGSUSED */ 3829 static int 3830 smbfs_getapage(vnode_t *vp, u_offset_t off, size_t len, uint_t *protp, 3831 page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr, 3832 enum seg_rw rw, cred_t *cr) 3833 { 3834 smbnode_t *np; 3835 smbmntinfo_t *smi; 3836 3837 uint_t bsize; 3838 struct buf *bp; 3839 page_t *pp; 3840 u_offset_t lbn; 3841 u_offset_t io_off; 3842 u_offset_t blkoff; 3843 size_t io_len; 3844 uint_t blksize; 3845 int error; 3846 /* int readahead; */ 3847 int readahead_issued = 0; 3848 /* int ra_window; * readahead window */ 3849 page_t *pagefound; 3850 3851 np = VTOSMB(vp); 3852 smi = VTOSMI(vp); 3853 3854 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 3855 return (EIO); 3856 3857 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 3858 return (EIO); 3859 3860 bsize = MAX(vp->v_vfsp->vfs_bsize, PAGESIZE); 3861 3862 reread: 3863 bp = NULL; 3864 pp = NULL; 3865 pagefound = NULL; 3866 3867 if (pl != NULL) 3868 pl[0] = NULL; 3869 3870 error = 0; 3871 lbn = off / bsize; 3872 blkoff = lbn * bsize; 3873 3874 /* 3875 * NFS queues up readahead work here. 3876 */ 3877 3878 again: 3879 if ((pagefound = page_exists(vp, off)) == NULL) { 3880 if (pl == NULL) { 3881 (void) 0; /* Todo: smbfs_async_readahead(); */ 3882 } else if (rw == S_CREATE) { 3883 /* 3884 * Block for this page is not allocated, or the offset 3885 * is beyond the current allocation size, or we're 3886 * allocating a swap slot and the page was not found, 3887 * so allocate it and return a zero page. 3888 */ 3889 if ((pp = page_create_va(vp, off, 3890 PAGESIZE, PG_WAIT, seg, addr)) == NULL) 3891 cmn_err(CE_PANIC, "smbfs_getapage: page_create"); 3892 io_len = PAGESIZE; 3893 mutex_enter(&np->r_statelock); 3894 np->r_nextr = off + PAGESIZE; 3895 mutex_exit(&np->r_statelock); 3896 } else { 3897 /* 3898 * Need to go to server to get a BLOCK, exception to 3899 * that being while reading at offset = 0 or doing 3900 * random i/o, in that case read only a PAGE. 3901 */ 3902 mutex_enter(&np->r_statelock); 3903 if (blkoff < np->r_size && 3904 blkoff + bsize >= np->r_size) { 3905 /* 3906 * If only a block or less is left in 3907 * the file, read all that is remaining. 3908 */ 3909 if (np->r_size <= off) { 3910 /* 3911 * Trying to access beyond EOF, 3912 * set up to get at least one page. 3913 */ 3914 blksize = off + PAGESIZE - blkoff; 3915 } else 3916 blksize = np->r_size - blkoff; 3917 } else if ((off == 0) || 3918 (off != np->r_nextr && !readahead_issued)) { 3919 blksize = PAGESIZE; 3920 blkoff = off; /* block = page here */ 3921 } else 3922 blksize = bsize; 3923 mutex_exit(&np->r_statelock); 3924 3925 pp = pvn_read_kluster(vp, off, seg, addr, &io_off, 3926 &io_len, blkoff, blksize, 0); 3927 3928 /* 3929 * Some other thread has entered the page, 3930 * so just use it. 3931 */ 3932 if (pp == NULL) 3933 goto again; 3934 3935 /* 3936 * Now round the request size up to page boundaries. 3937 * This ensures that the entire page will be 3938 * initialized to zeroes if EOF is encountered. 3939 */ 3940 io_len = ptob(btopr(io_len)); 3941 3942 bp = pageio_setup(pp, io_len, vp, B_READ); 3943 ASSERT(bp != NULL); 3944 3945 /* 3946 * pageio_setup should have set b_addr to 0. This 3947 * is correct since we want to do I/O on a page 3948 * boundary. bp_mapin will use this addr to calculate 3949 * an offset, and then set b_addr to the kernel virtual 3950 * address it allocated for us. 3951 */ 3952 ASSERT(bp->b_un.b_addr == 0); 3953 3954 bp->b_edev = 0; 3955 bp->b_dev = 0; 3956 bp->b_lblkno = lbtodb(io_off); 3957 bp->b_file = vp; 3958 bp->b_offset = (offset_t)off; 3959 bp_mapin(bp); 3960 3961 /* 3962 * If doing a write beyond what we believe is EOF, 3963 * don't bother trying to read the pages from the 3964 * server, we'll just zero the pages here. We 3965 * don't check that the rw flag is S_WRITE here 3966 * because some implementations may attempt a 3967 * read access to the buffer before copying data. 3968 */ 3969 mutex_enter(&np->r_statelock); 3970 if (io_off >= np->r_size && seg == segkmap) { 3971 mutex_exit(&np->r_statelock); 3972 bzero(bp->b_un.b_addr, io_len); 3973 } else { 3974 mutex_exit(&np->r_statelock); 3975 error = smbfs_bio(bp, 0, cr); 3976 } 3977 3978 /* 3979 * Unmap the buffer before freeing it. 3980 */ 3981 bp_mapout(bp); 3982 pageio_done(bp); 3983 3984 /* Here NFS3 updates all pp->p_fsdata */ 3985 3986 if (error == SMBFS_EOF) { 3987 /* 3988 * If doing a write system call just return 3989 * zeroed pages, else user tried to get pages 3990 * beyond EOF, return error. We don't check 3991 * that the rw flag is S_WRITE here because 3992 * some implementations may attempt a read 3993 * access to the buffer before copying data. 3994 */ 3995 if (seg == segkmap) 3996 error = 0; 3997 else 3998 error = EFAULT; 3999 } 4000 4001 if (!readahead_issued && !error) { 4002 mutex_enter(&np->r_statelock); 4003 np->r_nextr = io_off + io_len; 4004 mutex_exit(&np->r_statelock); 4005 } 4006 } 4007 } 4008 4009 if (pl == NULL) 4010 return (error); 4011 4012 if (error) { 4013 if (pp != NULL) 4014 pvn_read_done(pp, B_ERROR); 4015 return (error); 4016 } 4017 4018 if (pagefound) { 4019 se_t se = (rw == S_CREATE ? SE_EXCL : SE_SHARED); 4020 4021 /* 4022 * Page exists in the cache, acquire the appropriate lock. 4023 * If this fails, start all over again. 4024 */ 4025 if ((pp = page_lookup(vp, off, se)) == NULL) { 4026 #ifdef DEBUG 4027 smbfs_lostpage++; 4028 #endif 4029 goto reread; 4030 } 4031 pl[0] = pp; 4032 pl[1] = NULL; 4033 return (0); 4034 } 4035 4036 if (pp != NULL) 4037 pvn_plist_init(pp, pl, plsz, off, io_len, rw); 4038 4039 return (error); 4040 } 4041 4042 /* 4043 * Here NFS has: nfs3_readahead 4044 * No read-ahead in smbfs yet. 4045 */ 4046 4047 #endif // _KERNEL 4048 4049 /* 4050 * Flags are composed of {B_INVAL, B_FREE, B_DONTNEED, B_FORCE} 4051 * If len == 0, do from off to EOF. 4052 * 4053 * The normal cases should be len == 0 && off == 0 (entire vp list), 4054 * len == MAXBSIZE (from segmap_release actions), and len == PAGESIZE 4055 * (from pageout). 4056 * 4057 * Like nfs3_putpage + nfs_putpages 4058 */ 4059 /* ARGSUSED */ 4060 static int 4061 smbfs_putpage(vnode_t *vp, offset_t off, size_t len, int flags, cred_t *cr, 4062 caller_context_t *ct) 4063 { 4064 #ifdef _KERNEL 4065 smbnode_t *np; 4066 smbmntinfo_t *smi; 4067 page_t *pp; 4068 u_offset_t eoff; 4069 u_offset_t io_off; 4070 size_t io_len; 4071 int error; 4072 int rdirty; 4073 int err; 4074 4075 np = VTOSMB(vp); 4076 smi = VTOSMI(vp); 4077 4078 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 4079 return (EIO); 4080 4081 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 4082 return (EIO); 4083 4084 if (vp->v_flag & VNOMAP) 4085 return (ENOSYS); 4086 4087 /* Here NFS does rp->r_count (++/--) stuff. */ 4088 4089 /* Beginning of code from nfs_putpages. */ 4090 4091 if (!vn_has_cached_data(vp)) 4092 return (0); 4093 4094 /* 4095 * If ROUTOFSPACE is set, then all writes turn into B_INVAL 4096 * writes. B_FORCE is set to force the VM system to actually 4097 * invalidate the pages, even if the i/o failed. The pages 4098 * need to get invalidated because they can't be written out 4099 * because there isn't any space left on either the server's 4100 * file system or in the user's disk quota. The B_FREE bit 4101 * is cleared to avoid confusion as to whether this is a 4102 * request to place the page on the freelist or to destroy 4103 * it. 4104 */ 4105 if ((np->r_flags & ROUTOFSPACE) || 4106 (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)) 4107 flags = (flags & ~B_FREE) | B_INVAL | B_FORCE; 4108 4109 if (len == 0) { 4110 /* 4111 * If doing a full file synchronous operation, then clear 4112 * the RDIRTY bit. If a page gets dirtied while the flush 4113 * is happening, then RDIRTY will get set again. The 4114 * RDIRTY bit must get cleared before the flush so that 4115 * we don't lose this information. 4116 * 4117 * NFS has B_ASYNC vs sync stuff here. 4118 */ 4119 if (off == (u_offset_t)0 && 4120 (np->r_flags & RDIRTY)) { 4121 mutex_enter(&np->r_statelock); 4122 rdirty = (np->r_flags & RDIRTY); 4123 np->r_flags &= ~RDIRTY; 4124 mutex_exit(&np->r_statelock); 4125 } else 4126 rdirty = 0; 4127 4128 /* 4129 * Search the entire vp list for pages >= off, and flush 4130 * the dirty pages. 4131 */ 4132 error = pvn_vplist_dirty(vp, off, smbfs_putapage, 4133 flags, cr); 4134 4135 /* 4136 * If an error occurred and the file was marked as dirty 4137 * before and we aren't forcibly invalidating pages, then 4138 * reset the RDIRTY flag. 4139 */ 4140 if (error && rdirty && 4141 (flags & (B_INVAL | B_FORCE)) != (B_INVAL | B_FORCE)) { 4142 mutex_enter(&np->r_statelock); 4143 np->r_flags |= RDIRTY; 4144 mutex_exit(&np->r_statelock); 4145 } 4146 } else { 4147 /* 4148 * Do a range from [off...off + len) looking for pages 4149 * to deal with. 4150 */ 4151 error = 0; 4152 io_len = 1; /* quiet warnings */ 4153 eoff = off + len; 4154 4155 for (io_off = off; io_off < eoff; io_off += io_len) { 4156 mutex_enter(&np->r_statelock); 4157 if (io_off >= np->r_size) { 4158 mutex_exit(&np->r_statelock); 4159 break; 4160 } 4161 mutex_exit(&np->r_statelock); 4162 /* 4163 * If we are not invalidating, synchronously 4164 * freeing or writing pages use the routine 4165 * page_lookup_nowait() to prevent reclaiming 4166 * them from the free list. 4167 */ 4168 if ((flags & B_INVAL) || !(flags & B_ASYNC)) { 4169 pp = page_lookup(vp, io_off, 4170 (flags & (B_INVAL | B_FREE)) ? 4171 SE_EXCL : SE_SHARED); 4172 } else { 4173 pp = page_lookup_nowait(vp, io_off, 4174 (flags & B_FREE) ? SE_EXCL : SE_SHARED); 4175 } 4176 4177 if (pp == NULL || !pvn_getdirty(pp, flags)) 4178 io_len = PAGESIZE; 4179 else { 4180 err = smbfs_putapage(vp, pp, &io_off, 4181 &io_len, flags, cr); 4182 if (!error) 4183 error = err; 4184 /* 4185 * "io_off" and "io_len" are returned as 4186 * the range of pages we actually wrote. 4187 * This allows us to skip ahead more quickly 4188 * since several pages may've been dealt 4189 * with by this iteration of the loop. 4190 */ 4191 } 4192 } 4193 } 4194 4195 return (error); 4196 4197 #else // _KERNEL 4198 return (ENOSYS); 4199 #endif // _KERNEL 4200 } 4201 4202 #ifdef _KERNEL 4203 4204 /* 4205 * Write out a single page, possibly klustering adjacent dirty pages. 4206 * 4207 * Like nfs3_putapage / nfs3_sync_putapage 4208 */ 4209 static int 4210 smbfs_putapage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp, 4211 int flags, cred_t *cr) 4212 { 4213 smbnode_t *np; 4214 u_offset_t io_off; 4215 u_offset_t lbn_off; 4216 u_offset_t lbn; 4217 size_t io_len; 4218 uint_t bsize; 4219 int error; 4220 4221 np = VTOSMB(vp); 4222 4223 ASSERT(!vn_is_readonly(vp)); 4224 4225 bsize = MAX(vp->v_vfsp->vfs_bsize, PAGESIZE); 4226 lbn = pp->p_offset / bsize; 4227 lbn_off = lbn * bsize; 4228 4229 /* 4230 * Find a kluster that fits in one block, or in 4231 * one page if pages are bigger than blocks. If 4232 * there is less file space allocated than a whole 4233 * page, we'll shorten the i/o request below. 4234 */ 4235 pp = pvn_write_kluster(vp, pp, &io_off, &io_len, lbn_off, 4236 roundup(bsize, PAGESIZE), flags); 4237 4238 /* 4239 * pvn_write_kluster shouldn't have returned a page with offset 4240 * behind the original page we were given. Verify that. 4241 */ 4242 ASSERT((pp->p_offset / bsize) >= lbn); 4243 4244 /* 4245 * Now pp will have the list of kept dirty pages marked for 4246 * write back. It will also handle invalidation and freeing 4247 * of pages that are not dirty. Check for page length rounding 4248 * problems. 4249 */ 4250 if (io_off + io_len > lbn_off + bsize) { 4251 ASSERT((io_off + io_len) - (lbn_off + bsize) < PAGESIZE); 4252 io_len = lbn_off + bsize - io_off; 4253 } 4254 /* 4255 * The RMODINPROGRESS flag makes sure that smbfs_bio() sees a 4256 * consistent value of r_size. RMODINPROGRESS is set in writerp(). 4257 * When RMODINPROGRESS is set it indicates that a uiomove() is in 4258 * progress and the r_size has not been made consistent with the 4259 * new size of the file. When the uiomove() completes the r_size is 4260 * updated and the RMODINPROGRESS flag is cleared. 4261 * 4262 * The RMODINPROGRESS flag makes sure that smbfs_bio() sees a 4263 * consistent value of r_size. Without this handshaking, it is 4264 * possible that smbfs_bio() picks up the old value of r_size 4265 * before the uiomove() in writerp() completes. This will result 4266 * in the write through smbfs_bio() being dropped. 4267 * 4268 * More precisely, there is a window between the time the uiomove() 4269 * completes and the time the r_size is updated. If a VOP_PUTPAGE() 4270 * operation intervenes in this window, the page will be picked up, 4271 * because it is dirty (it will be unlocked, unless it was 4272 * pagecreate'd). When the page is picked up as dirty, the dirty 4273 * bit is reset (pvn_getdirty()). In smbfs_write(), r_size is 4274 * checked. This will still be the old size. Therefore the page will 4275 * not be written out. When segmap_release() calls VOP_PUTPAGE(), 4276 * the page will be found to be clean and the write will be dropped. 4277 */ 4278 if (np->r_flags & RMODINPROGRESS) { 4279 mutex_enter(&np->r_statelock); 4280 if ((np->r_flags & RMODINPROGRESS) && 4281 np->r_modaddr + MAXBSIZE > io_off && 4282 np->r_modaddr < io_off + io_len) { 4283 page_t *plist; 4284 /* 4285 * A write is in progress for this region of the file. 4286 * If we did not detect RMODINPROGRESS here then this 4287 * path through smbfs_putapage() would eventually go to 4288 * smbfs_bio() and may not write out all of the data 4289 * in the pages. We end up losing data. So we decide 4290 * to set the modified bit on each page in the page 4291 * list and mark the rnode with RDIRTY. This write 4292 * will be restarted at some later time. 4293 */ 4294 plist = pp; 4295 while (plist != NULL) { 4296 pp = plist; 4297 page_sub(&plist, pp); 4298 hat_setmod(pp); 4299 page_io_unlock(pp); 4300 page_unlock(pp); 4301 } 4302 np->r_flags |= RDIRTY; 4303 mutex_exit(&np->r_statelock); 4304 if (offp) 4305 *offp = io_off; 4306 if (lenp) 4307 *lenp = io_len; 4308 return (0); 4309 } 4310 mutex_exit(&np->r_statelock); 4311 } 4312 4313 /* 4314 * NFS handles (flags & B_ASYNC) here... 4315 * (See nfs_async_putapage()) 4316 * 4317 * This code section from: nfs3_sync_putapage() 4318 */ 4319 4320 flags |= B_WRITE; 4321 4322 error = smbfs_rdwrlbn(vp, pp, io_off, io_len, flags, cr); 4323 4324 if ((error == ENOSPC || error == EDQUOT || error == EFBIG || 4325 error == EACCES) && 4326 (flags & (B_INVAL|B_FORCE)) != (B_INVAL|B_FORCE)) { 4327 if (!(np->r_flags & ROUTOFSPACE)) { 4328 mutex_enter(&np->r_statelock); 4329 np->r_flags |= ROUTOFSPACE; 4330 mutex_exit(&np->r_statelock); 4331 } 4332 flags |= B_ERROR; 4333 pvn_write_done(pp, flags); 4334 /* 4335 * If this was not an async thread, then try again to 4336 * write out the pages, but this time, also destroy 4337 * them whether or not the write is successful. This 4338 * will prevent memory from filling up with these 4339 * pages and destroying them is the only alternative 4340 * if they can't be written out. 4341 * 4342 * Don't do this if this is an async thread because 4343 * when the pages are unlocked in pvn_write_done, 4344 * some other thread could have come along, locked 4345 * them, and queued for an async thread. It would be 4346 * possible for all of the async threads to be tied 4347 * up waiting to lock the pages again and they would 4348 * all already be locked and waiting for an async 4349 * thread to handle them. Deadlock. 4350 */ 4351 if (!(flags & B_ASYNC)) { 4352 error = smbfs_putpage(vp, io_off, io_len, 4353 B_INVAL | B_FORCE, cr, NULL); 4354 } 4355 } else { 4356 if (error) 4357 flags |= B_ERROR; 4358 else if (np->r_flags & ROUTOFSPACE) { 4359 mutex_enter(&np->r_statelock); 4360 np->r_flags &= ~ROUTOFSPACE; 4361 mutex_exit(&np->r_statelock); 4362 } 4363 pvn_write_done(pp, flags); 4364 } 4365 4366 /* Now more code from: nfs3_putapage */ 4367 4368 if (offp) 4369 *offp = io_off; 4370 if (lenp) 4371 *lenp = io_len; 4372 4373 return (error); 4374 } 4375 4376 #endif // _KERNEL 4377 4378 4379 /* 4380 * NFS has this in nfs_client.c (shared by v2,v3,...) 4381 * We have it here so smbfs_putapage can be file scope. 4382 */ 4383 void 4384 smbfs_invalidate_pages(vnode_t *vp, u_offset_t off, cred_t *cr) 4385 { 4386 smbnode_t *np; 4387 4388 np = VTOSMB(vp); 4389 4390 mutex_enter(&np->r_statelock); 4391 while (np->r_flags & RTRUNCATE) 4392 cv_wait(&np->r_cv, &np->r_statelock); 4393 np->r_flags |= RTRUNCATE; 4394 4395 if (off == (u_offset_t)0) { 4396 np->r_flags &= ~RDIRTY; 4397 if (!(np->r_flags & RSTALE)) 4398 np->r_error = 0; 4399 } 4400 /* Here NFSv3 has np->r_truncaddr = off; */ 4401 mutex_exit(&np->r_statelock); 4402 4403 #ifdef _KERNEL 4404 (void) pvn_vplist_dirty(vp, off, smbfs_putapage, 4405 B_INVAL | B_TRUNC, cr); 4406 #endif // _KERNEL 4407 4408 mutex_enter(&np->r_statelock); 4409 np->r_flags &= ~RTRUNCATE; 4410 cv_broadcast(&np->r_cv); 4411 mutex_exit(&np->r_statelock); 4412 } 4413 4414 #ifdef _KERNEL 4415 4416 /* Like nfs3_map */ 4417 4418 /* ARGSUSED */ 4419 static int 4420 smbfs_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp, 4421 size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, 4422 cred_t *cr, caller_context_t *ct) 4423 { 4424 segvn_crargs_t vn_a; 4425 struct vattr va; 4426 smbnode_t *np; 4427 smbmntinfo_t *smi; 4428 int error; 4429 4430 np = VTOSMB(vp); 4431 smi = VTOSMI(vp); 4432 4433 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 4434 return (EIO); 4435 4436 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 4437 return (EIO); 4438 4439 /* Sanity check: should have a valid open */ 4440 if (np->n_fid == NULL) 4441 return (EIO); 4442 4443 if (vp->v_flag & VNOMAP) 4444 return (ENOSYS); 4445 4446 if (off < 0 || off + (ssize_t)len < 0) 4447 return (ENXIO); 4448 4449 if (vp->v_type != VREG) 4450 return (ENODEV); 4451 4452 /* 4453 * NFS does close-to-open consistency stuff here. 4454 * Just get (possibly cached) attributes. 4455 */ 4456 va.va_mask = AT_ALL; 4457 if ((error = smbfsgetattr(vp, &va, cr)) != 0) 4458 return (error); 4459 4460 /* 4461 * Check to see if the vnode is currently marked as not cachable. 4462 * This means portions of the file are locked (through VOP_FRLOCK). 4463 * In this case the map request must be refused. We use 4464 * rp->r_lkserlock to avoid a race with concurrent lock requests. 4465 */ 4466 /* 4467 * Atomically increment r_inmap after acquiring r_rwlock. The 4468 * idea here is to acquire r_rwlock to block read/write and 4469 * not to protect r_inmap. r_inmap will inform smbfs_read/write() 4470 * that we are in smbfs_map(). Now, r_rwlock is acquired in order 4471 * and we can prevent the deadlock that would have occurred 4472 * when smbfs_addmap() would have acquired it out of order. 4473 * 4474 * Since we are not protecting r_inmap by any lock, we do not 4475 * hold any lock when we decrement it. We atomically decrement 4476 * r_inmap after we release r_lkserlock. Note that rwlock is 4477 * re-entered as writer in smbfs_addmap (called via as_map). 4478 */ 4479 4480 if (smbfs_rw_enter_sig(&np->r_rwlock, RW_WRITER, SMBINTR(vp))) 4481 return (EINTR); 4482 atomic_inc_uint(&np->r_inmap); 4483 smbfs_rw_exit(&np->r_rwlock); 4484 4485 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, SMBINTR(vp))) { 4486 atomic_dec_uint(&np->r_inmap); 4487 return (EINTR); 4488 } 4489 4490 if (vp->v_flag & VNOCACHE) { 4491 error = EAGAIN; 4492 goto done; 4493 } 4494 4495 /* 4496 * Don't allow concurrent locks and mapping if mandatory locking is 4497 * enabled. 4498 */ 4499 if ((flk_has_remote_locks(vp) || smbfs_lm_has_sleep(vp)) && 4500 MANDLOCK(vp, va.va_mode)) { 4501 error = EAGAIN; 4502 goto done; 4503 } 4504 4505 as_rangelock(as); 4506 error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); 4507 if (error != 0) { 4508 as_rangeunlock(as); 4509 goto done; 4510 } 4511 4512 vn_a.vp = vp; 4513 vn_a.offset = off; 4514 vn_a.type = (flags & MAP_TYPE); 4515 vn_a.prot = (uchar_t)prot; 4516 vn_a.maxprot = (uchar_t)maxprot; 4517 vn_a.flags = (flags & ~MAP_TYPE); 4518 vn_a.cred = cr; 4519 vn_a.amp = NULL; 4520 vn_a.szc = 0; 4521 vn_a.lgrp_mem_policy_flags = 0; 4522 4523 error = as_map(as, *addrp, len, segvn_create, &vn_a); 4524 as_rangeunlock(as); 4525 4526 done: 4527 smbfs_rw_exit(&np->r_lkserlock); 4528 atomic_dec_uint(&np->r_inmap); 4529 return (error); 4530 } 4531 4532 /* 4533 * This uses addmap/delmap functions to hold the SMB FID open as long as 4534 * there are pages mapped in this as/seg. Increment the FID refs. when 4535 * the maping count goes from zero to non-zero, and release the FID ref 4536 * when the maping count goes from non-zero to zero. 4537 */ 4538 4539 /* ARGSUSED */ 4540 static int 4541 smbfs_addmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr, 4542 size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, 4543 cred_t *cr, caller_context_t *ct) 4544 { 4545 smbnode_t *np = VTOSMB(vp); 4546 boolean_t inc_fidrefs = B_FALSE; 4547 4548 /* 4549 * When r_mapcnt goes from zero to non-zero, 4550 * increment n_fidrefs 4551 */ 4552 mutex_enter(&np->r_statelock); 4553 if (np->r_mapcnt == 0) 4554 inc_fidrefs = B_TRUE; 4555 np->r_mapcnt += btopr(len); 4556 mutex_exit(&np->r_statelock); 4557 4558 if (inc_fidrefs) { 4559 (void) smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, 0); 4560 np->n_fidrefs++; 4561 smbfs_rw_exit(&np->r_lkserlock); 4562 } 4563 4564 return (0); 4565 } 4566 4567 /* 4568 * Args passed to smbfs_delmap_async 4569 */ 4570 typedef struct smbfs_delmap_args { 4571 taskq_ent_t dm_tqent; 4572 cred_t *dm_cr; 4573 vnode_t *dm_vp; 4574 offset_t dm_off; 4575 caddr_t dm_addr; 4576 size_t dm_len; 4577 uint_t dm_prot; 4578 uint_t dm_maxprot; 4579 uint_t dm_flags; 4580 boolean_t dm_rele_fid; 4581 } smbfs_delmap_args_t; 4582 4583 /* 4584 * Using delmap not only to release the SMB FID (as described above) 4585 * but to flush dirty pages as needed. Both of those do the actual 4586 * work in an async taskq job to avoid interfering with locks held 4587 * in the VM layer when this is called. 4588 */ 4589 4590 /* ARGSUSED */ 4591 static int 4592 smbfs_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr, 4593 size_t len, uint_t prot, uint_t maxprot, uint_t flags, 4594 cred_t *cr, caller_context_t *ct) 4595 { 4596 smbnode_t *np = VTOSMB(vp); 4597 smbmntinfo_t *smi = VTOSMI(vp); 4598 smbfs_delmap_args_t *dmapp; 4599 4600 dmapp = kmem_zalloc(sizeof (*dmapp), KM_SLEEP); 4601 4602 /* 4603 * The VM layer may segvn_free the seg holding this vnode 4604 * before our callback has a chance run, so take a hold on 4605 * the vnode here and release it in the callback. 4606 * (same for the cred) 4607 */ 4608 crhold(cr); 4609 VN_HOLD(vp); 4610 4611 dmapp->dm_vp = vp; 4612 dmapp->dm_cr = cr; 4613 dmapp->dm_off = off; 4614 dmapp->dm_addr = addr; 4615 dmapp->dm_len = len; 4616 dmapp->dm_prot = prot; 4617 dmapp->dm_maxprot = maxprot; 4618 dmapp->dm_flags = flags; 4619 dmapp->dm_rele_fid = B_FALSE; 4620 4621 /* 4622 * Go ahead and decrement r_mapcount now, which is 4623 * the primary purpose of this function. 4624 * 4625 * When r_mapcnt goes to zero, we need to call 4626 * smbfs_rele_fid, but can't do that here, so 4627 * set a flag telling the async task to do it. 4628 */ 4629 mutex_enter(&np->r_statelock); 4630 np->r_mapcnt -= btopr(len); 4631 ASSERT(np->r_mapcnt >= 0); 4632 if (np->r_mapcnt == 0) 4633 dmapp->dm_rele_fid = B_TRUE; 4634 mutex_exit(&np->r_statelock); 4635 4636 taskq_dispatch_ent(smi->smi_taskq, smbfs_delmap_async, dmapp, 0, 4637 &dmapp->dm_tqent); 4638 4639 return (0); 4640 } 4641 4642 /* 4643 * Remove some pages from an mmap'd vnode. Flush any 4644 * dirty pages in the unmapped range. 4645 */ 4646 /* ARGSUSED */ 4647 static void 4648 smbfs_delmap_async(void *varg) 4649 { 4650 smbfs_delmap_args_t *dmapp = varg; 4651 cred_t *cr; 4652 vnode_t *vp; 4653 smbnode_t *np; 4654 smbmntinfo_t *smi; 4655 4656 cr = dmapp->dm_cr; 4657 vp = dmapp->dm_vp; 4658 np = VTOSMB(vp); 4659 smi = VTOSMI(vp); 4660 4661 /* Decremented r_mapcnt in smbfs_delmap */ 4662 4663 /* 4664 * Initiate a page flush and potential commit if there are 4665 * pages, the file system was not mounted readonly, the segment 4666 * was mapped shared, and the pages themselves were writeable. 4667 * 4668 * mark RDIRTY here, will be used to check if a file is dirty when 4669 * unmount smbfs 4670 */ 4671 if (vn_has_cached_data(vp) && !vn_is_readonly(vp) && 4672 dmapp->dm_flags == MAP_SHARED && 4673 (dmapp->dm_maxprot & PROT_WRITE) != 0) { 4674 mutex_enter(&np->r_statelock); 4675 np->r_flags |= RDIRTY; 4676 mutex_exit(&np->r_statelock); 4677 4678 /* 4679 * Need to finish the putpage before we 4680 * close the OtW FID needed for I/O. 4681 */ 4682 (void) smbfs_putpage(vp, dmapp->dm_off, dmapp->dm_len, 0, 4683 dmapp->dm_cr, NULL); 4684 } 4685 4686 if ((np->r_flags & RDIRECTIO) || (smi->smi_flags & SMI_DIRECTIO)) 4687 (void) smbfs_putpage(vp, dmapp->dm_off, dmapp->dm_len, 4688 B_INVAL, dmapp->dm_cr, NULL); 4689 4690 /* 4691 * If r_mapcnt went to zero, drop our FID ref now. 4692 * On the last fidref, this does an OtW close. 4693 */ 4694 if (dmapp->dm_rele_fid) { 4695 struct smb_cred scred; 4696 4697 (void) smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, 0); 4698 smb_credinit(&scred, dmapp->dm_cr); 4699 4700 smbfs_rele_fid(np, &scred); 4701 4702 smb_credrele(&scred); 4703 smbfs_rw_exit(&np->r_lkserlock); 4704 } 4705 4706 /* Release holds taken in smbfs_delmap */ 4707 VN_RELE(vp); 4708 crfree(cr); 4709 4710 kmem_free(dmapp, sizeof (*dmapp)); 4711 } 4712 4713 /* No smbfs_pageio() or smbfs_dispose() ops. */ 4714 4715 #endif // _KERNEL 4716 4717 /* misc. ******************************************************** */ 4718 4719 4720 /* 4721 * XXX 4722 * This op may need to support PSARC 2007/440, nbmand changes for CIFS Service. 4723 */ 4724 static int 4725 smbfs_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag, 4726 offset_t offset, struct flk_callback *flk_cbp, cred_t *cr, 4727 caller_context_t *ct) 4728 { 4729 if (curproc->p_zone != VTOSMI(vp)->smi_zone_ref.zref_zone) 4730 return (EIO); 4731 4732 if (VTOSMI(vp)->smi_flags & SMI_LLOCK) 4733 return (fs_frlock(vp, cmd, bfp, flag, offset, flk_cbp, cr, ct)); 4734 else 4735 return (ENOSYS); 4736 } 4737 4738 /* 4739 * Free storage space associated with the specified vnode. The portion 4740 * to be freed is specified by bfp->l_start and bfp->l_len (already 4741 * normalized to a "whence" of 0). 4742 * 4743 * Called by fcntl(fd, F_FREESP, lkp) for libc:ftruncate, etc. 4744 */ 4745 /* ARGSUSED */ 4746 static int 4747 smbfs_space(vnode_t *vp, int cmd, struct flock64 *bfp, int flag, 4748 offset_t offset, cred_t *cr, caller_context_t *ct) 4749 { 4750 int error; 4751 smbmntinfo_t *smi; 4752 4753 smi = VTOSMI(vp); 4754 4755 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 4756 return (EIO); 4757 4758 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 4759 return (EIO); 4760 4761 /* Caller (fcntl) has checked v_type */ 4762 ASSERT(vp->v_type == VREG); 4763 if (cmd != F_FREESP) 4764 return (EINVAL); 4765 4766 /* 4767 * Like NFS3, no 32-bit offset checks here. 4768 * Our SMB layer takes care to return EFBIG 4769 * when it has to fallback to a 32-bit call. 4770 */ 4771 4772 error = convoff(vp, bfp, 0, offset); 4773 if (!error) { 4774 ASSERT(bfp->l_start >= 0); 4775 if (bfp->l_len == 0) { 4776 struct vattr va; 4777 4778 /* 4779 * ftruncate should not change the ctime and 4780 * mtime if we truncate the file to its 4781 * previous size. 4782 */ 4783 va.va_mask = AT_SIZE; 4784 error = smbfsgetattr(vp, &va, cr); 4785 if (error || va.va_size == bfp->l_start) 4786 return (error); 4787 va.va_mask = AT_SIZE; 4788 va.va_size = bfp->l_start; 4789 error = smbfssetattr(vp, &va, 0, cr); 4790 /* SMBFS_VNEVENT... */ 4791 } else 4792 error = EINVAL; 4793 } 4794 4795 return (error); 4796 } 4797 4798 4799 /* ARGSUSED */ 4800 static int 4801 smbfs_realvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct) 4802 { 4803 4804 return (ENOSYS); 4805 } 4806 4807 4808 /* ARGSUSED */ 4809 static int 4810 smbfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, 4811 caller_context_t *ct) 4812 { 4813 vfs_t *vfs; 4814 smbmntinfo_t *smi; 4815 struct smb_share *ssp; 4816 4817 vfs = vp->v_vfsp; 4818 smi = VFTOSMI(vfs); 4819 4820 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 4821 return (EIO); 4822 4823 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) 4824 return (EIO); 4825 4826 switch (cmd) { 4827 case _PC_FILESIZEBITS: 4828 ssp = smi->smi_share; 4829 if (SSTOVC(ssp)->vc_sopt.sv_caps & SMB_CAP_LARGE_FILES) 4830 *valp = 64; 4831 else 4832 *valp = 32; 4833 break; 4834 4835 case _PC_LINK_MAX: 4836 /* We only ever report one link to an object */ 4837 *valp = 1; 4838 break; 4839 4840 case _PC_ACL_ENABLED: 4841 /* 4842 * Always indicate that ACLs are enabled and 4843 * that we support ACE_T format, otherwise 4844 * libsec will ask for ACLENT_T format data 4845 * which we don't support. 4846 */ 4847 *valp = _ACL_ACE_ENABLED; 4848 break; 4849 4850 case _PC_SYMLINK_MAX: /* No symlinks until we do Unix extensions */ 4851 *valp = 0; 4852 break; 4853 4854 case _PC_XATTR_EXISTS: 4855 if (vfs->vfs_flag & VFS_XATTR) { 4856 *valp = smbfs_xa_exists(vp, cr); 4857 break; 4858 } 4859 return (EINVAL); 4860 4861 case _PC_SATTR_ENABLED: 4862 case _PC_SATTR_EXISTS: 4863 *valp = 1; 4864 break; 4865 4866 case _PC_TIMESTAMP_RESOLUTION: 4867 /* 4868 * Windows times are tenths of microseconds 4869 * (multiples of 100 nanoseconds). 4870 */ 4871 *valp = 100L; 4872 break; 4873 4874 default: 4875 return (fs_pathconf(vp, cmd, valp, cr, ct)); 4876 } 4877 return (0); 4878 } 4879 4880 /* ARGSUSED */ 4881 static int 4882 smbfs_getsecattr(vnode_t *vp, vsecattr_t *vsa, int flag, cred_t *cr, 4883 caller_context_t *ct) 4884 { 4885 vfs_t *vfsp; 4886 smbmntinfo_t *smi; 4887 int error; 4888 uint_t mask; 4889 4890 vfsp = vp->v_vfsp; 4891 smi = VFTOSMI(vfsp); 4892 4893 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 4894 return (EIO); 4895 4896 if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED) 4897 return (EIO); 4898 4899 /* 4900 * Our _pathconf indicates _ACL_ACE_ENABLED, 4901 * so we should only see VSA_ACE, etc here. 4902 * Note: vn_create asks for VSA_DFACLCNT, 4903 * and it expects ENOSYS and empty data. 4904 */ 4905 mask = vsa->vsa_mask & (VSA_ACE | VSA_ACECNT | 4906 VSA_ACE_ACLFLAGS | VSA_ACE_ALLTYPES); 4907 if (mask == 0) 4908 return (ENOSYS); 4909 4910 if (smi->smi_flags & SMI_ACL) 4911 error = smbfs_acl_getvsa(vp, vsa, flag, cr); 4912 else 4913 error = ENOSYS; 4914 4915 if (error == ENOSYS) 4916 error = fs_fab_acl(vp, vsa, flag, cr, ct); 4917 4918 return (error); 4919 } 4920 4921 /* ARGSUSED */ 4922 static int 4923 smbfs_setsecattr(vnode_t *vp, vsecattr_t *vsa, int flag, cred_t *cr, 4924 caller_context_t *ct) 4925 { 4926 vfs_t *vfsp; 4927 smbmntinfo_t *smi; 4928 int error; 4929 uint_t mask; 4930 4931 vfsp = vp->v_vfsp; 4932 smi = VFTOSMI(vfsp); 4933 4934 if (curproc->p_zone != smi->smi_zone_ref.zref_zone) 4935 return (EIO); 4936 4937 if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED) 4938 return (EIO); 4939 4940 /* 4941 * Our _pathconf indicates _ACL_ACE_ENABLED, 4942 * so we should only see VSA_ACE, etc here. 4943 */ 4944 mask = vsa->vsa_mask & (VSA_ACE | VSA_ACECNT); 4945 if (mask == 0) 4946 return (ENOSYS); 4947 4948 if (vfsp->vfs_flag & VFS_RDONLY) 4949 return (EROFS); 4950 4951 /* 4952 * Allow only the mount owner to do this. 4953 * See comments at smbfs_access_rwx. 4954 */ 4955 error = secpolicy_vnode_setdac(cr, smi->smi_uid); 4956 if (error != 0) 4957 return (error); 4958 4959 if (smi->smi_flags & SMI_ACL) 4960 error = smbfs_acl_setvsa(vp, vsa, flag, cr); 4961 else 4962 error = ENOSYS; 4963 4964 return (error); 4965 } 4966 4967 4968 /* 4969 * XXX 4970 * This op should eventually support PSARC 2007/268. 4971 */ 4972 static int 4973 smbfs_shrlock(vnode_t *vp, int cmd, struct shrlock *shr, int flag, cred_t *cr, 4974 caller_context_t *ct) 4975 { 4976 if (curproc->p_zone != VTOSMI(vp)->smi_zone_ref.zref_zone) 4977 return (EIO); 4978 4979 if (VTOSMI(vp)->smi_flags & SMI_LLOCK) 4980 return (fs_shrlock(vp, cmd, shr, flag, cr, ct)); 4981 else 4982 return (ENOSYS); 4983 } 4984 4985 4986 /* 4987 * Most unimplemented ops will return ENOSYS because of fs_nosys(). 4988 * The only ops where that won't work are ACCESS (due to open(2) 4989 * failures) and ... (anything else left?) 4990 */ 4991 const fs_operation_def_t smbfs_vnodeops_template[] = { 4992 VOPNAME_OPEN, { .vop_open = smbfs_open }, 4993 VOPNAME_CLOSE, { .vop_close = smbfs_close }, 4994 VOPNAME_READ, { .vop_read = smbfs_read }, 4995 VOPNAME_WRITE, { .vop_write = smbfs_write }, 4996 VOPNAME_IOCTL, { .vop_ioctl = smbfs_ioctl }, 4997 VOPNAME_GETATTR, { .vop_getattr = smbfs_getattr }, 4998 VOPNAME_SETATTR, { .vop_setattr = smbfs_setattr }, 4999 VOPNAME_ACCESS, { .vop_access = smbfs_access }, 5000 VOPNAME_LOOKUP, { .vop_lookup = smbfs_lookup }, 5001 VOPNAME_CREATE, { .vop_create = smbfs_create }, 5002 VOPNAME_REMOVE, { .vop_remove = smbfs_remove }, 5003 VOPNAME_LINK, { .vop_link = smbfs_link }, 5004 VOPNAME_RENAME, { .vop_rename = smbfs_rename }, 5005 VOPNAME_MKDIR, { .vop_mkdir = smbfs_mkdir }, 5006 VOPNAME_RMDIR, { .vop_rmdir = smbfs_rmdir }, 5007 VOPNAME_READDIR, { .vop_readdir = smbfs_readdir }, 5008 VOPNAME_SYMLINK, { .vop_symlink = smbfs_symlink }, 5009 VOPNAME_READLINK, { .vop_readlink = smbfs_readlink }, 5010 VOPNAME_FSYNC, { .vop_fsync = smbfs_fsync }, 5011 VOPNAME_INACTIVE, { .vop_inactive = smbfs_inactive }, 5012 VOPNAME_FID, { .vop_fid = smbfs_fid }, 5013 VOPNAME_RWLOCK, { .vop_rwlock = smbfs_rwlock }, 5014 VOPNAME_RWUNLOCK, { .vop_rwunlock = smbfs_rwunlock }, 5015 VOPNAME_SEEK, { .vop_seek = smbfs_seek }, 5016 VOPNAME_FRLOCK, { .vop_frlock = smbfs_frlock }, 5017 VOPNAME_SPACE, { .vop_space = smbfs_space }, 5018 VOPNAME_REALVP, { .vop_realvp = smbfs_realvp }, 5019 #ifdef _KERNEL 5020 VOPNAME_GETPAGE, { .vop_getpage = smbfs_getpage }, 5021 VOPNAME_PUTPAGE, { .vop_putpage = smbfs_putpage }, 5022 VOPNAME_MAP, { .vop_map = smbfs_map }, 5023 VOPNAME_ADDMAP, { .vop_addmap = smbfs_addmap }, 5024 VOPNAME_DELMAP, { .vop_delmap = smbfs_delmap }, 5025 #endif // _KERNEL 5026 VOPNAME_PATHCONF, { .vop_pathconf = smbfs_pathconf }, 5027 VOPNAME_SETSECATTR, { .vop_setsecattr = smbfs_setsecattr }, 5028 VOPNAME_GETSECATTR, { .vop_getsecattr = smbfs_getsecattr }, 5029 VOPNAME_SHRLOCK, { .vop_shrlock = smbfs_shrlock }, 5030 #ifdef SMBFS_VNEVENT 5031 VOPNAME_VNEVENT, { .vop_vnevent = fs_vnevent_support }, 5032 #endif 5033 { NULL, NULL } 5034 }; 5035