Deleted Added
full compact
vfs_bio.c (38299) vfs_bio.c (38517)
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.168 1998/08/06 08:33:18 dfr Exp $
14 * $Id: vfs_bio.c,v 1.169 1998/08/13 08:09:07 dfr 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 *

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

643
644 vp = bp->b_vp;
645
646 resid = bp->b_bufsize;
647 foff = bp->b_offset;
648
649 for (i = 0; i < bp->b_npages; i++) {
650 m = bp->b_pages[i];
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 *

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

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

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

830 vm_page_test_dirty(m);
831 /*
832 * this keeps pressure off of the process memory
833 */
834 if (m->dirty == 0 && m->hold_count == 0)
835 vm_page_cache(m);
836 else
837 vm_page_deactivate(m);
652 if (m == bogus_page) {
653
654 obj = (vm_object_t) vp->v_object;
655 poff = OFF_TO_IDX(bp->b_offset);
656
657 for (j = i; j < bp->b_npages; j++) {
658 m = bp->b_pages[j];
659 if (m == bogus_page) {

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

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

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

1352 */
1353 if ((bp->b_flags & B_VMIO) &&
1354 ((object = bp->b_pages[0]->object)->flags & (OBJ_WRITEABLE|OBJ_CLEANING))) {
1355 /*
1356 * test the pages to see if they have been modified directly
1357 * by users through the VM system.
1358 */
1359 for (i = 0; i < bp->b_npages; i++) {
851 }
852 }
853 }
854 bufspace -= bp->b_bufsize;
855 vmiospace -= bp->b_bufsize;
856 pmap_qremove(trunc_page((vm_offset_t) bp->b_data), bp->b_npages);
857 bp->b_npages = 0;
858 bp->b_bufsize = 0;

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

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

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

1784 m = vm_page_alloc(obj, objoff, VM_ALLOC_NORMAL);
1785 if (!m) {
1786 VM_WAIT;
1787 vm_pageout_deficit += (desiredpages - bp->b_npages);
1788 goto doretry;
1789 }
1790
1791 vm_page_wire(m);
1361 vm_page_test_dirty(bp->b_pages[i]);
1362 }
1363
1364 /*
1365 * scan forwards for the first page modified
1366 */
1367 for (i = 0; i < bp->b_npages; i++) {
1368 if (bp->b_pages[i]->dirty) {

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

1784 m = vm_page_alloc(obj, objoff, VM_ALLOC_NORMAL);
1785 if (!m) {
1786 VM_WAIT;
1787 vm_pageout_deficit += (desiredpages - bp->b_npages);
1788 goto doretry;
1789 }
1790
1791 vm_page_wire(m);
1792 m->flags &= ~PG_BUSY;
1792 PAGE_CLEAR_FLAG(m, PG_BUSY);
1793 bp->b_flags &= ~B_CACHE;
1794
1795 } else if (m->flags & PG_BUSY) {
1796 s = splvm();
1797 if (m->flags & PG_BUSY) {
1793 bp->b_flags &= ~B_CACHE;
1794
1795 } else if (m->flags & PG_BUSY) {
1796 s = splvm();
1797 if (m->flags & PG_BUSY) {
1798 m->flags |= PG_WANTED;
1798 PAGE_SET_FLAG(m, PG_WANTED);
1799 tsleep(m, PVM, "pgtblk", 0);
1800 }
1801 splx(s);
1802 goto doretry;
1803 } else {
1804 if ((curproc != pageproc) &&
1805 ((m->queue - m->pc) == PQ_CACHE) &&
1806 ((cnt.v_free_count + cnt.v_cache_count) <
1807 (cnt.v_free_min + cnt.v_cache_min))) {
1808 pagedaemon_wakeup();
1809 }
1810 bytesinpage = tinc;
1811 if (tinc > (newbsize - toff))
1812 bytesinpage = newbsize - toff;
1813 if (bp->b_flags & B_CACHE)
1814 vfs_buf_set_valid(bp, off, toff, bytesinpage, m);
1799 tsleep(m, PVM, "pgtblk", 0);
1800 }
1801 splx(s);
1802 goto doretry;
1803 } else {
1804 if ((curproc != pageproc) &&
1805 ((m->queue - m->pc) == PQ_CACHE) &&
1806 ((cnt.v_free_count + cnt.v_cache_count) <
1807 (cnt.v_free_min + cnt.v_cache_min))) {
1808 pagedaemon_wakeup();
1809 }
1810 bytesinpage = tinc;
1811 if (tinc > (newbsize - toff))
1812 bytesinpage = newbsize - toff;
1813 if (bp->b_flags & B_CACHE)
1814 vfs_buf_set_valid(bp, off, toff, bytesinpage, m);
1815 m->flags &= ~PG_ZERO;
1815 PAGE_CLEAR_FLAG(m, PG_ZERO);
1816 vm_page_wire(m);
1817 }
1818 bp->b_pages[pageindex] = m;
1819 curbpnpages = pageindex + 1;
1820 }
1821 if (vp->v_tag == VT_NFS &&
1822 vp->v_type != VBLK) {
1823 if (bp->b_dirtyend > 0) {

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

1966 m = bp->b_pages[i];
1967 if (m == bogus_page) {
1968 bogusflag = 1;
1969 m = vm_page_lookup(obj, OFF_TO_IDX(foff));
1970 if (!m) {
1971#if defined(VFS_BIO_DEBUG)
1972 printf("biodone: page disappeared\n");
1973#endif
1816 vm_page_wire(m);
1817 }
1818 bp->b_pages[pageindex] = m;
1819 curbpnpages = pageindex + 1;
1820 }
1821 if (vp->v_tag == VT_NFS &&
1822 vp->v_type != VBLK) {
1823 if (bp->b_dirtyend > 0) {

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

1966 m = bp->b_pages[i];
1967 if (m == bogus_page) {
1968 bogusflag = 1;
1969 m = vm_page_lookup(obj, OFF_TO_IDX(foff));
1970 if (!m) {
1971#if defined(VFS_BIO_DEBUG)
1972 printf("biodone: page disappeared\n");
1973#endif
1974 --obj->paging_in_progress;
1974 vm_object_pip_subtract(obj, 1);
1975 continue;
1976 }
1977 bp->b_pages[i] = m;
1978 pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages);
1979 }
1980#if defined(VFS_BIO_DEBUG)
1981 if (OFF_TO_IDX(foff) != m->pindex) {
1982 printf("biodone: foff(%d)/m->pindex(%d) mismatch\n", foff, m->pindex);

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

1989 /*
1990 * In the write case, the valid and clean bits are
1991 * already changed correctly, so we only need to do this
1992 * here in the read case.
1993 */
1994 if ((bp->b_flags & B_READ) && !bogusflag && resid > 0) {
1995 vfs_page_set_valid(bp, foff, i, m);
1996 }
1975 continue;
1976 }
1977 bp->b_pages[i] = m;
1978 pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages);
1979 }
1980#if defined(VFS_BIO_DEBUG)
1981 if (OFF_TO_IDX(foff) != m->pindex) {
1982 printf("biodone: foff(%d)/m->pindex(%d) mismatch\n", foff, m->pindex);

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

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

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

2020 (int) bp->b_lblkno,
2021 bp->b_flags, bp->b_npages);
2022 printf(" valid: 0x%x, dirty: 0x%x, wired: %d\n",
2023 m->valid, m->dirty, m->wire_count);
2024#endif
2025 panic("biodone: page busy < 0\n");
2026 }
2027 PAGE_BWAKEUP(m);
1998
1999 /*
2000 * when debugging new filesystems or buffer I/O methods, this
2001 * is the most common error that pops up. if you see this, you
2002 * have not set the page busy flag correctly!!!
2003 */
2004 if (m->busy == 0) {
2005#if !defined(MAX_PERF)

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

2020 (int) bp->b_lblkno,
2021 bp->b_flags, bp->b_npages);
2022 printf(" valid: 0x%x, dirty: 0x%x, wired: %d\n",
2023 m->valid, m->dirty, m->wire_count);
2024#endif
2025 panic("biodone: page busy < 0\n");
2026 }
2027 PAGE_BWAKEUP(m);
2028 --obj->paging_in_progress;
2028 vm_object_pip_subtract(obj, 1);
2029 foff += resid;
2030 iosize -= resid;
2031 }
2032 if (obj &&
2033 (obj->paging_in_progress == 0) &&
2034 (obj->flags & OBJ_PIPWNT)) {
2029 foff += resid;
2030 iosize -= resid;
2031 }
2032 if (obj &&
2033 (obj->paging_in_progress == 0) &&
2034 (obj->flags & OBJ_PIPWNT)) {
2035 obj->flags &= ~OBJ_PIPWNT;
2035 vm_object_clear_flag(obj, OBJ_PIPWNT);
2036 wakeup(obj);
2037 }
2038 }
2039 /*
2040 * For asynchronous completions, release the buffer now. The brelse
2041 * checks for B_WANTED and will do the wakeup there if necessary - so
2042 * no need to do a wakeup here in the async case.
2043 */

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

2120#if !defined(MAX_PERF)
2121 if (!m) {
2122 panic("vfs_unbusy_pages: page missing\n");
2123 }
2124#endif
2125 bp->b_pages[i] = m;
2126 pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages);
2127 }
2036 wakeup(obj);
2037 }
2038 }
2039 /*
2040 * For asynchronous completions, release the buffer now. The brelse
2041 * checks for B_WANTED and will do the wakeup there if necessary - so
2042 * no need to do a wakeup here in the async case.
2043 */

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

2120#if !defined(MAX_PERF)
2121 if (!m) {
2122 panic("vfs_unbusy_pages: page missing\n");
2123 }
2124#endif
2125 bp->b_pages[i] = m;
2126 pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages);
2127 }
2128 s = splvm();
2129 --obj->paging_in_progress;
2130 splx(s);
2131 m->flags &= ~PG_ZERO;
2128 vm_object_pip_subtract(obj, 1);
2129 PAGE_CLEAR_FLAG(m, PG_ZERO);
2132 PAGE_BWAKEUP(m);
2133 }
2134 if (obj->paging_in_progress == 0 &&
2135 (obj->flags & OBJ_PIPWNT)) {
2130 PAGE_BWAKEUP(m);
2131 }
2132 if (obj->paging_in_progress == 0 &&
2133 (obj->flags & OBJ_PIPWNT)) {
2136 obj->flags &= ~OBJ_PIPWNT;
2134 vm_object_clear_flag(obj, OBJ_PIPWNT);
2137 wakeup(obj);
2138 }
2139 }
2140}
2141
2142/*
2143 * Set NFS' b_validoff and b_validend fields from the valid bits
2144 * of a page. If the consumer is not NFS, and the page is not

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

2245 vm_page_t m = bp->b_pages[i];
2246 if (vm_page_sleep(m, "vbpage", NULL))
2247 goto retry;
2248 }
2249
2250 for (i = 0; i < bp->b_npages; i++, foff += PAGE_SIZE) {
2251 vm_page_t m = bp->b_pages[i];
2252
2135 wakeup(obj);
2136 }
2137 }
2138}
2139
2140/*
2141 * Set NFS' b_validoff and b_validend fields from the valid bits
2142 * of a page. If the consumer is not NFS, and the page is not

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

2243 vm_page_t m = bp->b_pages[i];
2244 if (vm_page_sleep(m, "vbpage", NULL))
2245 goto retry;
2246 }
2247
2248 for (i = 0; i < bp->b_npages; i++, foff += PAGE_SIZE) {
2249 vm_page_t m = bp->b_pages[i];
2250
2253 m->flags &= ~PG_ZERO;
2251 PAGE_CLEAR_FLAG(m, PG_ZERO);
2254 if ((bp->b_flags & B_CLUSTER) == 0) {
2252 if ((bp->b_flags & B_CLUSTER) == 0) {
2255 s = splvm();
2256 obj->paging_in_progress++;
2257 splx(s);
2258 m->busy++;
2253 vm_object_pip_add(obj, 1);
2254 PAGE_BUSY(m);
2259 }
2260
2261 vm_page_protect(m, VM_PROT_NONE);
2262 if (clear_modify)
2263 vfs_page_set_valid(bp, foff, i, m);
2264 else if (bp->b_bcount >= PAGE_SIZE) {
2265 if (m->valid && (bp->b_flags & B_CACHE) == 0) {
2266 bp->b_pages[i] = bogus_page;

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

2326 int j;
2327 for(j=0;j<PAGE_SIZE/DEV_BSIZE;j++) {
2328 if (((bp->b_pages[i]->flags & PG_ZERO) == 0) &&
2329 (bp->b_pages[i]->valid & (1<<j)) == 0)
2330 bzero(bp->b_data + (i << PAGE_SHIFT) + j * DEV_BSIZE, DEV_BSIZE);
2331 }
2332 }
2333 bp->b_pages[i]->valid = VM_PAGE_BITS_ALL;
2255 }
2256
2257 vm_page_protect(m, VM_PROT_NONE);
2258 if (clear_modify)
2259 vfs_page_set_valid(bp, foff, i, m);
2260 else if (bp->b_bcount >= PAGE_SIZE) {
2261 if (m->valid && (bp->b_flags & B_CACHE) == 0) {
2262 bp->b_pages[i] = bogus_page;

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

2322 int j;
2323 for(j=0;j<PAGE_SIZE/DEV_BSIZE;j++) {
2324 if (((bp->b_pages[i]->flags & PG_ZERO) == 0) &&
2325 (bp->b_pages[i]->valid & (1<<j)) == 0)
2326 bzero(bp->b_data + (i << PAGE_SHIFT) + j * DEV_BSIZE, DEV_BSIZE);
2327 }
2328 }
2329 bp->b_pages[i]->valid = VM_PAGE_BITS_ALL;
2334 bp->b_pages[i]->flags &= ~PG_ZERO;
2330 PAGE_CLEAR_FLAG(bp->b_pages[i], PG_ZERO);
2335 }
2336 bp->b_resid = 0;
2337 } else {
2338 clrbuf(bp);
2339 }
2340}
2341
2342/*

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

2364 VM_ALLOC_NORMAL);
2365 if (!p) {
2366 vm_pageout_deficit += (to - from) >> PAGE_SHIFT;
2367 VM_WAIT;
2368 goto tryagain;
2369 }
2370 vm_page_wire(p);
2371 p->valid = VM_PAGE_BITS_ALL;
2331 }
2332 bp->b_resid = 0;
2333 } else {
2334 clrbuf(bp);
2335 }
2336}
2337
2338/*

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

2360 VM_ALLOC_NORMAL);
2361 if (!p) {
2362 vm_pageout_deficit += (to - from) >> PAGE_SHIFT;
2363 VM_WAIT;
2364 goto tryagain;
2365 }
2366 vm_page_wire(p);
2367 p->valid = VM_PAGE_BITS_ALL;
2372 p->flags &= ~PG_ZERO;
2368 PAGE_CLEAR_FLAG(p, PG_ZERO);
2373 pmap_kenter(pg, VM_PAGE_TO_PHYS(p));
2374 bp->b_pages[index] = p;
2375 PAGE_WAKEUP(p);
2376 }
2377 bp->b_npages = index;
2378}
2379
2380void

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

2394#if !defined(MAX_PERF)
2395 if (p->busy) {
2396 printf("vm_hold_free_pages: blkno: %d, lblkno: %d\n",
2397 bp->b_blkno, bp->b_lblkno);
2398 }
2399#endif
2400 bp->b_pages[index] = NULL;
2401 pmap_kremove(pg);
2369 pmap_kenter(pg, VM_PAGE_TO_PHYS(p));
2370 bp->b_pages[index] = p;
2371 PAGE_WAKEUP(p);
2372 }
2373 bp->b_npages = index;
2374}
2375
2376void

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

2390#if !defined(MAX_PERF)
2391 if (p->busy) {
2392 printf("vm_hold_free_pages: blkno: %d, lblkno: %d\n",
2393 bp->b_blkno, bp->b_lblkno);
2394 }
2395#endif
2396 bp->b_pages[index] = NULL;
2397 pmap_kremove(pg);
2402 p->flags |= PG_BUSY;
2398 PAGE_SET_FLAG(p, PG_BUSY);
2403 vm_page_unwire(p);
2404 vm_page_free(p);
2405 }
2406 }
2407 bp->b_npages = newnpages;
2408}
2409
2410

--- 41 unchanged lines hidden ---
2399 vm_page_unwire(p);
2400 vm_page_free(p);
2401 }
2402 }
2403 bp->b_npages = newnpages;
2404}
2405
2406

--- 41 unchanged lines hidden ---