Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-3]: src/sys/ufs/ffs Pull up following revision(s) (requested by y...
details: https://anonhg.NetBSD.org/src/rev/8cd5ade6997d
branches: netbsd-3
changeset: 577381:8cd5ade6997d
user: tron <tron%NetBSD.org@localhost>
date: Fri Oct 21 11:27:00 2005 +0000
description:
Pull up following revision(s) (requested by yamt in ticket #845):
sys/ufs/ffs/ffs_softdep.c: revision 1.70 via patch
- for pagecache dependency, track which page in the block
has been written or not individually by (ab)using b_resid
in pcbp as a bitmap.
- add a comment to explain why it's needed.
PR/15364. reviewed by Chuck Silvers.
diffstat:
sys/ufs/ffs/ffs_softdep.c | 44 +++++++++++++++++++++++++++++---------------
1 files changed, 29 insertions(+), 15 deletions(-)
diffs (111 lines):
diff -r 5c4f8ac78128 -r 8cd5ade6997d sys/ufs/ffs/ffs_softdep.c
--- a/sys/ufs/ffs/ffs_softdep.c Fri Oct 21 11:25:56 2005 +0000
+++ b/sys/ufs/ffs/ffs_softdep.c Fri Oct 21 11:27:00 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_softdep.c,v 1.63.2.1 2005/05/07 15:04:48 tron Exp $ */
+/* $NetBSD: ffs_softdep.c,v 1.63.2.2 2005/10/21 11:27:00 tron Exp $ */
/*
* Copyright 1998 Marshall Kirk McKusick. All Rights Reserved.
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_softdep.c,v 1.63.2.1 2005/05/07 15:04:48 tron Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_softdep.c,v 1.63.2.2 2005/10/21 11:27:00 tron Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@@ -197,6 +197,9 @@
void softdep_flush_vnode __P((struct vnode *, daddr_t));
static void softdep_trackbufs(struct inode *, int, boolean_t);
+#define PCBP_BITMAP(off, size) \
+ (((1 << howmany((size), PAGE_SIZE)) - 1) << ((off) >> PAGE_SHIFT))
+
/*
* Exported softdep operations.
*/
@@ -5792,6 +5795,11 @@
* Enter pagecache dependency buf in hash.
* Always reset b_resid to be the full amount of data in the block
* since the caller has the corresponding pages locked and dirty.
+ *
+ * Note that we are using b_resid as a bitmap, so that
+ * we can track which pages are written. As pages can be re-dirtied
+ * and re-written in the mean time, byte-count is not suffice for
+ * our purpose.
*/
bp = softdep_lookup_pcbp(vp, lbn);
@@ -5803,9 +5811,13 @@
LIST_INSERT_HEAD(&pcbphashhead[PCBPHASH(vp, lbn)], bp, b_hash);
LIST_INSERT_HEAD(&ip->i_pcbufhd, bp, b_vnbufs);
}
- bp->b_bcount = bp->b_resid = size;
- UVMHIST_LOG(ubchist, "vp = %p, lbn = %" PRId64
- ", bp = %p, bcount = resid = %ld", vp, lbn, bp, size);
+ bp->b_bcount = size;
+ KASSERT(size <= PAGE_SIZE * sizeof(bp->b_resid) * CHAR_BIT);
+ bp->b_resid = PCBP_BITMAP(0, size);
+ UVMHIST_LOG(ubchist, "vp = %p, lbn = %ld, "
+ "bp = %p, bcount = %ld", vp, lbn, bp, size);
+ UVMHIST_LOG(ubchist, "b_resid = %ld",
+ bp->b_resid, 0, 0, 0);
return bp;
}
@@ -5932,7 +5944,7 @@
struct worklist *wk;
daddr_t lbn;
voff_t off;
- long iosize = bp->b_bcount;
+ int iosize = bp->b_bcount;
int size, asize, bshift, bsize;
int i;
UVMHIST_FUNC("softdep_pageiodone"); UVMHIST_CALLED(ubchist);
@@ -5945,12 +5957,14 @@
for (i = 0; i < npages; i++) {
pg = uvm_pageratop((vaddr_t)bp->b_data + (i << PAGE_SHIFT));
if (pg == NULL) {
- continue;
+ panic("%s: no page", __func__);
}
for (off = pg->offset;
off < pg->offset + PAGE_SIZE;
off += bsize) {
+ int pgmask;
+
size = MIN(asize, iosize);
iosize -= size;
lbn = off >> bshift;
@@ -5961,20 +5975,20 @@
continue;
}
UVMHIST_LOG(ubchist,
- "bcount %ld resid %ld vp %p lbn %" PRId64,
+ "bcount %ld resid %ld vp %p lbn %ld",
pcbp ? pcbp->b_bcount : -1,
pcbp ? pcbp->b_resid : -1, vp, lbn);
UVMHIST_LOG(ubchist,
"pcbp %p iosize %ld, size %d, asize %d",
pcbp, iosize, size, asize);
- pcbp->b_resid -= size;
- if (pcbp->b_resid < 0) {
- panic("softdep_pageiodone: "
- "resid < 0, vp %p lbn 0x%" PRIx64 " pcbp %p"
- " iosize %ld, size %d, asize %d, bsize %d",
- vp, lbn, pcbp, iosize, size, asize, bsize);
+ pgmask = PCBP_BITMAP(off & (bsize - 1), size);
+ if ((~pcbp->b_resid & pgmask) != 0) {
+ UVMHIST_LOG(ubchist,
+ "multiple write resid %lx, pgmask %lx",
+ pcbp->b_resid, pgmask, 0, 0);
}
- if (pcbp->b_resid > 0) {
+ pcbp->b_resid &= ~pgmask;
+ if (pcbp->b_resid != 0) {
continue;
}
Home |
Main Index |
Thread Index |
Old Index