From f258e7dddeb4331d2cf4649541c1a3adfa7a416a Mon Sep 17 00:00:00 2001 From: Mark Vitale Date: Mon, 27 Aug 2012 15:11:32 -0400 Subject: [PATCH] vos: convertROtoRW - prevent VLDB corruption vos convertROtoRW incorrectly marks the first VLDB entry as the new RW if the converted RO is not in the VLDB. Correct this by creating a new valid RW site in the VLDB entry. Change-Id: I683ac10db90c2c41717c11c0d86eadc81a935e52 Reviewed-on: http://gerrit.openafs.org/8037 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/volser/vos.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/volser/vos.c b/src/volser/vos.c index 6d2c0b2..273b6f6 100644 --- a/src/volser/vos.c +++ b/src/volser/vos.c @@ -5650,9 +5650,29 @@ ConvertRO(struct cmd_syndesc *as, void *arock) PrintError("convertROtoRW ", code); goto error_exit; } - entry.serverFlags[roindex] = ITSRWVOL; + /* Update the VLDB to match what we did on disk as much as possible. */ + /* If the converted RO was in the VLDB, make it look like the new RW. */ + if (roserver) { + entry.serverFlags[roindex] = ITSRWVOL; + } else { + /* Add a new site entry for the newly created RW. It's possible + * (but unlikely) that we are already at MAXNSERVERS and that this + * new site will invalidate the whole VLDB entry; however, + * VLDB_ReplaceEntry will detect this and return VL_BADSERVER, + * so we need no extra guard logic here. + */ + afs_int32 newrwindex = entry.nServers; + (entry.nServers)++; + entry.serverNumber[newrwindex] = server; + entry.serverPartition[newrwindex] = partition; + entry.serverFlags[newrwindex] = ITSRWVOL; + } entry.flags |= RW_EXISTS; entry.flags &= ~BACK_EXISTS; + + /* if the old RW was in the VLDB, remove it by decrementing the number */ + /* of servers, replacing the RW entry with the last entry, and zeroing */ + /* out the last entry. */ if (rwserver) { (entry.nServers)--; if (rwindex != entry.nServers) { -- 1.9.4