#else
# include <opr/lockstub.h>
#endif
+#include <afs/afsutil.h>
#define UBIK_INTERNALS
#include "ubik.h"
* 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;
afs_int32 code;
- /* figure out where to write */
- code = (*adbase->stat) (adbase, LOGFILE, &ustat);
- if (code < 0)
- return code;
-
/* setup data and do write */
aopcode = htonl(aopcode);
- code =
- (*adbase->write) (adbase, LOGFILE, (char *)&aopcode, ustat.size,
- sizeof(afs_int32));
+ code = (*adbase->buffered_append)(adbase, LOGFILE, &aopcode, sizeof(afs_int32));
if (code != sizeof(afs_int32))
return UIOERROR;
/*!
* \brief Log a commit, never syncing.
*/
-int
+static int
udisk_LogEnd(struct ubik_dbase *adbase, struct ubik_version *aversion)
{
afs_int32 code;
afs_int32 data[3];
- struct ubik_stat ustat;
-
- /* figure out where to write */
- code = (*adbase->stat) (adbase, LOGFILE, &ustat);
- if (code)
- return code;
/* setup data */
data[0] = htonl(LOGEND);
/* do write */
code =
- (*adbase->write) (adbase, LOGFILE, (char *)data, ustat.size,
- 3 * sizeof(afs_int32));
+ (*adbase->buffered_append)(adbase, LOGFILE, data, 3 * sizeof(afs_int32));
if (code != 3 * sizeof(afs_int32))
return UIOERROR;
/*!
* \brief Log a truncate operation, never syncing.
*/
-int
+static int
udisk_LogTruncate(struct ubik_dbase *adbase, afs_int32 afile,
afs_int32 alength)
{
afs_int32 code;
afs_int32 data[3];
- struct ubik_stat ustat;
-
- /* figure out where to write */
- code = (*adbase->stat) (adbase, LOGFILE, &ustat);
- if (code < 0)
- return code;
/* setup data */
data[0] = htonl(LOGTRUNCATE);
/* do write */
code =
- (*adbase->write) (adbase, LOGFILE, (char *)data, ustat.size,
- 3 * sizeof(afs_int32));
+ (*adbase->buffered_append)(adbase, LOGFILE, data, 3 * sizeof(afs_int32));
if (code != 3 * sizeof(afs_int32))
return UIOERROR;
return 0;
/*!
* \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)
{
- struct ubik_stat ustat;
afs_int32 code;
afs_int32 data[4];
- afs_int32 lpos;
-
- /* find end of log */
- code = (*adbase->stat) (adbase, LOGFILE, &ustat);
- lpos = ustat.size;
- if (code < 0)
- return code;
/* setup header */
data[0] = htonl(LOGDATA);
/* write header */
code =
- (*adbase->write) (adbase, LOGFILE, (char *)data, lpos, 4 * sizeof(afs_int32));
+ (*adbase->buffered_append)(adbase, LOGFILE, data, 4 * sizeof(afs_int32));
if (code != 4 * sizeof(afs_int32))
return UIOERROR;
- lpos += 4 * sizeof(afs_int32);
/* write data */
- code = (*adbase->write) (adbase, LOGFILE, abuffer, lpos, alen);
+ code = (*adbase->buffered_append)(adbase, LOGFILE, abuffer, alen);
if (code != alen)
return UIOERROR;
return 0;
tb->file = BADFID;
Dlru(tb);
tb->lockers--;
- ubik_print("Ubik: Error reading database file: errno=%d\n", errno);
+ ViceLog(0, ("Ubik: Error reading database file: errno=%d\n", errno));
return 0;
}
ios++;
if (pp == 0) {
/* There are no unlocked buffers that don't need to be written to the disk. */
- ubik_print
- ("Ubik: Internal Error: Unable to find free buffer in ubik cache\n");
+ ViceLog(0, ("Ubik: Internal Error: Unable to find free buffer in ubik cache\n"));
return NULL;
}
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);
*atrans = NULL;
if (atype == UBIK_WRITETRANS) {
- if (adbase->flags & DBWRITING)
+ if (adbase->dbFlags & DBWRITING)
return USYNC;
code = udisk_LogOpcode(adbase, LOGNEW, 0);
if (code)
adbase->readers++;
else if (atype == UBIK_WRITETRANS) {
UBIK_VERSION_LOCK;
- adbase->flags |= DBWRITING;
+ adbase->dbFlags |= DBWRITING;
UBIK_VERSION_UNLOCK;
}
*atrans = tt;
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) {
+ ViceLog(0,
+ ("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 = version_globals.ubik_epochTime;
newversion.counter = 1;
UBIK_VERSION_LOCK;
dbase->version.counter++; /* bump commit count */
-#ifdef AFS_PTHREAD_ENV
- opr_cv_broadcast(&dbase->version_cond);
-#else
- LWP_NoYieldSignal(&dbase->version);
-#endif
code = udisk_LogEnd(dbase, &dbase->version);
if (code) {
dbase->version.counter--;
* will do nothing because the abort is there or no LogEnd opcode.
*/
dbase = atrans->dbase;
- if (atrans->type == UBIK_WRITETRANS && dbase->flags & DBWRITING) {
+ if (atrans->type == UBIK_WRITETRANS && dbase->dbFlags & DBWRITING) {
udisk_LogOpcode(dbase, LOGABORT, 1);
code = (*dbase->truncate) (dbase, LOGFILE, 0);
if (code)
/* check if we are the write trans before unsetting the DBWRITING bit, else
* we could be unsetting someone else's bit.
*/
- if (atrans->type == UBIK_WRITETRANS && dbase->flags & DBWRITING) {
+ if (atrans->type == UBIK_WRITETRANS && dbase->dbFlags & DBWRITING) {
UBIK_VERSION_LOCK;
- dbase->flags &= ~DBWRITING;
+ dbase->dbFlags &= ~DBWRITING;
UBIK_VERSION_UNLOCK;
} else {
dbase->readers--;
#ifdef AFS_PTHREAD_ENV
opr_cv_broadcast(&dbase->flags_cond);
#else
- LWP_NoYieldSignal(&dbase->flags);
+ LWP_NoYieldSignal(&dbase->dbFlags);
#endif
return 0;
}