aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/venti/srv/conv.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2008-04-15 19:17:51 -0700
committerRuss Cox <rsc@swtch.com>2008-04-15 19:17:51 -0700
commit9f8a101a7c2e88b968741e9057da4f741a736fb5 (patch)
tree8638184d3592cf9df280c28af1f0d3f2788d897d /src/cmd/venti/srv/conv.c
parent715d6f8e14e8bc20f21209ca107bef3300d28e8c (diff)
parent715d6f8e14e8bc20f21209ca107bef3300d28e8c (diff)
downloadplan9port-9f8a101a7c2e88b968741e9057da4f741a736fb5.tar.gz
plan9port-9f8a101a7c2e88b968741e9057da4f741a736fb5.tar.bz2
plan9port-9f8a101a7c2e88b968741e9057da4f741a736fb5.zip
merge
Diffstat (limited to 'src/cmd/venti/srv/conv.c')
-rw-r--r--src/cmd/venti/srv/conv.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/cmd/venti/srv/conv.c b/src/cmd/venti/srv/conv.c
index f72511b1..29b8c5f0 100644
--- a/src/cmd/venti/srv/conv.c
+++ b/src/cmd/venti/srv/conv.c
@@ -177,6 +177,27 @@ unpackarena(Arena *arena, u8int *buf)
p += U64Size;
arena->memstats.sealed = U8GET(p);
p += U8Size;
+
+ /*
+ * 2008/4/2
+ * Packarena (below) used to have a bug in which it would
+ * not zero out any existing extension fields when writing
+ * the arena metadata. This would manifest itself as arenas
+ * with arena->diskstats.sealed == 1 but arena->memstats.sealed == 0
+ * after a server restart. Because arena->memstats.sealed wouldn't
+ * be set, the server might try to fit another block into the arena
+ * (and succeed), violating the append-only structure of the log
+ * and invalidating any already-computed seal on the arena.
+ *
+ * It might end up that other fields in arena->memstats end up
+ * behind arena->diskstats too, but that would be considerably
+ * more rare, and the bug is fixed now. The case we need to
+ * handle is just the sealed mismatch.
+ *
+ * If we encounter such a bogus arena, fix the sealed field.
+ */
+ if(arena->diskstats.sealed)
+ arena->memstats.sealed = 1;
}else
arena->memstats = arena->diskstats;
if(buf + sz != p)
@@ -262,6 +283,11 @@ _packarena(Arena *arena, u8int *buf, int forceext)
p += U64Size;
U8PUT(p, arena->memstats.sealed);
p += U8Size;
+ }else{
+ /* Clear any extension fields already on disk. */
+ memset(p, 0, ArenaSize5a - ArenaSize5);
+ p += ArenaSize5a - ArenaSize5;
+ sz += ArenaSize5a - ArenaSize5;
}
if(buf + sz != p)