#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 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
write_vital_vlheader(struct vl_ctx *ctx)
{
if (vlwrite
- (ctx->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] = (struct extentaddr *)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] = (struct extentaddr *)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_flags) != 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 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] = (struct extentaddr *)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_flags = htonl(VLCONTBLOCK);
+ blockindex = ntohl(ctx->cheader->vital_header.eofPtr);
code =
- vlwrite(ctx->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);
+ 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(ctx->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(ctx->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);
*basep = 0;
/* Create the first extension block if it does not exist */
- if (!cheader.SIT) {
+ 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]) {
+ 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)) {
exp->ex_hostuuid = tuuid;
code =
vlwrite(ctx->trans,
- DOFFSET(ntohl(ex_addr[0]->ex_contaddrs[base]),
- (char *)ex_addr[base], (char *)exp),
+ 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(ctx);
if (code)
ERROR_EXIT(VL_IO);
}
- cheader.IpMappedAddr[i] = htonl(HostAddress[i]);
+ ctx->cheader->IpMappedAddr[i] = htonl(ctx->hostaddress[i]);
code =
vlwrite(ctx->trans,
- DOFFSET(0, &cheader,
- &cheader.IpMappedAddr[i]),
- (char *)&cheader.IpMappedAddr[i],
+ DOFFSET(0, ctx->cheader,
+ &ctx->cheader->IpMappedAddr[i]),
+ (char *)&ctx->cheader->IpMappedAddr[i],
sizeof(afs_int32));
if (code)
ERROR_EXIT(VL_IO);
{
afs_int32 blockindex;
- if (cheader.vital_header.freePtr) {
+ if (ctx->cheader->vital_header.freePtr) {
/* allocate this dude */
- blockindex = ntohl(cheader.vital_header.freePtr);
+ 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++;
+ ctx->cheader->vital_header.allocs++;
if (write_vital_vlheader(ctx))
return 0;
memset(tentry, 0, sizeof(nvlentry)); /* zero new entry */
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);
+ ctx->cheader->vital_header.freePtr = htonl(blockindex);
if (vlwrite(ctx->trans, blockindex, (char *)&tentry, sizeof(nvlentry)))
return VL_IO;
- cheader.vital_header.frees++;
+ ctx->cheader->vital_header.frees++;
if (write_vital_vlheader(ctx))
return VL_IO;
return 0;
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
}
}
} else {
- for (blockindex = ntohl(cheader.VolidHash[voltype][hashindex]);
+ for (blockindex = ntohl(ctx->cheader->VolidHash[voltype][hashindex]);
blockindex != NULLO; blockindex = tentry->nextIdHash[voltype]) {
if (vlentryread
(ctx->trans, blockindex, (char *)tentry, sizeof(nvlentry))) {
*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(ctx->trans, blockindex, (char *)tentry, sizeof(nvlentry))) {
*error = VL_IO;
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(ctx->trans, blockindex, (char *)&tentry, sizeof(nvlentry)))
return 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(ctx->trans, blockindex, (char *)&tentry, sizeof(nvlentry)))
return 0;
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
- (ctx->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;
}
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(ctx->trans,
- DOFFSET(0, &cheader,
- &cheader.VolidHash[voltype][hashindex]),
- (char *)&cheader.VolidHash[voltype][hashindex],
+ DOFFSET(0, ctx->cheader,
+ &ctx->cheader->VolidHash[voltype][hashindex]),
+ (char *)&ctx->cheader->VolidHash[voltype][hashindex],
sizeof(afs_int32));
if (code)
return VL_IO;
/* 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(ctx->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;
/* 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
- (ctx->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) {
afs_int32 lastblockindex;
if (blockindex == 0) /* get first one */
- blockindex = sizeof(cheader);
+ blockindex = sizeof(*ctx->cheader);
else {
if (!index_OK(ctx, blockindex)) {
*remaining = -1; /* error */
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(ctx->trans, blockindex, (char *)tentry, sizeof(nvlentry))) {
*remaining = -1;
static int
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);
+}