diff options
author | alc <alc@FreeBSD.org> | 2009-05-17 20:26:00 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2009-05-17 20:26:00 +0000 |
commit | dc942dabcf042f350216364389b0f23960f3d5fb (patch) | |
tree | e3ab31a35178114fbfd380d8fa1208bcaf90f814 /sys | |
parent | 5f2df6ce18b44323bfc72c3690ef7a1e205a5f0a (diff) | |
download | FreeBSD-src-dc942dabcf042f350216364389b0f23960f3d5fb.zip FreeBSD-src-dc942dabcf042f350216364389b0f23960f3d5fb.tar.gz |
Introduce vfs_bio_set_valid() and use it from ffs_realloccg(). This
eliminates the misuse of vfs_bio_clrbuf() by ffs_realloccg().
In collaboration with: tegge
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_bio.c | 38 | ||||
-rw-r--r-- | sys/sys/buf.h | 1 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_alloc.c | 14 |
3 files changed, 45 insertions, 8 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 2979f61..e5a947b 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -3625,6 +3625,44 @@ vfs_clean_pages(struct buf *bp) } /* + * vfs_bio_set_valid: + * + * Set the range within the buffer to valid. The range is + * relative to the beginning of the buffer, b_offset. Note that + * b_offset itself may be offset from the beginning of the first + * page. + */ +void +vfs_bio_set_valid(struct buf *bp, int base, int size) +{ + int i, n; + vm_page_t m; + + if (!(bp->b_flags & B_VMIO)) + return; + + /* + * Fixup base to be relative to beginning of first page. + * Set initial n to be the maximum number of bytes in the + * first page that can be validated. + */ + base += (bp->b_offset & PAGE_MASK); + n = PAGE_SIZE - (base & PAGE_MASK); + + VM_OBJECT_LOCK(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; + vm_page_set_valid(m, base & PAGE_MASK, n); + base += n; + size -= n; + n = PAGE_SIZE; + } + VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object); +} + +/* * vfs_bio_set_validclean: * * Set the range within the buffer to valid and clean. The range is diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 7ca6ffa..fb0d804 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -498,6 +498,7 @@ int cluster_read(struct vnode *, u_quad_t, daddr_t, long, struct ucred *, long, int, struct buf **); int cluster_wbuild(struct vnode *, long, daddr_t, int); void cluster_write(struct vnode *, struct buf *, u_quad_t, int); +void vfs_bio_set_valid(struct buf *, int base, int size); void vfs_bio_set_validclean(struct buf *, int base, int size); void vfs_bio_clrbuf(struct buf *); void vfs_busy_pages(struct buf *, int clear_modify); diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index 4748f68..b4f001e 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -326,10 +326,9 @@ retry: ip->i_flag |= IN_CHANGE | IN_UPDATE; allocbuf(bp, nsize); bp->b_flags |= B_DONE; - if ((bp->b_flags & (B_MALLOC | B_VMIO)) != B_VMIO) - bzero((char *)bp->b_data + osize, nsize - osize); - else - vfs_bio_clrbuf(bp); + bzero(bp->b_data + osize, nsize - osize); + if ((bp->b_flags & (B_MALLOC | B_VMIO)) == B_VMIO) + vfs_bio_set_valid(bp, osize, nsize - osize); *bpp = bp; return (0); } @@ -404,10 +403,9 @@ retry: ip->i_flag |= IN_CHANGE | IN_UPDATE; allocbuf(bp, nsize); bp->b_flags |= B_DONE; - if ((bp->b_flags & (B_MALLOC | B_VMIO)) != B_VMIO) - bzero((char *)bp->b_data + osize, nsize - osize); - else - vfs_bio_clrbuf(bp); + bzero(bp->b_data + osize, nsize - osize); + if ((bp->b_flags & (B_MALLOC | B_VMIO)) == B_VMIO) + vfs_bio_set_valid(bp, osize, nsize - osize); *bpp = bp; return (0); } |