nfs_bio.c revision 1.114 1 /* $NetBSD: nfs_bio.c,v 1.114 2003/12/07 21:15:46 fvdl Exp $ */
2
3 /*
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Rick Macklem at The University of Guelph.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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
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
32 * SUCH DAMAGE.
33 *
34 * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95
35 */
36
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.114 2003/12/07 21:15:46 fvdl Exp $");
39
40 #include "opt_nfs.h"
41 #include "opt_ddb.h"
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/resourcevar.h>
46 #include <sys/signalvar.h>
47 #include <sys/proc.h>
48 #include <sys/buf.h>
49 #include <sys/vnode.h>
50 #include <sys/mount.h>
51 #include <sys/kernel.h>
52 #include <sys/namei.h>
53 #include <sys/dirent.h>
54 #include <sys/malloc.h>
55
56 #include <uvm/uvm_extern.h>
57 #include <uvm/uvm.h>
58
59 #include <nfs/rpcv2.h>
60 #include <nfs/nfsproto.h>
61 #include <nfs/nfs.h>
62 #include <nfs/nfsmount.h>
63 #include <nfs/nqnfs.h>
64 #include <nfs/nfsnode.h>
65 #include <nfs/nfs_var.h>
66
67 extern int nfs_numasync;
68 extern int nfs_commitsize;
69 extern struct nfsstats nfsstats;
70
71 static int nfs_doio_read __P((struct buf *, struct uio *));
72 static int nfs_doio_write __P((struct buf *, struct uio *));
73 static int nfs_doio_phys __P((struct buf *, struct uio *));
74
75 /*
76 * Vnode op for read using bio
77 * Any similarity to readip() is purely coincidental
78 */
79 int
80 nfs_bioread(vp, uio, ioflag, cred, cflag)
81 struct vnode *vp;
82 struct uio *uio;
83 int ioflag, cflag;
84 struct ucred *cred;
85 {
86 struct nfsnode *np = VTONFS(vp);
87 struct buf *bp = NULL, *rabp;
88 struct vattr vattr;
89 struct proc *p;
90 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
91 struct nfsdircache *ndp = NULL, *nndp = NULL;
92 caddr_t baddr, ep, edp;
93 int got_buf = 0, error = 0, n = 0, on = 0, en, enn;
94 int enough = 0;
95 struct dirent *dp, *pdp;
96 off_t curoff = 0;
97
98 #ifdef DIAGNOSTIC
99 if (uio->uio_rw != UIO_READ)
100 panic("nfs_read mode");
101 #endif
102 if (uio->uio_resid == 0)
103 return (0);
104 if (vp->v_type != VDIR && uio->uio_offset < 0)
105 return (EINVAL);
106 p = uio->uio_procp;
107 #ifndef NFS_V2_ONLY
108 if ((nmp->nm_flag & NFSMNT_NFSV3) &&
109 !(nmp->nm_iflag & NFSMNT_GOTFSINFO))
110 (void)nfs_fsinfo(nmp, vp, cred, p);
111 #endif
112 if (vp->v_type != VDIR &&
113 (uio->uio_offset + uio->uio_resid) > nmp->nm_maxfilesize)
114 return (EFBIG);
115
116 /*
117 * For nfs, cache consistency can only be maintained approximately.
118 * Although RFC1094 does not specify the criteria, the following is
119 * believed to be compatible with the reference port.
120 * For nqnfs, full cache consistency is maintained within the loop.
121 * For nfs:
122 * If the file's modify time on the server has changed since the
123 * last read rpc or you have written to the file,
124 * you may have lost data cache consistency with the
125 * server, so flush all of the file's data out of the cache.
126 * Then force a getattr rpc to ensure that you have up to date
127 * attributes.
128 * NB: This implies that cache data can be read when up to
129 * NFS_ATTRTIMEO seconds out of date. If you find that you need current
130 * attributes this could be forced by setting n_attrstamp to 0 before
131 * the VOP_GETATTR() call.
132 */
133
134 if ((nmp->nm_flag & NFSMNT_NQNFS) == 0 && vp->v_type != VLNK) {
135 if (np->n_flag & NMODIFIED) {
136 if (vp->v_type != VREG) {
137 if (vp->v_type != VDIR)
138 panic("nfs: bioread, not dir");
139 nfs_invaldircache(vp, 0);
140 np->n_direofoffset = 0;
141 error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
142 if (error)
143 return (error);
144 }
145 np->n_attrstamp = 0;
146 error = VOP_GETATTR(vp, &vattr, cred, p);
147 if (error)
148 return (error);
149 np->n_mtime = vattr.va_mtime;
150 } else {
151 error = VOP_GETATTR(vp, &vattr, cred, p);
152 if (error)
153 return (error);
154 if (timespeccmp(&np->n_mtime, &vattr.va_mtime, !=)) {
155 if (vp->v_type == VDIR) {
156 nfs_invaldircache(vp, 0);
157 np->n_direofoffset = 0;
158 }
159 error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
160 if (error)
161 return (error);
162 np->n_mtime = vattr.va_mtime;
163 }
164 }
165 }
166
167 do {
168 #ifndef NFS_V2_ONLY
169 /*
170 * Get a valid lease. If cached data is stale, flush it.
171 */
172 if (nmp->nm_flag & NFSMNT_NQNFS) {
173 if (NQNFS_CKINVALID(vp, np, ND_READ)) {
174 do {
175 error = nqnfs_getlease(vp, ND_READ, cred, p);
176 } while (error == NQNFS_EXPIRED);
177 if (error)
178 return (error);
179 if (np->n_lrev != np->n_brev ||
180 (np->n_flag & NQNFSNONCACHE) ||
181 ((np->n_flag & NMODIFIED) && vp->v_type == VDIR)) {
182 if (vp->v_type == VDIR) {
183 nfs_invaldircache(vp, 0);
184 np->n_direofoffset = 0;
185 }
186 error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
187 if (error)
188 return (error);
189 np->n_brev = np->n_lrev;
190 }
191 } else if (vp->v_type == VDIR && (np->n_flag & NMODIFIED)) {
192 nfs_invaldircache(vp, 0);
193 error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
194 np->n_direofoffset = 0;
195 if (error)
196 return (error);
197 }
198 }
199 #endif
200 /*
201 * Don't cache symlinks.
202 */
203 if (np->n_flag & NQNFSNONCACHE
204 || ((vp->v_flag & VROOT) && vp->v_type == VLNK)) {
205 switch (vp->v_type) {
206 case VREG:
207 return (nfs_readrpc(vp, uio));
208 case VLNK:
209 return (nfs_readlinkrpc(vp, uio, cred));
210 case VDIR:
211 break;
212 default:
213 printf(" NQNFSNONCACHE: type %x unexpected\n",
214 vp->v_type);
215 };
216 }
217 baddr = (caddr_t)0;
218 switch (vp->v_type) {
219 case VREG:
220 nfsstats.biocache_reads++;
221
222 error = 0;
223 if (uio->uio_offset >= np->n_size) {
224 break;
225 }
226 while (uio->uio_resid > 0) {
227 void *win;
228 vsize_t bytelen = MIN(np->n_size - uio->uio_offset,
229 uio->uio_resid);
230
231 if (bytelen == 0)
232 break;
233 win = ubc_alloc(&vp->v_uobj, uio->uio_offset,
234 &bytelen, UBC_READ);
235 error = uiomove(win, bytelen, uio);
236 ubc_release(win, 0);
237 if (error) {
238 break;
239 }
240 }
241 n = 0;
242 break;
243
244 case VLNK:
245 nfsstats.biocache_readlinks++;
246 bp = nfs_getcacheblk(vp, (daddr_t)0, NFS_MAXPATHLEN, p);
247 if (!bp)
248 return (EINTR);
249 if ((bp->b_flags & B_DONE) == 0) {
250 bp->b_flags |= B_READ;
251 error = nfs_doio(bp, p);
252 if (error) {
253 brelse(bp);
254 return (error);
255 }
256 }
257 n = MIN(uio->uio_resid, NFS_MAXPATHLEN - bp->b_resid);
258 got_buf = 1;
259 on = 0;
260 break;
261 case VDIR:
262 diragain:
263 nfsstats.biocache_readdirs++;
264 ndp = nfs_searchdircache(vp, uio->uio_offset,
265 (nmp->nm_flag & NFSMNT_XLATECOOKIE), 0);
266 if (!ndp) {
267 /*
268 * We've been handed a cookie that is not
269 * in the cache. If we're not translating
270 * 32 <-> 64, it may be a value that was
271 * flushed out of the cache because it grew
272 * too big. Let the server judge if it's
273 * valid or not. In the translation case,
274 * we have no way of validating this value,
275 * so punt.
276 */
277 if (nmp->nm_flag & NFSMNT_XLATECOOKIE)
278 return (EINVAL);
279 ndp = nfs_enterdircache(vp, uio->uio_offset,
280 uio->uio_offset, 0, 0);
281 }
282
283 if (uio->uio_offset != 0 &&
284 ndp->dc_cookie == np->n_direofoffset) {
285 nfsstats.direofcache_hits++;
286 return (0);
287 }
288
289 bp = nfs_getcacheblk(vp, ndp->dc_blkno, NFS_DIRBLKSIZ, p);
290 if (!bp)
291 return (EINTR);
292 if ((bp->b_flags & B_DONE) == 0) {
293 bp->b_flags |= B_READ;
294 bp->b_dcookie = ndp->dc_blkcookie;
295 error = nfs_doio(bp, p);
296 if (error) {
297 /*
298 * Yuck! The directory has been modified on the
299 * server. Punt and let the userland code
300 * deal with it.
301 */
302 brelse(bp);
303 if (error == NFSERR_BAD_COOKIE) {
304 nfs_invaldircache(vp, 0);
305 nfs_vinvalbuf(vp, 0, cred, p, 1);
306 error = EINVAL;
307 }
308 return (error);
309 }
310 }
311
312 /*
313 * Just return if we hit EOF right away with this
314 * block. Always check here, because direofoffset
315 * may have been set by an nfsiod since the last
316 * check.
317 */
318 if (np->n_direofoffset != 0 &&
319 ndp->dc_blkcookie == np->n_direofoffset) {
320 brelse(bp);
321 return (0);
322 }
323
324 /*
325 * Find the entry we were looking for in the block.
326 */
327
328 en = ndp->dc_entry;
329
330 pdp = dp = (struct dirent *)bp->b_data;
331 edp = bp->b_data + bp->b_bcount - bp->b_resid;
332 enn = 0;
333 while (enn < en && (caddr_t)dp < edp) {
334 pdp = dp;
335 dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
336 enn++;
337 }
338
339 /*
340 * If the entry number was bigger than the number of
341 * entries in the block, or the cookie of the previous
342 * entry doesn't match, the directory cache is
343 * stale. Flush it and try again (i.e. go to
344 * the server).
345 */
346 if ((caddr_t)dp >= edp || (caddr_t)dp + dp->d_reclen > edp ||
347 (en > 0 && NFS_GETCOOKIE(pdp) != ndp->dc_cookie)) {
348 #ifdef DEBUG
349 printf("invalid cache: %p %p %p off %lx %lx\n",
350 pdp, dp, edp,
351 (unsigned long)uio->uio_offset,
352 (unsigned long)NFS_GETCOOKIE(pdp));
353 #endif
354 brelse(bp);
355 nfs_invaldircache(vp, 0);
356 nfs_vinvalbuf(vp, 0, cred, p, 0);
357 goto diragain;
358 }
359
360 on = (caddr_t)dp - bp->b_data;
361
362 /*
363 * Cache all entries that may be exported to the
364 * user, as they may be thrown back at us. The
365 * NFSBIO_CACHECOOKIES flag indicates that all
366 * entries are being 'exported', so cache them all.
367 */
368
369 if (en == 0 && pdp == dp) {
370 dp = (struct dirent *)
371 ((caddr_t)dp + dp->d_reclen);
372 enn++;
373 }
374
375 if (uio->uio_resid < (bp->b_bcount - bp->b_resid - on)) {
376 n = uio->uio_resid;
377 enough = 1;
378 } else
379 n = bp->b_bcount - bp->b_resid - on;
380
381 ep = bp->b_data + on + n;
382
383 /*
384 * Find last complete entry to copy, caching entries
385 * (if requested) as we go.
386 */
387
388 while ((caddr_t)dp < ep && (caddr_t)dp + dp->d_reclen <= ep) {
389 if (cflag & NFSBIO_CACHECOOKIES) {
390 nndp = nfs_enterdircache(vp, NFS_GETCOOKIE(pdp),
391 ndp->dc_blkcookie, enn, bp->b_lblkno);
392 if (nmp->nm_flag & NFSMNT_XLATECOOKIE) {
393 NFS_STASHCOOKIE32(pdp,
394 nndp->dc_cookie32);
395 }
396 }
397 pdp = dp;
398 dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
399 enn++;
400 }
401
402 /*
403 * If the last requested entry was not the last in the
404 * buffer (happens if NFS_DIRFRAGSIZ < NFS_DIRBLKSIZ),
405 * cache the cookie of the last requested one, and
406 * set of the offset to it.
407 */
408
409 if ((on + n) < bp->b_bcount - bp->b_resid) {
410 curoff = NFS_GETCOOKIE(pdp);
411 nndp = nfs_enterdircache(vp, curoff, ndp->dc_blkcookie,
412 enn, bp->b_lblkno);
413 if (nmp->nm_flag & NFSMNT_XLATECOOKIE) {
414 NFS_STASHCOOKIE32(pdp, nndp->dc_cookie32);
415 curoff = nndp->dc_cookie32;
416 }
417 } else
418 curoff = bp->b_dcookie;
419
420 /*
421 * Always cache the entry for the next block,
422 * so that readaheads can use it.
423 */
424 nndp = nfs_enterdircache(vp, bp->b_dcookie, bp->b_dcookie, 0,0);
425 if (nmp->nm_flag & NFSMNT_XLATECOOKIE) {
426 if (curoff == bp->b_dcookie) {
427 NFS_STASHCOOKIE32(pdp, nndp->dc_cookie32);
428 curoff = nndp->dc_cookie32;
429 }
430 }
431
432 n = ((caddr_t)pdp + pdp->d_reclen) - (bp->b_data + on);
433
434 /*
435 * If not eof and read aheads are enabled, start one.
436 * (You need the current block first, so that you have the
437 * directory offset cookie of the next block.)
438 */
439 if (nfs_numasync > 0 && nmp->nm_readahead > 0 &&
440 np->n_direofoffset == 0 && !(np->n_flag & NQNFSNONCACHE)) {
441 rabp = nfs_getcacheblk(vp, nndp->dc_blkno,
442 NFS_DIRBLKSIZ, p);
443 if (rabp) {
444 if ((rabp->b_flags & (B_DONE | B_DELWRI)) == 0) {
445 rabp->b_dcookie = nndp->dc_cookie;
446 rabp->b_flags |= (B_READ | B_ASYNC);
447 if (nfs_asyncio(rabp)) {
448 rabp->b_flags |= B_INVAL;
449 brelse(rabp);
450 }
451 } else
452 brelse(rabp);
453 }
454 }
455 got_buf = 1;
456 break;
457 default:
458 printf(" nfsbioread: type %x unexpected\n",vp->v_type);
459 break;
460 }
461
462 if (n > 0) {
463 if (!baddr)
464 baddr = bp->b_data;
465 error = uiomove(baddr + on, (int)n, uio);
466 }
467 switch (vp->v_type) {
468 case VREG:
469 break;
470 case VLNK:
471 n = 0;
472 break;
473 case VDIR:
474 if (np->n_flag & NQNFSNONCACHE)
475 bp->b_flags |= B_INVAL;
476 uio->uio_offset = curoff;
477 if (enough)
478 n = 0;
479 break;
480 default:
481 printf(" nfsbioread: type %x unexpected\n",vp->v_type);
482 }
483 if (got_buf)
484 brelse(bp);
485 } while (error == 0 && uio->uio_resid > 0 && n > 0);
486 return (error);
487 }
488
489 /*
490 * Vnode op for write using bio
491 */
492 int
493 nfs_write(v)
494 void *v;
495 {
496 struct vop_write_args /* {
497 struct vnode *a_vp;
498 struct uio *a_uio;
499 int a_ioflag;
500 struct ucred *a_cred;
501 } */ *ap = v;
502 struct uio *uio = ap->a_uio;
503 struct proc *p = uio->uio_procp;
504 struct vnode *vp = ap->a_vp;
505 struct nfsnode *np = VTONFS(vp);
506 struct ucred *cred = ap->a_cred;
507 int ioflag = ap->a_ioflag;
508 struct vattr vattr;
509 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
510 void *win;
511 voff_t oldoff, origoff;
512 vsize_t bytelen;
513 int error = 0;
514 int extended = 0, wrotedta = 0;
515
516 #ifdef DIAGNOSTIC
517 if (uio->uio_rw != UIO_WRITE)
518 panic("nfs_write mode");
519 if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc)
520 panic("nfs_write proc");
521 #endif
522 if (vp->v_type != VREG)
523 return (EIO);
524 if (np->n_flag & NWRITEERR) {
525 np->n_flag &= ~NWRITEERR;
526 return (np->n_error);
527 }
528 #ifndef NFS_V2_ONLY
529 if ((nmp->nm_flag & NFSMNT_NFSV3) &&
530 !(nmp->nm_iflag & NFSMNT_GOTFSINFO))
531 (void)nfs_fsinfo(nmp, vp, cred, p);
532 #endif
533 if (ioflag & (IO_APPEND | IO_SYNC)) {
534 if (np->n_flag & NMODIFIED) {
535 np->n_attrstamp = 0;
536 error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
537 if (error)
538 return (error);
539 }
540 if (ioflag & IO_APPEND) {
541 np->n_attrstamp = 0;
542 error = VOP_GETATTR(vp, &vattr, cred, p);
543 if (error)
544 return (error);
545 uio->uio_offset = np->n_size;
546 }
547 }
548 if (uio->uio_offset < 0)
549 return (EINVAL);
550 if ((uio->uio_offset + uio->uio_resid) > nmp->nm_maxfilesize)
551 return (EFBIG);
552 if (uio->uio_resid == 0)
553 return (0);
554 /*
555 * Maybe this should be above the vnode op call, but so long as
556 * file servers have no limits, i don't think it matters
557 */
558 if (p && uio->uio_offset + uio->uio_resid >
559 p->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
560 psignal(p, SIGXFSZ);
561 return (EFBIG);
562 }
563
564 if ((np->n_flag & NQNFSNONCACHE) && uio->uio_iovcnt == 1) {
565 int iomode = NFSV3WRITE_FILESYNC;
566 boolean_t stalewriteverf = FALSE;
567
568 lockmgr(&nmp->nm_writeverflock, LK_SHARED, NULL);
569 error = nfs_writerpc(vp, uio, &iomode, FALSE, &stalewriteverf);
570 lockmgr(&nmp->nm_writeverflock, LK_RELEASE, NULL);
571 if (stalewriteverf)
572 nfs_clearcommit(vp->v_mount);
573 return (error);
574 }
575
576 origoff = uio->uio_offset;
577 do {
578 boolean_t extending; /* if we are extending whole pages */
579 u_quad_t oldsize;
580 oldoff = uio->uio_offset;
581 bytelen = uio->uio_resid;
582
583 #ifndef NFS_V2_ONLY
584 /*
585 * Check for a valid write lease.
586 */
587 if ((nmp->nm_flag & NFSMNT_NQNFS) &&
588 NQNFS_CKINVALID(vp, np, ND_WRITE)) {
589 do {
590 error = nqnfs_getlease(vp, ND_WRITE, cred, p);
591 } while (error == NQNFS_EXPIRED);
592 if (error)
593 return (error);
594 if (np->n_lrev != np->n_brev ||
595 (np->n_flag & NQNFSNONCACHE)) {
596 error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);
597 if (error)
598 return (error);
599 np->n_brev = np->n_lrev;
600 }
601 }
602 #endif
603 nfsstats.biocache_writes++;
604
605 oldsize = np->n_size;
606 np->n_flag |= NMODIFIED;
607 if (np->n_size < uio->uio_offset + bytelen) {
608 np->n_size = uio->uio_offset + bytelen;
609 }
610 extending = ((uio->uio_offset & PAGE_MASK) == 0 &&
611 (bytelen & PAGE_MASK) == 0 &&
612 uio->uio_offset >= vp->v_size);
613 win = ubc_alloc(&vp->v_uobj, uio->uio_offset, &bytelen,
614 UBC_WRITE | (extending ? UBC_FAULTBUSY : 0));
615 error = uiomove(win, bytelen, uio);
616 ubc_release(win, 0);
617 if (error) {
618 if (extending) {
619 /*
620 * backout size and free pages past eof.
621 */
622 np->n_size = oldsize;
623 simple_lock(&vp->v_interlock);
624 (void)VOP_PUTPAGES(vp, round_page(vp->v_size),
625 0, PGO_SYNCIO | PGO_FREE);
626 }
627 break;
628 }
629 wrotedta = 1;
630
631 /*
632 * update UVM's notion of the size now that we've
633 * copied the data into the vnode's pages.
634 */
635
636 if (vp->v_size < uio->uio_offset) {
637 uvm_vnp_setsize(vp, uio->uio_offset);
638 extended = 1;
639 }
640
641 if ((oldoff & ~(nmp->nm_wsize - 1)) !=
642 (uio->uio_offset & ~(nmp->nm_wsize - 1))) {
643 simple_lock(&vp->v_interlock);
644 error = VOP_PUTPAGES(vp,
645 trunc_page(oldoff & ~(nmp->nm_wsize - 1)),
646 round_page((uio->uio_offset + nmp->nm_wsize - 1) &
647 ~(nmp->nm_wsize - 1)), PGO_CLEANIT);
648 }
649 } while (uio->uio_resid > 0);
650 if (wrotedta)
651 VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0));
652 if ((np->n_flag & NQNFSNONCACHE) || (ioflag & IO_SYNC)) {
653 simple_lock(&vp->v_interlock);
654 error = VOP_PUTPAGES(vp,
655 trunc_page(origoff & ~(nmp->nm_wsize - 1)),
656 round_page((uio->uio_offset + nmp->nm_wsize - 1) &
657 ~(nmp->nm_wsize - 1)),
658 PGO_CLEANIT | PGO_SYNCIO);
659 }
660 return error;
661 }
662
663 /*
664 * Get an nfs cache block.
665 * Allocate a new one if the block isn't currently in the cache
666 * and return the block marked busy. If the calling process is
667 * interrupted by a signal for an interruptible mount point, return
668 * NULL.
669 */
670 struct buf *
671 nfs_getcacheblk(vp, bn, size, p)
672 struct vnode *vp;
673 daddr_t bn;
674 int size;
675 struct proc *p;
676 {
677 struct buf *bp;
678 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
679
680 if (nmp->nm_flag & NFSMNT_INT) {
681 bp = getblk(vp, bn, size, PCATCH, 0);
682 while (bp == NULL) {
683 if (nfs_sigintr(nmp, NULL, p))
684 return (NULL);
685 bp = getblk(vp, bn, size, 0, 2 * hz);
686 }
687 } else
688 bp = getblk(vp, bn, size, 0, 0);
689 return (bp);
690 }
691
692 /*
693 * Flush and invalidate all dirty buffers. If another process is already
694 * doing the flush, just wait for completion.
695 */
696 int
697 nfs_vinvalbuf(vp, flags, cred, p, intrflg)
698 struct vnode *vp;
699 int flags;
700 struct ucred *cred;
701 struct proc *p;
702 int intrflg;
703 {
704 struct nfsnode *np = VTONFS(vp);
705 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
706 int error = 0, slpflag, slptimeo;
707
708 if ((nmp->nm_flag & NFSMNT_INT) == 0)
709 intrflg = 0;
710 if (intrflg) {
711 slpflag = PCATCH;
712 slptimeo = 2 * hz;
713 } else {
714 slpflag = 0;
715 slptimeo = 0;
716 }
717 /*
718 * First wait for any other process doing a flush to complete.
719 */
720 simple_lock(&vp->v_interlock);
721 while (np->n_flag & NFLUSHINPROG) {
722 np->n_flag |= NFLUSHWANT;
723 error = ltsleep(&np->n_flag, PRIBIO + 2, "nfsvinval",
724 slptimeo, &vp->v_interlock);
725 if (error && intrflg && nfs_sigintr(nmp, NULL, p)) {
726 simple_unlock(&vp->v_interlock);
727 return EINTR;
728 }
729 }
730
731 /*
732 * Now, flush as required.
733 */
734 np->n_flag |= NFLUSHINPROG;
735 simple_unlock(&vp->v_interlock);
736 error = vinvalbuf(vp, flags, cred, p, slpflag, 0);
737 while (error) {
738 if (intrflg && nfs_sigintr(nmp, NULL, p)) {
739 error = EINTR;
740 break;
741 }
742 error = vinvalbuf(vp, flags, cred, p, 0, slptimeo);
743 }
744 simple_lock(&vp->v_interlock);
745 if (error == 0)
746 np->n_flag &= ~NMODIFIED;
747 np->n_flag &= ~NFLUSHINPROG;
748 if (np->n_flag & NFLUSHWANT) {
749 np->n_flag &= ~NFLUSHWANT;
750 wakeup(&np->n_flag);
751 }
752 simple_unlock(&vp->v_interlock);
753 return error;
754 }
755
756 /*
757 * Initiate asynchronous I/O. Return an error if no nfsiods are available.
758 * This is mainly to avoid queueing async I/O requests when the nfsiods
759 * are all hung on a dead server.
760 */
761
762 int
763 nfs_asyncio(bp)
764 struct buf *bp;
765 {
766 int i;
767 struct nfsmount *nmp;
768 int gotiod, slpflag = 0, slptimeo = 0, error;
769
770 if (nfs_numasync == 0)
771 return (EIO);
772
773 nmp = VFSTONFS(bp->b_vp->v_mount);
774 again:
775 if (nmp->nm_flag & NFSMNT_INT)
776 slpflag = PCATCH;
777 gotiod = FALSE;
778
779 /*
780 * Find a free iod to process this request.
781 */
782
783 for (i = 0; i < NFS_MAXASYNCDAEMON; i++) {
784 struct nfs_iod *iod = &nfs_asyncdaemon[i];
785
786 simple_lock(&iod->nid_slock);
787 if (iod->nid_want) {
788 /*
789 * Found one, so wake it up and tell it which
790 * mount to process.
791 */
792 iod->nid_want = NULL;
793 iod->nid_mount = nmp;
794 wakeup(&iod->nid_want);
795 simple_lock(&nmp->nm_slock);
796 simple_unlock(&iod->nid_slock);
797 nmp->nm_bufqiods++;
798 gotiod = TRUE;
799 break;
800 }
801 simple_unlock(&iod->nid_slock);
802 }
803
804 /*
805 * If none are free, we may already have an iod working on this mount
806 * point. If so, it will process our request.
807 */
808
809 if (!gotiod) {
810 simple_lock(&nmp->nm_slock);
811 if (nmp->nm_bufqiods > 0)
812 gotiod = TRUE;
813 }
814
815 LOCK_ASSERT(simple_lock_held(&nmp->nm_slock));
816
817 /*
818 * If we have an iod which can process the request, then queue
819 * the buffer. However, even if we have an iod, do not initiate
820 * queue cleaning if curproc is the pageout daemon. if the NFS mount
821 * is via local loopback, we may put curproc (pagedaemon) to sleep
822 * waiting for the writes to complete. But the server (ourself)
823 * may block the write, waiting for its (ie., our) pagedaemon
824 * to produce clean pages to handle the write: deadlock.
825 * XXX: start non-loopback mounts straight away? If "lots free",
826 * let pagedaemon start loopback writes anyway?
827 */
828 if (gotiod) {
829
830 /*
831 * Ensure that the queue never grows too large.
832 */
833 if (curproc == uvm.pagedaemon_proc) {
834 /* Enque for later, to avoid free-page deadlock */
835 (void) 0;
836 } else while (nmp->nm_bufqlen >= 2*nfs_numasync) {
837 nmp->nm_bufqwant = TRUE;
838 error = ltsleep(&nmp->nm_bufq,
839 slpflag | PRIBIO | PNORELOCK,
840 "nfsaio", slptimeo, &nmp->nm_slock);
841 if (error) {
842 if (nfs_sigintr(nmp, NULL, curproc))
843 return (EINTR);
844 if (slpflag == PCATCH) {
845 slpflag = 0;
846 slptimeo = 2 * hz;
847 }
848 }
849
850 /*
851 * We might have lost our iod while sleeping,
852 * so check and loop if nescessary.
853 */
854
855 if (nmp->nm_bufqiods == 0)
856 goto again;
857
858 simple_lock(&nmp->nm_slock);
859 }
860 TAILQ_INSERT_TAIL(&nmp->nm_bufq, bp, b_freelist);
861 nmp->nm_bufqlen++;
862 simple_unlock(&nmp->nm_slock);
863 return (0);
864 }
865 simple_unlock(&nmp->nm_slock);
866
867 /*
868 * All the iods are busy on other mounts, so return EIO to
869 * force the caller to process the i/o synchronously.
870 */
871
872 return (EIO);
873 }
874
875 /*
876 * nfs_doio for read.
877 */
878 static int
879 nfs_doio_read(bp, uiop)
880 struct buf *bp;
881 struct uio *uiop;
882 {
883 struct vnode *vp = bp->b_vp;
884 struct nfsnode *np = VTONFS(vp);
885 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
886 int error = 0;
887
888 uiop->uio_rw = UIO_READ;
889 switch (vp->v_type) {
890 case VREG:
891 nfsstats.read_bios++;
892 error = nfs_readrpc(vp, uiop);
893 if (!error && uiop->uio_resid) {
894 int diff, len;
895
896 /*
897 * If len > 0, there is a hole in the file and
898 * no writes after the hole have been pushed to
899 * the server yet.
900 * Just zero fill the rest of the valid area.
901 */
902
903 diff = bp->b_bcount - uiop->uio_resid;
904 len = np->n_size - ((((off_t)bp->b_blkno) << DEV_BSHIFT)
905 + diff);
906 if (len > 0) {
907 len = MIN(len, uiop->uio_resid);
908 memset((char *)bp->b_data + diff, 0, len);
909 }
910 }
911 if (uiop->uio_procp && (vp->v_flag & VTEXT) &&
912 (((nmp->nm_flag & NFSMNT_NQNFS) &&
913 NQNFS_CKINVALID(vp, np, ND_READ) &&
914 np->n_lrev != np->n_brev) ||
915 (!(nmp->nm_flag & NFSMNT_NQNFS) &&
916 timespeccmp(&np->n_mtime, &np->n_vattr->va_mtime, !=)))) {
917 uprintf("Process killed due to "
918 "text file modification\n");
919 psignal(uiop->uio_procp, SIGKILL);
920 #if 0 /* XXX NJWLWP */
921 uiop->uio_procp->p_holdcnt++;
922 #endif
923 }
924 break;
925 case VLNK:
926 KASSERT(uiop->uio_offset == (off_t)0);
927 nfsstats.readlink_bios++;
928 error = nfs_readlinkrpc(vp, uiop, curproc->p_ucred);
929 break;
930 case VDIR:
931 nfsstats.readdir_bios++;
932 uiop->uio_offset = bp->b_dcookie;
933 if (nmp->nm_flag & NFSMNT_RDIRPLUS) {
934 error = nfs_readdirplusrpc(vp, uiop, curproc->p_ucred);
935 if (error == NFSERR_NOTSUPP)
936 nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
937 }
938 if ((nmp->nm_flag & NFSMNT_RDIRPLUS) == 0)
939 error = nfs_readdirrpc(vp, uiop, curproc->p_ucred);
940 if (!error) {
941 bp->b_dcookie = uiop->uio_offset;
942 }
943 break;
944 default:
945 printf("nfs_doio: type %x unexpected\n", vp->v_type);
946 break;
947 }
948 if (error) {
949 bp->b_flags |= B_ERROR;
950 bp->b_error = error;
951 }
952 return error;
953 }
954
955 /*
956 * nfs_doio for write.
957 */
958 static int
959 nfs_doio_write(bp, uiop)
960 struct buf *bp;
961 struct uio *uiop;
962 {
963 struct vnode *vp = bp->b_vp;
964 struct nfsnode *np = VTONFS(vp);
965 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
966 int iomode;
967 boolean_t stalewriteverf = FALSE;
968 int i, npages = (bp->b_bcount + PAGE_SIZE - 1) >> PAGE_SHIFT;
969 struct vm_page *pgs[npages];
970 boolean_t needcommit = TRUE;
971 boolean_t pageprotected;
972 struct uvm_object *uobj = &vp->v_uobj;
973 int error;
974 off_t off, cnt;
975
976 if ((bp->b_flags & B_ASYNC) != 0 && NFS_ISV3(vp)) {
977 iomode = NFSV3WRITE_UNSTABLE;
978 } else {
979 iomode = NFSV3WRITE_FILESYNC;
980 }
981
982 again:
983 lockmgr(&nmp->nm_writeverflock, LK_SHARED, NULL);
984
985 for (i = 0; i < npages; i++) {
986 pgs[i] = uvm_pageratop((vaddr_t)bp->b_data + (i << PAGE_SHIFT));
987 if (pgs[i]->uobject == uobj &&
988 pgs[i]->offset == uiop->uio_offset + (i << PAGE_SHIFT)) {
989 KASSERT(pgs[i]->flags & PG_BUSY);
990 /*
991 * this page belongs to our object.
992 */
993 simple_lock(&uobj->vmobjlock);
994 if (pgs[i]->flags & (PG_RELEASED|PG_PAGEOUT))
995 iomode = NFSV3WRITE_FILESYNC;
996 if ((pgs[i]->flags & PG_NEEDCOMMIT) == 0)
997 needcommit = FALSE;
998 simple_unlock(&uobj->vmobjlock);
999 } else {
1000 iomode = NFSV3WRITE_FILESYNC;
1001 needcommit = FALSE;
1002 }
1003 }
1004 if (!needcommit && iomode == NFSV3WRITE_UNSTABLE) {
1005 simple_lock(&uobj->vmobjlock);
1006 for (i = 0; i < npages; i++) {
1007 pgs[i]->flags |= PG_NEEDCOMMIT | PG_RDONLY;
1008 pmap_page_protect(pgs[i], VM_PROT_READ);
1009 }
1010 simple_unlock(&uobj->vmobjlock);
1011 pageprotected = TRUE; /* pages can't be modified during i/o. */
1012 } else
1013 pageprotected = FALSE;
1014
1015 /*
1016 * Send the data to the server if necessary,
1017 * otherwise just send a commit rpc.
1018 */
1019
1020 if (needcommit) {
1021
1022 /*
1023 * If the buffer is in the range that we already committed,
1024 * there's nothing to do.
1025 *
1026 * If it's in the range that we need to commit, push the
1027 * whole range at once, otherwise only push the buffer.
1028 * In both these cases, acquire the commit lock to avoid
1029 * other processes modifying the range.
1030 */
1031
1032 off = uiop->uio_offset;
1033 cnt = bp->b_bcount;
1034 lockmgr(&np->n_commitlock, LK_EXCLUSIVE, NULL);
1035 if (!nfs_in_committed_range(vp, off, bp->b_bcount)) {
1036 boolean_t pushedrange;
1037 if (nfs_in_tobecommitted_range(vp, off, bp->b_bcount)) {
1038 pushedrange = TRUE;
1039 off = np->n_pushlo;
1040 cnt = np->n_pushhi - np->n_pushlo;
1041 } else {
1042 pushedrange = FALSE;
1043 }
1044 error = nfs_commit(vp, off, cnt, curproc);
1045 if (error == 0) {
1046 if (pushedrange) {
1047 nfs_merge_commit_ranges(vp);
1048 } else {
1049 nfs_add_committed_range(vp, off, cnt);
1050 }
1051 }
1052 } else {
1053 error = 0;
1054 }
1055 lockmgr(&np->n_commitlock, LK_RELEASE, NULL);
1056 lockmgr(&nmp->nm_writeverflock, LK_RELEASE, NULL);
1057 if (!error) {
1058 /*
1059 * pages are now on stable storage.
1060 */
1061 uiop->uio_resid = 0;
1062 simple_lock(&uobj->vmobjlock);
1063 for (i = 0; i < npages; i++) {
1064 pgs[i]->flags &= ~(PG_NEEDCOMMIT | PG_RDONLY);
1065 }
1066 simple_unlock(&uobj->vmobjlock);
1067 return 0;
1068 } else if (error == NFSERR_STALEWRITEVERF) {
1069 nfs_clearcommit(vp->v_mount);
1070 goto again;
1071 }
1072 if (error) {
1073 bp->b_flags |= B_ERROR;
1074 bp->b_error = np->n_error = error;
1075 np->n_flag |= NWRITEERR;
1076 }
1077 return error;
1078 }
1079 off = uiop->uio_offset;
1080 cnt = bp->b_bcount;
1081 uiop->uio_rw = UIO_WRITE;
1082 nfsstats.write_bios++;
1083 error = nfs_writerpc(vp, uiop, &iomode, pageprotected, &stalewriteverf);
1084 if (!error && iomode == NFSV3WRITE_UNSTABLE) {
1085 /*
1086 * we need to commit pages later.
1087 */
1088 lockmgr(&np->n_commitlock, LK_EXCLUSIVE, NULL);
1089 nfs_add_tobecommitted_range(vp, off, cnt);
1090 /*
1091 * if there can be too many uncommitted pages, commit them now.
1092 */
1093 if (np->n_pushhi - np->n_pushlo > nfs_commitsize) {
1094 off = np->n_pushlo;
1095 cnt = nfs_commitsize >> 1;
1096 error = nfs_commit(vp, off, cnt, curproc);
1097 if (!error) {
1098 nfs_add_committed_range(vp, off, cnt);
1099 nfs_del_tobecommitted_range(vp, off, cnt);
1100 }
1101 if (error == NFSERR_STALEWRITEVERF) {
1102 stalewriteverf = TRUE;
1103 error = 0; /* it isn't a real error */
1104 }
1105 } else {
1106 /*
1107 * re-dirty pages so that they will be passed
1108 * to us later again.
1109 */
1110 simple_lock(&uobj->vmobjlock);
1111 for (i = 0; i < npages; i++) {
1112 pgs[i]->flags &= ~PG_CLEAN;
1113 }
1114 simple_unlock(&uobj->vmobjlock);
1115 }
1116 lockmgr(&np->n_commitlock, LK_RELEASE, NULL);
1117 } else if (!error) {
1118 /*
1119 * pages are now on stable storage.
1120 */
1121 lockmgr(&np->n_commitlock, LK_EXCLUSIVE, NULL);
1122 nfs_del_committed_range(vp, off, cnt);
1123 lockmgr(&np->n_commitlock, LK_RELEASE, NULL);
1124 simple_lock(&uobj->vmobjlock);
1125 for (i = 0; i < npages; i++) {
1126 pgs[i]->flags &= ~(PG_NEEDCOMMIT | PG_RDONLY);
1127 }
1128 simple_unlock(&uobj->vmobjlock);
1129 } else {
1130 /*
1131 * we got an error.
1132 */
1133 bp->b_flags |= B_ERROR;
1134 bp->b_error = np->n_error = error;
1135 np->n_flag |= NWRITEERR;
1136 }
1137
1138 lockmgr(&nmp->nm_writeverflock, LK_RELEASE, NULL);
1139
1140 if (stalewriteverf) {
1141 nfs_clearcommit(vp->v_mount);
1142 }
1143 return error;
1144 }
1145
1146 /*
1147 * nfs_doio for B_PHYS.
1148 */
1149 static int
1150 nfs_doio_phys(bp, uiop)
1151 struct buf *bp;
1152 struct uio *uiop;
1153 {
1154 struct vnode *vp = bp->b_vp;
1155 int error;
1156
1157 uiop->uio_offset = ((off_t)bp->b_blkno) << DEV_BSHIFT;
1158 if (bp->b_flags & B_READ) {
1159 uiop->uio_rw = UIO_READ;
1160 nfsstats.read_physios++;
1161 error = nfs_readrpc(vp, uiop);
1162 } else {
1163 int iomode = NFSV3WRITE_DATASYNC;
1164 boolean_t stalewriteverf;
1165 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
1166
1167 uiop->uio_rw = UIO_WRITE;
1168 nfsstats.write_physios++;
1169 lockmgr(&nmp->nm_writeverflock, LK_SHARED, NULL);
1170 error = nfs_writerpc(vp, uiop, &iomode, FALSE, &stalewriteverf);
1171 lockmgr(&nmp->nm_writeverflock, LK_RELEASE, NULL);
1172 if (stalewriteverf) {
1173 nfs_clearcommit(bp->b_vp->v_mount);
1174 }
1175 }
1176 if (error) {
1177 bp->b_flags |= B_ERROR;
1178 bp->b_error = error;
1179 }
1180 return error;
1181 }
1182
1183 /*
1184 * Do an I/O operation to/from a cache block. This may be called
1185 * synchronously or from an nfsiod.
1186 */
1187 int
1188 nfs_doio(bp, p)
1189 struct buf *bp;
1190 struct proc *p;
1191 {
1192 int error;
1193 struct uio uio;
1194 struct uio *uiop = &uio;
1195 struct iovec io;
1196 UVMHIST_FUNC("nfs_doio"); UVMHIST_CALLED(ubchist);
1197
1198 uiop->uio_iov = &io;
1199 uiop->uio_iovcnt = 1;
1200 uiop->uio_segflg = UIO_SYSSPACE;
1201 uiop->uio_procp = p;
1202 uiop->uio_offset = (((off_t)bp->b_blkno) << DEV_BSHIFT);
1203 io.iov_base = bp->b_data;
1204 io.iov_len = uiop->uio_resid = bp->b_bcount;
1205
1206 /*
1207 * Historically, paging was done with physio, but no more...
1208 */
1209 if (bp->b_flags & B_PHYS) {
1210 /*
1211 * ...though reading /dev/drum still gets us here.
1212 */
1213 error = nfs_doio_phys(bp, uiop);
1214 } else if (bp->b_flags & B_READ) {
1215 error = nfs_doio_read(bp, uiop);
1216 } else {
1217 error = nfs_doio_write(bp, uiop);
1218 }
1219 bp->b_resid = uiop->uio_resid;
1220 biodone(bp);
1221 return (error);
1222 }
1223
1224 /*
1225 * Vnode op for VM getpages.
1226 */
1227
1228 int
1229 nfs_getpages(v)
1230 void *v;
1231 {
1232 struct vop_getpages_args /* {
1233 struct vnode *a_vp;
1234 voff_t a_offset;
1235 struct vm_page **a_m;
1236 int *a_count;
1237 int a_centeridx;
1238 vm_prot_t a_access_type;
1239 int a_advice;
1240 int a_flags;
1241 } */ *ap = v;
1242
1243 struct vnode *vp = ap->a_vp;
1244 struct uvm_object *uobj = &vp->v_uobj;
1245 struct nfsnode *np = VTONFS(vp);
1246 const int npages = *ap->a_count;
1247 struct vm_page *pg, **pgs, *opgs[npages];
1248 off_t origoffset, len;
1249 int i, error;
1250 boolean_t v3 = NFS_ISV3(vp);
1251 boolean_t write = (ap->a_access_type & VM_PROT_WRITE) != 0;
1252 boolean_t locked = (ap->a_flags & PGO_LOCKED) != 0;
1253
1254 /*
1255 * call the genfs code to get the pages. `pgs' may be NULL
1256 * when doing read-ahead.
1257 */
1258
1259 pgs = ap->a_m;
1260 if (write && locked && v3) {
1261 KASSERT(pgs != NULL);
1262 #ifdef DEBUG
1263
1264 /*
1265 * If PGO_LOCKED is set, real pages shouldn't exists
1266 * in the array.
1267 */
1268
1269 for (i = 0; i < npages; i++)
1270 KDASSERT(pgs[i] == NULL || pgs[i] == PGO_DONTCARE);
1271 #endif
1272 memcpy(opgs, pgs, npages * sizeof(struct vm_pages *));
1273 }
1274 error = genfs_getpages(v);
1275 if (error) {
1276 return (error);
1277 }
1278
1279 /*
1280 * for read faults where the nfs node is not yet marked NMODIFIED,
1281 * set PG_RDONLY on the pages so that we come back here if someone
1282 * tries to modify later via the mapping that will be entered for
1283 * this fault.
1284 */
1285
1286 if (!write && (np->n_flag & NMODIFIED) == 0 && pgs != NULL) {
1287 if (!locked) {
1288 simple_lock(&uobj->vmobjlock);
1289 }
1290 for (i = 0; i < npages; i++) {
1291 pg = pgs[i];
1292 if (pg == NULL || pg == PGO_DONTCARE) {
1293 continue;
1294 }
1295 pg->flags |= PG_RDONLY;
1296 }
1297 if (!locked) {
1298 simple_unlock(&uobj->vmobjlock);
1299 }
1300 }
1301 if (!write) {
1302 return (0);
1303 }
1304
1305 /*
1306 * this is a write fault, update the commit info.
1307 */
1308
1309 origoffset = ap->a_offset;
1310 len = npages << PAGE_SHIFT;
1311
1312 if (v3) {
1313 error = lockmgr(&np->n_commitlock,
1314 LK_EXCLUSIVE | (locked ? LK_NOWAIT : 0), NULL);
1315 if (error) {
1316 KASSERT(locked != 0);
1317
1318 /*
1319 * Since PGO_LOCKED is set, we need to unbusy
1320 * all pages fetched by genfs_getpages() above,
1321 * tell the caller that there are no pages
1322 * available and put back original pgs array.
1323 */
1324
1325 uvm_lock_pageq();
1326 uvm_page_unbusy(pgs, npages);
1327 uvm_unlock_pageq();
1328 *ap->a_count = 0;
1329 memcpy(pgs, opgs,
1330 npages * sizeof(struct vm_pages *));
1331 return (error);
1332 }
1333 nfs_del_committed_range(vp, origoffset, len);
1334 nfs_del_tobecommitted_range(vp, origoffset, len);
1335 }
1336 np->n_flag |= NMODIFIED;
1337 if (!locked) {
1338 simple_lock(&uobj->vmobjlock);
1339 }
1340 for (i = 0; i < npages; i++) {
1341 pg = pgs[i];
1342 if (pg == NULL || pg == PGO_DONTCARE) {
1343 continue;
1344 }
1345 pg->flags &= ~(PG_NEEDCOMMIT | PG_RDONLY);
1346 }
1347 if (!locked) {
1348 simple_unlock(&uobj->vmobjlock);
1349 }
1350 if (v3) {
1351 lockmgr(&np->n_commitlock, LK_RELEASE, NULL);
1352 }
1353 return (0);
1354 }
1355