/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
#include <afsconfig.h>
#include <afs/param.h>
-
-#include <sys/types.h>
-#include <string.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
+#include <roken.h>
#include <lock.h>
#include <rx/xdr.h>
#include <ubik.h>
+
#include "vlserver.h"
#include "vlserver_internal.h"
-extern struct vlheader cheader;
struct vlheader xheader;
-extern afs_uint32 HostAddress[];
extern int maxnservers;
-struct extentaddr extentaddr;
-extern struct extentaddr *ex_addr[];
+extern afs_uint32 rd_HostAddress[MAXSERVERID + 1];
+extern afs_uint32 wr_HostAddress[MAXSERVERID + 1];
+struct extentaddr *rd_ex_addr[VL_MAX_ADDREXTBLKS] = { 0, 0, 0, 0 };
+struct extentaddr *wr_ex_addr[VL_MAX_ADDREXTBLKS] = { 0, 0, 0, 0 };
+struct vlheader rd_cheader; /* kept in network byte order */
+struct vlheader wr_cheader;
int vldbversion = 0;
-static int index_OK(struct ubik_trans *trans, afs_int32 blockindex);
+static int index_OK(struct vl_ctx *ctx, afs_int32 blockindex);
-#define ERROR_EXIT(code) {error=(code); goto error_exit;}
+#define ERROR_EXIT(code) do { \
+ error = (code); \
+ goto error_exit; \
+} while (0)
/* Hashing algorithm based on the volume id; HASHSIZE must be prime */
afs_int32
/* Convenient write of small critical vldb header info to the database. */
int
-write_vital_vlheader(struct ubik_trans *trans)
+write_vital_vlheader(struct vl_ctx *ctx)
{
if (vlwrite
- (trans, 0, (char *)&cheader.vital_header, sizeof(vital_vlheader)))
+ (ctx->trans, 0, (char *)&ctx->cheader->vital_header, sizeof(vital_vlheader)))
return VL_IO;
return 0;
}
int i;
extent_mod = 0;
- extentAddr = ntohl(cheader.SIT);
+ extentAddr = ntohl(rd_cheader.SIT);
if (!extentAddr)
return 0;
/* Read the first extension block */
- if (!ex_addr[0]) {
- ex_addr[0] = (struct extentaddr *)malloc(VL_ADDREXTBLK_SIZE);
- if (!ex_addr[0])
+ if (!rd_ex_addr[0]) {
+ rd_ex_addr[0] = malloc(VL_ADDREXTBLK_SIZE);
+ if (!rd_ex_addr[0])
ERROR_EXIT(VL_NOMEM);
}
- code = vlread(trans, extentAddr, (char *)ex_addr[0], VL_ADDREXTBLK_SIZE);
+ code = vlread(trans, extentAddr, (char *)rd_ex_addr[0], VL_ADDREXTBLK_SIZE);
if (code) {
- free(ex_addr[0]); /* Not the place to create it */
- ex_addr[0] = 0;
+ free(rd_ex_addr[0]); /* Not the place to create it */
+ rd_ex_addr[0] = 0;
ERROR_EXIT(VL_IO);
}
* continuation blocks
*/
for (i = 1; i < VL_MAX_ADDREXTBLKS; i++) {
- if (!ex_addr[0]->ex_contaddrs[i])
+ if (!rd_ex_addr[0]->ex_contaddrs[i])
continue;
/* Before reading it in, check to see if the address is good */
- if ((ntohl(ex_addr[0]->ex_contaddrs[i]) <
- ntohl(ex_addr[0]->ex_contaddrs[i - 1]) + VL_ADDREXTBLK_SIZE)
- || (ntohl(ex_addr[0]->ex_contaddrs[i]) >
- ntohl(cheader.vital_header.eofPtr) - VL_ADDREXTBLK_SIZE)) {
+ if ((ntohl(rd_ex_addr[0]->ex_contaddrs[i]) <
+ ntohl(rd_ex_addr[0]->ex_contaddrs[i - 1]) + VL_ADDREXTBLK_SIZE)
+ || (ntohl(rd_ex_addr[0]->ex_contaddrs[i]) >
+ ntohl(rd_cheader.vital_header.eofPtr) - VL_ADDREXTBLK_SIZE)) {
extent_mod = 1;
- ex_addr[0]->ex_contaddrs[i] = 0;
+ rd_ex_addr[0]->ex_contaddrs[i] = 0;
continue;
}
/* Read the continuation block */
- if (!ex_addr[i]) {
- ex_addr[i] = (struct extentaddr *)malloc(VL_ADDREXTBLK_SIZE);
- if (!ex_addr[i])
+ if (!rd_ex_addr[i]) {
+ rd_ex_addr[i] = malloc(VL_ADDREXTBLK_SIZE);
+ if (!rd_ex_addr[i])
ERROR_EXIT(VL_NOMEM);
}
code =
- vlread(trans, ntohl(ex_addr[0]->ex_contaddrs[i]),
- (char *)ex_addr[i], VL_ADDREXTBLK_SIZE);
+ vlread(trans, ntohl(rd_ex_addr[0]->ex_contaddrs[i]),
+ (char *)rd_ex_addr[i], VL_ADDREXTBLK_SIZE);
if (code) {
- free(ex_addr[i]); /* Not the place to create it */
- ex_addr[i] = 0;
+ free(rd_ex_addr[i]); /* Not the place to create it */
+ rd_ex_addr[i] = 0;
ERROR_EXIT(VL_IO);
}
/* After reading it in, check to see if its a real continuation block */
- if (ntohl(ex_addr[i]->ex_flags) != VLCONTBLOCK) {
+ if (ntohl(rd_ex_addr[i]->ex_hdrflags) != VLCONTBLOCK) {
extent_mod = 1;
- ex_addr[0]->ex_contaddrs[i] = 0;
- free(ex_addr[i]); /* Not the place to create it */
- ex_addr[i] = 0;
+ rd_ex_addr[0]->ex_contaddrs[i] = 0;
+ free(rd_ex_addr[i]); /* Not the place to create it */
+ rd_ex_addr[i] = 0;
continue;
}
}
if (extent_mod) {
- code = vlwrite(trans, extentAddr, ex_addr[0], VL_ADDREXTBLK_SIZE);
+ code = vlwrite(trans, extentAddr, rd_ex_addr[0], VL_ADDREXTBLK_SIZE);
if (!code) {
VLog(0, ("Multihome server support modification\n"));
}
afs_int32 error = 0, i, code, ubcode;
/* if version changed (or first call), read the header */
- ubcode = vlread(trans, 0, (char *)&cheader, sizeof(cheader));
- vldbversion = ntohl(cheader.vital_header.vldbversion);
+ ubcode = vlread(trans, 0, (char *)&rd_cheader, sizeof(rd_cheader));
+ vldbversion = ntohl(rd_cheader.vital_header.vldbversion);
if (!ubcode && (vldbversion != 0)) {
- memcpy(HostAddress, cheader.IpMappedAddr, sizeof(cheader.IpMappedAddr));
+ memcpy(rd_HostAddress, rd_cheader.IpMappedAddr, sizeof(rd_cheader.IpMappedAddr));
for (i = 0; i < MAXSERVERID + 1; i++) { /* cvt HostAddress to host order */
- HostAddress[i] = ntohl(HostAddress[i]);
+ rd_HostAddress[i] = ntohl(rd_HostAddress[i]);
}
code = readExtents(trans);
printf("Can't read VLDB header, re-initialising...\n");
/* try to write a good header */
- memset(&cheader, 0, sizeof(cheader));
- cheader.vital_header.vldbversion = htonl(VLDBVERSION);
- cheader.vital_header.headersize = htonl(sizeof(cheader));
+ memset(&rd_cheader, 0, sizeof(rd_cheader));
+ rd_cheader.vital_header.vldbversion = htonl(VLDBVERSION);
+ rd_cheader.vital_header.headersize = htonl(sizeof(rd_cheader));
/* DANGER: Must get this from a master place!! */
- cheader.vital_header.MaxVolumeId = htonl(0x20000000);
- cheader.vital_header.eofPtr = htonl(sizeof(cheader));
+ rd_cheader.vital_header.MaxVolumeId = htonl(0x20000000);
+ rd_cheader.vital_header.eofPtr = htonl(sizeof(rd_cheader));
for (i = 0; i < MAXSERVERID + 1; i++) {
- cheader.IpMappedAddr[i] = 0;
- HostAddress[i] = 0;
+ rd_cheader.IpMappedAddr[i] = 0;
+ rd_HostAddress[i] = 0;
}
- code = vlwrite(trans, 0, (char *)&cheader, sizeof(cheader));
+ code = vlwrite(trans, 0, (char *)&rd_cheader, sizeof(rd_cheader));
if (code) {
printf("Can't write VLDB header (error = %d)\n", code);
ERROR_EXIT(VL_IO);
}
- vldbversion = ntohl(cheader.vital_header.vldbversion);
+ vldbversion = ntohl(rd_cheader.vital_header.vldbversion);
} else {
ERROR_EXIT(VL_EMPTY);
}
afs_int32
-GetExtentBlock(struct ubik_trans *trans, afs_int32 base)
+GetExtentBlock(struct vl_ctx *ctx, register afs_int32 base)
{
afs_int32 blockindex, code, error = 0;
/* Base 0 must exist before any other can be created */
- if ((base != 0) && !ex_addr[0])
+ if ((base != 0) && !ctx->ex_addr[0])
ERROR_EXIT(VL_CREATEFAIL); /* internal error */
- if (!ex_addr[0] || !ex_addr[0]->ex_contaddrs[base]) {
+ if (!ctx->ex_addr[0] || !ctx->ex_addr[0]->ex_contaddrs[base]) {
/* Create a new extension block */
- if (!ex_addr[base]) {
- ex_addr[base] = (struct extentaddr *)malloc(VL_ADDREXTBLK_SIZE);
- if (!ex_addr[base])
+ if (!ctx->ex_addr[base]) {
+ ctx->ex_addr[base] = malloc(VL_ADDREXTBLK_SIZE);
+ if (!ctx->ex_addr[base])
ERROR_EXIT(VL_NOMEM);
}
- memset(ex_addr[base], 0, VL_ADDREXTBLK_SIZE);
+ memset(ctx->ex_addr[base], 0, VL_ADDREXTBLK_SIZE);
/* Write the full extension block at end of vldb */
- ex_addr[base]->ex_flags = htonl(VLCONTBLOCK);
- blockindex = ntohl(cheader.vital_header.eofPtr);
+ ctx->ex_addr[base]->ex_hdrflags = htonl(VLCONTBLOCK);
+ blockindex = ntohl(ctx->cheader->vital_header.eofPtr);
code =
- vlwrite(trans, blockindex, (char *)ex_addr[base],
+ vlwrite(ctx->trans, blockindex, (char *)ctx->ex_addr[base],
VL_ADDREXTBLK_SIZE);
if (code)
ERROR_EXIT(VL_IO);
/* Update the cheader.vitalheader structure on disk */
- cheader.vital_header.eofPtr = blockindex + VL_ADDREXTBLK_SIZE;
- cheader.vital_header.eofPtr = htonl(cheader.vital_header.eofPtr);
- code = write_vital_vlheader(trans);
+ ctx->cheader->vital_header.eofPtr = blockindex + VL_ADDREXTBLK_SIZE;
+ ctx->cheader->vital_header.eofPtr = htonl(ctx->cheader->vital_header.eofPtr);
+ code = write_vital_vlheader(ctx);
if (code)
ERROR_EXIT(VL_IO);
/* Write the address of the base extension block in the vldb header */
if (base == 0) {
- cheader.SIT = htonl(blockindex);
+ ctx->cheader->SIT = htonl(blockindex);
code =
- vlwrite(trans, DOFFSET(0, &cheader, &cheader.SIT),
- (char *)&cheader.SIT, sizeof(cheader.SIT));
+ vlwrite(ctx->trans, DOFFSET(0, ctx->cheader, &ctx->cheader->SIT),
+ (char *)&ctx->cheader->SIT, sizeof(ctx->cheader->SIT));
if (code)
ERROR_EXIT(VL_IO);
}
/* Write the address of this extension block into the base extension block */
- ex_addr[0]->ex_contaddrs[base] = htonl(blockindex);
+ ctx->ex_addr[0]->ex_contaddrs[base] = htonl(blockindex);
code =
- vlwrite(trans, ntohl(cheader.SIT), ex_addr[0],
+ vlwrite(ctx->trans, ntohl(ctx->cheader->SIT), ctx->ex_addr[0],
sizeof(struct extentaddr));
if (code)
ERROR_EXIT(VL_IO);
afs_int32
-FindExtentBlock(struct ubik_trans *trans, afsUUID *uuidp,
+FindExtentBlock(struct vl_ctx *ctx, afsUUID *uuidp,
afs_int32 createit, afs_int32 hostslot,
struct extentaddr **expp, afs_int32 *basep)
{
*basep = 0;
/* Create the first extension block if it does not exist */
- if (!cheader.SIT) {
- code = GetExtentBlock(trans, 0);
+ if (!ctx->cheader->SIT) {
+ code = GetExtentBlock(ctx, 0);
if (code)
ERROR_EXIT(code);
}
for (i = 0; i < MAXSERVERID + 1; i++) {
- if ((HostAddress[i] & 0xff000000) == 0xff000000) {
- if ((base = (HostAddress[i] >> 16) & 0xff) > VL_MAX_ADDREXTBLKS) {
+ if ((ctx->hostaddress[i] & 0xff000000) == 0xff000000) {
+ if ((base = (ctx->hostaddress[i] >> 16) & 0xff) > VL_MAX_ADDREXTBLKS) {
ERROR_EXIT(VL_INDEXERANGE);
}
- if ((index = HostAddress[i] & 0x0000ffff) > VL_MHSRV_PERBLK) {
+ if ((index = ctx->hostaddress[i] & 0x0000ffff) > VL_MHSRV_PERBLK) {
ERROR_EXIT(VL_INDEXERANGE);
}
- exp = &ex_addr[base][index];
+ exp = &ctx->ex_addr[base][index];
tuuid = exp->ex_hostuuid;
afs_ntohuuid(&tuuid);
if (afs_uuid_equal(uuidp, &tuuid)) {
if (createit) {
if (hostslot == -1) {
for (i = 0; i < MAXSERVERID + 1; i++) {
- if (!HostAddress[i])
+ if (!ctx->hostaddress[i])
break;
}
if (i > MAXSERVERID)
}
for (base = 0; base < VL_MAX_ADDREXTBLKS; base++) {
- if (!ex_addr[0]->ex_contaddrs[base]) {
- code = GetExtentBlock(trans, base);
+ if (!ctx->ex_addr[0]->ex_contaddrs[base]) {
+ code = GetExtentBlock(ctx, base);
if (code)
ERROR_EXIT(code);
}
for (j = 1; j < VL_MHSRV_PERBLK; j++) {
- exp = &ex_addr[base][j];
+ exp = &ctx->ex_addr[base][j];
tuuid = exp->ex_hostuuid;
afs_ntohuuid(&tuuid);
if (afs_uuid_is_nil(&tuuid)) {
afs_htonuuid(&tuuid);
exp->ex_hostuuid = tuuid;
code =
- vlwrite(trans,
- DOFFSET(ntohl(ex_addr[0]->ex_contaddrs[base]),
- (char *)ex_addr[base], (char *)exp),
+ vlwrite(ctx->trans,
+ DOFFSET(ntohl(ctx->ex_addr[0]->ex_contaddrs[base]),
+ (char *)ctx->ex_addr[base], (char *)exp),
(char *)&tuuid, sizeof(tuuid));
if (code)
ERROR_EXIT(VL_IO);
- HostAddress[i] =
+ ctx->hostaddress[i] =
0xff000000 | ((base << 16) & 0xff0000) | (j & 0xffff);
*expp = exp;
*basep = base;
if (vldbversion != VLDBVERSION_4) {
- cheader.vital_header.vldbversion =
+ ctx->cheader->vital_header.vldbversion =
htonl(VLDBVERSION_4);
- code = write_vital_vlheader(trans);
+ code = write_vital_vlheader(ctx);
if (code)
ERROR_EXIT(VL_IO);
}
- cheader.IpMappedAddr[i] = htonl(HostAddress[i]);
+ ctx->cheader->IpMappedAddr[i] = htonl(ctx->hostaddress[i]);
code =
- vlwrite(trans,
- DOFFSET(0, &cheader,
- &cheader.IpMappedAddr[i]),
- (char *)&cheader.IpMappedAddr[i],
+ vlwrite(ctx->trans,
+ DOFFSET(0, ctx->cheader,
+ &ctx->cheader->IpMappedAddr[i]),
+ (char *)&ctx->cheader->IpMappedAddr[i],
sizeof(afs_int32));
if (code)
ERROR_EXIT(VL_IO);
/* Allocate a free block of storage for entry, returning address of a new
zeroed entry (or zero if something is wrong). */
afs_int32
-AllocBlock(struct ubik_trans *trans, struct nvlentry *tentry)
+AllocBlock(struct vl_ctx *ctx, struct nvlentry *tentry)
{
afs_int32 blockindex;
- if (cheader.vital_header.freePtr) {
+ if (ctx->cheader->vital_header.freePtr) {
/* allocate this dude */
- blockindex = ntohl(cheader.vital_header.freePtr);
- if (vlentryread(trans, blockindex, (char *)tentry, sizeof(vlentry)))
+ blockindex = ntohl(ctx->cheader->vital_header.freePtr);
+ if (vlentryread(ctx->trans, blockindex, (char *)tentry, sizeof(vlentry)))
return 0;
- cheader.vital_header.freePtr = htonl(tentry->nextIdHash[0]);
+ ctx->cheader->vital_header.freePtr = htonl(tentry->nextIdHash[0]);
} else {
/* hosed, nothing on free list, grow file */
- blockindex = ntohl(cheader.vital_header.eofPtr); /* remember this guy */
- cheader.vital_header.eofPtr = htonl(blockindex + sizeof(vlentry));
+ blockindex = ntohl(ctx->cheader->vital_header.eofPtr); /* remember this guy */
+ ctx->cheader->vital_header.eofPtr = htonl(blockindex + sizeof(vlentry));
}
- cheader.vital_header.allocs++;
- if (write_vital_vlheader(trans))
+ ctx->cheader->vital_header.allocs++;
+ if (write_vital_vlheader(ctx))
return 0;
memset(tentry, 0, sizeof(nvlentry)); /* zero new entry */
return blockindex;
/* Free a block given its index. It must already have been unthreaded. Returns zero for success or an error code on failure. */
int
-FreeBlock(struct ubik_trans *trans, afs_int32 blockindex)
+FreeBlock(struct vl_ctx *ctx, afs_int32 blockindex)
{
struct nvlentry tentry;
/* check validity of blockindex just to be on the safe side */
- if (!index_OK(trans, blockindex))
+ if (!index_OK(ctx, blockindex))
return VL_BADINDEX;
memset(&tentry, 0, sizeof(nvlentry));
- tentry.nextIdHash[0] = cheader.vital_header.freePtr; /* already in network order */
+ tentry.nextIdHash[0] = ctx->cheader->vital_header.freePtr; /* already in network order */
tentry.flags = htonl(VLFREE);
- cheader.vital_header.freePtr = htonl(blockindex);
- if (vlwrite(trans, blockindex, (char *)&tentry, sizeof(nvlentry)))
+ ctx->cheader->vital_header.freePtr = htonl(blockindex);
+ if (vlwrite(ctx->trans, blockindex, (char *)&tentry, sizeof(nvlentry)))
return VL_IO;
- cheader.vital_header.frees++;
- if (write_vital_vlheader(trans))
+ ctx->cheader->vital_header.frees++;
+ if (write_vital_vlheader(ctx))
return VL_IO;
return 0;
}
* pointed to by tentry and return the block's index. If not found return 0.
*/
afs_int32
-FindByID(struct ubik_trans *trans, afs_uint32 volid, afs_int32 voltype,
+FindByID(struct vl_ctx *ctx, afs_uint32 volid, afs_int32 voltype,
struct nvlentry *tentry, afs_int32 *error)
{
afs_int32 typeindex, hashindex, blockindex;
if (voltype == -1) {
/* Should we have one big hash table for volids as opposed to the three ones? */
for (typeindex = 0; typeindex < MAXTYPES; typeindex++) {
- for (blockindex = ntohl(cheader.VolidHash[typeindex][hashindex]);
+ for (blockindex = ntohl(ctx->cheader->VolidHash[typeindex][hashindex]);
blockindex != NULLO;
blockindex = tentry->nextIdHash[typeindex]) {
if (vlentryread
- (trans, blockindex, (char *)tentry, sizeof(nvlentry))) {
+ (ctx->trans, blockindex, (char *)tentry, sizeof(nvlentry))) {
*error = VL_IO;
return 0;
}
}
}
} else {
- for (blockindex = ntohl(cheader.VolidHash[voltype][hashindex]);
+ for (blockindex = ntohl(ctx->cheader->VolidHash[voltype][hashindex]);
blockindex != NULLO; blockindex = tentry->nextIdHash[voltype]) {
if (vlentryread
- (trans, blockindex, (char *)tentry, sizeof(nvlentry))) {
+ (ctx->trans, blockindex, (char *)tentry, sizeof(nvlentry))) {
*error = VL_IO;
return 0;
}
* found return 0.
*/
afs_int32
-FindByName(struct ubik_trans *trans, char *volname, struct nvlentry *tentry,
+FindByName(struct vl_ctx *ctx, char *volname, struct nvlentry *tentry,
afs_int32 *error)
{
afs_int32 hashindex;
*error = 0;
hashindex = NameHash(tname);
- for (blockindex = ntohl(cheader.VolnameHash[hashindex]);
+ for (blockindex = ntohl(ctx->cheader->VolnameHash[hashindex]);
blockindex != NULLO; blockindex = tentry->nextNameHash) {
- if (vlentryread(trans, blockindex, (char *)tentry, sizeof(nvlentry))) {
+ if (vlentryread(ctx->trans, blockindex, (char *)tentry, sizeof(nvlentry))) {
*error = VL_IO;
return 0;
}
* Returns whether or not any of the supplied volume IDs already exist
* in the vldb.
*
- * @param trans the ubik transaction
+ * @param ctx transaction context
* @param ids an array of volume IDs
* @param ids_len the number of elements in the 'ids' array
* @param error filled in with an error code in case of error
* @retval 0 none of the volume IDs are used, or an error occurred
*/
int
-EntryIDExists(struct ubik_trans *trans, const afs_uint32 *ids,
+EntryIDExists(struct vl_ctx *ctx, const afs_uint32 *ids,
afs_int32 ids_len, afs_int32 *error)
{
afs_int32 typeindex;
for (typeindex = 0; typeindex < ids_len; typeindex++) {
if (ids[typeindex]
- && FindByID(trans, ids[typeindex], -1, &tentry, error)) {
+ && FindByID(ctx, ids[typeindex], -1, &tentry, error)) {
return 1;
} else if (*error) {
/**
* Finds the next range of unused volume IDs in the vldb.
*
- * @param trans the ubik transaction
+ * @param ctx transaction context
* @param maxvolid the current max vol ID, and where to start looking
* for an unused volume ID range
* @param bump how many volume IDs we need to be unused
* an error
*/
afs_uint32
-NextUnusedID(struct ubik_trans *trans, afs_uint32 maxvolid, afs_uint32 bump,
+NextUnusedID(struct vl_ctx *ctx, afs_uint32 maxvolid, afs_uint32 bump,
afs_int32 *error)
{
struct nvlentry tentry;
* how many free volume IDs we've seen in a row, and return when
* we've seen 'bump' unused IDs in a row */
for (id = maxvolid, nfree = 0; nfree < bump; ++id) {
- if (FindByID(trans, id, -1, &tentry, error)) {
+ if (FindByID(ctx, id, -1, &tentry, error)) {
nfree = 0;
} else if (*error) {
return 0;
}
int
-HashNDump(struct ubik_trans *trans, int hashindex)
+HashNDump(struct vl_ctx *ctx, int hashindex)
{
int i = 0;
int blockindex;
struct nvlentry tentry;
- for (blockindex = ntohl(cheader.VolnameHash[hashindex]);
+ for (blockindex = ntohl(ctx->cheader->VolnameHash[hashindex]);
blockindex != NULLO; blockindex = tentry.nextNameHash) {
- if (vlentryread(trans, blockindex, (char *)&tentry, sizeof(nvlentry)))
+ if (vlentryread(ctx->trans, blockindex, (char *)&tentry, sizeof(nvlentry)))
return 0;
i++;
VLog(0,
int
-HashIdDump(struct ubik_trans *trans, int hashindex)
+HashIdDump(struct vl_ctx *ctx, int hashindex)
{
int i = 0;
int blockindex;
struct nvlentry tentry;
- for (blockindex = ntohl(cheader.VolidHash[0][hashindex]);
+ for (blockindex = ntohl(ctx->cheader->VolidHash[0][hashindex]);
blockindex != NULLO; blockindex = tentry.nextIdHash[0]) {
- if (vlentryread(trans, blockindex, (char *)&tentry, sizeof(nvlentry)))
+ if (vlentryread(ctx->trans, blockindex, (char *)&tentry, sizeof(nvlentry)))
return 0;
i++;
VLog(0,
* routine returns zero if there were no errors.
*/
int
-ThreadVLentry(struct ubik_trans *trans, afs_int32 blockindex,
+ThreadVLentry(struct vl_ctx *ctx, afs_int32 blockindex,
struct nvlentry *tentry)
{
int errorcode;
- if (!index_OK(trans, blockindex))
+ if (!index_OK(ctx, blockindex))
return VL_BADINDEX;
/* Insert into volid's hash linked list */
- if ((errorcode = HashVolid(trans, RWVOL, blockindex, tentry)))
+ if ((errorcode = HashVolid(ctx, RWVOL, blockindex, tentry)))
return errorcode;
/* For rw entries we also enter the RO and BACK volume ids (if they
* exist) in the hash tables; note all there volids (RW, RO, BACK)
* should not be hashed yet! */
if (tentry->volumeId[ROVOL]) {
- if ((errorcode = HashVolid(trans, ROVOL, blockindex, tentry)))
+ if ((errorcode = HashVolid(ctx, ROVOL, blockindex, tentry)))
return errorcode;
}
if (tentry->volumeId[BACKVOL]) {
- if ((errorcode = HashVolid(trans, BACKVOL, blockindex, tentry)))
+ if ((errorcode = HashVolid(ctx, BACKVOL, blockindex, tentry)))
return errorcode;
}
/* Insert into volname's hash linked list */
- HashVolname(trans, blockindex, tentry);
+ HashVolname(ctx, blockindex, tentry);
/* Update cheader entry */
- if (write_vital_vlheader(trans))
+ if (write_vital_vlheader(ctx))
return VL_IO;
/* Update hash list pointers in the entry itself */
- if (vlentrywrite(trans, blockindex, (char *)tentry, sizeof(nvlentry)))
+ if (vlentrywrite(ctx->trans, blockindex, (char *)tentry, sizeof(nvlentry)))
return VL_IO;
return 0;
}
/* Remove a block from both the hash tables. If success return 0, else
* return an error code. */
int
-UnthreadVLentry(struct ubik_trans *trans, afs_int32 blockindex,
+UnthreadVLentry(struct vl_ctx *ctx, afs_int32 blockindex,
struct nvlentry *aentry)
{
afs_int32 errorcode, typeindex;
- if (!index_OK(trans, blockindex))
+ if (!index_OK(ctx, blockindex))
return VL_BADINDEX;
- if ((errorcode = UnhashVolid(trans, RWVOL, blockindex, aentry)))
+ if ((errorcode = UnhashVolid(ctx, RWVOL, blockindex, aentry)))
return errorcode;
/* Take the RO/RW entries of their respective hash linked lists. */
for (typeindex = ROVOL; typeindex <= BACKVOL; typeindex++) {
- if ((errorcode = UnhashVolid(trans, typeindex, blockindex, aentry)))
+ if ((errorcode = UnhashVolid(ctx, typeindex, blockindex, aentry)))
return errorcode;
}
/* Take it out of the Volname hash list */
- if ((errorcode = UnhashVolname(trans, blockindex, aentry)))
+ if ((errorcode = UnhashVolname(ctx, blockindex, aentry)))
return errorcode;
/* Update cheader entry */
- write_vital_vlheader(trans);
+ write_vital_vlheader(ctx);
return 0;
}
/* cheader must have be read before this routine is called. */
int
-HashVolid(struct ubik_trans *trans, afs_int32 voltype, afs_int32 blockindex,
+HashVolid(struct vl_ctx *ctx, afs_int32 voltype, afs_int32 blockindex,
struct nvlentry *tentry)
{
afs_int32 hashindex, errorcode;
struct nvlentry ventry;
if (FindByID
- (trans, tentry->volumeId[voltype], voltype, &ventry, &errorcode))
+ (ctx, tentry->volumeId[voltype], voltype, &ventry, &errorcode))
return VL_IDALREADYHASHED;
else if (errorcode)
return errorcode;
hashindex = IDHash(tentry->volumeId[voltype]);
tentry->nextIdHash[voltype] =
- ntohl(cheader.VolidHash[voltype][hashindex]);
- cheader.VolidHash[voltype][hashindex] = htonl(blockindex);
+ ntohl(ctx->cheader->VolidHash[voltype][hashindex]);
+ ctx->cheader->VolidHash[voltype][hashindex] = htonl(blockindex);
if (vlwrite
- (trans, DOFFSET(0, &cheader, &cheader.VolidHash[voltype][hashindex]),
- (char *)&cheader.VolidHash[voltype][hashindex], sizeof(afs_int32)))
+ (ctx->trans, DOFFSET(0, ctx->cheader, &ctx->cheader->VolidHash[voltype][hashindex]),
+ (char *)&ctx->cheader->VolidHash[voltype][hashindex], sizeof(afs_int32)))
return VL_IO;
return 0;
}
/* cheader must have be read before this routine is called. */
int
-UnhashVolid(struct ubik_trans *trans, afs_int32 voltype, afs_int32 blockindex,
+UnhashVolid(struct vl_ctx *ctx, afs_int32 voltype, afs_int32 blockindex,
struct nvlentry *aentry)
{
int hashindex, nextblockindex, prevblockindex;
return 0;
/* Take it out of the VolId[voltype] hash list */
hashindex = IDHash(aentry->volumeId[voltype]);
- nextblockindex = ntohl(cheader.VolidHash[voltype][hashindex]);
+ nextblockindex = ntohl(ctx->cheader->VolidHash[voltype][hashindex]);
if (nextblockindex == blockindex) {
/* First on the hash list; just adjust pointers */
- cheader.VolidHash[voltype][hashindex] =
+ ctx->cheader->VolidHash[voltype][hashindex] =
htonl(aentry->nextIdHash[voltype]);
code =
- vlwrite(trans,
- DOFFSET(0, &cheader,
- &cheader.VolidHash[voltype][hashindex]),
- (char *)&cheader.VolidHash[voltype][hashindex],
+ vlwrite(ctx->trans,
+ DOFFSET(0, ctx->cheader,
+ &ctx->cheader->VolidHash[voltype][hashindex]),
+ (char *)&ctx->cheader->VolidHash[voltype][hashindex],
sizeof(afs_int32));
if (code)
return VL_IO;
while (nextblockindex != blockindex) {
prevblockindex = nextblockindex; /* always done once */
if (vlentryread
- (trans, nextblockindex, (char *)&tentry, sizeof(nvlentry)))
+ (ctx->trans, nextblockindex, (char *)&tentry, sizeof(nvlentry)))
return VL_IO;
if ((nextblockindex = tentry.nextIdHash[voltype]) == NULLO)
return VL_NOENT;
temp = tentry.nextIdHash[voltype] = aentry->nextIdHash[voltype];
temp = htonl(temp); /* convert to network byte order before writing */
if (vlwrite
- (trans,
+ (ctx->trans,
DOFFSET(prevblockindex, &tentry, &tentry.nextIdHash[voltype]),
(char *)&temp, sizeof(afs_int32)))
return VL_IO;
int
-HashVolname(struct ubik_trans *trans, afs_int32 blockindex,
+HashVolname(struct vl_ctx *ctx, afs_int32 blockindex,
struct nvlentry *aentry)
{
afs_int32 hashindex;
/* Insert into volname's hash linked list */
hashindex = NameHash(aentry->name);
- aentry->nextNameHash = ntohl(cheader.VolnameHash[hashindex]);
- cheader.VolnameHash[hashindex] = htonl(blockindex);
+ aentry->nextNameHash = ntohl(ctx->cheader->VolnameHash[hashindex]);
+ ctx->cheader->VolnameHash[hashindex] = htonl(blockindex);
code =
- vlwrite(trans, DOFFSET(0, &cheader, &cheader.VolnameHash[hashindex]),
- (char *)&cheader.VolnameHash[hashindex], sizeof(afs_int32));
+ vlwrite(ctx->trans, DOFFSET(0, ctx->cheader, &ctx->cheader->VolnameHash[hashindex]),
+ (char *)&ctx->cheader->VolnameHash[hashindex], sizeof(afs_int32));
if (code)
return VL_IO;
return 0;
int
-UnhashVolname(struct ubik_trans *trans, afs_int32 blockindex,
+UnhashVolname(struct vl_ctx *ctx, afs_int32 blockindex,
struct nvlentry *aentry)
{
afs_int32 hashindex, nextblockindex, prevblockindex;
/* Take it out of the Volname hash list */
hashindex = NameHash(aentry->name);
- nextblockindex = ntohl(cheader.VolnameHash[hashindex]);
+ nextblockindex = ntohl(ctx->cheader->VolnameHash[hashindex]);
if (nextblockindex == blockindex) {
/* First on the hash list; just adjust pointers */
- cheader.VolnameHash[hashindex] = htonl(aentry->nextNameHash);
+ ctx->cheader->VolnameHash[hashindex] = htonl(aentry->nextNameHash);
if (vlwrite
- (trans, DOFFSET(0, &cheader, &cheader.VolnameHash[hashindex]),
- (char *)&cheader.VolnameHash[hashindex], sizeof(afs_int32)))
+ (ctx->trans, DOFFSET(0, ctx->cheader, &ctx->cheader->VolnameHash[hashindex]),
+ (char *)&ctx->cheader->VolnameHash[hashindex], sizeof(afs_int32)))
return VL_IO;
} else {
while (nextblockindex != blockindex) {
prevblockindex = nextblockindex; /* always done at least once */
if (vlentryread
- (trans, nextblockindex, (char *)&tentry, sizeof(nvlentry)))
+ (ctx->trans, nextblockindex, (char *)&tentry, sizeof(nvlentry)))
return VL_IO;
if ((nextblockindex = tentry.nextNameHash) == NULLO)
return VL_NOENT;
tentry.nextNameHash = aentry->nextNameHash;
temp = htonl(tentry.nextNameHash);
if (vlwrite
- (trans, DOFFSET(prevblockindex, &tentry, &tentry.nextNameHash),
+ (ctx->trans, DOFFSET(prevblockindex, &tentry, &tentry.nextNameHash),
(char *)&temp, sizeof(afs_int32)))
return VL_IO;
}
*/
afs_int32
-NextEntry(struct ubik_trans *trans, afs_int32 blockindex,
+NextEntry(struct vl_ctx *ctx, afs_int32 blockindex,
struct nvlentry *tentry, afs_int32 *remaining)
{
afs_int32 lastblockindex;
if (blockindex == 0) /* get first one */
- blockindex = sizeof(cheader);
+ blockindex = sizeof(*ctx->cheader);
else {
- if (!index_OK(trans, blockindex)) {
+ if (!index_OK(ctx, blockindex)) {
*remaining = -1; /* error */
return 0;
}
blockindex += sizeof(nvlentry);
}
/* now search for the first entry that isn't free */
- for (lastblockindex = ntohl(cheader.vital_header.eofPtr);
+ for (lastblockindex = ntohl(ctx->cheader->vital_header.eofPtr);
blockindex < lastblockindex;) {
- if (vlentryread(trans, blockindex, (char *)tentry, sizeof(nvlentry))) {
+ if (vlentryread(ctx->trans, blockindex, (char *)tentry, sizeof(nvlentry))) {
*remaining = -1;
return 0;
}
* table
*/
static int
-index_OK(struct ubik_trans *trans, afs_int32 blockindex)
+index_OK(struct vl_ctx *ctx, afs_int32 blockindex)
{
- if ((blockindex < sizeof(cheader))
- || (blockindex >= ntohl(cheader.vital_header.eofPtr)))
+ if ((blockindex < sizeof(*ctx->cheader))
+ || (blockindex >= ntohl(ctx->cheader->vital_header.eofPtr)))
return 0;
return 1;
}
+
+/* makes a deep copy of src_ex into dst_ex */
+static int
+vlexcpy(struct extentaddr **dst_ex, struct extentaddr **src_ex)
+{
+ int i;
+ for (i = 0; i < VL_MAX_ADDREXTBLKS; i++) {
+ if (src_ex[i]) {
+ if (!dst_ex[i]) {
+ dst_ex[i] = malloc(VL_ADDREXTBLK_SIZE);
+ }
+ if (!dst_ex[i]) {
+ return VL_NOMEM;
+ }
+ memcpy(dst_ex[i], src_ex[i], VL_ADDREXTBLK_SIZE);
+
+ } else if (dst_ex[i]) {
+ /* we have no src, but we have a dst... meaning, this block
+ * has gone away */
+ free(dst_ex[i]);
+ dst_ex[i] = NULL;
+ }
+ }
+ return 0;
+}
+
+int
+vlsetcache(struct vl_ctx *ctx, int locktype)
+{
+ if (locktype == LOCKREAD) {
+ ctx->hostaddress = rd_HostAddress;
+ ctx->ex_addr = rd_ex_addr;
+ ctx->cheader = &rd_cheader;
+ return 0;
+ } else {
+ memcpy(wr_HostAddress, rd_HostAddress, sizeof(wr_HostAddress));
+ memcpy(&wr_cheader, &rd_cheader, sizeof(wr_cheader));
+
+ ctx->hostaddress = wr_HostAddress;
+ ctx->ex_addr = wr_ex_addr;
+ ctx->cheader = &wr_cheader;
+
+ return vlexcpy(wr_ex_addr, rd_ex_addr);
+ }
+}
+
+int
+vlsynccache(void)
+{
+ memcpy(rd_HostAddress, wr_HostAddress, sizeof(rd_HostAddress));
+ memcpy(&rd_cheader, &wr_cheader, sizeof(rd_cheader));
+ return vlexcpy(rd_ex_addr, wr_ex_addr);
+}