Mon Jun 22 21:13:50 2009 UTC ()
Fix compilation with SMB_*_DEBUG options.


(njoly)
diff -r1.32 -r1.33 src/sys/fs/smbfs/smbfs_io.c
diff -r1.67 -r1.68 src/sys/fs/smbfs/smbfs_vnops.c

cvs diff -r1.32 -r1.33 src/sys/fs/smbfs/Attic/smbfs_io.c (switch to unified diff)

--- src/sys/fs/smbfs/Attic/smbfs_io.c 2009/03/18 16:00:21 1.32
+++ src/sys/fs/smbfs/Attic/smbfs_io.c 2009/06/22 21:13:50 1.33
@@ -1,447 +1,448 @@ @@ -1,447 +1,448 @@
1/* $NetBSD: smbfs_io.c,v 1.32 2009/03/18 16:00:21 cegger Exp $ */ 1/* $NetBSD: smbfs_io.c,v 1.33 2009/06/22 21:13:50 njoly Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000-2001, Boris Popov 4 * Copyright (c) 2000-2001, Boris Popov
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by Boris Popov. 17 * This product includes software developed by Boris Popov.
18 * 4. Neither the name of the author nor the names of any co-contributors 18 * 4. Neither the name of the author nor the names of any co-contributors
19 * may be used to endorse or promote products derived from this software 19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission. 20 * without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 * 33 *
34 * FreeBSD: src/sys/fs/smbfs/smbfs_io.c,v 1.7 2001/12/02 08:56:58 bp Exp 34 * FreeBSD: src/sys/fs/smbfs/smbfs_io.c,v 1.7 2001/12/02 08:56:58 bp Exp
35 * 35 *
36 */ 36 */
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD: smbfs_io.c,v 1.32 2009/03/18 16:00:21 cegger Exp $"); 39__KERNEL_RCSID(0, "$NetBSD: smbfs_io.c,v 1.33 2009/06/22 21:13:50 njoly Exp $");
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43#include <sys/resourcevar.h> /* defines plimit structure in proc struct */ 43#include <sys/resourcevar.h> /* defines plimit structure in proc struct */
44#include <sys/kernel.h> 44#include <sys/kernel.h>
45#include <sys/proc.h> 45#include <sys/proc.h>
46#include <sys/fcntl.h> 46#include <sys/fcntl.h>
47#include <sys/buf.h> 47#include <sys/buf.h>
48#include <sys/mount.h> 48#include <sys/mount.h>
49#include <sys/malloc.h> 49#include <sys/malloc.h>
50#include <sys/namei.h> 50#include <sys/namei.h>
51#include <sys/vnode.h> 51#include <sys/vnode.h>
52#include <sys/dirent.h> 52#include <sys/dirent.h>
53#include <sys/signalvar.h> 53#include <sys/signalvar.h>
54#include <sys/sysctl.h> 54#include <sys/sysctl.h>
55#include <sys/vmmeter.h> 55#include <sys/vmmeter.h>
56#include <sys/kauth.h> 56#include <sys/kauth.h>
57 57
58#ifndef __NetBSD__ 58#ifndef __NetBSD__
59#include <vm/vm.h> 59#include <vm/vm.h>
60#if __FreeBSD_version < 400000 60#if __FreeBSD_version < 400000
61#include <vm/vm_prot.h> 61#include <vm/vm_prot.h>
62#endif 62#endif
63#include <vm/vm_page.h> 63#include <vm/vm_page.h>
64#include <vm/vm_extern.h> 64#include <vm/vm_extern.h>
65#include <vm/vm_object.h> 65#include <vm/vm_object.h>
66#include <vm/vm_pager.h> 66#include <vm/vm_pager.h>
67#include <vm/vnode_pager.h> 67#include <vm/vnode_pager.h>
68#else /* __NetBSD__ */ 68#else /* __NetBSD__ */
69#include <uvm/uvm.h> 69#include <uvm/uvm.h>
70#include <uvm/uvm_extern.h> 70#include <uvm/uvm_extern.h>
71#endif /* __NetBSD__ */ 71#endif /* __NetBSD__ */
72 72
73/* 73/*
74#include <sys/ioccom.h> 74#include <sys/ioccom.h>
75*/ 75*/
76#include <netsmb/smb.h> 76#include <netsmb/smb.h>
77#include <netsmb/smb_conn.h> 77#include <netsmb/smb_conn.h>
78#include <netsmb/smb_subr.h> 78#include <netsmb/smb_subr.h>
79 79
80#include <fs/smbfs/smbfs.h> 80#include <fs/smbfs/smbfs.h>
81#include <fs/smbfs/smbfs_node.h> 81#include <fs/smbfs/smbfs_node.h>
82#include <fs/smbfs/smbfs_subr.h> 82#include <fs/smbfs/smbfs_subr.h>
83 83
84/*#define SMBFS_RWGENERIC*/ 84/*#define SMBFS_RWGENERIC*/
85 85
86#define DE_SIZE (sizeof(struct dirent)) 86#define DE_SIZE (sizeof(struct dirent))
87 87
88static int 88static int
89smbfs_readvdir(struct vnode *vp, struct uio *uio, kauth_cred_t cred) 89smbfs_readvdir(struct vnode *vp, struct uio *uio, kauth_cred_t cred)
90{ 90{
91 struct dirent *de; 91 struct dirent *de;
92 struct smb_cred scred; 92 struct smb_cred scred;
93 struct smbfs_fctx *ctx; 93 struct smbfs_fctx *ctx;
94 struct smbnode *np = VTOSMB(vp); 94 struct smbnode *np = VTOSMB(vp);
95 int error = 0/*, *eofflag = ap->a_eofflag*/; 95 int error = 0/*, *eofflag = ap->a_eofflag*/;
96 long offset, limit; 96 long offset, limit;
97 97
98 KASSERT(vp->v_type == VDIR); 98 KASSERT(vp->v_type == VDIR);
99 99
100 if (uio->uio_resid < DE_SIZE || uio->uio_offset < 0) 100 if (uio->uio_resid < DE_SIZE || uio->uio_offset < 0)
101 return EINVAL; 101 return EINVAL;
102 102
103 de = malloc(DE_SIZE, M_SMBFSDATA, M_WAITOK | M_ZERO); 103 de = malloc(DE_SIZE, M_SMBFSDATA, M_WAITOK | M_ZERO);
104 104
105 SMBVDEBUG("dirname='%.*s'\n", (int) np->n_nmlen, np->n_name); 105 SMBVDEBUG("dirname='%.*s'\n", (int) np->n_nmlen, np->n_name);
106 smb_makescred(&scred, curlwp, cred); 106 smb_makescred(&scred, curlwp, cred);
107 offset = uio->uio_offset / DE_SIZE; /* offset in the directory */ 107 offset = uio->uio_offset / DE_SIZE; /* offset in the directory */
108 limit = uio->uio_resid / DE_SIZE; 108 limit = uio->uio_resid / DE_SIZE;
109 109
110 /* Simulate . */ 110 /* Simulate . */
111 if (offset < 1) { 111 if (offset < 1) {
112 memset(de, 0, DE_SIZE); 112 memset(de, 0, DE_SIZE);
113 de->d_fileno = np->n_ino; 113 de->d_fileno = np->n_ino;
114 de->d_reclen = DE_SIZE; 114 de->d_reclen = DE_SIZE;
115 de->d_type = DT_DIR; 115 de->d_type = DT_DIR;
116 de->d_namlen = 1; 116 de->d_namlen = 1;
117 strncpy(de->d_name, ".", 2); 117 strncpy(de->d_name, ".", 2);
118 error = uiomove(de, DE_SIZE, uio); 118 error = uiomove(de, DE_SIZE, uio);
119 if (error) 119 if (error)
120 goto out; 120 goto out;
121 limit--; 121 limit--;
122 offset++; 122 offset++;
123 } 123 }
124 /* Simulate .. */ 124 /* Simulate .. */
125 if (limit > 0 && offset < 2) { 125 if (limit > 0 && offset < 2) {
126 memset(de, 0, DE_SIZE); 126 memset(de, 0, DE_SIZE);
127 de->d_fileno = (np->n_parent ? VTOSMB(np->n_parent)->n_ino : 2); 127 de->d_fileno = (np->n_parent ? VTOSMB(np->n_parent)->n_ino : 2);
128 de->d_reclen = DE_SIZE; 128 de->d_reclen = DE_SIZE;
129 de->d_type = DT_DIR; 129 de->d_type = DT_DIR;
130 de->d_namlen = 2; 130 de->d_namlen = 2;
131 strncpy(de->d_name, "..", 3); 131 strncpy(de->d_name, "..", 3);
132 error = uiomove(de, DE_SIZE, uio); 132 error = uiomove(de, DE_SIZE, uio);
133 if (error) 133 if (error)
134 goto out; 134 goto out;
135 limit--; 135 limit--;
136 offset++; 136 offset++;
137 } 137 }
138 138
139 if (limit == 0) 139 if (limit == 0)
140 goto out; 140 goto out;
141 141
142 if (offset != np->n_dirofs || np->n_dirseq == NULL) { 142 if (offset != np->n_dirofs || np->n_dirseq == NULL) {
143 SMBVDEBUG("Reopening search %ld:%ld\n", offset, np->n_dirofs); 143 SMBVDEBUG("Reopening search %ld:%ld\n", offset, np->n_dirofs);
144 if (np->n_dirseq) { 144 if (np->n_dirseq) {
145 smbfs_findclose(np->n_dirseq, &scred); 145 smbfs_findclose(np->n_dirseq, &scred);
146 np->n_dirseq = NULL; 146 np->n_dirseq = NULL;
147 } 147 }
148 np->n_dirofs = 2; 148 np->n_dirofs = 2;
149 error = smbfs_findopen(np, "*", 1, 149 error = smbfs_findopen(np, "*", 1,
150 SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR, 150 SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR,
151 &scred, &ctx); 151 &scred, &ctx);
152 if (error) { 152 if (error) {
153 SMBVDEBUG("can not open search, error = %d", error); 153 SMBVDEBUG("can not open search, error = %d", error);
154 goto out; 154 goto out;
155 } 155 }
156 np->n_dirseq = ctx; 156 np->n_dirseq = ctx;
157 } else 157 } else
158 ctx = np->n_dirseq; 158 ctx = np->n_dirseq;
159 159
160 /* skip entries before offset */ 160 /* skip entries before offset */
161 while (np->n_dirofs < offset) { 161 while (np->n_dirofs < offset) {
162 error = smbfs_findnext(ctx, offset - np->n_dirofs++, &scred); 162 error = smbfs_findnext(ctx, offset - np->n_dirofs++, &scred);
163 if (error) { 163 if (error) {
164 smbfs_findclose(np->n_dirseq, &scred); 164 smbfs_findclose(np->n_dirseq, &scred);
165 np->n_dirseq = NULL; 165 np->n_dirseq = NULL;
166 error = (error == ENOENT) ? 0 : error; 166 error = (error == ENOENT) ? 0 : error;
167 goto out; 167 goto out;
168 } 168 }
169 } 169 }
170 170
171 for (; limit; limit--, offset++) { 171 for (; limit; limit--, offset++) {
172 error = smbfs_findnext(ctx, limit, &scred); 172 error = smbfs_findnext(ctx, limit, &scred);
173 if (error) { 173 if (error) {
174 if (error == ENOENT) 174 if (error == ENOENT)
175 error = 0; 175 error = 0;
176 break; 176 break;
177 } 177 }
178 np->n_dirofs++; 178 np->n_dirofs++;
179 memset(de, 0, DE_SIZE); 179 memset(de, 0, DE_SIZE);
180 de->d_reclen = DE_SIZE; 180 de->d_reclen = DE_SIZE;
181 de->d_fileno = ctx->f_attr.fa_ino; 181 de->d_fileno = ctx->f_attr.fa_ino;
182 de->d_type = (ctx->f_attr.fa_attr & SMB_FA_DIR) ? 182 de->d_type = (ctx->f_attr.fa_attr & SMB_FA_DIR) ?
183 DT_DIR : DT_REG; 183 DT_DIR : DT_REG;
184 de->d_namlen = ctx->f_nmlen; 184 de->d_namlen = ctx->f_nmlen;
185 memcpy(de->d_name, ctx->f_name, de->d_namlen); 185 memcpy(de->d_name, ctx->f_name, de->d_namlen);
186 de->d_name[de->d_namlen] = '\0'; 186 de->d_name[de->d_namlen] = '\0';
187 error = uiomove(de, DE_SIZE, uio); 187 error = uiomove(de, DE_SIZE, uio);
188 if (error) 188 if (error)
189 break; 189 break;
190 } 190 }
191 191
192out: 192out:
193 free(de, M_SMBFSDATA); 193 free(de, M_SMBFSDATA);
194 return (error); 194 return (error);
195} 195}
196 196
197int 197int
198smbfs_readvnode(struct vnode *vp, struct uio *uiop, kauth_cred_t cred) 198smbfs_readvnode(struct vnode *vp, struct uio *uiop, kauth_cred_t cred)
199{ 199{
200 struct smbmount *smp = VFSTOSMBFS(vp->v_mount); 200 struct smbmount *smp = VFSTOSMBFS(vp->v_mount);
201 struct smbnode *np = VTOSMB(vp); 201 struct smbnode *np = VTOSMB(vp);
202 struct lwp *l = curlwp; 202 struct lwp *l = curlwp;
203 struct vattr vattr; 203 struct vattr vattr;
204 struct smb_cred scred; 204 struct smb_cred scred;
205 int error; 205 int error;
206 206
207 KASSERT(vp->v_type == VREG || vp->v_type == VDIR); 207 KASSERT(vp->v_type == VREG || vp->v_type == VDIR);
208 208
209 if (uiop->uio_resid == 0) 209 if (uiop->uio_resid == 0)
210 return 0; 210 return 0;
211 if (uiop->uio_offset < 0) 211 if (uiop->uio_offset < 0)
212 return EINVAL; 212 return EINVAL;
213/* if (uiop->uio_offset + uiop->uio_resid > smp->nm_maxfilesize) 213/* if (uiop->uio_offset + uiop->uio_resid > smp->nm_maxfilesize)
214 return EFBIG;*/ 214 return EFBIG;*/
215 if (vp->v_type == VDIR) { 215 if (vp->v_type == VDIR) {
216 error = smbfs_readvdir(vp, uiop, cred); 216 error = smbfs_readvdir(vp, uiop, cred);
217 return error; 217 return error;
218 } 218 }
219 219
220 if (np->n_flag & NMODIFIED) { 220 if (np->n_flag & NMODIFIED) {
221 smbfs_attr_cacheremove(vp); 221 smbfs_attr_cacheremove(vp);
222 error = VOP_GETATTR(vp, &vattr, cred); 222 error = VOP_GETATTR(vp, &vattr, cred);
223 if (error) 223 if (error)
224 return error; 224 return error;
225 np->n_mtime.tv_sec = vattr.va_mtime.tv_sec; 225 np->n_mtime.tv_sec = vattr.va_mtime.tv_sec;
226 } else { 226 } else {
227 error = VOP_GETATTR(vp, &vattr, cred); 227 error = VOP_GETATTR(vp, &vattr, cred);
228 if (error) 228 if (error)
229 return error; 229 return error;
230 if (np->n_mtime.tv_sec != vattr.va_mtime.tv_sec) { 230 if (np->n_mtime.tv_sec != vattr.va_mtime.tv_sec) {
231 error = smbfs_vinvalbuf(vp, V_SAVE, cred, l, 1); 231 error = smbfs_vinvalbuf(vp, V_SAVE, cred, l, 1);
232 if (error) 232 if (error)
233 return error; 233 return error;
234 np->n_mtime.tv_sec = vattr.va_mtime.tv_sec; 234 np->n_mtime.tv_sec = vattr.va_mtime.tv_sec;
235 } 235 }
236 } 236 }
237 smb_makescred(&scred, l, cred); 237 smb_makescred(&scred, l, cred);
238 return smb_read(smp->sm_share, np->n_fid, uiop, &scred); 238 return smb_read(smp->sm_share, np->n_fid, uiop, &scred);
239} 239}
240 240
241int 241int
242smbfs_writevnode(struct vnode *vp, struct uio *uiop, 242smbfs_writevnode(struct vnode *vp, struct uio *uiop,
243 kauth_cred_t cred, int ioflag) 243 kauth_cred_t cred, int ioflag)
244{ 244{
245 struct smbmount *smp = VTOSMBFS(vp); 245 struct smbmount *smp = VTOSMBFS(vp);
246 struct smbnode *np = VTOSMB(vp); 246 struct smbnode *np = VTOSMB(vp);
247 struct smb_cred scred; 247 struct smb_cred scred;
248 struct lwp *l = curlwp; 248 struct lwp *l = curlwp;
249 struct proc *p = l->l_proc; 249 struct proc *p = l->l_proc;
250 int error = 0; 250 int error = 0;
251 int extended = 0; 251 int extended = 0;
252 size_t resid = uiop->uio_resid; 252 size_t resid = uiop->uio_resid;
253 253
254 /* vn types other than VREG unsupported */ 254 /* vn types other than VREG unsupported */
255 KASSERT(vp->v_type == VREG); 255 KASSERT(vp->v_type == VREG);
256 256
257 SMBVDEBUG("ofs=%lld,resid=%d\n", 257 SMBVDEBUG("ofs=%lld,resid=%zu\n",
258 (long long int) uiop->uio_offset, 258 (long long int) uiop->uio_offset,
259 uiop->uio_resid); 259 uiop->uio_resid);
260 if (uiop->uio_offset < 0) 260 if (uiop->uio_offset < 0)
261 return EINVAL; 261 return EINVAL;
262/* if (uiop->uio_offset + uiop->uio_resid > smp->nm_maxfilesize) 262/* if (uiop->uio_offset + uiop->uio_resid > smp->nm_maxfilesize)
263 return (EFBIG);*/ 263 return (EFBIG);*/
264 if (ioflag & (IO_APPEND | IO_SYNC)) { 264 if (ioflag & (IO_APPEND | IO_SYNC)) {
265 if (np->n_flag & NMODIFIED) { 265 if (np->n_flag & NMODIFIED) {
266 smbfs_attr_cacheremove(vp); 266 smbfs_attr_cacheremove(vp);
267 error = smbfs_vinvalbuf(vp, V_SAVE, cred, l, 1); 267 error = smbfs_vinvalbuf(vp, V_SAVE, cred, l, 1);
268 if (error) 268 if (error)
269 return error; 269 return error;
270 } 270 }
271 if (ioflag & IO_APPEND) { 271 if (ioflag & IO_APPEND) {
272#if notyet 272#if notyet
273 /* 273 /*
274 * File size can be changed by another client 274 * File size can be changed by another client
275 */ 275 */
276 smbfs_attr_cacheremove(vp); 276 smbfs_attr_cacheremove(vp);
277 error = VOP_GETATTR(vp, &vattr, cred, td); 277 error = VOP_GETATTR(vp, &vattr, cred, td);
278 if (error) 278 if (error)
279 return (error); 279 return (error);
280#endif 280#endif
281 uiop->uio_offset = np->n_size; 281 uiop->uio_offset = np->n_size;
282 } 282 }
283 } 283 }
284 if (uiop->uio_resid == 0) 284 if (uiop->uio_resid == 0)
285 return 0; 285 return 0;
286 if (p && uiop->uio_offset + uiop->uio_resid > p->p_rlimit[RLIMIT_FSIZE].rlim_cur) { 286 if (p && uiop->uio_offset + uiop->uio_resid > p->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
287 mutex_enter(proc_lock); 287 mutex_enter(proc_lock);
288 psignal(p, SIGXFSZ); 288 psignal(p, SIGXFSZ);
289 mutex_exit(proc_lock); 289 mutex_exit(proc_lock);
290 return EFBIG; 290 return EFBIG;
291 } 291 }
292 smb_makescred(&scred, l, cred); 292 smb_makescred(&scred, l, cred);
293 error = smb_write(smp->sm_share, np->n_fid, uiop, &scred); 293 error = smb_write(smp->sm_share, np->n_fid, uiop, &scred);
294 SMBVDEBUG("after: ofs=%lld,resid=%d,err=%d\n",(long long int)uiop->uio_offset, uiop->uio_resid, error); 294 SMBVDEBUG("after: ofs=%lld,resid=%zu,err=%d\n",
 295 (long long int)uiop->uio_offset, uiop->uio_resid, error);
295 if (!error) { 296 if (!error) {
296 if (uiop->uio_offset > np->n_size) { 297 if (uiop->uio_offset > np->n_size) {
297 np->n_size = uiop->uio_offset; 298 np->n_size = uiop->uio_offset;
298 uvm_vnp_setsize(vp, np->n_size); 299 uvm_vnp_setsize(vp, np->n_size);
299 extended = 1; 300 extended = 1;
300 } 301 }
301 302
302 } 303 }
303 if (resid > uiop->uio_resid) 304 if (resid > uiop->uio_resid)
304 VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); 305 VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0));
305 return error; 306 return error;
306} 307}
307 308
308/* 309/*
309 * Do an I/O operation to/from a cache block. 310 * Do an I/O operation to/from a cache block.
310 */ 311 */
311int 312int
312smbfs_doio(struct buf *bp, kauth_cred_t cr, struct lwp *l) 313smbfs_doio(struct buf *bp, kauth_cred_t cr, struct lwp *l)
313{ 314{
314 struct vnode *vp = bp->b_vp; 315 struct vnode *vp = bp->b_vp;
315 struct smbmount *smp = VFSTOSMBFS(vp->v_mount); 316 struct smbmount *smp = VFSTOSMBFS(vp->v_mount);
316 struct smbnode *np = VTOSMB(vp); 317 struct smbnode *np = VTOSMB(vp);
317 struct uio uio, *uiop = &uio; 318 struct uio uio, *uiop = &uio;
318 struct iovec io; 319 struct iovec io;
319 struct smb_cred scred; 320 struct smb_cred scred;
320 int error = 0; 321 int error = 0;
321 322
322 uiop->uio_iov = &io; 323 uiop->uio_iov = &io;
323 uiop->uio_iovcnt = 1; 324 uiop->uio_iovcnt = 1;
324 UIO_SETUP_SYSSPACE(uiop); 325 UIO_SETUP_SYSSPACE(uiop);
325 326
326 smb_makescred(&scred, l, cr); 327 smb_makescred(&scred, l, cr);
327 328
328 if (bp->b_flags == B_READ) { 329 if (bp->b_flags == B_READ) {
329 io.iov_len = uiop->uio_resid = bp->b_bcount; 330 io.iov_len = uiop->uio_resid = bp->b_bcount;
330 io.iov_base = bp->b_data; 331 io.iov_base = bp->b_data;
331 uiop->uio_rw = UIO_READ; 332 uiop->uio_rw = UIO_READ;
332 switch (vp->v_type) { 333 switch (vp->v_type) {
333 case VREG: 334 case VREG:
334 uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE; 335 uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE;
335 error = smb_read(smp->sm_share, np->n_fid, uiop, &scred); 336 error = smb_read(smp->sm_share, np->n_fid, uiop, &scred);
336 if (error) 337 if (error)
337 break; 338 break;
338 if (uiop->uio_resid) { 339 if (uiop->uio_resid) {
339 int left = uiop->uio_resid; 340 int left = uiop->uio_resid;
340 int nread = bp->b_bcount - left; 341 int nread = bp->b_bcount - left;
341 if (left > 0) 342 if (left > 0)
342 memset((char *)bp->b_data + nread, 0, left); 343 memset((char *)bp->b_data + nread, 0, left);
343 } 344 }
344 break; 345 break;
345 default: 346 default:
346 printf("smbfs_doio: type %x unexpected\n",vp->v_type); 347 printf("smbfs_doio: type %x unexpected\n",vp->v_type);
347 break; 348 break;
348 }; 349 };
349 if (error) { 350 if (error) {
350 bp->b_error = error; 351 bp->b_error = error;
351 } 352 }
352 } else { /* write */ 353 } else { /* write */
353 io.iov_len = uiop->uio_resid = bp->b_bcount; 354 io.iov_len = uiop->uio_resid = bp->b_bcount;
354 uiop->uio_offset = ((off_t)bp->b_blkno) << DEV_BSHIFT; 355 uiop->uio_offset = ((off_t)bp->b_blkno) << DEV_BSHIFT;
355 io.iov_base = bp->b_data; 356 io.iov_base = bp->b_data;
356 uiop->uio_rw = UIO_WRITE; 357 uiop->uio_rw = UIO_WRITE;
357 bp->b_cflags |= BC_BUSY; 358 bp->b_cflags |= BC_BUSY;
358 error = smb_write(smp->sm_share, np->n_fid, uiop, &scred); 359 error = smb_write(smp->sm_share, np->n_fid, uiop, &scred);
359 bp->b_cflags &= ~BC_BUSY; 360 bp->b_cflags &= ~BC_BUSY;
360 361
361 362
362#ifndef __NetBSD__ /* XXX */ 363#ifndef __NetBSD__ /* XXX */
363 /* 364 /*
364 * For an interrupted write, the buffer is still valid 365 * For an interrupted write, the buffer is still valid
365 * and the write hasn't been pushed to the server yet, 366 * and the write hasn't been pushed to the server yet,
366 * so we can't set BIO_ERROR and report the interruption 367 * so we can't set BIO_ERROR and report the interruption
367 * by setting B_EINTR. For the B_ASYNC case, B_EINTR 368 * by setting B_EINTR. For the B_ASYNC case, B_EINTR
368 * is not relevant, so the rpc attempt is essentially 369 * is not relevant, so the rpc attempt is essentially
369 * a noop. For the case of a V3 write rpc not being 370 * a noop. For the case of a V3 write rpc not being
370 * committed to stable storage, the block is still 371 * committed to stable storage, the block is still
371 * dirty and requires either a commit rpc or another 372 * dirty and requires either a commit rpc or another
372 * write rpc with iomode == NFSV3WRITE_FILESYNC before 373 * write rpc with iomode == NFSV3WRITE_FILESYNC before
373 * the block is reused. This is indicated by setting 374 * the block is reused. This is indicated by setting
374 * the B_DELWRI and B_NEEDCOMMIT flags. 375 * the B_DELWRI and B_NEEDCOMMIT flags.
375 */ 376 */
376 if (error == EINTR 377 if (error == EINTR
377 || (!error && (bp->b_flags & B_NEEDCOMMIT))) { 378 || (!error && (bp->b_flags & B_NEEDCOMMIT))) {
378 int s; 379 int s;
379 380
380 s = splbio(); 381 s = splbio();
381 bp->b_flags &= ~(B_INVAL|B_NOCACHE); 382 bp->b_flags &= ~(B_INVAL|B_NOCACHE);
382 if ((bp->b_flags & B_ASYNC) == 0) 383 if ((bp->b_flags & B_ASYNC) == 0)
383 bp->b_flags |= B_EINTR; 384 bp->b_flags |= B_EINTR;
384 if ((bp->b_flags & B_PAGING) == 0) { 385 if ((bp->b_flags & B_PAGING) == 0) {
385 bdirty(bp); 386 bdirty(bp);
386 bp->b_flags &= ~B_DONE; 387 bp->b_flags &= ~B_DONE;
387 } 388 }
388 if ((bp->b_flags & B_ASYNC) == 0) 389 if ((bp->b_flags & B_ASYNC) == 0)
389 bp->b_flags |= B_EINTR; 390 bp->b_flags |= B_EINTR;
390 splx(s); 391 splx(s);
391 } else { 392 } else {
392 if (error) { 393 if (error) {
393 bp->b_ioflags |= BIO_ERROR; 394 bp->b_ioflags |= BIO_ERROR;
394 bp->b_error = error; 395 bp->b_error = error;
395 } 396 }
396 bp->b_dirtyoff = bp->b_dirtyend = 0; 397 bp->b_dirtyoff = bp->b_dirtyend = 0;
397 } 398 }
398#endif /* !__NetBSD__ */ 399#endif /* !__NetBSD__ */
399 } 400 }
400 bp->b_resid = uiop->uio_resid; 401 bp->b_resid = uiop->uio_resid;
401 biodone(bp); 402 biodone(bp);
402 return error; 403 return error;
403} 404}
404 405
405/* 406/*
406 * Flush and invalidate all dirty buffers. If another process is already 407 * Flush and invalidate all dirty buffers. If another process is already
407 * doing the flush, just wait for completion. 408 * doing the flush, just wait for completion.
408 */ 409 */
409int 410int
410smbfs_vinvalbuf(struct vnode *vp, int flags, kauth_cred_t cred, struct lwp *l, int intrflg) 411smbfs_vinvalbuf(struct vnode *vp, int flags, kauth_cred_t cred, struct lwp *l, int intrflg)
411{ 412{
412 struct smbnode *np = VTOSMB(vp); 413 struct smbnode *np = VTOSMB(vp);
413 int error = 0, slpflag; 414 int error = 0, slpflag;
414 415
415 if (intrflg) 416 if (intrflg)
416 slpflag = PCATCH; 417 slpflag = PCATCH;
417 else 418 else
418 slpflag = 0; 419 slpflag = 0;
419 420
420 while (np->n_flag & NFLUSHINPROG) { 421 while (np->n_flag & NFLUSHINPROG) {
421 np->n_flag |= NFLUSHWANT; 422 np->n_flag |= NFLUSHWANT;
422 error = tsleep(&np->n_flag, 423 error = tsleep(&np->n_flag,
423 (PRIBIO + 2) | slpflag, "smfsvinv", 0); 424 (PRIBIO + 2) | slpflag, "smfsvinv", 0);
424 if (error) 425 if (error)
425 return (error); 426 return (error);
426 } 427 }
427 np->n_flag |= NFLUSHINPROG; 428 np->n_flag |= NFLUSHINPROG;
428 for(;;) { 429 for(;;) {
429 if ((error = vinvalbuf(vp, flags, cred, l, slpflag, 0)) == 0) 430 if ((error = vinvalbuf(vp, flags, cred, l, slpflag, 0)) == 0)
430 break; 431 break;
431 432
432 if (intrflg && (error == ERESTART || error == EINTR)) { 433 if (intrflg && (error == ERESTART || error == EINTR)) {
433 np->n_flag &= ~NFLUSHINPROG; 434 np->n_flag &= ~NFLUSHINPROG;
434 if (np->n_flag & NFLUSHWANT) { 435 if (np->n_flag & NFLUSHWANT) {
435 np->n_flag &= ~NFLUSHWANT; 436 np->n_flag &= ~NFLUSHWANT;
436 wakeup(&np->n_flag); 437 wakeup(&np->n_flag);
437 } 438 }
438 return (error); 439 return (error);
439 } 440 }
440 } 441 }
441 np->n_flag &= ~(NMODIFIED | NFLUSHINPROG); 442 np->n_flag &= ~(NMODIFIED | NFLUSHINPROG);
442 if (np->n_flag & NFLUSHWANT) { 443 if (np->n_flag & NFLUSHWANT) {
443 np->n_flag &= ~NFLUSHWANT; 444 np->n_flag &= ~NFLUSHWANT;
444 wakeup(&np->n_flag); 445 wakeup(&np->n_flag);
445 } 446 }
446 return (error); 447 return (error);
447} 448}

cvs diff -r1.67 -r1.68 src/sys/fs/smbfs/Attic/smbfs_vnops.c (switch to unified diff)

--- src/sys/fs/smbfs/Attic/smbfs_vnops.c 2009/05/07 19:30:30 1.67
+++ src/sys/fs/smbfs/Attic/smbfs_vnops.c 2009/06/22 21:13:50 1.68
@@ -1,1358 +1,1359 @@ @@ -1,1358 +1,1359 @@
1/* $NetBSD: smbfs_vnops.c,v 1.67 2009/05/07 19:30:30 elad Exp $ */ 1/* $NetBSD: smbfs_vnops.c,v 1.68 2009/06/22 21:13:50 njoly Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jaromir Dolecek. 8 * by Jaromir Dolecek.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 2000-2001 Boris Popov 33 * Copyright (c) 2000-2001 Boris Popov
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software 44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement: 45 * must display the following acknowledgement:
46 * This product includes software developed by Boris Popov. 46 * This product includes software developed by Boris Popov.
47 * 4. Neither the name of the author nor the names of any co-contributors 47 * 4. Neither the name of the author nor the names of any co-contributors
48 * may be used to endorse or promote products derived from this software 48 * may be used to endorse or promote products derived from this software
49 * without specific prior written permission. 49 * without specific prior written permission.
50 * 50 *
51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE. 61 * SUCH DAMAGE.
62 * 62 *
63 * FreeBSD: src/sys/fs/smbfs/smbfs_vnops.c,v 1.15 2001/12/20 15:56:45 bp Exp 63 * FreeBSD: src/sys/fs/smbfs/smbfs_vnops.c,v 1.15 2001/12/20 15:56:45 bp Exp
64 */ 64 */
65 65
66#include <sys/cdefs.h> 66#include <sys/cdefs.h>
67__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.67 2009/05/07 19:30:30 elad Exp $"); 67__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.68 2009/06/22 21:13:50 njoly Exp $");
68 68
69#include <sys/param.h> 69#include <sys/param.h>
70#include <sys/systm.h> 70#include <sys/systm.h>
71#include <sys/namei.h> 71#include <sys/namei.h>
72#include <sys/kernel.h> 72#include <sys/kernel.h>
73#include <sys/proc.h> 73#include <sys/proc.h>
74#include <sys/buf.h> 74#include <sys/buf.h>
75#include <sys/fcntl.h> 75#include <sys/fcntl.h>
76#include <sys/mount.h> 76#include <sys/mount.h>
77#include <sys/unistd.h> 77#include <sys/unistd.h>
78#include <sys/vnode.h> 78#include <sys/vnode.h>
79#include <sys/lockf.h> 79#include <sys/lockf.h>
80#include <sys/kauth.h> 80#include <sys/kauth.h>
81 81
82#include <machine/limits.h> 82#include <machine/limits.h>
83 83
84#include <uvm/uvm.h> 84#include <uvm/uvm.h>
85#include <uvm/uvm_extern.h> 85#include <uvm/uvm_extern.h>
86 86
87#include <netsmb/smb.h> 87#include <netsmb/smb.h>
88#include <netsmb/smb_conn.h> 88#include <netsmb/smb_conn.h>
89#include <netsmb/smb_subr.h> 89#include <netsmb/smb_subr.h>
90 90
91#include <fs/smbfs/smbfs.h> 91#include <fs/smbfs/smbfs.h>
92#include <fs/smbfs/smbfs_node.h> 92#include <fs/smbfs/smbfs_node.h>
93#include <fs/smbfs/smbfs_subr.h> 93#include <fs/smbfs/smbfs_subr.h>
94 94
95#include <miscfs/genfs/genfs.h> 95#include <miscfs/genfs/genfs.h>
96 96
97/* 97/*
98 * Prototypes for SMBFS vnode operations 98 * Prototypes for SMBFS vnode operations
99 */ 99 */
100int smbfs_create(void *); 100int smbfs_create(void *);
101int smbfs_open(void *); 101int smbfs_open(void *);
102int smbfs_close(void *); 102int smbfs_close(void *);
103int smbfs_access(void *); 103int smbfs_access(void *);
104int smbfs_getattr(void *); 104int smbfs_getattr(void *);
105int smbfs_setattr(void *); 105int smbfs_setattr(void *);
106int smbfs_read(void *); 106int smbfs_read(void *);
107int smbfs_write(void *); 107int smbfs_write(void *);
108int smbfs_fsync(void *); 108int smbfs_fsync(void *);
109int smbfs_remove(void *); 109int smbfs_remove(void *);
110int smbfs_link(void *); 110int smbfs_link(void *);
111int smbfs_lookup(void *); 111int smbfs_lookup(void *);
112int smbfs_rename(void *); 112int smbfs_rename(void *);
113int smbfs_mkdir(void *); 113int smbfs_mkdir(void *);
114int smbfs_rmdir(void *); 114int smbfs_rmdir(void *);
115int smbfs_symlink(void *); 115int smbfs_symlink(void *);
116int smbfs_readdir(void *); 116int smbfs_readdir(void *);
117int smbfs_strategy(void *); 117int smbfs_strategy(void *);
118int smbfs_print(void *); 118int smbfs_print(void *);
119int smbfs_pathconf(void *ap); 119int smbfs_pathconf(void *ap);
120int smbfs_advlock(void *); 120int smbfs_advlock(void *);
121 121
122int (**smbfs_vnodeop_p)(void *); 122int (**smbfs_vnodeop_p)(void *);
123static struct vnodeopv_entry_desc smbfs_vnodeop_entries[] = { 123static struct vnodeopv_entry_desc smbfs_vnodeop_entries[] = {
124 { &vop_default_desc, vn_default_error }, 124 { &vop_default_desc, vn_default_error },
125 { &vop_access_desc, smbfs_access }, 125 { &vop_access_desc, smbfs_access },
126 { &vop_advlock_desc, smbfs_advlock }, 126 { &vop_advlock_desc, smbfs_advlock },
127 { &vop_close_desc, smbfs_close }, 127 { &vop_close_desc, smbfs_close },
128 { &vop_create_desc, smbfs_create }, 128 { &vop_create_desc, smbfs_create },
129 { &vop_fsync_desc, smbfs_fsync }, 129 { &vop_fsync_desc, smbfs_fsync },
130 { &vop_getattr_desc, smbfs_getattr }, 130 { &vop_getattr_desc, smbfs_getattr },
131 { &vop_getpages_desc, genfs_compat_getpages }, 131 { &vop_getpages_desc, genfs_compat_getpages },
132 { &vop_inactive_desc, smbfs_inactive }, 132 { &vop_inactive_desc, smbfs_inactive },
133 { &vop_ioctl_desc, genfs_enoioctl }, 133 { &vop_ioctl_desc, genfs_enoioctl },
134 { &vop_islocked_desc, genfs_islocked }, 134 { &vop_islocked_desc, genfs_islocked },
135 { &vop_link_desc, smbfs_link }, 135 { &vop_link_desc, smbfs_link },
136 { &vop_lock_desc, genfs_lock }, 136 { &vop_lock_desc, genfs_lock },
137 { &vop_lookup_desc, smbfs_lookup }, 137 { &vop_lookup_desc, smbfs_lookup },
138 { &vop_mkdir_desc, smbfs_mkdir }, 138 { &vop_mkdir_desc, smbfs_mkdir },
139 { &vop_mknod_desc, genfs_eopnotsupp }, 139 { &vop_mknod_desc, genfs_eopnotsupp },
140 { &vop_open_desc, smbfs_open }, 140 { &vop_open_desc, smbfs_open },
141 { &vop_pathconf_desc, smbfs_pathconf }, 141 { &vop_pathconf_desc, smbfs_pathconf },
142 { &vop_print_desc, smbfs_print }, 142 { &vop_print_desc, smbfs_print },
143 { &vop_putpages_desc, genfs_putpages }, 143 { &vop_putpages_desc, genfs_putpages },
144 { &vop_read_desc, smbfs_read }, 144 { &vop_read_desc, smbfs_read },
145 { &vop_readdir_desc, smbfs_readdir }, 145 { &vop_readdir_desc, smbfs_readdir },
146 { &vop_reclaim_desc, smbfs_reclaim }, 146 { &vop_reclaim_desc, smbfs_reclaim },
147 { &vop_remove_desc, smbfs_remove }, 147 { &vop_remove_desc, smbfs_remove },
148 { &vop_rename_desc, smbfs_rename }, 148 { &vop_rename_desc, smbfs_rename },
149 { &vop_rmdir_desc, smbfs_rmdir }, 149 { &vop_rmdir_desc, smbfs_rmdir },
150 { &vop_setattr_desc, smbfs_setattr }, 150 { &vop_setattr_desc, smbfs_setattr },
151 { &vop_strategy_desc, smbfs_strategy }, 151 { &vop_strategy_desc, smbfs_strategy },
152 { &vop_symlink_desc, smbfs_symlink }, 152 { &vop_symlink_desc, smbfs_symlink },
153 { &vop_unlock_desc, genfs_unlock }, 153 { &vop_unlock_desc, genfs_unlock },
154 { &vop_write_desc, smbfs_write }, 154 { &vop_write_desc, smbfs_write },
155 { &vop_mmap_desc, genfs_mmap }, /* mmap */ 155 { &vop_mmap_desc, genfs_mmap }, /* mmap */
156 { &vop_seek_desc, genfs_seek }, /* seek */ 156 { &vop_seek_desc, genfs_seek }, /* seek */
157 { &vop_kqfilter_desc, smbfs_kqfilter}, /* kqfilter */ 157 { &vop_kqfilter_desc, smbfs_kqfilter}, /* kqfilter */
158 { NULL, NULL } 158 { NULL, NULL }
159}; 159};
160const struct vnodeopv_desc smbfs_vnodeop_opv_desc = 160const struct vnodeopv_desc smbfs_vnodeop_opv_desc =
161 { &smbfs_vnodeop_p, smbfs_vnodeop_entries }; 161 { &smbfs_vnodeop_p, smbfs_vnodeop_entries };
162 162
163int 163int
164smbfs_access(void *v) 164smbfs_access(void *v)
165{ 165{
166 struct vop_access_args /* { 166 struct vop_access_args /* {
167 struct vnode *a_vp; 167 struct vnode *a_vp;
168 int a_mode; 168 int a_mode;
169 kauth_cred_t a_cred; 169 kauth_cred_t a_cred;
170 } */ *ap = v; 170 } */ *ap = v;
171 struct vnode *vp = ap->a_vp; 171 struct vnode *vp = ap->a_vp;
172#ifdef SMB_VNODE_DEBUG 172#ifdef SMB_VNODE_DEBUG
173 struct smbnode *np = VTOSMB(vp); 173 struct smbnode *np = VTOSMB(vp);
174#endif 174#endif
175 u_int acc_mode = ap->a_mode; 175 u_int acc_mode = ap->a_mode;
176 struct smbmount *smp = VTOSMBFS(vp); 176 struct smbmount *smp = VTOSMBFS(vp);
177 177
178 SMBVDEBUG("file '%.*s', node mode=%o, acc mode=%x\n", 178 SMBVDEBUG("file '%.*s', node mode=%o, acc mode=%x\n",
179 (int) np->n_nmlen, np->n_name, 179 (int) np->n_nmlen, np->n_name,
180 (vp->v_type == VDIR) ? smp->sm_args.dir_mode : smp->sm_args.file_mode, 180 (vp->v_type == VDIR) ? smp->sm_args.dir_mode : smp->sm_args.file_mode,
181 acc_mode); 181 acc_mode);
182 182
183 /* 183 /*
184 * Disallow write attempts on read-only file systems; 184 * Disallow write attempts on read-only file systems;
185 * unless the file is a socket, fifo, or a block or 185 * unless the file is a socket, fifo, or a block or
186 * character device resident on the file system. 186 * character device resident on the file system.
187 */ 187 */
188 if (acc_mode & VWRITE) { 188 if (acc_mode & VWRITE) {
189 switch (vp->v_type) { 189 switch (vp->v_type) {
190 case VREG: 190 case VREG:
191 case VDIR: 191 case VDIR:
192 case VLNK: 192 case VLNK:
193 if (vp->v_mount->mnt_flag & MNT_RDONLY) 193 if (vp->v_mount->mnt_flag & MNT_RDONLY)
194 return EROFS; 194 return EROFS;
195 default: 195 default:
196 break; 196 break;
197 } 197 }
198 } 198 }
199 199
200 return (vaccess(vp->v_type, 200 return (vaccess(vp->v_type,
201 (vp->v_type == VDIR) ? smp->sm_args.dir_mode : smp->sm_args.file_mode, 201 (vp->v_type == VDIR) ? smp->sm_args.dir_mode : smp->sm_args.file_mode,
202 smp->sm_args.uid, smp->sm_args.gid, 202 smp->sm_args.uid, smp->sm_args.gid,
203 acc_mode, ap->a_cred)); 203 acc_mode, ap->a_cred));
204} 204}
205 205
206/* ARGSUSED */ 206/* ARGSUSED */
207int 207int
208smbfs_open(void *v) 208smbfs_open(void *v)
209{ 209{
210 struct vop_open_args /* { 210 struct vop_open_args /* {
211 struct vnode *a_vp; 211 struct vnode *a_vp;
212 int a_mode; 212 int a_mode;
213 kauth_cred_t a_cred; 213 kauth_cred_t a_cred;
214 } */ *ap = v; 214 } */ *ap = v;
215 struct lwp *l = curlwp; 215 struct lwp *l = curlwp;
216 struct vnode *vp = ap->a_vp; 216 struct vnode *vp = ap->a_vp;
217 struct smbnode *np = VTOSMB(vp); 217 struct smbnode *np = VTOSMB(vp);
218 struct smb_cred scred; 218 struct smb_cred scred;
219 struct vattr vattr; 219 struct vattr vattr;
220 u_int32_t sv_caps = SMB_CAPS(SSTOVC(np->n_mount->sm_share)); 220 u_int32_t sv_caps = SMB_CAPS(SSTOVC(np->n_mount->sm_share));
221 int error, accmode; 221 int error, accmode;
222 222
223 SMBVDEBUG("%.*s,%d\n", (int) np->n_nmlen, np->n_name, 223 SMBVDEBUG("%.*s,%d\n", (int) np->n_nmlen, np->n_name,
224 (np->n_flag & NOPEN) != 0); 224 (np->n_flag & NOPEN) != 0);
225 if (vp->v_type != VREG && vp->v_type != VDIR) { 225 if (vp->v_type != VREG && vp->v_type != VDIR) {
226 SMBFSERR("open eacces vtype=%d\n", vp->v_type); 226 SMBFSERR("open eacces vtype=%d\n", vp->v_type);
227 return EACCES; 227 return EACCES;
228 } 228 }
229 if (vp->v_type == VDIR) { 229 if (vp->v_type == VDIR) {
230 if ((sv_caps & SMB_CAP_NT_SMBS) == 0) { 230 if ((sv_caps & SMB_CAP_NT_SMBS) == 0) {
231 np->n_flag |= NOPEN; 231 np->n_flag |= NOPEN;
232 return 0; 232 return 0;
233 } 233 }
234 234
235 goto do_open; /* skip 'modified' check */ 235 goto do_open; /* skip 'modified' check */
236 } 236 }
237 237
238 if (np->n_flag & NMODIFIED) { 238 if (np->n_flag & NMODIFIED) {
239 if ((error = smbfs_vinvalbuf(vp, V_SAVE, ap->a_cred, l, 1)) == EINTR) 239 if ((error = smbfs_vinvalbuf(vp, V_SAVE, ap->a_cred, l, 1)) == EINTR)
240 return error; 240 return error;
241 smbfs_attr_cacheremove(vp); 241 smbfs_attr_cacheremove(vp);
242 error = VOP_GETATTR(vp, &vattr, ap->a_cred); 242 error = VOP_GETATTR(vp, &vattr, ap->a_cred);
243 if (error) 243 if (error)
244 return error; 244 return error;
245 np->n_mtime.tv_sec = vattr.va_mtime.tv_sec; 245 np->n_mtime.tv_sec = vattr.va_mtime.tv_sec;
246 } else { 246 } else {
247 error = VOP_GETATTR(vp, &vattr, ap->a_cred); 247 error = VOP_GETATTR(vp, &vattr, ap->a_cred);
248 if (error) 248 if (error)
249 return error; 249 return error;
250 if (np->n_mtime.tv_sec != vattr.va_mtime.tv_sec) { 250 if (np->n_mtime.tv_sec != vattr.va_mtime.tv_sec) {
251 error = smbfs_vinvalbuf(vp, V_SAVE, ap->a_cred, l, 1); 251 error = smbfs_vinvalbuf(vp, V_SAVE, ap->a_cred, l, 1);
252 if (error == EINTR) 252 if (error == EINTR)
253 return error; 253 return error;
254 np->n_mtime.tv_sec = vattr.va_mtime.tv_sec; 254 np->n_mtime.tv_sec = vattr.va_mtime.tv_sec;
255 } 255 }
256 } 256 }
257 257
258do_open: 258do_open:
259 if ((np->n_flag & NOPEN) != 0) 259 if ((np->n_flag & NOPEN) != 0)
260 return 0; 260 return 0;
261 261
262 smb_makescred(&scred, l, ap->a_cred); 262 smb_makescred(&scred, l, ap->a_cred);
263 if (vp->v_type == VDIR) 263 if (vp->v_type == VDIR)
264 error = smbfs_smb_ntcreatex(np, 264 error = smbfs_smb_ntcreatex(np,
265 SMB_SM_DENYNONE|SMB_AM_OPENREAD, &scred); 265 SMB_SM_DENYNONE|SMB_AM_OPENREAD, &scred);
266 else { 266 else {
267 /* 267 /*
268 * Use DENYNONE to give unixy semantics of permitting 268 * Use DENYNONE to give unixy semantics of permitting
269 * everything not forbidden by permissions. Ie denial 269 * everything not forbidden by permissions. Ie denial
270 * is up to server with clients/openers needing to use 270 * is up to server with clients/openers needing to use
271 * advisory locks for further control. 271 * advisory locks for further control.
272 */ 272 */
273 accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD; 273 accmode = SMB_SM_DENYNONE|SMB_AM_OPENREAD;
274 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 274 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
275 accmode = SMB_SM_DENYNONE|SMB_AM_OPENRW; 275 accmode = SMB_SM_DENYNONE|SMB_AM_OPENRW;
276 error = smbfs_smb_open(np, accmode, &scred); 276 error = smbfs_smb_open(np, accmode, &scred);
277 if (error) { 277 if (error) {
278 if (ap->a_mode & FWRITE) 278 if (ap->a_mode & FWRITE)
279 return EACCES; 279 return EACCES;
280 280
281 error = smbfs_smb_open(np, 281 error = smbfs_smb_open(np,
282 SMB_SM_DENYNONE|SMB_AM_OPENREAD, &scred); 282 SMB_SM_DENYNONE|SMB_AM_OPENREAD, &scred);
283 } 283 }
284 } 284 }
285 if (!error) 285 if (!error)
286 np->n_flag |= NOPEN; 286 np->n_flag |= NOPEN;
287 smbfs_attr_cacheremove(vp); 287 smbfs_attr_cacheremove(vp);
288 return error; 288 return error;
289} 289}
290 290
291/* 291/*
292 * Close called. 292 * Close called.
293 */ 293 */
294int 294int
295smbfs_close(void *v) 295smbfs_close(void *v)
296{ 296{
297 struct vop_close_args /* { 297 struct vop_close_args /* {
298 struct vnodeop_desc *a_desc; 298 struct vnodeop_desc *a_desc;
299 struct vnode *a_vp; 299 struct vnode *a_vp;
300 int a_fflag; 300 int a_fflag;
301 kauth_cred_t a_cred; 301 kauth_cred_t a_cred;
302 } */ *ap = v; 302 } */ *ap = v;
303 int error; 303 int error;
304 struct lwp *l = curlwp; 304 struct lwp *l = curlwp;
305 struct vnode *vp = ap->a_vp; 305 struct vnode *vp = ap->a_vp;
306 struct smbnode *np = VTOSMB(vp); 306 struct smbnode *np = VTOSMB(vp);
307 307
308 /* Flush all file data */ 308 /* Flush all file data */
309 error = smbfs_vinvalbuf(vp, V_SAVE, ap->a_cred, l, 1); 309 error = smbfs_vinvalbuf(vp, V_SAVE, ap->a_cred, l, 1);
310 if (error) 310 if (error)
311 return (error); 311 return (error);
312 312
313 /* 313 /*
314 * We must close the directory lookup context now, so that 314 * We must close the directory lookup context now, so that
315 * later directory changes would be properly detected. 315 * later directory changes would be properly detected.
316 * Ideally, the lookup routines should handle such case, and 316 * Ideally, the lookup routines should handle such case, and
317 * the context would be removed only in smbfs_inactive(). 317 * the context would be removed only in smbfs_inactive().
318 */ 318 */
319 if (vp->v_type == VDIR && (np->n_flag & NOPEN) != 0 && 319 if (vp->v_type == VDIR && (np->n_flag & NOPEN) != 0 &&
320 np->n_dirseq != NULL) { 320 np->n_dirseq != NULL) {
321 struct smb_cred scred; 321 struct smb_cred scred;
322 322
323 smb_makescred(&scred, l, ap->a_cred); 323 smb_makescred(&scred, l, ap->a_cred);
324 smbfs_findclose(np->n_dirseq, &scred); 324 smbfs_findclose(np->n_dirseq, &scred);
325 np->n_dirseq = NULL; 325 np->n_dirseq = NULL;
326 } 326 }
327 327
328 return (0); 328 return (0);
329} 329}
330 330
331/* 331/*
332 * smbfs_getattr call from vfs. 332 * smbfs_getattr call from vfs.
333 */ 333 */
334int 334int
335smbfs_getattr(void *v) 335smbfs_getattr(void *v)
336{ 336{
337 struct vop_getattr_args /* { 337 struct vop_getattr_args /* {
338 struct vnode *a_vp; 338 struct vnode *a_vp;
339 struct vattr *a_vap; 339 struct vattr *a_vap;
340 kauth_cred_t a_cred; 340 kauth_cred_t a_cred;
341 } */ *ap = v; 341 } */ *ap = v;
342 struct vnode *vp = ap->a_vp; 342 struct vnode *vp = ap->a_vp;
343 struct smbnode *np = VTOSMB(vp); 343 struct smbnode *np = VTOSMB(vp);
344 struct vattr *va=ap->a_vap; 344 struct vattr *va=ap->a_vap;
345 struct smbfattr fattr; 345 struct smbfattr fattr;
346 struct smb_cred scred; 346 struct smb_cred scred;
347 u_quad_t oldsize; 347 u_quad_t oldsize;
348 int error; 348 int error;
349 349
350 SMBVDEBUG("%p: '%.*s' isroot %d\n", vp, 350 SMBVDEBUG("%p: '%.*s' isroot %d\n", vp,
351 (int) np->n_nmlen, np->n_name, (vp->v_vflag & VV_ROOT) != 0); 351 (int) np->n_nmlen, np->n_name, (vp->v_vflag & VV_ROOT) != 0);
352 352
353 if ((error = smbfs_attr_cachelookup(vp, va)) == 0) 353 if ((error = smbfs_attr_cachelookup(vp, va)) == 0)
354 return (0); 354 return (0);
355 355
356 SMBVDEBUG0("not in the cache\n"); 356 SMBVDEBUG0("not in the cache\n");
357 smb_makescred(&scred, curlwp, ap->a_cred); 357 smb_makescred(&scred, curlwp, ap->a_cred);
358 oldsize = np->n_size; 358 oldsize = np->n_size;
359 error = smbfs_smb_lookup(np, NULL, 0, &fattr, &scred); 359 error = smbfs_smb_lookup(np, NULL, 0, &fattr, &scred);
360 if (error) { 360 if (error) {
361 SMBVDEBUG("error %d\n", error); 361 SMBVDEBUG("error %d\n", error);
362 return error; 362 return error;
363 } 363 }
364 smbfs_attr_cacheenter(vp, &fattr); 364 smbfs_attr_cacheenter(vp, &fattr);
365 smbfs_attr_cachelookup(vp, va); 365 smbfs_attr_cachelookup(vp, va);
366 if ((np->n_flag & NOPEN) != 0) 366 if ((np->n_flag & NOPEN) != 0)
367 np->n_size = oldsize; 367 np->n_size = oldsize;
368 return 0; 368 return 0;
369} 369}
370 370
371int 371int
372smbfs_setattr(void *v) 372smbfs_setattr(void *v)
373{ 373{
374 struct vop_setattr_args /* { 374 struct vop_setattr_args /* {
375 struct vnode *a_vp; 375 struct vnode *a_vp;
376 struct vattr *a_vap; 376 struct vattr *a_vap;
377 kauth_cred_t a_cred; 377 kauth_cred_t a_cred;
378 } */ *ap = v; 378 } */ *ap = v;
379 struct lwp *l = curlwp; 379 struct lwp *l = curlwp;
380 struct vnode *vp = ap->a_vp; 380 struct vnode *vp = ap->a_vp;
381 struct smbnode *np = VTOSMB(vp); 381 struct smbnode *np = VTOSMB(vp);
382 struct vattr *vap = ap->a_vap; 382 struct vattr *vap = ap->a_vap;
383 struct timespec *mtime, *atime; 383 struct timespec *mtime, *atime;
384 struct smb_cred scred; 384 struct smb_cred scred;
385 struct smb_share *ssp = np->n_mount->sm_share; 385 struct smb_share *ssp = np->n_mount->sm_share;
386 struct smb_vc *vcp = SSTOVC(ssp); 386 struct smb_vc *vcp = SSTOVC(ssp);
387 u_quad_t tsize = 0; 387 u_quad_t tsize = 0;
388 int isreadonly, doclose, error = 0; 388 int isreadonly, doclose, error = 0;
389 389
390 SMBVDEBUG0("\n"); 390 SMBVDEBUG0("\n");
391 if (vap->va_flags != VNOVAL) 391 if (vap->va_flags != VNOVAL)
392 return EOPNOTSUPP; 392 return EOPNOTSUPP;
393 isreadonly = (vp->v_mount->mnt_flag & MNT_RDONLY); 393 isreadonly = (vp->v_mount->mnt_flag & MNT_RDONLY);
394 /* 394 /*
395 * Disallow write attempts if the filesystem is mounted read-only. 395 * Disallow write attempts if the filesystem is mounted read-only.
396 */ 396 */
397 if ((vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL || 397 if ((vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL ||
398 vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL || 398 vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL ||
399 vap->va_mode != (mode_t)VNOVAL) && isreadonly) 399 vap->va_mode != (mode_t)VNOVAL) && isreadonly)
400 return EROFS; 400 return EROFS;
401 smb_makescred(&scred, l, ap->a_cred); 401 smb_makescred(&scred, l, ap->a_cred);
402 if (vap->va_size != VNOVAL) { 402 if (vap->va_size != VNOVAL) {
403 switch (vp->v_type) { 403 switch (vp->v_type) {
404 case VDIR: 404 case VDIR:
405 return EISDIR; 405 return EISDIR;
406 case VREG: 406 case VREG:
407 break; 407 break;
408 default: 408 default:
409 return EINVAL; 409 return EINVAL;
410 }; 410 };
411 if (isreadonly) 411 if (isreadonly)
412 return EROFS; 412 return EROFS;
413 doclose = 0; 413 doclose = 0;
414 tsize = np->n_size; 414 tsize = np->n_size;
415 np->n_size = vap->va_size; 415 np->n_size = vap->va_size;
416 uvm_vnp_setsize(vp, vap->va_size); 416 uvm_vnp_setsize(vp, vap->va_size);
417 if ((np->n_flag & NOPEN) == 0) { 417 if ((np->n_flag & NOPEN) == 0) {
418 error = smbfs_smb_open(np, 418 error = smbfs_smb_open(np,
419 SMB_SM_DENYNONE|SMB_AM_OPENRW, &scred); 419 SMB_SM_DENYNONE|SMB_AM_OPENRW, &scred);
420 if (error == 0) 420 if (error == 0)
421 doclose = 1; 421 doclose = 1;
422 } 422 }
423 if (error == 0) 423 if (error == 0)
424 error = smbfs_smb_setfsize(np, vap->va_size, &scred); 424 error = smbfs_smb_setfsize(np, vap->va_size, &scred);
425 if (doclose) 425 if (doclose)
426 smbfs_smb_close(ssp, np->n_fid, NULL, &scred); 426 smbfs_smb_close(ssp, np->n_fid, NULL, &scred);
427 if (error) { 427 if (error) {
428 np->n_size = tsize; 428 np->n_size = tsize;
429 uvm_vnp_setsize(vp, tsize); 429 uvm_vnp_setsize(vp, tsize);
430 return (error); 430 return (error);
431 } 431 }
432 } 432 }
433 mtime = atime = NULL; 433 mtime = atime = NULL;
434 if (vap->va_mtime.tv_sec != VNOVAL) 434 if (vap->va_mtime.tv_sec != VNOVAL)
435 mtime = &vap->va_mtime; 435 mtime = &vap->va_mtime;
436 if (vap->va_atime.tv_sec != VNOVAL) 436 if (vap->va_atime.tv_sec != VNOVAL)
437 atime = &vap->va_atime; 437 atime = &vap->va_atime;
438 if (mtime != atime) { 438 if (mtime != atime) {
439 error = genfs_can_chtimes(ap->a_vp, vap->va_vaflags, 439 error = genfs_can_chtimes(ap->a_vp, vap->va_vaflags,
440 VTOSMBFS(vp)->sm_args.uid, ap->a_cred); 440 VTOSMBFS(vp)->sm_args.uid, ap->a_cred);
441 if (error) 441 if (error)
442 return (error); 442 return (error);
443 443
444#if 0 444#if 0
445 if (mtime == NULL) 445 if (mtime == NULL)
446 mtime = &np->n_mtime; 446 mtime = &np->n_mtime;
447 if (atime == NULL) 447 if (atime == NULL)
448 atime = &np->n_atime; 448 atime = &np->n_atime;
449#endif 449#endif
450 /* 450 /*
451 * If file is opened, then we can use handle based calls. 451 * If file is opened, then we can use handle based calls.
452 * If not, use path based ones. 452 * If not, use path based ones.
453 */ 453 */
454 if ((np->n_flag & NOPEN) == 0) { 454 if ((np->n_flag & NOPEN) == 0) {
455 if (vcp->vc_flags & SMBV_WIN95) { 455 if (vcp->vc_flags & SMBV_WIN95) {
456 error = VOP_OPEN(vp, FWRITE, ap->a_cred); 456 error = VOP_OPEN(vp, FWRITE, ap->a_cred);
457 if (!error) { 457 if (!error) {
458/* error = smbfs_smb_setfattrNT(np, 0, mtime, atime, &scred); 458/* error = smbfs_smb_setfattrNT(np, 0, mtime, atime, &scred);
459 VOP_GETATTR(vp, &vattr, ap->a_cred);*/ 459 VOP_GETATTR(vp, &vattr, ap->a_cred);*/
460 if (mtime) 460 if (mtime)
461 np->n_mtime = *mtime; 461 np->n_mtime = *mtime;
462 VOP_CLOSE(vp, FWRITE, ap->a_cred); 462 VOP_CLOSE(vp, FWRITE, ap->a_cred);
463 } 463 }
464 } else if (SMB_CAPS(vcp) & SMB_CAP_NT_SMBS) { 464 } else if (SMB_CAPS(vcp) & SMB_CAP_NT_SMBS) {
465 error = smbfs_smb_setptime2(np, mtime, atime, 0, &scred); 465 error = smbfs_smb_setptime2(np, mtime, atime, 0, &scred);
466/* error = smbfs_smb_setpattrNT(np, 0, mtime, atime, &scred);*/ 466/* error = smbfs_smb_setpattrNT(np, 0, mtime, atime, &scred);*/
467 } else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN2_0) { 467 } else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN2_0) {
468 error = smbfs_smb_setptime2(np, mtime, atime, 0, &scred); 468 error = smbfs_smb_setptime2(np, mtime, atime, 0, &scred);
469 } else { 469 } else {
470 error = smbfs_smb_setpattr(np, 0, mtime, &scred); 470 error = smbfs_smb_setpattr(np, 0, mtime, &scred);
471 } 471 }
472 } else { 472 } else {
473 if (SMB_CAPS(vcp) & SMB_CAP_NT_SMBS) { 473 if (SMB_CAPS(vcp) & SMB_CAP_NT_SMBS) {
474 error = smbfs_smb_setfattrNT(np, 0, mtime, atime, &scred); 474 error = smbfs_smb_setfattrNT(np, 0, mtime, atime, &scred);
475 } else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN1_0) { 475 } else if (SMB_DIALECT(vcp) >= SMB_DIALECT_LANMAN1_0) {
476 error = smbfs_smb_setftime(np, mtime, atime, &scred); 476 error = smbfs_smb_setftime(np, mtime, atime, &scred);
477 } else { 477 } else {
478 /* 478 /*
479 * XXX I have no idea how to handle this for core 479 * XXX I have no idea how to handle this for core
480 * level servers. The possible solution is to 480 * level servers. The possible solution is to
481 * update mtime after file is closed. 481 * update mtime after file is closed.
482 */ 482 */
483 } 483 }
484 } 484 }
485 } 485 }
486 /* 486 /*
487 * Invalidate attribute cache in case if server doesn't set 487 * Invalidate attribute cache in case if server doesn't set
488 * required attributes. 488 * required attributes.
489 */ 489 */
490 smbfs_attr_cacheremove(vp); /* invalidate cache */ 490 smbfs_attr_cacheremove(vp); /* invalidate cache */
491 VOP_GETATTR(vp, vap, ap->a_cred); 491 VOP_GETATTR(vp, vap, ap->a_cred);
492 np->n_mtime.tv_sec = vap->va_mtime.tv_sec; 492 np->n_mtime.tv_sec = vap->va_mtime.tv_sec;
493 VN_KNOTE(vp, NOTE_ATTRIB); 493 VN_KNOTE(vp, NOTE_ATTRIB);
494 return error; 494 return error;
495} 495}
496/* 496/*
497 * smbfs_read call. 497 * smbfs_read call.
498 */ 498 */
499int 499int
500smbfs_read(void *v) 500smbfs_read(void *v)
501{ 501{
502 struct vop_read_args /* { 502 struct vop_read_args /* {
503 struct vnode *a_vp; 503 struct vnode *a_vp;
504 struct uio *a_uio; 504 struct uio *a_uio;
505 int a_ioflag; 505 int a_ioflag;
506 kauth_cred_t a_cred; 506 kauth_cred_t a_cred;
507 } */ *ap = v; 507 } */ *ap = v;
508 struct vnode *vp = ap->a_vp; 508 struct vnode *vp = ap->a_vp;
509 509
510 if (vp->v_type != VREG && vp->v_type != VDIR) 510 if (vp->v_type != VREG && vp->v_type != VDIR)
511 return EPERM; 511 return EPERM;
512 512
513 return smbfs_readvnode(vp, ap->a_uio, ap->a_cred); 513 return smbfs_readvnode(vp, ap->a_uio, ap->a_cred);
514} 514}
515 515
516int 516int
517smbfs_write(void *v) 517smbfs_write(void *v)
518{ 518{
519 struct vop_write_args /* { 519 struct vop_write_args /* {
520 struct vnode *a_vp; 520 struct vnode *a_vp;
521 struct uio *a_uio; 521 struct uio *a_uio;
522 int a_ioflag; 522 int a_ioflag;
523 kauth_cred_t a_cred; 523 kauth_cred_t a_cred;
524 } */ *ap = v; 524 } */ *ap = v;
525 struct vnode *vp = ap->a_vp; 525 struct vnode *vp = ap->a_vp;
526 struct uio *uio = ap->a_uio; 526 struct uio *uio = ap->a_uio;
527 527
528 SMBVDEBUG("%d,ofs=%lld,sz=%u\n",vp->v_type, (long long int)uio->uio_offset, uio->uio_resid); 528 SMBVDEBUG("%d,ofs=%lld,sz=%zu\n",vp->v_type,
 529 (long long int)uio->uio_offset, uio->uio_resid);
529 if (vp->v_type != VREG) 530 if (vp->v_type != VREG)
530 return (EPERM); 531 return (EPERM);
531 return smbfs_writevnode(vp, uio, ap->a_cred, ap->a_ioflag); 532 return smbfs_writevnode(vp, uio, ap->a_cred, ap->a_ioflag);
532} 533}
533/* 534/*
534 * smbfs_create call 535 * smbfs_create call
535 * Create a regular file. On entry the directory to contain the file being 536 * Create a regular file. On entry the directory to contain the file being
536 * created is locked. We must release before we return. We must also free 537 * created is locked. We must release before we return. We must also free
537 * the pathname buffer pointed at by cnp->cn_pnbuf, always on error, or 538 * the pathname buffer pointed at by cnp->cn_pnbuf, always on error, or
538 * only if the SAVESTART bit in cn_flags is clear on success. 539 * only if the SAVESTART bit in cn_flags is clear on success.
539 */ 540 */
540int 541int
541smbfs_create(void *v) 542smbfs_create(void *v)
542{ 543{
543 struct vop_create_args /* { 544 struct vop_create_args /* {
544 struct vnode *a_dvp; 545 struct vnode *a_dvp;
545 struct vnode **a_vpp; 546 struct vnode **a_vpp;
546 struct componentname *a_cnp; 547 struct componentname *a_cnp;
547 struct vattr *a_vap; 548 struct vattr *a_vap;
548 } */ *ap = v; 549 } */ *ap = v;
549 struct vnode *dvp = ap->a_dvp; 550 struct vnode *dvp = ap->a_dvp;
550 struct vattr *vap = ap->a_vap; 551 struct vattr *vap = ap->a_vap;
551 struct componentname *cnp = ap->a_cnp; 552 struct componentname *cnp = ap->a_cnp;
552 struct smbnode *dnp = VTOSMB(dvp); 553 struct smbnode *dnp = VTOSMB(dvp);
553 struct smbfattr fattr; 554 struct smbfattr fattr;
554 struct smb_cred scred; 555 struct smb_cred scred;
555 const char *name = cnp->cn_nameptr; 556 const char *name = cnp->cn_nameptr;
556 int nmlen = cnp->cn_namelen; 557 int nmlen = cnp->cn_namelen;
557 int error = EINVAL; 558 int error = EINVAL;
558 559
559 560
560 if (vap->va_type != VREG) 561 if (vap->va_type != VREG)
561 goto out; 562 goto out;
562 563
563 smb_makescred(&scred, curlwp, cnp->cn_cred); 564 smb_makescred(&scred, curlwp, cnp->cn_cred);
564 error = smbfs_smb_create(dnp, name, nmlen, &scred); 565 error = smbfs_smb_create(dnp, name, nmlen, &scred);
565 if (error) 566 if (error)
566 goto out; 567 goto out;
567 568
568 error = smbfs_smb_lookup(dnp, name, nmlen, &fattr, &scred); 569 error = smbfs_smb_lookup(dnp, name, nmlen, &fattr, &scred);
569 if (error) 570 if (error)
570 goto out; 571 goto out;
571 error = smbfs_nget(VTOVFS(dvp), dvp, name, nmlen, &fattr, ap->a_vpp); 572 error = smbfs_nget(VTOVFS(dvp), dvp, name, nmlen, &fattr, ap->a_vpp);
572 if (error) 573 if (error)
573 goto out; 574 goto out;
574 575
575 /* No error */ 576 /* No error */
576 if (cnp->cn_flags & MAKEENTRY) 577 if (cnp->cn_flags & MAKEENTRY)
577 cache_enter(dvp, *ap->a_vpp, cnp); 578 cache_enter(dvp, *ap->a_vpp, cnp);
578 579
579 out: 580 out:
580 if (error || ((cnp->cn_flags & SAVESTART) == 0)) 581 if (error || ((cnp->cn_flags & SAVESTART) == 0))
581 PNBUF_PUT(cnp->cn_pnbuf); 582 PNBUF_PUT(cnp->cn_pnbuf);
582 VN_KNOTE(dvp, NOTE_WRITE); 583 VN_KNOTE(dvp, NOTE_WRITE);
583 vput(dvp); 584 vput(dvp);
584 return (error); 585 return (error);
585 586
586 587
587} 588}
588 589
589int 590int
590smbfs_remove(void *v) 591smbfs_remove(void *v)
591{ 592{
592 struct vop_remove_args /* { 593 struct vop_remove_args /* {
593 struct vnodeop_desc *a_desc; 594 struct vnodeop_desc *a_desc;
594 struct vnode * a_dvp; 595 struct vnode * a_dvp;
595 struct vnode * a_vp; 596 struct vnode * a_vp;
596 struct componentname * a_cnp; 597 struct componentname * a_cnp;
597 } */ *ap = v; 598 } */ *ap = v;
598 struct vnode *vp = ap->a_vp; 599 struct vnode *vp = ap->a_vp;
599 struct vnode *dvp = ap->a_dvp; 600 struct vnode *dvp = ap->a_dvp;
600 struct componentname *cnp = ap->a_cnp; 601 struct componentname *cnp = ap->a_cnp;
601 struct smbnode *np = VTOSMB(vp); 602 struct smbnode *np = VTOSMB(vp);
602 struct smb_cred scred; 603 struct smb_cred scred;
603 int error; 604 int error;
604 605
605 if (vp->v_type == VDIR || (np->n_flag & NOPEN) != 0 606 if (vp->v_type == VDIR || (np->n_flag & NOPEN) != 0
606 || vp->v_usecount != 1) { 607 || vp->v_usecount != 1) {
607 /* XXX Eventually should do something along NFS sillyrename */ 608 /* XXX Eventually should do something along NFS sillyrename */
608 error = EPERM; 609 error = EPERM;
609 } else { 610 } else {
610 smb_makescred(&scred, curlwp, cnp->cn_cred); 611 smb_makescred(&scred, curlwp, cnp->cn_cred);
611 error = smbfs_smb_delete(np, &scred); 612 error = smbfs_smb_delete(np, &scred);
612 } 613 }
613 614
614 VN_KNOTE(ap->a_vp, NOTE_DELETE); 615 VN_KNOTE(ap->a_vp, NOTE_DELETE);
615 VN_KNOTE(ap->a_dvp, NOTE_WRITE); 616 VN_KNOTE(ap->a_dvp, NOTE_WRITE);
616 if (dvp == vp) 617 if (dvp == vp)
617 vrele(vp); 618 vrele(vp);
618 else 619 else
619 vput(vp); 620 vput(vp);
620 vput(dvp); 621 vput(dvp);
621 return (error); 622 return (error);
622} 623}
623 624
624/* 625/*
625 * smbfs_file rename call 626 * smbfs_file rename call
626 */ 627 */
627int 628int
628smbfs_rename(void *v) 629smbfs_rename(void *v)
629{ 630{
630 struct vop_rename_args /* { 631 struct vop_rename_args /* {
631 struct vnode *a_fdvp; 632 struct vnode *a_fdvp;
632 struct vnode *a_fvp; 633 struct vnode *a_fvp;
633 struct componentname *a_fcnp; 634 struct componentname *a_fcnp;
634 struct vnode *a_tdvp; 635 struct vnode *a_tdvp;
635 struct vnode *a_tvp; 636 struct vnode *a_tvp;
636 struct componentname *a_tcnp; 637 struct componentname *a_tcnp;
637 } */ *ap = v; 638 } */ *ap = v;
638 struct vnode *fvp = ap->a_fvp; 639 struct vnode *fvp = ap->a_fvp;
639 struct vnode *tvp = ap->a_tvp; 640 struct vnode *tvp = ap->a_tvp;
640 struct vnode *fdvp = ap->a_fdvp; 641 struct vnode *fdvp = ap->a_fdvp;
641 struct vnode *tdvp = ap->a_tdvp; 642 struct vnode *tdvp = ap->a_tdvp;
642 struct componentname *tcnp = ap->a_tcnp; 643 struct componentname *tcnp = ap->a_tcnp;
643/* struct componentname *fcnp = ap->a_fcnp;*/ 644/* struct componentname *fcnp = ap->a_fcnp;*/
644 struct smb_cred scred; 645 struct smb_cred scred;
645#ifdef notyet 646#ifdef notyet
646 u_int16_t flags = 6; 647 u_int16_t flags = 6;
647#endif 648#endif
648 int error=0; 649 int error=0;
649 650
650 /* Check for cross-device rename */ 651 /* Check for cross-device rename */
651 if ((fvp->v_mount != tdvp->v_mount) || 652 if ((fvp->v_mount != tdvp->v_mount) ||
652 (tvp && (fvp->v_mount != tvp->v_mount))) { 653 (tvp && (fvp->v_mount != tvp->v_mount))) {
653 error = EXDEV; 654 error = EXDEV;
654 goto out; 655 goto out;
655 } 656 }
656 657
657 if (tvp && tvp->v_usecount > 1) { 658 if (tvp && tvp->v_usecount > 1) {
658 error = EBUSY; 659 error = EBUSY;
659 goto out; 660 goto out;
660 } 661 }
661#ifdef notnow 662#ifdef notnow
662 flags = 0x10; /* verify all writes */ 663 flags = 0x10; /* verify all writes */
663 if (fvp->v_type == VDIR) { 664 if (fvp->v_type == VDIR) {
664 flags |= 2; 665 flags |= 2;
665 } else if (fvp->v_type == VREG) { 666 } else if (fvp->v_type == VREG) {
666 flags |= 1; 667 flags |= 1;
667 } else { 668 } else {
668 error = EINVAL; 669 error = EINVAL;
669 goto out; 670 goto out;
670 } 671 }
671#endif 672#endif
672 smb_makescred(&scred, curlwp, tcnp->cn_cred); 673 smb_makescred(&scred, curlwp, tcnp->cn_cred);
673 /* 674 /*
674 * It seems that Samba doesn't implement SMB_COM_MOVE call... 675 * It seems that Samba doesn't implement SMB_COM_MOVE call...
675 */ 676 */
676#ifdef notnow 677#ifdef notnow
677 if (SMB_DIALECT(SSTOCN(smp->sm_share)) >= SMB_DIALECT_LANMAN1_0) { 678 if (SMB_DIALECT(SSTOCN(smp->sm_share)) >= SMB_DIALECT_LANMAN1_0) {
678 error = smbfs_smb_move(VTOSMB(fvp), VTOSMB(tdvp), 679 error = smbfs_smb_move(VTOSMB(fvp), VTOSMB(tdvp),
679 tcnp->cn_nameptr, tcnp->cn_namelen, flags, &scred); 680 tcnp->cn_nameptr, tcnp->cn_namelen, flags, &scred);
680 } else 681 } else
681#endif 682#endif
682 { 683 {
683 /* 684 /*
684 * We have to do the work atomicaly 685 * We have to do the work atomicaly
685 */ 686 */
686 if (tvp && tvp != fvp) { 687 if (tvp && tvp != fvp) {
687 error = smbfs_smb_delete(VTOSMB(tvp), &scred); 688 error = smbfs_smb_delete(VTOSMB(tvp), &scred);
688 if (error) 689 if (error)
689 goto out; 690 goto out;
690 VN_KNOTE(tdvp, NOTE_WRITE); 691 VN_KNOTE(tdvp, NOTE_WRITE);
691 VN_KNOTE(tvp, NOTE_DELETE); 692 VN_KNOTE(tvp, NOTE_DELETE);
692 cache_purge(tvp); 693 cache_purge(tvp);
693 } 694 }
694 error = smbfs_smb_rename(VTOSMB(fvp), VTOSMB(tdvp), 695 error = smbfs_smb_rename(VTOSMB(fvp), VTOSMB(tdvp),
695 tcnp->cn_nameptr, tcnp->cn_namelen, &scred); 696 tcnp->cn_nameptr, tcnp->cn_namelen, &scred);
696 VN_KNOTE(fdvp, NOTE_WRITE); 697 VN_KNOTE(fdvp, NOTE_WRITE);
697 VN_KNOTE(fvp, NOTE_RENAME); 698 VN_KNOTE(fvp, NOTE_RENAME);
698 } 699 }
699 700
700 if (fvp->v_type == VDIR) { 701 if (fvp->v_type == VDIR) {
701 if (tvp != NULL && tvp->v_type == VDIR) 702 if (tvp != NULL && tvp->v_type == VDIR)
702 cache_purge(tdvp); 703 cache_purge(tdvp);
703 cache_purge(fdvp); 704 cache_purge(fdvp);
704 } 705 }
705 706
706 smbfs_attr_cacheremove(fdvp); 707 smbfs_attr_cacheremove(fdvp);
707 smbfs_attr_cacheremove(tdvp); 708 smbfs_attr_cacheremove(tdvp);
708 709
709out: 710out:
710 711
711 if (tdvp == tvp) 712 if (tdvp == tvp)
712 vrele(tdvp); 713 vrele(tdvp);
713 else 714 else
714 vput(tdvp); 715 vput(tdvp);
715 if (tvp) 716 if (tvp)
716 vput(tvp); 717 vput(tvp);
717 718
718 vrele(fdvp); 719 vrele(fdvp);
719 vrele(fvp); 720 vrele(fvp);
720 721
721 return (error); 722 return (error);
722} 723}
723 724
724/* 725/*
725 * somtime it will come true... 726 * somtime it will come true...
726 */ 727 */
727int 728int
728smbfs_link(void *v) 729smbfs_link(void *v)
729{ 730{
730 return genfs_eopnotsupp(v); 731 return genfs_eopnotsupp(v);
731} 732}
732 733
733/* 734/*
734 * smbfs_symlink link create call. 735 * smbfs_symlink link create call.
735 * Sometime it will be functional... 736 * Sometime it will be functional...
736 */ 737 */
737int 738int
738smbfs_symlink(void *v) 739smbfs_symlink(void *v)
739{ 740{
740 return genfs_eopnotsupp(v); 741 return genfs_eopnotsupp(v);
741} 742}
742 743
743int 744int
744smbfs_mkdir(void *v) 745smbfs_mkdir(void *v)
745{ 746{
746 struct vop_mkdir_args /* { 747 struct vop_mkdir_args /* {
747 struct vnode *a_dvp; 748 struct vnode *a_dvp;
748 struct vnode **a_vpp; 749 struct vnode **a_vpp;
749 struct componentname *a_cnp; 750 struct componentname *a_cnp;
750 struct vattr *a_vap; 751 struct vattr *a_vap;
751 } */ *ap = v; 752 } */ *ap = v;
752 struct vnode *dvp = ap->a_dvp; 753 struct vnode *dvp = ap->a_dvp;
753/* struct vattr *vap = ap->a_vap;*/ 754/* struct vattr *vap = ap->a_vap;*/
754 struct vnode *vp; 755 struct vnode *vp;
755 struct componentname *cnp = ap->a_cnp; 756 struct componentname *cnp = ap->a_cnp;
756 struct smbnode *dnp = VTOSMB(dvp); 757 struct smbnode *dnp = VTOSMB(dvp);
757 struct smb_cred scred; 758 struct smb_cred scred;
758 struct smbfattr fattr; 759 struct smbfattr fattr;
759 const char *name = cnp->cn_nameptr; 760 const char *name = cnp->cn_nameptr;
760 int len = cnp->cn_namelen; 761 int len = cnp->cn_namelen;
761 int error; 762 int error;
762 763
763 if ((name[0] == '.') && ((len == 1) || ((len == 2) && (name[1] == '.')))){ 764 if ((name[0] == '.') && ((len == 1) || ((len == 2) && (name[1] == '.')))){
764 error = EEXIST; 765 error = EEXIST;
765 goto out; 766 goto out;
766 } 767 }
767 768
768 smb_makescred(&scred, curlwp, cnp->cn_cred); 769 smb_makescred(&scred, curlwp, cnp->cn_cred);
769 error = smbfs_smb_mkdir(dnp, name, len, &scred); 770 error = smbfs_smb_mkdir(dnp, name, len, &scred);
770 if (error) 771 if (error)
771 goto out; 772 goto out;
772 error = smbfs_smb_lookup(dnp, name, len, &fattr, &scred); 773 error = smbfs_smb_lookup(dnp, name, len, &fattr, &scred);
773 if (error) 774 if (error)
774 goto out; 775 goto out;
775 error = smbfs_nget(VTOVFS(dvp), dvp, name, len, &fattr, &vp); 776 error = smbfs_nget(VTOVFS(dvp), dvp, name, len, &fattr, &vp);
776 if (error) 777 if (error)
777 goto out; 778 goto out;
778 *ap->a_vpp = vp; 779 *ap->a_vpp = vp;
779 780
780 out: 781 out:
781 if (error || ((cnp->cn_flags & SAVESTART) == 0)) 782 if (error || ((cnp->cn_flags & SAVESTART) == 0))
782 PNBUF_PUT(cnp->cn_pnbuf); 783 PNBUF_PUT(cnp->cn_pnbuf);
783 VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); 784 VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
784 vput(dvp); 785 vput(dvp);
785 786
786 return (error); 787 return (error);
787} 788}
788 789
789/* 790/*
790 * smbfs_remove directory call 791 * smbfs_remove directory call
791 */ 792 */
792int 793int
793smbfs_rmdir(void *v) 794smbfs_rmdir(void *v)
794{ 795{
795 struct vop_rmdir_args /* { 796 struct vop_rmdir_args /* {
796 struct vnode *a_dvp; 797 struct vnode *a_dvp;
797 struct vnode *a_vp; 798 struct vnode *a_vp;
798 struct componentname *a_cnp; 799 struct componentname *a_cnp;
799 } */ *ap = v; 800 } */ *ap = v;
800 struct vnode *vp = ap->a_vp; 801 struct vnode *vp = ap->a_vp;
801 struct vnode *dvp = ap->a_dvp; 802 struct vnode *dvp = ap->a_dvp;
802 struct componentname *cnp = ap->a_cnp; 803 struct componentname *cnp = ap->a_cnp;
803/* struct smbmount *smp = VTOSMBFS(vp);*/ 804/* struct smbmount *smp = VTOSMBFS(vp);*/
804 struct smbnode *dnp = VTOSMB(dvp); 805 struct smbnode *dnp = VTOSMB(dvp);
805 struct smbnode *np = VTOSMB(vp); 806 struct smbnode *np = VTOSMB(vp);
806 struct smb_cred scred; 807 struct smb_cred scred;
807 int error; 808 int error;
808 809
809 if (dvp == vp) { 810 if (dvp == vp) {
810 vrele(dvp); 811 vrele(dvp);
811 vput(dvp); 812 vput(dvp);
812 return (EINVAL); 813 return (EINVAL);
813 } 814 }
814 815
815 smb_makescred(&scred, curlwp, cnp->cn_cred); 816 smb_makescred(&scred, curlwp, cnp->cn_cred);
816 error = smbfs_smb_rmdir(np, &scred); 817 error = smbfs_smb_rmdir(np, &scred);
817 dnp->n_flag |= NMODIFIED; 818 dnp->n_flag |= NMODIFIED;
818 smbfs_attr_cacheremove(dvp); 819 smbfs_attr_cacheremove(dvp);
819 VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); 820 VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
820 VN_KNOTE(vp, NOTE_DELETE); 821 VN_KNOTE(vp, NOTE_DELETE);
821 cache_purge(dvp); 822 cache_purge(dvp);
822 cache_purge(vp); 823 cache_purge(vp);
823 vput(vp); 824 vput(vp);
824 vput(dvp); 825 vput(dvp);
825 826
826 return (error); 827 return (error);
827} 828}
828 829
829/* 830/*
830 * smbfs_readdir call 831 * smbfs_readdir call
831 */ 832 */
832int 833int
833smbfs_readdir(void *v) 834smbfs_readdir(void *v)
834{ 835{
835 struct vop_readdir_args /* { 836 struct vop_readdir_args /* {
836 struct vnode *a_vp; 837 struct vnode *a_vp;
837 struct uio *a_uio; 838 struct uio *a_uio;
838 kauth_cred_t a_cred; 839 kauth_cred_t a_cred;
839 int *a_eofflag; 840 int *a_eofflag;
840 u_long *a_cookies; 841 u_long *a_cookies;
841 int a_ncookies; 842 int a_ncookies;
842 } */ *ap = v; 843 } */ *ap = v;
843 struct vnode *vp = ap->a_vp; 844 struct vnode *vp = ap->a_vp;
844 845
845 if (vp->v_type != VDIR) 846 if (vp->v_type != VDIR)
846 return (EPERM); 847 return (EPERM);
847#ifdef notnow 848#ifdef notnow
848 if (ap->a_ncookies) { 849 if (ap->a_ncookies) {
849 printf("smbfs_readdir: no support for cookies now..."); 850 printf("smbfs_readdir: no support for cookies now...");
850 return (EOPNOTSUPP); 851 return (EOPNOTSUPP);
851 } 852 }
852#endif 853#endif
853 return (smbfs_readvnode(vp, ap->a_uio, ap->a_cred)); 854 return (smbfs_readvnode(vp, ap->a_uio, ap->a_cred));
854} 855}
855 856
856/* ARGSUSED */ 857/* ARGSUSED */
857int 858int
858smbfs_fsync(void *v) 859smbfs_fsync(void *v)
859{ 860{
860 /*return (smb_flush(ap->a_vp, ap->a_cred, ap->a_waitfor, ap->a_l, 1));*/ 861 /*return (smb_flush(ap->a_vp, ap->a_cred, ap->a_waitfor, ap->a_l, 1));*/
861 return (0); 862 return (0);
862} 863}
863 864
864int 865int
865smbfs_print(void *v) 866smbfs_print(void *v)
866{ 867{
867 struct vop_print_args /* { 868 struct vop_print_args /* {
868 struct vnode *a_vp; 869 struct vnode *a_vp;
869 } */ *ap = v; 870 } */ *ap = v;
870 struct vnode *vp = ap->a_vp; 871 struct vnode *vp = ap->a_vp;
871 struct smbnode *np = VTOSMB(vp); 872 struct smbnode *np = VTOSMB(vp);
872 873
873 printf("tag VT_SMBFS, name = %.*s, parent = %p, open = %d\n", 874 printf("tag VT_SMBFS, name = %.*s, parent = %p, open = %d\n",
874 (int)np->n_nmlen, np->n_name, 875 (int)np->n_nmlen, np->n_name,
875 np->n_parent ? np->n_parent : NULL, 876 np->n_parent ? np->n_parent : NULL,
876 (np->n_flag & NOPEN) != 0); 877 (np->n_flag & NOPEN) != 0);
877 return (0); 878 return (0);
878} 879}
879 880
880int 881int
881smbfs_pathconf(void *v) 882smbfs_pathconf(void *v)
882{ 883{
883 struct vop_pathconf_args /* { 884 struct vop_pathconf_args /* {
884 struct vnode *vp; 885 struct vnode *vp;
885 int a_name; 886 int a_name;
886 register_t *a_retval; 887 register_t *a_retval;
887 } */ *ap = v; 888 } */ *ap = v;
888 register_t *retval = ap->a_retval; 889 register_t *retval = ap->a_retval;
889 int error = 0; 890 int error = 0;
890 891
891 switch (ap->a_name) { 892 switch (ap->a_name) {
892 case _PC_PIPE_BUF: 893 case _PC_PIPE_BUF:
893 *retval = PIPE_BUF; 894 *retval = PIPE_BUF;
894 break; 895 break;
895 case _PC_SYNC_IO: 896 case _PC_SYNC_IO:
896 *retval = 1; 897 *retval = 1;
897 break; 898 break;
898 case _PC_LINK_MAX: 899 case _PC_LINK_MAX:
899 *retval = 0; 900 *retval = 0;
900 break; 901 break;
901 case _PC_NAME_MAX: 902 case _PC_NAME_MAX:
902 *retval = ap->a_vp->v_mount->mnt_stat.f_namemax; 903 *retval = ap->a_vp->v_mount->mnt_stat.f_namemax;
903 break; 904 break;
904 case _PC_PATH_MAX: 905 case _PC_PATH_MAX:
905 *retval = 800; /* XXX: a correct one ? */ 906 *retval = 800; /* XXX: a correct one ? */
906 break; 907 break;
907 default: 908 default:
908 error = EINVAL; 909 error = EINVAL;
909 break; 910 break;
910 } 911 }
911 912
912 return (error); 913 return (error);
913} 914}
914 915
915int 916int
916smbfs_strategy(void *v) 917smbfs_strategy(void *v)
917{ 918{
918 struct vop_strategy_args /* { 919 struct vop_strategy_args /* {
919 struct vnode *a_vp; 920 struct vnode *a_vp;
920 struct buf *a_bp; 921 struct buf *a_bp;
921 } */ *ap = v; 922 } */ *ap = v;
922 struct buf *bp = ap->a_bp; 923 struct buf *bp = ap->a_bp;
923 kauth_cred_t cr; 924 kauth_cred_t cr;
924 struct lwp *l; 925 struct lwp *l;
925 int error = 0; 926 int error = 0;
926 927
927 SMBVDEBUG0("\n"); 928 SMBVDEBUG0("\n");
928 if ((bp->b_flags & (B_PHYS|B_ASYNC)) == (B_PHYS|B_ASYNC)) 929 if ((bp->b_flags & (B_PHYS|B_ASYNC)) == (B_PHYS|B_ASYNC))
929 panic("smbfs physio/async"); 930 panic("smbfs physio/async");
930 if (bp->b_flags & B_ASYNC) { 931 if (bp->b_flags & B_ASYNC) {
931 l = NULL; 932 l = NULL;
932 cr = NULL; 933 cr = NULL;
933 } else { 934 } else {
934 l = curlwp; /* XXX */ 935 l = curlwp; /* XXX */
935 cr = l->l_cred; 936 cr = l->l_cred;
936 } 937 }
937 938
938 if ((bp->b_flags & B_ASYNC) == 0) 939 if ((bp->b_flags & B_ASYNC) == 0)
939 error = smbfs_doio(bp, cr, l); 940 error = smbfs_doio(bp, cr, l);
940 941
941 return (error); 942 return (error);
942} 943}
943 944
944#ifndef __NetBSD__ 945#ifndef __NetBSD__
945static char smbfs_atl[] = "rhsvda"; 946static char smbfs_atl[] = "rhsvda";
946static int 947static int
947smbfs_getextattr(struct vop_getextattr_args *ap) 948smbfs_getextattr(struct vop_getextattr_args *ap)
948/* { 949/* {
949 IN struct vnode *a_vp; 950 IN struct vnode *a_vp;
950 IN char *a_name; 951 IN char *a_name;
951 INOUT struct uio *a_uio; 952 INOUT struct uio *a_uio;
952 IN kauth_cred_t a_cred; 953 IN kauth_cred_t a_cred;
953}; 954};
954*/ 955*/
955{ 956{
956 struct vnode *vp = ap->a_vp; 957 struct vnode *vp = ap->a_vp;
957 struct lwp *l = ap->a_l; 958 struct lwp *l = ap->a_l;
958 kauth_cred_t cred = ap->a_cred; 959 kauth_cred_t cred = ap->a_cred;
959 struct uio *uio = ap->a_uio; 960 struct uio *uio = ap->a_uio;
960 const char *name = ap->a_name; 961 const char *name = ap->a_name;
961 struct smbnode *np = VTOSMB(vp); 962 struct smbnode *np = VTOSMB(vp);
962 struct vattr vattr; 963 struct vattr vattr;
963 char buf[10]; 964 char buf[10];
964 int i, attr, error; 965 int i, attr, error;
965 966
966 error = VOP_ACCESS(vp, VREAD, cred, td); 967 error = VOP_ACCESS(vp, VREAD, cred, td);
967 if (error) 968 if (error)
968 return error; 969 return error;
969 error = VOP_GETATTR(vp, &vattr, cred, td); 970 error = VOP_GETATTR(vp, &vattr, cred, td);
970 if (error) 971 if (error)
971 return error; 972 return error;
972 if (strcmp(name, "dosattr") == 0) { 973 if (strcmp(name, "dosattr") == 0) {
973 attr = np->n_dosattr; 974 attr = np->n_dosattr;
974 for (i = 0; i < 6; i++, attr >>= 1) 975 for (i = 0; i < 6; i++, attr >>= 1)
975 buf[i] = (attr & 1) ? smbfs_atl[i] : '-'; 976 buf[i] = (attr & 1) ? smbfs_atl[i] : '-';
976 buf[i] = 0; 977 buf[i] = 0;
977 error = uiomove(buf, i, uio); 978 error = uiomove(buf, i, uio);
978 979
979 } else 980 } else
980 error = EINVAL; 981 error = EINVAL;
981 return error; 982 return error;
982} 983}
983#endif /* !__NetBSD__ */ 984#endif /* !__NetBSD__ */
984 985
985/* 986/*
986 * Since we expected to support F_GETLK (and SMB protocol has no such function), 987 * Since we expected to support F_GETLK (and SMB protocol has no such function),
987 * it is necessary to use lf_advlock(). It would be nice if this function had 988 * it is necessary to use lf_advlock(). It would be nice if this function had
988 * a callback mechanism because it will help to improve a level of consistency. 989 * a callback mechanism because it will help to improve a level of consistency.
989 */ 990 */
990int 991int
991smbfs_advlock(void *v) 992smbfs_advlock(void *v)
992{ 993{
993 struct vop_advlock_args /* { 994 struct vop_advlock_args /* {
994 struct vnode *a_vp; 995 struct vnode *a_vp;
995 void *a_id; 996 void *a_id;
996 int a_op; 997 int a_op;
997 struct flock *a_fl; 998 struct flock *a_fl;
998 int a_flags; 999 int a_flags;
999 } */ *ap = v; 1000 } */ *ap = v;
1000 struct vnode *vp = ap->a_vp; 1001 struct vnode *vp = ap->a_vp;
1001 struct smbnode *np = VTOSMB(vp); 1002 struct smbnode *np = VTOSMB(vp);
1002 struct flock *fl = ap->a_fl; 1003 struct flock *fl = ap->a_fl;
1003 struct lwp *l = curlwp; 1004 struct lwp *l = curlwp;
1004 struct smb_cred scred; 1005 struct smb_cred scred;
1005 u_quad_t size; 1006 u_quad_t size;
1006 off_t start, end, oadd; 1007 off_t start, end, oadd;
1007 int error, lkop; 1008 int error, lkop;
1008 1009
1009 if (vp->v_type == VDIR) { 1010 if (vp->v_type == VDIR) {
1010 /* 1011 /*
1011 * SMB protocol have no support for directory locking. 1012 * SMB protocol have no support for directory locking.
1012 * Although locks can be processed on local machine, I don't 1013 * Although locks can be processed on local machine, I don't
1013 * think that this is a good idea, because some programs 1014 * think that this is a good idea, because some programs
1014 * can work wrong assuming directory is locked. So, we just 1015 * can work wrong assuming directory is locked. So, we just
1015 * return 'operation not supported'. 1016 * return 'operation not supported'.
1016 */ 1017 */
1017 return EOPNOTSUPP; 1018 return EOPNOTSUPP;
1018 } 1019 }
1019 size = np->n_size; 1020 size = np->n_size;
1020 switch (fl->l_whence) { 1021 switch (fl->l_whence) {
1021 1022
1022 case SEEK_SET: 1023 case SEEK_SET:
1023 case SEEK_CUR: 1024 case SEEK_CUR:
1024 start = fl->l_start; 1025 start = fl->l_start;
1025 break; 1026 break;
1026 1027
1027 case SEEK_END: 1028 case SEEK_END:
1028#ifndef __NetBSD__ 1029#ifndef __NetBSD__
1029 if (size > OFF_MAX || 1030 if (size > OFF_MAX ||
1030 (fl->l_start > 0 && size > OFF_MAX - fl->l_start)) 1031 (fl->l_start > 0 && size > OFF_MAX - fl->l_start))
1031 return EOVERFLOW; 1032 return EOVERFLOW;
1032#endif 1033#endif
1033 start = size + fl->l_start; 1034 start = size + fl->l_start;
1034 break; 1035 break;
1035 1036
1036 default: 1037 default:
1037 return EINVAL; 1038 return EINVAL;
1038 } 1039 }
1039 if (start < 0) 1040 if (start < 0)
1040 return EINVAL; 1041 return EINVAL;
1041 if (fl->l_len < 0) { 1042 if (fl->l_len < 0) {
1042 if (start == 0) 1043 if (start == 0)
1043 return EINVAL; 1044 return EINVAL;
1044 end = start - 1; 1045 end = start - 1;
1045 start += fl->l_len; 1046 start += fl->l_len;
1046 if (start < 0) 1047 if (start < 0)
1047 return EINVAL; 1048 return EINVAL;
1048 } else if (fl->l_len == 0) 1049 } else if (fl->l_len == 0)
1049 end = -1; 1050 end = -1;
1050 else { 1051 else {
1051 oadd = fl->l_len - 1; 1052 oadd = fl->l_len - 1;
1052#ifndef __NetBSD__ 1053#ifndef __NetBSD__
1053 if (oadd > OFF_MAX - start) 1054 if (oadd > OFF_MAX - start)
1054 return EOVERFLOW; 1055 return EOVERFLOW;
1055#endif 1056#endif
1056 end = start + oadd; 1057 end = start + oadd;
1057 } 1058 }
1058 smb_makescred(&scred, l, l ? l->l_cred : NULL); 1059 smb_makescred(&scred, l, l ? l->l_cred : NULL);
1059 switch (ap->a_op) { 1060 switch (ap->a_op) {
1060 case F_SETLK: 1061 case F_SETLK:
1061 switch (fl->l_type) { 1062 switch (fl->l_type) {
1062 case F_WRLCK: 1063 case F_WRLCK:
1063 lkop = SMB_LOCK_EXCL; 1064 lkop = SMB_LOCK_EXCL;
1064 break; 1065 break;
1065 case F_RDLCK: 1066 case F_RDLCK:
1066 lkop = SMB_LOCK_SHARED; 1067 lkop = SMB_LOCK_SHARED;
1067 break; 1068 break;
1068 case F_UNLCK: 1069 case F_UNLCK:
1069 lkop = SMB_LOCK_RELEASE; 1070 lkop = SMB_LOCK_RELEASE;
1070 break; 1071 break;
1071 default: 1072 default:
1072 return EINVAL; 1073 return EINVAL;
1073 } 1074 }
1074 error = lf_advlock(ap, &np->n_lockf, size); 1075 error = lf_advlock(ap, &np->n_lockf, size);
1075 if (error) 1076 if (error)
1076 break; 1077 break;
1077 /* 1078 /*
1078 * The ID we use for smb_lock is passed as PID to SMB 1079 * The ID we use for smb_lock is passed as PID to SMB
1079 * server. It MUST agree with PID as setup in basic 1080 * server. It MUST agree with PID as setup in basic
1080 * SMB header in later write requests, otherwise SMB server 1081 * SMB header in later write requests, otherwise SMB server
1081 * returns EDEADLK. See also smb_rq_new() on SMB header setup. 1082 * returns EDEADLK. See also smb_rq_new() on SMB header setup.
1082 */ 1083 */
1083 error = smbfs_smb_lock(np, lkop,(void *)1, start, end, &scred); 1084 error = smbfs_smb_lock(np, lkop,(void *)1, start, end, &scred);
1084 if (error) { 1085 if (error) {
1085 ap->a_op = F_UNLCK; 1086 ap->a_op = F_UNLCK;
1086 lf_advlock(ap, &np->n_lockf, size); 1087 lf_advlock(ap, &np->n_lockf, size);
1087 } 1088 }
1088 break; 1089 break;
1089 case F_UNLCK: 1090 case F_UNLCK:
1090 lf_advlock(ap, &np->n_lockf, size); 1091 lf_advlock(ap, &np->n_lockf, size);
1091 error = smbfs_smb_lock(np, SMB_LOCK_RELEASE, ap->a_id, start, end, &scred); 1092 error = smbfs_smb_lock(np, SMB_LOCK_RELEASE, ap->a_id, start, end, &scred);
1092 break; 1093 break;
1093 case F_GETLK: 1094 case F_GETLK:
1094 error = lf_advlock(ap, &np->n_lockf, size); 1095 error = lf_advlock(ap, &np->n_lockf, size);
1095 break; 1096 break;
1096 default: 1097 default:
1097 return EINVAL; 1098 return EINVAL;
1098 } 1099 }
1099 1100
1100 return error; 1101 return error;
1101} 1102}
1102 1103
1103static int 1104static int
1104smbfs_pathcheck(struct smbmount *smp, const char *name, int nmlen) 1105smbfs_pathcheck(struct smbmount *smp, const char *name, int nmlen)
1105{ 1106{
1106 static const char * const badchars = "*/\\:<>;?"; 1107 static const char * const badchars = "*/\\:<>;?";
1107 static const char * const badchars83 = " +|,[]="; 1108 static const char * const badchars83 = " +|,[]=";
1108 const char *cp; 1109 const char *cp;
1109 int i; 1110 int i;
1110 1111
1111 if (SMB_DIALECT(SSTOVC(smp->sm_share)) < SMB_DIALECT_LANMAN2_0) { 1112 if (SMB_DIALECT(SSTOVC(smp->sm_share)) < SMB_DIALECT_LANMAN2_0) {
1112 /* 1113 /*
1113 * Name should conform 8.3 format 1114 * Name should conform 8.3 format
1114 */ 1115 */
1115 if (nmlen > 12) 1116 if (nmlen > 12)
1116 return (ENAMETOOLONG); 1117 return (ENAMETOOLONG);
1117 1118
1118 if ((cp = memchr(name, '.', nmlen)) == NULL 1119 if ((cp = memchr(name, '.', nmlen)) == NULL
1119 || cp == name || (cp - name) > 8 1120 || cp == name || (cp - name) > 8
1120 || (cp = memchr(cp + 1, '.', nmlen - (cp - name))) != NULL) 1121 || (cp = memchr(cp + 1, '.', nmlen - (cp - name))) != NULL)
1121 goto bad; 1122 goto bad;
1122 1123
1123 for (cp = name, i = 0; i < nmlen; i++, cp++) 1124 for (cp = name, i = 0; i < nmlen; i++, cp++)
1124 if (strchr(badchars83, *cp) != NULL) 1125 if (strchr(badchars83, *cp) != NULL)
1125 goto bad; 1126 goto bad;
1126 } 1127 }
1127 1128
1128 for (cp = name, i = 0; i < nmlen; i++, cp++) 1129 for (cp = name, i = 0; i < nmlen; i++, cp++)
1129 if (strchr(badchars, *cp) != NULL) 1130 if (strchr(badchars, *cp) != NULL)
1130 goto bad; 1131 goto bad;
1131 1132
1132 /* name is fine */ 1133 /* name is fine */
1133 return (0); 1134 return (0);
1134 1135
1135 bad: 1136 bad:
1136 return (ENOENT); 1137 return (ENOENT);
1137} 1138}
1138 1139
1139/* 1140/*
1140 * Things go even weird without fixed inode numbers... 1141 * Things go even weird without fixed inode numbers...
1141 */ 1142 */
1142int 1143int
1143smbfs_lookup(void *v) 1144smbfs_lookup(void *v)
1144{ 1145{
1145 struct vop_lookup_args /* { 1146 struct vop_lookup_args /* {
1146 struct vnode *a_dvp; 1147 struct vnode *a_dvp;
1147 struct vnode **a_vpp; 1148 struct vnode **a_vpp;
1148 struct componentname *a_cnp; 1149 struct componentname *a_cnp;
1149 } */ *ap = v; 1150 } */ *ap = v;
1150 struct componentname *cnp = ap->a_cnp; 1151 struct componentname *cnp = ap->a_cnp;
1151 struct vnode *dvp = ap->a_dvp; 1152 struct vnode *dvp = ap->a_dvp;
1152 struct vnode **vpp = ap->a_vpp; 1153 struct vnode **vpp = ap->a_vpp;
1153 struct mount *mp = dvp->v_mount; 1154 struct mount *mp = dvp->v_mount;
1154 struct smbnode *dnp; 1155 struct smbnode *dnp;
1155 struct smbfattr fattr; 1156 struct smbfattr fattr;
1156 struct smb_cred scred; 1157 struct smb_cred scred;
1157 const char *name = cnp->cn_nameptr; 1158 const char *name = cnp->cn_nameptr;
1158 int flags = cnp->cn_flags; 1159 int flags = cnp->cn_flags;
1159 int nameiop = cnp->cn_nameiop; 1160 int nameiop = cnp->cn_nameiop;
1160 int nmlen = cnp->cn_namelen; 1161 int nmlen = cnp->cn_namelen;
1161 int error, islastcn, isdot; 1162 int error, islastcn, isdot;
1162 1163
1163 /* 1164 /*
1164 * Check accessiblity of directory. 1165 * Check accessiblity of directory.
1165 */ 1166 */
1166 error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred); 1167 error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred);
1167 if (error) 1168 if (error)
1168 return (error); 1169 return (error);
1169 1170
1170 if ((cnp->cn_flags & ISLASTCN) && 1171 if ((cnp->cn_flags & ISLASTCN) &&
1171 (dvp->v_mount->mnt_flag & MNT_RDONLY) && 1172 (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
1172 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) 1173 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
1173 return (EROFS); 1174 return (EROFS);
1174 1175
1175 SMBVDEBUG("%d '%.*s' in '%.*s'\n", nameiop, nmlen, name, 1176 SMBVDEBUG("%d '%.*s' in '%.*s'\n", nameiop, nmlen, name,
1176 (int) VTOSMB(dvp)->n_nmlen, VTOSMB(dvp)->n_name); 1177 (int) VTOSMB(dvp)->n_nmlen, VTOSMB(dvp)->n_name);
1177 1178
1178 islastcn = flags & ISLASTCN; 1179 islastcn = flags & ISLASTCN;
1179 1180
1180 /* 1181 /*
1181 * Before tediously performing a linear scan of the directory, 1182 * Before tediously performing a linear scan of the directory,
1182 * check the name cache to see if the directory/name pair 1183 * check the name cache to see if the directory/name pair
1183 * we are looking for is known already. 1184 * we are looking for is known already.
1184 * If the directory/name pair is found in the name cache, 1185 * If the directory/name pair is found in the name cache,
1185 * we have to ensure the directory has not changed from 1186 * we have to ensure the directory has not changed from
1186 * the time the cache entry has been created. If it has, 1187 * the time the cache entry has been created. If it has,
1187 * the cache entry has to be ignored. 1188 * the cache entry has to be ignored.
1188 */ 1189 */
1189 if ((error = cache_lookup(dvp, vpp, cnp)) >= 0) { 1190 if ((error = cache_lookup(dvp, vpp, cnp)) >= 0) {
1190 struct vattr vattr; 1191 struct vattr vattr;
1191 struct vnode *newvp; 1192 struct vnode *newvp;
1192 int err2; 1193 int err2;
1193 1194
1194 if (error && error != ENOENT) { 1195 if (error && error != ENOENT) {
1195 *vpp = NULLVP; 1196 *vpp = NULLVP;
1196 return error; 1197 return error;
1197 } 1198 }
1198 1199
1199 err2 = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred); 1200 err2 = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred);
1200 if (err2 != 0) { 1201 if (err2 != 0) {
1201 if (error == 0) { 1202 if (error == 0) {
1202 if (*vpp != dvp) 1203 if (*vpp != dvp)
1203 vput(*vpp); 1204 vput(*vpp);
1204 else 1205 else
1205 vrele(*vpp); 1206 vrele(*vpp);
1206 } 1207 }
1207 *vpp = NULLVP; 1208 *vpp = NULLVP;
1208 return err2; 1209 return err2;
1209 } 1210 }
1210 1211
1211 if (error == ENOENT) { 1212 if (error == ENOENT) {
1212 if (!VOP_GETATTR(dvp, &vattr, cnp->cn_cred) 1213 if (!VOP_GETATTR(dvp, &vattr, cnp->cn_cred)
1213 && vattr.va_mtime.tv_sec == VTOSMB(dvp)->n_nctime) 1214 && vattr.va_mtime.tv_sec == VTOSMB(dvp)->n_nctime)
1214 return ENOENT; 1215 return ENOENT;
1215 cache_purge(dvp); 1216 cache_purge(dvp);
1216 VTOSMB(dvp)->n_nctime = 0; 1217 VTOSMB(dvp)->n_nctime = 0;
1217 goto dolookup; 1218 goto dolookup;
1218 } 1219 }
1219 1220
1220 newvp = *vpp; 1221 newvp = *vpp;
1221 if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred) 1222 if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred)
1222 && vattr.va_ctime.tv_sec == VTOSMB(newvp)->n_ctime) 1223 && vattr.va_ctime.tv_sec == VTOSMB(newvp)->n_ctime)
1223 { 1224 {
1224 /* nfsstats.lookupcache_hits++; */ 1225 /* nfsstats.lookupcache_hits++; */
1225 if (cnp->cn_nameiop != LOOKUP && islastcn) 1226 if (cnp->cn_nameiop != LOOKUP && islastcn)
1226 cnp->cn_flags |= SAVENAME; 1227 cnp->cn_flags |= SAVENAME;
1227 1228
1228 return (0); 1229 return (0);
1229 } 1230 }
1230 1231
1231 cache_purge(newvp); 1232 cache_purge(newvp);
1232 if (newvp != dvp) 1233 if (newvp != dvp)
1233 vput(newvp); 1234 vput(newvp);
1234 else 1235 else
1235 vrele(newvp); 1236 vrele(newvp);
1236 *vpp = NULLVP; 1237 *vpp = NULLVP;
1237 } 1238 }
1238 1239
1239 dolookup: 1240 dolookup:
1240 1241
1241 /* ensure the name is sane */ 1242 /* ensure the name is sane */
1242 if (nameiop != LOOKUP) { 1243 if (nameiop != LOOKUP) {
1243 error = smbfs_pathcheck(VFSTOSMBFS(mp), cnp->cn_nameptr, 1244 error = smbfs_pathcheck(VFSTOSMBFS(mp), cnp->cn_nameptr,
1244 cnp->cn_namelen); 1245 cnp->cn_namelen);
1245 if (error) 1246 if (error)
1246 return (error); 1247 return (error);
1247 } 1248 }
1248 1249
1249 dnp = VTOSMB(dvp); 1250 dnp = VTOSMB(dvp);
1250 isdot = (nmlen == 1 && name[0] == '.'); 1251 isdot = (nmlen == 1 && name[0] == '.');
1251 1252
1252 /* 1253 /*
1253 * entry is not in the cache or has been expired 1254 * entry is not in the cache or has been expired
1254 */ 1255 */
1255 smb_makescred(&scred, curlwp, cnp->cn_cred); 1256 smb_makescred(&scred, curlwp, cnp->cn_cred);
1256 if (flags & ISDOTDOT) 1257 if (flags & ISDOTDOT)
1257 error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, 1258 error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0,
1258 &fattr, &scred); 1259 &fattr, &scred);
1259 else 1260 else
1260 error = smbfs_smb_lookup(dnp, name, nmlen, &fattr, &scred); 1261 error = smbfs_smb_lookup(dnp, name, nmlen, &fattr, &scred);
1261 1262
1262 if (error) { 1263 if (error) {
1263 /* Not found */ 1264 /* Not found */
1264 1265
1265 if (error != ENOENT) 1266 if (error != ENOENT)
1266 return (error); 1267 return (error);
1267 1268
1268 /* 1269 /*
1269 * Handle RENAME or CREATE case... 1270 * Handle RENAME or CREATE case...
1270 */ 1271 */
1271 if ((nameiop == CREATE || nameiop == RENAME) && islastcn) { 1272 if ((nameiop == CREATE || nameiop == RENAME) && islastcn) {
1272 /* 1273 /*
1273 * Access for write is interpreted as allowing 1274 * Access for write is interpreted as allowing
1274 * creation of files in the directory. 1275 * creation of files in the directory.
1275 */ 1276 */
1276 error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred); 1277 error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
1277 if (error) 1278 if (error)
1278 return (error); 1279 return (error);
1279 1280
1280 cnp->cn_flags |= SAVENAME; 1281 cnp->cn_flags |= SAVENAME;
1281 return (EJUSTRETURN); 1282 return (EJUSTRETURN);
1282 } 1283 }
1283 1284
1284 /* 1285 /*
1285 * Insert name into cache (as non-existent) if appropriate. 1286 * Insert name into cache (as non-existent) if appropriate.
1286 */ 1287 */
1287 if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) 1288 if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE)
1288 cache_enter(dvp, *vpp, cnp); 1289 cache_enter(dvp, *vpp, cnp);
1289 1290
1290 return (ENOENT); 1291 return (ENOENT);
1291 } 1292 }
1292 1293
1293 /* Found */ 1294 /* Found */
1294 1295
1295 /* Handle RENAME case... */ 1296 /* Handle RENAME case... */
1296 if (nameiop == RENAME && islastcn) { 1297 if (nameiop == RENAME && islastcn) {
1297 error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred); 1298 error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
1298 if (error) 1299 if (error)
1299 return (error); 1300 return (error);
1300 1301
1301 if (isdot) 1302 if (isdot)
1302 return (EISDIR); 1303 return (EISDIR);
1303 if (flags & ISDOTDOT) 1304 if (flags & ISDOTDOT)
1304 VOP_UNLOCK(dvp, 0); 1305 VOP_UNLOCK(dvp, 0);
1305 error = smbfs_nget(mp, dvp, name, nmlen, &fattr, vpp); 1306 error = smbfs_nget(mp, dvp, name, nmlen, &fattr, vpp);
1306 if (flags & ISDOTDOT) 1307 if (flags & ISDOTDOT)
1307 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); 1308 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
1308 if (error) 1309 if (error)
1309 return (error); 1310 return (error);
1310 cnp->cn_flags |= SAVENAME; 1311 cnp->cn_flags |= SAVENAME;
1311 return (0); 1312 return (0);
1312 } 1313 }
1313 1314
1314 if (isdot) { 1315 if (isdot) {
1315 1316
1316 /* 1317 /*
1317 * "." lookup 1318 * "." lookup
1318 */ 1319 */
1319 VREF(dvp); 1320 VREF(dvp);
1320 *vpp = dvp; 1321 *vpp = dvp;
1321 } else if (flags & ISDOTDOT) { 1322 } else if (flags & ISDOTDOT) {
1322 1323
1323 /* 1324 /*
1324 * ".." lookup 1325 * ".." lookup
1325 */ 1326 */
1326 VOP_UNLOCK(dvp, 0); 1327 VOP_UNLOCK(dvp, 0);
1327 error = smbfs_nget(mp, dvp, name, nmlen, NULL, vpp); 1328 error = smbfs_nget(mp, dvp, name, nmlen, NULL, vpp);
1328 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); 1329 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
1329 if (error) { 1330 if (error) {
1330 return error; 1331 return error;
1331 } 1332 }
1332 } else { 1333 } else {
1333 /* 1334 /*
1334 * Other lookups. 1335 * Other lookups.
1335 */ 1336 */
1336 error = smbfs_nget(mp, dvp, name, nmlen, &fattr, vpp); 1337 error = smbfs_nget(mp, dvp, name, nmlen, &fattr, vpp);
1337 if (error) 1338 if (error)
1338 return error; 1339 return error;
1339 } 1340 }
1340 1341
1341 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) 1342 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
1342 cnp->cn_flags |= SAVENAME; 1343 cnp->cn_flags |= SAVENAME;
1343 1344
1344 if ((cnp->cn_flags & MAKEENTRY)) { 1345 if ((cnp->cn_flags & MAKEENTRY)) {
1345 KASSERT(error == 0); 1346 KASSERT(error == 0);
1346 if (cnp->cn_nameiop != DELETE || !islastcn) { 1347 if (cnp->cn_nameiop != DELETE || !islastcn) {
1347 VTOSMB(*vpp)->n_ctime = VTOSMB(*vpp)->n_mtime.tv_sec; 1348 VTOSMB(*vpp)->n_ctime = VTOSMB(*vpp)->n_mtime.tv_sec;
1348 cache_enter(dvp, *vpp, cnp); 1349 cache_enter(dvp, *vpp, cnp);
1349#ifdef notdef 1350#ifdef notdef
1350 } else if (error == ENOENT && cnp->cn_nameiop != CREATE) { 1351 } else if (error == ENOENT && cnp->cn_nameiop != CREATE) {
1351 VTOSMB(*vpp)->n_nctime = VTOSMB(*vpp)->n_mtime.tv_sec; 1352 VTOSMB(*vpp)->n_nctime = VTOSMB(*vpp)->n_mtime.tv_sec;
1352 cache_enter(dvp, *vpp, cnp); 1353 cache_enter(dvp, *vpp, cnp);
1353#endif 1354#endif
1354 } 1355 }
1355 } 1356 }
1356 1357
1357 return (0); 1358 return (0);
1358} 1359}