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 #include <sys/systm.h>
40 #include <sys/cred.h>
41 #include <sys/vnode.h>
42 #include <sys/vfs.h>
43 #include <sys/filio.h>
44 #include <sys/uio.h>
45 #include <sys/dirent.h>
46 #include <sys/errno.h>
47 #include <sys/sunddi.h>
48 #include <sys/sysmacros.h>
49 #include <sys/kmem.h>
50 #include <sys/cmn_err.h>
51 #include <sys/vfs_opreg.h>
52 #include <sys/policy.h>
53
54 #include <netsmb/smb_osdep.h>
55 #include <netsmb/smb.h>
56 #include <netsmb/smb_conn.h>
57 #include <netsmb/smb_subr.h>
58
59 #include <smbfs/smbfs.h>
60 #include <smbfs/smbfs_node.h>
61 #include <smbfs/smbfs_subr.h>
62
63 #include <sys/fs/smbfs_ioctl.h>
64 #include <fs/fs_subr.h>
65
66 /*
67 * We assign directory offsets like the NFS client, where the
68 * offset increments by _one_ after each directory entry.
69 * Further, the entries "." and ".." are always at offsets
70 * zero and one (respectively) and the "real" entries from
71 * the server appear at offsets starting with two. This
72 * macro is used to initialize the n_dirofs field after
73 * setting n_dirseq with a _findopen call.
84 static const char illegal_chars[] = {
85 ':', /* colon - keep this first! */
86 '\\', /* back slash */
87 '/', /* slash */
88 '*', /* asterisk */
89 '?', /* question mark */
90 '"', /* double quote */
91 '<', /* less than sign */
92 '>', /* greater than sign */
93 '|', /* vertical bar */
94 0
95 };
96
97 /*
98 * Turning this on causes nodes to be created in the cache
99 * during directory listings, normally avoiding a second
100 * OtW attribute fetch just after a readdir.
101 */
102 int smbfs_fastlookup = 1;
103
104 /* local static function defines */
105
106 static int smbfslookup_cache(vnode_t *, char *, int, vnode_t **,
107 cred_t *);
108 static int smbfslookup(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr,
109 int cache_ok, caller_context_t *);
110 static int smbfsremove(vnode_t *dvp, vnode_t *vp, struct smb_cred *scred,
111 int flags);
112 static int smbfsrename(vnode_t *odvp, vnode_t *ovp, vnode_t *ndvp,
113 char *nnm, struct smb_cred *scred, int flags);
114 static int smbfssetattr(vnode_t *, struct vattr *, int, cred_t *);
115 static int smbfs_accessx(void *, int, cred_t *);
116 static int smbfs_readvdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
117 caller_context_t *);
118 static void smbfs_rele_fid(smbnode_t *, struct smb_cred *);
119 static uint32_t xvattr_to_dosattr(smbnode_t *, struct vattr *);
120
121 /*
122 * These are the vnode ops routines which implement the vnode interface to
123 * the networked file system. These routines just take their parameters,
124 * make them look networkish by putting the right info into interface structs,
125 * and then calling the appropriate remote routine(s) to do the work.
126 *
127 * Note on directory name lookup cacheing: If we detect a stale fhandle,
128 * we purge the directory cache relative to that vnode. This way, the
129 * user won't get burned by the cache repeatedly. See <smbfs/smbnode.h> for
130 * more details on smbnode locking.
131 */
132
133 static int smbfs_open(vnode_t **, int, cred_t *, caller_context_t *);
134 static int smbfs_close(vnode_t *, int, int, offset_t, cred_t *,
135 caller_context_t *);
136 static int smbfs_read(vnode_t *, struct uio *, int, cred_t *,
137 caller_context_t *);
138 static int smbfs_write(vnode_t *, struct uio *, int, cred_t *,
139 caller_context_t *);
140 static int smbfs_ioctl(vnode_t *, int, intptr_t, int, cred_t *, int *,
141 caller_context_t *);
142 static int smbfs_getattr(vnode_t *, struct vattr *, int, cred_t *,
143 caller_context_t *);
144 static int smbfs_setattr(vnode_t *, struct vattr *, int, cred_t *,
145 caller_context_t *);
146 static int smbfs_access(vnode_t *, int, int, cred_t *, caller_context_t *);
147 static int smbfs_fsync(vnode_t *, int, cred_t *, caller_context_t *);
148 static void smbfs_inactive(vnode_t *, cred_t *, caller_context_t *);
149 static int smbfs_lookup(vnode_t *, char *, vnode_t **, struct pathname *,
150 int, vnode_t *, cred_t *, caller_context_t *,
151 int *, pathname_t *);
152 static int smbfs_create(vnode_t *, char *, struct vattr *, enum vcexcl,
153 int, vnode_t **, cred_t *, int, caller_context_t *,
154 vsecattr_t *);
155 static int smbfs_remove(vnode_t *, char *, cred_t *, caller_context_t *,
156 int);
157 static int smbfs_rename(vnode_t *, char *, vnode_t *, char *, cred_t *,
158 caller_context_t *, int);
159 static int smbfs_mkdir(vnode_t *, char *, struct vattr *, vnode_t **,
160 cred_t *, caller_context_t *, int, vsecattr_t *);
161 static int smbfs_rmdir(vnode_t *, char *, vnode_t *, cred_t *,
162 caller_context_t *, int);
163 static int smbfs_readdir(vnode_t *, struct uio *, cred_t *, int *,
164 caller_context_t *, int);
165 static int smbfs_rwlock(vnode_t *, int, caller_context_t *);
166 static void smbfs_rwunlock(vnode_t *, int, caller_context_t *);
167 static int smbfs_seek(vnode_t *, offset_t, offset_t *, caller_context_t *);
168 static int smbfs_frlock(vnode_t *, int, struct flock64 *, int, offset_t,
169 struct flk_callback *, cred_t *, caller_context_t *);
170 static int smbfs_space(vnode_t *, int, struct flock64 *, int, offset_t,
171 cred_t *, caller_context_t *);
172 static int smbfs_pathconf(vnode_t *, int, ulong_t *, cred_t *,
173 caller_context_t *);
174 static int smbfs_setsecattr(vnode_t *, vsecattr_t *, int, cred_t *,
175 caller_context_t *);
176 static int smbfs_getsecattr(vnode_t *, vsecattr_t *, int, cred_t *,
177 caller_context_t *);
178 static int smbfs_shrlock(vnode_t *, int, struct shrlock *, int, cred_t *,
179 caller_context_t *);
180
181 /* Dummy function to use until correct function is ported in */
182 int noop_vnodeop() {
183 return (0);
184 }
185
186 struct vnodeops *smbfs_vnodeops = NULL;
187
188 /*
189 * Most unimplemented ops will return ENOSYS because of fs_nosys().
190 * The only ops where that won't work are ACCESS (due to open(2)
191 * failures) and ... (anything else left?)
192 */
193 const fs_operation_def_t smbfs_vnodeops_template[] = {
194 { VOPNAME_OPEN, { .vop_open = smbfs_open } },
195 { VOPNAME_CLOSE, { .vop_close = smbfs_close } },
196 { VOPNAME_READ, { .vop_read = smbfs_read } },
197 { VOPNAME_WRITE, { .vop_write = smbfs_write } },
198 { VOPNAME_IOCTL, { .vop_ioctl = smbfs_ioctl } },
199 { VOPNAME_GETATTR, { .vop_getattr = smbfs_getattr } },
200 { VOPNAME_SETATTR, { .vop_setattr = smbfs_setattr } },
201 { VOPNAME_ACCESS, { .vop_access = smbfs_access } },
202 { VOPNAME_LOOKUP, { .vop_lookup = smbfs_lookup } },
203 { VOPNAME_CREATE, { .vop_create = smbfs_create } },
204 { VOPNAME_REMOVE, { .vop_remove = smbfs_remove } },
205 { VOPNAME_LINK, { .error = fs_nosys } }, /* smbfs_link, */
206 { VOPNAME_RENAME, { .vop_rename = smbfs_rename } },
207 { VOPNAME_MKDIR, { .vop_mkdir = smbfs_mkdir } },
208 { VOPNAME_RMDIR, { .vop_rmdir = smbfs_rmdir } },
209 { VOPNAME_READDIR, { .vop_readdir = smbfs_readdir } },
210 { VOPNAME_SYMLINK, { .error = fs_nosys } }, /* smbfs_symlink, */
211 { VOPNAME_READLINK, { .error = fs_nosys } }, /* smbfs_readlink, */
212 { VOPNAME_FSYNC, { .vop_fsync = smbfs_fsync } },
213 { VOPNAME_INACTIVE, { .vop_inactive = smbfs_inactive } },
214 { VOPNAME_FID, { .error = fs_nosys } }, /* smbfs_fid, */
215 { VOPNAME_RWLOCK, { .vop_rwlock = smbfs_rwlock } },
216 { VOPNAME_RWUNLOCK, { .vop_rwunlock = smbfs_rwunlock } },
217 { VOPNAME_SEEK, { .vop_seek = smbfs_seek } },
218 { VOPNAME_FRLOCK, { .vop_frlock = smbfs_frlock } },
219 { VOPNAME_SPACE, { .vop_space = smbfs_space } },
220 { VOPNAME_REALVP, { .error = fs_nosys } }, /* smbfs_realvp, */
221 { VOPNAME_GETPAGE, { .error = fs_nosys } }, /* smbfs_getpage, */
222 { VOPNAME_PUTPAGE, { .error = fs_nosys } }, /* smbfs_putpage, */
223 { VOPNAME_MAP, { .error = fs_nosys } }, /* smbfs_map, */
224 { VOPNAME_ADDMAP, { .error = fs_nosys } }, /* smbfs_addmap, */
225 { VOPNAME_DELMAP, { .error = fs_nosys } }, /* smbfs_delmap, */
226 { VOPNAME_DUMP, { .error = fs_nosys } }, /* smbfs_dump, */
227 { VOPNAME_PATHCONF, { .vop_pathconf = smbfs_pathconf } },
228 { VOPNAME_PAGEIO, { .error = fs_nosys } }, /* smbfs_pageio, */
229 { VOPNAME_SETSECATTR, { .vop_setsecattr = smbfs_setsecattr } },
230 { VOPNAME_GETSECATTR, { .vop_getsecattr = smbfs_getsecattr } },
231 { VOPNAME_SHRLOCK, { .vop_shrlock = smbfs_shrlock } },
232 { NULL, NULL }
233 };
234
235 /*
236 * XXX
237 * When new and relevant functionality is enabled, we should be
238 * calling vfs_set_feature() to inform callers that pieces of
239 * functionality are available, per PSARC 2007/227.
240 */
241 /* ARGSUSED */
242 static int
243 smbfs_open(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct)
244 {
245 smbnode_t *np;
246 vnode_t *vp;
247 smbfattr_t fa;
248 u_int32_t rights, rightsrcvd;
249 u_int16_t fid, oldfid;
250 int oldgenid;
251 struct smb_cred scred;
252 smbmntinfo_t *smi;
253 smb_share_t *ssp;
254 cred_t *oldcr;
255 int tmperror;
267 return (EIO);
268
269 if (vp->v_type != VREG && vp->v_type != VDIR) { /* XXX VLNK? */
270 SMBVDEBUG("open eacces vtype=%d\n", vp->v_type);
271 return (EACCES);
272 }
273
274 /*
275 * Get exclusive access to n_fid and related stuff.
276 * No returns after this until out.
277 */
278 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, SMBINTR(vp)))
279 return (EINTR);
280 smb_credinit(&scred, cr);
281
282 /*
283 * Keep track of the vnode type at first open.
284 * It may change later, and we need close to do
285 * cleanup for the type we opened. Also deny
286 * open of new types until old type is closed.
287 * XXX: Per-open instance nodes whould help.
288 */
289 if (np->n_ovtype == VNON) {
290 ASSERT(np->n_dirrefs == 0);
291 ASSERT(np->n_fidrefs == 0);
292 } else if (np->n_ovtype != vp->v_type) {
293 SMBVDEBUG("open n_ovtype=%d v_type=%d\n",
294 np->n_ovtype, vp->v_type);
295 error = EACCES;
296 goto out;
297 }
298
299 /*
300 * Directory open. See smbfs_readvdir()
301 */
302 if (vp->v_type == VDIR) {
303 if (np->n_dirseq == NULL) {
304 /* first open */
305 error = smbfs_smb_findopen(np, "*", 1,
306 SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR,
307 &scred, &np->n_dirseq);
406 * Keep track of the vnode type at first open.
407 * (see comments above)
408 */
409 if (np->n_ovtype == VNON)
410 np->n_ovtype = vp->v_type;
411
412 out:
413 smb_credrele(&scred);
414 smbfs_rw_exit(&np->r_lkserlock);
415 return (error);
416 }
417
418 /*ARGSUSED*/
419 static int
420 smbfs_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr,
421 caller_context_t *ct)
422 {
423 smbnode_t *np;
424 smbmntinfo_t *smi;
425 struct smb_cred scred;
426
427 np = VTOSMB(vp);
428 smi = VTOSMI(vp);
429
430 /*
431 * Don't "bail out" for VFS_UNMOUNTED here,
432 * as we want to do cleanup, etc.
433 */
434
435 /*
436 * zone_enter(2) prevents processes from changing zones with SMBFS files
437 * open; if we happen to get here from the wrong zone we can't do
438 * anything over the wire.
439 */
440 if (smi->smi_zone_ref.zref_zone != curproc->p_zone) {
441 /*
442 * We could attempt to clean up locks, except we're sure
443 * that the current process didn't acquire any locks on
444 * the file: any attempt to lock a file belong to another zone
445 * will fail, and one can't lock an SMBFS file and then change
453 * everything (minus the final smbfs_getattr_otw() call) should
454 * be OK. If the zone is going away smbfs_async_inactive() will
455 * throw away cached pages inline.
456 */
457 return (EIO);
458 }
459
460 /*
461 * If we are using local locking for this filesystem, then
462 * release all of the SYSV style record locks. Otherwise,
463 * we are doing network locking and we need to release all
464 * of the network locks. All of the locks held by this
465 * process on this file are released no matter what the
466 * incoming reference count is.
467 */
468 if (smi->smi_flags & SMI_LLOCK) {
469 pid_t pid = ddi_get_pid();
470 cleanlocks(vp, pid, 0);
471 cleanshares(vp, pid);
472 }
473
474 /*
475 * This (passed in) count is the ref. count from the
476 * user's file_t before the closef call (fio.c).
477 * We only care when the reference goes away.
478 */
479 if (count > 1)
480 return (0);
481
482 /*
483 * Decrement the reference count for the FID
484 * and possibly do the OtW close.
485 *
486 * Exclusive lock for modifying n_fid stuff.
487 * Don't want this one ever interruptible.
488 */
489 (void) smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, 0);
490 smb_credinit(&scred, cr);
491
492 smbfs_rele_fid(np, &scred);
493
494 smb_credrele(&scred);
495 smbfs_rw_exit(&np->r_lkserlock);
496
497 return (0);
498 }
499
500 /*
501 * Helper for smbfs_close. Decrement the reference count
502 * for an SMB-level file or directory ID, and when the last
573 np->r_cred = NULL;
574 mutex_exit(&np->r_statelock);
575 if (oldcr != NULL)
576 crfree(oldcr);
577 }
578
579 /* ARGSUSED */
580 static int
581 smbfs_read(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
582 caller_context_t *ct)
583 {
584 struct smb_cred scred;
585 struct vattr va;
586 smbnode_t *np;
587 smbmntinfo_t *smi;
588 smb_share_t *ssp;
589 offset_t endoff;
590 ssize_t past_eof;
591 int error;
592
593 np = VTOSMB(vp);
594 smi = VTOSMI(vp);
595 ssp = smi->smi_share;
596
597 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
598 return (EIO);
599
600 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
601 return (EIO);
602
603 ASSERT(smbfs_rw_lock_held(&np->r_rwlock, RW_READER));
604
605 if (vp->v_type != VREG)
606 return (EISDIR);
607
608 if (uiop->uio_resid == 0)
609 return (0);
610
611 /*
612 * Like NFS3, just check for 63-bit overflow.
622 if (error = smbfsgetattr(vp, &va, cr))
623 return (error);
624
625 /* Update mtime with mtime from server here? */
626
627 /* if offset is beyond EOF, read nothing */
628 if (uiop->uio_loffset >= va.va_size)
629 return (0);
630
631 /*
632 * Limit the read to the remaining file size.
633 * Do this by temporarily reducing uio_resid
634 * by the amount the lies beyoned the EOF.
635 */
636 if (endoff > va.va_size) {
637 past_eof = (ssize_t)(endoff - va.va_size);
638 uiop->uio_resid -= past_eof;
639 } else
640 past_eof = 0;
641
642 /* Shared lock for n_fid use in smb_rwuio */
643 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
644 return (EINTR);
645 smb_credinit(&scred, cr);
646
647 /* After reconnect, n_fid is invalid */
648 if (np->n_vcgenid != ssp->ss_vcgenid)
649 error = ESTALE;
650 else
651 error = smb_rwuio(ssp, np->n_fid, UIO_READ,
652 uiop, &scred, smb_timo_read);
653
654 smb_credrele(&scred);
655 smbfs_rw_exit(&np->r_lkserlock);
656
657 /* undo adjustment of resid */
658 uiop->uio_resid += past_eof;
659
660 return (error);
661 }
662
663
664 /* ARGSUSED */
665 static int
666 smbfs_write(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
667 caller_context_t *ct)
668 {
669 struct smb_cred scred;
670 struct vattr va;
671 smbnode_t *np;
672 smbmntinfo_t *smi;
673 smb_share_t *ssp;
674 offset_t endoff, limit;
675 ssize_t past_limit;
676 int error, timo;
677
678 np = VTOSMB(vp);
679 smi = VTOSMI(vp);
680 ssp = smi->smi_share;
681
682 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
683 return (EIO);
684
685 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
686 return (EIO);
687
688 ASSERT(smbfs_rw_lock_held(&np->r_rwlock, RW_WRITER));
689
690 if (vp->v_type != VREG)
691 return (EISDIR);
692
693 if (uiop->uio_resid == 0)
694 return (0);
695
696 /*
697 * Handle ioflag bits: (FAPPEND|FSYNC|FDSYNC)
698 */
699 if (ioflag & (FAPPEND | FSYNC)) {
700 if (np->n_flag & NMODIFIED) {
701 smbfs_attrcache_remove(np);
702 /* XXX: smbfs_vinvalbuf? */
703 }
704 }
705 if (ioflag & FAPPEND) {
706 /*
707 * File size can be changed by another client
708 */
709 va.va_mask = AT_SIZE;
710 if (error = smbfsgetattr(vp, &va, cr))
711 return (error);
712 uiop->uio_loffset = va.va_size;
713 }
714
715 /*
716 * Like NFS3, just check for 63-bit overflow.
717 */
718 endoff = uiop->uio_loffset + uiop->uio_resid;
719 if (uiop->uio_loffset < 0 || endoff < 0)
720 return (EINVAL);
721
722 /*
723 * Check to make sure that the process will not exceed
724 * its limit on file size. It is okay to write up to
725 * the limit, but not beyond. Thus, the write which
726 * reaches the limit will be short and the next write
727 * will return an error.
728 *
729 * So if we're starting at or beyond the limit, EFBIG.
730 * Otherwise, temporarily reduce resid to the amount
731 * the falls after the limit.
732 */
733 limit = uiop->uio_llimit;
734 if (limit == RLIM64_INFINITY || limit > MAXOFFSET_T)
735 limit = MAXOFFSET_T;
736 if (uiop->uio_loffset >= limit)
737 return (EFBIG);
738 if (endoff > limit) {
739 past_limit = (ssize_t)(endoff - limit);
740 uiop->uio_resid -= past_limit;
741 } else
742 past_limit = 0;
743
744 /* Timeout: longer for append. */
745 timo = smb_timo_write;
746 if (endoff > np->r_size)
747 timo = smb_timo_append;
748
749 /* Shared lock for n_fid use in smb_rwuio */
750 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
751 return (EINTR);
752 smb_credinit(&scred, cr);
753
754 /* After reconnect, n_fid is invalid */
755 if (np->n_vcgenid != ssp->ss_vcgenid)
756 error = ESTALE;
757 else
758 error = smb_rwuio(ssp, np->n_fid, UIO_WRITE,
759 uiop, &scred, timo);
760
761 if (error == 0) {
762 mutex_enter(&np->r_statelock);
763 np->n_flag |= (NFLUSHWIRE | NATTRCHANGED);
764 if (uiop->uio_loffset > (offset_t)np->r_size)
765 np->r_size = (len_t)uiop->uio_loffset;
766 mutex_exit(&np->r_statelock);
767 if (ioflag & (FSYNC|FDSYNC)) {
768 /* Don't error the I/O if this fails. */
769 (void) smbfs_smb_flush(np, &scred);
770 }
771 }
772
773 smb_credrele(&scred);
774 smbfs_rw_exit(&np->r_lkserlock);
775
776 /* undo adjustment of resid */
777 uiop->uio_resid += past_limit;
778
779 return (error);
780 }
781
782
783 /* ARGSUSED */
784 static int
785 smbfs_ioctl(vnode_t *vp, int cmd, intptr_t arg, int flag,
786 cred_t *cr, int *rvalp, caller_context_t *ct)
787 {
788 int error;
789 smbmntinfo_t *smi;
790
791 smi = VTOSMI(vp);
792
793 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
794 return (EIO);
795
796 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
797 return (EIO);
798
799 switch (cmd) {
800 /* First three from ZFS. XXX - need these? */
801
802 case _FIOFFS:
803 error = smbfs_fsync(vp, 0, cr, ct);
804 break;
805
806 /*
807 * The following two ioctls are used by bfu.
808 * Silently ignore to avoid bfu errors.
809 */
810 case _FIOGDIO:
811 case _FIOSDIO:
812 error = 0;
813 break;
814
815 #ifdef NOT_YET /* XXX - from the NFS code. */
816 case _FIODIRECTIO:
817 error = smbfs_directio(vp, (int)arg, cr);
818 #endif
819
820 /*
821 * Allow get/set with "raw" security descriptor (SD) data.
822 * Useful for testing, diagnosing idmap problems, etc.
823 */
824 case SMBFSIO_GETSD:
825 error = smbfs_acl_iocget(vp, arg, flag, cr);
826 break;
827
828 case SMBFSIO_SETSD:
829 error = smbfs_acl_iocset(vp, arg, flag, cr);
830 break;
831
832 default:
833 error = ENOTTY;
834 break;
835 }
836
837 return (error);
838 }
839
840
841 /*
842 * Return either cached or remote attributes. If get remote attr
843 * use them to check and invalidate caches, then cache the new attributes.
844 */
845 /* ARGSUSED */
846 static int
847 smbfs_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
848 caller_context_t *ct)
849 {
850 smbnode_t *np;
851 smbmntinfo_t *smi;
852
853 smi = VTOSMI(vp);
854
855 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
856 return (EIO);
857
858 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
859 return (EIO);
860
861 /*
862 * If it has been specified that the return value will
863 * just be used as a hint, and we are only being asked
864 * for size, fsid or rdevid, then return the client's
865 * notion of these values without checking to make sure
866 * that the attribute cache is up to date.
867 * The whole point is to avoid an over the wire GETATTR
868 * call.
869 */
870 np = VTOSMB(vp);
871 if (flags & ATTR_HINT) {
872 if (vap->va_mask ==
873 (vap->va_mask & (AT_SIZE | AT_FSID | AT_RDEV))) {
874 mutex_enter(&np->r_statelock);
875 if (vap->va_mask | AT_SIZE)
876 vap->va_size = np->r_size;
877 if (vap->va_mask | AT_FSID)
878 vap->va_fsid = vp->v_vfsp->vfs_dev;
879 if (vap->va_mask | AT_RDEV)
880 vap->va_rdev = vp->v_rdev;
881 mutex_exit(&np->r_statelock);
882 return (0);
883 }
884 }
885
886 return (smbfsgetattr(vp, vap, cr));
887 }
888
889 /* smbfsgetattr() in smbfs_client.c */
890
891 /*ARGSUSED4*/
892 static int
893 smbfs_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
894 caller_context_t *ct)
895 {
896 vfs_t *vfsp;
897 smbmntinfo_t *smi;
898 int error;
899 uint_t mask;
900 struct vattr oldva;
901
902 vfsp = vp->v_vfsp;
903 smi = VFTOSMI(vfsp);
904
905 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
936 return (error);
937
938 if (mask & (AT_UID | AT_GID)) {
939 if (smi->smi_flags & SMI_ACL)
940 error = smbfs_acl_setids(vp, vap, cr);
941 else
942 error = ENOSYS;
943 if (error != 0) {
944 SMBVDEBUG("error %d seting UID/GID on %s",
945 error, VTOSMB(vp)->n_rpath);
946 /*
947 * It might be more correct to return the
948 * error here, but that causes complaints
949 * when root extracts a cpio archive, etc.
950 * So ignore this error, and go ahead with
951 * the rest of the setattr work.
952 */
953 }
954 }
955
956 return (smbfssetattr(vp, vap, flags, cr));
957 }
958
959 /*
960 * Mostly from Darwin smbfs_setattr()
961 * but then modified a lot.
962 */
963 /* ARGSUSED */
964 static int
965 smbfssetattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
966 {
967 int error = 0;
968 smbnode_t *np = VTOSMB(vp);
969 uint_t mask = vap->va_mask;
970 struct timespec *mtime, *atime;
971 struct smb_cred scred;
972 int cerror, modified = 0;
973 unsigned short fid;
974 int have_fid = 0;
975 uint32_t rights = 0;
976 uint32_t dosattr = 0;
977
978 ASSERT(curproc->p_zone == VTOSMI(vp)->smi_zone_ref.zref_zone);
979
980 /*
981 * There are no settable attributes on the XATTR dir,
982 * so just silently ignore these. On XATTR files,
983 * you can set the size but nothing else.
984 */
985 if (vp->v_flag & V_XATTRDIR)
986 return (0);
987 if (np->n_flag & N_XATTR) {
988 if (mask & AT_TIMES)
989 SMBVDEBUG("ignore set time on xattr\n");
990 mask &= AT_SIZE;
991 }
992
993 /*
994 * If our caller is trying to set multiple attributes, they
995 * can make no assumption about what order they are done in.
996 * Here we try to do them in order of decreasing likelihood
997 * of failure, just to minimize the chance we'll wind up
998 * with a partially complete request.
999 */
1000
1001 /* Shared lock for (possible) n_fid use. */
1002 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
1003 return (EINTR);
1004 smb_credinit(&scred, cr);
1005
1006 /*
1007 * If the caller has provided extensible attributes,
1008 * map those into DOS attributes supported by SMB.
1009 * Note: zero means "no change".
1010 */
1011 if (mask & AT_XVATTR)
1012 dosattr = xvattr_to_dosattr(np, vap);
1013
1035 error = smbfs_smb_tmpopen(np, rights, &scred, &fid);
1036 if (error) {
1037 SMBVDEBUG("error %d opening %s\n",
1038 error, np->n_rpath);
1039 goto out;
1040 }
1041 have_fid = 1;
1042 }
1043
1044 /*
1045 * If the server supports the UNIX extensions, right here is where
1046 * we'd support changes to uid, gid, mode, and possibly va_flags.
1047 * For now we claim to have made any such changes.
1048 */
1049
1050 if (mask & AT_SIZE) {
1051 /*
1052 * If the new file size is less than what the client sees as
1053 * the file size, then just change the size and invalidate
1054 * the pages.
1055 * I am commenting this code at present because the function
1056 * smbfs_putapage() is not yet implemented.
1057 */
1058
1059 /*
1060 * Set the file size to vap->va_size.
1061 */
1062 ASSERT(have_fid);
1063 error = smbfs_smb_setfsize(np, fid, vap->va_size, &scred);
1064 if (error) {
1065 SMBVDEBUG("setsize error %d file %s\n",
1066 error, np->n_rpath);
1067 } else {
1068 /*
1069 * Darwin had code here to zero-extend.
1070 * Tests indicate the server will zero-fill,
1071 * so looks like we don't need to do this.
1072 * Good thing, as this could take forever.
1073 *
1074 * XXX: Reportedly, writing one byte of zero
1075 * at the end offset avoids problems here.
1076 */
1077 mutex_enter(&np->r_statelock);
1078 np->r_size = vap->va_size;
1079 mutex_exit(&np->r_statelock);
1080 modified = 1;
1081 }
1082 }
1083
1084 /*
1085 * XXX: When Solaris has create_time, set that too.
1086 * Note: create_time is different from ctime.
1087 */
1088 mtime = ((mask & AT_MTIME) ? &vap->va_mtime : 0);
1089 atime = ((mask & AT_ATIME) ? &vap->va_atime : 0);
1090
1091 if (dosattr || mtime || atime) {
1092 /*
1093 * Always use the handle-based set attr call now.
1094 */
1095 ASSERT(have_fid);
1096 error = smbfs_smb_setfattr(np, fid,
1097 dosattr, mtime, atime, &scred);
1098 if (error) {
1099 SMBVDEBUG("set times error %d file %s\n",
1100 error, np->n_rpath);
1101 } else {
1102 modified = 1;
1103 }
1104 }
1105
1106 out:
1107 if (modified) {
1108 /*
1109 * Invalidate attribute cache in case the server
1110 * doesn't set exactly the attributes we asked.
1111 */
1112 smbfs_attrcache_remove(np);
1113 }
1114
1115 if (have_fid) {
1116 cerror = smbfs_smb_tmpclose(np, fid, &scred);
1117 if (cerror)
1118 SMBVDEBUG("error %d closing %s\n",
1119 cerror, np->n_rpath);
1120 }
1121
1122 smb_credrele(&scred);
1123 smbfs_rw_exit(&np->r_lkserlock);
1124
1125 return (error);
1126 }
1127
1128 /*
1129 * Helper function for extensible system attributes (PSARC 2007/315)
1130 * Compute the DOS attribute word to pass to _setfattr (see above).
1131 * This returns zero IFF no change is being made to attributes.
1132 * Otherwise return the new attributes or SMB_EFA_NORMAL.
1133 */
1134 static uint32_t
1135 xvattr_to_dosattr(smbnode_t *np, struct vattr *vap)
1136 {
1137 xvattr_t *xvap = (xvattr_t *)vap;
1138 xoptattr_t *xoap = NULL;
1139 uint32_t attr = np->r_attr.fa_attr;
1140 boolean_t anyset = B_FALSE;
1141
1142 if ((xoap = xva_getxoptattr(xvap)) == NULL)
1143 return (0);
1144
1191 * due to the current "single user mounts" restriction:
1192 * All access under a given mount point uses the CIFS
1193 * credentials established by the owner of the mount.
1194 *
1195 * Most access checking is handled by the CIFS server,
1196 * but we need sufficient Unix access checks here to
1197 * prevent other local Unix users from having access
1198 * to objects under this mount that the uid/gid/mode
1199 * settings in the mount would not allow.
1200 *
1201 * With this model, there is a case where we need the
1202 * ability to do an access check before we have the
1203 * vnode for an object. This function takes advantage
1204 * of the fact that the uid/gid/mode is per mount, and
1205 * avoids the need for a vnode.
1206 *
1207 * We still (sort of) need a vnode when we call
1208 * secpolicy_vnode_access, but that only uses
1209 * the vtype field, so we can use a pair of fake
1210 * vnodes that have only v_type filled in.
1211 *
1212 * XXX: Later, add a new secpolicy_vtype_access()
1213 * that takes the vtype instead of a vnode, and
1214 * get rid of the tmpl_vxxx fake vnodes below.
1215 */
1216 static int
1217 smbfs_access_rwx(vfs_t *vfsp, int vtype, int mode, cred_t *cr)
1218 {
1219 /* See the secpolicy call below. */
1220 static const vnode_t tmpl_vdir = { .v_type = VDIR };
1221 static const vnode_t tmpl_vreg = { .v_type = VREG };
1222 vattr_t va;
1223 vnode_t *tvp;
1224 struct smbmntinfo *smi = VFTOSMI(vfsp);
1225 int shift = 0;
1226
1227 /*
1228 * Build our (fabricated) vnode attributes.
1229 * XXX: Could make these templates in the
1230 * per-mount struct and use them here.
1231 */
1232 bzero(&va, sizeof (va));
1233 va.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
1234 va.va_type = vtype;
1235 va.va_mode = (vtype == VDIR) ?
1236 smi->smi_dmode : smi->smi_fmode;
1237 va.va_uid = smi->smi_uid;
1238 va.va_gid = smi->smi_gid;
1239
1240 /*
1241 * Disallow write attempts on read-only file systems,
1242 * unless the file is a device or fifo node. Note:
1243 * Inline vn_is_readonly and IS_DEVVP here because
1244 * we may not have a vnode ptr. Original expr. was:
1245 * (mode & VWRITE) && vn_is_readonly(vp) && !IS_DEVVP(vp))
1246 */
1247 if ((mode & VWRITE) &&
1248 (vfsp->vfs_flag & VFS_RDONLY) &&
1249 !(vtype == VCHR || vtype == VBLK || vtype == VFIFO))
1250 return (EROFS);
1251
1252 /*
1253 * Disallow attempts to access mandatory lock files.
1254 * Similarly, expand MANDLOCK here.
1255 * XXX: not sure we need this.
1256 */
1257 if ((mode & (VWRITE | VREAD | VEXEC)) &&
1258 va.va_type == VREG && MANDMODE(va.va_mode))
1259 return (EACCES);
1260
1261 /*
1262 * Access check is based on only
1263 * one of owner, group, public.
1264 * If not owner, then check group.
1265 * If not a member of the group,
1266 * then check public access.
1267 */
1268 if (crgetuid(cr) != va.va_uid) {
1269 shift += 3;
1270 if (!groupmember(va.va_gid, cr))
1271 shift += 3;
1272 }
1273
1274 /*
1275 * We need a vnode for secpolicy_vnode_access,
1305 /* ARGSUSED */
1306 static int
1307 smbfs_access(vnode_t *vp, int mode, int flags, cred_t *cr, caller_context_t *ct)
1308 {
1309 vfs_t *vfsp;
1310 smbmntinfo_t *smi;
1311
1312 vfsp = vp->v_vfsp;
1313 smi = VFTOSMI(vfsp);
1314
1315 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
1316 return (EIO);
1317
1318 if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED)
1319 return (EIO);
1320
1321 return (smbfs_access_rwx(vfsp, vp->v_type, mode, cr));
1322 }
1323
1324
1325 /*
1326 * Flush local dirty pages to stable storage on the server.
1327 *
1328 * If FNODSYNC is specified, then there is nothing to do because
1329 * metadata changes are not cached on the client before being
1330 * sent to the server.
1331 */
1332 /* ARGSUSED */
1333 static int
1334 smbfs_fsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct)
1335 {
1336 int error = 0;
1337 smbmntinfo_t *smi;
1338 smbnode_t *np;
1339 struct smb_cred scred;
1340
1341 np = VTOSMB(vp);
1342 smi = VTOSMI(vp);
1343
1344 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
1345 return (EIO);
1346
1347 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
1348 return (EIO);
1349
1350 if ((syncflag & FNODSYNC) || IS_SWAPVP(vp))
1351 return (0);
1352
1353 if ((syncflag & (FSYNC|FDSYNC)) == 0)
1354 return (0);
1355
1356 /* Shared lock for n_fid use in _flush */
1357 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
1358 return (EINTR);
1359 smb_credinit(&scred, cr);
1360
1361 error = smbfs_smb_flush(np, &scred);
1362
1363 smb_credrele(&scred);
1364 smbfs_rw_exit(&np->r_lkserlock);
1365
1366 return (error);
1367 }
1368
1369 /*
1370 * Last reference to vnode went away.
1371 */
1372 /* ARGSUSED */
1373 static void
1374 smbfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
1375 {
1376 smbnode_t *np;
1377 struct smb_cred scred;
1378
1379 /*
1380 * Don't "bail out" for VFS_UNMOUNTED here,
1381 * as we want to do cleanup, etc.
1382 * See also pcfs_inactive
1383 */
1384
1385 np = VTOSMB(vp);
1386
1387 /*
1388 * If this is coming from the wrong zone, we let someone in the right
1389 * zone take care of it asynchronously. We can get here due to
1390 * VN_RELE() being called from pageout() or fsflush(). This call may
1391 * potentially turn into an expensive no-op if, for instance, v_count
1392 * gets incremented in the meantime, but it's still correct.
1393 */
1394
1395 /*
1396 * Defend against the possibility that higher-level callers
1397 * might not correctly balance open and close calls. If we
1398 * get here with open references remaining, it means there
1399 * was a missing VOP_CLOSE somewhere. If that happens, do
1400 * the close here so we don't "leak" FIDs on the server.
1401 *
1402 * Exclusive lock for modifying n_fid stuff.
1403 * Don't want this one ever interruptible.
1404 */
1405 (void) smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, 0);
1406 smb_credinit(&scred, cr);
1407
1408 switch (np->n_ovtype) {
1409 case VNON:
1410 /* not open (OK) */
1411 break;
1412
1413 case VDIR:
1414 if (np->n_dirrefs == 0)
1415 break;
1523 int rplen;
1524 struct smb_cred scred;
1525 struct smbfattr fa;
1526
1527 smi = VTOSMI(dvp);
1528 dnp = VTOSMB(dvp);
1529
1530 ASSERT(curproc->p_zone == smi->smi_zone_ref.zref_zone);
1531
1532 #ifdef NOT_YET
1533 vcp = SSTOVC(smi->smi_share);
1534
1535 /* XXX: Should compute this once and store it in smbmntinfo_t */
1536 supplen = (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN2_0) ? 255 : 12;
1537 #else
1538 supplen = 255;
1539 #endif
1540
1541 /*
1542 * RWlock must be held, either reader or writer.
1543 * XXX: Can we check without looking directly
1544 * inside the struct smbfs_rwlock_t?
1545 */
1546 ASSERT(dnp->r_rwlock.count != 0);
1547
1548 /*
1549 * If lookup is for "", just return dvp.
1550 * No need to perform any access checks.
1551 */
1552 if (nmlen == 0) {
1553 VN_HOLD(dvp);
1554 *vpp = dvp;
1555 return (0);
1556 }
1557
1558 /*
1559 * Can't do lookups in non-directories.
1560 */
1561 if (dvp->v_type != VDIR)
1562 return (ENOTDIR);
1563
1564 /*
1571 /*
1572 * If lookup is for ".", just return dvp.
1573 * Access check was done above.
1574 */
1575 if (nmlen == 1 && name[0] == '.') {
1576 VN_HOLD(dvp);
1577 *vpp = dvp;
1578 return (0);
1579 }
1580
1581 /*
1582 * Now some sanity checks on the name.
1583 * First check the length.
1584 */
1585 if (nmlen > supplen)
1586 return (ENAMETOOLONG);
1587
1588 /*
1589 * Avoid surprises with characters that are
1590 * illegal in Windows file names.
1591 * Todo: CATIA mappings XXX
1592 */
1593 ill = illegal_chars;
1594 if (dnp->n_flag & N_XATTR)
1595 ill++; /* allow colon */
1596 if (strpbrk(nm, ill))
1597 return (EINVAL);
1598
1599 /*
1600 * Special handling for lookup of ".."
1601 *
1602 * We keep full pathnames (as seen on the server)
1603 * so we can just trim off the last component to
1604 * get the full pathname of the parent. Note:
1605 * We don't actually copy and modify, but just
1606 * compute the trimmed length and pass that with
1607 * the current dir path (not null terminated).
1608 *
1609 * We don't go over-the-wire to get attributes
1610 * for ".." because we know it's a directory,
1611 * and we can just leave the rest "stale"
1792 if (np->r_attrtime <= gethrtime()) {
1793 /* stale */
1794 #ifdef DEBUG
1795 smbfs_lookup_cache_stale++;
1796 #endif
1797 VN_RELE(vp);
1798 return (0);
1799 }
1800
1801 /*
1802 * Success!
1803 * Caller gets hold from smbfs_node_findcreate
1804 */
1805 #ifdef DEBUG
1806 smbfs_lookup_cache_hits++;
1807 #endif
1808 *vpp = vp;
1809 return (0);
1810 }
1811
1812 /*
1813 * XXX
1814 * vsecattr_t is new to build 77, and we need to eventually support
1815 * it in order to create an ACL when an object is created.
1816 *
1817 * This op should support the new FIGNORECASE flag for case-insensitive
1818 * lookups, per PSARC 2007/244.
1819 */
1820 /* ARGSUSED */
1821 static int
1822 smbfs_create(vnode_t *dvp, char *nm, struct vattr *va, enum vcexcl exclusive,
1823 int mode, vnode_t **vpp, cred_t *cr, int lfaware, caller_context_t *ct,
1824 vsecattr_t *vsecp)
1825 {
1826 int error;
1827 int cerror;
1828 vfs_t *vfsp;
1829 vnode_t *vp;
1830 #ifdef NOT_YET
1831 smbnode_t *np;
1832 #endif
1833 smbnode_t *dnp;
1834 smbmntinfo_t *smi;
1835 struct vattr vattr;
1836 struct smbfattr fattr;
1837 struct smb_cred scred;
1838 const char *name = (const char *)nm;
1839 int nmlen = strlen(nm);
1840 uint32_t disp;
1841 uint16_t fid;
1842 int xattr;
1843
1844 vfsp = dvp->v_vfsp;
1845 smi = VFTOSMI(vfsp);
1846 dnp = VTOSMB(dvp);
1847 vp = NULL;
1848
1849 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
1850 return (EPERM);
1851
1852 if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED)
1853 return (EIO);
1854
1855 /*
1856 * Note: this may break mknod(2) calls to create a directory,
1857 * but that's obscure use. Some other filesystems do this.
1858 * XXX: Later, redirect VDIR type here to _mkdir.
1859 */
1860 if (va->va_type != VREG)
1861 return (EINVAL);
1862
1863 /*
1864 * If the pathname is "", just use dvp, no checks.
1865 * Do this outside of the rwlock (like zfs).
1866 */
1867 if (nmlen == 0) {
1868 VN_HOLD(dvp);
1869 *vpp = dvp;
1870 return (0);
1871 }
1872
1873 /* Don't allow "." or ".." through here. */
1874 if ((nmlen == 1 && name[0] == '.') ||
1875 (nmlen == 2 && name[0] == '.' && name[1] == '.'))
1876 return (EISDIR);
1877
1878 /*
1903 * The file already exists. Error?
1904 * NB: have a hold from smbfslookup
1905 */
1906 if (exclusive == EXCL) {
1907 error = EEXIST;
1908 VN_RELE(vp);
1909 goto out;
1910 }
1911 /*
1912 * Verify requested access.
1913 */
1914 error = smbfs_access(vp, mode, 0, cr, ct);
1915 if (error) {
1916 VN_RELE(vp);
1917 goto out;
1918 }
1919
1920 /*
1921 * Truncate (if requested).
1922 */
1923 if ((vattr.va_mask & AT_SIZE) && vattr.va_size == 0) {
1924 vattr.va_mask = AT_SIZE;
1925 error = smbfssetattr(vp, &vattr, 0, cr);
1926 if (error) {
1927 VN_RELE(vp);
1928 goto out;
1929 }
1930 }
1931 /* Success! */
1932 #ifdef NOT_YET
1933 vnevent_create(vp, ct);
1934 #endif
1935 *vpp = vp;
1936 goto out;
1937 }
1938
1939 /*
1940 * The file did not exist. Need VWRITE in the directory.
1941 */
1942 error = smbfs_access(dvp, VWRITE, 0, cr, ct);
1943 if (error)
1944 goto out;
1945
1946 /*
1947 * Now things get tricky. We also need to check the
1948 * requested open mode against the file we may create.
1949 * See comments at smbfs_access_rwx
1950 */
1951 error = smbfs_access_rwx(vfsp, VREG, mode, cr);
1952 if (error)
1953 goto out;
1954
1963
1964 if (exclusive == EXCL)
1965 disp = NTCREATEX_DISP_CREATE;
1966 else {
1967 /* Truncate regular files if requested. */
1968 if ((va->va_type == VREG) &&
1969 (va->va_mask & AT_SIZE) &&
1970 (va->va_size == 0))
1971 disp = NTCREATEX_DISP_OVERWRITE_IF;
1972 else
1973 disp = NTCREATEX_DISP_OPEN_IF;
1974 }
1975 xattr = (dnp->n_flag & N_XATTR) ? 1 : 0;
1976 error = smbfs_smb_create(dnp,
1977 name, nmlen, xattr,
1978 disp, &scred, &fid);
1979 if (error)
1980 goto out;
1981
1982 /*
1983 * XXX: Missing some code here to deal with
1984 * the case where we opened an existing file,
1985 * it's size is larger than 32-bits, and we're
1986 * setting the size from a process that's not
1987 * aware of large file offsets. i.e.
1988 * from the NFS3 code:
1989 */
1990 #if NOT_YET /* XXX */
1991 if ((vattr.va_mask & AT_SIZE) &&
1992 vp->v_type == VREG) {
1993 np = VTOSMB(vp);
1994 /*
1995 * Check here for large file handled
1996 * by LF-unaware process (as
1997 * ufs_create() does)
1998 */
1999 if (!(lfaware & FOFFMAX)) {
2000 mutex_enter(&np->r_statelock);
2001 if (np->r_size > MAXOFF32_T)
2002 error = EOVERFLOW;
2003 mutex_exit(&np->r_statelock);
2004 }
2005 if (!error) {
2006 vattr.va_mask = AT_SIZE;
2007 error = smbfssetattr(vp,
2008 &vattr, 0, cr);
2009 }
2010 }
2011 #endif /* XXX */
2012 /*
2013 * Should use the fid to get/set the size
2014 * while we have it opened here. See above.
2015 */
2016
2017 cerror = smbfs_smb_close(smi->smi_share, fid, NULL, &scred);
2018 if (cerror)
2019 SMBVDEBUG("error %d closing %s\\%s\n",
2020 cerror, dnp->n_rpath, name);
2021
2022 /*
2023 * In the open case, the name may differ a little
2024 * from what we passed to create (case, etc.)
2025 * so call lookup to get the (opened) name.
2026 *
2027 * XXX: Could avoid this extra lookup if the
2028 * "createact" result from NT_CREATE says we
2029 * created the object.
2030 */
2031 error = smbfs_smb_lookup(dnp, &name, &nmlen, &fattr, &scred);
2032 if (error)
2033 goto out;
2034
2035 /* update attr and directory cache */
2036 smbfs_attr_touchdir(dnp);
2037
2038 error = smbfs_nget(dvp, name, nmlen, &fattr, &vp);
2039 if (error)
2040 goto out;
2041
2042 /* XXX invalidate pages if we truncated? */
2043
2044 /* Success! */
2045 *vpp = vp;
2046 error = 0;
2047
2048 out:
2049 smb_credrele(&scred);
2050 smbfs_rw_exit(&dnp->r_rwlock);
2051 if (name != nm)
2052 smbfs_name_free(name, nmlen);
2053 return (error);
2054 }
2055
2056 /*
2057 * XXX
2058 * This op should support the new FIGNORECASE flag for case-insensitive
2059 * lookups, per PSARC 2007/244.
2060 */
2061 /* ARGSUSED */
2062 static int
2063 smbfs_remove(vnode_t *dvp, char *nm, cred_t *cr, caller_context_t *ct,
2129 int flags)
2130 {
2131 smbnode_t *dnp = VTOSMB(dvp);
2132 smbnode_t *np = VTOSMB(vp);
2133 char *tmpname = NULL;
2134 int tnlen;
2135 int error;
2136 unsigned short fid;
2137 boolean_t have_fid = B_FALSE;
2138 boolean_t renamed = B_FALSE;
2139
2140 /*
2141 * The dvp RWlock must be held as writer.
2142 */
2143 ASSERT(dnp->r_rwlock.owner == curthread);
2144
2145 /* Never allow link/unlink directories on SMB. */
2146 if (vp->v_type == VDIR)
2147 return (EPERM);
2148
2149 /* Shared lock for n_fid use in smbfs_smb_setdisp etc. */
2150 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
2151 return (EINTR);
2152
2153 /* Force lookup to go OtW */
2154 smbfs_attrcache_remove(np);
2155
2156 /*
2157 * Get a file handle with delete access.
2158 * Close this FID before return.
2159 */
2160 error = smbfs_smb_tmpopen(np, STD_RIGHT_DELETE_ACCESS,
2161 scred, &fid);
2162 if (error) {
2163 SMBVDEBUG("error %d opening %s\n",
2164 error, np->n_rpath);
2165 goto out;
2166 }
2167 have_fid = B_TRUE;
2168
2169 /*
2170 * If we have the file open, try to rename it to a temporary name.
2171 * If we can't rename, continue on and try setting DoC anyway.
2172 */
2173 if ((vp->v_count > 1) && (np->n_fidrefs > 0)) {
2174 tmpname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
2175 tnlen = smbfs_newname(tmpname, MAXNAMELEN);
2198 * the separator ('/' or ':')
2199 */
2200 if (renamed) {
2201 char *oldname;
2202 int oldnlen;
2203 int err2;
2204
2205 oldname = np->n_rpath + (dnp->n_rplen + 1);
2206 oldnlen = np->n_rplen - (dnp->n_rplen + 1);
2207 err2 = smbfs_smb_t2rename(np, oldname, oldnlen,
2208 scred, fid, 0);
2209 SMBVDEBUG("error %d un-renaming %s -> %s\n",
2210 err2, tmpname, np->n_rpath);
2211 }
2212 error = EBUSY;
2213 goto out;
2214 }
2215 /* Done! */
2216 smbfs_attrcache_prune(np);
2217
2218 out:
2219 if (tmpname != NULL)
2220 kmem_free(tmpname, MAXNAMELEN);
2221
2222 if (have_fid)
2223 (void) smbfs_smb_tmpclose(np, fid, scred);
2224 smbfs_rw_exit(&np->r_lkserlock);
2225
2226 if (error == 0) {
2227 /* Keep lookup from finding this node anymore. */
2228 smbfs_rmhash(np);
2229 }
2230
2231 return (error);
2232 }
2233
2234
2235 /*
2236 * XXX
2237 * This op should support the new FIGNORECASE flag for case-insensitive
2238 * lookups, per PSARC 2007/244.
2239 */
2240 /* ARGSUSED */
2241 static int
2242 smbfs_rename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm, cred_t *cr,
2243 caller_context_t *ct, int flags)
2244 {
2245 struct smb_cred scred;
2246 smbnode_t *odnp = VTOSMB(odvp);
2247 smbnode_t *ndnp = VTOSMB(ndvp);
2248 vnode_t *ovp;
2249 int error;
2250
2251 if (curproc->p_zone != VTOSMI(odvp)->smi_zone_ref.zref_zone ||
2252 curproc->p_zone != VTOSMI(ndvp)->smi_zone_ref.zref_zone)
2253 return (EPERM);
2254
2407 */
2408 if (nvp->v_type == VDIR) {
2409 error = EEXIST;
2410 goto out;
2411 }
2412 error = smbfsremove(ndvp, nvp, scred, flags);
2413 if (error != 0)
2414 goto out;
2415
2416 /*
2417 * OK, removed the target file. Continue as if
2418 * lookup target had failed (nvp == NULL).
2419 */
2420 vn_vfsunlock(nvp);
2421 nvp_locked = 0;
2422 VN_RELE(nvp);
2423 nvp = NULL;
2424 } /* nvp */
2425
2426 smbfs_attrcache_remove(onp);
2427
2428 error = smbfs_smb_rename(onp, ndnp, nnm, strlen(nnm), scred);
2429
2430 /*
2431 * If the old name should no longer exist,
2432 * discard any cached attributes under it.
2433 */
2434 if (error == 0)
2435 smbfs_attrcache_prune(onp);
2436
2437 out:
2438 if (nvp) {
2439 if (nvp_locked)
2440 vn_vfsunlock(nvp);
2441 VN_RELE(nvp);
2442 }
2443
2444 return (error);
2445 }
2446
2447 /*
2448 * XXX
2449 * vsecattr_t is new to build 77, and we need to eventually support
2450 * it in order to create an ACL when an object is created.
2451 *
2452 * This op should support the new FIGNORECASE flag for case-insensitive
2453 * lookups, per PSARC 2007/244.
2454 */
2455 /* ARGSUSED */
2468
2469 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
2470 return (EPERM);
2471
2472 if (smi->smi_flags & SMI_DEAD || dvp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
2473 return (EIO);
2474
2475 if ((nmlen == 1 && name[0] == '.') ||
2476 (nmlen == 2 && name[0] == '.' && name[1] == '.'))
2477 return (EEXIST);
2478
2479 /* Only plain files are allowed in V_XATTRDIR. */
2480 if (dvp->v_flag & V_XATTRDIR)
2481 return (EINVAL);
2482
2483 if (smbfs_rw_enter_sig(&dnp->r_rwlock, RW_WRITER, SMBINTR(dvp)))
2484 return (EINTR);
2485 smb_credinit(&scred, cr);
2486
2487 /*
2488 * XXX: Do we need r_lkserlock too?
2489 * No use of any shared fid or fctx...
2490 */
2491
2492 /*
2493 * Require write access in the containing directory.
2494 */
2495 error = smbfs_access(dvp, VWRITE, 0, cr, ct);
2496 if (error)
2497 goto out;
2498
2499 error = smbfs_smb_mkdir(dnp, name, nmlen, &scred);
2500 if (error)
2501 goto out;
2502
2503 error = smbfs_smb_lookup(dnp, &name, &nmlen, &fattr, &scred);
2504 if (error)
2505 goto out;
2506
2507 smbfs_attr_touchdir(dnp);
2508
2509 error = smbfs_nget(dvp, name, nmlen, &fattr, &vp);
2510 if (error)
2511 goto out;
2512
2615 dnp->n_flag |= NMODIFIED;
2616 mutex_exit(&np->r_statelock);
2617 smbfs_attr_touchdir(dnp);
2618 smbfs_rmhash(np);
2619
2620 out:
2621 if (vp) {
2622 if (vp_locked)
2623 vn_vfsunlock(vp);
2624 VN_RELE(vp);
2625 }
2626 smb_credrele(&scred);
2627 smbfs_rw_exit(&dnp->r_rwlock);
2628
2629 return (error);
2630 }
2631
2632
2633 /* ARGSUSED */
2634 static int
2635 smbfs_readdir(vnode_t *vp, struct uio *uiop, cred_t *cr, int *eofp,
2636 caller_context_t *ct, int flags)
2637 {
2638 struct smbnode *np = VTOSMB(vp);
2639 int error = 0;
2640 smbmntinfo_t *smi;
2641
2642 smi = VTOSMI(vp);
2643
2644 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
2645 return (EIO);
2646
2647 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
2648 return (EIO);
2649
2650 /*
2651 * Require read access in the directory.
2652 */
2653 error = smbfs_access(vp, VREAD, 0, cr, ct);
2654 if (error)
2655 return (error);
2656
2657 ASSERT(smbfs_rw_lock_held(&np->r_rwlock, RW_READER));
2658
2659 /*
2660 * XXX: Todo readdir cache here
2661 * Note: NFS code is just below this.
2662 *
2663 * I am serializing the entire readdir opreation
2664 * now since we have not yet implemented readdir
2665 * cache. This fix needs to be revisited once
2666 * we implement readdir cache.
2667 */
2668 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, SMBINTR(vp)))
2669 return (EINTR);
2670
2671 error = smbfs_readvdir(vp, uiop, cr, eofp, ct);
2672
2673 smbfs_rw_exit(&np->r_lkserlock);
2674
2675 return (error);
2676 }
2677
2678 /* ARGSUSED */
2679 static int
2680 smbfs_readvdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
2681 caller_context_t *ct)
2875 }
2876 /*
2877 * If we encountered an error (i.e. "access denied")
2878 * from the FindFirst call, we will have copied out
2879 * the "." and ".." entries leaving offset == 2.
2880 * In that case, restore the original offset/resid
2881 * so the caller gets no data with the error.
2882 */
2883 if (error != 0 && offset == FIRST_DIROFS) {
2884 uio->uio_loffset = save_offset;
2885 uio->uio_resid = save_resid;
2886 }
2887 SMBVDEBUG("out: offset=%d, resid=%d\n",
2888 (int)uio->uio_offset, (int)uio->uio_resid);
2889
2890 kmem_free(dp, dbufsiz);
2891 smb_credrele(&scred);
2892 return (error);
2893 }
2894
2895
2896 /*
2897 * The pair of functions VOP_RWLOCK, VOP_RWUNLOCK
2898 * are optional functions that are called by:
2899 * getdents, before/after VOP_READDIR
2900 * pread, before/after ... VOP_READ
2901 * pwrite, before/after ... VOP_WRITE
2902 * (other places)
2903 *
2904 * Careful here: None of the above check for any
2905 * error returns from VOP_RWLOCK / VOP_RWUNLOCK!
2906 * In fact, the return value from _rwlock is NOT
2907 * an error code, but V_WRITELOCK_TRUE / _FALSE.
2908 *
2909 * Therefore, it's up to _this_ code to make sure
2910 * the lock state remains balanced, which means
2911 * we can't "bail out" on interrupts, etc.
2912 */
2913
2914 /* ARGSUSED2 */
2915 static int
2949 return (EPERM);
2950
2951 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
2952 return (EIO);
2953
2954 /*
2955 * Because we stuff the readdir cookie into the offset field
2956 * someone may attempt to do an lseek with the cookie which
2957 * we want to succeed.
2958 */
2959 if (vp->v_type == VDIR)
2960 return (0);
2961
2962 /* Like NFS3, just check for 63-bit overflow. */
2963 if (*noffp < 0)
2964 return (EINVAL);
2965
2966 return (0);
2967 }
2968
2969
2970 /*
2971 * XXX
2972 * This op may need to support PSARC 2007/440, nbmand changes for CIFS Service.
2973 */
2974 static int
2975 smbfs_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
2976 offset_t offset, struct flk_callback *flk_cbp, cred_t *cr,
2977 caller_context_t *ct)
2978 {
2979 if (curproc->p_zone != VTOSMI(vp)->smi_zone_ref.zref_zone)
2980 return (EIO);
2981
2982 if (VTOSMI(vp)->smi_flags & SMI_LLOCK)
2983 return (fs_frlock(vp, cmd, bfp, flag, offset, flk_cbp, cr, ct));
2984 else
2985 return (ENOSYS);
2986 }
2987
2988 /*
2989 * Free storage space associated with the specified vnode. The portion
2990 * to be freed is specified by bfp->l_start and bfp->l_len (already
3020 */
3021
3022 error = convoff(vp, bfp, 0, offset);
3023 if (!error) {
3024 ASSERT(bfp->l_start >= 0);
3025 if (bfp->l_len == 0) {
3026 struct vattr va;
3027
3028 /*
3029 * ftruncate should not change the ctime and
3030 * mtime if we truncate the file to its
3031 * previous size.
3032 */
3033 va.va_mask = AT_SIZE;
3034 error = smbfsgetattr(vp, &va, cr);
3035 if (error || va.va_size == bfp->l_start)
3036 return (error);
3037 va.va_mask = AT_SIZE;
3038 va.va_size = bfp->l_start;
3039 error = smbfssetattr(vp, &va, 0, cr);
3040 } else
3041 error = EINVAL;
3042 }
3043
3044 return (error);
3045 }
3046
3047 /* ARGSUSED */
3048 static int
3049 smbfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
3050 caller_context_t *ct)
3051 {
3052 vfs_t *vfs;
3053 smbmntinfo_t *smi;
3054 struct smb_share *ssp;
3055
3056 vfs = vp->v_vfsp;
3057 smi = VFTOSMI(vfs);
3058
3059 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
3060 return (EIO);
3061
3062 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
3063 return (EIO);
3064
3065 switch (cmd) {
3066 case _PC_FILESIZEBITS:
3067 ssp = smi->smi_share;
3068 if (SSTOVC(ssp)->vc_sopt.sv_caps & SMB_CAP_LARGE_FILES)
3203 return (error);
3204 }
3205
3206
3207 /*
3208 * XXX
3209 * This op should eventually support PSARC 2007/268.
3210 */
3211 static int
3212 smbfs_shrlock(vnode_t *vp, int cmd, struct shrlock *shr, int flag, cred_t *cr,
3213 caller_context_t *ct)
3214 {
3215 if (curproc->p_zone != VTOSMI(vp)->smi_zone_ref.zref_zone)
3216 return (EIO);
3217
3218 if (VTOSMI(vp)->smi_flags & SMI_LLOCK)
3219 return (fs_shrlock(vp, cmd, shr, flag, cr, ct));
3220 else
3221 return (ENOSYS);
3222 }
|
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/zone.h>
62 #include <sys/vmsystm.h>
63
64 #include <vm/hat.h>
65 #include <vm/as.h>
66 #include <vm/page.h>
67 #include <vm/pvn.h>
68 #include <vm/seg.h>
69 #include <vm/seg_map.h>
70 #include <vm/seg_kpm.h>
71 #include <vm/seg_vn.h>
72
73 #include <netsmb/smb_osdep.h>
74 #include <netsmb/smb.h>
75 #include <netsmb/smb_conn.h>
76 #include <netsmb/smb_subr.h>
77
78 #include <smbfs/smbfs.h>
79 #include <smbfs/smbfs_node.h>
80 #include <smbfs/smbfs_subr.h>
81
82 #include <sys/fs/smbfs_ioctl.h>
83 #include <fs/fs_subr.h>
84
85 /*
86 * We assign directory offsets like the NFS client, where the
87 * offset increments by _one_ after each directory entry.
88 * Further, the entries "." and ".." are always at offsets
89 * zero and one (respectively) and the "real" entries from
90 * the server appear at offsets starting with two. This
91 * macro is used to initialize the n_dirofs field after
92 * setting n_dirseq with a _findopen call.
103 static const char illegal_chars[] = {
104 ':', /* colon - keep this first! */
105 '\\', /* back slash */
106 '/', /* slash */
107 '*', /* asterisk */
108 '?', /* question mark */
109 '"', /* double quote */
110 '<', /* less than sign */
111 '>', /* greater than sign */
112 '|', /* vertical bar */
113 0
114 };
115
116 /*
117 * Turning this on causes nodes to be created in the cache
118 * during directory listings, normally avoiding a second
119 * OtW attribute fetch just after a readdir.
120 */
121 int smbfs_fastlookup = 1;
122
123 struct vnodeops *smbfs_vnodeops = NULL;
124
125 /* local static function defines */
126
127 static int smbfslookup_cache(vnode_t *, char *, int, vnode_t **,
128 cred_t *);
129 static int smbfslookup(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr,
130 int cache_ok, caller_context_t *);
131 static int smbfsremove(vnode_t *dvp, vnode_t *vp, struct smb_cred *scred,
132 int flags);
133 static int smbfsrename(vnode_t *odvp, vnode_t *ovp, vnode_t *ndvp,
134 char *nnm, struct smb_cred *scred, int flags);
135 static int smbfssetattr(vnode_t *, struct vattr *, int, cred_t *);
136 static int smbfs_accessx(void *, int, cred_t *);
137 static int smbfs_readvdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
138 caller_context_t *);
139 static void smbfs_rele_fid(smbnode_t *, struct smb_cred *);
140 static uint32_t xvattr_to_dosattr(smbnode_t *, struct vattr *);
141
142 static int smbfs_rdwrlbn(vnode_t *, page_t *, u_offset_t, size_t, int,
143 cred_t *);
144 static int smbfs_bio(struct buf *, int, cred_t *);
145 static int smbfs_writenp(smbnode_t *np, caddr_t base, int tcount,
146 struct uio *uiop, int pgcreated);
147
148 static int smbfs_fsync(vnode_t *, int, cred_t *, caller_context_t *);
149 static int smbfs_putpage(vnode_t *, offset_t, size_t, int, cred_t *,
150 caller_context_t *);
151 static int smbfs_getapage(vnode_t *, u_offset_t, size_t, uint_t *,
152 page_t *[], size_t, struct seg *, caddr_t,
153 enum seg_rw, cred_t *);
154 static int smbfs_putapage(vnode_t *, page_t *, u_offset_t *, size_t *,
155 int, cred_t *);
156 static void smbfs_delmap_callback(struct as *, void *, uint_t);
157
158 /*
159 * Error flags used to pass information about certain special errors
160 * which need to be handled specially.
161 */
162 #define SMBFS_EOF -98
163
164 /* When implementing OtW locks, make this a real function. */
165 #define smbfs_lm_has_sleep(vp) 0
166
167 /*
168 * These are the vnode ops routines which implement the vnode interface to
169 * the networked file system. These routines just take their parameters,
170 * make them look networkish by putting the right info into interface structs,
171 * and then calling the appropriate remote routine(s) to do the work.
172 *
173 * Note on directory name lookup cacheing: If we detect a stale fhandle,
174 * we purge the directory cache relative to that vnode. This way, the
175 * user won't get burned by the cache repeatedly. See <smbfs/smbnode.h> for
176 * more details on smbnode locking.
177 */
178
179
180 /*
181 * XXX
182 * When new and relevant functionality is enabled, we should be
183 * calling vfs_set_feature() to inform callers that pieces of
184 * functionality are available, per PSARC 2007/227.
185 */
186 /* ARGSUSED */
187 static int
188 smbfs_open(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct)
189 {
190 smbnode_t *np;
191 vnode_t *vp;
192 smbfattr_t fa;
193 u_int32_t rights, rightsrcvd;
194 u_int16_t fid, oldfid;
195 int oldgenid;
196 struct smb_cred scred;
197 smbmntinfo_t *smi;
198 smb_share_t *ssp;
199 cred_t *oldcr;
200 int tmperror;
212 return (EIO);
213
214 if (vp->v_type != VREG && vp->v_type != VDIR) { /* XXX VLNK? */
215 SMBVDEBUG("open eacces vtype=%d\n", vp->v_type);
216 return (EACCES);
217 }
218
219 /*
220 * Get exclusive access to n_fid and related stuff.
221 * No returns after this until out.
222 */
223 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, SMBINTR(vp)))
224 return (EINTR);
225 smb_credinit(&scred, cr);
226
227 /*
228 * Keep track of the vnode type at first open.
229 * It may change later, and we need close to do
230 * cleanup for the type we opened. Also deny
231 * open of new types until old type is closed.
232 */
233 if (np->n_ovtype == VNON) {
234 ASSERT(np->n_dirrefs == 0);
235 ASSERT(np->n_fidrefs == 0);
236 } else if (np->n_ovtype != vp->v_type) {
237 SMBVDEBUG("open n_ovtype=%d v_type=%d\n",
238 np->n_ovtype, vp->v_type);
239 error = EACCES;
240 goto out;
241 }
242
243 /*
244 * Directory open. See smbfs_readvdir()
245 */
246 if (vp->v_type == VDIR) {
247 if (np->n_dirseq == NULL) {
248 /* first open */
249 error = smbfs_smb_findopen(np, "*", 1,
250 SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR,
251 &scred, &np->n_dirseq);
350 * Keep track of the vnode type at first open.
351 * (see comments above)
352 */
353 if (np->n_ovtype == VNON)
354 np->n_ovtype = vp->v_type;
355
356 out:
357 smb_credrele(&scred);
358 smbfs_rw_exit(&np->r_lkserlock);
359 return (error);
360 }
361
362 /*ARGSUSED*/
363 static int
364 smbfs_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr,
365 caller_context_t *ct)
366 {
367 smbnode_t *np;
368 smbmntinfo_t *smi;
369 struct smb_cred scred;
370 int error = 0;
371
372 np = VTOSMB(vp);
373 smi = VTOSMI(vp);
374
375 /*
376 * Don't "bail out" for VFS_UNMOUNTED here,
377 * as we want to do cleanup, etc.
378 */
379
380 /*
381 * zone_enter(2) prevents processes from changing zones with SMBFS files
382 * open; if we happen to get here from the wrong zone we can't do
383 * anything over the wire.
384 */
385 if (smi->smi_zone_ref.zref_zone != curproc->p_zone) {
386 /*
387 * We could attempt to clean up locks, except we're sure
388 * that the current process didn't acquire any locks on
389 * the file: any attempt to lock a file belong to another zone
390 * will fail, and one can't lock an SMBFS file and then change
398 * everything (minus the final smbfs_getattr_otw() call) should
399 * be OK. If the zone is going away smbfs_async_inactive() will
400 * throw away cached pages inline.
401 */
402 return (EIO);
403 }
404
405 /*
406 * If we are using local locking for this filesystem, then
407 * release all of the SYSV style record locks. Otherwise,
408 * we are doing network locking and we need to release all
409 * of the network locks. All of the locks held by this
410 * process on this file are released no matter what the
411 * incoming reference count is.
412 */
413 if (smi->smi_flags & SMI_LLOCK) {
414 pid_t pid = ddi_get_pid();
415 cleanlocks(vp, pid, 0);
416 cleanshares(vp, pid);
417 }
418 /*
419 * else doing OtW locking. SMB servers drop all locks
420 * on the file ID we close here, so no _lockrelease()
421 */
422
423 /*
424 * This (passed in) count is the ref. count from the
425 * user's file_t before the closef call (fio.c).
426 * The rest happens only on last close.
427 */
428 if (count > 1)
429 return (0);
430
431 /* NFS has DNLC purge here. */
432
433 /*
434 * If the file was open for write and there are pages,
435 * then make sure dirty pages written back.
436 *
437 * NFS does this async when "close-to-open" is off
438 * (MI_NOCTO flag is set) to avoid blocking the caller.
439 * For now, always do this synchronously (no B_ASYNC).
440 */
441 if ((flag & FWRITE) && vn_has_cached_data(vp)) {
442 error = smbfs_putpage(vp, (offset_t)0, 0, 0, cr, ct);
443 if (error == EAGAIN)
444 error = 0;
445 }
446 if (error == 0) {
447 mutex_enter(&np->r_statelock);
448 np->r_flags &= ~RSTALE;
449 np->r_error = 0;
450 mutex_exit(&np->r_statelock);
451 }
452
453 /*
454 * Decrement the reference count for the FID
455 * and possibly do the OtW close.
456 *
457 * Exclusive lock for modifying n_fid stuff.
458 * Don't want this one ever interruptible.
459 */
460 (void) smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, 0);
461 smb_credinit(&scred, cr);
462
463 smbfs_rele_fid(np, &scred);
464
465 smb_credrele(&scred);
466 smbfs_rw_exit(&np->r_lkserlock);
467
468 return (0);
469 }
470
471 /*
472 * Helper for smbfs_close. Decrement the reference count
473 * for an SMB-level file or directory ID, and when the last
544 np->r_cred = NULL;
545 mutex_exit(&np->r_statelock);
546 if (oldcr != NULL)
547 crfree(oldcr);
548 }
549
550 /* ARGSUSED */
551 static int
552 smbfs_read(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
553 caller_context_t *ct)
554 {
555 struct smb_cred scred;
556 struct vattr va;
557 smbnode_t *np;
558 smbmntinfo_t *smi;
559 smb_share_t *ssp;
560 offset_t endoff;
561 ssize_t past_eof;
562 int error;
563
564 caddr_t base;
565 u_offset_t off;
566 size_t n;
567 int on;
568 uint_t flags;
569
570 np = VTOSMB(vp);
571 smi = VTOSMI(vp);
572 ssp = smi->smi_share;
573
574 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
575 return (EIO);
576
577 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
578 return (EIO);
579
580 ASSERT(smbfs_rw_lock_held(&np->r_rwlock, RW_READER));
581
582 if (vp->v_type != VREG)
583 return (EISDIR);
584
585 if (uiop->uio_resid == 0)
586 return (0);
587
588 /*
589 * Like NFS3, just check for 63-bit overflow.
599 if (error = smbfsgetattr(vp, &va, cr))
600 return (error);
601
602 /* Update mtime with mtime from server here? */
603
604 /* if offset is beyond EOF, read nothing */
605 if (uiop->uio_loffset >= va.va_size)
606 return (0);
607
608 /*
609 * Limit the read to the remaining file size.
610 * Do this by temporarily reducing uio_resid
611 * by the amount the lies beyoned the EOF.
612 */
613 if (endoff > va.va_size) {
614 past_eof = (ssize_t)(endoff - va.va_size);
615 uiop->uio_resid -= past_eof;
616 } else
617 past_eof = 0;
618
619 /*
620 * Bypass VM if caching has been disabled (e.g., locking) or if
621 * using client-side direct I/O and the file is not mmap'd and
622 * there are no cached pages.
623 */
624 if ((vp->v_flag & VNOCACHE) ||
625 (((np->r_flags & RDIRECTIO) || (smi->smi_flags & SMI_DIRECTIO)) &&
626 np->r_mapcnt == 0 && np->r_inmap == 0 &&
627 !vn_has_cached_data(vp))) {
628
629 /* Shared lock for n_fid use in smb_rwuio */
630 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
631 return (EINTR);
632 smb_credinit(&scred, cr);
633
634 /* After reconnect, n_fid is invalid */
635 if (np->n_vcgenid != ssp->ss_vcgenid)
636 error = ESTALE;
637 else
638 error = smb_rwuio(ssp, np->n_fid, UIO_READ,
639 uiop, &scred, smb_timo_read);
640
641 smb_credrele(&scred);
642 smbfs_rw_exit(&np->r_lkserlock);
643
644 /* undo adjustment of resid */
645 uiop->uio_resid += past_eof;
646
647 return (error);
648 }
649
650 /* (else) Do I/O through segmap. */
651 do {
652 off = uiop->uio_loffset & MAXBMASK; /* mapping offset */
653 on = uiop->uio_loffset & MAXBOFFSET; /* Relative offset */
654 n = MIN(MAXBSIZE - on, uiop->uio_resid);
655
656 error = smbfs_validate_caches(vp, cr);
657 if (error)
658 break;
659
660 /* NFS waits for RINCACHEPURGE here. */
661
662 if (vpm_enable) {
663 /*
664 * Copy data.
665 */
666 error = vpm_data_copy(vp, off + on, n, uiop,
667 1, NULL, 0, S_READ);
668 } else {
669 base = segmap_getmapflt(segkmap, vp, off + on, n, 1,
670 S_READ);
671
672 error = uiomove(base + on, n, UIO_READ, uiop);
673 }
674
675 if (!error) {
676 /*
677 * If read a whole block or read to eof,
678 * won't need this buffer again soon.
679 */
680 mutex_enter(&np->r_statelock);
681 if (n + on == MAXBSIZE ||
682 uiop->uio_loffset == np->r_size)
683 flags = SM_DONTNEED;
684 else
685 flags = 0;
686 mutex_exit(&np->r_statelock);
687 if (vpm_enable) {
688 error = vpm_sync_pages(vp, off, n, flags);
689 } else {
690 error = segmap_release(segkmap, base, flags);
691 }
692 } else {
693 if (vpm_enable) {
694 (void) vpm_sync_pages(vp, off, n, 0);
695 } else {
696 (void) segmap_release(segkmap, base, 0);
697 }
698 }
699 } while (!error && uiop->uio_resid > 0);
700
701 /* undo adjustment of resid */
702 uiop->uio_resid += past_eof;
703
704 return (error);
705 }
706
707
708 /* ARGSUSED */
709 static int
710 smbfs_write(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
711 caller_context_t *ct)
712 {
713 struct smb_cred scred;
714 struct vattr va;
715 smbnode_t *np;
716 smbmntinfo_t *smi;
717 smb_share_t *ssp;
718 offset_t endoff, limit;
719 ssize_t past_limit;
720 int error, timo;
721 caddr_t base;
722 u_offset_t off;
723 size_t n;
724 int on;
725 uint_t flags;
726 u_offset_t last_off;
727 size_t last_resid;
728 uint_t bsize;
729
730 np = VTOSMB(vp);
731 smi = VTOSMI(vp);
732 ssp = smi->smi_share;
733
734 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
735 return (EIO);
736
737 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
738 return (EIO);
739
740 ASSERT(smbfs_rw_lock_held(&np->r_rwlock, RW_WRITER));
741
742 if (vp->v_type != VREG)
743 return (EISDIR);
744
745 if (uiop->uio_resid == 0)
746 return (0);
747
748 /*
749 * Handle ioflag bits: (FAPPEND|FSYNC|FDSYNC)
750 */
751 if (ioflag & (FAPPEND | FSYNC)) {
752 if (np->n_flag & NMODIFIED) {
753 smbfs_attrcache_remove(np);
754 }
755 }
756 if (ioflag & FAPPEND) {
757 /*
758 * File size can be changed by another client
759 *
760 * Todo: Consider redesigning this to use a
761 * handle opened for append instead.
762 */
763 va.va_mask = AT_SIZE;
764 if (error = smbfsgetattr(vp, &va, cr))
765 return (error);
766 uiop->uio_loffset = va.va_size;
767 }
768
769 /*
770 * Like NFS3, just check for 63-bit overflow.
771 */
772 endoff = uiop->uio_loffset + uiop->uio_resid;
773 if (uiop->uio_loffset < 0 || endoff < 0)
774 return (EINVAL);
775
776 /*
777 * Check to make sure that the process will not exceed
778 * its limit on file size. It is okay to write up to
779 * the limit, but not beyond. Thus, the write which
780 * reaches the limit will be short and the next write
781 * will return an error.
782 *
783 * So if we're starting at or beyond the limit, EFBIG.
784 * Otherwise, temporarily reduce resid to the amount
785 * that is after the limit.
786 */
787 limit = uiop->uio_llimit;
788 if (limit == RLIM64_INFINITY || limit > MAXOFFSET_T)
789 limit = MAXOFFSET_T;
790 if (uiop->uio_loffset >= limit) {
791 proc_t *p = ttoproc(curthread);
792
793 mutex_enter(&p->p_lock);
794 (void) rctl_action(rctlproc_legacy[RLIMIT_FSIZE],
795 p->p_rctls, p, RCA_UNSAFE_SIGINFO);
796 mutex_exit(&p->p_lock);
797 return (EFBIG);
798 }
799 if (endoff > limit) {
800 past_limit = (ssize_t)(endoff - limit);
801 uiop->uio_resid -= past_limit;
802 } else
803 past_limit = 0;
804
805 /*
806 * Bypass VM if caching has been disabled (e.g., locking) or if
807 * using client-side direct I/O and the file is not mmap'd and
808 * there are no cached pages.
809 */
810 if ((vp->v_flag & VNOCACHE) ||
811 (((np->r_flags & RDIRECTIO) || (smi->smi_flags & SMI_DIRECTIO)) &&
812 np->r_mapcnt == 0 && np->r_inmap == 0 &&
813 !vn_has_cached_data(vp))) {
814
815 smbfs_fwrite:
816 if (np->r_flags & RSTALE) {
817 last_resid = uiop->uio_resid;
818 last_off = uiop->uio_loffset;
819 error = np->r_error;
820 /*
821 * A close may have cleared r_error, if so,
822 * propagate ESTALE error return properly
823 */
824 if (error == 0)
825 error = ESTALE;
826 goto bottom;
827 }
828
829 /* Timeout: longer for append. */
830 timo = smb_timo_write;
831 if (endoff > np->r_size)
832 timo = smb_timo_append;
833
834 /* Shared lock for n_fid use in smb_rwuio */
835 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
836 return (EINTR);
837 smb_credinit(&scred, cr);
838
839 /* After reconnect, n_fid is invalid */
840 if (np->n_vcgenid != ssp->ss_vcgenid)
841 error = ESTALE;
842 else
843 error = smb_rwuio(ssp, np->n_fid, UIO_WRITE,
844 uiop, &scred, timo);
845
846 if (error == 0) {
847 mutex_enter(&np->r_statelock);
848 np->n_flag |= (NFLUSHWIRE | NATTRCHANGED);
849 if (uiop->uio_loffset > (offset_t)np->r_size)
850 np->r_size = (len_t)uiop->uio_loffset;
851 mutex_exit(&np->r_statelock);
852 if (ioflag & (FSYNC | FDSYNC)) {
853 /* Don't error the I/O if this fails. */
854 (void) smbfs_smb_flush(np, &scred);
855 }
856 }
857
858 smb_credrele(&scred);
859 smbfs_rw_exit(&np->r_lkserlock);
860
861 /* undo adjustment of resid */
862 uiop->uio_resid += past_limit;
863
864 return (error);
865 }
866
867 /* (else) Do I/O through segmap. */
868 bsize = vp->v_vfsp->vfs_bsize;
869
870 do {
871 off = uiop->uio_loffset & MAXBMASK; /* mapping offset */
872 on = uiop->uio_loffset & MAXBOFFSET; /* Relative offset */
873 n = MIN(MAXBSIZE - on, uiop->uio_resid);
874
875 last_resid = uiop->uio_resid;
876 last_off = uiop->uio_loffset;
877
878 if (np->r_flags & RSTALE) {
879 error = np->r_error;
880 /*
881 * A close may have cleared r_error, if so,
882 * propagate ESTALE error return properly
883 */
884 if (error == 0)
885 error = ESTALE;
886 break;
887 }
888
889 /*
890 * From NFS: Don't create dirty pages faster than they
891 * can be cleaned.
892 *
893 * Here NFS also checks for async writes (np->r_awcount)
894 */
895 mutex_enter(&np->r_statelock);
896 while (np->r_gcount > 0) {
897 if (SMBINTR(vp)) {
898 klwp_t *lwp = ttolwp(curthread);
899
900 if (lwp != NULL)
901 lwp->lwp_nostop++;
902 if (!cv_wait_sig(&np->r_cv, &np->r_statelock)) {
903 mutex_exit(&np->r_statelock);
904 if (lwp != NULL)
905 lwp->lwp_nostop--;
906 error = EINTR;
907 goto bottom;
908 }
909 if (lwp != NULL)
910 lwp->lwp_nostop--;
911 } else
912 cv_wait(&np->r_cv, &np->r_statelock);
913 }
914 mutex_exit(&np->r_statelock);
915
916 /*
917 * Touch the page and fault it in if it is not in core
918 * before segmap_getmapflt or vpm_data_copy can lock it.
919 * This is to avoid the deadlock if the buffer is mapped
920 * to the same file through mmap which we want to write.
921 */
922 uio_prefaultpages((long)n, uiop);
923
924 if (vpm_enable) {
925 /*
926 * It will use kpm mappings, so no need to
927 * pass an address.
928 */
929 error = smbfs_writenp(np, NULL, n, uiop, 0);
930 } else {
931 if (segmap_kpm) {
932 int pon = uiop->uio_loffset & PAGEOFFSET;
933 size_t pn = MIN(PAGESIZE - pon,
934 uiop->uio_resid);
935 int pagecreate;
936
937 mutex_enter(&np->r_statelock);
938 pagecreate = (pon == 0) && (pn == PAGESIZE ||
939 uiop->uio_loffset + pn >= np->r_size);
940 mutex_exit(&np->r_statelock);
941
942 base = segmap_getmapflt(segkmap, vp, off + on,
943 pn, !pagecreate, S_WRITE);
944
945 error = smbfs_writenp(np, base + pon, n, uiop,
946 pagecreate);
947
948 } else {
949 base = segmap_getmapflt(segkmap, vp, off + on,
950 n, 0, S_READ);
951 error = smbfs_writenp(np, base + on, n, uiop, 0);
952 }
953 }
954
955 if (!error) {
956 if (smi->smi_flags & SMI_NOAC)
957 flags = SM_WRITE;
958 else if ((uiop->uio_loffset % bsize) == 0 ||
959 IS_SWAPVP(vp)) {
960 /*
961 * Have written a whole block.
962 * Start an asynchronous write
963 * and mark the buffer to
964 * indicate that it won't be
965 * needed again soon.
966 */
967 flags = SM_WRITE | SM_ASYNC | SM_DONTNEED;
968 } else
969 flags = 0;
970 if ((ioflag & (FSYNC|FDSYNC)) ||
971 (np->r_flags & ROUTOFSPACE)) {
972 flags &= ~SM_ASYNC;
973 flags |= SM_WRITE;
974 }
975 if (vpm_enable) {
976 error = vpm_sync_pages(vp, off, n, flags);
977 } else {
978 error = segmap_release(segkmap, base, flags);
979 }
980 } else {
981 if (vpm_enable) {
982 (void) vpm_sync_pages(vp, off, n, 0);
983 } else {
984 (void) segmap_release(segkmap, base, 0);
985 }
986 /*
987 * In the event that we got an access error while
988 * faulting in a page for a write-only file just
989 * force a write.
990 */
991 if (error == EACCES)
992 goto smbfs_fwrite;
993 }
994 } while (!error && uiop->uio_resid > 0);
995
996 bottom:
997 /* undo adjustment of resid */
998 if (error) {
999 uiop->uio_resid = last_resid + past_limit;
1000 uiop->uio_loffset = last_off;
1001 } else {
1002 uiop->uio_resid += past_limit;
1003 }
1004
1005 return (error);
1006 }
1007
1008 /*
1009 * Like nfs_client.c: writerp()
1010 *
1011 * Write by creating pages and uiomove data onto them.
1012 */
1013
1014 int
1015 smbfs_writenp(smbnode_t *np, caddr_t base, int tcount, struct uio *uio,
1016 int pgcreated)
1017 {
1018 int pagecreate;
1019 int n;
1020 int saved_n;
1021 caddr_t saved_base;
1022 u_offset_t offset;
1023 int error;
1024 int sm_error;
1025 vnode_t *vp = SMBTOV(np);
1026
1027 ASSERT(tcount <= MAXBSIZE && tcount <= uio->uio_resid);
1028 ASSERT(smbfs_rw_lock_held(&np->r_rwlock, RW_WRITER));
1029 if (!vpm_enable) {
1030 ASSERT(((uintptr_t)base & MAXBOFFSET) + tcount <= MAXBSIZE);
1031 }
1032
1033 /*
1034 * Move bytes in at most PAGESIZE chunks. We must avoid
1035 * spanning pages in uiomove() because page faults may cause
1036 * the cache to be invalidated out from under us. The r_size is not
1037 * updated until after the uiomove. If we push the last page of a
1038 * file before r_size is correct, we will lose the data written past
1039 * the current (and invalid) r_size.
1040 */
1041 do {
1042 offset = uio->uio_loffset;
1043 pagecreate = 0;
1044
1045 /*
1046 * n is the number of bytes required to satisfy the request
1047 * or the number of bytes to fill out the page.
1048 */
1049 n = (int)MIN((PAGESIZE - (offset & PAGEOFFSET)), tcount);
1050
1051 /*
1052 * Check to see if we can skip reading in the page
1053 * and just allocate the memory. We can do this
1054 * if we are going to rewrite the entire mapping
1055 * or if we are going to write to or beyond the current
1056 * end of file from the beginning of the mapping.
1057 *
1058 * The read of r_size is now protected by r_statelock.
1059 */
1060 mutex_enter(&np->r_statelock);
1061 /*
1062 * When pgcreated is nonzero the caller has already done
1063 * a segmap_getmapflt with forcefault 0 and S_WRITE. With
1064 * segkpm this means we already have at least one page
1065 * created and mapped at base.
1066 */
1067 pagecreate = pgcreated ||
1068 ((offset & PAGEOFFSET) == 0 &&
1069 (n == PAGESIZE || ((offset + n) >= np->r_size)));
1070
1071 mutex_exit(&np->r_statelock);
1072 if (!vpm_enable && pagecreate) {
1073 /*
1074 * The last argument tells segmap_pagecreate() to
1075 * always lock the page, as opposed to sometimes
1076 * returning with the page locked. This way we avoid a
1077 * fault on the ensuing uiomove(), but also
1078 * more importantly (to fix bug 1094402) we can
1079 * call segmap_fault() to unlock the page in all
1080 * cases. An alternative would be to modify
1081 * segmap_pagecreate() to tell us when it is
1082 * locking a page, but that's a fairly major
1083 * interface change.
1084 */
1085 if (pgcreated == 0)
1086 (void) segmap_pagecreate(segkmap, base,
1087 (uint_t)n, 1);
1088 saved_base = base;
1089 saved_n = n;
1090 }
1091
1092 /*
1093 * The number of bytes of data in the last page can not
1094 * be accurately be determined while page is being
1095 * uiomove'd to and the size of the file being updated.
1096 * Thus, inform threads which need to know accurately
1097 * how much data is in the last page of the file. They
1098 * will not do the i/o immediately, but will arrange for
1099 * the i/o to happen later when this modify operation
1100 * will have finished.
1101 */
1102 ASSERT(!(np->r_flags & RMODINPROGRESS));
1103 mutex_enter(&np->r_statelock);
1104 np->r_flags |= RMODINPROGRESS;
1105 np->r_modaddr = (offset & MAXBMASK);
1106 mutex_exit(&np->r_statelock);
1107
1108 if (vpm_enable) {
1109 /*
1110 * Copy data. If new pages are created, part of
1111 * the page that is not written will be initizliazed
1112 * with zeros.
1113 */
1114 error = vpm_data_copy(vp, offset, n, uio,
1115 !pagecreate, NULL, 0, S_WRITE);
1116 } else {
1117 error = uiomove(base, n, UIO_WRITE, uio);
1118 }
1119
1120 /*
1121 * r_size is the maximum number of
1122 * bytes known to be in the file.
1123 * Make sure it is at least as high as the
1124 * first unwritten byte pointed to by uio_loffset.
1125 */
1126 mutex_enter(&np->r_statelock);
1127 if (np->r_size < uio->uio_loffset)
1128 np->r_size = uio->uio_loffset;
1129 np->r_flags &= ~RMODINPROGRESS;
1130 np->r_flags |= RDIRTY;
1131 mutex_exit(&np->r_statelock);
1132
1133 /* n = # of bytes written */
1134 n = (int)(uio->uio_loffset - offset);
1135
1136 if (!vpm_enable) {
1137 base += n;
1138 }
1139 tcount -= n;
1140 /*
1141 * If we created pages w/o initializing them completely,
1142 * we need to zero the part that wasn't set up.
1143 * This happens on a most EOF write cases and if
1144 * we had some sort of error during the uiomove.
1145 */
1146 if (!vpm_enable && pagecreate) {
1147 if ((uio->uio_loffset & PAGEOFFSET) || n == 0)
1148 (void) kzero(base, PAGESIZE - n);
1149
1150 if (pgcreated) {
1151 /*
1152 * Caller is responsible for this page,
1153 * it was not created in this loop.
1154 */
1155 pgcreated = 0;
1156 } else {
1157 /*
1158 * For bug 1094402: segmap_pagecreate locks
1159 * page. Unlock it. This also unlocks the
1160 * pages allocated by page_create_va() in
1161 * segmap_pagecreate().
1162 */
1163 sm_error = segmap_fault(kas.a_hat, segkmap,
1164 saved_base, saved_n,
1165 F_SOFTUNLOCK, S_WRITE);
1166 if (error == 0)
1167 error = sm_error;
1168 }
1169 }
1170 } while (tcount > 0 && error == 0);
1171
1172 return (error);
1173 }
1174
1175 /*
1176 * Flags are composed of {B_ASYNC, B_INVAL, B_FREE, B_DONTNEED}
1177 * Like nfs3_rdwrlbn()
1178 */
1179 static int
1180 smbfs_rdwrlbn(vnode_t *vp, page_t *pp, u_offset_t off, size_t len,
1181 int flags, cred_t *cr)
1182 {
1183 smbmntinfo_t *smi = VTOSMI(vp);
1184 struct buf *bp;
1185 int error;
1186 int sync;
1187
1188 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
1189 return (EIO);
1190
1191 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
1192 return (EIO);
1193
1194 bp = pageio_setup(pp, len, vp, flags);
1195 ASSERT(bp != NULL);
1196
1197 /*
1198 * pageio_setup should have set b_addr to 0. This
1199 * is correct since we want to do I/O on a page
1200 * boundary. bp_mapin will use this addr to calculate
1201 * an offset, and then set b_addr to the kernel virtual
1202 * address it allocated for us.
1203 */
1204 ASSERT(bp->b_un.b_addr == 0);
1205
1206 bp->b_edev = 0;
1207 bp->b_dev = 0;
1208 bp->b_lblkno = lbtodb(off);
1209 bp->b_file = vp;
1210 bp->b_offset = (offset_t)off;
1211 bp_mapin(bp);
1212
1213 /*
1214 * Calculate the desired level of stability to write data.
1215 */
1216 if ((flags & (B_WRITE|B_ASYNC)) == (B_WRITE|B_ASYNC) &&
1217 freemem > desfree) {
1218 sync = 0;
1219 } else {
1220 sync = 1;
1221 }
1222
1223 error = smbfs_bio(bp, sync, cr);
1224
1225 bp_mapout(bp);
1226 pageio_done(bp);
1227
1228 return (error);
1229 }
1230
1231
1232 /*
1233 * Corresponds to nfs3_vnopc.c : nfs3_bio(), though the NFS code
1234 * uses nfs3read()/nfs3write() where we use smb_rwuio(). Also,
1235 * NFS has this later in the file. Move it up here closer to
1236 * the one call site just above.
1237 */
1238
1239 static int
1240 smbfs_bio(struct buf *bp, int sync, cred_t *cr)
1241 {
1242 struct iovec aiov[1];
1243 struct uio auio;
1244 struct smb_cred scred;
1245 smbnode_t *np = VTOSMB(bp->b_vp);
1246 smbmntinfo_t *smi = np->n_mount;
1247 smb_share_t *ssp = smi->smi_share;
1248 offset_t offset;
1249 offset_t endoff;
1250 size_t count;
1251 size_t past_eof;
1252 int error;
1253
1254 ASSERT(curproc->p_zone == smi->smi_zone_ref.zref_zone);
1255
1256 offset = ldbtob(bp->b_lblkno);
1257 count = bp->b_bcount;
1258 endoff = offset + count;
1259 if (offset < 0 || endoff < 0)
1260 return (EINVAL);
1261
1262 /*
1263 * Limit file I/O to the remaining file size, but see
1264 * the notes in smbfs_getpage about SMBFS_EOF.
1265 */
1266 mutex_enter(&np->r_statelock);
1267 if (offset >= np->r_size) {
1268 mutex_exit(&np->r_statelock);
1269 if (bp->b_flags & B_READ) {
1270 return (SMBFS_EOF);
1271 } else {
1272 return (EINVAL);
1273 }
1274 }
1275 if (endoff > np->r_size) {
1276 past_eof = (size_t)(endoff - np->r_size);
1277 count -= past_eof;
1278 } else
1279 past_eof = 0;
1280 mutex_exit(&np->r_statelock);
1281 ASSERT(count > 0);
1282
1283 /* Caller did bpmapin(). Mapped address is... */
1284 aiov[0].iov_base = bp->b_un.b_addr;
1285 aiov[0].iov_len = count;
1286 auio.uio_iov = aiov;
1287 auio.uio_iovcnt = 1;
1288 auio.uio_loffset = offset;
1289 auio.uio_segflg = UIO_SYSSPACE;
1290 auio.uio_fmode = 0;
1291 auio.uio_resid = count;
1292
1293 /* Shared lock for n_fid use in smb_rwuio */
1294 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER,
1295 smi->smi_flags & SMI_INT))
1296 return (EINTR);
1297 smb_credinit(&scred, cr);
1298
1299 DTRACE_IO1(start, struct buf *, bp);
1300
1301 if (bp->b_flags & B_READ) {
1302
1303 /* After reconnect, n_fid is invalid */
1304 if (np->n_vcgenid != ssp->ss_vcgenid)
1305 error = ESTALE;
1306 else
1307 error = smb_rwuio(ssp, np->n_fid, UIO_READ,
1308 &auio, &scred, smb_timo_read);
1309
1310 /* Like NFS, only set b_error here. */
1311 bp->b_error = error;
1312 bp->b_resid = auio.uio_resid;
1313
1314 if (!error && auio.uio_resid != 0)
1315 error = EIO;
1316 if (!error && past_eof != 0) {
1317 /* Zero the memory beyond EOF. */
1318 bzero(bp->b_un.b_addr + count, past_eof);
1319 }
1320 } else {
1321
1322 /* After reconnect, n_fid is invalid */
1323 if (np->n_vcgenid != ssp->ss_vcgenid)
1324 error = ESTALE;
1325 else
1326 error = smb_rwuio(ssp, np->n_fid, UIO_WRITE,
1327 &auio, &scred, smb_timo_write);
1328
1329 /* Like NFS, only set b_error here. */
1330 bp->b_error = error;
1331 bp->b_resid = auio.uio_resid;
1332
1333 if (!error && auio.uio_resid != 0)
1334 error = EIO;
1335 if (!error && sync) {
1336 (void) smbfs_smb_flush(np, &scred);
1337 }
1338 }
1339
1340 /*
1341 * This comes from nfs3_commit()
1342 */
1343 if (error != 0) {
1344 mutex_enter(&np->r_statelock);
1345 if (error == ESTALE)
1346 np->r_flags |= RSTALE;
1347 if (!np->r_error)
1348 np->r_error = error;
1349 mutex_exit(&np->r_statelock);
1350 bp->b_flags |= B_ERROR;
1351 }
1352
1353 DTRACE_IO1(done, struct buf *, bp);
1354
1355 smb_credrele(&scred);
1356 smbfs_rw_exit(&np->r_lkserlock);
1357
1358 if (error == ESTALE)
1359 smbfs_attrcache_remove(np);
1360
1361 return (error);
1362 }
1363
1364 /*
1365 * Here NFS has: nfs3write, nfs3read
1366 * We use smb_rwuio instead.
1367 */
1368
1369 /* ARGSUSED */
1370 static int
1371 smbfs_ioctl(vnode_t *vp, int cmd, intptr_t arg, int flag,
1372 cred_t *cr, int *rvalp, caller_context_t *ct)
1373 {
1374 int error;
1375 smbmntinfo_t *smi;
1376
1377 smi = VTOSMI(vp);
1378
1379 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
1380 return (EIO);
1381
1382 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
1383 return (EIO);
1384
1385 switch (cmd) {
1386
1387 case _FIOFFS:
1388 error = smbfs_fsync(vp, 0, cr, ct);
1389 break;
1390
1391 /*
1392 * The following two ioctls are used by bfu.
1393 * Silently ignore to avoid bfu errors.
1394 */
1395 case _FIOGDIO:
1396 case _FIOSDIO:
1397 error = 0;
1398 break;
1399
1400 #if 0 /* Todo - SMB ioctl query regions */
1401 case _FIO_SEEK_DATA:
1402 case _FIO_SEEK_HOLE:
1403 #endif
1404
1405 case _FIODIRECTIO:
1406 error = smbfs_directio(vp, (int)arg, cr);
1407 break;
1408
1409 /*
1410 * Allow get/set with "raw" security descriptor (SD) data.
1411 * Useful for testing, diagnosing idmap problems, etc.
1412 */
1413 case SMBFSIO_GETSD:
1414 error = smbfs_acl_iocget(vp, arg, flag, cr);
1415 break;
1416
1417 case SMBFSIO_SETSD:
1418 error = smbfs_acl_iocset(vp, arg, flag, cr);
1419 break;
1420
1421 default:
1422 error = ENOTTY;
1423 break;
1424 }
1425
1426 return (error);
1427 }
1428
1429
1430 /*
1431 * Return either cached or remote attributes. If get remote attr
1432 * use them to check and invalidate caches, then cache the new attributes.
1433 */
1434 /* ARGSUSED */
1435 static int
1436 smbfs_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
1437 caller_context_t *ct)
1438 {
1439 smbnode_t *np;
1440 smbmntinfo_t *smi;
1441 int error;
1442
1443 smi = VTOSMI(vp);
1444
1445 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
1446 return (EIO);
1447
1448 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
1449 return (EIO);
1450
1451 /*
1452 * If it has been specified that the return value will
1453 * just be used as a hint, and we are only being asked
1454 * for size, fsid or rdevid, then return the client's
1455 * notion of these values without checking to make sure
1456 * that the attribute cache is up to date.
1457 * The whole point is to avoid an over the wire GETATTR
1458 * call.
1459 */
1460 np = VTOSMB(vp);
1461 if (flags & ATTR_HINT) {
1462 if (vap->va_mask ==
1463 (vap->va_mask & (AT_SIZE | AT_FSID | AT_RDEV))) {
1464 mutex_enter(&np->r_statelock);
1465 if (vap->va_mask | AT_SIZE)
1466 vap->va_size = np->r_size;
1467 if (vap->va_mask | AT_FSID)
1468 vap->va_fsid = vp->v_vfsp->vfs_dev;
1469 if (vap->va_mask | AT_RDEV)
1470 vap->va_rdev = vp->v_rdev;
1471 mutex_exit(&np->r_statelock);
1472 return (0);
1473 }
1474 }
1475
1476 /*
1477 * Only need to flush pages if asking for the mtime
1478 * and if there any dirty pages.
1479 *
1480 * Here NFS also checks for async writes (np->r_awcount)
1481 */
1482 if (vap->va_mask & AT_MTIME) {
1483 if (vn_has_cached_data(vp) &&
1484 ((np->r_flags & RDIRTY) != 0)) {
1485 mutex_enter(&np->r_statelock);
1486 np->r_gcount++;
1487 mutex_exit(&np->r_statelock);
1488 error = smbfs_putpage(vp, (offset_t)0, 0, 0, cr, ct);
1489 mutex_enter(&np->r_statelock);
1490 if (error && (error == ENOSPC || error == EDQUOT)) {
1491 if (!np->r_error)
1492 np->r_error = error;
1493 }
1494 if (--np->r_gcount == 0)
1495 cv_broadcast(&np->r_cv);
1496 mutex_exit(&np->r_statelock);
1497 }
1498 }
1499
1500 return (smbfsgetattr(vp, vap, cr));
1501 }
1502
1503 /* smbfsgetattr() in smbfs_client.c */
1504
1505 /*ARGSUSED4*/
1506 static int
1507 smbfs_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
1508 caller_context_t *ct)
1509 {
1510 vfs_t *vfsp;
1511 smbmntinfo_t *smi;
1512 int error;
1513 uint_t mask;
1514 struct vattr oldva;
1515
1516 vfsp = vp->v_vfsp;
1517 smi = VFTOSMI(vfsp);
1518
1519 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
1550 return (error);
1551
1552 if (mask & (AT_UID | AT_GID)) {
1553 if (smi->smi_flags & SMI_ACL)
1554 error = smbfs_acl_setids(vp, vap, cr);
1555 else
1556 error = ENOSYS;
1557 if (error != 0) {
1558 SMBVDEBUG("error %d seting UID/GID on %s",
1559 error, VTOSMB(vp)->n_rpath);
1560 /*
1561 * It might be more correct to return the
1562 * error here, but that causes complaints
1563 * when root extracts a cpio archive, etc.
1564 * So ignore this error, and go ahead with
1565 * the rest of the setattr work.
1566 */
1567 }
1568 }
1569
1570 error = smbfssetattr(vp, vap, flags, cr);
1571
1572 #ifdef SMBFS_VNEVENT
1573 if (error == 0 && (vap->va_mask & AT_SIZE) && vap->va_size == 0)
1574 vnevent_truncate(vp, ct);
1575 #endif
1576
1577 return (error);
1578 }
1579
1580 /*
1581 * Mostly from Darwin smbfs_setattr()
1582 * but then modified a lot.
1583 */
1584 /* ARGSUSED */
1585 static int
1586 smbfssetattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
1587 {
1588 int error = 0;
1589 smbnode_t *np = VTOSMB(vp);
1590 uint_t mask = vap->va_mask;
1591 struct timespec *mtime, *atime;
1592 struct smb_cred scred;
1593 int cerror, modified = 0;
1594 unsigned short fid;
1595 int have_fid = 0;
1596 uint32_t rights = 0;
1597 uint32_t dosattr = 0;
1598
1599 ASSERT(curproc->p_zone == VTOSMI(vp)->smi_zone_ref.zref_zone);
1600
1601 /*
1602 * There are no settable attributes on the XATTR dir,
1603 * so just silently ignore these. On XATTR files,
1604 * you can set the size but nothing else.
1605 */
1606 if (vp->v_flag & V_XATTRDIR)
1607 return (0);
1608 if (np->n_flag & N_XATTR) {
1609 if (mask & AT_TIMES)
1610 SMBVDEBUG("ignore set time on xattr\n");
1611 mask &= AT_SIZE;
1612 }
1613
1614 /*
1615 * Only need to flush pages if there are any pages and
1616 * if the file is marked as dirty in some fashion. The
1617 * file must be flushed so that we can accurately
1618 * determine the size of the file and the cached data
1619 * after the SETATTR returns. A file is considered to
1620 * be dirty if it is either marked with RDIRTY, has
1621 * outstanding i/o's active, or is mmap'd. In this
1622 * last case, we can't tell whether there are dirty
1623 * pages, so we flush just to be sure.
1624 */
1625 if (vn_has_cached_data(vp) &&
1626 ((np->r_flags & RDIRTY) ||
1627 np->r_count > 0 ||
1628 np->r_mapcnt > 0)) {
1629 ASSERT(vp->v_type != VCHR);
1630 error = smbfs_putpage(vp, (offset_t)0, 0, 0, cr, NULL);
1631 if (error && (error == ENOSPC || error == EDQUOT)) {
1632 mutex_enter(&np->r_statelock);
1633 if (!np->r_error)
1634 np->r_error = error;
1635 mutex_exit(&np->r_statelock);
1636 }
1637 }
1638
1639 /*
1640 * If our caller is trying to set multiple attributes, they
1641 * can make no assumption about what order they are done in.
1642 * Here we try to do them in order of decreasing likelihood
1643 * of failure, just to minimize the chance we'll wind up
1644 * with a partially complete request.
1645 */
1646
1647 /* Shared lock for (possible) n_fid use. */
1648 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
1649 return (EINTR);
1650 smb_credinit(&scred, cr);
1651
1652 /*
1653 * If the caller has provided extensible attributes,
1654 * map those into DOS attributes supported by SMB.
1655 * Note: zero means "no change".
1656 */
1657 if (mask & AT_XVATTR)
1658 dosattr = xvattr_to_dosattr(np, vap);
1659
1681 error = smbfs_smb_tmpopen(np, rights, &scred, &fid);
1682 if (error) {
1683 SMBVDEBUG("error %d opening %s\n",
1684 error, np->n_rpath);
1685 goto out;
1686 }
1687 have_fid = 1;
1688 }
1689
1690 /*
1691 * If the server supports the UNIX extensions, right here is where
1692 * we'd support changes to uid, gid, mode, and possibly va_flags.
1693 * For now we claim to have made any such changes.
1694 */
1695
1696 if (mask & AT_SIZE) {
1697 /*
1698 * If the new file size is less than what the client sees as
1699 * the file size, then just change the size and invalidate
1700 * the pages.
1701 */
1702
1703 /*
1704 * Set the file size to vap->va_size.
1705 */
1706 ASSERT(have_fid);
1707 error = smbfs_smb_setfsize(np, fid, vap->va_size, &scred);
1708 if (error) {
1709 SMBVDEBUG("setsize error %d file %s\n",
1710 error, np->n_rpath);
1711 } else {
1712 /*
1713 * Darwin had code here to zero-extend.
1714 * Tests indicate the server will zero-fill,
1715 * so looks like we don't need to do that.
1716 */
1717 mutex_enter(&np->r_statelock);
1718 np->r_size = vap->va_size;
1719 mutex_exit(&np->r_statelock);
1720 modified = 1;
1721 }
1722 }
1723
1724 /*
1725 * Todo: Implement setting create_time (which is
1726 * different from ctime).
1727 */
1728 mtime = ((mask & AT_MTIME) ? &vap->va_mtime : 0);
1729 atime = ((mask & AT_ATIME) ? &vap->va_atime : 0);
1730
1731 if (dosattr || mtime || atime) {
1732 /*
1733 * Always use the handle-based set attr call now.
1734 */
1735 ASSERT(have_fid);
1736 error = smbfs_smb_setfattr(np, fid,
1737 dosattr, mtime, atime, &scred);
1738 if (error) {
1739 SMBVDEBUG("set times error %d file %s\n",
1740 error, np->n_rpath);
1741 } else {
1742 modified = 1;
1743 }
1744 }
1745
1746 out:
1747 if (have_fid) {
1748 cerror = smbfs_smb_tmpclose(np, fid, &scred);
1749 if (cerror)
1750 SMBVDEBUG("error %d closing %s\n",
1751 cerror, np->n_rpath);
1752 }
1753
1754 smb_credrele(&scred);
1755 smbfs_rw_exit(&np->r_lkserlock);
1756
1757 if (modified) {
1758 /*
1759 * Invalidate attribute cache in case the server
1760 * doesn't set exactly the attributes we asked.
1761 */
1762 smbfs_attrcache_remove(np);
1763
1764 /*
1765 * If changing the size of the file, invalidate
1766 * any local cached data which is no longer part
1767 * of the file. We also possibly invalidate the
1768 * last page in the file. We could use
1769 * pvn_vpzero(), but this would mark the page as
1770 * modified and require it to be written back to
1771 * the server for no particularly good reason.
1772 * This way, if we access it, then we bring it
1773 * back in. A read should be cheaper than a
1774 * write.
1775 */
1776 if (mask & AT_SIZE) {
1777 smbfs_invalidate_pages(vp,
1778 (vap->va_size & PAGEMASK), cr);
1779 }
1780 }
1781
1782 return (error);
1783 }
1784
1785 /*
1786 * Helper function for extensible system attributes (PSARC 2007/315)
1787 * Compute the DOS attribute word to pass to _setfattr (see above).
1788 * This returns zero IFF no change is being made to attributes.
1789 * Otherwise return the new attributes or SMB_EFA_NORMAL.
1790 */
1791 static uint32_t
1792 xvattr_to_dosattr(smbnode_t *np, struct vattr *vap)
1793 {
1794 xvattr_t *xvap = (xvattr_t *)vap;
1795 xoptattr_t *xoap = NULL;
1796 uint32_t attr = np->r_attr.fa_attr;
1797 boolean_t anyset = B_FALSE;
1798
1799 if ((xoap = xva_getxoptattr(xvap)) == NULL)
1800 return (0);
1801
1848 * due to the current "single user mounts" restriction:
1849 * All access under a given mount point uses the CIFS
1850 * credentials established by the owner of the mount.
1851 *
1852 * Most access checking is handled by the CIFS server,
1853 * but we need sufficient Unix access checks here to
1854 * prevent other local Unix users from having access
1855 * to objects under this mount that the uid/gid/mode
1856 * settings in the mount would not allow.
1857 *
1858 * With this model, there is a case where we need the
1859 * ability to do an access check before we have the
1860 * vnode for an object. This function takes advantage
1861 * of the fact that the uid/gid/mode is per mount, and
1862 * avoids the need for a vnode.
1863 *
1864 * We still (sort of) need a vnode when we call
1865 * secpolicy_vnode_access, but that only uses
1866 * the vtype field, so we can use a pair of fake
1867 * vnodes that have only v_type filled in.
1868 */
1869 static int
1870 smbfs_access_rwx(vfs_t *vfsp, int vtype, int mode, cred_t *cr)
1871 {
1872 /* See the secpolicy call below. */
1873 static const vnode_t tmpl_vdir = { .v_type = VDIR };
1874 static const vnode_t tmpl_vreg = { .v_type = VREG };
1875 vattr_t va;
1876 vnode_t *tvp;
1877 struct smbmntinfo *smi = VFTOSMI(vfsp);
1878 int shift = 0;
1879
1880 /*
1881 * Build our (fabricated) vnode attributes.
1882 */
1883 bzero(&va, sizeof (va));
1884 va.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
1885 va.va_type = vtype;
1886 va.va_mode = (vtype == VDIR) ?
1887 smi->smi_dmode : smi->smi_fmode;
1888 va.va_uid = smi->smi_uid;
1889 va.va_gid = smi->smi_gid;
1890
1891 /*
1892 * Disallow write attempts on read-only file systems,
1893 * unless the file is a device or fifo node. Note:
1894 * Inline vn_is_readonly and IS_DEVVP here because
1895 * we may not have a vnode ptr. Original expr. was:
1896 * (mode & VWRITE) && vn_is_readonly(vp) && !IS_DEVVP(vp))
1897 */
1898 if ((mode & VWRITE) &&
1899 (vfsp->vfs_flag & VFS_RDONLY) &&
1900 !(vtype == VCHR || vtype == VBLK || vtype == VFIFO))
1901 return (EROFS);
1902
1903 /*
1904 * Disallow attempts to access mandatory lock files.
1905 * Similarly, expand MANDLOCK here.
1906 */
1907 if ((mode & (VWRITE | VREAD | VEXEC)) &&
1908 va.va_type == VREG && MANDMODE(va.va_mode))
1909 return (EACCES);
1910
1911 /*
1912 * Access check is based on only
1913 * one of owner, group, public.
1914 * If not owner, then check group.
1915 * If not a member of the group,
1916 * then check public access.
1917 */
1918 if (crgetuid(cr) != va.va_uid) {
1919 shift += 3;
1920 if (!groupmember(va.va_gid, cr))
1921 shift += 3;
1922 }
1923
1924 /*
1925 * We need a vnode for secpolicy_vnode_access,
1955 /* ARGSUSED */
1956 static int
1957 smbfs_access(vnode_t *vp, int mode, int flags, cred_t *cr, caller_context_t *ct)
1958 {
1959 vfs_t *vfsp;
1960 smbmntinfo_t *smi;
1961
1962 vfsp = vp->v_vfsp;
1963 smi = VFTOSMI(vfsp);
1964
1965 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
1966 return (EIO);
1967
1968 if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED)
1969 return (EIO);
1970
1971 return (smbfs_access_rwx(vfsp, vp->v_type, mode, cr));
1972 }
1973
1974
1975 /* ARGSUSED */
1976 static int
1977 smbfs_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr, caller_context_t *ct)
1978 {
1979 /* Not yet... */
1980 return (ENOSYS);
1981 }
1982
1983
1984 /*
1985 * Flush local dirty pages to stable storage on the server.
1986 *
1987 * If FNODSYNC is specified, then there is nothing to do because
1988 * metadata changes are not cached on the client before being
1989 * sent to the server.
1990 */
1991 /* ARGSUSED */
1992 static int
1993 smbfs_fsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct)
1994 {
1995 int error = 0;
1996 smbmntinfo_t *smi;
1997 smbnode_t *np;
1998 struct smb_cred scred;
1999
2000 np = VTOSMB(vp);
2001 smi = VTOSMI(vp);
2002
2003 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
2004 return (EIO);
2005
2006 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
2007 return (EIO);
2008
2009 if ((syncflag & FNODSYNC) || IS_SWAPVP(vp))
2010 return (0);
2011
2012 if ((syncflag & (FSYNC|FDSYNC)) == 0)
2013 return (0);
2014
2015 error = smbfs_putpage(vp, (offset_t)0, 0, 0, cr, ct);
2016 if (error)
2017 return (error);
2018
2019 /* Shared lock for n_fid use in _flush */
2020 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
2021 return (EINTR);
2022 smb_credinit(&scred, cr);
2023
2024 error = smbfs_smb_flush(np, &scred);
2025
2026 smb_credrele(&scred);
2027 smbfs_rw_exit(&np->r_lkserlock);
2028
2029 return (error);
2030 }
2031
2032 /*
2033 * Last reference to vnode went away.
2034 */
2035 /* ARGSUSED */
2036 static void
2037 smbfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
2038 {
2039 struct smb_cred scred;
2040 smbnode_t *np = VTOSMB(vp);
2041 int error;
2042
2043 /*
2044 * Don't "bail out" for VFS_UNMOUNTED here,
2045 * as we want to do cleanup, etc.
2046 * See also pcfs_inactive
2047 */
2048
2049 /*
2050 * If this is coming from the wrong zone, we let someone in the right
2051 * zone take care of it asynchronously. We can get here due to
2052 * VN_RELE() being called from pageout() or fsflush(). This call may
2053 * potentially turn into an expensive no-op if, for instance, v_count
2054 * gets incremented in the meantime, but it's still correct.
2055 */
2056
2057 /*
2058 * From NFS:rinactive()
2059 *
2060 * Before freeing anything, wait until all asynchronous
2061 * activity is done on this rnode. This will allow all
2062 * asynchronous read ahead and write behind i/o's to
2063 * finish.
2064 */
2065 mutex_enter(&np->r_statelock);
2066 while (np->r_count > 0)
2067 cv_wait(&np->r_cv, &np->r_statelock);
2068 mutex_exit(&np->r_statelock);
2069
2070 /*
2071 * Flush and invalidate all pages associated with the vnode.
2072 */
2073 if (vn_has_cached_data(vp)) {
2074 if ((np->r_flags & RDIRTY) && !np->r_error) {
2075 error = smbfs_putpage(vp, (u_offset_t)0, 0, 0, cr, ct);
2076 if (error && (error == ENOSPC || error == EDQUOT)) {
2077 mutex_enter(&np->r_statelock);
2078 if (!np->r_error)
2079 np->r_error = error;
2080 mutex_exit(&np->r_statelock);
2081 }
2082 }
2083 smbfs_invalidate_pages(vp, (u_offset_t)0, cr);
2084 }
2085 /*
2086 * This vnode should have lost all cached data.
2087 */
2088 ASSERT(vn_has_cached_data(vp) == 0);
2089
2090 /*
2091 * Defend against the possibility that higher-level callers
2092 * might not correctly balance open and close calls. If we
2093 * get here with open references remaining, it means there
2094 * was a missing VOP_CLOSE somewhere. If that happens, do
2095 * the close here so we don't "leak" FIDs on the server.
2096 *
2097 * Exclusive lock for modifying n_fid stuff.
2098 * Don't want this one ever interruptible.
2099 */
2100 (void) smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, 0);
2101 smb_credinit(&scred, cr);
2102
2103 switch (np->n_ovtype) {
2104 case VNON:
2105 /* not open (OK) */
2106 break;
2107
2108 case VDIR:
2109 if (np->n_dirrefs == 0)
2110 break;
2218 int rplen;
2219 struct smb_cred scred;
2220 struct smbfattr fa;
2221
2222 smi = VTOSMI(dvp);
2223 dnp = VTOSMB(dvp);
2224
2225 ASSERT(curproc->p_zone == smi->smi_zone_ref.zref_zone);
2226
2227 #ifdef NOT_YET
2228 vcp = SSTOVC(smi->smi_share);
2229
2230 /* XXX: Should compute this once and store it in smbmntinfo_t */
2231 supplen = (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN2_0) ? 255 : 12;
2232 #else
2233 supplen = 255;
2234 #endif
2235
2236 /*
2237 * RWlock must be held, either reader or writer.
2238 */
2239 ASSERT(dnp->r_rwlock.count != 0);
2240
2241 /*
2242 * If lookup is for "", just return dvp.
2243 * No need to perform any access checks.
2244 */
2245 if (nmlen == 0) {
2246 VN_HOLD(dvp);
2247 *vpp = dvp;
2248 return (0);
2249 }
2250
2251 /*
2252 * Can't do lookups in non-directories.
2253 */
2254 if (dvp->v_type != VDIR)
2255 return (ENOTDIR);
2256
2257 /*
2264 /*
2265 * If lookup is for ".", just return dvp.
2266 * Access check was done above.
2267 */
2268 if (nmlen == 1 && name[0] == '.') {
2269 VN_HOLD(dvp);
2270 *vpp = dvp;
2271 return (0);
2272 }
2273
2274 /*
2275 * Now some sanity checks on the name.
2276 * First check the length.
2277 */
2278 if (nmlen > supplen)
2279 return (ENAMETOOLONG);
2280
2281 /*
2282 * Avoid surprises with characters that are
2283 * illegal in Windows file names.
2284 * Todo: CATIA mappings?
2285 */
2286 ill = illegal_chars;
2287 if (dnp->n_flag & N_XATTR)
2288 ill++; /* allow colon */
2289 if (strpbrk(nm, ill))
2290 return (EINVAL);
2291
2292 /*
2293 * Special handling for lookup of ".."
2294 *
2295 * We keep full pathnames (as seen on the server)
2296 * so we can just trim off the last component to
2297 * get the full pathname of the parent. Note:
2298 * We don't actually copy and modify, but just
2299 * compute the trimmed length and pass that with
2300 * the current dir path (not null terminated).
2301 *
2302 * We don't go over-the-wire to get attributes
2303 * for ".." because we know it's a directory,
2304 * and we can just leave the rest "stale"
2485 if (np->r_attrtime <= gethrtime()) {
2486 /* stale */
2487 #ifdef DEBUG
2488 smbfs_lookup_cache_stale++;
2489 #endif
2490 VN_RELE(vp);
2491 return (0);
2492 }
2493
2494 /*
2495 * Success!
2496 * Caller gets hold from smbfs_node_findcreate
2497 */
2498 #ifdef DEBUG
2499 smbfs_lookup_cache_hits++;
2500 #endif
2501 *vpp = vp;
2502 return (0);
2503 }
2504
2505
2506 /*
2507 * XXX
2508 * vsecattr_t is new to build 77, and we need to eventually support
2509 * it in order to create an ACL when an object is created.
2510 *
2511 * This op should support the new FIGNORECASE flag for case-insensitive
2512 * lookups, per PSARC 2007/244.
2513 */
2514 /* ARGSUSED */
2515 static int
2516 smbfs_create(vnode_t *dvp, char *nm, struct vattr *va, enum vcexcl exclusive,
2517 int mode, vnode_t **vpp, cred_t *cr, int lfaware, caller_context_t *ct,
2518 vsecattr_t *vsecp)
2519 {
2520 int error;
2521 int cerror;
2522 vfs_t *vfsp;
2523 vnode_t *vp;
2524 smbnode_t *np;
2525 smbnode_t *dnp;
2526 smbmntinfo_t *smi;
2527 struct vattr vattr;
2528 struct smbfattr fattr;
2529 struct smb_cred scred;
2530 const char *name = (const char *)nm;
2531 int nmlen = strlen(nm);
2532 uint32_t disp;
2533 uint16_t fid;
2534 int xattr;
2535
2536 vfsp = dvp->v_vfsp;
2537 smi = VFTOSMI(vfsp);
2538 dnp = VTOSMB(dvp);
2539 vp = NULL;
2540
2541 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
2542 return (EPERM);
2543
2544 if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED)
2545 return (EIO);
2546
2547 /*
2548 * Note: this may break mknod(2) calls to create a directory,
2549 * but that's obscure use. Some other filesystems do this.
2550 * Todo: redirect VDIR type here to _mkdir.
2551 */
2552 if (va->va_type != VREG)
2553 return (EINVAL);
2554
2555 /*
2556 * If the pathname is "", just use dvp, no checks.
2557 * Do this outside of the rwlock (like zfs).
2558 */
2559 if (nmlen == 0) {
2560 VN_HOLD(dvp);
2561 *vpp = dvp;
2562 return (0);
2563 }
2564
2565 /* Don't allow "." or ".." through here. */
2566 if ((nmlen == 1 && name[0] == '.') ||
2567 (nmlen == 2 && name[0] == '.' && name[1] == '.'))
2568 return (EISDIR);
2569
2570 /*
2595 * The file already exists. Error?
2596 * NB: have a hold from smbfslookup
2597 */
2598 if (exclusive == EXCL) {
2599 error = EEXIST;
2600 VN_RELE(vp);
2601 goto out;
2602 }
2603 /*
2604 * Verify requested access.
2605 */
2606 error = smbfs_access(vp, mode, 0, cr, ct);
2607 if (error) {
2608 VN_RELE(vp);
2609 goto out;
2610 }
2611
2612 /*
2613 * Truncate (if requested).
2614 */
2615 if ((vattr.va_mask & AT_SIZE) && vp->v_type == VREG) {
2616 np = VTOSMB(vp);
2617 /*
2618 * Check here for large file truncation by
2619 * LF-unaware process, like ufs_create().
2620 */
2621 if (!(lfaware & FOFFMAX)) {
2622 mutex_enter(&np->r_statelock);
2623 if (np->r_size > MAXOFF32_T)
2624 error = EOVERFLOW;
2625 mutex_exit(&np->r_statelock);
2626 }
2627 if (error) {
2628 VN_RELE(vp);
2629 goto out;
2630 }
2631 vattr.va_mask = AT_SIZE;
2632 error = smbfssetattr(vp, &vattr, 0, cr);
2633 if (error) {
2634 VN_RELE(vp);
2635 goto out;
2636 }
2637 #ifdef SMBFS_VNEVENT
2638 /* Existing file was truncated */
2639 vnevent_create(vp, ct);
2640 #endif
2641 /* invalidate pages done in smbfssetattr() */
2642 }
2643 /* Success! */
2644 *vpp = vp;
2645 goto out;
2646 }
2647
2648 /*
2649 * The file did not exist. Need VWRITE in the directory.
2650 */
2651 error = smbfs_access(dvp, VWRITE, 0, cr, ct);
2652 if (error)
2653 goto out;
2654
2655 /*
2656 * Now things get tricky. We also need to check the
2657 * requested open mode against the file we may create.
2658 * See comments at smbfs_access_rwx
2659 */
2660 error = smbfs_access_rwx(vfsp, VREG, mode, cr);
2661 if (error)
2662 goto out;
2663
2672
2673 if (exclusive == EXCL)
2674 disp = NTCREATEX_DISP_CREATE;
2675 else {
2676 /* Truncate regular files if requested. */
2677 if ((va->va_type == VREG) &&
2678 (va->va_mask & AT_SIZE) &&
2679 (va->va_size == 0))
2680 disp = NTCREATEX_DISP_OVERWRITE_IF;
2681 else
2682 disp = NTCREATEX_DISP_OPEN_IF;
2683 }
2684 xattr = (dnp->n_flag & N_XATTR) ? 1 : 0;
2685 error = smbfs_smb_create(dnp,
2686 name, nmlen, xattr,
2687 disp, &scred, &fid);
2688 if (error)
2689 goto out;
2690
2691 /*
2692 * Should use the fid to get/set the size
2693 * while we have it opened here. See above.
2694 */
2695
2696 cerror = smbfs_smb_close(smi->smi_share, fid, NULL, &scred);
2697 if (cerror)
2698 SMBVDEBUG("error %d closing %s\\%s\n",
2699 cerror, dnp->n_rpath, name);
2700
2701 /*
2702 * In the open case, the name may differ a little
2703 * from what we passed to create (case, etc.)
2704 * so call lookup to get the (opened) name.
2705 *
2706 * XXX: Could avoid this extra lookup if the
2707 * "createact" result from NT_CREATE says we
2708 * created the object.
2709 */
2710 error = smbfs_smb_lookup(dnp, &name, &nmlen, &fattr, &scred);
2711 if (error)
2712 goto out;
2713
2714 /* update attr and directory cache */
2715 smbfs_attr_touchdir(dnp);
2716
2717 error = smbfs_nget(dvp, name, nmlen, &fattr, &vp);
2718 if (error)
2719 goto out;
2720
2721 /* Success! */
2722 *vpp = vp;
2723 error = 0;
2724
2725 out:
2726 smb_credrele(&scred);
2727 smbfs_rw_exit(&dnp->r_rwlock);
2728 if (name != nm)
2729 smbfs_name_free(name, nmlen);
2730 return (error);
2731 }
2732
2733 /*
2734 * XXX
2735 * This op should support the new FIGNORECASE flag for case-insensitive
2736 * lookups, per PSARC 2007/244.
2737 */
2738 /* ARGSUSED */
2739 static int
2740 smbfs_remove(vnode_t *dvp, char *nm, cred_t *cr, caller_context_t *ct,
2806 int flags)
2807 {
2808 smbnode_t *dnp = VTOSMB(dvp);
2809 smbnode_t *np = VTOSMB(vp);
2810 char *tmpname = NULL;
2811 int tnlen;
2812 int error;
2813 unsigned short fid;
2814 boolean_t have_fid = B_FALSE;
2815 boolean_t renamed = B_FALSE;
2816
2817 /*
2818 * The dvp RWlock must be held as writer.
2819 */
2820 ASSERT(dnp->r_rwlock.owner == curthread);
2821
2822 /* Never allow link/unlink directories on SMB. */
2823 if (vp->v_type == VDIR)
2824 return (EPERM);
2825
2826 /*
2827 * We need to flush any dirty pages which happen to
2828 * be hanging around before removing the file. This
2829 * shouldn't happen very often and mostly on file
2830 * systems mounted "nocto".
2831 */
2832 if (vn_has_cached_data(vp) &&
2833 ((np->r_flags & RDIRTY) || np->r_count > 0)) {
2834 error = smbfs_putpage(vp, (offset_t)0, 0, 0,
2835 scred->scr_cred, NULL);
2836 if (error && (error == ENOSPC || error == EDQUOT)) {
2837 mutex_enter(&np->r_statelock);
2838 if (!np->r_error)
2839 np->r_error = error;
2840 mutex_exit(&np->r_statelock);
2841 }
2842 }
2843
2844 /* Shared lock for n_fid use in smbfs_smb_setdisp etc. */
2845 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
2846 return (EINTR);
2847
2848 /*
2849 * Get a file handle with delete access.
2850 * Close this FID before return.
2851 */
2852 error = smbfs_smb_tmpopen(np, STD_RIGHT_DELETE_ACCESS,
2853 scred, &fid);
2854 if (error) {
2855 SMBVDEBUG("error %d opening %s\n",
2856 error, np->n_rpath);
2857 goto out;
2858 }
2859 have_fid = B_TRUE;
2860
2861 /*
2862 * If we have the file open, try to rename it to a temporary name.
2863 * If we can't rename, continue on and try setting DoC anyway.
2864 */
2865 if ((vp->v_count > 1) && (np->n_fidrefs > 0)) {
2866 tmpname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
2867 tnlen = smbfs_newname(tmpname, MAXNAMELEN);
2890 * the separator ('/' or ':')
2891 */
2892 if (renamed) {
2893 char *oldname;
2894 int oldnlen;
2895 int err2;
2896
2897 oldname = np->n_rpath + (dnp->n_rplen + 1);
2898 oldnlen = np->n_rplen - (dnp->n_rplen + 1);
2899 err2 = smbfs_smb_t2rename(np, oldname, oldnlen,
2900 scred, fid, 0);
2901 SMBVDEBUG("error %d un-renaming %s -> %s\n",
2902 err2, tmpname, np->n_rpath);
2903 }
2904 error = EBUSY;
2905 goto out;
2906 }
2907 /* Done! */
2908 smbfs_attrcache_prune(np);
2909
2910 #ifdef SMBFS_VNEVENT
2911 vnevent_remove(vp, dvp, nm, ct);
2912 #endif
2913
2914 out:
2915 if (tmpname != NULL)
2916 kmem_free(tmpname, MAXNAMELEN);
2917
2918 if (have_fid)
2919 (void) smbfs_smb_tmpclose(np, fid, scred);
2920 smbfs_rw_exit(&np->r_lkserlock);
2921
2922 if (error == 0) {
2923 /* Keep lookup from finding this node anymore. */
2924 smbfs_rmhash(np);
2925 }
2926
2927 return (error);
2928 }
2929
2930
2931 /* ARGSUSED */
2932 static int
2933 smbfs_link(vnode_t *tdvp, vnode_t *svp, char *tnm, cred_t *cr,
2934 caller_context_t *ct, int flags)
2935 {
2936 /* Not yet... */
2937 return (ENOSYS);
2938 }
2939
2940
2941 /*
2942 * XXX
2943 * This op should support the new FIGNORECASE flag for case-insensitive
2944 * lookups, per PSARC 2007/244.
2945 */
2946 /* ARGSUSED */
2947 static int
2948 smbfs_rename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm, cred_t *cr,
2949 caller_context_t *ct, int flags)
2950 {
2951 struct smb_cred scred;
2952 smbnode_t *odnp = VTOSMB(odvp);
2953 smbnode_t *ndnp = VTOSMB(ndvp);
2954 vnode_t *ovp;
2955 int error;
2956
2957 if (curproc->p_zone != VTOSMI(odvp)->smi_zone_ref.zref_zone ||
2958 curproc->p_zone != VTOSMI(ndvp)->smi_zone_ref.zref_zone)
2959 return (EPERM);
2960
3113 */
3114 if (nvp->v_type == VDIR) {
3115 error = EEXIST;
3116 goto out;
3117 }
3118 error = smbfsremove(ndvp, nvp, scred, flags);
3119 if (error != 0)
3120 goto out;
3121
3122 /*
3123 * OK, removed the target file. Continue as if
3124 * lookup target had failed (nvp == NULL).
3125 */
3126 vn_vfsunlock(nvp);
3127 nvp_locked = 0;
3128 VN_RELE(nvp);
3129 nvp = NULL;
3130 } /* nvp */
3131
3132 smbfs_attrcache_remove(onp);
3133 error = smbfs_smb_rename(onp, ndnp, nnm, strlen(nnm), scred);
3134
3135 /*
3136 * If the old name should no longer exist,
3137 * discard any cached attributes under it.
3138 */
3139 if (error == 0) {
3140 smbfs_attrcache_prune(onp);
3141 /* SMBFS_VNEVENT... */
3142 }
3143
3144 out:
3145 if (nvp) {
3146 if (nvp_locked)
3147 vn_vfsunlock(nvp);
3148 VN_RELE(nvp);
3149 }
3150
3151 return (error);
3152 }
3153
3154 /*
3155 * XXX
3156 * vsecattr_t is new to build 77, and we need to eventually support
3157 * it in order to create an ACL when an object is created.
3158 *
3159 * This op should support the new FIGNORECASE flag for case-insensitive
3160 * lookups, per PSARC 2007/244.
3161 */
3162 /* ARGSUSED */
3175
3176 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
3177 return (EPERM);
3178
3179 if (smi->smi_flags & SMI_DEAD || dvp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
3180 return (EIO);
3181
3182 if ((nmlen == 1 && name[0] == '.') ||
3183 (nmlen == 2 && name[0] == '.' && name[1] == '.'))
3184 return (EEXIST);
3185
3186 /* Only plain files are allowed in V_XATTRDIR. */
3187 if (dvp->v_flag & V_XATTRDIR)
3188 return (EINVAL);
3189
3190 if (smbfs_rw_enter_sig(&dnp->r_rwlock, RW_WRITER, SMBINTR(dvp)))
3191 return (EINTR);
3192 smb_credinit(&scred, cr);
3193
3194 /*
3195 * Require write access in the containing directory.
3196 */
3197 error = smbfs_access(dvp, VWRITE, 0, cr, ct);
3198 if (error)
3199 goto out;
3200
3201 error = smbfs_smb_mkdir(dnp, name, nmlen, &scred);
3202 if (error)
3203 goto out;
3204
3205 error = smbfs_smb_lookup(dnp, &name, &nmlen, &fattr, &scred);
3206 if (error)
3207 goto out;
3208
3209 smbfs_attr_touchdir(dnp);
3210
3211 error = smbfs_nget(dvp, name, nmlen, &fattr, &vp);
3212 if (error)
3213 goto out;
3214
3317 dnp->n_flag |= NMODIFIED;
3318 mutex_exit(&np->r_statelock);
3319 smbfs_attr_touchdir(dnp);
3320 smbfs_rmhash(np);
3321
3322 out:
3323 if (vp) {
3324 if (vp_locked)
3325 vn_vfsunlock(vp);
3326 VN_RELE(vp);
3327 }
3328 smb_credrele(&scred);
3329 smbfs_rw_exit(&dnp->r_rwlock);
3330
3331 return (error);
3332 }
3333
3334
3335 /* ARGSUSED */
3336 static int
3337 smbfs_symlink(vnode_t *dvp, char *lnm, struct vattr *tva, char *tnm, cred_t *cr,
3338 caller_context_t *ct, int flags)
3339 {
3340 /* Not yet... */
3341 return (ENOSYS);
3342 }
3343
3344
3345 /* ARGSUSED */
3346 static int
3347 smbfs_readdir(vnode_t *vp, struct uio *uiop, cred_t *cr, int *eofp,
3348 caller_context_t *ct, int flags)
3349 {
3350 struct smbnode *np = VTOSMB(vp);
3351 int error = 0;
3352 smbmntinfo_t *smi;
3353
3354 smi = VTOSMI(vp);
3355
3356 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
3357 return (EIO);
3358
3359 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
3360 return (EIO);
3361
3362 /*
3363 * Require read access in the directory.
3364 */
3365 error = smbfs_access(vp, VREAD, 0, cr, ct);
3366 if (error)
3367 return (error);
3368
3369 ASSERT(smbfs_rw_lock_held(&np->r_rwlock, RW_READER));
3370
3371 /*
3372 * Todo readdir cache here
3373 *
3374 * I am serializing the entire readdir opreation
3375 * now since we have not yet implemented readdir
3376 * cache. This fix needs to be revisited once
3377 * we implement readdir cache.
3378 */
3379 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, SMBINTR(vp)))
3380 return (EINTR);
3381
3382 error = smbfs_readvdir(vp, uiop, cr, eofp, ct);
3383
3384 smbfs_rw_exit(&np->r_lkserlock);
3385
3386 return (error);
3387 }
3388
3389 /* ARGSUSED */
3390 static int
3391 smbfs_readvdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
3392 caller_context_t *ct)
3586 }
3587 /*
3588 * If we encountered an error (i.e. "access denied")
3589 * from the FindFirst call, we will have copied out
3590 * the "." and ".." entries leaving offset == 2.
3591 * In that case, restore the original offset/resid
3592 * so the caller gets no data with the error.
3593 */
3594 if (error != 0 && offset == FIRST_DIROFS) {
3595 uio->uio_loffset = save_offset;
3596 uio->uio_resid = save_resid;
3597 }
3598 SMBVDEBUG("out: offset=%d, resid=%d\n",
3599 (int)uio->uio_offset, (int)uio->uio_resid);
3600
3601 kmem_free(dp, dbufsiz);
3602 smb_credrele(&scred);
3603 return (error);
3604 }
3605
3606 /*
3607 * Here NFS has: nfs3_bio
3608 * See smbfs_bio above.
3609 */
3610
3611 /* ARGSUSED */
3612 static int
3613 smbfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct)
3614 {
3615 return (ENOSYS);
3616 }
3617
3618
3619 /*
3620 * The pair of functions VOP_RWLOCK, VOP_RWUNLOCK
3621 * are optional functions that are called by:
3622 * getdents, before/after VOP_READDIR
3623 * pread, before/after ... VOP_READ
3624 * pwrite, before/after ... VOP_WRITE
3625 * (other places)
3626 *
3627 * Careful here: None of the above check for any
3628 * error returns from VOP_RWLOCK / VOP_RWUNLOCK!
3629 * In fact, the return value from _rwlock is NOT
3630 * an error code, but V_WRITELOCK_TRUE / _FALSE.
3631 *
3632 * Therefore, it's up to _this_ code to make sure
3633 * the lock state remains balanced, which means
3634 * we can't "bail out" on interrupts, etc.
3635 */
3636
3637 /* ARGSUSED2 */
3638 static int
3672 return (EPERM);
3673
3674 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
3675 return (EIO);
3676
3677 /*
3678 * Because we stuff the readdir cookie into the offset field
3679 * someone may attempt to do an lseek with the cookie which
3680 * we want to succeed.
3681 */
3682 if (vp->v_type == VDIR)
3683 return (0);
3684
3685 /* Like NFS3, just check for 63-bit overflow. */
3686 if (*noffp < 0)
3687 return (EINVAL);
3688
3689 return (0);
3690 }
3691
3692 /* mmap support ******************************************************** */
3693
3694 #ifdef DEBUG
3695 static int smbfs_lostpage = 0; /* number of times we lost original page */
3696 #endif
3697
3698 /*
3699 * Return all the pages from [off..off+len) in file
3700 * Like nfs3_getpage
3701 */
3702 /* ARGSUSED */
3703 static int
3704 smbfs_getpage(vnode_t *vp, offset_t off, size_t len, uint_t *protp,
3705 page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr,
3706 enum seg_rw rw, cred_t *cr, caller_context_t *ct)
3707 {
3708 smbnode_t *np;
3709 smbmntinfo_t *smi;
3710 int error;
3711
3712 np = VTOSMB(vp);
3713 smi = VTOSMI(vp);
3714
3715 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
3716 return (EIO);
3717
3718 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
3719 return (EIO);
3720
3721 if (vp->v_flag & VNOMAP)
3722 return (ENOSYS);
3723
3724 if (protp != NULL)
3725 *protp = PROT_ALL;
3726
3727 /*
3728 * Now valididate that the caches are up to date.
3729 */
3730 error = smbfs_validate_caches(vp, cr);
3731 if (error)
3732 return (error);
3733
3734 retry:
3735 mutex_enter(&np->r_statelock);
3736
3737 /*
3738 * Don't create dirty pages faster than they
3739 * can be cleaned ... (etc. see nfs)
3740 *
3741 * Here NFS also tests:
3742 * (mi->mi_max_threads != 0 &&
3743 * rp->r_awcount > 2 * mi->mi_max_threads)
3744 */
3745 if (rw == S_CREATE) {
3746 while (np->r_gcount > 0)
3747 cv_wait(&np->r_cv, &np->r_statelock);
3748 }
3749
3750 /*
3751 * If we are getting called as a side effect of a write
3752 * operation the local file size might not be extended yet.
3753 * In this case we want to be able to return pages of zeroes.
3754 */
3755 if (off + len > np->r_size + PAGEOFFSET && seg != segkmap) {
3756 mutex_exit(&np->r_statelock);
3757 return (EFAULT); /* beyond EOF */
3758 }
3759
3760 mutex_exit(&np->r_statelock);
3761
3762 error = pvn_getpages(smbfs_getapage, vp, off, len, protp,
3763 pl, plsz, seg, addr, rw, cr);
3764
3765 switch (error) {
3766 case SMBFS_EOF:
3767 smbfs_purge_caches(vp, cr);
3768 goto retry;
3769 case ESTALE:
3770 /*
3771 * Here NFS has: PURGE_STALE_FH(error, vp, cr);
3772 * In-line here as we only use it once.
3773 */
3774 mutex_enter(&np->r_statelock);
3775 np->r_flags |= RSTALE;
3776 if (!np->r_error)
3777 np->r_error = (error);
3778 mutex_exit(&np->r_statelock);
3779 if (vn_has_cached_data(vp))
3780 smbfs_invalidate_pages(vp, (u_offset_t)0, cr);
3781 smbfs_purge_caches(vp, cr);
3782 break;
3783 default:
3784 break;
3785 }
3786
3787 return (error);
3788 }
3789
3790 /*
3791 * Called from pvn_getpages to get a particular page.
3792 * Like nfs3_getapage
3793 */
3794 /* ARGSUSED */
3795 static int
3796 smbfs_getapage(vnode_t *vp, u_offset_t off, size_t len, uint_t *protp,
3797 page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr,
3798 enum seg_rw rw, cred_t *cr)
3799 {
3800 smbnode_t *np;
3801 smbmntinfo_t *smi;
3802
3803 uint_t bsize;
3804 struct buf *bp;
3805 page_t *pp;
3806 u_offset_t lbn;
3807 u_offset_t io_off;
3808 u_offset_t blkoff;
3809 size_t io_len;
3810 uint_t blksize;
3811 int error;
3812 /* int readahead; */
3813 int readahead_issued = 0;
3814 /* int ra_window; * readahead window */
3815 page_t *pagefound;
3816
3817 np = VTOSMB(vp);
3818 smi = VTOSMI(vp);
3819
3820 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
3821 return (EIO);
3822
3823 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
3824 return (EIO);
3825
3826 bsize = MAX(vp->v_vfsp->vfs_bsize, PAGESIZE);
3827
3828 reread:
3829 bp = NULL;
3830 pp = NULL;
3831 pagefound = NULL;
3832
3833 if (pl != NULL)
3834 pl[0] = NULL;
3835
3836 error = 0;
3837 lbn = off / bsize;
3838 blkoff = lbn * bsize;
3839
3840 /*
3841 * NFS queues up readahead work here.
3842 */
3843
3844 again:
3845 if ((pagefound = page_exists(vp, off)) == NULL) {
3846 if (pl == NULL) {
3847 (void) 0; /* Todo: smbfs_async_readahead(); */
3848 } else if (rw == S_CREATE) {
3849 /*
3850 * Block for this page is not allocated, or the offset
3851 * is beyond the current allocation size, or we're
3852 * allocating a swap slot and the page was not found,
3853 * so allocate it and return a zero page.
3854 */
3855 if ((pp = page_create_va(vp, off,
3856 PAGESIZE, PG_WAIT, seg, addr)) == NULL)
3857 cmn_err(CE_PANIC, "smbfs_getapage: page_create");
3858 io_len = PAGESIZE;
3859 mutex_enter(&np->r_statelock);
3860 np->r_nextr = off + PAGESIZE;
3861 mutex_exit(&np->r_statelock);
3862 } else {
3863 /*
3864 * Need to go to server to get a BLOCK, exception to
3865 * that being while reading at offset = 0 or doing
3866 * random i/o, in that case read only a PAGE.
3867 */
3868 mutex_enter(&np->r_statelock);
3869 if (blkoff < np->r_size &&
3870 blkoff + bsize >= np->r_size) {
3871 /*
3872 * If only a block or less is left in
3873 * the file, read all that is remaining.
3874 */
3875 if (np->r_size <= off) {
3876 /*
3877 * Trying to access beyond EOF,
3878 * set up to get at least one page.
3879 */
3880 blksize = off + PAGESIZE - blkoff;
3881 } else
3882 blksize = np->r_size - blkoff;
3883 } else if ((off == 0) ||
3884 (off != np->r_nextr && !readahead_issued)) {
3885 blksize = PAGESIZE;
3886 blkoff = off; /* block = page here */
3887 } else
3888 blksize = bsize;
3889 mutex_exit(&np->r_statelock);
3890
3891 pp = pvn_read_kluster(vp, off, seg, addr, &io_off,
3892 &io_len, blkoff, blksize, 0);
3893
3894 /*
3895 * Some other thread has entered the page,
3896 * so just use it.
3897 */
3898 if (pp == NULL)
3899 goto again;
3900
3901 /*
3902 * Now round the request size up to page boundaries.
3903 * This ensures that the entire page will be
3904 * initialized to zeroes if EOF is encountered.
3905 */
3906 io_len = ptob(btopr(io_len));
3907
3908 bp = pageio_setup(pp, io_len, vp, B_READ);
3909 ASSERT(bp != NULL);
3910
3911 /*
3912 * pageio_setup should have set b_addr to 0. This
3913 * is correct since we want to do I/O on a page
3914 * boundary. bp_mapin will use this addr to calculate
3915 * an offset, and then set b_addr to the kernel virtual
3916 * address it allocated for us.
3917 */
3918 ASSERT(bp->b_un.b_addr == 0);
3919
3920 bp->b_edev = 0;
3921 bp->b_dev = 0;
3922 bp->b_lblkno = lbtodb(io_off);
3923 bp->b_file = vp;
3924 bp->b_offset = (offset_t)off;
3925 bp_mapin(bp);
3926
3927 /*
3928 * If doing a write beyond what we believe is EOF,
3929 * don't bother trying to read the pages from the
3930 * server, we'll just zero the pages here. We
3931 * don't check that the rw flag is S_WRITE here
3932 * because some implementations may attempt a
3933 * read access to the buffer before copying data.
3934 */
3935 mutex_enter(&np->r_statelock);
3936 if (io_off >= np->r_size && seg == segkmap) {
3937 mutex_exit(&np->r_statelock);
3938 bzero(bp->b_un.b_addr, io_len);
3939 } else {
3940 mutex_exit(&np->r_statelock);
3941 error = smbfs_bio(bp, 0, cr);
3942 }
3943
3944 /*
3945 * Unmap the buffer before freeing it.
3946 */
3947 bp_mapout(bp);
3948 pageio_done(bp);
3949
3950 /* Here NFS3 updates all pp->p_fsdata */
3951
3952 if (error == SMBFS_EOF) {
3953 /*
3954 * If doing a write system call just return
3955 * zeroed pages, else user tried to get pages
3956 * beyond EOF, return error. We don't check
3957 * that the rw flag is S_WRITE here because
3958 * some implementations may attempt a read
3959 * access to the buffer before copying data.
3960 */
3961 if (seg == segkmap)
3962 error = 0;
3963 else
3964 error = EFAULT;
3965 }
3966
3967 if (!readahead_issued && !error) {
3968 mutex_enter(&np->r_statelock);
3969 np->r_nextr = io_off + io_len;
3970 mutex_exit(&np->r_statelock);
3971 }
3972 }
3973 }
3974
3975 if (pl == NULL)
3976 return (error);
3977
3978 if (error) {
3979 if (pp != NULL)
3980 pvn_read_done(pp, B_ERROR);
3981 return (error);
3982 }
3983
3984 if (pagefound) {
3985 se_t se = (rw == S_CREATE ? SE_EXCL : SE_SHARED);
3986
3987 /*
3988 * Page exists in the cache, acquire the appropriate lock.
3989 * If this fails, start all over again.
3990 */
3991 if ((pp = page_lookup(vp, off, se)) == NULL) {
3992 #ifdef DEBUG
3993 smbfs_lostpage++;
3994 #endif
3995 goto reread;
3996 }
3997 pl[0] = pp;
3998 pl[1] = NULL;
3999 return (0);
4000 }
4001
4002 if (pp != NULL)
4003 pvn_plist_init(pp, pl, plsz, off, io_len, rw);
4004
4005 return (error);
4006 }
4007
4008 /*
4009 * Here NFS has: nfs3_readahead
4010 * No read-ahead in smbfs yet.
4011 */
4012
4013 /*
4014 * Flags are composed of {B_INVAL, B_FREE, B_DONTNEED, B_FORCE}
4015 * If len == 0, do from off to EOF.
4016 *
4017 * The normal cases should be len == 0 && off == 0 (entire vp list),
4018 * len == MAXBSIZE (from segmap_release actions), and len == PAGESIZE
4019 * (from pageout).
4020 *
4021 * Like nfs3_putpage + nfs_putpages
4022 */
4023 /* ARGSUSED */
4024 static int
4025 smbfs_putpage(vnode_t *vp, offset_t off, size_t len, int flags, cred_t *cr,
4026 caller_context_t *ct)
4027 {
4028 smbnode_t *np;
4029 smbmntinfo_t *smi;
4030 page_t *pp;
4031 u_offset_t eoff;
4032 u_offset_t io_off;
4033 size_t io_len;
4034 int error;
4035 int rdirty;
4036 int err;
4037
4038 np = VTOSMB(vp);
4039 smi = VTOSMI(vp);
4040
4041 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
4042 return (EIO);
4043
4044 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
4045 return (EIO);
4046
4047 if (vp->v_flag & VNOMAP)
4048 return (ENOSYS);
4049
4050 /* Here NFS does rp->r_count (++/--) stuff. */
4051
4052 /* Beginning of code from nfs_putpages. */
4053
4054 if (!vn_has_cached_data(vp))
4055 return (0);
4056
4057 /*
4058 * If ROUTOFSPACE is set, then all writes turn into B_INVAL
4059 * writes. B_FORCE is set to force the VM system to actually
4060 * invalidate the pages, even if the i/o failed. The pages
4061 * need to get invalidated because they can't be written out
4062 * because there isn't any space left on either the server's
4063 * file system or in the user's disk quota. The B_FREE bit
4064 * is cleared to avoid confusion as to whether this is a
4065 * request to place the page on the freelist or to destroy
4066 * it.
4067 */
4068 if ((np->r_flags & ROUTOFSPACE) ||
4069 (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED))
4070 flags = (flags & ~B_FREE) | B_INVAL | B_FORCE;
4071
4072 if (len == 0) {
4073 /*
4074 * If doing a full file synchronous operation, then clear
4075 * the RDIRTY bit. If a page gets dirtied while the flush
4076 * is happening, then RDIRTY will get set again. The
4077 * RDIRTY bit must get cleared before the flush so that
4078 * we don't lose this information.
4079 *
4080 * NFS has B_ASYNC vs sync stuff here.
4081 */
4082 if (off == (u_offset_t)0 &&
4083 (np->r_flags & RDIRTY)) {
4084 mutex_enter(&np->r_statelock);
4085 rdirty = (np->r_flags & RDIRTY);
4086 np->r_flags &= ~RDIRTY;
4087 mutex_exit(&np->r_statelock);
4088 } else
4089 rdirty = 0;
4090
4091 /*
4092 * Search the entire vp list for pages >= off, and flush
4093 * the dirty pages.
4094 */
4095 error = pvn_vplist_dirty(vp, off, smbfs_putapage,
4096 flags, cr);
4097
4098 /*
4099 * If an error occurred and the file was marked as dirty
4100 * before and we aren't forcibly invalidating pages, then
4101 * reset the RDIRTY flag.
4102 */
4103 if (error && rdirty &&
4104 (flags & (B_INVAL | B_FORCE)) != (B_INVAL | B_FORCE)) {
4105 mutex_enter(&np->r_statelock);
4106 np->r_flags |= RDIRTY;
4107 mutex_exit(&np->r_statelock);
4108 }
4109 } else {
4110 /*
4111 * Do a range from [off...off + len) looking for pages
4112 * to deal with.
4113 */
4114 error = 0;
4115 io_len = 1; /* quiet warnings */
4116 eoff = off + len;
4117
4118 for (io_off = off; io_off < eoff; io_off += io_len) {
4119 mutex_enter(&np->r_statelock);
4120 if (io_off >= np->r_size) {
4121 mutex_exit(&np->r_statelock);
4122 break;
4123 }
4124 mutex_exit(&np->r_statelock);
4125 /*
4126 * If we are not invalidating, synchronously
4127 * freeing or writing pages use the routine
4128 * page_lookup_nowait() to prevent reclaiming
4129 * them from the free list.
4130 */
4131 if ((flags & B_INVAL) || !(flags & B_ASYNC)) {
4132 pp = page_lookup(vp, io_off,
4133 (flags & (B_INVAL | B_FREE)) ?
4134 SE_EXCL : SE_SHARED);
4135 } else {
4136 pp = page_lookup_nowait(vp, io_off,
4137 (flags & B_FREE) ? SE_EXCL : SE_SHARED);
4138 }
4139
4140 if (pp == NULL || !pvn_getdirty(pp, flags))
4141 io_len = PAGESIZE;
4142 else {
4143 err = smbfs_putapage(vp, pp, &io_off,
4144 &io_len, flags, cr);
4145 if (!error)
4146 error = err;
4147 /*
4148 * "io_off" and "io_len" are returned as
4149 * the range of pages we actually wrote.
4150 * This allows us to skip ahead more quickly
4151 * since several pages may've been dealt
4152 * with by this iteration of the loop.
4153 */
4154 }
4155 }
4156 }
4157
4158 return (error);
4159 }
4160
4161 /*
4162 * Write out a single page, possibly klustering adjacent dirty pages.
4163 *
4164 * Like nfs3_putapage / nfs3_sync_putapage
4165 */
4166 static int
4167 smbfs_putapage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp,
4168 int flags, cred_t *cr)
4169 {
4170 smbnode_t *np;
4171 u_offset_t io_off;
4172 u_offset_t lbn_off;
4173 u_offset_t lbn;
4174 size_t io_len;
4175 uint_t bsize;
4176 int error;
4177
4178 np = VTOSMB(vp);
4179
4180 ASSERT(!vn_is_readonly(vp));
4181
4182 bsize = MAX(vp->v_vfsp->vfs_bsize, PAGESIZE);
4183 lbn = pp->p_offset / bsize;
4184 lbn_off = lbn * bsize;
4185
4186 /*
4187 * Find a kluster that fits in one block, or in
4188 * one page if pages are bigger than blocks. If
4189 * there is less file space allocated than a whole
4190 * page, we'll shorten the i/o request below.
4191 */
4192 pp = pvn_write_kluster(vp, pp, &io_off, &io_len, lbn_off,
4193 roundup(bsize, PAGESIZE), flags);
4194
4195 /*
4196 * pvn_write_kluster shouldn't have returned a page with offset
4197 * behind the original page we were given. Verify that.
4198 */
4199 ASSERT((pp->p_offset / bsize) >= lbn);
4200
4201 /*
4202 * Now pp will have the list of kept dirty pages marked for
4203 * write back. It will also handle invalidation and freeing
4204 * of pages that are not dirty. Check for page length rounding
4205 * problems.
4206 */
4207 if (io_off + io_len > lbn_off + bsize) {
4208 ASSERT((io_off + io_len) - (lbn_off + bsize) < PAGESIZE);
4209 io_len = lbn_off + bsize - io_off;
4210 }
4211 /*
4212 * The RMODINPROGRESS flag makes sure that smbfs_bio() sees a
4213 * consistent value of r_size. RMODINPROGRESS is set in writerp().
4214 * When RMODINPROGRESS is set it indicates that a uiomove() is in
4215 * progress and the r_size has not been made consistent with the
4216 * new size of the file. When the uiomove() completes the r_size is
4217 * updated and the RMODINPROGRESS flag is cleared.
4218 *
4219 * The RMODINPROGRESS flag makes sure that smbfs_bio() sees a
4220 * consistent value of r_size. Without this handshaking, it is
4221 * possible that smbfs_bio() picks up the old value of r_size
4222 * before the uiomove() in writerp() completes. This will result
4223 * in the write through smbfs_bio() being dropped.
4224 *
4225 * More precisely, there is a window between the time the uiomove()
4226 * completes and the time the r_size is updated. If a VOP_PUTPAGE()
4227 * operation intervenes in this window, the page will be picked up,
4228 * because it is dirty (it will be unlocked, unless it was
4229 * pagecreate'd). When the page is picked up as dirty, the dirty
4230 * bit is reset (pvn_getdirty()). In smbfs_write(), r_size is
4231 * checked. This will still be the old size. Therefore the page will
4232 * not be written out. When segmap_release() calls VOP_PUTPAGE(),
4233 * the page will be found to be clean and the write will be dropped.
4234 */
4235 if (np->r_flags & RMODINPROGRESS) {
4236 mutex_enter(&np->r_statelock);
4237 if ((np->r_flags & RMODINPROGRESS) &&
4238 np->r_modaddr + MAXBSIZE > io_off &&
4239 np->r_modaddr < io_off + io_len) {
4240 page_t *plist;
4241 /*
4242 * A write is in progress for this region of the file.
4243 * If we did not detect RMODINPROGRESS here then this
4244 * path through smbfs_putapage() would eventually go to
4245 * smbfs_bio() and may not write out all of the data
4246 * in the pages. We end up losing data. So we decide
4247 * to set the modified bit on each page in the page
4248 * list and mark the rnode with RDIRTY. This write
4249 * will be restarted at some later time.
4250 */
4251 plist = pp;
4252 while (plist != NULL) {
4253 pp = plist;
4254 page_sub(&plist, pp);
4255 hat_setmod(pp);
4256 page_io_unlock(pp);
4257 page_unlock(pp);
4258 }
4259 np->r_flags |= RDIRTY;
4260 mutex_exit(&np->r_statelock);
4261 if (offp)
4262 *offp = io_off;
4263 if (lenp)
4264 *lenp = io_len;
4265 return (0);
4266 }
4267 mutex_exit(&np->r_statelock);
4268 }
4269
4270 /*
4271 * NFS handles (flags & B_ASYNC) here...
4272 * (See nfs_async_putapage())
4273 *
4274 * This code section from: nfs3_sync_putapage()
4275 */
4276
4277 flags |= B_WRITE;
4278
4279 error = smbfs_rdwrlbn(vp, pp, io_off, io_len, flags, cr);
4280
4281 if ((error == ENOSPC || error == EDQUOT || error == EFBIG ||
4282 error == EACCES) &&
4283 (flags & (B_INVAL|B_FORCE)) != (B_INVAL|B_FORCE)) {
4284 if (!(np->r_flags & ROUTOFSPACE)) {
4285 mutex_enter(&np->r_statelock);
4286 np->r_flags |= ROUTOFSPACE;
4287 mutex_exit(&np->r_statelock);
4288 }
4289 flags |= B_ERROR;
4290 pvn_write_done(pp, flags);
4291 /*
4292 * If this was not an async thread, then try again to
4293 * write out the pages, but this time, also destroy
4294 * them whether or not the write is successful. This
4295 * will prevent memory from filling up with these
4296 * pages and destroying them is the only alternative
4297 * if they can't be written out.
4298 *
4299 * Don't do this if this is an async thread because
4300 * when the pages are unlocked in pvn_write_done,
4301 * some other thread could have come along, locked
4302 * them, and queued for an async thread. It would be
4303 * possible for all of the async threads to be tied
4304 * up waiting to lock the pages again and they would
4305 * all already be locked and waiting for an async
4306 * thread to handle them. Deadlock.
4307 */
4308 if (!(flags & B_ASYNC)) {
4309 error = smbfs_putpage(vp, io_off, io_len,
4310 B_INVAL | B_FORCE, cr, NULL);
4311 }
4312 } else {
4313 if (error)
4314 flags |= B_ERROR;
4315 else if (np->r_flags & ROUTOFSPACE) {
4316 mutex_enter(&np->r_statelock);
4317 np->r_flags &= ~ROUTOFSPACE;
4318 mutex_exit(&np->r_statelock);
4319 }
4320 pvn_write_done(pp, flags);
4321 }
4322
4323 /* Now more code from: nfs3_putapage */
4324
4325 if (offp)
4326 *offp = io_off;
4327 if (lenp)
4328 *lenp = io_len;
4329
4330 return (error);
4331 }
4332
4333 /*
4334 * NFS has this in nfs_client.c (shared by v2,v3,...)
4335 * We have it here so smbfs_putapage can be file scope.
4336 */
4337 void
4338 smbfs_invalidate_pages(vnode_t *vp, u_offset_t off, cred_t *cr)
4339 {
4340 smbnode_t *np;
4341
4342 np = VTOSMB(vp);
4343
4344 mutex_enter(&np->r_statelock);
4345 while (np->r_flags & RTRUNCATE)
4346 cv_wait(&np->r_cv, &np->r_statelock);
4347 np->r_flags |= RTRUNCATE;
4348
4349 if (off == (u_offset_t)0) {
4350 np->r_flags &= ~RDIRTY;
4351 if (!(np->r_flags & RSTALE))
4352 np->r_error = 0;
4353 }
4354 /* Here NFSv3 has np->r_truncaddr = off; */
4355 mutex_exit(&np->r_statelock);
4356
4357 (void) pvn_vplist_dirty(vp, off, smbfs_putapage,
4358 B_INVAL | B_TRUNC, cr);
4359
4360 mutex_enter(&np->r_statelock);
4361 np->r_flags &= ~RTRUNCATE;
4362 cv_broadcast(&np->r_cv);
4363 mutex_exit(&np->r_statelock);
4364 }
4365
4366 /* Like nfs3_map */
4367
4368 /* ARGSUSED */
4369 static int
4370 smbfs_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp,
4371 size_t len, uchar_t prot, uchar_t maxprot, uint_t flags,
4372 cred_t *cr, caller_context_t *ct)
4373 {
4374 segvn_crargs_t vn_a;
4375 struct vattr va;
4376 smbnode_t *np;
4377 smbmntinfo_t *smi;
4378 int error;
4379
4380 np = VTOSMB(vp);
4381 smi = VTOSMI(vp);
4382
4383 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
4384 return (EIO);
4385
4386 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
4387 return (EIO);
4388
4389 if (vp->v_flag & VNOMAP)
4390 return (ENOSYS);
4391
4392 if (off < 0 || off + (ssize_t)len < 0)
4393 return (ENXIO);
4394
4395 if (vp->v_type != VREG)
4396 return (ENODEV);
4397
4398 /*
4399 * NFS does close-to-open consistency stuff here.
4400 * Just get (possibly cached) attributes.
4401 */
4402 va.va_mask = AT_ALL;
4403 if ((error = smbfsgetattr(vp, &va, cr)) != 0)
4404 return (error);
4405
4406 /*
4407 * Check to see if the vnode is currently marked as not cachable.
4408 * This means portions of the file are locked (through VOP_FRLOCK).
4409 * In this case the map request must be refused. We use
4410 * rp->r_lkserlock to avoid a race with concurrent lock requests.
4411 */
4412 /*
4413 * Atomically increment r_inmap after acquiring r_rwlock. The
4414 * idea here is to acquire r_rwlock to block read/write and
4415 * not to protect r_inmap. r_inmap will inform smbfs_read/write()
4416 * that we are in smbfs_map(). Now, r_rwlock is acquired in order
4417 * and we can prevent the deadlock that would have occurred
4418 * when smbfs_addmap() would have acquired it out of order.
4419 *
4420 * Since we are not protecting r_inmap by any lock, we do not
4421 * hold any lock when we decrement it. We atomically decrement
4422 * r_inmap after we release r_lkserlock. Note that rwlock is
4423 * re-entered as writer in smbfs_addmap (called via as_map).
4424 */
4425
4426 if (smbfs_rw_enter_sig(&np->r_rwlock, RW_WRITER, SMBINTR(vp)))
4427 return (EINTR);
4428 atomic_inc_uint(&np->r_inmap);
4429 smbfs_rw_exit(&np->r_rwlock);
4430
4431 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, SMBINTR(vp))) {
4432 atomic_dec_uint(&np->r_inmap);
4433 return (EINTR);
4434 }
4435
4436 if (vp->v_flag & VNOCACHE) {
4437 error = EAGAIN;
4438 goto done;
4439 }
4440
4441 /*
4442 * Don't allow concurrent locks and mapping if mandatory locking is
4443 * enabled.
4444 */
4445 if ((flk_has_remote_locks(vp) || smbfs_lm_has_sleep(vp)) &&
4446 MANDLOCK(vp, va.va_mode)) {
4447 error = EAGAIN;
4448 goto done;
4449 }
4450
4451 as_rangelock(as);
4452 error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags);
4453 if (error != 0) {
4454 as_rangeunlock(as);
4455 goto done;
4456 }
4457
4458 vn_a.vp = vp;
4459 vn_a.offset = off;
4460 vn_a.type = (flags & MAP_TYPE);
4461 vn_a.prot = (uchar_t)prot;
4462 vn_a.maxprot = (uchar_t)maxprot;
4463 vn_a.flags = (flags & ~MAP_TYPE);
4464 vn_a.cred = cr;
4465 vn_a.amp = NULL;
4466 vn_a.szc = 0;
4467 vn_a.lgrp_mem_policy_flags = 0;
4468
4469 error = as_map(as, *addrp, len, segvn_create, &vn_a);
4470 as_rangeunlock(as);
4471
4472 done:
4473 smbfs_rw_exit(&np->r_lkserlock);
4474 atomic_dec_uint(&np->r_inmap);
4475 return (error);
4476 }
4477
4478 /* ARGSUSED */
4479 static int
4480 smbfs_addmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
4481 size_t len, uchar_t prot, uchar_t maxprot, uint_t flags,
4482 cred_t *cr, caller_context_t *ct)
4483 {
4484 smbnode_t *np = VTOSMB(vp);
4485 boolean_t inc_fidrefs = B_FALSE;
4486
4487 /*
4488 * When r_mapcnt goes from zero to non-zero,
4489 * increment n_fidrefs
4490 */
4491 mutex_enter(&np->r_statelock);
4492 if (np->r_mapcnt == 0)
4493 inc_fidrefs = B_TRUE;
4494 np->r_mapcnt += btopr(len);
4495 mutex_exit(&np->r_statelock);
4496
4497 if (inc_fidrefs) {
4498 (void) smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, 0);
4499 np->n_fidrefs++;
4500 smbfs_rw_exit(&np->r_lkserlock);
4501 }
4502
4503 return (0);
4504 }
4505
4506 /*
4507 * Use an address space callback to flush pages dirty pages after unmap,
4508 * which we can't do directly in smbfs_delmap due to locking issues.
4509 */
4510 typedef struct smbfs_delmap_args {
4511 vnode_t *vp;
4512 cred_t *cr;
4513 offset_t off;
4514 caddr_t addr;
4515 size_t len;
4516 uint_t prot;
4517 uint_t maxprot;
4518 uint_t flags;
4519 boolean_t dec_fidrefs;
4520 } smbfs_delmap_args_t;
4521
4522 /* ARGSUSED */
4523 static int
4524 smbfs_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
4525 size_t len, uint_t prot, uint_t maxprot, uint_t flags,
4526 cred_t *cr, caller_context_t *ct)
4527 {
4528 smbnode_t *np = VTOSMB(vp);
4529 smbfs_delmap_args_t *dmapp;
4530 int error;
4531
4532 dmapp = kmem_zalloc(sizeof (*dmapp), KM_SLEEP);
4533
4534 dmapp->vp = vp;
4535 dmapp->off = off;
4536 dmapp->addr = addr;
4537 dmapp->len = len;
4538 dmapp->prot = prot;
4539 dmapp->maxprot = maxprot;
4540 dmapp->flags = flags;
4541 dmapp->cr = cr;
4542 dmapp->dec_fidrefs = B_FALSE;
4543
4544 /*
4545 * When r_mapcnt returns to zero, arrange for the
4546 * callback to decrement n_fidrefs
4547 */
4548 mutex_enter(&np->r_statelock);
4549 np->r_mapcnt -= btopr(len);
4550 ASSERT(np->r_mapcnt >= 0);
4551 if (np->r_mapcnt == 0)
4552 dmapp->dec_fidrefs = B_TRUE;
4553 mutex_exit(&np->r_statelock);
4554
4555 error = as_add_callback(as, smbfs_delmap_callback, dmapp,
4556 AS_UNMAP_EVENT, addr, len, KM_SLEEP);
4557 if (error != 0) {
4558 /*
4559 * So sad, no callback is coming. Can't flush pages
4560 * in delmap (as locks). Just handle n_fidrefs.
4561 */
4562 cmn_err(CE_NOTE, "smbfs_delmap(%p) "
4563 "as_add_callback err=%d",
4564 (void *)vp, error);
4565
4566 if (dmapp->dec_fidrefs) {
4567 struct smb_cred scred;
4568
4569 (void) smbfs_rw_enter_sig(&np->r_lkserlock,
4570 RW_WRITER, 0);
4571 smb_credinit(&scred, dmapp->cr);
4572
4573 smbfs_rele_fid(np, &scred);
4574
4575 smb_credrele(&scred);
4576 smbfs_rw_exit(&np->r_lkserlock);
4577 }
4578 kmem_free(dmapp, sizeof (*dmapp));
4579 }
4580
4581 return (0);
4582 }
4583
4584 /*
4585 * Remove some pages from an mmap'd vnode. Flush any
4586 * dirty pages in the unmapped range.
4587 */
4588 /* ARGSUSED */
4589 static void
4590 smbfs_delmap_callback(struct as *as, void *arg, uint_t event)
4591 {
4592 vnode_t *vp;
4593 smbnode_t *np;
4594 smbmntinfo_t *smi;
4595 smbfs_delmap_args_t *dmapp = arg;
4596
4597 vp = dmapp->vp;
4598 np = VTOSMB(vp);
4599 smi = VTOSMI(vp);
4600
4601 /* Decremented r_mapcnt in smbfs_delmap */
4602
4603 /*
4604 * Initiate a page flush and potential commit if there are
4605 * pages, the file system was not mounted readonly, the segment
4606 * was mapped shared, and the pages themselves were writeable.
4607 *
4608 * mark RDIRTY here, will be used to check if a file is dirty when
4609 * unmount smbfs
4610 */
4611 if (vn_has_cached_data(vp) && !vn_is_readonly(vp) &&
4612 dmapp->flags == MAP_SHARED && (dmapp->maxprot & PROT_WRITE)) {
4613 mutex_enter(&np->r_statelock);
4614 np->r_flags |= RDIRTY;
4615 mutex_exit(&np->r_statelock);
4616
4617 /*
4618 * Need to finish the putpage before we
4619 * close the OtW FID needed for I/O.
4620 */
4621 (void) smbfs_putpage(vp, dmapp->off, dmapp->len, 0,
4622 dmapp->cr, NULL);
4623 }
4624
4625 if ((np->r_flags & RDIRECTIO) || (smi->smi_flags & SMI_DIRECTIO))
4626 (void) smbfs_putpage(vp, dmapp->off, dmapp->len,
4627 B_INVAL, dmapp->cr, NULL);
4628
4629 /*
4630 * If r_mapcnt went to zero, drop our FID ref now.
4631 * On the last fidref, this does an OtW close.
4632 */
4633 if (dmapp->dec_fidrefs) {
4634 struct smb_cred scred;
4635
4636 (void) smbfs_rw_enter_sig(&np->r_lkserlock, RW_WRITER, 0);
4637 smb_credinit(&scred, dmapp->cr);
4638
4639 smbfs_rele_fid(np, &scred);
4640
4641 smb_credrele(&scred);
4642 smbfs_rw_exit(&np->r_lkserlock);
4643 }
4644
4645 (void) as_delete_callback(as, arg);
4646 kmem_free(dmapp, sizeof (*dmapp));
4647 }
4648
4649 /* No smbfs_pageio() or smbfs_dispose() ops. */
4650
4651 /* misc. ******************************************************** */
4652
4653
4654 /*
4655 * XXX
4656 * This op may need to support PSARC 2007/440, nbmand changes for CIFS Service.
4657 */
4658 static int
4659 smbfs_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
4660 offset_t offset, struct flk_callback *flk_cbp, cred_t *cr,
4661 caller_context_t *ct)
4662 {
4663 if (curproc->p_zone != VTOSMI(vp)->smi_zone_ref.zref_zone)
4664 return (EIO);
4665
4666 if (VTOSMI(vp)->smi_flags & SMI_LLOCK)
4667 return (fs_frlock(vp, cmd, bfp, flag, offset, flk_cbp, cr, ct));
4668 else
4669 return (ENOSYS);
4670 }
4671
4672 /*
4673 * Free storage space associated with the specified vnode. The portion
4674 * to be freed is specified by bfp->l_start and bfp->l_len (already
4704 */
4705
4706 error = convoff(vp, bfp, 0, offset);
4707 if (!error) {
4708 ASSERT(bfp->l_start >= 0);
4709 if (bfp->l_len == 0) {
4710 struct vattr va;
4711
4712 /*
4713 * ftruncate should not change the ctime and
4714 * mtime if we truncate the file to its
4715 * previous size.
4716 */
4717 va.va_mask = AT_SIZE;
4718 error = smbfsgetattr(vp, &va, cr);
4719 if (error || va.va_size == bfp->l_start)
4720 return (error);
4721 va.va_mask = AT_SIZE;
4722 va.va_size = bfp->l_start;
4723 error = smbfssetattr(vp, &va, 0, cr);
4724 /* SMBFS_VNEVENT... */
4725 } else
4726 error = EINVAL;
4727 }
4728
4729 return (error);
4730 }
4731
4732
4733 /* ARGSUSED */
4734 static int
4735 smbfs_realvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
4736 {
4737
4738 return (ENOSYS);
4739 }
4740
4741
4742 /* ARGSUSED */
4743 static int
4744 smbfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
4745 caller_context_t *ct)
4746 {
4747 vfs_t *vfs;
4748 smbmntinfo_t *smi;
4749 struct smb_share *ssp;
4750
4751 vfs = vp->v_vfsp;
4752 smi = VFTOSMI(vfs);
4753
4754 if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
4755 return (EIO);
4756
4757 if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
4758 return (EIO);
4759
4760 switch (cmd) {
4761 case _PC_FILESIZEBITS:
4762 ssp = smi->smi_share;
4763 if (SSTOVC(ssp)->vc_sopt.sv_caps & SMB_CAP_LARGE_FILES)
4898 return (error);
4899 }
4900
4901
4902 /*
4903 * XXX
4904 * This op should eventually support PSARC 2007/268.
4905 */
4906 static int
4907 smbfs_shrlock(vnode_t *vp, int cmd, struct shrlock *shr, int flag, cred_t *cr,
4908 caller_context_t *ct)
4909 {
4910 if (curproc->p_zone != VTOSMI(vp)->smi_zone_ref.zref_zone)
4911 return (EIO);
4912
4913 if (VTOSMI(vp)->smi_flags & SMI_LLOCK)
4914 return (fs_shrlock(vp, cmd, shr, flag, cr, ct));
4915 else
4916 return (ENOSYS);
4917 }
4918
4919
4920 /*
4921 * Most unimplemented ops will return ENOSYS because of fs_nosys().
4922 * The only ops where that won't work are ACCESS (due to open(2)
4923 * failures) and ... (anything else left?)
4924 */
4925 const fs_operation_def_t smbfs_vnodeops_template[] = {
4926 VOPNAME_OPEN, { .vop_open = smbfs_open },
4927 VOPNAME_CLOSE, { .vop_close = smbfs_close },
4928 VOPNAME_READ, { .vop_read = smbfs_read },
4929 VOPNAME_WRITE, { .vop_write = smbfs_write },
4930 VOPNAME_IOCTL, { .vop_ioctl = smbfs_ioctl },
4931 VOPNAME_GETATTR, { .vop_getattr = smbfs_getattr },
4932 VOPNAME_SETATTR, { .vop_setattr = smbfs_setattr },
4933 VOPNAME_ACCESS, { .vop_access = smbfs_access },
4934 VOPNAME_LOOKUP, { .vop_lookup = smbfs_lookup },
4935 VOPNAME_CREATE, { .vop_create = smbfs_create },
4936 VOPNAME_REMOVE, { .vop_remove = smbfs_remove },
4937 VOPNAME_LINK, { .vop_link = smbfs_link },
4938 VOPNAME_RENAME, { .vop_rename = smbfs_rename },
4939 VOPNAME_MKDIR, { .vop_mkdir = smbfs_mkdir },
4940 VOPNAME_RMDIR, { .vop_rmdir = smbfs_rmdir },
4941 VOPNAME_READDIR, { .vop_readdir = smbfs_readdir },
4942 VOPNAME_SYMLINK, { .vop_symlink = smbfs_symlink },
4943 VOPNAME_READLINK, { .vop_readlink = smbfs_readlink },
4944 VOPNAME_FSYNC, { .vop_fsync = smbfs_fsync },
4945 VOPNAME_INACTIVE, { .vop_inactive = smbfs_inactive },
4946 VOPNAME_FID, { .vop_fid = smbfs_fid },
4947 VOPNAME_RWLOCK, { .vop_rwlock = smbfs_rwlock },
4948 VOPNAME_RWUNLOCK, { .vop_rwunlock = smbfs_rwunlock },
4949 VOPNAME_SEEK, { .vop_seek = smbfs_seek },
4950 VOPNAME_FRLOCK, { .vop_frlock = smbfs_frlock },
4951 VOPNAME_SPACE, { .vop_space = smbfs_space },
4952 VOPNAME_REALVP, { .vop_realvp = smbfs_realvp },
4953 VOPNAME_GETPAGE, { .vop_getpage = smbfs_getpage },
4954 VOPNAME_PUTPAGE, { .vop_putpage = smbfs_putpage },
4955 VOPNAME_MAP, { .vop_map = smbfs_map },
4956 VOPNAME_ADDMAP, { .vop_addmap = smbfs_addmap },
4957 VOPNAME_DELMAP, { .vop_delmap = smbfs_delmap },
4958 VOPNAME_DUMP, { .error = fs_nosys }, /* smbfs_dump, */
4959 VOPNAME_PATHCONF, { .vop_pathconf = smbfs_pathconf },
4960 VOPNAME_PAGEIO, { .error = fs_nosys }, /* smbfs_pageio, */
4961 VOPNAME_SETSECATTR, { .vop_setsecattr = smbfs_setsecattr },
4962 VOPNAME_GETSECATTR, { .vop_getsecattr = smbfs_getsecattr },
4963 VOPNAME_SHRLOCK, { .vop_shrlock = smbfs_shrlock },
4964 #ifdef SMBFS_VNEVENT
4965 VOPNAME_VNEVENT, { .vop_vnevent = fs_vnevent_support },
4966 #endif
4967 { NULL, NULL }
4968 };
|