1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
/*-
* 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);
}
|