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