Deleted Added
full compact
1/*
2 * Copyright (c) 1994,1997 John S. Dyson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice immediately at the beginning of the file, without modification,
10 * this list of conditions, and the following disclaimer.
11 * 2. Absolutely no warranty of function or purpose is made by the author
12 * John S. Dyson.
13 *
14 * $Id: vfs_bio.c,v 1.157 1998/03/17 08:41:28 kato Exp $
14 * $Id: vfs_bio.c,v 1.158 1998/03/17 17:36:05 dyson Exp $
15 */
16
17/*
18 * this file contains a new buffer I/O scheme implementing a coherent
19 * VM object and buffer cache scheme. Pains have been taken to make
20 * sure that the performance degradation associated with schemes such
21 * as this is not realized.
22 *

--- 155 unchanged lines hidden (view full) ---

178 bp = &buf[i];
179 bzero(bp, sizeof *bp);
180 bp->b_flags = B_INVAL; /* we're just an empty header */
181 bp->b_dev = NODEV;
182 bp->b_rcred = NOCRED;
183 bp->b_wcred = NOCRED;
184 bp->b_qindex = QUEUE_EMPTY;
185 bp->b_vnbufs.le_next = NOLIST;
186 bp->b_generation = 0;
186 LIST_INIT(&bp->b_dep);
187 TAILQ_INSERT_TAIL(&bufqueues[QUEUE_EMPTY], bp, b_freelist);
188 LIST_INSERT_HEAD(&invalhash, bp, b_hash);
189 }
190/*
191 * maxbufspace is currently calculated to support all filesystem blocks
192 * to be 8K. If you happen to use a 16K filesystem, the size of the buffer
193 * cache is still the same as it would be for 8K filesystems. This

--- 167 unchanged lines hidden (view full) ---

361
362/*
363 * Write, release buffer on completion. (Done by iodone
364 * if async.)
365 */
366int
367bwrite(struct buf * bp)
368{
370 int oldflags = bp->b_flags;
369 int oldflags;
370 struct vnode *vp;
371 struct mount *mp;
372
373
374 if (bp->b_flags & B_INVAL) {
375 brelse(bp);
376 return (0);
377 }
378
379 oldflags = bp->b_flags;
380
381#if !defined(MAX_PERF)
380 if (!(bp->b_flags & B_BUSY))
382 if ((bp->b_flags & B_BUSY) == 0)
383 panic("bwrite: buffer is not busy???");
384#endif
385
386 bp->b_flags &= ~(B_READ | B_DONE | B_ERROR | B_DELWRI);
387 bp->b_flags |= B_WRITEINPROG;
388
389 if ((oldflags & B_DELWRI) == B_DELWRI) {
390 --numdirtybuffers;

--- 20 unchanged lines hidden (view full) ---

411 if ((oldflags & B_ASYNC) == 0)
412 mp->mnt_stat.f_syncwrites++;
413 else
414 mp->mnt_stat.f_asyncwrites++;
415 }
416
417 if ((oldflags & B_ASYNC) == 0) {
418 int rtval = biowait(bp);
417
418 if (oldflags & B_DELWRI) {
419 reassignbuf(bp, bp->b_vp);
420 }
419 brelse(bp);
420 return (rtval);
421 }
422 return (0);
423}
424
425inline void
426vfs_bio_need_satisfy(void) {

--- 32 unchanged lines hidden (view full) ---

459 }
460 if (bp->b_flags & B_TAPE) {
461 bawrite(bp);
462 return;
463 }
464 bp->b_flags &= ~(B_READ|B_RELBUF);
465 if ((bp->b_flags & B_DELWRI) == 0) {
466 bp->b_flags |= B_DONE | B_DELWRI;
469 s = splbio();
467 reassignbuf(bp, bp->b_vp);
471 splx(s);
468 ++numdirtybuffers;
469 }
470
471 /*
472 * This bmap keeps the system from needing to do the bmap later,
473 * perhaps when the system is attempting to do a sync. Since it
474 * is likely that the indirect block -- or whatever other datastructure
475 * that the filesystem needs is still in memory now, it is a good

--- 47 unchanged lines hidden (view full) ---

523bdirty(bp)
524 struct buf *bp;
525{
526 int s;
527
528 bp->b_flags &= ~(B_READ|B_RELBUF); /* XXX ??? check this */
529 if ((bp->b_flags & B_DELWRI) == 0) {
530 bp->b_flags |= B_DONE | B_DELWRI; /* why done? XXX JRE */
535 s = splbio();
531 reassignbuf(bp, bp->b_vp);
537 splx(s);
532 ++numdirtybuffers;
533 }
534}
535
536/*
537 * Asynchronous write.
538 * Start output on a buffer, but do not wait for it to complete.
539 * The buffer is released when the output completes.

--- 101 unchanged lines hidden (view full) ---

641
642 vp = bp->b_vp;
643
644 resid = bp->b_bufsize;
645 foff = bp->b_offset;
646
647 for (i = 0; i < bp->b_npages; i++) {
648 m = bp->b_pages[i];
649 m->flags &= ~PG_ZERO;
650 if (m == bogus_page) {
651
652 obj = (vm_object_t) vp->v_object;
653 poff = OFF_TO_IDX(bp->b_offset);
654
655 for (j = i; j < bp->b_npages; j++) {
656 m = bp->b_pages[j];
657 if (m == bogus_page) {

--- 5 unchanged lines hidden (view full) ---

663#endif
664 bp->b_pages[j] = m;
665 }
666 }
667
668 if ((bp->b_flags & B_INVAL) == 0) {
669 pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages);
670 }
676 break;
671 }
672 if (bp->b_flags & (B_NOCACHE|B_ERROR)) {
673 int poffset = foff & PAGE_MASK;
674 int presid = resid > (PAGE_SIZE - poffset) ?
675 (PAGE_SIZE - poffset) : resid;
676 vm_page_set_invalid(m, poffset, presid);
677 }
678 resid -= PAGE_SIZE;

--- 19 unchanged lines hidden (view full) ---

698 if (bp->b_bufsize == 0) {
699 bp->b_flags |= B_INVAL;
700 bp->b_qindex = QUEUE_EMPTY;
701 TAILQ_INSERT_HEAD(&bufqueues[QUEUE_EMPTY], bp, b_freelist);
702 LIST_REMOVE(bp, b_hash);
703 LIST_INSERT_HEAD(&invalhash, bp, b_hash);
704 bp->b_dev = NODEV;
705 kvafreespace += bp->b_kvasize;
712 bp->b_generation++;
706
707 /* buffers with junk contents */
708 } else if (bp->b_flags & (B_ERROR | B_INVAL | B_NOCACHE | B_RELBUF)) {
709 bp->b_flags |= B_INVAL;
710 bp->b_qindex = QUEUE_AGE;
711 TAILQ_INSERT_HEAD(&bufqueues[QUEUE_AGE], bp, b_freelist);
712 LIST_REMOVE(bp, b_hash);
713 LIST_INSERT_HEAD(&invalhash, bp, b_hash);
714 bp->b_dev = NODEV;
722 bp->b_generation++;
715
716 /* buffers that are locked */
717 } else if (bp->b_flags & B_LOCKED) {
718 bp->b_qindex = QUEUE_LOCKED;
719 TAILQ_INSERT_TAIL(&bufqueues[QUEUE_LOCKED], bp, b_freelist);
720
721 /* buffers with stale but valid contents */
722 } else if (bp->b_flags & B_AGE) {

--- 12 unchanged lines hidden (view full) ---

735 --numdirtybuffers;
736 bp->b_flags &= ~B_DELWRI;
737 }
738 vfs_bio_need_satisfy();
739 }
740
741 /* unlock */
742 bp->b_flags &= ~(B_ORDERED | B_WANTED | B_BUSY |
751 B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF);
743 B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF);
744 splx(s);
745}
746
747/*
748 * Release a buffer.
749 */
750void
751bqrelse(struct buf * bp)

--- 76 unchanged lines hidden (view full) ---

828 vm_page_test_dirty(m);
829 /*
830 * this keeps pressure off of the process memory
831 */
832 if (m->dirty == 0 && m->hold_count == 0)
833 vm_page_cache(m);
834 else
835 vm_page_deactivate(m);
836 m->flags &= ~PG_ZERO;
837 } else if (m->hold_count == 0) {
838 m->flags |= PG_BUSY;
839 vm_page_protect(m, VM_PROT_NONE);
840 vm_page_free(m);
841 }
842 } else {
843 /*
844 * If async, then at least we clear the
845 * act_count.
846 */
847 m->act_count = 0;
848 m->flags &= ~PG_ZERO;
849 }
850 }
851 }
852 bufspace -= bp->b_bufsize;
853 vmiospace -= bp->b_bufsize;
854 pmap_qremove(trunc_page((vm_offset_t) bp->b_data), bp->b_npages);
855 bp->b_npages = 0;
856 bp->b_bufsize = 0;

--- 74 unchanged lines hidden (view full) ---

931 if (ncl != 1) {
932 nwritten = cluster_wbuild(vp, size, lblkno, ncl);
933 splx(s);
934 return nwritten;
935 }
936 }
937
938 bremfree(bp);
939 bp->b_flags |= B_BUSY | B_ASYNC;
940
941 splx(s);
942 /*
943 * default (old) behavior, writing out only one block
944 */
949 bp->b_flags |= B_BUSY | B_ASYNC;
945 nwritten = bp->b_bufsize;
946 (void) VOP_BWRITE(bp);
947 return nwritten;
948}
949
950
951/*
952 * Find a buffer header which is available for use.

--- 158 unchanged lines hidden (view full) ---

1111 bp->b_flags &= ~B_ASYNC;
1112 vfs_vmio_release(bp);
1113 }
1114
1115 if (bp->b_vp)
1116 brelvp(bp);
1117
1118fillbuf:
1124 bp->b_generation++;
1119
1120 /* we are not free, nor do we contain interesting data */
1121 if (bp->b_rcred != NOCRED) {
1122 crfree(bp->b_rcred);
1123 bp->b_rcred = NOCRED;
1124 }
1125 if (bp->b_wcred != NOCRED) {
1126 crfree(bp->b_wcred);

--- 7 unchanged lines hidden (view full) ---

1134 LIST_INSERT_HEAD(&invalhash, bp, b_hash);
1135 if (bp->b_bufsize) {
1136 allocbuf(bp, 0);
1137 }
1138 bp->b_flags = B_BUSY;
1139 bp->b_dev = NODEV;
1140 bp->b_vp = NULL;
1141 bp->b_blkno = bp->b_lblkno = 0;
1148 bp->b_offset = 0;
1142 bp->b_offset = NOOFFSET;
1143 bp->b_iodone = 0;
1144 bp->b_error = 0;
1145 bp->b_resid = 0;
1146 bp->b_bcount = 0;
1147 bp->b_npages = 0;
1148 bp->b_dirtyoff = bp->b_dirtyend = 0;
1149 bp->b_validoff = bp->b_validend = 0;
1150 bp->b_usecount = 5;

--- 197 unchanged lines hidden (view full) ---

1348 * is not cleared simply by protecting pages off.
1349 */
1350 if ((bp->b_flags & B_VMIO) &&
1351 ((object = bp->b_pages[0]->object)->flags & (OBJ_WRITEABLE|OBJ_CLEANING))) {
1352 /*
1353 * test the pages to see if they have been modified directly
1354 * by users through the VM system.
1355 */
1362 for (i = 0; i < bp->b_npages; i++)
1356 for (i = 0; i < bp->b_npages; i++) {
1357 bp->b_pages[i]->flags &= ~PG_ZERO;
1358 vm_page_test_dirty(bp->b_pages[i]);
1359 }
1360
1361 /*
1362 * scan forwards for the first page modified
1363 */
1364 for (i = 0; i < bp->b_npages; i++) {
1365 if (bp->b_pages[i]->dirty) {
1366 break;
1367 }

--- 51 unchanged lines hidden (view full) ---

1419
1420 s = splbio();
1421loop:
1422 if (numfreebuffers < lofreebuffers) {
1423 waitfreebuffers(slpflag, slptimeo);
1424 }
1425
1426 if ((bp = gbincore(vp, blkno))) {
1431 generation = bp->b_generation;
1427loop1:
1428 if (bp->b_flags & B_BUSY) {
1429
1430 bp->b_flags |= B_WANTED;
1431 if (bp->b_usecount < BUF_MAXUSE)
1432 ++bp->b_usecount;
1433
1434 if (!tsleep(bp,
1435 (PRIBIO + 4) | slpflag, "getblk", slptimeo)) {
1441 if (bp->b_generation != generation)
1442 goto loop;
1443 goto loop1;
1436 goto loop;
1437 }
1438
1439 splx(s);
1440 return (struct buf *) NULL;
1441 }
1442 bp->b_flags |= B_BUSY | B_CACHE;
1443 bremfree(bp);
1444
1445 /*
1446 * check for size inconsistancies (note that they shouldn't
1447 * happen but do when filesystems don't handle the size changes
1448 * correctly.) We are conservative on metadata and don't just
1449 * extend the buffer but write (if needed) and re-constitute it.
1450 */
1451
1452 if (bp->b_bcount != size) {
1460 bp->b_generation++;
1453 if ((bp->b_flags & B_VMIO) && (size <= bp->b_kvasize)) {
1454 allocbuf(bp, size);
1455 } else {
1456 if (bp->b_flags & B_DELWRI) {
1457 bp->b_flags |= B_NOCACHE;
1458 VOP_BWRITE(bp);
1459 } else {
1460 if (bp->b_flags & B_VMIO) {
1461 bp->b_flags |= B_RELBUF;
1462 brelse(bp);
1463 } else {
1464 bp->b_flags |= B_NOCACHE;
1465 VOP_BWRITE(bp);
1466 }
1467 }
1468 goto loop;
1469 }
1470 }
1471
1472#ifdef DIAGNOSTIC
1473 if (bp->b_offset == NOOFFSET)
1474 panic("getblk: no buffer offset");
1475#endif
1476
1477 /*
1478 * Check that the constituted buffer really deserves for the
1482 * B_CACHE bit to be set.
1479 * B_CACHE bit to be set. B_VMIO type buffers might not
1480 * contain fully valid pages. Normal (old-style) buffers
1481 * should be fully valid.
1482 */
1484 checksize = bp->b_bufsize;
1485 for (i = 0; i < bp->b_npages; i++) {
1486 int resid;
1487 int poffset;
1488 poffset = bp->b_offset & PAGE_MASK;
1489 resid = (checksize > (PAGE_SIZE - poffset)) ?
1490 (PAGE_SIZE - poffset) : checksize;
1491 if (!vm_page_is_valid(bp->b_pages[i], poffset, resid)) {
1492 bp->b_flags &= ~(B_CACHE | B_DONE);
1493 break;
1483 if (bp->b_flags & B_VMIO) {
1484 checksize = bp->b_bufsize;
1485 for (i = 0; i < bp->b_npages; i++) {
1486 int resid;
1487 int poffset;
1488 poffset = bp->b_offset & PAGE_MASK;
1489 resid = (checksize > (PAGE_SIZE - poffset)) ?
1490 (PAGE_SIZE - poffset) : checksize;
1491 if (!vm_page_is_valid(bp->b_pages[i], poffset, resid)) {
1492 bp->b_flags &= ~(B_CACHE | B_DONE);
1493 break;
1494 }
1495 checksize -= resid;
1496 }
1495 checksize -= resid;
1497 }
1498
1499 if (bp->b_usecount < BUF_MAXUSE)
1500 ++bp->b_usecount;
1501 splx(s);
1502 return (bp);
1503 } else {
1504 vm_object_t obj;

--- 19 unchanged lines hidden (view full) ---

1524 goto loop;
1525 }
1526
1527 /*
1528 * Insert the buffer into the hash, so that it can
1529 * be found by incore.
1530 */
1531 bp->b_blkno = bp->b_lblkno = blkno;
1532
1533 if (vp->v_type != VBLK)
1534 bp->b_offset = (off_t) blkno * maxsize;
1535 else
1536 bp->b_offset = (off_t) blkno * DEV_BSIZE;
1537
1538 bgetvp(vp, bp);
1539 LIST_REMOVE(bp, b_hash);
1540 bh = BUFHASH(vp, blkno);

--- 200 unchanged lines hidden (view full) ---

1741
1742 if (bp->b_npages < desiredpages) {
1743 obj = vp->v_object;
1744 tinc = PAGE_SIZE;
1745 if (tinc > bsize)
1746 tinc = bsize;
1747
1748 off = bp->b_offset;
1749#ifdef DIAGNOSTIC
1750 if (bp->b_offset == NOOFFSET)
1751 panic("allocbuf: no buffer offset");
1752#endif
1753
1754 curbpnpages = bp->b_npages;
1755 doretry:
1756 bp->b_validoff = orig_validoff;
1757 bp->b_validend = orig_validend;
1758 bp->b_flags |= B_CACHE;
1759 for (toff = 0; toff < newbsize; toff += tinc) {
1760 int bytesinpage;
1761

--- 41 unchanged lines hidden (view full) ---

1803 (cnt.v_free_min + cnt.v_cache_min))) {
1804 pagedaemon_wakeup();
1805 }
1806 bytesinpage = tinc;
1807 if (tinc > (newbsize - toff))
1808 bytesinpage = newbsize - toff;
1809 if (bp->b_flags & B_CACHE)
1810 vfs_buf_set_valid(bp, off, toff, bytesinpage, m);
1811 m->flags &= ~PG_ZERO;
1812 vm_page_wire(m);
1813 }
1814 bp->b_pages[pageindex] = m;
1815 curbpnpages = pageindex + 1;
1816 }
1817 if (vp->v_tag == VT_NFS &&
1818 vp->v_type != VBLK) {
1819 if (bp->b_dirtyend > 0) {

--- 73 unchanged lines hidden (view full) ---

1893#endif
1894 return;
1895 }
1896 bp->b_flags |= B_DONE;
1897
1898 if ((bp->b_flags & B_READ) == 0) {
1899 vwakeup(bp);
1900 }
1901
1902#ifdef BOUNCE_BUFFERS
1894 if (bp->b_flags & B_BOUNCE)
1903 if (bp->b_flags & B_BOUNCE) {
1904 vm_bounce_free(bp);
1905 }
1906#endif
1907
1908 /* call optional completion function if requested */
1909 if (bp->b_flags & B_CALL) {
1910 bp->b_flags &= ~B_CALL;
1911 (*bp->b_iodone) (bp);
1912 splx(s);
1913 return;

--- 21 unchanged lines hidden (view full) ---

1935 }
1936
1937 if ((vp->v_flag & VOBJBUF) == 0) {
1938 panic("biodone: vnode is not setup for merged cache");
1939 }
1940#endif
1941
1942 foff = bp->b_offset;
1943#ifdef DIAGNOSTIC
1944 if (bp->b_offset == NOOFFSET)
1945 panic("biodone: no buffer offset");
1946#endif
1947
1948#if !defined(MAX_PERF)
1949 if (!obj) {
1950 panic("biodone: no object");
1951 }
1952#endif
1953#if defined(VFS_BIO_DEBUG)
1954 if (obj->paging_in_progress < bp->b_npages) {

--- 30 unchanged lines hidden (view full) ---

1985 /*
1986 * In the write case, the valid and clean bits are
1987 * already changed correctly, so we only need to do this
1988 * here in the read case.
1989 */
1990 if ((bp->b_flags & B_READ) && !bogusflag && resid > 0) {
1991 vfs_page_set_valid(bp, foff, i, m);
1992 }
1993 m->flags &= ~PG_ZERO;
1994
1995 /*
1996 * when debugging new filesystems or buffer I/O methods, this
1997 * is the most common error that pops up. if you see this, you
1998 * have not set the page busy flag correctly!!!
1999 */
2000 if (m->busy == 0) {
2001#if !defined(MAX_PERF)

--- 115 unchanged lines hidden (view full) ---

2117 if (!m) {
2118 panic("vfs_unbusy_pages: page missing\n");
2119 }
2120#endif
2121 bp->b_pages[i] = m;
2122 pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages);
2123 }
2124 --obj->paging_in_progress;
2125 m->flags &= ~PG_ZERO;
2126 PAGE_BWAKEUP(m);
2127 }
2128 if (obj->paging_in_progress == 0 &&
2129 (obj->flags & OBJ_PIPWNT)) {
2130 obj->flags &= ~OBJ_PIPWNT;
2131 wakeup(obj);
2132 }
2133 }

--- 88 unchanged lines hidden (view full) ---

2222 int i,s;
2223
2224 if (bp->b_flags & B_VMIO) {
2225 struct vnode *vp = bp->b_vp;
2226 vm_object_t obj = vp->v_object;
2227 vm_ooffset_t foff;
2228
2229 foff = bp->b_offset;
2230#ifdef DIAGNOSTIC
2231 if (bp->b_offset == NOOFFSET)
2232 panic("vfs_busy_pages: no buffer offset");
2233#endif
2234
2235 vfs_setdirty(bp);
2236
2237retry:
2238 for (i = 0; i < bp->b_npages; i++) {
2239 vm_page_t m = bp->b_pages[i];
2240 if (vm_page_sleep(m, "vbpage", NULL))
2241 goto retry;
2242 }
2243
2244 for (i = 0; i < bp->b_npages; i++, foff += PAGE_SIZE) {
2245 vm_page_t m = bp->b_pages[i];
2246
2247 m->flags &= ~PG_ZERO;
2248 if ((bp->b_flags & B_CLUSTER) == 0) {
2249 obj->paging_in_progress++;
2250 m->busy++;
2251 }
2252
2253 vm_page_protect(m, VM_PROT_NONE);
2254 if (clear_modify)
2255 vfs_page_set_valid(bp, foff, i, m);

--- 17 unchanged lines hidden (view full) ---

2273{
2274 int i;
2275
2276 if (bp->b_flags & B_VMIO) {
2277 struct vnode *vp = bp->b_vp;
2278 vm_ooffset_t foff;
2279 foff = bp->b_offset;
2280
2281#ifdef DIAGNOSTIC
2282 if (bp->b_offset == NOOFFSET)
2283 panic("vfs_clean_pages: no buffer offset");
2284#endif
2285
2286 for (i = 0; i < bp->b_npages; i++, foff += PAGE_SIZE) {
2287 vm_page_t m = bp->b_pages[i];
2288 vfs_page_set_valid(bp, foff, i, m);
2289 }
2290 }
2291}
2292
2293void
2294vfs_bio_clrbuf(struct buf *bp) {
2295 int i;
2270 if( bp->b_flags & B_VMIO) {
2296 if (((bp->b_flags & (B_VMIO | B_MALLOC)) == B_VMIO) ||
2297 ((bp->b_flags & (B_VMIO | B_MALLOC)) == 0) && (bp->b_npages > 0) ) {
2298 if( (bp->b_npages == 1) && (bp->b_bufsize < PAGE_SIZE)) {
2299 int mask;
2300 mask = 0;
2301 for(i=0;i<bp->b_bufsize;i+=DEV_BSIZE)
2302 mask |= (1 << (i/DEV_BSIZE));
2276 if( bp->b_pages[0]->valid != mask) {
2303 if(((bp->b_pages[0]->flags & PG_ZERO) == 0) &&
2304 (bp->b_pages[0]->valid != mask)) {
2305 bzero(bp->b_data, bp->b_bufsize);
2306 }
2307 bp->b_pages[0]->valid = mask;
2308 bp->b_resid = 0;
2309 return;
2310 }
2311 for(i=0;i<bp->b_npages;i++) {
2312 if( bp->b_pages[i]->valid == VM_PAGE_BITS_ALL)
2313 continue;
2314 if( bp->b_pages[i]->valid == 0) {
2315 if ((bp->b_pages[i]->flags & PG_ZERO) == 0) {
2316 bzero(bp->b_data + (i << PAGE_SHIFT), PAGE_SIZE);
2317 }
2318 } else {
2319 int j;
2320 for(j=0;j<PAGE_SIZE/DEV_BSIZE;j++) {
2293 if( (bp->b_pages[i]->valid & (1<<j)) == 0)
2321 if (((bp->b_pages[i]->flags & PG_ZERO) == 0) &&
2322 (bp->b_pages[i]->valid & (1<<j)) == 0)
2323 bzero(bp->b_data + (i << PAGE_SHIFT) + j * DEV_BSIZE, DEV_BSIZE);
2324 }
2325 }
2326 bp->b_pages[i]->valid = VM_PAGE_BITS_ALL;
2327 bp->b_pages[i]->flags &= ~PG_ZERO;
2328 }
2329 bp->b_resid = 0;
2330 } else {
2331 clrbuf(bp);
2332 }
2333}
2334
2335/*

--- 107 unchanged lines hidden ---