/*- * 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 #include #include #include #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); }