summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_bio.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-03-19 14:27:14 +0000
committerkib <kib@FreeBSD.org>2013-03-19 14:27:14 +0000
commit51030488d7e4350d03bd9c713a728be82cce19f1 (patch)
tree3a6efddd5ee4e197e29b974a1cb3308a8775924d /sys/kern/vfs_bio.c
parent0702655ee71b5df8e10557cbf741ad09071b628d (diff)
downloadFreeBSD-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.c26
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
OpenPOWER on IntegriCloud