summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2009-05-17 20:26:00 +0000
committeralc <alc@FreeBSD.org>2009-05-17 20:26:00 +0000
commitdc942dabcf042f350216364389b0f23960f3d5fb (patch)
treee3ab31a35178114fbfd380d8fa1208bcaf90f814 /sys
parent5f2df6ce18b44323bfc72c3690ef7a1e205a5f0a (diff)
downloadFreeBSD-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.c38
-rw-r--r--sys/sys/buf.h1
-rw-r--r--sys/ufs/ffs/ffs_alloc.c14
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);
}
OpenPOWER on IntegriCloud