1 /* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rick Macklem at The University of Guelph. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)nfs_bio.c 8.8 (Berkeley) 01/09/95 11 */ 12 13 #include <sys/param.h> 14 #include <sys/systm.h> 15 #include <sys/resourcevar.h> 16 #include <sys/proc.h> 17 #include <sys/buf.h> 18 #include <sys/vnode.h> 19 #include <sys/trace.h> 20 #include <sys/mount.h> 21 #include <sys/kernel.h> 22 23 #include <vm/vm.h> 24 25 #include <nfs/nfsnode.h> 26 #include <nfs/rpcv2.h> 27 #include <nfs/nfsv2.h> 28 #include <nfs/nfs.h> 29 #include <nfs/nfsmount.h> 30 #include <nfs/nqnfs.h> 31 32 struct buf *incore(), *nfs_getcacheblk(); 33 extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; 34 extern int nfs_numasync; 35 36 /* 37 * Vnode op for read using bio 38 * Any similarity to readip() is purely coincidental 39 */ 40 nfs_bioread(vp, uio, ioflag, cred) 41 register struct vnode *vp; 42 register struct uio *uio; 43 int ioflag; 44 struct ucred *cred; 45 { 46 register struct nfsnode *np = VTONFS(vp); 47 register int biosize, diff; 48 struct buf *bp, *rabp; 49 struct vattr vattr; 50 struct proc *p; 51 struct nfsmount *nmp; 52 daddr_t lbn, bn, rabn; 53 caddr_t baddr; 54 int got_buf, nra, error = 0, n, on, not_readin; 55 56 #ifdef lint 57 ioflag = ioflag; 58 #endif /* lint */ 59 #ifdef DIAGNOSTIC 60 if (uio->uio_rw != UIO_READ) 61 panic("nfs_read mode"); 62 #endif 63 if (uio->uio_resid == 0) 64 return (0); 65 if (uio->uio_offset < 0 && vp->v_type != VDIR) 66 return (EINVAL); 67 nmp = VFSTONFS(vp->v_mount); 68 biosize = nmp->nm_rsize; 69 p = uio->uio_procp; 70 /* 71 * For nfs, cache consistency can only be maintained approximately. 72 * Although RFC1094 does not specify the criteria, the following is 73 * believed to be compatible with the reference port. 74 * For nqnfs, full cache consistency is maintained within the loop. 75 * For nfs: 76 * If the file's modify time on the server has changed since the 77 * last read rpc or you have written to the file, 78 * you may have lost data cache consistency with the 79 * server, so flush all of the file's data out of the cache. 80 * Then force a getattr rpc to ensure that you have up to date 81 * attributes. 82 * The mount flag NFSMNT_MYWRITE says "Assume that my writes are 83 * the ones changing the modify time. 84 * NB: This implies that cache data can be read when up to 85 * NFS_ATTRTIMEO seconds out of date. If you find that you need current 86 * attributes this could be forced by setting n_attrstamp to 0 before 87 * the VOP_GETATTR() call. 88 */ 89 if ((nmp->nm_flag & NFSMNT_NQNFS) == 0 && vp->v_type != VLNK) { 90 if (np->n_flag & NMODIFIED) { 91 if ((nmp->nm_flag & NFSMNT_MYWRITE) == 0 || 92 vp->v_type != VREG) { 93 if (error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1)) 94 return (error); 95 } 96 np->n_attrstamp = 0; 97 np->n_direofoffset = 0; 98 if (error = VOP_GETATTR(vp, &vattr, cred, p)) 99 return (error); 100 np->n_mtime = vattr.va_mtime.ts_sec; 101 } else { 102 if (error = VOP_GETATTR(vp, &vattr, cred, p)) 103 return (error); 104 if (np->n_mtime != vattr.va_mtime.ts_sec) { 105 np->n_direofoffset = 0; 106 if (error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1)) 107 return (error); 108 np->n_mtime = vattr.va_mtime.ts_sec; 109 } 110 } 111 } 112 do { 113 114 /* 115 * Get a valid lease. If cached data is stale, flush it. 116 */ 117 if (nmp->nm_flag & NFSMNT_NQNFS) { 118 if (NQNFS_CKINVALID(vp, np, NQL_READ)) { 119 do { 120 error = nqnfs_getlease(vp, NQL_READ, cred, p); 121 } while (error == NQNFS_EXPIRED); 122 if (error) 123 return (error); 124 if (np->n_lrev != np->n_brev || 125 (np->n_flag & NQNFSNONCACHE) || 126 ((np->n_flag & NMODIFIED) && vp->v_type == VDIR)) { 127 if (vp->v_type == VDIR) { 128 np->n_direofoffset = 0; 129 cache_purge(vp); 130 } 131 if (error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1)) 132 return (error); 133 np->n_brev = np->n_lrev; 134 } 135 } else if (vp->v_type == VDIR && (np->n_flag & NMODIFIED)) { 136 np->n_direofoffset = 0; 137 cache_purge(vp); 138 if (error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1)) 139 return (error); 140 } 141 } 142 if (np->n_flag & NQNFSNONCACHE) { 143 switch (vp->v_type) { 144 case VREG: 145 error = nfs_readrpc(vp, uio, cred); 146 break; 147 case VLNK: 148 error = nfs_readlinkrpc(vp, uio, cred); 149 break; 150 case VDIR: 151 error = nfs_readdirrpc(vp, uio, cred); 152 break; 153 }; 154 return (error); 155 } 156 baddr = (caddr_t)0; 157 switch (vp->v_type) { 158 case VREG: 159 nfsstats.biocache_reads++; 160 lbn = uio->uio_offset / biosize; 161 on = uio->uio_offset & (biosize-1); 162 bn = lbn * (biosize / DEV_BSIZE); 163 not_readin = 1; 164 165 /* 166 * Start the read ahead(s), as required. 167 */ 168 if (nfs_numasync > 0 && nmp->nm_readahead > 0 && 169 lbn == vp->v_lastr + 1) { 170 for (nra = 0; nra < nmp->nm_readahead && 171 (lbn + 1 + nra) * biosize < np->n_size; nra++) { 172 rabn = (lbn + 1 + nra) * (biosize / DEV_BSIZE); 173 if (!incore(vp, rabn)) { 174 rabp = nfs_getcacheblk(vp, rabn, biosize, p); 175 if (!rabp) 176 return (EINTR); 177 if ((rabp->b_flags & (B_DELWRI | B_DONE)) == 0) { 178 rabp->b_flags |= (B_READ | B_ASYNC); 179 if (nfs_asyncio(rabp, cred)) { 180 rabp->b_flags |= B_INVAL; 181 brelse(rabp); 182 } 183 } else 184 brelse(rabp); 185 } 186 } 187 } 188 189 /* 190 * If the block is in the cache and has the required data 191 * in a valid region, just copy it out. 192 * Otherwise, get the block and write back/read in, 193 * as required. 194 */ 195 if ((bp = incore(vp, bn)) && 196 (bp->b_flags & (B_BUSY | B_WRITEINPROG)) == 197 (B_BUSY | B_WRITEINPROG)) 198 got_buf = 0; 199 else { 200 again: 201 bp = nfs_getcacheblk(vp, bn, biosize, p); 202 if (!bp) 203 return (EINTR); 204 got_buf = 1; 205 if ((bp->b_flags & (B_DONE | B_DELWRI)) == 0) { 206 bp->b_flags |= B_READ; 207 not_readin = 0; 208 if (error = nfs_doio(bp, cred, p)) { 209 brelse(bp); 210 return (error); 211 } 212 } 213 } 214 n = min((unsigned)(biosize - on), uio->uio_resid); 215 diff = np->n_size - uio->uio_offset; 216 if (diff < n) 217 n = diff; 218 if (not_readin && n > 0) { 219 if (on < bp->b_validoff || (on + n) > bp->b_validend) { 220 if (!got_buf) { 221 bp = nfs_getcacheblk(vp, bn, biosize, p); 222 if (!bp) 223 return (EINTR); 224 got_buf = 1; 225 } 226 bp->b_flags |= B_INVAL; 227 if (bp->b_dirtyend > 0) { 228 if ((bp->b_flags & B_DELWRI) == 0) 229 panic("nfsbioread"); 230 if (VOP_BWRITE(bp) == EINTR) 231 return (EINTR); 232 } else 233 brelse(bp); 234 goto again; 235 } 236 } 237 vp->v_lastr = lbn; 238 diff = (on >= bp->b_validend) ? 0 : (bp->b_validend - on); 239 if (diff < n) 240 n = diff; 241 break; 242 case VLNK: 243 nfsstats.biocache_readlinks++; 244 bp = nfs_getcacheblk(vp, (daddr_t)0, NFS_MAXPATHLEN, p); 245 if (!bp) 246 return (EINTR); 247 if ((bp->b_flags & B_DONE) == 0) { 248 bp->b_flags |= B_READ; 249 if (error = nfs_doio(bp, cred, p)) { 250 brelse(bp); 251 return (error); 252 } 253 } 254 n = min(uio->uio_resid, NFS_MAXPATHLEN - bp->b_resid); 255 got_buf = 1; 256 on = 0; 257 break; 258 case VDIR: 259 nfsstats.biocache_readdirs++; 260 bn = (daddr_t)uio->uio_offset; 261 bp = nfs_getcacheblk(vp, bn, NFS_DIRBLKSIZ, p); 262 if (!bp) 263 return (EINTR); 264 if ((bp->b_flags & B_DONE) == 0) { 265 bp->b_flags |= B_READ; 266 if (error = nfs_doio(bp, cred, p)) { 267 brelse(bp); 268 return (error); 269 } 270 } 271 272 /* 273 * If not eof and read aheads are enabled, start one. 274 * (You need the current block first, so that you have the 275 * directory offset cookie of the next block. 276 */ 277 rabn = bp->b_blkno; 278 if (nfs_numasync > 0 && nmp->nm_readahead > 0 && 279 rabn != 0 && rabn != np->n_direofoffset && 280 !incore(vp, rabn)) { 281 rabp = nfs_getcacheblk(vp, rabn, NFS_DIRBLKSIZ, p); 282 if (rabp) { 283 if ((rabp->b_flags & (B_DONE | B_DELWRI)) == 0) { 284 rabp->b_flags |= (B_READ | B_ASYNC); 285 if (nfs_asyncio(rabp, cred)) { 286 rabp->b_flags |= B_INVAL; 287 brelse(rabp); 288 } 289 } else 290 brelse(rabp); 291 } 292 } 293 on = 0; 294 n = min(uio->uio_resid, NFS_DIRBLKSIZ - bp->b_resid); 295 got_buf = 1; 296 break; 297 }; 298 299 if (n > 0) { 300 if (!baddr) 301 baddr = bp->b_data; 302 error = uiomove(baddr + on, (int)n, uio); 303 } 304 switch (vp->v_type) { 305 case VREG: 306 if (n + on == biosize || uio->uio_offset == np->n_size) 307 bp->b_flags |= B_AGE; 308 break; 309 case VLNK: 310 n = 0; 311 break; 312 case VDIR: 313 uio->uio_offset = bp->b_blkno; 314 break; 315 }; 316 if (got_buf) 317 brelse(bp); 318 } while (error == 0 && uio->uio_resid > 0 && n > 0); 319 return (error); 320 } 321 322 /* 323 * Vnode op for write using bio 324 */ 325 nfs_write(ap) 326 struct vop_write_args /* { 327 struct vnode *a_vp; 328 struct uio *a_uio; 329 int a_ioflag; 330 struct ucred *a_cred; 331 } */ *ap; 332 { 333 register int biosize; 334 register struct uio *uio = ap->a_uio; 335 struct proc *p = uio->uio_procp; 336 register struct vnode *vp = ap->a_vp; 337 struct nfsnode *np = VTONFS(vp); 338 register struct ucred *cred = ap->a_cred; 339 int ioflag = ap->a_ioflag; 340 struct buf *bp; 341 struct vattr vattr; 342 struct nfsmount *nmp; 343 daddr_t lbn, bn; 344 int n, on, error = 0; 345 346 #ifdef DIAGNOSTIC 347 if (uio->uio_rw != UIO_WRITE) 348 panic("nfs_write mode"); 349 if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc) 350 panic("nfs_write proc"); 351 #endif 352 if (vp->v_type != VREG) 353 return (EIO); 354 if (np->n_flag & NWRITEERR) { 355 np->n_flag &= ~NWRITEERR; 356 return (np->n_error); 357 } 358 if (ioflag & (IO_APPEND | IO_SYNC)) { 359 if (np->n_flag & NMODIFIED) { 360 np->n_attrstamp = 0; 361 if (error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1)) 362 return (error); 363 } 364 if (ioflag & IO_APPEND) { 365 np->n_attrstamp = 0; 366 if (error = VOP_GETATTR(vp, &vattr, cred, p)) 367 return (error); 368 uio->uio_offset = np->n_size; 369 } 370 } 371 nmp = VFSTONFS(vp->v_mount); 372 if (uio->uio_offset < 0) 373 return (EINVAL); 374 if (uio->uio_resid == 0) 375 return (0); 376 /* 377 * Maybe this should be above the vnode op call, but so long as 378 * file servers have no limits, i don't think it matters 379 */ 380 if (p && uio->uio_offset + uio->uio_resid > 381 p->p_rlimit[RLIMIT_FSIZE].rlim_cur) { 382 psignal(p, SIGXFSZ); 383 return (EFBIG); 384 } 385 /* 386 * I use nm_rsize, not nm_wsize so that all buffer cache blocks 387 * will be the same size within a filesystem. nfs_writerpc will 388 * still use nm_wsize when sizing the rpc's. 389 */ 390 biosize = nmp->nm_rsize; 391 do { 392 393 /* 394 * XXX make sure we aren't cached in the VM page cache 395 */ 396 (void)vnode_pager_uncache(vp); 397 398 /* 399 * Check for a valid write lease. 400 * If non-cachable, just do the rpc 401 */ 402 if ((nmp->nm_flag & NFSMNT_NQNFS) && 403 NQNFS_CKINVALID(vp, np, NQL_WRITE)) { 404 do { 405 error = nqnfs_getlease(vp, NQL_WRITE, cred, p); 406 } while (error == NQNFS_EXPIRED); 407 if (error) 408 return (error); 409 if (np->n_lrev != np->n_brev || 410 (np->n_flag & NQNFSNONCACHE)) { 411 if (error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1)) 412 return (error); 413 np->n_brev = np->n_lrev; 414 } 415 } 416 if (np->n_flag & NQNFSNONCACHE) 417 return (nfs_writerpc(vp, uio, cred, ioflag)); 418 nfsstats.biocache_writes++; 419 lbn = uio->uio_offset / biosize; 420 on = uio->uio_offset & (biosize-1); 421 n = min((unsigned)(biosize - on), uio->uio_resid); 422 bn = lbn * (biosize / DEV_BSIZE); 423 again: 424 bp = nfs_getcacheblk(vp, bn, biosize, p); 425 if (!bp) 426 return (EINTR); 427 if (bp->b_wcred == NOCRED) { 428 crhold(cred); 429 bp->b_wcred = cred; 430 } 431 np->n_flag |= NMODIFIED; 432 if (uio->uio_offset + n > np->n_size) { 433 np->n_size = uio->uio_offset + n; 434 vnode_pager_setsize(vp, (u_long)np->n_size); 435 } 436 437 /* 438 * If the new write will leave a contiguous dirty 439 * area, just update the b_dirtyoff and b_dirtyend, 440 * otherwise force a write rpc of the old dirty area. 441 */ 442 if (bp->b_dirtyend > 0 && 443 (on > bp->b_dirtyend || (on + n) < bp->b_dirtyoff)) { 444 bp->b_proc = p; 445 if (VOP_BWRITE(bp) == EINTR) 446 return (EINTR); 447 goto again; 448 } 449 450 /* 451 * Check for valid write lease and get one as required. 452 * In case getblk() and/or bwrite() delayed us. 453 */ 454 if ((nmp->nm_flag & NFSMNT_NQNFS) && 455 NQNFS_CKINVALID(vp, np, NQL_WRITE)) { 456 do { 457 error = nqnfs_getlease(vp, NQL_WRITE, cred, p); 458 } while (error == NQNFS_EXPIRED); 459 if (error) { 460 brelse(bp); 461 return (error); 462 } 463 if (np->n_lrev != np->n_brev || 464 (np->n_flag & NQNFSNONCACHE)) { 465 brelse(bp); 466 if (error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1)) 467 return (error); 468 np->n_brev = np->n_lrev; 469 goto again; 470 } 471 } 472 if (error = uiomove((char *)bp->b_data + on, n, uio)) { 473 bp->b_flags |= B_ERROR; 474 brelse(bp); 475 return (error); 476 } 477 if (bp->b_dirtyend > 0) { 478 bp->b_dirtyoff = min(on, bp->b_dirtyoff); 479 bp->b_dirtyend = max((on + n), bp->b_dirtyend); 480 } else { 481 bp->b_dirtyoff = on; 482 bp->b_dirtyend = on + n; 483 } 484 #ifndef notdef 485 if (bp->b_validend == 0 || bp->b_validend < bp->b_dirtyoff || 486 bp->b_validoff > bp->b_dirtyend) { 487 bp->b_validoff = bp->b_dirtyoff; 488 bp->b_validend = bp->b_dirtyend; 489 } else { 490 bp->b_validoff = min(bp->b_validoff, bp->b_dirtyoff); 491 bp->b_validend = max(bp->b_validend, bp->b_dirtyend); 492 } 493 #else 494 bp->b_validoff = bp->b_dirtyoff; 495 bp->b_validend = bp->b_dirtyend; 496 #endif 497 if (ioflag & IO_APPEND) 498 bp->b_flags |= B_APPENDWRITE; 499 500 /* 501 * If the lease is non-cachable or IO_SYNC do bwrite(). 502 */ 503 if ((np->n_flag & NQNFSNONCACHE) || (ioflag & IO_SYNC)) { 504 bp->b_proc = p; 505 if (error = VOP_BWRITE(bp)) 506 return (error); 507 } else if ((n + on) == biosize && 508 (nmp->nm_flag & NFSMNT_NQNFS) == 0) { 509 bp->b_proc = (struct proc *)0; 510 bawrite(bp); 511 } else 512 bdwrite(bp); 513 } while (uio->uio_resid > 0 && n > 0); 514 return (0); 515 } 516 517 /* 518 * Get an nfs cache block. 519 * Allocate a new one if the block isn't currently in the cache 520 * and return the block marked busy. If the calling process is 521 * interrupted by a signal for an interruptible mount point, return 522 * NULL. 523 */ 524 struct buf * 525 nfs_getcacheblk(vp, bn, size, p) 526 struct vnode *vp; 527 daddr_t bn; 528 int size; 529 struct proc *p; 530 { 531 register struct buf *bp; 532 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 533 534 if (nmp->nm_flag & NFSMNT_INT) { 535 bp = getblk(vp, bn, size, PCATCH, 0); 536 while (bp == (struct buf *)0) { 537 if (nfs_sigintr(nmp, (struct nfsreq *)0, p)) 538 return ((struct buf *)0); 539 bp = getblk(vp, bn, size, 0, 2 * hz); 540 } 541 } else 542 bp = getblk(vp, bn, size, 0, 0); 543 return (bp); 544 } 545 546 /* 547 * Flush and invalidate all dirty buffers. If another process is already 548 * doing the flush, just wait for completion. 549 */ 550 nfs_vinvalbuf(vp, flags, cred, p, intrflg) 551 struct vnode *vp; 552 int flags; 553 struct ucred *cred; 554 struct proc *p; 555 int intrflg; 556 { 557 register struct nfsnode *np = VTONFS(vp); 558 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 559 int error = 0, slpflag, slptimeo; 560 561 if ((nmp->nm_flag & NFSMNT_INT) == 0) 562 intrflg = 0; 563 if (intrflg) { 564 slpflag = PCATCH; 565 slptimeo = 2 * hz; 566 } else { 567 slpflag = 0; 568 slptimeo = 0; 569 } 570 /* 571 * First wait for any other process doing a flush to complete. 572 */ 573 while (np->n_flag & NFLUSHINPROG) { 574 np->n_flag |= NFLUSHWANT; 575 error = tsleep((caddr_t)&np->n_flag, PRIBIO + 2, "nfsvinval", 576 slptimeo); 577 if (error && intrflg && nfs_sigintr(nmp, (struct nfsreq *)0, p)) 578 return (EINTR); 579 } 580 581 /* 582 * Now, flush as required. 583 */ 584 np->n_flag |= NFLUSHINPROG; 585 error = vinvalbuf(vp, flags, cred, p, slpflag, 0); 586 while (error) { 587 if (intrflg && nfs_sigintr(nmp, (struct nfsreq *)0, p)) { 588 np->n_flag &= ~NFLUSHINPROG; 589 if (np->n_flag & NFLUSHWANT) { 590 np->n_flag &= ~NFLUSHWANT; 591 wakeup((caddr_t)&np->n_flag); 592 } 593 return (EINTR); 594 } 595 error = vinvalbuf(vp, flags, cred, p, 0, slptimeo); 596 } 597 np->n_flag &= ~(NMODIFIED | NFLUSHINPROG); 598 if (np->n_flag & NFLUSHWANT) { 599 np->n_flag &= ~NFLUSHWANT; 600 wakeup((caddr_t)&np->n_flag); 601 } 602 return (0); 603 } 604 605 /* 606 * Initiate asynchronous I/O. Return an error if no nfsiods are available. 607 * This is mainly to avoid queueing async I/O requests when the nfsiods 608 * are all hung on a dead server. 609 */ 610 nfs_asyncio(bp, cred) 611 register struct buf *bp; 612 struct ucred *cred; 613 { 614 register int i; 615 616 if (nfs_numasync == 0) 617 return (EIO); 618 for (i = 0; i < NFS_MAXASYNCDAEMON; i++) 619 if (nfs_iodwant[i]) { 620 if (bp->b_flags & B_READ) { 621 if (bp->b_rcred == NOCRED && cred != NOCRED) { 622 crhold(cred); 623 bp->b_rcred = cred; 624 } 625 } else { 626 if (bp->b_wcred == NOCRED && cred != NOCRED) { 627 crhold(cred); 628 bp->b_wcred = cred; 629 } 630 } 631 632 TAILQ_INSERT_TAIL(&nfs_bufq, bp, b_freelist); 633 nfs_iodwant[i] = (struct proc *)0; 634 wakeup((caddr_t)&nfs_iodwant[i]); 635 return (0); 636 } 637 return (EIO); 638 } 639 640 /* 641 * Do an I/O operation to/from a cache block. This may be called 642 * synchronously or from an nfsiod. 643 */ 644 int 645 nfs_doio(bp, cr, p) 646 register struct buf *bp; 647 struct cred *cr; 648 struct proc *p; 649 { 650 register struct uio *uiop; 651 register struct vnode *vp; 652 struct nfsnode *np; 653 struct nfsmount *nmp; 654 int error, diff, len; 655 struct uio uio; 656 struct iovec io; 657 658 vp = bp->b_vp; 659 np = VTONFS(vp); 660 nmp = VFSTONFS(vp->v_mount); 661 uiop = &uio; 662 uiop->uio_iov = &io; 663 uiop->uio_iovcnt = 1; 664 uiop->uio_segflg = UIO_SYSSPACE; 665 uiop->uio_procp = p; 666 667 /* 668 * Historically, paging was done with physio, but no more. 669 */ 670 if (bp->b_flags & B_PHYS) 671 panic("doio phys"); 672 if (bp->b_flags & B_READ) { 673 io.iov_len = uiop->uio_resid = bp->b_bcount; 674 io.iov_base = bp->b_data; 675 uiop->uio_rw = UIO_READ; 676 switch (vp->v_type) { 677 case VREG: 678 uiop->uio_offset = bp->b_blkno * DEV_BSIZE; 679 nfsstats.read_bios++; 680 error = nfs_readrpc(vp, uiop, cr); 681 if (!error) { 682 bp->b_validoff = 0; 683 if (uiop->uio_resid) { 684 /* 685 * If len > 0, there is a hole in the file and 686 * no writes after the hole have been pushed to 687 * the server yet. 688 * Just zero fill the rest of the valid area. 689 */ 690 diff = bp->b_bcount - uiop->uio_resid; 691 len = np->n_size - (bp->b_blkno * DEV_BSIZE 692 + diff); 693 if (len > 0) { 694 len = min(len, uiop->uio_resid); 695 bzero((char *)bp->b_data + diff, len); 696 bp->b_validend = diff + len; 697 } else 698 bp->b_validend = diff; 699 } else 700 bp->b_validend = bp->b_bcount; 701 } 702 if (p && (vp->v_flag & VTEXT) && 703 (((nmp->nm_flag & NFSMNT_NQNFS) && 704 NQNFS_CKINVALID(vp, np, NQL_READ) && 705 np->n_lrev != np->n_brev) || 706 (!(nmp->nm_flag & NFSMNT_NQNFS) && 707 np->n_mtime != np->n_vattr.va_mtime.ts_sec))) { 708 uprintf("Process killed due to text file modification\n"); 709 psignal(p, SIGKILL); 710 p->p_flag |= P_NOSWAP; 711 } 712 break; 713 case VLNK: 714 uiop->uio_offset = 0; 715 nfsstats.readlink_bios++; 716 error = nfs_readlinkrpc(vp, uiop, cr); 717 break; 718 case VDIR: 719 uiop->uio_offset = bp->b_lblkno; 720 nfsstats.readdir_bios++; 721 if (VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) 722 error = nfs_readdirlookrpc(vp, uiop, cr); 723 else 724 error = nfs_readdirrpc(vp, uiop, cr); 725 /* 726 * Save offset cookie in b_blkno. 727 */ 728 bp->b_blkno = uiop->uio_offset; 729 break; 730 }; 731 if (error) { 732 bp->b_flags |= B_ERROR; 733 bp->b_error = error; 734 } 735 } else { 736 io.iov_len = uiop->uio_resid = bp->b_dirtyend 737 - bp->b_dirtyoff; 738 uiop->uio_offset = (bp->b_blkno * DEV_BSIZE) 739 + bp->b_dirtyoff; 740 io.iov_base = (char *)bp->b_data + bp->b_dirtyoff; 741 uiop->uio_rw = UIO_WRITE; 742 nfsstats.write_bios++; 743 if (bp->b_flags & B_APPENDWRITE) 744 error = nfs_writerpc(vp, uiop, cr, IO_APPEND); 745 else 746 error = nfs_writerpc(vp, uiop, cr, 0); 747 bp->b_flags &= ~(B_WRITEINPROG | B_APPENDWRITE); 748 749 /* 750 * For an interrupted write, the buffer is still valid and the 751 * write hasn't been pushed to the server yet, so we can't set 752 * B_ERROR and report the interruption by setting B_EINTR. For 753 * the B_ASYNC case, B_EINTR is not relevant, so the rpc attempt 754 * is essentially a noop. 755 */ 756 if (error == EINTR) { 757 bp->b_flags &= ~B_INVAL; 758 bp->b_flags |= B_DELWRI; 759 760 /* 761 * Since for the B_ASYNC case, nfs_bwrite() has reassigned the 762 * buffer to the clean list, we have to reassign it back to the 763 * dirty one. Ugh. 764 */ 765 if (bp->b_flags & B_ASYNC) 766 reassignbuf(bp, vp); 767 else 768 bp->b_flags |= B_EINTR; 769 } else { 770 if (error) { 771 bp->b_flags |= B_ERROR; 772 bp->b_error = np->n_error = error; 773 np->n_flag |= NWRITEERR; 774 } 775 bp->b_dirtyoff = bp->b_dirtyend = 0; 776 } 777 } 778 bp->b_resid = uiop->uio_resid; 779 biodone(bp); 780 return (error); 781 } 782