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 --- |