diff options
author | kib <kib@FreeBSD.org> | 2013-03-19 14:27:14 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2013-03-19 14:27:14 +0000 |
commit | 51030488d7e4350d03bd9c713a728be82cce19f1 (patch) | |
tree | 3a6efddd5ee4e197e29b974a1cb3308a8775924d /sys/kern/vfs_bio.c | |
parent | 0702655ee71b5df8e10557cbf741ad09071b628d (diff) | |
download | FreeBSD-src-51030488d7e4350d03bd9c713a728be82cce19f1.zip FreeBSD-src-51030488d7e4350d03bd9c713a728be82cce19f1.tar.gz |
Add a helper function vfs_bio_bzero_buf() to zero the portion of the
buffer, transparently handling mapped or unmapped buffers. Its intent
is to replace the use of bzero(bp->b_data) in cases where the buffer
might be unmapped, to avoid unneeded upgrades.
Sponsored by: The FreeBSD Foundation
Tested by: pho
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r-- | sys/kern/vfs_bio.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index cded596..6f790d2 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -4176,6 +4176,32 @@ unlock: bp->b_resid = 0; } +void +vfs_bio_bzero_buf(struct buf *bp, int base, int size) +{ + vm_page_t m; + int i, n; + + if ((bp->b_flags & B_UNMAPPED) == 0) { + BUF_CHECK_MAPPED(bp); + bzero(bp->b_data + base, size); + } else { + BUF_CHECK_UNMAPPED(bp); + n = PAGE_SIZE - (base & PAGE_MASK); + VM_OBJECT_WLOCK(bp->b_bufobj->bo_object); + for (i = base / PAGE_SIZE; size > 0 && i < bp->b_npages; ++i) { + m = bp->b_pages[i]; + if (n > size) + n = size; + pmap_zero_page_area(m, base & PAGE_MASK, n); + base += n; + size -= n; + n = PAGE_SIZE; + } + VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object); + } +} + /* * vm_hold_load_pages and vm_hold_free_pages get pages into * a buffers address space. The pages are anonymous and are |