Deleted Added
full compact
vfs_bio.c (32585) vfs_bio.c (32702)
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 *
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.142 1998/01/12 01:46:25 dyson Exp $
14 * $Id: vfs_bio.c,v 1.143 1998/01/17 09:16:26 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 *

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

172 bp = &buf[i];
173 bzero(bp, sizeof *bp);
174 bp->b_flags = B_INVAL; /* we're just an empty header */
175 bp->b_dev = NODEV;
176 bp->b_rcred = NOCRED;
177 bp->b_wcred = NOCRED;
178 bp->b_qindex = QUEUE_EMPTY;
179 bp->b_vnbufs.le_next = NOLIST;
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 *

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

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

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

649 if (bp->b_bufsize == 0) {
650 bp->b_flags |= B_INVAL;
651 bp->b_qindex = QUEUE_EMPTY;
652 TAILQ_INSERT_HEAD(&bufqueues[QUEUE_EMPTY], bp, b_freelist);
653 LIST_REMOVE(bp, b_hash);
654 LIST_INSERT_HEAD(&invalhash, bp, b_hash);
655 bp->b_dev = NODEV;
656 kvafreespace += bp->b_kvasize;
181 TAILQ_INSERT_TAIL(&bufqueues[QUEUE_EMPTY], bp, b_freelist);
182 LIST_INSERT_HEAD(&invalhash, bp, b_hash);
183 }
184/*
185 * maxbufspace is currently calculated to support all filesystem blocks
186 * to be 8K. If you happen to use a 16K filesystem, the size of the buffer
187 * cache is still the same as it would be for 8K filesystems. This
188 * keeps the size of the buffer cache "in check" for big block filesystems.

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

650 if (bp->b_bufsize == 0) {
651 bp->b_flags |= B_INVAL;
652 bp->b_qindex = QUEUE_EMPTY;
653 TAILQ_INSERT_HEAD(&bufqueues[QUEUE_EMPTY], bp, b_freelist);
654 LIST_REMOVE(bp, b_hash);
655 LIST_INSERT_HEAD(&invalhash, bp, b_hash);
656 bp->b_dev = NODEV;
657 kvafreespace += bp->b_kvasize;
658 bp->b_generation++;
657
658 /* buffers with junk contents */
659 } else if (bp->b_flags & (B_ERROR | B_INVAL | B_NOCACHE | B_RELBUF)) {
660 bp->b_flags |= B_INVAL;
661 bp->b_qindex = QUEUE_AGE;
662 TAILQ_INSERT_HEAD(&bufqueues[QUEUE_AGE], bp, b_freelist);
663 LIST_REMOVE(bp, b_hash);
664 LIST_INSERT_HEAD(&invalhash, bp, b_hash);
665 bp->b_dev = NODEV;
659
660 /* buffers with junk contents */
661 } else if (bp->b_flags & (B_ERROR | B_INVAL | B_NOCACHE | B_RELBUF)) {
662 bp->b_flags |= B_INVAL;
663 bp->b_qindex = QUEUE_AGE;
664 TAILQ_INSERT_HEAD(&bufqueues[QUEUE_AGE], bp, b_freelist);
665 LIST_REMOVE(bp, b_hash);
666 LIST_INSERT_HEAD(&invalhash, bp, b_hash);
667 bp->b_dev = NODEV;
668 bp->b_generation++;
666
667 /* buffers that are locked */
668 } else if (bp->b_flags & B_LOCKED) {
669 bp->b_qindex = QUEUE_LOCKED;
670 TAILQ_INSERT_TAIL(&bufqueues[QUEUE_LOCKED], bp, b_freelist);
671
672 /* buffers with stale but valid contents */
673 } else if (bp->b_flags & B_AGE) {

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

1078 bp->b_flags &= ~B_ASYNC;
1079 vfs_vmio_release(bp);
1080 }
1081
1082 if (bp->b_vp)
1083 brelvp(bp);
1084
1085fillbuf:
669
670 /* buffers that are locked */
671 } else if (bp->b_flags & B_LOCKED) {
672 bp->b_qindex = QUEUE_LOCKED;
673 TAILQ_INSERT_TAIL(&bufqueues[QUEUE_LOCKED], bp, b_freelist);
674
675 /* buffers with stale but valid contents */
676 } else if (bp->b_flags & B_AGE) {

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

1081 bp->b_flags &= ~B_ASYNC;
1082 vfs_vmio_release(bp);
1083 }
1084
1085 if (bp->b_vp)
1086 brelvp(bp);
1087
1088fillbuf:
1089 bp->b_generation++;
1086
1087 /* we are not free, nor do we contain interesting data */
1088 if (bp->b_rcred != NOCRED) {
1089 crfree(bp->b_rcred);
1090 bp->b_rcred = NOCRED;
1091 }
1092 if (bp->b_wcred != NOCRED) {
1093 crfree(bp->b_wcred);

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

1343 */
1344struct buf *
1345getblk(struct vnode * vp, daddr_t blkno, int size, int slpflag, int slptimeo)
1346{
1347 struct buf *bp;
1348 int s;
1349 struct bufhashhdr *bh;
1350 int maxsize;
1090
1091 /* we are not free, nor do we contain interesting data */
1092 if (bp->b_rcred != NOCRED) {
1093 crfree(bp->b_rcred);
1094 bp->b_rcred = NOCRED;
1095 }
1096 if (bp->b_wcred != NOCRED) {
1097 crfree(bp->b_wcred);

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

1347 */
1348struct buf *
1349getblk(struct vnode * vp, daddr_t blkno, int size, int slpflag, int slptimeo)
1350{
1351 struct buf *bp;
1352 int s;
1353 struct bufhashhdr *bh;
1354 int maxsize;
1355 int generation;
1351
1352 if (vp->v_mount) {
1353 maxsize = vp->v_mount->mnt_stat.f_iosize;
1354 /*
1355 * This happens on mount points.
1356 */
1357 if (maxsize < size)
1358 maxsize = size;

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

1365 panic("getblk: size(%d) > MAXBSIZE(%d)\n", size, MAXBSIZE);
1366#endif
1367
1368 s = splbio();
1369loop:
1370 if (numfreebuffers < lofreebuffers) {
1371 waitfreebuffers(slpflag, slptimeo);
1372 }
1356
1357 if (vp->v_mount) {
1358 maxsize = vp->v_mount->mnt_stat.f_iosize;
1359 /*
1360 * This happens on mount points.
1361 */
1362 if (maxsize < size)
1363 maxsize = size;

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

1370 panic("getblk: size(%d) > MAXBSIZE(%d)\n", size, MAXBSIZE);
1371#endif
1372
1373 s = splbio();
1374loop:
1375 if (numfreebuffers < lofreebuffers) {
1376 waitfreebuffers(slpflag, slptimeo);
1377 }
1373
1378
1374 if ((bp = gbincore(vp, blkno))) {
1379 if ((bp = gbincore(vp, blkno))) {
1380loop1:
1381 generation = bp->b_generation;
1375 if (bp->b_flags & B_BUSY) {
1376 bp->b_flags |= B_WANTED;
1377 if (bp->b_usecount < BUF_MAXUSE)
1378 ++bp->b_usecount;
1379 if (!tsleep(bp,
1382 if (bp->b_flags & B_BUSY) {
1383 bp->b_flags |= B_WANTED;
1384 if (bp->b_usecount < BUF_MAXUSE)
1385 ++bp->b_usecount;
1386 if (!tsleep(bp,
1380 (PRIBIO + 1) | slpflag, "getblk", slptimeo))
1381 goto loop;
1382
1383 splx(s);
1384 return (struct buf *) NULL;
1387 (PRIBIO + 1) | slpflag, "getblk", slptimeo)) {
1388 if (bp->b_generation != generation)
1389 goto loop;
1390 goto loop1;
1391 } else {
1392 splx(s);
1393 return (struct buf *) NULL;
1394 }
1385 }
1386 bp->b_flags |= B_BUSY | B_CACHE;
1387 bremfree(bp);
1388
1389 /*
1390 * check for size inconsistancies (note that they shouldn't
1391 * happen but do when filesystems don't handle the size changes
1392 * correctly.) We are conservative on metadata and don't just
1393 * extend the buffer but write and re-constitute it.
1394 */
1395
1396 if (bp->b_bcount != size) {
1395 }
1396 bp->b_flags |= B_BUSY | B_CACHE;
1397 bremfree(bp);
1398
1399 /*
1400 * check for size inconsistancies (note that they shouldn't
1401 * happen but do when filesystems don't handle the size changes
1402 * correctly.) We are conservative on metadata and don't just
1403 * extend the buffer but write and re-constitute it.
1404 */
1405
1406 if (bp->b_bcount != size) {
1407 bp->b_generation++;
1397 if ((bp->b_flags & B_VMIO) && (size <= bp->b_kvasize)) {
1398 allocbuf(bp, size);
1399 } else {
1400 bp->b_flags |= B_NOCACHE;
1401 VOP_BWRITE(bp);
1402 goto loop;
1403 }
1404 }

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

1678 vfs_buf_set_valid(bp, off, toff, bytesinpage, m);
1679 continue;
1680 }
1681 m = vm_page_lookup(obj, objoff);
1682 if (!m) {
1683 m = vm_page_alloc(obj, objoff, VM_ALLOC_NORMAL);
1684 if (!m) {
1685 VM_WAIT;
1408 if ((bp->b_flags & B_VMIO) && (size <= bp->b_kvasize)) {
1409 allocbuf(bp, size);
1410 } else {
1411 bp->b_flags |= B_NOCACHE;
1412 VOP_BWRITE(bp);
1413 goto loop;
1414 }
1415 }

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

1689 vfs_buf_set_valid(bp, off, toff, bytesinpage, m);
1690 continue;
1691 }
1692 m = vm_page_lookup(obj, objoff);
1693 if (!m) {
1694 m = vm_page_alloc(obj, objoff, VM_ALLOC_NORMAL);
1695 if (!m) {
1696 VM_WAIT;
1697 vm_pageout_deficit += (desiredpages - bp->b_npages);
1686 goto doretry;
1687 }
1688 /*
1689 * Normally it is unwise to clear PG_BUSY without
1690 * PAGE_WAKEUP -- but it is okay here, as there is
1691 * no chance for blocking between here and vm_page_alloc
1692 */
1693 m->flags &= ~PG_BUSY;

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

2235 for (pg = from; pg < to; pg += PAGE_SIZE, index++) {
2236
2237tryagain:
2238
2239 p = vm_page_alloc(kernel_object,
2240 ((pg - VM_MIN_KERNEL_ADDRESS) >> PAGE_SHIFT),
2241 VM_ALLOC_NORMAL);
2242 if (!p) {
1698 goto doretry;
1699 }
1700 /*
1701 * Normally it is unwise to clear PG_BUSY without
1702 * PAGE_WAKEUP -- but it is okay here, as there is
1703 * no chance for blocking between here and vm_page_alloc
1704 */
1705 m->flags &= ~PG_BUSY;

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

2247 for (pg = from; pg < to; pg += PAGE_SIZE, index++) {
2248
2249tryagain:
2250
2251 p = vm_page_alloc(kernel_object,
2252 ((pg - VM_MIN_KERNEL_ADDRESS) >> PAGE_SHIFT),
2253 VM_ALLOC_NORMAL);
2254 if (!p) {
2255 vm_pageout_deficit += (to - from) >> PAGE_SHIFT;
2243 VM_WAIT;
2244 goto tryagain;
2245 }
2246 vm_page_wire(p);
2247 pmap_kenter(pg, VM_PAGE_TO_PHYS(p));
2248 bp->b_pages[index] = p;
2249 PAGE_WAKEUP(p);
2250 }

--- 73 unchanged lines hidden ---
2256 VM_WAIT;
2257 goto tryagain;
2258 }
2259 vm_page_wire(p);
2260 pmap_kenter(pg, VM_PAGE_TO_PHYS(p));
2261 bp->b_pages[index] = p;
2262 PAGE_WAKEUP(p);
2263 }

--- 73 unchanged lines hidden ---