You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
3.6 KiB

/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996, 1997, 1998, 1999
* Sleepycat Software. All rights reserved.
*/
#include "db_config.h"
#ifndef lint
static const char sccsid[] = "@(#)bt_upgrade.c 11.5 (Sleepycat) 10/20/99";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#endif
#include "db_int.h"
#include "db_page.h"
#include "db_swap.h"
#include "btree.h"
#include "db_am.h"
static int CDB___bam_upgrade6 __P((DB *, int, char *, DB_FH *));
/*
* CDB___bam_upgrade --
* Upgrade Btree databases.
*
* PUBLIC: int CDB___bam_upgrade __P((DB *, int, char *, DB_FH *, char *));
*/
int
CDB___bam_upgrade(dbp, swapped, real_name, fhp, mbuf)
DB *dbp;
int swapped;
char *real_name, *mbuf;
DB_FH *fhp;
{
DB_ENV *dbenv;
int ret;
dbenv = dbp->dbenv;
/* Check the version. */
switch (((DBMETA *)mbuf)->version) {
case 6:
if ((ret = CDB___bam_upgrade6(dbp, swapped, real_name, fhp)) != 0)
return (ret);
/* FALLTHROUGH */
case 7:
break;
default:
CDB___db_err(dbenv, "%s: unsupported btree version: %lu",
real_name, (u_long)((DBMETA *)mbuf)->version);
return (DB_OLD_VERSION);
}
return (0);
}
/*
* CDB___bam_upgrade6 --
* Upgrade the database from version 6 to version 7.
*/
static int
CDB___bam_upgrade6(dbp, swapped, real_name, fhp)
DB *dbp;
int swapped;
char *real_name;
DB_FH *fhp;
{
DB_ENV *dbenv;
ssize_t n;
u_int32_t tmp;
int ret;
u_int8_t buf[256], *p;
dbenv = dbp->dbenv;
if (dbp->db_feedback != NULL)
dbp->db_feedback(dbp, DB_UPGRADE, 0);
/*
* Seek to the beginning of the file and read the metadata page. We
* read 256 bytes, which is larger than any access method's metadata
* page.
*/
if ((ret = CDB___os_seek(fhp, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0)
return (ret);
if ((ret = CDB___os_read(fhp, buf, sizeof(buf), &n)) != 0)
return (ret);
/*
* Upgrade a Btree meta-data page.
* Version 6: byte range: Version 7: byte range:
* lsn 00-07 lsn 00-07
* pgno 08-11 pgno 08-11
* magic 12-15 magic 12-15
* version 16-19 version 16-19
* pagesize 20-23 pagesize 20-23
* maxkey 24-27 unused 24
* type 25
* unused 26-27
* minkey 28-31 free 28-31
* free 32-35 flags 32-35
* flags 36-39 uid 36-55
* re_len 40-43 maxkey 56-59
* re_pad 44-47 minkey 60-63
* uid 48-63 re_len 64-67
* re_pad 68-71
* root 72-75
*/
/*
* We are going to create a new uid, so we can move the stuff
* at the end of the structure first, overwriting the uid.
*/
/* 64-71 done: Move re_len and re_pad */
memmove(buf + 64, buf + 40, 8);
/* 56-63 done: Move maxkey and minkey */
memmove(buf + 56, buf + 24, 8);
/* 16-19 done: Update the version. */
tmp = 7;
if (swapped)
M_32_SWAP(tmp);
memcpy(buf + 16, &tmp, sizeof(u_int32_t));
/* 0-23 done: Bytes 0-24 are unchanged. */
p = buf + 24;
/* 24-27 done: Add type. */
*p++ = '\0';
*p++ = P_BTREEMETA;
*p++ = '\0';
*p = '\0';
/* 28-35 done: Move free and flags */
memmove(buf + 28, buf + 32, 8);
/* 36-55 done: Replace the unique ID. */
if ((ret = CDB___os_fileid(dbenv, real_name, 1, buf + 36)) != 0)
return (ret);
/* 72-75 done: Set the root page. */
tmp = 1;
if (swapped)
M_32_SWAP(tmp);
memcpy(buf + 72, &tmp, sizeof(u_int32_t));
/* Write the metadata page out. */
if ((ret = CDB___os_seek(fhp, 0, 0, 0, 1, DB_OS_SEEK_SET)) != 0)
return (ret);
if ((ret = CDB___os_write(fhp, buf, 128, &n)) != 0)
return (ret);
if ((ret = CDB___os_fsync(fhp)) != 0)
return (ret);
if (dbp->db_feedback != NULL)
dbp->db_feedback(dbp, DB_UPGRADE, 100);
return (0);
}