#include "db_config.h"
#include "db_int.h"
#include "dbinc/db_page.h"
#include "dbinc/fop.h"
#include "dbinc/db_am.h"
#include "dbinc/mp.h"
#include "dbinc/txn.h"
static int __fop_rename_recover_int
__P((ENV *, DBT *, DB_LSN *, db_recops, void *, int));
int
__fop_create_recover(env, dbtp, lsnp, op, info)
ENV *env;
DBT *dbtp;
DB_LSN *lsnp;
db_recops op;
void *info;
{
__fop_create_args *argp;
DB_FH *fhp;
DBMETA *meta;
u_int8_t mbuf[DBMETASIZE];
int ret;
char *real_name;
COMPQUIET(info, NULL);
real_name = NULL;
REC_PRINT(__fop_create_print);
REC_NOOP_INTRO(__fop_create_read);
meta = (DBMETA *)mbuf;
if ((ret = __db_appname(env, (APPNAME)argp->appname,
(const char *)argp->name.data, 0, NULL, &real_name)) != 0)
goto out;
if (DB_UNDO(op)) {
if (__os_open(env, real_name, 0, 0, 0, &fhp) == 0) {
if (__fop_read_meta(env,
real_name, mbuf, DBMETASIZE, fhp, 1, NULL) == 0 &&
__db_chk_meta(env, NULL, meta, 1) == 0) {
if ((ret = __memp_nameop(env,
meta->uid, NULL, real_name, NULL, 0)) != 0)
goto out;
} else
goto do_unlink;
(void)__os_closehandle(env, fhp);
} else
do_unlink: (void)__os_unlink(env, real_name, 0);
} else if (DB_REDO(op)) {
if ((ret = __os_open(env, real_name, 0,
DB_OSO_CREATE, (int)argp->mode, &fhp)) == 0)
(void)__os_closehandle(env, fhp);
else
goto out;
}
*lsnp = argp->prev_lsn;
out: if (real_name != NULL)
__os_free(env, real_name);
REC_NOOP_CLOSE;
}
int
__fop_remove_recover(env, dbtp, lsnp, op, info)
ENV *env;
DBT *dbtp;
DB_LSN *lsnp;
db_recops op;
void *info;
{
__fop_remove_args *argp;
int ret;
char *real_name;
COMPQUIET(info, NULL);
real_name = NULL;
REC_PRINT(__fop_remove_print);
REC_NOOP_INTRO(__fop_remove_read);
if ((ret = __db_appname(env, (APPNAME)argp->appname,
(const char *)argp->name.data, 0, NULL, &real_name)) != 0)
goto out;
if (DB_REDO(op))
(void)__memp_nameop(env,
(u_int8_t *)argp->fid.data, NULL, real_name, NULL, 0);
*lsnp = argp->prev_lsn;
out: if (real_name != NULL)
__os_free(env, real_name);
REC_NOOP_CLOSE;
}
int
__fop_write_recover(env, dbtp, lsnp, op, info)
ENV *env;
DBT *dbtp;
DB_LSN *lsnp;
db_recops op;
void *info;
{
__fop_write_args *argp;
int ret;
COMPQUIET(info, NULL);
REC_PRINT(__fop_write_print);
REC_NOOP_INTRO(__fop_write_read);
ret = 0;
if (DB_UNDO(op))
DB_ASSERT(env, argp->flag != 0);
else if (DB_REDO(op))
ret = __fop_write(env,
argp->txnp, argp->name.data, (APPNAME)argp->appname,
NULL, argp->pgsize, argp->pageno, argp->offset,
argp->page.data, argp->page.size, argp->flag, 0);
if (ret == 0)
*lsnp = argp->prev_lsn;
REC_NOOP_CLOSE;
}
int
__fop_rename_recover(env, dbtp, lsnp, op, info)
ENV *env;
DBT *dbtp;
DB_LSN *lsnp;
db_recops op;
void *info;
{
return (__fop_rename_recover_int(env, dbtp, lsnp, op, info, 1));
}
int
__fop_rename_noundo_recover(env, dbtp, lsnp, op, info)
ENV *env;
DBT *dbtp;
DB_LSN *lsnp;
db_recops op;
void *info;
{
return (__fop_rename_recover_int(env, dbtp, lsnp, op, info, 0));
}
static int
__fop_rename_recover_int(env, dbtp, lsnp, op, info, undo)
ENV *env;
DBT *dbtp;
DB_LSN *lsnp;
db_recops op;
void *info;
int undo;
{
__fop_rename_args *argp;
DB_FH *fhp;
DBMETA *meta;
u_int8_t *fileid, mbuf[DBMETASIZE];
int ret;
char *real_new, *real_old, *src;
COMPQUIET(info, NULL);
fhp = NULL;
meta = (DBMETA *)&mbuf[0];
ret = 0;
real_new = real_old = NULL;
REC_PRINT(__fop_rename_print);
REC_NOOP_INTRO(__fop_rename_read);
fileid = argp->fileid.data;
if ((ret = __db_appname(env, (APPNAME)argp->appname,
(const char *)argp->newname.data, 0, NULL, &real_new)) != 0)
goto out;
if ((ret = __db_appname(env, (APPNAME)argp->appname,
(const char *)argp->oldname.data, 0, NULL, &real_old)) != 0)
goto out;
if (op != DB_TXN_ABORT && op != DB_TXN_APPLY) {
src = DB_UNDO(op) ? real_new : real_old;
if (__os_open(env, src, 0, 0, 0, &fhp) != 0)
goto done;
if (__fop_read_meta(env,
src, mbuf, DBMETASIZE, fhp, 1, NULL) != 0)
goto done;
if (__db_chk_meta(env, NULL, meta, 1) != 0)
goto done;
if (memcmp(argp->fileid.data, meta->uid, DB_FILE_ID_LEN) != 0)
goto done;
(void)__os_closehandle(env, fhp);
fhp = NULL;
if (DB_REDO(op)) {
if (__os_open(env, real_new, 0, 0, 0, &fhp) == 0 &&
__fop_read_meta(env, src, mbuf,
DBMETASIZE, fhp, 1, NULL) == 0 &&
__db_chk_meta(env, NULL, meta, 1) == 0 &&
memcmp(argp->fileid.data,
meta->uid, DB_FILE_ID_LEN) != 0) {
(void)__memp_nameop(env,
fileid, NULL, real_old, NULL, 0);
goto done;
}
}
}
if (undo && DB_UNDO(op))
(void)__memp_nameop(env, fileid,
(const char *)argp->oldname.data, real_new, real_old, 0);
if (DB_REDO(op))
(void)__memp_nameop(env, fileid,
(const char *)argp->newname.data, real_old, real_new, 0);
done: *lsnp = argp->prev_lsn;
out: if (real_new != NULL)
__os_free(env, real_new);
if (real_old != NULL)
__os_free(env, real_old);
if (fhp != NULL)
(void)__os_closehandle(env, fhp);
REC_NOOP_CLOSE;
}
int
__fop_file_remove_recover(env, dbtp, lsnp, op, info)
ENV *env;
DBT *dbtp;
DB_LSN *lsnp;
db_recops op;
void *info;
{
__fop_file_remove_args *argp;
DBMETA *meta;
DB_FH *fhp;
size_t len;
u_int8_t mbuf[DBMETASIZE];
u_int32_t cstat, ret_stat;
int is_real, is_tmp, ret;
char *real_name;
fhp = NULL;
meta = (DBMETA *)&mbuf[0];
is_real = is_tmp = 0;
real_name = NULL;
REC_PRINT(__fop_file_remove_print);
REC_NOOP_INTRO(__fop_file_remove_read);
if (op != DB_TXN_BACKWARD_ROLL &&
op != DB_TXN_FORWARD_ROLL && op != DB_TXN_APPLY)
goto done;
if ((ret = __db_appname(env,
(APPNAME)argp->appname, argp->name.data, 0, NULL, &real_name)) != 0)
goto out;
len = 0;
if (__os_open(env, real_name, 0, 0, 0, &fhp) != 0 ||
(ret = __fop_read_meta(env, real_name,
mbuf, DBMETASIZE, fhp, 1, &len)) != 0) {
if (len != 0)
goto out;
cstat = TXN_EXPECTED;
} else {
(void)__db_chk_meta(env, NULL, meta, 1);
is_real =
memcmp(argp->real_fid.data, meta->uid, DB_FILE_ID_LEN) == 0;
is_tmp =
memcmp(argp->tmp_fid.data, meta->uid, DB_FILE_ID_LEN) == 0;
if (!is_real && !is_tmp)
cstat = TXN_IGNORE;
else
cstat = TXN_COMMIT;
}
if (fhp != NULL) {
(void)__os_closehandle(env, fhp);
fhp = NULL;
}
if (DB_UNDO(op)) {
if ((ret = __db_txnlist_update(env,
info, argp->child, cstat, NULL, &ret_stat, 1)) != 0)
goto out;
} else if (DB_REDO(op)) {
if (cstat == TXN_COMMIT)
(void)__memp_nameop(env,
is_real ? argp->real_fid.data : argp->tmp_fid.data,
NULL, real_name, NULL, 0);
}
done: *lsnp = argp->prev_lsn;
ret = 0;
out: if (real_name != NULL)
__os_free(env, real_name);
if (fhp != NULL)
(void)__os_closehandle(env, fhp);
REC_NOOP_CLOSE;
}