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
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);
|
|
}
|