afs_int32
IdHash(afs_uint32 volid)
{
- return ((abs(volid)) % HASHSIZE);
+ return (volid % HASHSIZE);
}
#define LEGALCHARS ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
vldbread(addr, (char *)mhblockP, VL_ADDREXTBLK_SIZE);
+ /* Every mh block has the VLCONTBLOCK flag set in the header to
+ * indicate the entry is an 8192 byte extended block. The
+ * VLCONTBLOCK flag is always clear in regular vl entries. The
+ * vlserver depends on the VLCONTBLOCK flag to correctly traverse
+ * the vldb. The flags field is in network byte order. */
+ mhblockP->ex_hdrflags = ntohl(mhblockP->ex_hdrflags);
+
if (block == 0) {
+ /* These header fields are only used in the first mh block. */
mhblockP->ex_count = ntohl(mhblockP->ex_count);
- mhblockP->ex_hdrflags = ntohl(mhblockP->ex_hdrflags);
for (i = 0; i < VL_MAX_ADDREXTBLKS; i++) {
mhblockP->ex_contaddrs[i] = ntohl(mhblockP->ex_contaddrs[i]);
}
if (verbose) {
quiet_println("Writing back MH block % at addr %u\n", block, addr);
}
+ mhblockP->ex_hdrflags = htonl(mhblockP->ex_hdrflags);
if (block == 0) {
+ /*
+ * These header fields are only used in the first mh block, so were
+ * converted to host byte order only when the first mh block was read.
+ */
mhblockP->ex_count = htonl(mhblockP->ex_count);
- mhblockP->ex_hdrflags = htonl(mhblockP->ex_hdrflags);
for (i = 0; i < VL_MAX_ADDREXTBLKS; i++) {
mhblockP->ex_contaddrs[i] = htonl(mhblockP->ex_contaddrs[i]);
}
readMH(mhinfo[i].addr, i, MHblock);
if (MHblock->ex_hdrflags != VLCONTBLOCK) {
log_error
- (VLDB_CHECK_ERROR,"address %u (offset 0x%0x): Multihomed Block 0: Not a multihomed block\n",
- header->SIT, OFFSET(header->SIT));
+ (VLDB_CHECK_ERROR,"address %u (offset 0x%0x): Multihomed Block %d: Not a multihomed block\n",
+ mhinfo[i].addr, OFFSET(mhinfo[i].addr), i);
}
rindex = mhinfo[i].addr / sizeof(vlentry);
if (fix) {
/*
- * If we are fixing we will rebuild all the hash lists from the ground up
+ * If we are fixing we will rebuild the free and hash lists from the ground up.
*/
+ header.vital_header.freePtr = 0;
memcpy(oldnamehash, header.VolnameHash, sizeof(oldnamehash));
memset(header.VolnameHash, 0, sizeof(header.VolnameHash));
log_error(VLDB_CHECK_ERROR,"address %u (offset 0x%0x): Record not in a BK chain (type 0x%0x)\n",
record[i].addr, OFFSET(record[i].addr), record[i].type);
}
+ if ((vlentry.LockTimestamp == 0 && (vlentry.flags & VLOP_ALLOPERS) != 0) ||
+ (vlentry.LockTimestamp != 0 && (vlentry.flags & VLOP_ALLOPERS) == 0)) {
+ log_error(VLDB_CHECK_ERROR,
+ "address %u (offset 0x%0x): Lock inconsistency in volume '%s'; timestamp %d, lock flags 0x%0x\n",
+ record[i].addr, OFFSET(record[i].addr), vlentry.name,
+ vlentry.LockTimestamp, (vlentry.flags & VLOP_ALLOPERS));
+ }
+
if (fix) {
afs_uint32 oldhash, newhash;
char oldNameBuffer[10 + VL_MAXNAMELEN];
vlentry.nextIdHash[j] = header.VolidHash[j][hash];
header.VolidHash[j][hash] = record[i].addr;
}
+
+ /*
+ * Fix lock timestamp and flag inconsistencies.
+ */
+ if (vlentry.LockTimestamp == 0 && (vlentry.flags & VLOP_ALLOPERS) != 0) {
+ quiet_println("FIX: Record %u: Inconsistent lock in volume %s; setting timestamp.\n",
+ record[i].addr, vlentry.name);
+ vlentry.LockTimestamp = time(NULL);
+ }
+ if (vlentry.LockTimestamp != 0 && (vlentry.flags & VLOP_ALLOPERS) == 0) {
+ quiet_println("FIX: Record %u: Inconsistent lock in volume %s; setting misc lock flag.\n",
+ record[i].addr, vlentry.name);
+ vlentry.flags |= VLOP_DELETE; /* Shown by vos as "delete/misc". */
+ }
+
writeentry(record[i].addr, &vlentry);
}
}
}
writeMH(record[i].addr, block, MHblock);
}
+ } else if (record[i].type & FR) {
+ if (fix) {
+ readentry(record[i].addr, &vlentry, &type);
+ vlentry.nextIdHash[0] = header.vital_header.freePtr;
+ header.vital_header.freePtr = record[i].addr;
+ if ((record[i].type & FRC) == 0) {
+ quiet_println
+ ("FIX: Putting free entry on the free chain: addr=%lu (offset 0x%0x)\n",
+ record[i].addr, OFFSET(record[i].addr));
+ }
+ writeentry(record[i].addr, &vlentry);
+ }
}
}
if (fix) {
setlinebuf(stdout);
- ts = cmd_CreateSyntax(NULL, WorkerBee, NULL, "vldb check");
+ ts = cmd_CreateSyntax(NULL, WorkerBee, NULL, 0, "vldb check");
cmd_AddParm(ts, "-database", CMD_SINGLE, CMD_REQUIRED, "vldb_file");
cmd_AddParm(ts, "-uheader", CMD_FLAG, CMD_OPTIONAL,
"Display UBIK header");