Deleted Added
full compact
vfs_bio.c (109554) vfs_bio.c (109572)
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 * $FreeBSD: head/sys/kern/vfs_bio.c 109554 2003-01-20 09:24:03Z alc $
14 * $FreeBSD: head/sys/kern/vfs_bio.c 109572 2003-01-20 17:46:48Z dillon $
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 *

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

3542}
3543
3544/*
3545 * Map an IO request into kernel virtual address space.
3546 *
3547 * All requests are (re)mapped into kernel VA space.
3548 * Notice that we use b_bufsize for the size of the buffer
3549 * to be mapped. b_bcount might be modified by the driver.
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 *

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

3542}
3543
3544/*
3545 * Map an IO request into kernel virtual address space.
3546 *
3547 * All requests are (re)mapped into kernel VA space.
3548 * Notice that we use b_bufsize for the size of the buffer
3549 * to be mapped. b_bcount might be modified by the driver.
3550 *
3551 * Note that even if the caller determines that the address space should
3552 * be valid, a race or a smaller-file mapped into a larger space may
3553 * actually cause vmapbuf() to fail, so all callers of vmapbuf() MUST
3554 * check the return value.
3550 */
3555 */
3551void
3556int
3552vmapbuf(struct buf *bp)
3553{
3554 caddr_t addr, kva;
3555 vm_offset_t pa;
3557vmapbuf(struct buf *bp)
3558{
3559 caddr_t addr, kva;
3560 vm_offset_t pa;
3556 int pidx;
3561 int pidx, i;
3557 struct vm_page *m;
3558 struct pmap *pmap = &curproc->p_vmspace->vm_pmap;
3559
3560 GIANT_REQUIRED;
3561
3562 if ((bp->b_flags & B_PHYS) == 0)
3563 panic("vmapbuf");
3564
3565 for (addr = (caddr_t)trunc_page((vm_offset_t)bp->b_data), pidx = 0;
3566 addr < bp->b_data + bp->b_bufsize;
3567 addr += PAGE_SIZE, pidx++) {
3568 /*
3569 * Do the vm_fault if needed; do the copy-on-write thing
3570 * when reading stuff off device into memory.
3571 *
3572 * NOTE! Must use pmap_extract() because addr may be in
3573 * the userland address space, and kextract is only guarenteed
3574 * to work for the kernland address space (see: sparc64 port).
3575 */
3562 struct vm_page *m;
3563 struct pmap *pmap = &curproc->p_vmspace->vm_pmap;
3564
3565 GIANT_REQUIRED;
3566
3567 if ((bp->b_flags & B_PHYS) == 0)
3568 panic("vmapbuf");
3569
3570 for (addr = (caddr_t)trunc_page((vm_offset_t)bp->b_data), pidx = 0;
3571 addr < bp->b_data + bp->b_bufsize;
3572 addr += PAGE_SIZE, pidx++) {
3573 /*
3574 * Do the vm_fault if needed; do the copy-on-write thing
3575 * when reading stuff off device into memory.
3576 *
3577 * NOTE! Must use pmap_extract() because addr may be in
3578 * the userland address space, and kextract is only guarenteed
3579 * to work for the kernland address space (see: sparc64 port).
3580 */
3576 vm_fault_quick((addr >= bp->b_data) ? addr : bp->b_data,
3577 (bp->b_iocmd == BIO_READ)?(VM_PROT_READ|VM_PROT_WRITE):VM_PROT_READ);
3581retry:
3582 i = vm_fault_quick((addr >= bp->b_data) ? addr : bp->b_data,
3583 (bp->b_iocmd == BIO_READ) ?
3584 (VM_PROT_READ|VM_PROT_WRITE) : VM_PROT_READ);
3585 if (i < 0) {
3586 printf("vmapbuf: warning, bad user address during I/O\n");
3587 vm_page_lock_queues();
3588 for (i = 0; i < pidx; ++i) {
3589 vm_page_unhold(bp->b_pages[i]);
3590 bp->b_pages[i] = NULL;
3591 }
3592 vm_page_unlock_queues();
3593 return(-1);
3594 }
3578 pa = trunc_page(pmap_extract(pmap, (vm_offset_t) addr));
3595 pa = trunc_page(pmap_extract(pmap, (vm_offset_t) addr));
3579 if (pa == 0)
3580 panic("vmapbuf: page not present");
3596 if (pa == 0) {
3597 printf("vmapbuf: warning, race against user address during I/O");
3598 goto retry;
3599 }
3581 m = PHYS_TO_VM_PAGE(pa);
3582 vm_page_lock_queues();
3583 vm_page_hold(m);
3584 vm_page_unlock_queues();
3585 bp->b_pages[pidx] = m;
3586 }
3587 if (pidx > btoc(MAXPHYS))
3588 panic("vmapbuf: mapped more than MAXPHYS");
3589 pmap_qenter((vm_offset_t)bp->b_saveaddr, bp->b_pages, pidx);
3590
3591 kva = bp->b_saveaddr;
3592 bp->b_npages = pidx;
3593 bp->b_saveaddr = bp->b_data;
3594 bp->b_data = kva + (((vm_offset_t) bp->b_data) & PAGE_MASK);
3600 m = PHYS_TO_VM_PAGE(pa);
3601 vm_page_lock_queues();
3602 vm_page_hold(m);
3603 vm_page_unlock_queues();
3604 bp->b_pages[pidx] = m;
3605 }
3606 if (pidx > btoc(MAXPHYS))
3607 panic("vmapbuf: mapped more than MAXPHYS");
3608 pmap_qenter((vm_offset_t)bp->b_saveaddr, bp->b_pages, pidx);
3609
3610 kva = bp->b_saveaddr;
3611 bp->b_npages = pidx;
3612 bp->b_saveaddr = bp->b_data;
3613 bp->b_data = kva + (((vm_offset_t) bp->b_data) & PAGE_MASK);
3614 return(0);
3595}
3596
3597/*
3598 * Free the io map PTEs associated with this IO operation.
3599 * We also invalidate the TLB entries and restore the original b_addr.
3600 */
3601void
3602vunmapbuf(struct buf *bp)

--- 57 unchanged lines hidden ---
3615}
3616
3617/*
3618 * Free the io map PTEs associated with this IO operation.
3619 * We also invalidate the TLB entries and restore the original b_addr.
3620 */
3621void
3622vunmapbuf(struct buf *bp)

--- 57 unchanged lines hidden ---