#include <afs/param.h>
#include <roken.h>
+#include <afs/opr.h>
-#include <sys/types.h>
-#include <string.h>
-#include <stdarg.h>
-#include <errno.h>
-
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
+#ifdef AFS_PTHREAD_ENV
+# include <opr/lock.h>
#else
-#include <sys/file.h>
-#include <netinet/in.h>
+# include <opr/lockstub.h>
#endif
-#include <lock.h>
-#include <rx/xdr.h>
-
-
-
#define UBIK_INTERNALS
#include "ubik.h"
#include "ubik_int.h"
static char *BufferData;
static struct buffer *newslot(struct ubik_dbase *adbase, afs_int32 afid,
afs_int32 apage);
-static int initd = 0;
#define BADFID 0xffffffff
static int DTrunc(struct ubik_trans *atrans, afs_int32 fid, afs_int32 length);
* Abort transaction: opcode \n
* Write data: opcode, file, position, length, <length> data bytes \n
*/
-int
+static int
udisk_LogOpcode(struct ubik_dbase *adbase, afs_int32 aopcode, int async)
{
struct ubik_stat ustat;
/*!
* \brief Log a commit, never syncing.
*/
-int
+static int
udisk_LogEnd(struct ubik_dbase *adbase, struct ubik_version *aversion)
{
afs_int32 code;
/*!
* \brief Log a truncate operation, never syncing.
*/
-int
+static int
udisk_LogTruncate(struct ubik_dbase *adbase, afs_int32 afile,
afs_int32 alength)
{
/*!
* \brief Write some data to the log, never syncing.
*/
-int
+static int
udisk_LogWriteData(struct ubik_dbase *adbase, afs_int32 afile, void *abuffer,
afs_int32 apos, afs_int32 alen)
{
return 0;
}
-static int
-DInit(int abuffers)
+int
+udisk_Init(int abuffers)
{
/* Initialize the venus buffer system. */
int i;
struct buffer *tb;
- Buffers = (struct buffer *)malloc(abuffers * sizeof(struct buffer));
- memset(Buffers, 0, abuffers * sizeof(struct buffer));
- BufferData = (char *)malloc(abuffers * UBIK_PAGESIZE);
+ Buffers = calloc(abuffers, sizeof(struct buffer));
+ BufferData = malloc(abuffers * UBIK_PAGESIZE);
nbuffers = abuffers;
for (i = 0; i < PHSIZE; i++)
phTable[i] = 0;
{
struct ubik_trunc *tt;
if (!freeTruncList) {
- freeTruncList =
- (struct ubik_trunc *)malloc(sizeof(struct ubik_trunc));
+ freeTruncList = malloc(sizeof(struct ubik_trunc));
freeTruncList->next = (struct ubik_trunc *)0;
}
tt = freeTruncList;
bp = DNew(atrans, afile, apos >> UBIK_LOGPAGESIZE);
if (!bp)
return UIOERROR;
- memset(bp, 0, UBIK_PAGESIZE);
}
/* otherwise, min of remaining bytes and end of buffer to user mode */
offset = apos & (UBIK_PAGESIZE - 1);
afs_int32 code;
struct ubik_trans *tt;
- *atrans = (struct ubik_trans *)NULL;
- /* Make sure system is initialized before doing anything */
- if (!initd) {
- initd = 1;
- DInit(ubik_nBuffers);
- }
+ *atrans = NULL;
if (atype == UBIK_WRITETRANS) {
if (adbase->flags & DBWRITING)
return USYNC;
if (code)
return code;
}
- tt = (struct ubik_trans *)malloc(sizeof(struct ubik_trans));
- memset(tt, 0, sizeof(struct ubik_trans));
+ tt = calloc(1, sizeof(struct ubik_trans));
tt->dbase = adbase;
tt->next = adbase->activeTrans;
adbase->activeTrans = tt;
tt->type = atype;
if (atype == UBIK_READTRANS)
adbase->readers++;
- else if (atype == UBIK_WRITETRANS)
+ else if (atype == UBIK_WRITETRANS) {
+ UBIK_VERSION_LOCK;
adbase->flags |= DBWRITING;
+ UBIK_VERSION_UNLOCK;
+ }
*atrans = tt;
return 0;
}
struct ubik_dbase *dbase;
afs_int32 code = 0;
struct ubik_version oldversion, newversion;
+ afs_int32 now = FT_ApproxTime();
if (atrans->flags & TRDONE)
return (UTWOENDS);
/* On the first write to the database. We update the versions */
if (ubeacon_AmSyncSite() && !(urecovery_state & UBIK_RECLABELDB)) {
+ UBIK_VERSION_LOCK;
+ if (version_globals.ubik_epochTime < UBIK_MILESTONE
+ || version_globals.ubik_epochTime > now) {
+ ubik_print
+ ("Ubik: New database label %d is out of the valid range (%d - %d)\n",
+ version_globals.ubik_epochTime, UBIK_MILESTONE, now);
+ panic("Writing Ubik DB label\n");
+ }
oldversion = dbase->version;
- newversion.epoch = FT_ApproxTime();;
+ newversion.epoch = version_globals.ubik_epochTime;
newversion.counter = 1;
code = (*dbase->setlabel) (dbase, 0, &newversion);
- if (code)
- return (code);
- ubik_epochTime = newversion.epoch;
+ if (code) {
+ UBIK_VERSION_UNLOCK;
+ return code;
+ }
+
dbase->version = newversion;
+ UBIK_VERSION_UNLOCK;
+
+ urecovery_state |= UBIK_RECLABELDB;
/* Ignore the error here. If the call fails, the site is
* marked down and when we detect it is up again, we will
*/
ContactQuorum_DISK_SetVersion( atrans, 1 /*CStampVersion */ ,
&oldversion, &newversion);
- urecovery_state |= UBIK_RECLABELDB;
}
+ UBIK_VERSION_LOCK;
dbase->version.counter++; /* bump commit count */
#ifdef AFS_PTHREAD_ENV
- CV_BROADCAST(&dbase->version_cond);
+ opr_cv_broadcast(&dbase->version_cond);
#else
LWP_NoYieldSignal(&dbase->version);
#endif
code = udisk_LogEnd(dbase, &dbase->version);
if (code) {
dbase->version.counter--;
- return (code);
+ UBIK_VERSION_UNLOCK;
+ return code;
}
+ UBIK_VERSION_UNLOCK;
/* If we fail anytime after this, then panic and let the
* recovery replay the log.
* we could be unsetting someone else's bit.
*/
if (atrans->type == UBIK_WRITETRANS && dbase->flags & DBWRITING) {
+ UBIK_VERSION_LOCK;
dbase->flags &= ~DBWRITING;
+ UBIK_VERSION_UNLOCK;
} else {
dbase->readers--;
}
/* Wakeup any writers waiting in BeginTrans() */
#ifdef AFS_PTHREAD_ENV
- CV_BROADCAST(&dbase->flags_cond);
+ opr_cv_broadcast(&dbase->flags_cond);
#else
LWP_NoYieldSignal(&dbase->flags);
#endif