summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_bio.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-09-13 04:29:55 +0000
committeralc <alc@FreeBSD.org>2003-09-13 04:29:55 +0000
commitee4ef644cf8abb7a54eb097d0ce4ccc2ad21a827 (patch)
treef4fca5d75fe16e00d6d30a18fd9c7e480affdad0 /sys/kern/vfs_bio.c
parentff5ea568349e8f98a541517dd57f4aa42c8ef934 (diff)
downloadFreeBSD-src-ee4ef644cf8abb7a54eb097d0ce4ccc2ad21a827.zip
FreeBSD-src-ee4ef644cf8abb7a54eb097d0ce4ccc2ad21a827.tar.gz
Convert vmapbuf() from using pmap_extract() to using
pmap_extract_and_hold(). Note, however, that GIANT_REQUIRED should not be removed until all platforms fully implement the "prot" parameter to pmap_extract_and_hold(). Reviewed by: tegge
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r--sys/kern/vfs_bio.c20
1 files changed, 7 insertions, 13 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 021458c..e2ba116 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -3655,7 +3655,7 @@ int
vmapbuf(struct buf *bp)
{
caddr_t addr, kva;
- vm_paddr_t pa;
+ vm_prot_t prot;
int pidx, i;
struct vm_page *m;
struct pmap *pmap = &curproc->p_vmspace->vm_pmap;
@@ -3666,6 +3666,8 @@ vmapbuf(struct buf *bp)
panic("vmapbuf");
if (bp->b_bufsize < 0)
return (-1);
+ prot = (bp->b_iocmd == BIO_READ) ? VM_PROT_READ | VM_PROT_WRITE :
+ VM_PROT_READ;
for (addr = (caddr_t)trunc_page((vm_offset_t)bp->b_data), pidx = 0;
addr < bp->b_data + bp->b_bufsize;
addr += PAGE_SIZE, pidx++) {
@@ -3678,10 +3680,8 @@ vmapbuf(struct buf *bp)
* to work for the kernland address space (see: sparc64 port).
*/
retry:
- i = vm_fault_quick((addr >= bp->b_data) ? addr : bp->b_data,
- (bp->b_iocmd == BIO_READ) ?
- (VM_PROT_READ|VM_PROT_WRITE) : VM_PROT_READ);
- if (i < 0) {
+ if (vm_fault_quick(addr >= bp->b_data ? addr : bp->b_data,
+ prot)) {
vm_page_lock_queues();
for (i = 0; i < pidx; ++i) {
vm_page_unhold(bp->b_pages[i]);
@@ -3690,15 +3690,9 @@ retry:
vm_page_unlock_queues();
return(-1);
}
- pa = pmap_extract(pmap, (vm_offset_t)addr);
- if (pa == 0) {
- printf("vmapbuf: warning, race against user address during I/O");
+ m = pmap_extract_and_hold(pmap, (vm_offset_t)addr, prot);
+ if (m == NULL)
goto retry;
- }
- m = PHYS_TO_VM_PAGE(pa);
- vm_page_lock_queues();
- vm_page_hold(m);
- vm_page_unlock_queues();
bp->b_pages[pidx] = m;
}
if (pidx > btoc(MAXPHYS))
OpenPOWER on IntegriCloud