-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/crypto.h"
-
-/*
- * __crypto_region_init --
- * Initialize crypto.
- */
-int
-__crypto_region_init(dbenv)
- DB_ENV *dbenv;
-{
- REGENV *renv;
- REGINFO *infop;
- CIPHER *cipher;
- DB_CIPHER *db_cipher;
- char *sh_passwd;
- int ret;
-
- db_cipher = dbenv->crypto_handle;
-
- ret = 0;
- infop = dbenv->reginfo;
- renv = infop->primary;
- if (renv->cipher_off == INVALID_ROFF) {
- if (!CRYPTO_ON(dbenv))
- return (0);
- if (!F_ISSET(infop, REGION_CREATE)) {
- __db_err(dbenv,
- "Joining non-encrypted environment with encryption key");
- return (EINVAL);
- }
- if (F_ISSET(db_cipher, CIPHER_ANY)) {
- __db_err(dbenv, "Encryption algorithm not supplied");
- return (EINVAL);
- }
- /*
- * Must create the shared information. We need: Shared cipher
- * information that contains the passwd. After we copy the
- * passwd, we smash and free the one in the dbenv.
- */
- if ((ret =
- __db_shalloc(infop, sizeof(CIPHER), 0, &cipher)) != 0)
- return (ret);
- memset(cipher, 0, sizeof(*cipher));
- if ((ret = __db_shalloc(
- infop, dbenv->passwd_len, 0, &sh_passwd)) != 0) {
- __db_shalloc_free(infop, cipher);
- return (ret);
- }
- memset(sh_passwd, 0, dbenv->passwd_len);
- cipher->passwd = R_OFFSET(infop, sh_passwd);
- cipher->passwd_len = dbenv->passwd_len;
- cipher->flags = db_cipher->alg;
- memcpy(sh_passwd, dbenv->passwd, cipher->passwd_len);
- renv->cipher_off = R_OFFSET(infop, cipher);
- } else {
- if (!CRYPTO_ON(dbenv)) {
- __db_err(dbenv,
- "Encrypted environment: no encryption key supplied");
- return (EINVAL);
- }
- cipher = R_ADDR(infop, renv->cipher_off);
- sh_passwd = R_ADDR(infop, cipher->passwd);
- if ((cipher->passwd_len != dbenv->passwd_len) ||
- memcmp(dbenv->passwd, sh_passwd, cipher->passwd_len) != 0) {
- __db_err(dbenv, "Invalid password");
- return (EPERM);
- }
- if (!F_ISSET(db_cipher, CIPHER_ANY) &&
- db_cipher->alg != cipher->flags) {
- __db_err(dbenv,
- "Environment encrypted using a different algorithm");
- return (EINVAL);
- }
- if (F_ISSET(db_cipher, CIPHER_ANY))
- /*
- * We have CIPHER_ANY and we are joining the existing
- * env. Setup our cipher structure for whatever
- * algorithm this env has.
- */
- if ((ret = __crypto_algsetup(dbenv, db_cipher,
- cipher->flags, 0)) != 0)
- return (ret);
- }
- ret = db_cipher->init(dbenv, db_cipher);
-
- /*
- * On success, no matter if we allocated it or are using the already
- * existing one, we are done with the passwd in the dbenv. We smash
- * N-1 bytes so that we don't overwrite the nul.
- */
- memset(dbenv->passwd, 0xff, dbenv->passwd_len-1);
- __os_free(dbenv, dbenv->passwd);
- dbenv->passwd = NULL;
- dbenv->passwd_len = 0;
-
- return (ret);
-}
-
-/*
- * __crypto_dbenv_close --
- * Crypto-specific destruction of DB_ENV structure.
- *
- * PUBLIC: int __crypto_dbenv_close __P((DB_ENV *));
- */
-int
-__crypto_dbenv_close(dbenv)
- DB_ENV *dbenv;
-{
- DB_CIPHER *db_cipher;
- int ret;
-
- ret = 0;
- db_cipher = dbenv->crypto_handle;
- if (dbenv->passwd != NULL) {
- memset(dbenv->passwd, 0xff, dbenv->passwd_len-1);
- __os_free(dbenv, dbenv->passwd);
- dbenv->passwd = NULL;
- }
- if (!CRYPTO_ON(dbenv))
- return (0);
- if (!F_ISSET(db_cipher, CIPHER_ANY))
- ret = db_cipher->close(dbenv, db_cipher->data);
- __os_free(dbenv, db_cipher);
- return (ret);
-}
-
-/*
- * __crypto_region_destroy --
- * Destroy any system resources allocated in the primary region.
- *
- * PUBLIC: int __crypto_region_destroy __P((DB_ENV *));
- */
-int
-__crypto_region_destroy(dbenv)
- DB_ENV *dbenv;
-{
- CIPHER *cipher;
- REGENV *renv;
- REGINFO *infop;
-
- infop = dbenv->reginfo;
- renv = infop->primary;
- if (renv->cipher_off != INVALID_ROFF) {
- cipher = R_ADDR(infop, renv->cipher_off);
- __db_shalloc_free(infop, R_ADDR(infop, cipher->passwd));
- __db_shalloc_free(infop, cipher);
- }
- return (0);
-}
-
-/*
- * __crypto_algsetup --
- * Given a db_cipher structure and a valid algorithm flag, call
- * the specific algorithm setup function.
- *
- * PUBLIC: int __crypto_algsetup __P((DB_ENV *, DB_CIPHER *, u_int32_t, int));
- */
-int
-__crypto_algsetup(dbenv, db_cipher, alg, do_init)
- DB_ENV *dbenv;
- DB_CIPHER *db_cipher;
- u_int32_t alg;
- int do_init;
-{
- int ret;
-
- ret = 0;
- if (!CRYPTO_ON(dbenv)) {
- __db_err(dbenv, "No cipher structure given");
- return (EINVAL);
- }
- F_CLR(db_cipher, CIPHER_ANY);
- switch (alg) {
- case CIPHER_AES:
- db_cipher->alg = CIPHER_AES;
- ret = __aes_setup(dbenv, db_cipher);
- break;
- default:
- __db_panic(dbenv, EINVAL);
- /* NOTREACHED */
- }
- if (do_init)
- ret = db_cipher->init(dbenv, db_cipher);
- return (ret);
-}
-
-/*
- * __crypto_decrypt_meta --
- * Perform decryption on a metapage if needed.
- *
- * PUBLIC: int __crypto_decrypt_meta __P((DB_ENV *, DB *, u_int8_t *, int));
- */
-int
-__crypto_decrypt_meta(dbenv, dbp, mbuf, do_metachk)
- DB_ENV *dbenv;
- DB *dbp;
- u_int8_t *mbuf;
- int do_metachk;
-{
- DB_CIPHER *db_cipher;
- DB dummydb;
- DBMETA *meta;
- size_t pg_off;
- int ret;
- u_int8_t *iv;
-
- /*
- * If we weren't given a dbp, we just want to decrypt the page on
- * behalf of some internal subsystem, not on behalf of a user with
- * a dbp. Therefore, set up a dummy dbp so that the call to
- * P_OVERHEAD below works.
- */
- if (dbp == NULL) {
- memset(&dummydb, 0, sizeof(DB));
- dbp = &dummydb;
- }
-
- ret = 0;
- meta = (DBMETA *)mbuf;
-
- /*
- * !!!
- * We used an "unused" field in the meta-data page to flag whether or
- * not the database is encrypted. Unfortunately, that unused field
- * was used in Berkeley DB releases before 3.0 (for example, 2.7.7).
- * It would have been OK, except encryption doesn't follow the usual
- * rules of "upgrade before doing anything else", we check encryption
- * before checking for old versions of the database.
- *
- * We don't have to check Btree databases -- before 3.0, the field of
- * interest was the bt_maxkey field (which was never supported and has
- * since been removed).
- *
- * Ugly check to jump out if this format is older than what we support.
- * It assumes no encrypted page will have an unencrypted magic number,
- * but that seems relatively safe. [#10920]
- */
- if (meta->magic == DB_HASHMAGIC && meta->version <= 5)
- return (0);
-
- /*
- * Meta-pages may be encrypted for DBMETASIZE bytes. If we have a
- * non-zero IV (that is written after encryption) then we decrypt (or
- * error if the user isn't set up for security). We guarantee that
- * the IV space on non-encrypted pages will be zero and a zero-IV is
- * illegal for encryption. Therefore any non-zero IV means an
- * encrypted database. This basically checks the passwd on the file
- * if we cannot find a good magic number. We walk through all the
- * algorithms we know about attempting to decrypt (and possibly
- * byteswap).
- *
- * !!!
- * All method meta pages have the IV and checksum at the exact same
- * location, but not in DBMETA, use BTMETA.
- */
- if (meta->encrypt_alg != 0) {
- db_cipher = (DB_CIPHER *)dbenv->crypto_handle;
- if (!F_ISSET(dbp, DB_AM_ENCRYPT)) {
- if (!CRYPTO_ON(dbenv)) {
- __db_err(dbenv,
- "Encrypted database: no encryption flag specified");
- return (EINVAL);
- }
- /*
- * User has a correct, secure env, but has encountered
- * a database in that env that is secure, but user
- * didn't dbp->set_flags. Since it is existing, use
- * encryption if it is that way already.
- */
- F_SET(dbp, DB_AM_ENCRYPT|DB_AM_CHKSUM);
- }
- /*
- * This was checked in set_flags when DB_AM_ENCRYPT was set.
- * So it better still be true here.
- */
- DB_ASSERT(CRYPTO_ON(dbenv));
- if (!F_ISSET(db_cipher, CIPHER_ANY) &&
- meta->encrypt_alg != db_cipher->alg) {
- __db_err(dbenv,
- "Database encrypted using a different algorithm");
- return (EINVAL);
- }
- DB_ASSERT(F_ISSET(dbp, DB_AM_CHKSUM));
- iv = ((BTMETA *)mbuf)->iv;
- /*
- * For ALL pages, we do not encrypt the beginning of the page
- * that contains overhead information. This is true of meta
- * and all other pages.
- */
- pg_off = P_OVERHEAD(dbp);
-alg_retry:
- /*
- * If they asked for a specific algorithm, then
- * use it. Otherwise walk through those we know.
- */
- if (!F_ISSET(db_cipher, CIPHER_ANY)) {
- if (do_metachk && (ret = db_cipher->decrypt(dbenv,
- db_cipher->data, iv, mbuf + pg_off,
- DBMETASIZE - pg_off)))
- return (ret);
- if (((BTMETA *)meta)->crypto_magic !=
- meta->magic) {
- __db_err(dbenv, "Invalid password");
- return (EINVAL);
- }
- /*
- * Success here. The algorithm asked for and the one
- * on the file match. We've just decrypted the meta
- * page and checked the magic numbers. They match,
- * indicating the password is right. All is right
- * with the world.
- */
- return (0);
- }
- /*
- * If we get here, CIPHER_ANY must be set.
- */
- ret = __crypto_algsetup(dbenv, db_cipher, meta->encrypt_alg, 1);
- goto alg_retry;
- } else if (F_ISSET(dbp, DB_AM_ENCRYPT)) {
- /*
- * They gave us a passwd, but the database is not encrypted.
- * This is an error. We do NOT want to silently allow them
- * to write data in the clear when the user set up and expects
- * encrypted data.
- *
- * This covers at least the following scenario.
- * 1. User creates and sets up an encrypted database.
- * 2. Attacker cannot read the actual data in the database
- * because it is encrypted, but can remove/replace the file
- * with an empty, unencrypted database file.
- * 3. User sets encryption and we get to this code now.
- * If we allowed the file to be used in the clear since
- * it is that way on disk, the user would unsuspectingly
- * write sensitive data in the clear.
- * 4. Attacker reads data that user thought was encrypted.
- *
- * Therefore, asking for encryption with a database that
- * was not encrypted is an error.
- */
- __db_err(dbenv,
- "Unencrypted database with a supplied encryption key");
- return (EINVAL);
- }
- return (ret);
-}
-
-/*
- * __crypto_set_passwd --
- * Get the password from the shared region; and set it in a new
- * environment handle. Use this to duplicate environment handles.
- *
- * PUBLIC: int __crypto_set_passwd __P((DB_ENV *, DB_ENV *));
- */
-int
-__crypto_set_passwd(dbenv_src, dbenv_dest)
- DB_ENV *dbenv_src, *dbenv_dest;
-{
- CIPHER *cipher;
- REGENV *renv;
- REGINFO *infop;
- char *sh_passwd;
- int ret;
-
- ret = 0;
- infop = dbenv_src->reginfo;
- renv = infop->primary;
-
- DB_ASSERT(CRYPTO_ON(dbenv_src));
-
- cipher = R_ADDR(infop, renv->cipher_off);
- sh_passwd = R_ADDR(infop, cipher->passwd);
- return (__env_set_encrypt(dbenv_dest, sh_passwd, DB_ENCRYPT_AES));
-}
diff --git a/storage/bdb/crypto/crypto.html b/storage/bdb/crypto/crypto.html
deleted file mode 100644
index 7d2804b43b4..00000000000
--- a/storage/bdb/crypto/crypto.html
+++ /dev/null
@@ -1,639 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- Security Interface for Berkeley DB
-
-Susan LoVerso
-
sue@sleepycat.com
-
Rev 1.6
-
2002 Feb 26
-
-We provide an interface allowing secure access to Berkeley DB.
-Our goal is to allow users to have encrypted secure databases. In
-this document, the term ciphering means the act of encryption or
-decryption. They are equal but opposite actions and the same issues
-apply to both just in the opposite direction.
-
-Requirements
-The overriding requirement is to provide a simple mechanism to allow users
-to have a secure database. A secure database means that all of the
-pages of a database will be encrypted, and all of the log files will be
-encrypted.
-Falling out from this work will be a simple mechanism to allow users
-to request that we checksum their data for additional error detection (without
-encryption/decryption).
-
We expect that data in process memory or stored in shared memory, potentially
-backed by disk, is not encrypted or secure.
-
-DB Method Interface Modifications
-With a logging environment, all database changes are recorded in the log
-files. Therefore, users requiring secure databases in such environments
-also require secure log files.
-A prior thought had been to allow different passwords on the environment
-and the databases within. However, such a scheme, then requires that
-the password be logged in order for recovery to be able to restore the
-database. Therefore, any application having the password for the
-log could get the password for any databases by reading the log.
-So having a different password on a database does not gain any additional
-security and it makes certain things harder and more complex. Some
-of those more complex things include the need to handle database and env
-passwords differently since they'd need to be stored and accessed from
-different places. Also resolving the issue of how db_checkpoint
-or db_sync, which flush database pages to disk, would find the passwords
-of various databases without any dbps was unsolved. The feature didn't
-gain anything and caused significant pain. Therefore the decision
-is that there will be a single password protecting an environment and all
-the logs and some databases within that environment. We do allow
-users to have a secure environment and clear databases. Users that
-want secure databases within a secure environment must set a flag.
-
Users wishing to enable encryption on a database in a secure environment
-or enable just checksumming on their database pages will use new flags
-to DB->set_flags().
-Providing ciphering over an entire environment is accomplished by adding
-a single environment method: DBENV->set_encrypt().
-Providing encryption for a database (not part of an environment) is accomplished
-by adding a new database method: DB->set_encrypt().
-
Both of the set_encrypt methods must be called before their respective
-open calls. The environment method must be before the environment
-open because we must know about security before there is any possibility
-of writing any log records out. The database method must be before
-the database open in order to read the root page. The planned interfaces
-for these methods are:
-
DBENV->set_encrypt(DBENV *dbenv, /* DB_ENV structure */
- char *passwd /* Password */
- u_int32_t flags); /* Flags */
-
-DB->set_encrypt(DB *dbp, /* DB structure */
- char *passwd /* Password */
- u_int32_t flags); /* Flags */
-The flags accepted by these functions are:
-#define DB_ENCRYPT_AES 0x00000001 /* Use the AES encryption algorithm */
-Passwords are NULL-terminated strings. NULL or zero length strings
-are illegal. These flags enable the checksumming and encryption using
-the particular algorithms we have chosen for this implementation.
-The flags are named such that there is a logical naming pattern if additional
-checksum or encryption algorithms are used. If a user gives a flag of zero,
-it will behave in a manner similar to DB_UNKNOWN. It will be illegal if
-they are creating the environment or database, as an algorithm must be
-specified. If they are joining an existing environment or opening an existing
-database, they will use whatever algorithm is in force at the time.
-Using DB_ENCRYPT_AES automatically implies SHA1 checksumming.
-These functions will perform several initialization steps. We
-will allocate crypto_handle for our env handle and set up our function
-pointers. We will allocate space and copy the password into our env
-handle password area. Similar to DB->set_cachesize, calling
-DB->set_encrypt
-will actually reflect back into the local environment created by DB.
-
Lastly, we will add a new flag, DB_OVERWRITE, to the DBENV->remove
-method. The purpose of this flag is to force all of the memory used
-by the shared regions to be overwritten before removal. We will use
-rm_overwrite,
-a function that overwrites and syncs a file 3 times with varying bit patterns
-to really remove a file. Additionally, this flag will force a sync
-of the overwritten regions to disk, if the regions are backed by the file
-system. That way there is no residual information left in the clear
-in memory or freed disk blocks. Although we expect that this flag
-will be used by customers using security, primarily, its action is not
-dependent on passwords or a secure setup, and so can be used by anyone.
-
-Initialization of the Environment
-The setup of the security subsystem will be similar to replication initialization
-since it is a sort of subsystem, but it does not have its own region.
-When the environment handle is created via db_env_create, we initialize
-our set_encrypt method to be the RPC or local version. Therefore
-the DB_ENV structure needs a new pointer:
- void *crypto_handle; /* Security handle */
-The crypto handle will really point to a new __db_cipher structure
-that will contain a set of functions and a pointer to the in-memory information
-needed by the specific encryption algorithm. It will look like:
-typedef struct __db_cipher {
- int (*init)__P((...)); /* Alg-specific initialization function */
- int (*encrypt)__P((...)); /* Alg-specific encryption algorithm */
- int (*decrypt)__P((...)); /* Alg-specific decryption function */
- void *data; /* Pointer to alg-specific information (AES_CIPHER) */
- u_int32_t flags; /* Cipher flags */
-} DB_CIPHER;
-
-#define DB_MAC_KEY 20 /* Size of the MAC key */
-typedef struct __aes_cipher {
- keyInstance encrypt_ki; /* Encrypt keyInstance temp. */
- keyInstance decrypt_ki; /* Decrypt keyInstance temp. */
- u_int8_t mac_key[DB_MAC_KEY]; /* MAC key */
- u_int32_t flags; /* AES-specific flags */
-} AES_CIPHER;
-It should be noted that none of these structures have their own mutex.
-We hold the environment region locked while we are creating this, but once
-this is set up, it is read-only forever.
-During dbenv->set_encrypt,
-we set the encryption, decryption and checksumming methods to the appropriate
-functions based on the flags. This function will allocate us a crypto
-handle that we store in the DB_ENV structure just like all the
-other subsystems. For now, only AES ciphering functions and SHA1
-checksumming functions are supported. Also we will copy the password
-into the DB_ENV structure. We ultimately need to keep the
-password in the environment's shared memory region or compare this one
-against the one that is there, if we are joining an existing environment,
-but we do not have it yet because open has not yet been called. We
-will allocate a structure that will be used in initialization and set up
-the function pointers to point to the algorithm-specific functions.
-
In the __env_open path, in __db_e_attach, if we
-are creating the region and the dbenv->passwd field is set, we need
-to use the length of the password in the initial computation of the environment's
-size. This guarantees sufficient space for storing the password in
-shared memory. Then we will call a new function to initialize the
-security region, __crypto_region_init in __env_open.
-If we are the creator, we will allocate space in the shared region to store
-the password and copy the password into that space. Or, if we are
-not the creator we will compare the password stored in the dbenv with the
-one in shared memory. Additionally, we will compare the ciphering
-algorithm to the one stored in the shared region.We'll smash the dbenv
-password and free it. If they do not match, we return an error.
-If we are the creator we store the offset into the REGENV structure.
-Then __crypto_region_init will call the initialization function
-set up earlier based on the ciphering algorithm specified. For now
-we will call __aes_init. Additionally this function will allocate
-and set up the per-process state vector for this encryption's IVs.
-See Generating the Initialization
-Vector for a detailed description of the IV and state vector.
-
In the AES-specific initialization function, __aes_init,
-we will initialize it by calling
-__aes_derivekeys in order to fill
-in the keyInstance and mac_key fields in that structure. The REGENV
-structure will have one additional item
-
roff_t passwd_off; /* Offset of passwd */
-
-
-Initializing a Database
-During db->set_encrypt,
-we set the encryption, decryption and checksumming methods to the appropriate
-functions based on the flags. Basically, we test that we are not
-in an existing environment and we haven't called open. Then we just
-call through the environment handle to set the password.
-Also, we will need to add a flag in the database meta-data page that
-indicates that the database is encrypted and what its algorithm is.
-This will be used when the meta-page is read after reopening a file. We
-need this information on the meta-page in order to detect a user opening
-a secure database without a password. I propose using the first unused1
-byte (renaming it too) in the meta page for this purpose.
-
All pages will not be encrypted for the first 64 bytes of data.
-Database meta-pages will be encrypted on the first 512 bytes only.
-All meta-page types will have an IV and checksum added within the first
-512 bytes as well as a crypto magic number. This will expand the
-size of the meta-page from 256 bytes to 512 bytes. The page in/out routines,
-__db_pgin and __db_pgout know the page type of the page and
-will apply the 512 bytes ciphering to meta pages. In __db_pgout,
-if we have a crypto handle in our (private) environment, we will apply
-ciphering to either the entire page, or the first 512 bytes if it is a
-meta-page. In __db_pgin, we will decrypt if the page we have
-a crypto handle.
-
When multiple processes share a database, all must use the same password
-as the database creator. Using an existing database requires several conditions
-to be true. First, if the creator of the database did not create
-with security, then opening later with security is an error. Second,
-if the creator did create it with security, then opening later without
-security is an error. Third, we need to be able to test and check
-that when another process opens a secure database that the password they
-provided is the same as the one in use by the creator.
-
When reading the meta-page, in __db_file_setup, we do not go
-through the paging functions, but directly read via __os_read.
-It is at this point that we will determine if the user is configured correctly.
-If the meta-page we read has an IV and checksum, they better have a crypto
-handle. If they have a crypto handle, then the meta-page must have
-an IV and checksum. If both of those are true, we test the password.
-We compare the unencrypted magic number to the newly-decrypted crypto magic
-number and if they are not the same, then we report that the user gave
-us a bad password.
-
On a mostly unrelated topic, even when we go to very large pagesizes,
-the meta information will still be within a disk sector. So, after
-talking it over with Keith and Margo, we determined that unencrypted meta-pages
-still will not need a checksum.
-
-Encryption and Checksum Routines
-These routines are provided to us by Adam Stubblefield at Rice University
-(astubble@rice.edu). The functional interfaces are:
-__aes_derivekeys(DB_ENV *dbenv, /* dbenv */
- u_int8_t *passwd, /* Password */
- size_t passwd_len, /* Length of passwd */
- u_int8_t *mac_key, /* 20 byte array to store MAC key */
- keyInstance *encrypt_key, /* Encryption key of passwd */
- keyInstance *decrypt_key); /* Decryption key of passwd */
-This is the only function requiring the textual user password. From
-the password, this function generates a key used in the checksum function,
-__db_chksum.
-It also fills in keyInstance structures which are then used in the
-encryption and decryption routines. The keyInstance structures must
-already be allocated. These will be stored in the AES_CIPHER structure.
- __db_chksum(u_int8_t *data, /* Data to checksum */
- size_t data_len, /* Length of data */
- u_int8_t *mac_key, /* 20 byte array from __db_derive_keys */
- u_int8_t *checksum); /* 20 byte array to store checksum */
-This function generates a checksum on the data given. This function
-will do double-duty for users that simply want error detection on their
-pages. When users are using encryption, the mac_key will contain
-the 20-byte key set up in __aes_derivekeys. If they just want
-checksumming, then mac_key will be NULL. According to Adam,
-we can safely use the first N-bytes of the checksum. So for seeding
-the generator for initialization vectors, we'll hash the time and then
-send in the first 4 bytes for the seed. I believe we can probably
-do the same thing for checksumming log records. We can only use 4
-bytes for the checksum in the non-secure case. So when we want to
-verify the log checksum we can compute the mac but just compare the first
-4 bytes to the one we read. All locations where we generate or check
-log record checksums that currently call __ham_func4 will now call
-__db_chksum.
-I believe there are 5 such locations,
-__log_put, __log_putr, __log_newfile,
-__log_rep_put
-and __txn_force_abort.
-__aes_encrypt(DB_ENV *dbenv, /* dbenv */
- keyInstance *key, /* Password key instance from __db_derive_keys */
- u_int8_t *iv, /* Initialization vector */
- u_int8_t *data, /* Data to encrypt */
- size_t data_len); /* Length of data to encrypt - 16 byte multiple */
-This is the function to encrypt data. It will be called to encrypt
-pages and log records. The key instance is initialized in
-__aes_derivekeys.
-The initialization vector, iv, is the 16 byte random value set up
-by the Mersenne Twister pseudo-random generator. Lastly, we pass
-in a pointer to the data to encrypt and its length in data_len.
-The data_len must be a multiple of 16 bytes. The encryption is done
-in-place so that when the encryption code returns our encrypted data is
-in the same location as the original data.
-__aes_decrypt(DB_ENV *dbenv, /* dbenv */
- keyInstance *key, /* Password key instance from __db_derive_keys */
- u_int8_t *iv, /* Initialization vector */
- u_int8_t *data, /* Data to decrypt */
- size_t data_len); /* Length of data to decrypt - 16 byte multiple */
-This is the function to decrypt the data. It is exactly the same
-as the encryption function except for the action it performs. All
-of the args and issues are the same. It also decrypts in place.
-
-Generating the Initialization
-Vector
-Internally, we need to provide a unique initialization vector (IV) of 16
-bytes every time we encrypt any data with the same password. For
-the IV we are planning on using mt19937, the Mersenne Twister, a random
-number generator that has a period of 2**19937-1. This package can be found
-at http://www.math.keio.ac.jp/~matumoto/emt.html.
-Tests show that although it repeats a single integer every once in a while,
-that after several million iterations, it doesn't repeat any 4 integers
-that we'd be stuffing into our 16-byte IV. We plan on seeding this
-generator with the time (tv_sec) hashed through SHA1 when we create the
-environment. This package uses a global state vector that contains
-624 unsigned long integers. We do not allow a 16-byte IV of zero.
-It is simpler just to reject any 4-byte value of 0 and if we get one, just
-call the generator again and get a different number. We need to detect
-holes in files and if we read an IV of zero that is a simple indication
-that we need to check for an entire page of zero. The IVs are stored
-on the page after encryption and are not encrypted themselves so it is
-not possible for an entire encrypted page to be read as all zeroes, unless
-it was a hole in a file. See Holes in Files
-for more details.
-We will not be holding any locks when we need to generate our IV but
-we need to protect access to the state vector and the index. Calls
-to the MT code will come while encrypting some data in __aes_encrypt.
-The MT code will assume that all necessary locks are held in the caller.
-We will have per-process state vectors that are set up when a process begins.
-That way we minimize the contention and only multi-threaded processes need
-acquire locks for the IV. We will have the state vector in the environment
-handle in heap memory, as well as the index and there will be a mutex protecting
-it for threaded access. This will be added to the DB_ENV
-structure:
-
DB_MUTEX *mt_mutexp; /* Mersenne Twister mutex */
- int *mti; /* MT index */
- u_long *mt; /* MT state vector */
-This portion of the environment will be initialized at the end of __dbenv_open,
-right after we initialize the other mutex for the dblist. When we
-allocate the space, we will generate our initial state vector. If we are
-multi-threaded we'll allocate and initialize our mutex also.
-We need to make changes to the MT code to make it work in our namespace
-and to take a pointer to the location of the state vector and
-the index. There will be a wrapper function __db_generate_iv
-that DB will call and it will call the appropriate MT function. I
-am also going to change the default seed to use a hashed time instead of
-a hard coded value. I have looked at other implementations of the
-MT code available on the web site. The C++ version does a hash on
-the current time. I will modify our MT code to seed with the hashed
-time as well. That way the code to seed is contained within the MT
-code and we can just write the wrapper to get an IV. We will not
-be changing the core computational code of MT.
-
-DB Internal Issues
-
-
-When do we Cipher?
-All of the page ciphering is done in the __db_pgin/__db_pgout functions.
-We will encrypt after the method-specific function on page-out and decrypt
-before the method-specfic function on page-in. We do not hold any
-locks when entering these functions. We determine that we need to
-cipher based on the existence of the encryption flag in the dbp.
-For ciphering log records, the encryption will be done as the first
-thing (or a new wrapper) in __log_put. See Log
-Record Encryption for those details.
-
-
-Page Changes
-The checksum and IV values will be stored prior to the first index of the
-page. We have a new P_INP macro that replaces use of inp[X] in the
-code. This macro takes a dbp as an argument and determines where
-our first index is based on whether we have DB_AM_CHKSUM and DB_AM_ENCRYPT
-set. If neither is set, then our first index is where it always was.
- If just checksumming is set, then we reserve a 4-byte checksum.
-If encryption is set, then we reserve 36 bytes for our checksum/IV as well
-as some space to get proper alignment to encrypt on a 16-byte boundary.
-Since several paging macros use inp[X] in them, those macros must now
-take a dbp. There are a lot of changes to make all the necessary
-paging macros take a dbp, although these changes are trivial in nature.
-
Also, there is a new function __db_chk_meta to perform checksumming
-and decryption checking on meta pages specifically. This function
-is where we check that the database algorithm matches what the user gave
-(or if they set DB_CIPHER_ANY then we set it), and other encryption related
-testing for bad combinations of what is in the file versus what is in the
-user structures.
-
-Verification
-The verification code will also need to be updated to deal with secure
-pages. Basically when the verification code reads in the meta page
-it will call __db_chk_meta to perform any checksumming and decryption.
-
-Holes in Files
-Holes in files will be dealt with rather simply. We need to be able
-to distinguish reading a hole in a file from an encrypted page that happened
-to encrypt to all zero's. If we read a hole in a file, we do not
-want to send that empty page through the decryption routine. This
-can be determined simply without incurring the performance penalty of comparing
-every byte on a page on every read until we get a non-zero byte.
-
The __db_pgin function is only given an invalid page P_INVALID in this
-case. So, if the page type, which is always unencrypted, is
-P_INVALID, then we do not perform any checksum verification or decryption.
-
-Errors and Recovery
-Dealing with a checksum error is tricky. Ultimately, if a checksum
-error occurs it is extremely likely that the user must do catastrophic
-recovery. There is no other failure return other than DB_RUNRECOVERY
-for indicating that the user should run catastrophic recovery. We
-do not want to add a new error return for applications to check because
-a lot of applications already look for and deal with DB_RUNRECOVERY as
-an error condition and we want to fit ourselves into that application model.
-We already indicate to the user that when they get that error, then they
-need to run recovery. If recovery fails, then they need to run catastrophic
-recovery. We need to get ourselves to the point where users will
-run catastrophic recovery.
-If we get a checksum error, then we need to log a message stating a
-checksum error occurred on page N. In __db_pgin, we can check
-if logging is on in the environment. If so, we want to log the message.
-
When the application gets the DB_RUNRECOVERY error, they'll have to
-shut down their application and run recovery. When the recovery encounters
-the record indicating checksum failure, then normal recovery will fail
-and the user will have to perform catastrophic recovery. When catastrophic
-recovery encounters that record, it will simply ignore it.
-
-Log Record Encryption
-Log records will be ciphered. It might make sense to wrap __log_put
-to encrypt the DBT we send down. The __log_put function is
-where the checksum is computed before acquiring the region lock.
-But also this function is where we call __rep_send_message to send
-the DBT to the replication clients. Therefore, we need the DBT to
-be encrypted prior to there. We also need it encrypted before checksumming.
-I think __log_put will become __log_put_internal, and the
-new __log_put will encrypt if needed and then call __log_put_internal
-(the
-function formerly known as __log_put). Log records are kept
-in a shared memory region buffer prior to going out to disk. Records
-in the buffer will be encrypted. No locks are held at the time we
-will need to encrypt.
-On reading the log, via log cursors, the log code stores log records
-in the log buffer. Records in that buffer will be encrypted, so decryption
-will occur no matter whether we are returning records from the buffer or
-if we are returning log records directly from the disk. Current checksum
-checking is done in
-__log_get_c_int. Decryption will be done
-after the checksum is checked.
-
There are currently two nasty issues with encrypted log records.
-The first is that __txn_force_abort overwrites a commit record in
-the log buffer with an abort record. Well, our log buffer will be
-encrypted. Therefore, __txn_force_abort is going to need to
-do encryption of its new record. This can be accomplished by sending
-in the dbenv handle to the function. It is available to us in __log_flush_commit
-and we can just pass it in. I don't like putting log encryption in
-the txn code, but the layering violation is already there.
-
The second issue is that the encryption code requires data that is a
-multiple of 16 bytes and log record lengths are variable. We will
-need to pad log records to meet the requirement. Since the callers
-of __log_put set up the given DBT it is a logical place to pad if
-necessary. We will modify the gen_rec.awk script to have all of the generated
-logging functions pad for us if we have a crypto handle. This padding will
-also expand the size of log files. Anyone calling log_put and using
-security from the application will have to pad on their own or it will
-return an error.
-
When ciphering the log file, we will need a different header than the
-current one. The current header only has space for a 4 byte checksum.
-Our secure header will need space for the 16 byte IV and 20 byte checksum.
-This will blow up our log files when running securely since every single
-log record header will now consume 32 additional bytes. I believe
-that the log header does not need to be encrypted. It contains an
-offset, a length and our IV and checksum. Our IV and checksum are
-never encrypted. I don't believe there to be any risk in having the
-offset and length in the clear.
-
I would prefer not to have two types of log headers that are incompatible
-with each other. It is not acceptable to increase the log headers
-of all users from 12 bytes to 44 bytes. Such a change would also
-make log files incompatible with earlier releases. Worse even, is
-that the cksum field of the header is in between the offset and
-len. It would be really convenient if we could have just made a bigger
-cksum portion without affecting the location of the other fields.
-Oh well. Most customers will not be using encryption and we won't
-make them pay the price of the expanded header. Keith indicates that
-the log file format is changing with the next release so I will move the
-cksum field so it can at least be overlaid.
-
One method around this would be to have a single internal header that
-contains all the information both mechanisms need, but when we write out
-the header we choose which pieces to write. By appending the security
-information to the end of the existing structure, and adding a size field,
-we can modify a few places to use the size field to write out only the
-current first 12 bytes, or the entire security header needed.
-
-Replication
-Replication clients are going to need to start all of their individual
-environment handles with the same password. The log records are going
-to be sent to the clients decrypted and the clients will have to encrypt
-them on their way to the client log files. We cannot send encrypted
-log records to clients. The reason is that the checksum and IV are
-stored in the log header and the master only sends the log record itself
-to the client. Therefore, the client has no way to decrypt a log
-record from the master. Therefore, anyone wanting to use truly secure
-replication is going to have to have a secure transport mechanism.
-By not encrypting records, clients can theoretically have different passwords
-and DB won't care.
-On the master side we must copy the DBT sent in. We encrypt the
-original and send to clients the clear record. On the client side,
-support for encryption is added into __log_rep_put.
-
-Sharing the Environment
-When multiple processes join the environment, all must use the same password
-as the creator.
-Joining an existing environment requires several conditions to be true.
-First, if the creator of the environment did not create with security,
-then joining later with security is an error. Second, if the creator
-did create it with security, then joining later without security is an
-error. Third, we need to be able to test and check that when another
-process joins a secure environment that the password they provided is the
-same as the one in use by the creator.
-
The first two scenarios should be fairly trivial to determine, if we
-aren't creating the environment, we can compare what is there with what
-we have. In the third case, the __crypto_region_init function
-will see that the environment region has a valid passwd_off and we'll then
-compare that password to the one we have in our dbenv handle. In
-any case we'll smash the dbenv handle's passwd and free that memory before
-returning whether we have a password match or not.
-
We need to store the passwords themselves in the region because multiple
-calls to the __aes_derivekeys function with the same password yields
-different keyInstance contents. Therefore we don't have any way to
-check passwords other than retaining and comparing the actual passwords.
-
-Other APIs
-All of the other APIs will need interface enhancements to support the new
-security methods. The Java and C++ interfaces will likely be done
-by Michael Cahill and Sue will implement the Tcl and RPC changes.
-Tcl will need the changes for testing purposes but the interface should
-be public, not test-only. RPC should fully support security.
-The biggest risk that I can see is that the client will send the password
-to the server in the clear. Anyone sniffing the wires or running
-tcpdump or other packet grabbing code could grab that. Someone really
-interested in using security over RPC probably ought to add authentication
-and other measures to the RPC server as well.
-
-Utilities
-All should take a -P flag to specify a password for the environment or
-password. Those that take an env and a database might need something
-more to distinguish between env passwds and db passwds. Here is what we
-do for each utility:
-
--
-berkeley_db_svc - Needs -P after each -h specified.
-
--
-db_archive - Needs -P if the env is encrypted.
-
--
-db_checkpoint - Needs -P if the env is encrypted.
-
--
-db_deadlock - No changes
-
--
-db_dump - Needs -P if the env or database is encrypted.
-
--
-db_load - Needs -P if the env or database is encrypted.
-
--
-db_printlog - Needs -P if the env is encrypted.
-
--
-db_recover - Needs -P if the env is encrypted.
-
--
-db_stat - Needs -P if the env or database is encrypted.
-
--
-db_upgrade - Needs -P if the env or database is encrypted.
-
--
-db_verify - Needs -P if the env or database is encrypted.
-
-
-
-Testing
-All testing should be able to be accomplished via Tcl. The following
-tests (and probably others I haven't thought of yet) should be performed:
-
--
-Basic functionality - basically a test001 but encrypted without an env
-
--
-Basic functionality, w/ env - like the previous test but with an env.
-
--
-Basic functionality, multiple processes - like first test, but make sure
-others can correctly join.
-
--
-Basic functionality, mult. processes - like above test, but initialize/close
-environment/database first so that the next test processes are all joiners
-of an existing env, but creator no longer exists and the shared region
-must be opened.
-
--
-Recovery test - Run recovery over an encrypted environment.
-
--
-Subdb test - Run with subdbs that are encrypted.
-
--
-Utility test - Verify the new options to all the utilities.
-
--
-Error handling - Test the basic setup errors for both env's and databases
-with multiple processes. They are:
-
-
--
-Attempt to set a NULL or zero-length passwd.
-
--
-Create Env w/ security and attempt to create database w/ its own password.
-
--
-Env/DB creates with security. Proc2 joins without - should get an
-error.
-
--
-Env/DB creates without security. Proc2 joins with - should get an
-error.
-
--
-Env/DB creates with security. Proc2 joins with different password
-- should get an error.
-
--
-Env/DB creates with security. Closes. Proc2 reopens with different
-password - should get an error.
-
--
-Env/DB creates with security. Closes. Tcl overwrites a page
-of the database with garbage. Proc2 reopens with the correct password.
-Code should detect checksum error.
-
--
-Env/DB creates with security. Open a 2nd identical DB with a different
-password. Put the exact same data into both databases. Close.
-Overwrite the identical page of DB1 with the one from DB2. Reopen
-the database with correct DB1 password. Code should detect an encryption
-error on that page.
-
-
-
-
-Risks
-There are several holes in this design. It is important to document
-them clearly.
-The first is that all of the pages are stored in memory and possibly
-the file system in the clear. The password is stored in the shared
-data regions in the clear. Therefore if an attacker can read the
-process memory, they can do whatever they want. If the attacker can
-read system memory or swap they can access the data as well. Since
-everything in the shared data regions (with the exception of the buffered
-log) will be in the clear, it is important to realize that file backed
-regions will be written in the clear, including the portion of the regions
-containing passwords. We recommend to users that they use system
-memory instead of file backed shared memory.
-
-
diff --git a/storage/bdb/crypto/mersenne/mt19937db.c b/storage/bdb/crypto/mersenne/mt19937db.c
deleted file mode 100644
index 1dad5f6ad12..00000000000
--- a/storage/bdb/crypto/mersenne/mt19937db.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * $Id: mt19937db.c,v 12.1 2005/07/20 16:50:57 bostic Exp $
- */
-#include "db_config.h"
-
-#include "db_int.h"
-#include "dbinc/crypto.h"
-#include "dbinc/hmac.h"
-
-/* A C-program for MT19937: Integer version (1999/10/28) */
-/* genrand() generates one pseudorandom unsigned integer (32bit) */
-/* which is uniformly distributed among 0 to 2^32-1 for each */
-/* call. sgenrand(seed) sets initial values to the working area */
-/* of 624 words. Before genrand(), sgenrand(seed) must be */
-/* called once. (seed is any 32-bit integer.) */
-/* Coded by Takuji Nishimura, considering the suggestions by */
-/* Topher Cooper and Marc Rieffel in July-Aug. 1997. */
-
-/* This library is free software under the Artistic license: */
-/* see the file COPYING distributed together with this code. */
-/* For the verification of the code, its output sequence file */
-/* mt19937int.out is attached (2001/4/2) */
-
-/* Copyright (C) 1997, 1999 Makoto Matsumoto and Takuji Nishimura. */
-/* Any feedback is very welcome. For any question, comments, */
-/* see http://www.math.keio.ac.jp/matumoto/emt.html or email */
-/* matumoto@math.keio.ac.jp */
-
-/* REFERENCE */
-/* M. Matsumoto and T. Nishimura, */
-/* "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform */
-/* Pseudo-Random Number Generator", */
-/* ACM Transactions on Modeling and Computer Simulation, */
-/* Vol. 8, No. 1, January 1998, pp 3--30. */
-
-/* Period parameters */
-#define N 624
-#define M 397
-#define MATRIX_A 0x9908b0df /* constant vector a */
-#define UPPER_MASK 0x80000000 /* most significant w-r bits */
-#define LOWER_MASK 0x7fffffff /* least significant r bits */
-
-/* Tempering parameters */
-#define TEMPERING_MASK_B 0x9d2c5680
-#define TEMPERING_MASK_C 0xefc60000
-#define TEMPERING_SHIFT_U(y) (y >> 11)
-#define TEMPERING_SHIFT_S(y) (y << 7)
-#define TEMPERING_SHIFT_T(y) (y << 15)
-#define TEMPERING_SHIFT_L(y) (y >> 18)
-
-static void __db_sgenrand __P((unsigned long, unsigned long *, int *));
-#ifdef NOT_USED
-static void __db_lsgenrand __P((unsigned long *, unsigned long *, int *));
-#endif
-static unsigned long __db_genrand __P((DB_ENV *));
-
-/*
- * __db_generate_iv --
- * Generate an initialization vector (IV)
- *
- * PUBLIC: int __db_generate_iv __P((DB_ENV *, u_int32_t *));
- */
-int
-__db_generate_iv(dbenv, iv)
- DB_ENV *dbenv;
- u_int32_t *iv;
-{
- int i, n, ret;
-
- ret = 0;
- n = DB_IV_BYTES / sizeof(u_int32_t);
- MUTEX_LOCK(dbenv, dbenv->mtx_mt);
- if (dbenv->mt == NULL) {
- if ((ret = __os_calloc(dbenv, 1, N*sizeof(unsigned long),
- &dbenv->mt)) != 0)
- return (ret);
- /* mti==N+1 means mt[N] is not initialized */
- dbenv->mti = N + 1;
- }
- for (i = 0; i < n; i++) {
- /*
- * We do not allow 0. If we get one just try again.
- */
- do {
- iv[i] = (u_int32_t)__db_genrand(dbenv);
- } while (iv[i] == 0);
- }
-
- MUTEX_UNLOCK(dbenv, dbenv->mtx_mt);
- return (0);
-}
-
-/* Initializing the array with a seed */
-static void
-__db_sgenrand(seed, mt, mtip)
- unsigned long seed;
- unsigned long mt[];
- int *mtip;
-{
- int i;
-
- DB_ASSERT(seed != 0);
- for (i=0;i> 16;
- seed = 69069 * seed + 1;
- }
- *mtip = N;
-}
-
-#ifdef NOT_USED
-/* Initialization by "sgenrand()" is an example. Theoretically, */
-/* there are 2^19937-1 possible states as an intial state. */
-/* This function allows to choose any of 2^19937-1 ones. */
-/* Essential bits in "seed_array[]" is following 19937 bits: */
-/* (seed_array[0]&UPPER_MASK), seed_array[1], ..., seed_array[N-1]. */
-/* (seed_array[0]&LOWER_MASK) is discarded. */
-/* Theoretically, */
-/* (seed_array[0]&UPPER_MASK), seed_array[1], ..., seed_array[N-1] */
-/* can take any values except all zeros. */
-static void
-__db_lsgenrand(seed_array, mt, mtip)
- unsigned long seed_array[];
- unsigned long mt[];
- int *mtip;
- /* the length of seed_array[] must be at least N */
-{
- int i;
-
- for (i=0;imtx_mt locked.
- */
- if (dbenv->mti >= N) { /* generate N words at one time */
- int kk;
-
- if (dbenv->mti == N+1) { /* if sgenrand() has not been called, */
- /*
- * Seed the generator with the hashed time. The __db_mac
- * function will return 4 bytes if we don't send in a key.
- */
- do {
- __os_clock(dbenv, &secs, &usecs);
- __db_chksum((u_int8_t *)&secs, sizeof(secs), NULL,
- (u_int8_t *)&seed);
- } while (seed == 0);
- __db_sgenrand((long)seed, dbenv->mt, &dbenv->mti);
- }
-
- for (kk=0;kkmt[kk]&UPPER_MASK)|(dbenv->mt[kk+1]&LOWER_MASK);
- dbenv->mt[kk] = dbenv->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
- }
- for (;kkmt[kk]&UPPER_MASK)|(dbenv->mt[kk+1]&LOWER_MASK);
- dbenv->mt[kk] = dbenv->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
- }
- y = (dbenv->mt[N-1]&UPPER_MASK)|(dbenv->mt[0]&LOWER_MASK);
- dbenv->mt[N-1] = dbenv->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
-
- dbenv->mti = 0;
- }
-
- y = dbenv->mt[dbenv->mti++];
- y ^= TEMPERING_SHIFT_U(y);
- y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
- y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
- y ^= TEMPERING_SHIFT_L(y);
-
- return y;
-}
diff --git a/storage/bdb/crypto/rijndael/rijndael-alg-fst.c b/storage/bdb/crypto/rijndael/rijndael-alg-fst.c
deleted file mode 100644
index 4a251606d28..00000000000
--- a/storage/bdb/crypto/rijndael/rijndael-alg-fst.c
+++ /dev/null
@@ -1,1466 +0,0 @@
-/**
- * rijndael-alg-fst.c
- *
- * @version 3.0 (December 2000)
- *
- * Optimised ANSI C code for the Rijndael cipher (now AES)
- *
- * @author Vincent Rijmen
- * @author Antoon Bosselaers
- * @author Paulo Barreto
- *
- * This code is hereby placed in the public domain.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "db_config.h"
-
-#include "db_int.h"
-#include "dbinc/crypto.h"
-
-#include "crypto/rijndael/rijndael-alg-fst.h"
-
-/*
-Te0[x] = S [x].[02, 01, 01, 03];
-Te1[x] = S [x].[03, 02, 01, 01];
-Te2[x] = S [x].[01, 03, 02, 01];
-Te3[x] = S [x].[01, 01, 03, 02];
-Te4[x] = S [x].[01, 01, 01, 01];
-
-Td0[x] = Si[x].[0e, 09, 0d, 0b];
-Td1[x] = Si[x].[0b, 0e, 09, 0d];
-Td2[x] = Si[x].[0d, 0b, 0e, 09];
-Td3[x] = Si[x].[09, 0d, 0b, 0e];
-Td4[x] = Si[x].[01, 01, 01, 01];
-*/
-
-static const u32 Te0[256] = {
- (u_int)0xc66363a5, (u_int)0xf87c7c84, (u_int)0xee777799, (u_int)0xf67b7b8d,
- (u_int)0xfff2f20d, (u_int)0xd66b6bbd, (u_int)0xde6f6fb1, (u_int)0x91c5c554,
- (u_int)0x60303050, (u_int)0x02010103, (u_int)0xce6767a9, (u_int)0x562b2b7d,
- (u_int)0xe7fefe19, (u_int)0xb5d7d762, (u_int)0x4dababe6, (u_int)0xec76769a,
- (u_int)0x8fcaca45, (u_int)0x1f82829d, (u_int)0x89c9c940, (u_int)0xfa7d7d87,
- (u_int)0xeffafa15, (u_int)0xb25959eb, (u_int)0x8e4747c9, (u_int)0xfbf0f00b,
- (u_int)0x41adadec, (u_int)0xb3d4d467, (u_int)0x5fa2a2fd, (u_int)0x45afafea,
- (u_int)0x239c9cbf, (u_int)0x53a4a4f7, (u_int)0xe4727296, (u_int)0x9bc0c05b,
- (u_int)0x75b7b7c2, (u_int)0xe1fdfd1c, (u_int)0x3d9393ae, (u_int)0x4c26266a,
- (u_int)0x6c36365a, (u_int)0x7e3f3f41, (u_int)0xf5f7f702, (u_int)0x83cccc4f,
- (u_int)0x6834345c, (u_int)0x51a5a5f4, (u_int)0xd1e5e534, (u_int)0xf9f1f108,
- (u_int)0xe2717193, (u_int)0xabd8d873, (u_int)0x62313153, (u_int)0x2a15153f,
- (u_int)0x0804040c, (u_int)0x95c7c752, (u_int)0x46232365, (u_int)0x9dc3c35e,
- (u_int)0x30181828, (u_int)0x379696a1, (u_int)0x0a05050f, (u_int)0x2f9a9ab5,
- (u_int)0x0e070709, (u_int)0x24121236, (u_int)0x1b80809b, (u_int)0xdfe2e23d,
- (u_int)0xcdebeb26, (u_int)0x4e272769, (u_int)0x7fb2b2cd, (u_int)0xea75759f,
- (u_int)0x1209091b, (u_int)0x1d83839e, (u_int)0x582c2c74, (u_int)0x341a1a2e,
- (u_int)0x361b1b2d, (u_int)0xdc6e6eb2, (u_int)0xb45a5aee, (u_int)0x5ba0a0fb,
- (u_int)0xa45252f6, (u_int)0x763b3b4d, (u_int)0xb7d6d661, (u_int)0x7db3b3ce,
- (u_int)0x5229297b, (u_int)0xdde3e33e, (u_int)0x5e2f2f71, (u_int)0x13848497,
- (u_int)0xa65353f5, (u_int)0xb9d1d168, (u_int)0x00000000, (u_int)0xc1eded2c,
- (u_int)0x40202060, (u_int)0xe3fcfc1f, (u_int)0x79b1b1c8, (u_int)0xb65b5bed,
- (u_int)0xd46a6abe, (u_int)0x8dcbcb46, (u_int)0x67bebed9, (u_int)0x7239394b,
- (u_int)0x944a4ade, (u_int)0x984c4cd4, (u_int)0xb05858e8, (u_int)0x85cfcf4a,
- (u_int)0xbbd0d06b, (u_int)0xc5efef2a, (u_int)0x4faaaae5, (u_int)0xedfbfb16,
- (u_int)0x864343c5, (u_int)0x9a4d4dd7, (u_int)0x66333355, (u_int)0x11858594,
- (u_int)0x8a4545cf, (u_int)0xe9f9f910, (u_int)0x04020206, (u_int)0xfe7f7f81,
- (u_int)0xa05050f0, (u_int)0x783c3c44, (u_int)0x259f9fba, (u_int)0x4ba8a8e3,
- (u_int)0xa25151f3, (u_int)0x5da3a3fe, (u_int)0x804040c0, (u_int)0x058f8f8a,
- (u_int)0x3f9292ad, (u_int)0x219d9dbc, (u_int)0x70383848, (u_int)0xf1f5f504,
- (u_int)0x63bcbcdf, (u_int)0x77b6b6c1, (u_int)0xafdada75, (u_int)0x42212163,
- (u_int)0x20101030, (u_int)0xe5ffff1a, (u_int)0xfdf3f30e, (u_int)0xbfd2d26d,
- (u_int)0x81cdcd4c, (u_int)0x180c0c14, (u_int)0x26131335, (u_int)0xc3ecec2f,
- (u_int)0xbe5f5fe1, (u_int)0x359797a2, (u_int)0x884444cc, (u_int)0x2e171739,
- (u_int)0x93c4c457, (u_int)0x55a7a7f2, (u_int)0xfc7e7e82, (u_int)0x7a3d3d47,
- (u_int)0xc86464ac, (u_int)0xba5d5de7, (u_int)0x3219192b, (u_int)0xe6737395,
- (u_int)0xc06060a0, (u_int)0x19818198, (u_int)0x9e4f4fd1, (u_int)0xa3dcdc7f,
- (u_int)0x44222266, (u_int)0x542a2a7e, (u_int)0x3b9090ab, (u_int)0x0b888883,
- (u_int)0x8c4646ca, (u_int)0xc7eeee29, (u_int)0x6bb8b8d3, (u_int)0x2814143c,
- (u_int)0xa7dede79, (u_int)0xbc5e5ee2, (u_int)0x160b0b1d, (u_int)0xaddbdb76,
- (u_int)0xdbe0e03b, (u_int)0x64323256, (u_int)0x743a3a4e, (u_int)0x140a0a1e,
- (u_int)0x924949db, (u_int)0x0c06060a, (u_int)0x4824246c, (u_int)0xb85c5ce4,
- (u_int)0x9fc2c25d, (u_int)0xbdd3d36e, (u_int)0x43acacef, (u_int)0xc46262a6,
- (u_int)0x399191a8, (u_int)0x319595a4, (u_int)0xd3e4e437, (u_int)0xf279798b,
- (u_int)0xd5e7e732, (u_int)0x8bc8c843, (u_int)0x6e373759, (u_int)0xda6d6db7,
- (u_int)0x018d8d8c, (u_int)0xb1d5d564, (u_int)0x9c4e4ed2, (u_int)0x49a9a9e0,
- (u_int)0xd86c6cb4, (u_int)0xac5656fa, (u_int)0xf3f4f407, (u_int)0xcfeaea25,
- (u_int)0xca6565af, (u_int)0xf47a7a8e, (u_int)0x47aeaee9, (u_int)0x10080818,
- (u_int)0x6fbabad5, (u_int)0xf0787888, (u_int)0x4a25256f, (u_int)0x5c2e2e72,
- (u_int)0x381c1c24, (u_int)0x57a6a6f1, (u_int)0x73b4b4c7, (u_int)0x97c6c651,
- (u_int)0xcbe8e823, (u_int)0xa1dddd7c, (u_int)0xe874749c, (u_int)0x3e1f1f21,
- (u_int)0x964b4bdd, (u_int)0x61bdbddc, (u_int)0x0d8b8b86, (u_int)0x0f8a8a85,
- (u_int)0xe0707090, (u_int)0x7c3e3e42, (u_int)0x71b5b5c4, (u_int)0xcc6666aa,
- (u_int)0x904848d8, (u_int)0x06030305, (u_int)0xf7f6f601, (u_int)0x1c0e0e12,
- (u_int)0xc26161a3, (u_int)0x6a35355f, (u_int)0xae5757f9, (u_int)0x69b9b9d0,
- (u_int)0x17868691, (u_int)0x99c1c158, (u_int)0x3a1d1d27, (u_int)0x279e9eb9,
- (u_int)0xd9e1e138, (u_int)0xebf8f813, (u_int)0x2b9898b3, (u_int)0x22111133,
- (u_int)0xd26969bb, (u_int)0xa9d9d970, (u_int)0x078e8e89, (u_int)0x339494a7,
- (u_int)0x2d9b9bb6, (u_int)0x3c1e1e22, (u_int)0x15878792, (u_int)0xc9e9e920,
- (u_int)0x87cece49, (u_int)0xaa5555ff, (u_int)0x50282878, (u_int)0xa5dfdf7a,
- (u_int)0x038c8c8f, (u_int)0x59a1a1f8, (u_int)0x09898980, (u_int)0x1a0d0d17,
- (u_int)0x65bfbfda, (u_int)0xd7e6e631, (u_int)0x844242c6, (u_int)0xd06868b8,
- (u_int)0x824141c3, (u_int)0x299999b0, (u_int)0x5a2d2d77, (u_int)0x1e0f0f11,
- (u_int)0x7bb0b0cb, (u_int)0xa85454fc, (u_int)0x6dbbbbd6, (u_int)0x2c16163a,
-};
-static const u32 Te1[256] = {
- (u_int)0xa5c66363, (u_int)0x84f87c7c, (u_int)0x99ee7777, (u_int)0x8df67b7b,
- (u_int)0x0dfff2f2, (u_int)0xbdd66b6b, (u_int)0xb1de6f6f, (u_int)0x5491c5c5,
- (u_int)0x50603030, (u_int)0x03020101, (u_int)0xa9ce6767, (u_int)0x7d562b2b,
- (u_int)0x19e7fefe, (u_int)0x62b5d7d7, (u_int)0xe64dabab, (u_int)0x9aec7676,
- (u_int)0x458fcaca, (u_int)0x9d1f8282, (u_int)0x4089c9c9, (u_int)0x87fa7d7d,
- (u_int)0x15effafa, (u_int)0xebb25959, (u_int)0xc98e4747, (u_int)0x0bfbf0f0,
- (u_int)0xec41adad, (u_int)0x67b3d4d4, (u_int)0xfd5fa2a2, (u_int)0xea45afaf,
- (u_int)0xbf239c9c, (u_int)0xf753a4a4, (u_int)0x96e47272, (u_int)0x5b9bc0c0,
- (u_int)0xc275b7b7, (u_int)0x1ce1fdfd, (u_int)0xae3d9393, (u_int)0x6a4c2626,
- (u_int)0x5a6c3636, (u_int)0x417e3f3f, (u_int)0x02f5f7f7, (u_int)0x4f83cccc,
- (u_int)0x5c683434, (u_int)0xf451a5a5, (u_int)0x34d1e5e5, (u_int)0x08f9f1f1,
- (u_int)0x93e27171, (u_int)0x73abd8d8, (u_int)0x53623131, (u_int)0x3f2a1515,
- (u_int)0x0c080404, (u_int)0x5295c7c7, (u_int)0x65462323, (u_int)0x5e9dc3c3,
- (u_int)0x28301818, (u_int)0xa1379696, (u_int)0x0f0a0505, (u_int)0xb52f9a9a,
- (u_int)0x090e0707, (u_int)0x36241212, (u_int)0x9b1b8080, (u_int)0x3ddfe2e2,
- (u_int)0x26cdebeb, (u_int)0x694e2727, (u_int)0xcd7fb2b2, (u_int)0x9fea7575,
- (u_int)0x1b120909, (u_int)0x9e1d8383, (u_int)0x74582c2c, (u_int)0x2e341a1a,
- (u_int)0x2d361b1b, (u_int)0xb2dc6e6e, (u_int)0xeeb45a5a, (u_int)0xfb5ba0a0,
- (u_int)0xf6a45252, (u_int)0x4d763b3b, (u_int)0x61b7d6d6, (u_int)0xce7db3b3,
- (u_int)0x7b522929, (u_int)0x3edde3e3, (u_int)0x715e2f2f, (u_int)0x97138484,
- (u_int)0xf5a65353, (u_int)0x68b9d1d1, (u_int)0x00000000, (u_int)0x2cc1eded,
- (u_int)0x60402020, (u_int)0x1fe3fcfc, (u_int)0xc879b1b1, (u_int)0xedb65b5b,
- (u_int)0xbed46a6a, (u_int)0x468dcbcb, (u_int)0xd967bebe, (u_int)0x4b723939,
- (u_int)0xde944a4a, (u_int)0xd4984c4c, (u_int)0xe8b05858, (u_int)0x4a85cfcf,
- (u_int)0x6bbbd0d0, (u_int)0x2ac5efef, (u_int)0xe54faaaa, (u_int)0x16edfbfb,
- (u_int)0xc5864343, (u_int)0xd79a4d4d, (u_int)0x55663333, (u_int)0x94118585,
- (u_int)0xcf8a4545, (u_int)0x10e9f9f9, (u_int)0x06040202, (u_int)0x81fe7f7f,
- (u_int)0xf0a05050, (u_int)0x44783c3c, (u_int)0xba259f9f, (u_int)0xe34ba8a8,
- (u_int)0xf3a25151, (u_int)0xfe5da3a3, (u_int)0xc0804040, (u_int)0x8a058f8f,
- (u_int)0xad3f9292, (u_int)0xbc219d9d, (u_int)0x48703838, (u_int)0x04f1f5f5,
- (u_int)0xdf63bcbc, (u_int)0xc177b6b6, (u_int)0x75afdada, (u_int)0x63422121,
- (u_int)0x30201010, (u_int)0x1ae5ffff, (u_int)0x0efdf3f3, (u_int)0x6dbfd2d2,
- (u_int)0x4c81cdcd, (u_int)0x14180c0c, (u_int)0x35261313, (u_int)0x2fc3ecec,
- (u_int)0xe1be5f5f, (u_int)0xa2359797, (u_int)0xcc884444, (u_int)0x392e1717,
- (u_int)0x5793c4c4, (u_int)0xf255a7a7, (u_int)0x82fc7e7e, (u_int)0x477a3d3d,
- (u_int)0xacc86464, (u_int)0xe7ba5d5d, (u_int)0x2b321919, (u_int)0x95e67373,
- (u_int)0xa0c06060, (u_int)0x98198181, (u_int)0xd19e4f4f, (u_int)0x7fa3dcdc,
- (u_int)0x66442222, (u_int)0x7e542a2a, (u_int)0xab3b9090, (u_int)0x830b8888,
- (u_int)0xca8c4646, (u_int)0x29c7eeee, (u_int)0xd36bb8b8, (u_int)0x3c281414,
- (u_int)0x79a7dede, (u_int)0xe2bc5e5e, (u_int)0x1d160b0b, (u_int)0x76addbdb,
- (u_int)0x3bdbe0e0, (u_int)0x56643232, (u_int)0x4e743a3a, (u_int)0x1e140a0a,
- (u_int)0xdb924949, (u_int)0x0a0c0606, (u_int)0x6c482424, (u_int)0xe4b85c5c,
- (u_int)0x5d9fc2c2, (u_int)0x6ebdd3d3, (u_int)0xef43acac, (u_int)0xa6c46262,
- (u_int)0xa8399191, (u_int)0xa4319595, (u_int)0x37d3e4e4, (u_int)0x8bf27979,
- (u_int)0x32d5e7e7, (u_int)0x438bc8c8, (u_int)0x596e3737, (u_int)0xb7da6d6d,
- (u_int)0x8c018d8d, (u_int)0x64b1d5d5, (u_int)0xd29c4e4e, (u_int)0xe049a9a9,
- (u_int)0xb4d86c6c, (u_int)0xfaac5656, (u_int)0x07f3f4f4, (u_int)0x25cfeaea,
- (u_int)0xafca6565, (u_int)0x8ef47a7a, (u_int)0xe947aeae, (u_int)0x18100808,
- (u_int)0xd56fbaba, (u_int)0x88f07878, (u_int)0x6f4a2525, (u_int)0x725c2e2e,
- (u_int)0x24381c1c, (u_int)0xf157a6a6, (u_int)0xc773b4b4, (u_int)0x5197c6c6,
- (u_int)0x23cbe8e8, (u_int)0x7ca1dddd, (u_int)0x9ce87474, (u_int)0x213e1f1f,
- (u_int)0xdd964b4b, (u_int)0xdc61bdbd, (u_int)0x860d8b8b, (u_int)0x850f8a8a,
- (u_int)0x90e07070, (u_int)0x427c3e3e, (u_int)0xc471b5b5, (u_int)0xaacc6666,
- (u_int)0xd8904848, (u_int)0x05060303, (u_int)0x01f7f6f6, (u_int)0x121c0e0e,
- (u_int)0xa3c26161, (u_int)0x5f6a3535, (u_int)0xf9ae5757, (u_int)0xd069b9b9,
- (u_int)0x91178686, (u_int)0x5899c1c1, (u_int)0x273a1d1d, (u_int)0xb9279e9e,
- (u_int)0x38d9e1e1, (u_int)0x13ebf8f8, (u_int)0xb32b9898, (u_int)0x33221111,
- (u_int)0xbbd26969, (u_int)0x70a9d9d9, (u_int)0x89078e8e, (u_int)0xa7339494,
- (u_int)0xb62d9b9b, (u_int)0x223c1e1e, (u_int)0x92158787, (u_int)0x20c9e9e9,
- (u_int)0x4987cece, (u_int)0xffaa5555, (u_int)0x78502828, (u_int)0x7aa5dfdf,
- (u_int)0x8f038c8c, (u_int)0xf859a1a1, (u_int)0x80098989, (u_int)0x171a0d0d,
- (u_int)0xda65bfbf, (u_int)0x31d7e6e6, (u_int)0xc6844242, (u_int)0xb8d06868,
- (u_int)0xc3824141, (u_int)0xb0299999, (u_int)0x775a2d2d, (u_int)0x111e0f0f,
- (u_int)0xcb7bb0b0, (u_int)0xfca85454, (u_int)0xd66dbbbb, (u_int)0x3a2c1616,
-};
-static const u32 Te2[256] = {
- (u_int)0x63a5c663, (u_int)0x7c84f87c, (u_int)0x7799ee77, (u_int)0x7b8df67b,
- (u_int)0xf20dfff2, (u_int)0x6bbdd66b, (u_int)0x6fb1de6f, (u_int)0xc55491c5,
- (u_int)0x30506030, (u_int)0x01030201, (u_int)0x67a9ce67, (u_int)0x2b7d562b,
- (u_int)0xfe19e7fe, (u_int)0xd762b5d7, (u_int)0xabe64dab, (u_int)0x769aec76,
- (u_int)0xca458fca, (u_int)0x829d1f82, (u_int)0xc94089c9, (u_int)0x7d87fa7d,
- (u_int)0xfa15effa, (u_int)0x59ebb259, (u_int)0x47c98e47, (u_int)0xf00bfbf0,
- (u_int)0xadec41ad, (u_int)0xd467b3d4, (u_int)0xa2fd5fa2, (u_int)0xafea45af,
- (u_int)0x9cbf239c, (u_int)0xa4f753a4, (u_int)0x7296e472, (u_int)0xc05b9bc0,
- (u_int)0xb7c275b7, (u_int)0xfd1ce1fd, (u_int)0x93ae3d93, (u_int)0x266a4c26,
- (u_int)0x365a6c36, (u_int)0x3f417e3f, (u_int)0xf702f5f7, (u_int)0xcc4f83cc,
- (u_int)0x345c6834, (u_int)0xa5f451a5, (u_int)0xe534d1e5, (u_int)0xf108f9f1,
- (u_int)0x7193e271, (u_int)0xd873abd8, (u_int)0x31536231, (u_int)0x153f2a15,
- (u_int)0x040c0804, (u_int)0xc75295c7, (u_int)0x23654623, (u_int)0xc35e9dc3,
- (u_int)0x18283018, (u_int)0x96a13796, (u_int)0x050f0a05, (u_int)0x9ab52f9a,
- (u_int)0x07090e07, (u_int)0x12362412, (u_int)0x809b1b80, (u_int)0xe23ddfe2,
- (u_int)0xeb26cdeb, (u_int)0x27694e27, (u_int)0xb2cd7fb2, (u_int)0x759fea75,
- (u_int)0x091b1209, (u_int)0x839e1d83, (u_int)0x2c74582c, (u_int)0x1a2e341a,
- (u_int)0x1b2d361b, (u_int)0x6eb2dc6e, (u_int)0x5aeeb45a, (u_int)0xa0fb5ba0,
- (u_int)0x52f6a452, (u_int)0x3b4d763b, (u_int)0xd661b7d6, (u_int)0xb3ce7db3,
- (u_int)0x297b5229, (u_int)0xe33edde3, (u_int)0x2f715e2f, (u_int)0x84971384,
- (u_int)0x53f5a653, (u_int)0xd168b9d1, (u_int)0x00000000, (u_int)0xed2cc1ed,
- (u_int)0x20604020, (u_int)0xfc1fe3fc, (u_int)0xb1c879b1, (u_int)0x5bedb65b,
- (u_int)0x6abed46a, (u_int)0xcb468dcb, (u_int)0xbed967be, (u_int)0x394b7239,
- (u_int)0x4ade944a, (u_int)0x4cd4984c, (u_int)0x58e8b058, (u_int)0xcf4a85cf,
- (u_int)0xd06bbbd0, (u_int)0xef2ac5ef, (u_int)0xaae54faa, (u_int)0xfb16edfb,
- (u_int)0x43c58643, (u_int)0x4dd79a4d, (u_int)0x33556633, (u_int)0x85941185,
- (u_int)0x45cf8a45, (u_int)0xf910e9f9, (u_int)0x02060402, (u_int)0x7f81fe7f,
- (u_int)0x50f0a050, (u_int)0x3c44783c, (u_int)0x9fba259f, (u_int)0xa8e34ba8,
- (u_int)0x51f3a251, (u_int)0xa3fe5da3, (u_int)0x40c08040, (u_int)0x8f8a058f,
- (u_int)0x92ad3f92, (u_int)0x9dbc219d, (u_int)0x38487038, (u_int)0xf504f1f5,
- (u_int)0xbcdf63bc, (u_int)0xb6c177b6, (u_int)0xda75afda, (u_int)0x21634221,
- (u_int)0x10302010, (u_int)0xff1ae5ff, (u_int)0xf30efdf3, (u_int)0xd26dbfd2,
- (u_int)0xcd4c81cd, (u_int)0x0c14180c, (u_int)0x13352613, (u_int)0xec2fc3ec,
- (u_int)0x5fe1be5f, (u_int)0x97a23597, (u_int)0x44cc8844, (u_int)0x17392e17,
- (u_int)0xc45793c4, (u_int)0xa7f255a7, (u_int)0x7e82fc7e, (u_int)0x3d477a3d,
- (u_int)0x64acc864, (u_int)0x5de7ba5d, (u_int)0x192b3219, (u_int)0x7395e673,
- (u_int)0x60a0c060, (u_int)0x81981981, (u_int)0x4fd19e4f, (u_int)0xdc7fa3dc,
- (u_int)0x22664422, (u_int)0x2a7e542a, (u_int)0x90ab3b90, (u_int)0x88830b88,
- (u_int)0x46ca8c46, (u_int)0xee29c7ee, (u_int)0xb8d36bb8, (u_int)0x143c2814,
- (u_int)0xde79a7de, (u_int)0x5ee2bc5e, (u_int)0x0b1d160b, (u_int)0xdb76addb,
- (u_int)0xe03bdbe0, (u_int)0x32566432, (u_int)0x3a4e743a, (u_int)0x0a1e140a,
- (u_int)0x49db9249, (u_int)0x060a0c06, (u_int)0x246c4824, (u_int)0x5ce4b85c,
- (u_int)0xc25d9fc2, (u_int)0xd36ebdd3, (u_int)0xacef43ac, (u_int)0x62a6c462,
- (u_int)0x91a83991, (u_int)0x95a43195, (u_int)0xe437d3e4, (u_int)0x798bf279,
- (u_int)0xe732d5e7, (u_int)0xc8438bc8, (u_int)0x37596e37, (u_int)0x6db7da6d,
- (u_int)0x8d8c018d, (u_int)0xd564b1d5, (u_int)0x4ed29c4e, (u_int)0xa9e049a9,
- (u_int)0x6cb4d86c, (u_int)0x56faac56, (u_int)0xf407f3f4, (u_int)0xea25cfea,
- (u_int)0x65afca65, (u_int)0x7a8ef47a, (u_int)0xaee947ae, (u_int)0x08181008,
- (u_int)0xbad56fba, (u_int)0x7888f078, (u_int)0x256f4a25, (u_int)0x2e725c2e,
- (u_int)0x1c24381c, (u_int)0xa6f157a6, (u_int)0xb4c773b4, (u_int)0xc65197c6,
- (u_int)0xe823cbe8, (u_int)0xdd7ca1dd, (u_int)0x749ce874, (u_int)0x1f213e1f,
- (u_int)0x4bdd964b, (u_int)0xbddc61bd, (u_int)0x8b860d8b, (u_int)0x8a850f8a,
- (u_int)0x7090e070, (u_int)0x3e427c3e, (u_int)0xb5c471b5, (u_int)0x66aacc66,
- (u_int)0x48d89048, (u_int)0x03050603, (u_int)0xf601f7f6, (u_int)0x0e121c0e,
- (u_int)0x61a3c261, (u_int)0x355f6a35, (u_int)0x57f9ae57, (u_int)0xb9d069b9,
- (u_int)0x86911786, (u_int)0xc15899c1, (u_int)0x1d273a1d, (u_int)0x9eb9279e,
- (u_int)0xe138d9e1, (u_int)0xf813ebf8, (u_int)0x98b32b98, (u_int)0x11332211,
- (u_int)0x69bbd269, (u_int)0xd970a9d9, (u_int)0x8e89078e, (u_int)0x94a73394,
- (u_int)0x9bb62d9b, (u_int)0x1e223c1e, (u_int)0x87921587, (u_int)0xe920c9e9,
- (u_int)0xce4987ce, (u_int)0x55ffaa55, (u_int)0x28785028, (u_int)0xdf7aa5df,
- (u_int)0x8c8f038c, (u_int)0xa1f859a1, (u_int)0x89800989, (u_int)0x0d171a0d,
- (u_int)0xbfda65bf, (u_int)0xe631d7e6, (u_int)0x42c68442, (u_int)0x68b8d068,
- (u_int)0x41c38241, (u_int)0x99b02999, (u_int)0x2d775a2d, (u_int)0x0f111e0f,
- (u_int)0xb0cb7bb0, (u_int)0x54fca854, (u_int)0xbbd66dbb, (u_int)0x163a2c16,
-};
-static const u32 Te3[256] = {
-
- (u_int)0x6363a5c6, (u_int)0x7c7c84f8, (u_int)0x777799ee, (u_int)0x7b7b8df6,
- (u_int)0xf2f20dff, (u_int)0x6b6bbdd6, (u_int)0x6f6fb1de, (u_int)0xc5c55491,
- (u_int)0x30305060, (u_int)0x01010302, (u_int)0x6767a9ce, (u_int)0x2b2b7d56,
- (u_int)0xfefe19e7, (u_int)0xd7d762b5, (u_int)0xababe64d, (u_int)0x76769aec,
- (u_int)0xcaca458f, (u_int)0x82829d1f, (u_int)0xc9c94089, (u_int)0x7d7d87fa,
- (u_int)0xfafa15ef, (u_int)0x5959ebb2, (u_int)0x4747c98e, (u_int)0xf0f00bfb,
- (u_int)0xadadec41, (u_int)0xd4d467b3, (u_int)0xa2a2fd5f, (u_int)0xafafea45,
- (u_int)0x9c9cbf23, (u_int)0xa4a4f753, (u_int)0x727296e4, (u_int)0xc0c05b9b,
- (u_int)0xb7b7c275, (u_int)0xfdfd1ce1, (u_int)0x9393ae3d, (u_int)0x26266a4c,
- (u_int)0x36365a6c, (u_int)0x3f3f417e, (u_int)0xf7f702f5, (u_int)0xcccc4f83,
- (u_int)0x34345c68, (u_int)0xa5a5f451, (u_int)0xe5e534d1, (u_int)0xf1f108f9,
- (u_int)0x717193e2, (u_int)0xd8d873ab, (u_int)0x31315362, (u_int)0x15153f2a,
- (u_int)0x04040c08, (u_int)0xc7c75295, (u_int)0x23236546, (u_int)0xc3c35e9d,
- (u_int)0x18182830, (u_int)0x9696a137, (u_int)0x05050f0a, (u_int)0x9a9ab52f,
- (u_int)0x0707090e, (u_int)0x12123624, (u_int)0x80809b1b, (u_int)0xe2e23ddf,
- (u_int)0xebeb26cd, (u_int)0x2727694e, (u_int)0xb2b2cd7f, (u_int)0x75759fea,
- (u_int)0x09091b12, (u_int)0x83839e1d, (u_int)0x2c2c7458, (u_int)0x1a1a2e34,
- (u_int)0x1b1b2d36, (u_int)0x6e6eb2dc, (u_int)0x5a5aeeb4, (u_int)0xa0a0fb5b,
- (u_int)0x5252f6a4, (u_int)0x3b3b4d76, (u_int)0xd6d661b7, (u_int)0xb3b3ce7d,
- (u_int)0x29297b52, (u_int)0xe3e33edd, (u_int)0x2f2f715e, (u_int)0x84849713,
- (u_int)0x5353f5a6, (u_int)0xd1d168b9, (u_int)0x00000000, (u_int)0xeded2cc1,
- (u_int)0x20206040, (u_int)0xfcfc1fe3, (u_int)0xb1b1c879, (u_int)0x5b5bedb6,
- (u_int)0x6a6abed4, (u_int)0xcbcb468d, (u_int)0xbebed967, (u_int)0x39394b72,
- (u_int)0x4a4ade94, (u_int)0x4c4cd498, (u_int)0x5858e8b0, (u_int)0xcfcf4a85,
- (u_int)0xd0d06bbb, (u_int)0xefef2ac5, (u_int)0xaaaae54f, (u_int)0xfbfb16ed,
- (u_int)0x4343c586, (u_int)0x4d4dd79a, (u_int)0x33335566, (u_int)0x85859411,
- (u_int)0x4545cf8a, (u_int)0xf9f910e9, (u_int)0x02020604, (u_int)0x7f7f81fe,
- (u_int)0x5050f0a0, (u_int)0x3c3c4478, (u_int)0x9f9fba25, (u_int)0xa8a8e34b,
- (u_int)0x5151f3a2, (u_int)0xa3a3fe5d, (u_int)0x4040c080, (u_int)0x8f8f8a05,
- (u_int)0x9292ad3f, (u_int)0x9d9dbc21, (u_int)0x38384870, (u_int)0xf5f504f1,
- (u_int)0xbcbcdf63, (u_int)0xb6b6c177, (u_int)0xdada75af, (u_int)0x21216342,
- (u_int)0x10103020, (u_int)0xffff1ae5, (u_int)0xf3f30efd, (u_int)0xd2d26dbf,
- (u_int)0xcdcd4c81, (u_int)0x0c0c1418, (u_int)0x13133526, (u_int)0xecec2fc3,
- (u_int)0x5f5fe1be, (u_int)0x9797a235, (u_int)0x4444cc88, (u_int)0x1717392e,
- (u_int)0xc4c45793, (u_int)0xa7a7f255, (u_int)0x7e7e82fc, (u_int)0x3d3d477a,
- (u_int)0x6464acc8, (u_int)0x5d5de7ba, (u_int)0x19192b32, (u_int)0x737395e6,
- (u_int)0x6060a0c0, (u_int)0x81819819, (u_int)0x4f4fd19e, (u_int)0xdcdc7fa3,
- (u_int)0x22226644, (u_int)0x2a2a7e54, (u_int)0x9090ab3b, (u_int)0x8888830b,
- (u_int)0x4646ca8c, (u_int)0xeeee29c7, (u_int)0xb8b8d36b, (u_int)0x14143c28,
- (u_int)0xdede79a7, (u_int)0x5e5ee2bc, (u_int)0x0b0b1d16, (u_int)0xdbdb76ad,
- (u_int)0xe0e03bdb, (u_int)0x32325664, (u_int)0x3a3a4e74, (u_int)0x0a0a1e14,
- (u_int)0x4949db92, (u_int)0x06060a0c, (u_int)0x24246c48, (u_int)0x5c5ce4b8,
- (u_int)0xc2c25d9f, (u_int)0xd3d36ebd, (u_int)0xacacef43, (u_int)0x6262a6c4,
- (u_int)0x9191a839, (u_int)0x9595a431, (u_int)0xe4e437d3, (u_int)0x79798bf2,
- (u_int)0xe7e732d5, (u_int)0xc8c8438b, (u_int)0x3737596e, (u_int)0x6d6db7da,
- (u_int)0x8d8d8c01, (u_int)0xd5d564b1, (u_int)0x4e4ed29c, (u_int)0xa9a9e049,
- (u_int)0x6c6cb4d8, (u_int)0x5656faac, (u_int)0xf4f407f3, (u_int)0xeaea25cf,
- (u_int)0x6565afca, (u_int)0x7a7a8ef4, (u_int)0xaeaee947, (u_int)0x08081810,
- (u_int)0xbabad56f, (u_int)0x787888f0, (u_int)0x25256f4a, (u_int)0x2e2e725c,
- (u_int)0x1c1c2438, (u_int)0xa6a6f157, (u_int)0xb4b4c773, (u_int)0xc6c65197,
- (u_int)0xe8e823cb, (u_int)0xdddd7ca1, (u_int)0x74749ce8, (u_int)0x1f1f213e,
- (u_int)0x4b4bdd96, (u_int)0xbdbddc61, (u_int)0x8b8b860d, (u_int)0x8a8a850f,
- (u_int)0x707090e0, (u_int)0x3e3e427c, (u_int)0xb5b5c471, (u_int)0x6666aacc,
- (u_int)0x4848d890, (u_int)0x03030506, (u_int)0xf6f601f7, (u_int)0x0e0e121c,
- (u_int)0x6161a3c2, (u_int)0x35355f6a, (u_int)0x5757f9ae, (u_int)0xb9b9d069,
- (u_int)0x86869117, (u_int)0xc1c15899, (u_int)0x1d1d273a, (u_int)0x9e9eb927,
- (u_int)0xe1e138d9, (u_int)0xf8f813eb, (u_int)0x9898b32b, (u_int)0x11113322,
- (u_int)0x6969bbd2, (u_int)0xd9d970a9, (u_int)0x8e8e8907, (u_int)0x9494a733,
- (u_int)0x9b9bb62d, (u_int)0x1e1e223c, (u_int)0x87879215, (u_int)0xe9e920c9,
- (u_int)0xcece4987, (u_int)0x5555ffaa, (u_int)0x28287850, (u_int)0xdfdf7aa5,
- (u_int)0x8c8c8f03, (u_int)0xa1a1f859, (u_int)0x89898009, (u_int)0x0d0d171a,
- (u_int)0xbfbfda65, (u_int)0xe6e631d7, (u_int)0x4242c684, (u_int)0x6868b8d0,
- (u_int)0x4141c382, (u_int)0x9999b029, (u_int)0x2d2d775a, (u_int)0x0f0f111e,
- (u_int)0xb0b0cb7b, (u_int)0x5454fca8, (u_int)0xbbbbd66d, (u_int)0x16163a2c,
-};
-static const u32 Te4[256] = {
- (u_int)0x63636363, (u_int)0x7c7c7c7c, (u_int)0x77777777, (u_int)0x7b7b7b7b,
- (u_int)0xf2f2f2f2, (u_int)0x6b6b6b6b, (u_int)0x6f6f6f6f, (u_int)0xc5c5c5c5,
- (u_int)0x30303030, (u_int)0x01010101, (u_int)0x67676767, (u_int)0x2b2b2b2b,
- (u_int)0xfefefefe, (u_int)0xd7d7d7d7, (u_int)0xabababab, (u_int)0x76767676,
- (u_int)0xcacacaca, (u_int)0x82828282, (u_int)0xc9c9c9c9, (u_int)0x7d7d7d7d,
- (u_int)0xfafafafa, (u_int)0x59595959, (u_int)0x47474747, (u_int)0xf0f0f0f0,
- (u_int)0xadadadad, (u_int)0xd4d4d4d4, (u_int)0xa2a2a2a2, (u_int)0xafafafaf,
- (u_int)0x9c9c9c9c, (u_int)0xa4a4a4a4, (u_int)0x72727272, (u_int)0xc0c0c0c0,
- (u_int)0xb7b7b7b7, (u_int)0xfdfdfdfd, (u_int)0x93939393, (u_int)0x26262626,
- (u_int)0x36363636, (u_int)0x3f3f3f3f, (u_int)0xf7f7f7f7, (u_int)0xcccccccc,
- (u_int)0x34343434, (u_int)0xa5a5a5a5, (u_int)0xe5e5e5e5, (u_int)0xf1f1f1f1,
- (u_int)0x71717171, (u_int)0xd8d8d8d8, (u_int)0x31313131, (u_int)0x15151515,
- (u_int)0x04040404, (u_int)0xc7c7c7c7, (u_int)0x23232323, (u_int)0xc3c3c3c3,
- (u_int)0x18181818, (u_int)0x96969696, (u_int)0x05050505, (u_int)0x9a9a9a9a,
- (u_int)0x07070707, (u_int)0x12121212, (u_int)0x80808080, (u_int)0xe2e2e2e2,
- (u_int)0xebebebeb, (u_int)0x27272727, (u_int)0xb2b2b2b2, (u_int)0x75757575,
- (u_int)0x09090909, (u_int)0x83838383, (u_int)0x2c2c2c2c, (u_int)0x1a1a1a1a,
- (u_int)0x1b1b1b1b, (u_int)0x6e6e6e6e, (u_int)0x5a5a5a5a, (u_int)0xa0a0a0a0,
- (u_int)0x52525252, (u_int)0x3b3b3b3b, (u_int)0xd6d6d6d6, (u_int)0xb3b3b3b3,
- (u_int)0x29292929, (u_int)0xe3e3e3e3, (u_int)0x2f2f2f2f, (u_int)0x84848484,
- (u_int)0x53535353, (u_int)0xd1d1d1d1, (u_int)0x00000000, (u_int)0xedededed,
- (u_int)0x20202020, (u_int)0xfcfcfcfc, (u_int)0xb1b1b1b1, (u_int)0x5b5b5b5b,
- (u_int)0x6a6a6a6a, (u_int)0xcbcbcbcb, (u_int)0xbebebebe, (u_int)0x39393939,
- (u_int)0x4a4a4a4a, (u_int)0x4c4c4c4c, (u_int)0x58585858, (u_int)0xcfcfcfcf,
- (u_int)0xd0d0d0d0, (u_int)0xefefefef, (u_int)0xaaaaaaaa, (u_int)0xfbfbfbfb,
- (u_int)0x43434343, (u_int)0x4d4d4d4d, (u_int)0x33333333, (u_int)0x85858585,
- (u_int)0x45454545, (u_int)0xf9f9f9f9, (u_int)0x02020202, (u_int)0x7f7f7f7f,
- (u_int)0x50505050, (u_int)0x3c3c3c3c, (u_int)0x9f9f9f9f, (u_int)0xa8a8a8a8,
- (u_int)0x51515151, (u_int)0xa3a3a3a3, (u_int)0x40404040, (u_int)0x8f8f8f8f,
- (u_int)0x92929292, (u_int)0x9d9d9d9d, (u_int)0x38383838, (u_int)0xf5f5f5f5,
- (u_int)0xbcbcbcbc, (u_int)0xb6b6b6b6, (u_int)0xdadadada, (u_int)0x21212121,
- (u_int)0x10101010, (u_int)0xffffffff, (u_int)0xf3f3f3f3, (u_int)0xd2d2d2d2,
- (u_int)0xcdcdcdcd, (u_int)0x0c0c0c0c, (u_int)0x13131313, (u_int)0xecececec,
- (u_int)0x5f5f5f5f, (u_int)0x97979797, (u_int)0x44444444, (u_int)0x17171717,
- (u_int)0xc4c4c4c4, (u_int)0xa7a7a7a7, (u_int)0x7e7e7e7e, (u_int)0x3d3d3d3d,
- (u_int)0x64646464, (u_int)0x5d5d5d5d, (u_int)0x19191919, (u_int)0x73737373,
- (u_int)0x60606060, (u_int)0x81818181, (u_int)0x4f4f4f4f, (u_int)0xdcdcdcdc,
- (u_int)0x22222222, (u_int)0x2a2a2a2a, (u_int)0x90909090, (u_int)0x88888888,
- (u_int)0x46464646, (u_int)0xeeeeeeee, (u_int)0xb8b8b8b8, (u_int)0x14141414,
- (u_int)0xdededede, (u_int)0x5e5e5e5e, (u_int)0x0b0b0b0b, (u_int)0xdbdbdbdb,
- (u_int)0xe0e0e0e0, (u_int)0x32323232, (u_int)0x3a3a3a3a, (u_int)0x0a0a0a0a,
- (u_int)0x49494949, (u_int)0x06060606, (u_int)0x24242424, (u_int)0x5c5c5c5c,
- (u_int)0xc2c2c2c2, (u_int)0xd3d3d3d3, (u_int)0xacacacac, (u_int)0x62626262,
- (u_int)0x91919191, (u_int)0x95959595, (u_int)0xe4e4e4e4, (u_int)0x79797979,
- (u_int)0xe7e7e7e7, (u_int)0xc8c8c8c8, (u_int)0x37373737, (u_int)0x6d6d6d6d,
- (u_int)0x8d8d8d8d, (u_int)0xd5d5d5d5, (u_int)0x4e4e4e4e, (u_int)0xa9a9a9a9,
- (u_int)0x6c6c6c6c, (u_int)0x56565656, (u_int)0xf4f4f4f4, (u_int)0xeaeaeaea,
- (u_int)0x65656565, (u_int)0x7a7a7a7a, (u_int)0xaeaeaeae, (u_int)0x08080808,
- (u_int)0xbabababa, (u_int)0x78787878, (u_int)0x25252525, (u_int)0x2e2e2e2e,
- (u_int)0x1c1c1c1c, (u_int)0xa6a6a6a6, (u_int)0xb4b4b4b4, (u_int)0xc6c6c6c6,
- (u_int)0xe8e8e8e8, (u_int)0xdddddddd, (u_int)0x74747474, (u_int)0x1f1f1f1f,
- (u_int)0x4b4b4b4b, (u_int)0xbdbdbdbd, (u_int)0x8b8b8b8b, (u_int)0x8a8a8a8a,
- (u_int)0x70707070, (u_int)0x3e3e3e3e, (u_int)0xb5b5b5b5, (u_int)0x66666666,
- (u_int)0x48484848, (u_int)0x03030303, (u_int)0xf6f6f6f6, (u_int)0x0e0e0e0e,
- (u_int)0x61616161, (u_int)0x35353535, (u_int)0x57575757, (u_int)0xb9b9b9b9,
- (u_int)0x86868686, (u_int)0xc1c1c1c1, (u_int)0x1d1d1d1d, (u_int)0x9e9e9e9e,
- (u_int)0xe1e1e1e1, (u_int)0xf8f8f8f8, (u_int)0x98989898, (u_int)0x11111111,
- (u_int)0x69696969, (u_int)0xd9d9d9d9, (u_int)0x8e8e8e8e, (u_int)0x94949494,
- (u_int)0x9b9b9b9b, (u_int)0x1e1e1e1e, (u_int)0x87878787, (u_int)0xe9e9e9e9,
- (u_int)0xcececece, (u_int)0x55555555, (u_int)0x28282828, (u_int)0xdfdfdfdf,
- (u_int)0x8c8c8c8c, (u_int)0xa1a1a1a1, (u_int)0x89898989, (u_int)0x0d0d0d0d,
- (u_int)0xbfbfbfbf, (u_int)0xe6e6e6e6, (u_int)0x42424242, (u_int)0x68686868,
- (u_int)0x41414141, (u_int)0x99999999, (u_int)0x2d2d2d2d, (u_int)0x0f0f0f0f,
- (u_int)0xb0b0b0b0, (u_int)0x54545454, (u_int)0xbbbbbbbb, (u_int)0x16161616,
-};
-static const u32 Td0[256] = {
- (u_int)0x51f4a750, (u_int)0x7e416553, (u_int)0x1a17a4c3, (u_int)0x3a275e96,
- (u_int)0x3bab6bcb, (u_int)0x1f9d45f1, (u_int)0xacfa58ab, (u_int)0x4be30393,
- (u_int)0x2030fa55, (u_int)0xad766df6, (u_int)0x88cc7691, (u_int)0xf5024c25,
- (u_int)0x4fe5d7fc, (u_int)0xc52acbd7, (u_int)0x26354480, (u_int)0xb562a38f,
- (u_int)0xdeb15a49, (u_int)0x25ba1b67, (u_int)0x45ea0e98, (u_int)0x5dfec0e1,
- (u_int)0xc32f7502, (u_int)0x814cf012, (u_int)0x8d4697a3, (u_int)0x6bd3f9c6,
- (u_int)0x038f5fe7, (u_int)0x15929c95, (u_int)0xbf6d7aeb, (u_int)0x955259da,
- (u_int)0xd4be832d, (u_int)0x587421d3, (u_int)0x49e06929, (u_int)0x8ec9c844,
- (u_int)0x75c2896a, (u_int)0xf48e7978, (u_int)0x99583e6b, (u_int)0x27b971dd,
- (u_int)0xbee14fb6, (u_int)0xf088ad17, (u_int)0xc920ac66, (u_int)0x7dce3ab4,
- (u_int)0x63df4a18, (u_int)0xe51a3182, (u_int)0x97513360, (u_int)0x62537f45,
- (u_int)0xb16477e0, (u_int)0xbb6bae84, (u_int)0xfe81a01c, (u_int)0xf9082b94,
- (u_int)0x70486858, (u_int)0x8f45fd19, (u_int)0x94de6c87, (u_int)0x527bf8b7,
- (u_int)0xab73d323, (u_int)0x724b02e2, (u_int)0xe31f8f57, (u_int)0x6655ab2a,
- (u_int)0xb2eb2807, (u_int)0x2fb5c203, (u_int)0x86c57b9a, (u_int)0xd33708a5,
- (u_int)0x302887f2, (u_int)0x23bfa5b2, (u_int)0x02036aba, (u_int)0xed16825c,
- (u_int)0x8acf1c2b, (u_int)0xa779b492, (u_int)0xf307f2f0, (u_int)0x4e69e2a1,
- (u_int)0x65daf4cd, (u_int)0x0605bed5, (u_int)0xd134621f, (u_int)0xc4a6fe8a,
- (u_int)0x342e539d, (u_int)0xa2f355a0, (u_int)0x058ae132, (u_int)0xa4f6eb75,
- (u_int)0x0b83ec39, (u_int)0x4060efaa, (u_int)0x5e719f06, (u_int)0xbd6e1051,
- (u_int)0x3e218af9, (u_int)0x96dd063d, (u_int)0xdd3e05ae, (u_int)0x4de6bd46,
- (u_int)0x91548db5, (u_int)0x71c45d05, (u_int)0x0406d46f, (u_int)0x605015ff,
- (u_int)0x1998fb24, (u_int)0xd6bde997, (u_int)0x894043cc, (u_int)0x67d99e77,
- (u_int)0xb0e842bd, (u_int)0x07898b88, (u_int)0xe7195b38, (u_int)0x79c8eedb,
- (u_int)0xa17c0a47, (u_int)0x7c420fe9, (u_int)0xf8841ec9, (u_int)0x00000000,
- (u_int)0x09808683, (u_int)0x322bed48, (u_int)0x1e1170ac, (u_int)0x6c5a724e,
- (u_int)0xfd0efffb, (u_int)0x0f853856, (u_int)0x3daed51e, (u_int)0x362d3927,
- (u_int)0x0a0fd964, (u_int)0x685ca621, (u_int)0x9b5b54d1, (u_int)0x24362e3a,
- (u_int)0x0c0a67b1, (u_int)0x9357e70f, (u_int)0xb4ee96d2, (u_int)0x1b9b919e,
- (u_int)0x80c0c54f, (u_int)0x61dc20a2, (u_int)0x5a774b69, (u_int)0x1c121a16,
- (u_int)0xe293ba0a, (u_int)0xc0a02ae5, (u_int)0x3c22e043, (u_int)0x121b171d,
- (u_int)0x0e090d0b, (u_int)0xf28bc7ad, (u_int)0x2db6a8b9, (u_int)0x141ea9c8,
- (u_int)0x57f11985, (u_int)0xaf75074c, (u_int)0xee99ddbb, (u_int)0xa37f60fd,
- (u_int)0xf701269f, (u_int)0x5c72f5bc, (u_int)0x44663bc5, (u_int)0x5bfb7e34,
- (u_int)0x8b432976, (u_int)0xcb23c6dc, (u_int)0xb6edfc68, (u_int)0xb8e4f163,
- (u_int)0xd731dcca, (u_int)0x42638510, (u_int)0x13972240, (u_int)0x84c61120,
- (u_int)0x854a247d, (u_int)0xd2bb3df8, (u_int)0xaef93211, (u_int)0xc729a16d,
- (u_int)0x1d9e2f4b, (u_int)0xdcb230f3, (u_int)0x0d8652ec, (u_int)0x77c1e3d0,
- (u_int)0x2bb3166c, (u_int)0xa970b999, (u_int)0x119448fa, (u_int)0x47e96422,
- (u_int)0xa8fc8cc4, (u_int)0xa0f03f1a, (u_int)0x567d2cd8, (u_int)0x223390ef,
- (u_int)0x87494ec7, (u_int)0xd938d1c1, (u_int)0x8ccaa2fe, (u_int)0x98d40b36,
- (u_int)0xa6f581cf, (u_int)0xa57ade28, (u_int)0xdab78e26, (u_int)0x3fadbfa4,
- (u_int)0x2c3a9de4, (u_int)0x5078920d, (u_int)0x6a5fcc9b, (u_int)0x547e4662,
- (u_int)0xf68d13c2, (u_int)0x90d8b8e8, (u_int)0x2e39f75e, (u_int)0x82c3aff5,
- (u_int)0x9f5d80be, (u_int)0x69d0937c, (u_int)0x6fd52da9, (u_int)0xcf2512b3,
- (u_int)0xc8ac993b, (u_int)0x10187da7, (u_int)0xe89c636e, (u_int)0xdb3bbb7b,
- (u_int)0xcd267809, (u_int)0x6e5918f4, (u_int)0xec9ab701, (u_int)0x834f9aa8,
- (u_int)0xe6956e65, (u_int)0xaaffe67e, (u_int)0x21bccf08, (u_int)0xef15e8e6,
- (u_int)0xbae79bd9, (u_int)0x4a6f36ce, (u_int)0xea9f09d4, (u_int)0x29b07cd6,
- (u_int)0x31a4b2af, (u_int)0x2a3f2331, (u_int)0xc6a59430, (u_int)0x35a266c0,
- (u_int)0x744ebc37, (u_int)0xfc82caa6, (u_int)0xe090d0b0, (u_int)0x33a7d815,
- (u_int)0xf104984a, (u_int)0x41ecdaf7, (u_int)0x7fcd500e, (u_int)0x1791f62f,
- (u_int)0x764dd68d, (u_int)0x43efb04d, (u_int)0xccaa4d54, (u_int)0xe49604df,
- (u_int)0x9ed1b5e3, (u_int)0x4c6a881b, (u_int)0xc12c1fb8, (u_int)0x4665517f,
- (u_int)0x9d5eea04, (u_int)0x018c355d, (u_int)0xfa877473, (u_int)0xfb0b412e,
- (u_int)0xb3671d5a, (u_int)0x92dbd252, (u_int)0xe9105633, (u_int)0x6dd64713,
- (u_int)0x9ad7618c, (u_int)0x37a10c7a, (u_int)0x59f8148e, (u_int)0xeb133c89,
- (u_int)0xcea927ee, (u_int)0xb761c935, (u_int)0xe11ce5ed, (u_int)0x7a47b13c,
- (u_int)0x9cd2df59, (u_int)0x55f2733f, (u_int)0x1814ce79, (u_int)0x73c737bf,
- (u_int)0x53f7cdea, (u_int)0x5ffdaa5b, (u_int)0xdf3d6f14, (u_int)0x7844db86,
- (u_int)0xcaaff381, (u_int)0xb968c43e, (u_int)0x3824342c, (u_int)0xc2a3405f,
- (u_int)0x161dc372, (u_int)0xbce2250c, (u_int)0x283c498b, (u_int)0xff0d9541,
- (u_int)0x39a80171, (u_int)0x080cb3de, (u_int)0xd8b4e49c, (u_int)0x6456c190,
- (u_int)0x7bcb8461, (u_int)0xd532b670, (u_int)0x486c5c74, (u_int)0xd0b85742,
-};
-static const u32 Td1[256] = {
- (u_int)0x5051f4a7, (u_int)0x537e4165, (u_int)0xc31a17a4, (u_int)0x963a275e,
- (u_int)0xcb3bab6b, (u_int)0xf11f9d45, (u_int)0xabacfa58, (u_int)0x934be303,
- (u_int)0x552030fa, (u_int)0xf6ad766d, (u_int)0x9188cc76, (u_int)0x25f5024c,
- (u_int)0xfc4fe5d7, (u_int)0xd7c52acb, (u_int)0x80263544, (u_int)0x8fb562a3,
- (u_int)0x49deb15a, (u_int)0x6725ba1b, (u_int)0x9845ea0e, (u_int)0xe15dfec0,
- (u_int)0x02c32f75, (u_int)0x12814cf0, (u_int)0xa38d4697, (u_int)0xc66bd3f9,
- (u_int)0xe7038f5f, (u_int)0x9515929c, (u_int)0xebbf6d7a, (u_int)0xda955259,
- (u_int)0x2dd4be83, (u_int)0xd3587421, (u_int)0x2949e069, (u_int)0x448ec9c8,
- (u_int)0x6a75c289, (u_int)0x78f48e79, (u_int)0x6b99583e, (u_int)0xdd27b971,
- (u_int)0xb6bee14f, (u_int)0x17f088ad, (u_int)0x66c920ac, (u_int)0xb47dce3a,
- (u_int)0x1863df4a, (u_int)0x82e51a31, (u_int)0x60975133, (u_int)0x4562537f,
- (u_int)0xe0b16477, (u_int)0x84bb6bae, (u_int)0x1cfe81a0, (u_int)0x94f9082b,
- (u_int)0x58704868, (u_int)0x198f45fd, (u_int)0x8794de6c, (u_int)0xb7527bf8,
- (u_int)0x23ab73d3, (u_int)0xe2724b02, (u_int)0x57e31f8f, (u_int)0x2a6655ab,
- (u_int)0x07b2eb28, (u_int)0x032fb5c2, (u_int)0x9a86c57b, (u_int)0xa5d33708,
- (u_int)0xf2302887, (u_int)0xb223bfa5, (u_int)0xba02036a, (u_int)0x5ced1682,
- (u_int)0x2b8acf1c, (u_int)0x92a779b4, (u_int)0xf0f307f2, (u_int)0xa14e69e2,
- (u_int)0xcd65daf4, (u_int)0xd50605be, (u_int)0x1fd13462, (u_int)0x8ac4a6fe,
- (u_int)0x9d342e53, (u_int)0xa0a2f355, (u_int)0x32058ae1, (u_int)0x75a4f6eb,
- (u_int)0x390b83ec, (u_int)0xaa4060ef, (u_int)0x065e719f, (u_int)0x51bd6e10,
- (u_int)0xf93e218a, (u_int)0x3d96dd06, (u_int)0xaedd3e05, (u_int)0x464de6bd,
- (u_int)0xb591548d, (u_int)0x0571c45d, (u_int)0x6f0406d4, (u_int)0xff605015,
- (u_int)0x241998fb, (u_int)0x97d6bde9, (u_int)0xcc894043, (u_int)0x7767d99e,
- (u_int)0xbdb0e842, (u_int)0x8807898b, (u_int)0x38e7195b, (u_int)0xdb79c8ee,
- (u_int)0x47a17c0a, (u_int)0xe97c420f, (u_int)0xc9f8841e, (u_int)0x00000000,
- (u_int)0x83098086, (u_int)0x48322bed, (u_int)0xac1e1170, (u_int)0x4e6c5a72,
- (u_int)0xfbfd0eff, (u_int)0x560f8538, (u_int)0x1e3daed5, (u_int)0x27362d39,
- (u_int)0x640a0fd9, (u_int)0x21685ca6, (u_int)0xd19b5b54, (u_int)0x3a24362e,
- (u_int)0xb10c0a67, (u_int)0x0f9357e7, (u_int)0xd2b4ee96, (u_int)0x9e1b9b91,
- (u_int)0x4f80c0c5, (u_int)0xa261dc20, (u_int)0x695a774b, (u_int)0x161c121a,
- (u_int)0x0ae293ba, (u_int)0xe5c0a02a, (u_int)0x433c22e0, (u_int)0x1d121b17,
- (u_int)0x0b0e090d, (u_int)0xadf28bc7, (u_int)0xb92db6a8, (u_int)0xc8141ea9,
- (u_int)0x8557f119, (u_int)0x4caf7507, (u_int)0xbbee99dd, (u_int)0xfda37f60,
- (u_int)0x9ff70126, (u_int)0xbc5c72f5, (u_int)0xc544663b, (u_int)0x345bfb7e,
- (u_int)0x768b4329, (u_int)0xdccb23c6, (u_int)0x68b6edfc, (u_int)0x63b8e4f1,
- (u_int)0xcad731dc, (u_int)0x10426385, (u_int)0x40139722, (u_int)0x2084c611,
- (u_int)0x7d854a24, (u_int)0xf8d2bb3d, (u_int)0x11aef932, (u_int)0x6dc729a1,
- (u_int)0x4b1d9e2f, (u_int)0xf3dcb230, (u_int)0xec0d8652, (u_int)0xd077c1e3,
- (u_int)0x6c2bb316, (u_int)0x99a970b9, (u_int)0xfa119448, (u_int)0x2247e964,
- (u_int)0xc4a8fc8c, (u_int)0x1aa0f03f, (u_int)0xd8567d2c, (u_int)0xef223390,
- (u_int)0xc787494e, (u_int)0xc1d938d1, (u_int)0xfe8ccaa2, (u_int)0x3698d40b,
- (u_int)0xcfa6f581, (u_int)0x28a57ade, (u_int)0x26dab78e, (u_int)0xa43fadbf,
- (u_int)0xe42c3a9d, (u_int)0x0d507892, (u_int)0x9b6a5fcc, (u_int)0x62547e46,
- (u_int)0xc2f68d13, (u_int)0xe890d8b8, (u_int)0x5e2e39f7, (u_int)0xf582c3af,
- (u_int)0xbe9f5d80, (u_int)0x7c69d093, (u_int)0xa96fd52d, (u_int)0xb3cf2512,
- (u_int)0x3bc8ac99, (u_int)0xa710187d, (u_int)0x6ee89c63, (u_int)0x7bdb3bbb,
- (u_int)0x09cd2678, (u_int)0xf46e5918, (u_int)0x01ec9ab7, (u_int)0xa8834f9a,
- (u_int)0x65e6956e, (u_int)0x7eaaffe6, (u_int)0x0821bccf, (u_int)0xe6ef15e8,
- (u_int)0xd9bae79b, (u_int)0xce4a6f36, (u_int)0xd4ea9f09, (u_int)0xd629b07c,
- (u_int)0xaf31a4b2, (u_int)0x312a3f23, (u_int)0x30c6a594, (u_int)0xc035a266,
- (u_int)0x37744ebc, (u_int)0xa6fc82ca, (u_int)0xb0e090d0, (u_int)0x1533a7d8,
- (u_int)0x4af10498, (u_int)0xf741ecda, (u_int)0x0e7fcd50, (u_int)0x2f1791f6,
- (u_int)0x8d764dd6, (u_int)0x4d43efb0, (u_int)0x54ccaa4d, (u_int)0xdfe49604,
- (u_int)0xe39ed1b5, (u_int)0x1b4c6a88, (u_int)0xb8c12c1f, (u_int)0x7f466551,
- (u_int)0x049d5eea, (u_int)0x5d018c35, (u_int)0x73fa8774, (u_int)0x2efb0b41,
- (u_int)0x5ab3671d, (u_int)0x5292dbd2, (u_int)0x33e91056, (u_int)0x136dd647,
- (u_int)0x8c9ad761, (u_int)0x7a37a10c, (u_int)0x8e59f814, (u_int)0x89eb133c,
- (u_int)0xeecea927, (u_int)0x35b761c9, (u_int)0xede11ce5, (u_int)0x3c7a47b1,
- (u_int)0x599cd2df, (u_int)0x3f55f273, (u_int)0x791814ce, (u_int)0xbf73c737,
- (u_int)0xea53f7cd, (u_int)0x5b5ffdaa, (u_int)0x14df3d6f, (u_int)0x867844db,
- (u_int)0x81caaff3, (u_int)0x3eb968c4, (u_int)0x2c382434, (u_int)0x5fc2a340,
- (u_int)0x72161dc3, (u_int)0x0cbce225, (u_int)0x8b283c49, (u_int)0x41ff0d95,
- (u_int)0x7139a801, (u_int)0xde080cb3, (u_int)0x9cd8b4e4, (u_int)0x906456c1,
- (u_int)0x617bcb84, (u_int)0x70d532b6, (u_int)0x74486c5c, (u_int)0x42d0b857,
-};
-static const u32 Td2[256] = {
- (u_int)0xa75051f4, (u_int)0x65537e41, (u_int)0xa4c31a17, (u_int)0x5e963a27,
- (u_int)0x6bcb3bab, (u_int)0x45f11f9d, (u_int)0x58abacfa, (u_int)0x03934be3,
- (u_int)0xfa552030, (u_int)0x6df6ad76, (u_int)0x769188cc, (u_int)0x4c25f502,
- (u_int)0xd7fc4fe5, (u_int)0xcbd7c52a, (u_int)0x44802635, (u_int)0xa38fb562,
- (u_int)0x5a49deb1, (u_int)0x1b6725ba, (u_int)0x0e9845ea, (u_int)0xc0e15dfe,
- (u_int)0x7502c32f, (u_int)0xf012814c, (u_int)0x97a38d46, (u_int)0xf9c66bd3,
- (u_int)0x5fe7038f, (u_int)0x9c951592, (u_int)0x7aebbf6d, (u_int)0x59da9552,
- (u_int)0x832dd4be, (u_int)0x21d35874, (u_int)0x692949e0, (u_int)0xc8448ec9,
- (u_int)0x896a75c2, (u_int)0x7978f48e, (u_int)0x3e6b9958, (u_int)0x71dd27b9,
- (u_int)0x4fb6bee1, (u_int)0xad17f088, (u_int)0xac66c920, (u_int)0x3ab47dce,
- (u_int)0x4a1863df, (u_int)0x3182e51a, (u_int)0x33609751, (u_int)0x7f456253,
- (u_int)0x77e0b164, (u_int)0xae84bb6b, (u_int)0xa01cfe81, (u_int)0x2b94f908,
- (u_int)0x68587048, (u_int)0xfd198f45, (u_int)0x6c8794de, (u_int)0xf8b7527b,
- (u_int)0xd323ab73, (u_int)0x02e2724b, (u_int)0x8f57e31f, (u_int)0xab2a6655,
- (u_int)0x2807b2eb, (u_int)0xc2032fb5, (u_int)0x7b9a86c5, (u_int)0x08a5d337,
- (u_int)0x87f23028, (u_int)0xa5b223bf, (u_int)0x6aba0203, (u_int)0x825ced16,
- (u_int)0x1c2b8acf, (u_int)0xb492a779, (u_int)0xf2f0f307, (u_int)0xe2a14e69,
- (u_int)0xf4cd65da, (u_int)0xbed50605, (u_int)0x621fd134, (u_int)0xfe8ac4a6,
- (u_int)0x539d342e, (u_int)0x55a0a2f3, (u_int)0xe132058a, (u_int)0xeb75a4f6,
- (u_int)0xec390b83, (u_int)0xefaa4060, (u_int)0x9f065e71, (u_int)0x1051bd6e,
-
- (u_int)0x8af93e21, (u_int)0x063d96dd, (u_int)0x05aedd3e, (u_int)0xbd464de6,
- (u_int)0x8db59154, (u_int)0x5d0571c4, (u_int)0xd46f0406, (u_int)0x15ff6050,
- (u_int)0xfb241998, (u_int)0xe997d6bd, (u_int)0x43cc8940, (u_int)0x9e7767d9,
- (u_int)0x42bdb0e8, (u_int)0x8b880789, (u_int)0x5b38e719, (u_int)0xeedb79c8,
- (u_int)0x0a47a17c, (u_int)0x0fe97c42, (u_int)0x1ec9f884, (u_int)0x00000000,
- (u_int)0x86830980, (u_int)0xed48322b, (u_int)0x70ac1e11, (u_int)0x724e6c5a,
- (u_int)0xfffbfd0e, (u_int)0x38560f85, (u_int)0xd51e3dae, (u_int)0x3927362d,
- (u_int)0xd9640a0f, (u_int)0xa621685c, (u_int)0x54d19b5b, (u_int)0x2e3a2436,
- (u_int)0x67b10c0a, (u_int)0xe70f9357, (u_int)0x96d2b4ee, (u_int)0x919e1b9b,
- (u_int)0xc54f80c0, (u_int)0x20a261dc, (u_int)0x4b695a77, (u_int)0x1a161c12,
- (u_int)0xba0ae293, (u_int)0x2ae5c0a0, (u_int)0xe0433c22, (u_int)0x171d121b,
- (u_int)0x0d0b0e09, (u_int)0xc7adf28b, (u_int)0xa8b92db6, (u_int)0xa9c8141e,
- (u_int)0x198557f1, (u_int)0x074caf75, (u_int)0xddbbee99, (u_int)0x60fda37f,
- (u_int)0x269ff701, (u_int)0xf5bc5c72, (u_int)0x3bc54466, (u_int)0x7e345bfb,
- (u_int)0x29768b43, (u_int)0xc6dccb23, (u_int)0xfc68b6ed, (u_int)0xf163b8e4,
- (u_int)0xdccad731, (u_int)0x85104263, (u_int)0x22401397, (u_int)0x112084c6,
- (u_int)0x247d854a, (u_int)0x3df8d2bb, (u_int)0x3211aef9, (u_int)0xa16dc729,
- (u_int)0x2f4b1d9e, (u_int)0x30f3dcb2, (u_int)0x52ec0d86, (u_int)0xe3d077c1,
- (u_int)0x166c2bb3, (u_int)0xb999a970, (u_int)0x48fa1194, (u_int)0x642247e9,
- (u_int)0x8cc4a8fc, (u_int)0x3f1aa0f0, (u_int)0x2cd8567d, (u_int)0x90ef2233,
- (u_int)0x4ec78749, (u_int)0xd1c1d938, (u_int)0xa2fe8cca, (u_int)0x0b3698d4,
- (u_int)0x81cfa6f5, (u_int)0xde28a57a, (u_int)0x8e26dab7, (u_int)0xbfa43fad,
- (u_int)0x9de42c3a, (u_int)0x920d5078, (u_int)0xcc9b6a5f, (u_int)0x4662547e,
- (u_int)0x13c2f68d, (u_int)0xb8e890d8, (u_int)0xf75e2e39, (u_int)0xaff582c3,
- (u_int)0x80be9f5d, (u_int)0x937c69d0, (u_int)0x2da96fd5, (u_int)0x12b3cf25,
- (u_int)0x993bc8ac, (u_int)0x7da71018, (u_int)0x636ee89c, (u_int)0xbb7bdb3b,
- (u_int)0x7809cd26, (u_int)0x18f46e59, (u_int)0xb701ec9a, (u_int)0x9aa8834f,
- (u_int)0x6e65e695, (u_int)0xe67eaaff, (u_int)0xcf0821bc, (u_int)0xe8e6ef15,
- (u_int)0x9bd9bae7, (u_int)0x36ce4a6f, (u_int)0x09d4ea9f, (u_int)0x7cd629b0,
- (u_int)0xb2af31a4, (u_int)0x23312a3f, (u_int)0x9430c6a5, (u_int)0x66c035a2,
- (u_int)0xbc37744e, (u_int)0xcaa6fc82, (u_int)0xd0b0e090, (u_int)0xd81533a7,
- (u_int)0x984af104, (u_int)0xdaf741ec, (u_int)0x500e7fcd, (u_int)0xf62f1791,
- (u_int)0xd68d764d, (u_int)0xb04d43ef, (u_int)0x4d54ccaa, (u_int)0x04dfe496,
- (u_int)0xb5e39ed1, (u_int)0x881b4c6a, (u_int)0x1fb8c12c, (u_int)0x517f4665,
- (u_int)0xea049d5e, (u_int)0x355d018c, (u_int)0x7473fa87, (u_int)0x412efb0b,
- (u_int)0x1d5ab367, (u_int)0xd25292db, (u_int)0x5633e910, (u_int)0x47136dd6,
- (u_int)0x618c9ad7, (u_int)0x0c7a37a1, (u_int)0x148e59f8, (u_int)0x3c89eb13,
- (u_int)0x27eecea9, (u_int)0xc935b761, (u_int)0xe5ede11c, (u_int)0xb13c7a47,
- (u_int)0xdf599cd2, (u_int)0x733f55f2, (u_int)0xce791814, (u_int)0x37bf73c7,
- (u_int)0xcdea53f7, (u_int)0xaa5b5ffd, (u_int)0x6f14df3d, (u_int)0xdb867844,
- (u_int)0xf381caaf, (u_int)0xc43eb968, (u_int)0x342c3824, (u_int)0x405fc2a3,
- (u_int)0xc372161d, (u_int)0x250cbce2, (u_int)0x498b283c, (u_int)0x9541ff0d,
- (u_int)0x017139a8, (u_int)0xb3de080c, (u_int)0xe49cd8b4, (u_int)0xc1906456,
- (u_int)0x84617bcb, (u_int)0xb670d532, (u_int)0x5c74486c, (u_int)0x5742d0b8,
-};
-static const u32 Td3[256] = {
- (u_int)0xf4a75051, (u_int)0x4165537e, (u_int)0x17a4c31a, (u_int)0x275e963a,
- (u_int)0xab6bcb3b, (u_int)0x9d45f11f, (u_int)0xfa58abac, (u_int)0xe303934b,
- (u_int)0x30fa5520, (u_int)0x766df6ad, (u_int)0xcc769188, (u_int)0x024c25f5,
- (u_int)0xe5d7fc4f, (u_int)0x2acbd7c5, (u_int)0x35448026, (u_int)0x62a38fb5,
- (u_int)0xb15a49de, (u_int)0xba1b6725, (u_int)0xea0e9845, (u_int)0xfec0e15d,
- (u_int)0x2f7502c3, (u_int)0x4cf01281, (u_int)0x4697a38d, (u_int)0xd3f9c66b,
- (u_int)0x8f5fe703, (u_int)0x929c9515, (u_int)0x6d7aebbf, (u_int)0x5259da95,
- (u_int)0xbe832dd4, (u_int)0x7421d358, (u_int)0xe0692949, (u_int)0xc9c8448e,
- (u_int)0xc2896a75, (u_int)0x8e7978f4, (u_int)0x583e6b99, (u_int)0xb971dd27,
- (u_int)0xe14fb6be, (u_int)0x88ad17f0, (u_int)0x20ac66c9, (u_int)0xce3ab47d,
- (u_int)0xdf4a1863, (u_int)0x1a3182e5, (u_int)0x51336097, (u_int)0x537f4562,
- (u_int)0x6477e0b1, (u_int)0x6bae84bb, (u_int)0x81a01cfe, (u_int)0x082b94f9,
- (u_int)0x48685870, (u_int)0x45fd198f, (u_int)0xde6c8794, (u_int)0x7bf8b752,
- (u_int)0x73d323ab, (u_int)0x4b02e272, (u_int)0x1f8f57e3, (u_int)0x55ab2a66,
- (u_int)0xeb2807b2, (u_int)0xb5c2032f, (u_int)0xc57b9a86, (u_int)0x3708a5d3,
- (u_int)0x2887f230, (u_int)0xbfa5b223, (u_int)0x036aba02, (u_int)0x16825ced,
- (u_int)0xcf1c2b8a, (u_int)0x79b492a7, (u_int)0x07f2f0f3, (u_int)0x69e2a14e,
- (u_int)0xdaf4cd65, (u_int)0x05bed506, (u_int)0x34621fd1, (u_int)0xa6fe8ac4,
- (u_int)0x2e539d34, (u_int)0xf355a0a2, (u_int)0x8ae13205, (u_int)0xf6eb75a4,
- (u_int)0x83ec390b, (u_int)0x60efaa40, (u_int)0x719f065e, (u_int)0x6e1051bd,
- (u_int)0x218af93e, (u_int)0xdd063d96, (u_int)0x3e05aedd, (u_int)0xe6bd464d,
- (u_int)0x548db591, (u_int)0xc45d0571, (u_int)0x06d46f04, (u_int)0x5015ff60,
- (u_int)0x98fb2419, (u_int)0xbde997d6, (u_int)0x4043cc89, (u_int)0xd99e7767,
- (u_int)0xe842bdb0, (u_int)0x898b8807, (u_int)0x195b38e7, (u_int)0xc8eedb79,
- (u_int)0x7c0a47a1, (u_int)0x420fe97c, (u_int)0x841ec9f8, (u_int)0x00000000,
- (u_int)0x80868309, (u_int)0x2bed4832, (u_int)0x1170ac1e, (u_int)0x5a724e6c,
- (u_int)0x0efffbfd, (u_int)0x8538560f, (u_int)0xaed51e3d, (u_int)0x2d392736,
- (u_int)0x0fd9640a, (u_int)0x5ca62168, (u_int)0x5b54d19b, (u_int)0x362e3a24,
- (u_int)0x0a67b10c, (u_int)0x57e70f93, (u_int)0xee96d2b4, (u_int)0x9b919e1b,
- (u_int)0xc0c54f80, (u_int)0xdc20a261, (u_int)0x774b695a, (u_int)0x121a161c,
- (u_int)0x93ba0ae2, (u_int)0xa02ae5c0, (u_int)0x22e0433c, (u_int)0x1b171d12,
- (u_int)0x090d0b0e, (u_int)0x8bc7adf2, (u_int)0xb6a8b92d, (u_int)0x1ea9c814,
- (u_int)0xf1198557, (u_int)0x75074caf, (u_int)0x99ddbbee, (u_int)0x7f60fda3,
- (u_int)0x01269ff7, (u_int)0x72f5bc5c, (u_int)0x663bc544, (u_int)0xfb7e345b,
- (u_int)0x4329768b, (u_int)0x23c6dccb, (u_int)0xedfc68b6, (u_int)0xe4f163b8,
- (u_int)0x31dccad7, (u_int)0x63851042, (u_int)0x97224013, (u_int)0xc6112084,
- (u_int)0x4a247d85, (u_int)0xbb3df8d2, (u_int)0xf93211ae, (u_int)0x29a16dc7,
- (u_int)0x9e2f4b1d, (u_int)0xb230f3dc, (u_int)0x8652ec0d, (u_int)0xc1e3d077,
- (u_int)0xb3166c2b, (u_int)0x70b999a9, (u_int)0x9448fa11, (u_int)0xe9642247,
- (u_int)0xfc8cc4a8, (u_int)0xf03f1aa0, (u_int)0x7d2cd856, (u_int)0x3390ef22,
- (u_int)0x494ec787, (u_int)0x38d1c1d9, (u_int)0xcaa2fe8c, (u_int)0xd40b3698,
- (u_int)0xf581cfa6, (u_int)0x7ade28a5, (u_int)0xb78e26da, (u_int)0xadbfa43f,
- (u_int)0x3a9de42c, (u_int)0x78920d50, (u_int)0x5fcc9b6a, (u_int)0x7e466254,
- (u_int)0x8d13c2f6, (u_int)0xd8b8e890, (u_int)0x39f75e2e, (u_int)0xc3aff582,
- (u_int)0x5d80be9f, (u_int)0xd0937c69, (u_int)0xd52da96f, (u_int)0x2512b3cf,
- (u_int)0xac993bc8, (u_int)0x187da710, (u_int)0x9c636ee8, (u_int)0x3bbb7bdb,
- (u_int)0x267809cd, (u_int)0x5918f46e, (u_int)0x9ab701ec, (u_int)0x4f9aa883,
- (u_int)0x956e65e6, (u_int)0xffe67eaa, (u_int)0xbccf0821, (u_int)0x15e8e6ef,
- (u_int)0xe79bd9ba, (u_int)0x6f36ce4a, (u_int)0x9f09d4ea, (u_int)0xb07cd629,
- (u_int)0xa4b2af31, (u_int)0x3f23312a, (u_int)0xa59430c6, (u_int)0xa266c035,
- (u_int)0x4ebc3774, (u_int)0x82caa6fc, (u_int)0x90d0b0e0, (u_int)0xa7d81533,
- (u_int)0x04984af1, (u_int)0xecdaf741, (u_int)0xcd500e7f, (u_int)0x91f62f17,
- (u_int)0x4dd68d76, (u_int)0xefb04d43, (u_int)0xaa4d54cc, (u_int)0x9604dfe4,
- (u_int)0xd1b5e39e, (u_int)0x6a881b4c, (u_int)0x2c1fb8c1, (u_int)0x65517f46,
- (u_int)0x5eea049d, (u_int)0x8c355d01, (u_int)0x877473fa, (u_int)0x0b412efb,
- (u_int)0x671d5ab3, (u_int)0xdbd25292, (u_int)0x105633e9, (u_int)0xd647136d,
- (u_int)0xd7618c9a, (u_int)0xa10c7a37, (u_int)0xf8148e59, (u_int)0x133c89eb,
- (u_int)0xa927eece, (u_int)0x61c935b7, (u_int)0x1ce5ede1, (u_int)0x47b13c7a,
- (u_int)0xd2df599c, (u_int)0xf2733f55, (u_int)0x14ce7918, (u_int)0xc737bf73,
- (u_int)0xf7cdea53, (u_int)0xfdaa5b5f, (u_int)0x3d6f14df, (u_int)0x44db8678,
- (u_int)0xaff381ca, (u_int)0x68c43eb9, (u_int)0x24342c38, (u_int)0xa3405fc2,
- (u_int)0x1dc37216, (u_int)0xe2250cbc, (u_int)0x3c498b28, (u_int)0x0d9541ff,
- (u_int)0xa8017139, (u_int)0x0cb3de08, (u_int)0xb4e49cd8, (u_int)0x56c19064,
- (u_int)0xcb84617b, (u_int)0x32b670d5, (u_int)0x6c5c7448, (u_int)0xb85742d0,
-};
-static const u32 Td4[256] = {
- (u_int)0x52525252, (u_int)0x09090909, (u_int)0x6a6a6a6a, (u_int)0xd5d5d5d5,
- (u_int)0x30303030, (u_int)0x36363636, (u_int)0xa5a5a5a5, (u_int)0x38383838,
- (u_int)0xbfbfbfbf, (u_int)0x40404040, (u_int)0xa3a3a3a3, (u_int)0x9e9e9e9e,
- (u_int)0x81818181, (u_int)0xf3f3f3f3, (u_int)0xd7d7d7d7, (u_int)0xfbfbfbfb,
- (u_int)0x7c7c7c7c, (u_int)0xe3e3e3e3, (u_int)0x39393939, (u_int)0x82828282,
- (u_int)0x9b9b9b9b, (u_int)0x2f2f2f2f, (u_int)0xffffffff, (u_int)0x87878787,
- (u_int)0x34343434, (u_int)0x8e8e8e8e, (u_int)0x43434343, (u_int)0x44444444,
- (u_int)0xc4c4c4c4, (u_int)0xdededede, (u_int)0xe9e9e9e9, (u_int)0xcbcbcbcb,
- (u_int)0x54545454, (u_int)0x7b7b7b7b, (u_int)0x94949494, (u_int)0x32323232,
- (u_int)0xa6a6a6a6, (u_int)0xc2c2c2c2, (u_int)0x23232323, (u_int)0x3d3d3d3d,
- (u_int)0xeeeeeeee, (u_int)0x4c4c4c4c, (u_int)0x95959595, (u_int)0x0b0b0b0b,
- (u_int)0x42424242, (u_int)0xfafafafa, (u_int)0xc3c3c3c3, (u_int)0x4e4e4e4e,
- (u_int)0x08080808, (u_int)0x2e2e2e2e, (u_int)0xa1a1a1a1, (u_int)0x66666666,
- (u_int)0x28282828, (u_int)0xd9d9d9d9, (u_int)0x24242424, (u_int)0xb2b2b2b2,
- (u_int)0x76767676, (u_int)0x5b5b5b5b, (u_int)0xa2a2a2a2, (u_int)0x49494949,
- (u_int)0x6d6d6d6d, (u_int)0x8b8b8b8b, (u_int)0xd1d1d1d1, (u_int)0x25252525,
- (u_int)0x72727272, (u_int)0xf8f8f8f8, (u_int)0xf6f6f6f6, (u_int)0x64646464,
- (u_int)0x86868686, (u_int)0x68686868, (u_int)0x98989898, (u_int)0x16161616,
- (u_int)0xd4d4d4d4, (u_int)0xa4a4a4a4, (u_int)0x5c5c5c5c, (u_int)0xcccccccc,
- (u_int)0x5d5d5d5d, (u_int)0x65656565, (u_int)0xb6b6b6b6, (u_int)0x92929292,
- (u_int)0x6c6c6c6c, (u_int)0x70707070, (u_int)0x48484848, (u_int)0x50505050,
- (u_int)0xfdfdfdfd, (u_int)0xedededed, (u_int)0xb9b9b9b9, (u_int)0xdadadada,
- (u_int)0x5e5e5e5e, (u_int)0x15151515, (u_int)0x46464646, (u_int)0x57575757,
- (u_int)0xa7a7a7a7, (u_int)0x8d8d8d8d, (u_int)0x9d9d9d9d, (u_int)0x84848484,
- (u_int)0x90909090, (u_int)0xd8d8d8d8, (u_int)0xabababab, (u_int)0x00000000,
- (u_int)0x8c8c8c8c, (u_int)0xbcbcbcbc, (u_int)0xd3d3d3d3, (u_int)0x0a0a0a0a,
- (u_int)0xf7f7f7f7, (u_int)0xe4e4e4e4, (u_int)0x58585858, (u_int)0x05050505,
- (u_int)0xb8b8b8b8, (u_int)0xb3b3b3b3, (u_int)0x45454545, (u_int)0x06060606,
- (u_int)0xd0d0d0d0, (u_int)0x2c2c2c2c, (u_int)0x1e1e1e1e, (u_int)0x8f8f8f8f,
- (u_int)0xcacacaca, (u_int)0x3f3f3f3f, (u_int)0x0f0f0f0f, (u_int)0x02020202,
- (u_int)0xc1c1c1c1, (u_int)0xafafafaf, (u_int)0xbdbdbdbd, (u_int)0x03030303,
- (u_int)0x01010101, (u_int)0x13131313, (u_int)0x8a8a8a8a, (u_int)0x6b6b6b6b,
- (u_int)0x3a3a3a3a, (u_int)0x91919191, (u_int)0x11111111, (u_int)0x41414141,
- (u_int)0x4f4f4f4f, (u_int)0x67676767, (u_int)0xdcdcdcdc, (u_int)0xeaeaeaea,
- (u_int)0x97979797, (u_int)0xf2f2f2f2, (u_int)0xcfcfcfcf, (u_int)0xcececece,
- (u_int)0xf0f0f0f0, (u_int)0xb4b4b4b4, (u_int)0xe6e6e6e6, (u_int)0x73737373,
- (u_int)0x96969696, (u_int)0xacacacac, (u_int)0x74747474, (u_int)0x22222222,
- (u_int)0xe7e7e7e7, (u_int)0xadadadad, (u_int)0x35353535, (u_int)0x85858585,
- (u_int)0xe2e2e2e2, (u_int)0xf9f9f9f9, (u_int)0x37373737, (u_int)0xe8e8e8e8,
- (u_int)0x1c1c1c1c, (u_int)0x75757575, (u_int)0xdfdfdfdf, (u_int)0x6e6e6e6e,
- (u_int)0x47474747, (u_int)0xf1f1f1f1, (u_int)0x1a1a1a1a, (u_int)0x71717171,
- (u_int)0x1d1d1d1d, (u_int)0x29292929, (u_int)0xc5c5c5c5, (u_int)0x89898989,
- (u_int)0x6f6f6f6f, (u_int)0xb7b7b7b7, (u_int)0x62626262, (u_int)0x0e0e0e0e,
- (u_int)0xaaaaaaaa, (u_int)0x18181818, (u_int)0xbebebebe, (u_int)0x1b1b1b1b,
- (u_int)0xfcfcfcfc, (u_int)0x56565656, (u_int)0x3e3e3e3e, (u_int)0x4b4b4b4b,
- (u_int)0xc6c6c6c6, (u_int)0xd2d2d2d2, (u_int)0x79797979, (u_int)0x20202020,
- (u_int)0x9a9a9a9a, (u_int)0xdbdbdbdb, (u_int)0xc0c0c0c0, (u_int)0xfefefefe,
- (u_int)0x78787878, (u_int)0xcdcdcdcd, (u_int)0x5a5a5a5a, (u_int)0xf4f4f4f4,
- (u_int)0x1f1f1f1f, (u_int)0xdddddddd, (u_int)0xa8a8a8a8, (u_int)0x33333333,
- (u_int)0x88888888, (u_int)0x07070707, (u_int)0xc7c7c7c7, (u_int)0x31313131,
- (u_int)0xb1b1b1b1, (u_int)0x12121212, (u_int)0x10101010, (u_int)0x59595959,
- (u_int)0x27272727, (u_int)0x80808080, (u_int)0xecececec, (u_int)0x5f5f5f5f,
- (u_int)0x60606060, (u_int)0x51515151, (u_int)0x7f7f7f7f, (u_int)0xa9a9a9a9,
- (u_int)0x19191919, (u_int)0xb5b5b5b5, (u_int)0x4a4a4a4a, (u_int)0x0d0d0d0d,
- (u_int)0x2d2d2d2d, (u_int)0xe5e5e5e5, (u_int)0x7a7a7a7a, (u_int)0x9f9f9f9f,
- (u_int)0x93939393, (u_int)0xc9c9c9c9, (u_int)0x9c9c9c9c, (u_int)0xefefefef,
- (u_int)0xa0a0a0a0, (u_int)0xe0e0e0e0, (u_int)0x3b3b3b3b, (u_int)0x4d4d4d4d,
- (u_int)0xaeaeaeae, (u_int)0x2a2a2a2a, (u_int)0xf5f5f5f5, (u_int)0xb0b0b0b0,
- (u_int)0xc8c8c8c8, (u_int)0xebebebeb, (u_int)0xbbbbbbbb, (u_int)0x3c3c3c3c,
- (u_int)0x83838383, (u_int)0x53535353, (u_int)0x99999999, (u_int)0x61616161,
- (u_int)0x17171717, (u_int)0x2b2b2b2b, (u_int)0x04040404, (u_int)0x7e7e7e7e,
- (u_int)0xbabababa, (u_int)0x77777777, (u_int)0xd6d6d6d6, (u_int)0x26262626,
- (u_int)0xe1e1e1e1, (u_int)0x69696969, (u_int)0x14141414, (u_int)0x63636363,
- (u_int)0x55555555, (u_int)0x21212121, (u_int)0x0c0c0c0c, (u_int)0x7d7d7d7d,
-};
-static const u32 rcon[] = {
- 0x01000000, 0x02000000, 0x04000000, 0x08000000,
- 0x10000000, 0x20000000, 0x40000000, 0x80000000,
- 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-};
-
-#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
-
-#ifdef _MSC_VER
-#define GETU32(p) SWAP(*((u32 *)(p)))
-#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
-#else
-#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
-#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
-#endif
-
-/**
- * Expand the cipher key into the encryption key schedule.
- *
- * @return the number of rounds for the given cipher key size.
- */
-/*
- * __db_rijndaelKeySetupEnc --
- *
- * PUBLIC: int __db_rijndaelKeySetupEnc __P((u32 *, const u8 *, int));
- */
-int
-__db_rijndaelKeySetupEnc(rk, cipherKey, keyBits)
- u32 *rk; /* rk[4*(Nr + 1)] */
- const u8 *cipherKey;
- int keyBits;
-{
- int i = 0;
- u32 temp;
-
- rk[0] = GETU32(cipherKey );
- rk[1] = GETU32(cipherKey + 4);
- rk[2] = GETU32(cipherKey + 8);
- rk[3] = GETU32(cipherKey + 12);
- if (keyBits == 128) {
- for (;;) {
- temp = rk[3];
- rk[4] = rk[0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[5] = rk[1] ^ rk[4];
- rk[6] = rk[2] ^ rk[5];
- rk[7] = rk[3] ^ rk[6];
- if (++i == 10) {
- return 10;
- }
- rk += 4;
- }
- }
- rk[4] = GETU32(cipherKey + 16);
- rk[5] = GETU32(cipherKey + 20);
- if (keyBits == 192) {
- for (;;) {
- temp = rk[ 5];
- rk[ 6] = rk[ 0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[ 7] = rk[ 1] ^ rk[ 6];
- rk[ 8] = rk[ 2] ^ rk[ 7];
- rk[ 9] = rk[ 3] ^ rk[ 8];
- if (++i == 8) {
- return 12;
- }
- rk[10] = rk[ 4] ^ rk[ 9];
- rk[11] = rk[ 5] ^ rk[10];
- rk += 6;
- }
- }
- rk[6] = GETU32(cipherKey + 24);
- rk[7] = GETU32(cipherKey + 28);
- if (keyBits == 256) {
- for (;;) {
- temp = rk[ 7];
- rk[ 8] = rk[ 0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[ 9] = rk[ 1] ^ rk[ 8];
- rk[10] = rk[ 2] ^ rk[ 9];
- rk[11] = rk[ 3] ^ rk[10];
- if (++i == 7) {
- return 14;
- }
- temp = rk[11];
- rk[12] = rk[ 4] ^
- (Te4[(temp >> 24) ] & 0xff000000) ^
- (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(temp ) & 0xff] & 0x000000ff);
- rk[13] = rk[ 5] ^ rk[12];
- rk[14] = rk[ 6] ^ rk[13];
- rk[15] = rk[ 7] ^ rk[14];
-
- rk += 8;
- }
- }
- return 0;
-}
-
-/**
- * Expand the cipher key into the decryption key schedule.
- *
- * @return the number of rounds for the given cipher key size.
- */
-/*
- * __db_rijndaelKeySetupDec --
- *
- * PUBLIC: int __db_rijndaelKeySetupDec __P((u32 *, const u8 *, int));
- */
-int
-__db_rijndaelKeySetupDec(rk, cipherKey, keyBits)
- u32 *rk; /* rk[4*(Nr + 1)] */
- const u8 *cipherKey;
- int keyBits;
-{
- int Nr, i, j;
- u32 temp;
-
- /* expand the cipher key: */
- Nr = __db_rijndaelKeySetupEnc(rk, cipherKey, keyBits);
- /* invert the order of the round keys: */
- for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) {
- temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
- temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
- temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
- temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
- }
- /* apply the inverse MixColumn transform to all round keys but the first and the last: */
- for (i = 1; i < Nr; i++) {
- rk += 4;
- rk[0] =
- Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[0] ) & 0xff] & 0xff];
- rk[1] =
- Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[1] ) & 0xff] & 0xff];
- rk[2] =
- Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[2] ) & 0xff] & 0xff];
- rk[3] =
- Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[3] ) & 0xff] & 0xff];
- }
- return Nr;
-}
-
-/*
- * __db_rijndaelEncrypt --
- *
- * PUBLIC: void __db_rijndaelEncrypt __P((u32 *, int, const u8 *, u8 *));
- */
-void
-__db_rijndaelEncrypt(rk, Nr, pt, ct)
- u32 *rk; /* rk[4*(Nr + 1)] */
- int Nr;
- const u8 *pt;
- u8 *ct;
-{
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(pt ) ^ rk[0];
- s1 = GETU32(pt + 4) ^ rk[1];
- s2 = GETU32(pt + 8) ^ rk[2];
- s3 = GETU32(pt + 12) ^ rk[3];
-#ifdef FULL_UNROLL
- /* round 1: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
- /* round 2: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
- /* round 3: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
- /* round 4: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
- /* round 5: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
- /* round 6: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
- /* round 7: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
- /* round 8: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
- /* round 9: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
- if (Nr > 10) {
- /* round 10: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
- /* round 11: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
- if (Nr > 12) {
- /* round 12: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
- /* round 13: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
- }
- }
- rk += Nr << 2;
-#else /* !FULL_UNROLL */
- /*
- * Nr - 1 full rounds:
- */
- r = Nr >> 1;
- for (;;) {
- t0 =
- Te0[(s0 >> 24) ] ^
- Te1[(s1 >> 16) & 0xff] ^
- Te2[(s2 >> 8) & 0xff] ^
- Te3[(s3 ) & 0xff] ^
- rk[4];
- t1 =
- Te0[(s1 >> 24) ] ^
- Te1[(s2 >> 16) & 0xff] ^
- Te2[(s3 >> 8) & 0xff] ^
- Te3[(s0 ) & 0xff] ^
- rk[5];
- t2 =
- Te0[(s2 >> 24) ] ^
- Te1[(s3 >> 16) & 0xff] ^
- Te2[(s0 >> 8) & 0xff] ^
- Te3[(s1 ) & 0xff] ^
- rk[6];
- t3 =
- Te0[(s3 >> 24) ] ^
- Te1[(s0 >> 16) & 0xff] ^
- Te2[(s1 >> 8) & 0xff] ^
- Te3[(s2 ) & 0xff] ^
- rk[7];
-
- rk += 8;
- if (--r == 0) {
- break;
- }
-
- s0 =
- Te0[(t0 >> 24) ] ^
- Te1[(t1 >> 16) & 0xff] ^
- Te2[(t2 >> 8) & 0xff] ^
- Te3[(t3 ) & 0xff] ^
- rk[0];
- s1 =
- Te0[(t1 >> 24) ] ^
- Te1[(t2 >> 16) & 0xff] ^
- Te2[(t3 >> 8) & 0xff] ^
- Te3[(t0 ) & 0xff] ^
- rk[1];
- s2 =
- Te0[(t2 >> 24) ] ^
- Te1[(t3 >> 16) & 0xff] ^
- Te2[(t0 >> 8) & 0xff] ^
- Te3[(t1 ) & 0xff] ^
- rk[2];
- s3 =
- Te0[(t3 >> 24) ] ^
- Te1[(t0 >> 16) & 0xff] ^
- Te2[(t1 >> 8) & 0xff] ^
- Te3[(t2 ) & 0xff] ^
- rk[3];
- }
-#endif /* ?FULL_UNROLL */
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 =
- (Te4[(t0 >> 24) ] & 0xff000000) ^
- (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t3 ) & 0xff] & 0x000000ff) ^
- rk[0];
- PUTU32(ct , s0);
- s1 =
- (Te4[(t1 >> 24) ] & 0xff000000) ^
- (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t0 ) & 0xff] & 0x000000ff) ^
- rk[1];
- PUTU32(ct + 4, s1);
- s2 =
- (Te4[(t2 >> 24) ] & 0xff000000) ^
- (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t1 ) & 0xff] & 0x000000ff) ^
- rk[2];
- PUTU32(ct + 8, s2);
- s3 =
- (Te4[(t3 >> 24) ] & 0xff000000) ^
- (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t2 ) & 0xff] & 0x000000ff) ^
- rk[3];
- PUTU32(ct + 12, s3);
-}
-
-/*
- * __db_rijndaelDecrypt --
- *
- * PUBLIC: void __db_rijndaelDecrypt __P((u32 *, int, const u8 *, u8 *));
- */
-void
-__db_rijndaelDecrypt(rk, Nr, ct, pt)
- u32 *rk; /* rk[4*(Nr + 1)] */
- int Nr;
- const u8 *ct;
- u8 *pt;
-{
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(ct ) ^ rk[0];
- s1 = GETU32(ct + 4) ^ rk[1];
- s2 = GETU32(ct + 8) ^ rk[2];
- s3 = GETU32(ct + 12) ^ rk[3];
-#ifdef FULL_UNROLL
- /* round 1: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
- /* round 2: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
- /* round 3: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
- /* round 4: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
- /* round 5: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
- /* round 6: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
- /* round 7: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
- /* round 8: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
- /* round 9: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
- if (Nr > 10) {
- /* round 10: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
- /* round 11: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
- if (Nr > 12) {
- /* round 12: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
- /* round 13: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
- }
- }
- rk += Nr << 2;
-#else /* !FULL_UNROLL */
- /*
- * Nr - 1 full rounds:
- */
- r = Nr >> 1;
- for (;;) {
- t0 =
- Td0[(s0 >> 24) ] ^
- Td1[(s3 >> 16) & 0xff] ^
- Td2[(s2 >> 8) & 0xff] ^
- Td3[(s1 ) & 0xff] ^
- rk[4];
- t1 =
- Td0[(s1 >> 24) ] ^
- Td1[(s0 >> 16) & 0xff] ^
- Td2[(s3 >> 8) & 0xff] ^
- Td3[(s2 ) & 0xff] ^
- rk[5];
- t2 =
- Td0[(s2 >> 24) ] ^
- Td1[(s1 >> 16) & 0xff] ^
- Td2[(s0 >> 8) & 0xff] ^
- Td3[(s3 ) & 0xff] ^
- rk[6];
- t3 =
- Td0[(s3 >> 24) ] ^
- Td1[(s2 >> 16) & 0xff] ^
- Td2[(s1 >> 8) & 0xff] ^
- Td3[(s0 ) & 0xff] ^
- rk[7];
-
- rk += 8;
- if (--r == 0) {
- break;
- }
-
- s0 =
- Td0[(t0 >> 24) ] ^
- Td1[(t3 >> 16) & 0xff] ^
- Td2[(t2 >> 8) & 0xff] ^
- Td3[(t1 ) & 0xff] ^
- rk[0];
- s1 =
- Td0[(t1 >> 24) ] ^
- Td1[(t0 >> 16) & 0xff] ^
- Td2[(t3 >> 8) & 0xff] ^
- Td3[(t2 ) & 0xff] ^
- rk[1];
- s2 =
- Td0[(t2 >> 24) ] ^
- Td1[(t1 >> 16) & 0xff] ^
- Td2[(t0 >> 8) & 0xff] ^
- Td3[(t3 ) & 0xff] ^
- rk[2];
- s3 =
- Td0[(t3 >> 24) ] ^
- Td1[(t2 >> 16) & 0xff] ^
- Td2[(t1 >> 8) & 0xff] ^
- Td3[(t0 ) & 0xff] ^
- rk[3];
- }
-#endif /* ?FULL_UNROLL */
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 =
- (Td4[(t0 >> 24) ] & 0xff000000) ^
- (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t1 ) & 0xff] & 0x000000ff) ^
- rk[0];
- PUTU32(pt , s0);
- s1 =
- (Td4[(t1 >> 24) ] & 0xff000000) ^
- (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t2 ) & 0xff] & 0x000000ff) ^
- rk[1];
- PUTU32(pt + 4, s1);
- s2 =
- (Td4[(t2 >> 24) ] & 0xff000000) ^
- (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t3 ) & 0xff] & 0x000000ff) ^
- rk[2];
- PUTU32(pt + 8, s2);
- s3 =
- (Td4[(t3 >> 24) ] & 0xff000000) ^
- (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t0 ) & 0xff] & 0x000000ff) ^
- rk[3];
- PUTU32(pt + 12, s3);
-}
-
-#ifdef INTERMEDIATE_VALUE_KAT
-
-/*
- * __db_rijndaelEncryptRound --
- *
- * PUBLIC: void __db_rijndaelEncryptRound __P((const u32 *, int, u8 *, int));
- */
-void
-__db_rijndaelEncryptRound(rk, Nr, pt, ct)
- const u32 *rk; /* rk[4*(Nr + 1)] */
- int Nr;
- u8 *block;
- int rounds;
-{
- int r;
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(block ) ^ rk[0];
- s1 = GETU32(block + 4) ^ rk[1];
- s2 = GETU32(block + 8) ^ rk[2];
- s3 = GETU32(block + 12) ^ rk[3];
- rk += 4;
-
- /*
- * Nr - 1 full rounds:
- */
- for (r = (rounds < Nr ? rounds : Nr - 1); r > 0; r--) {
- t0 =
- Te0[(s0 >> 24) ] ^
- Te1[(s1 >> 16) & 0xff] ^
- Te2[(s2 >> 8) & 0xff] ^
- Te3[(s3 ) & 0xff] ^
- rk[0];
- t1 =
- Te0[(s1 >> 24) ] ^
- Te1[(s2 >> 16) & 0xff] ^
- Te2[(s3 >> 8) & 0xff] ^
- Te3[(s0 ) & 0xff] ^
- rk[1];
- t2 =
- Te0[(s2 >> 24) ] ^
- Te1[(s3 >> 16) & 0xff] ^
- Te2[(s0 >> 8) & 0xff] ^
- Te3[(s1 ) & 0xff] ^
- rk[2];
- t3 =
- Te0[(s3 >> 24) ] ^
- Te1[(s0 >> 16) & 0xff] ^
- Te2[(s1 >> 8) & 0xff] ^
- Te3[(s2 ) & 0xff] ^
- rk[3];
-
- s0 = t0;
- s1 = t1;
- s2 = t2;
- s3 = t3;
- rk += 4;
-
- }
-
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- if (rounds == Nr) {
- t0 =
- (Te4[(s0 >> 24) ] & 0xff000000) ^
- (Te4[(s1 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(s2 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(s3 ) & 0xff] & 0x000000ff) ^
- rk[0];
- t1 =
- (Te4[(s1 >> 24) ] & 0xff000000) ^
- (Te4[(s2 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(s3 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(s0 ) & 0xff] & 0x000000ff) ^
- rk[1];
- t2 =
- (Te4[(s2 >> 24) ] & 0xff000000) ^
- (Te4[(s3 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(s0 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(s1 ) & 0xff] & 0x000000ff) ^
- rk[2];
- t3 =
- (Te4[(s3 >> 24) ] & 0xff000000) ^
- (Te4[(s0 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(s1 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(s2 ) & 0xff] & 0x000000ff) ^
- rk[3];
-
- s0 = t0;
- s1 = t1;
- s2 = t2;
- s3 = t3;
- }
-
- PUTU32(block , s0);
- PUTU32(block + 4, s1);
- PUTU32(block + 8, s2);
- PUTU32(block + 12, s3);
-}
-
-/*
- * __db_rijndaelDecryptRound --
- *
- * PUBLIC: void __db_rijndaelDecryptRound __P((const u32 *, int, u8 *, int));
- */
-void
-__db_rijndaelDecryptRound(rk, Nr, pt, ct)
- const u32 *rk; /* rk[4*(Nr + 1)] */
- int Nr;
- u8 *block;
- int rounds;
-{
- int r;
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(block ) ^ rk[0];
- s1 = GETU32(block + 4) ^ rk[1];
- s2 = GETU32(block + 8) ^ rk[2];
- s3 = GETU32(block + 12) ^ rk[3];
- rk += 4;
-
- /*
- * Nr - 1 full rounds:
- */
- for (r = (rounds < Nr ? rounds : Nr) - 1; r > 0; r--) {
- t0 =
- Td0[(s0 >> 24) ] ^
- Td1[(s3 >> 16) & 0xff] ^
- Td2[(s2 >> 8) & 0xff] ^
- Td3[(s1 ) & 0xff] ^
- rk[0];
- t1 =
- Td0[(s1 >> 24) ] ^
- Td1[(s0 >> 16) & 0xff] ^
- Td2[(s3 >> 8) & 0xff] ^
- Td3[(s2 ) & 0xff] ^
- rk[1];
- t2 =
- Td0[(s2 >> 24) ] ^
- Td1[(s1 >> 16) & 0xff] ^
- Td2[(s0 >> 8) & 0xff] ^
- Td3[(s3 ) & 0xff] ^
- rk[2];
- t3 =
- Td0[(s3 >> 24) ] ^
- Td1[(s2 >> 16) & 0xff] ^
- Td2[(s1 >> 8) & 0xff] ^
- Td3[(s0 ) & 0xff] ^
- rk[3];
-
- s0 = t0;
- s1 = t1;
- s2 = t2;
- s3 = t3;
- rk += 4;
-
- }
-
- /*
- * complete the last round and
- * map cipher state to byte array block:
- */
- t0 =
- (Td4[(s0 >> 24) ] & 0xff000000) ^
- (Td4[(s3 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(s2 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(s1 ) & 0xff] & 0x000000ff);
- t1 =
- (Td4[(s1 >> 24) ] & 0xff000000) ^
- (Td4[(s0 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(s3 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(s2 ) & 0xff] & 0x000000ff);
- t2 =
- (Td4[(s2 >> 24) ] & 0xff000000) ^
- (Td4[(s1 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(s0 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(s3 ) & 0xff] & 0x000000ff);
- t3 =
- (Td4[(s3 >> 24) ] & 0xff000000) ^
- (Td4[(s2 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(s1 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(s0 ) & 0xff] & 0x000000ff);
-
- if (rounds == Nr) {
- t0 ^= rk[0];
- t1 ^= rk[1];
- t2 ^= rk[2];
- t3 ^= rk[3];
- }
-
- PUTU32(block , t0);
- PUTU32(block + 4, t1);
- PUTU32(block + 8, t2);
- PUTU32(block + 12, t3);
-}
-
-#endif /* INTERMEDIATE_VALUE_KAT */
diff --git a/storage/bdb/crypto/rijndael/rijndael-alg-fst.h b/storage/bdb/crypto/rijndael/rijndael-alg-fst.h
deleted file mode 100644
index 60c01212764..00000000000
--- a/storage/bdb/crypto/rijndael/rijndael-alg-fst.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * $Id: rijndael-alg-fst.h,v 12.0 2004/11/17 03:43:17 bostic Exp $
- */
-/**
- * rijndael-alg-fst.h
- *
- * @version 3.0 (December 2000)
- *
- * Optimised ANSI C code for the Rijndael cipher (now AES)
- *
- * @author Vincent Rijmen
- * @author Antoon Bosselaers
- * @author Paulo Barreto
- *
- * This code is hereby placed in the public domain.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __RIJNDAEL_ALG_FST_H
-#define __RIJNDAEL_ALG_FST_H
-
-#define MAXKC (256/32)
-#define MAXKB (256/8)
-#define MAXNR 14
-
-typedef u_int8_t u8;
-typedef u_int16_t u16;
-typedef u_int32_t u32;
-
-#endif /* __RIJNDAEL_ALG_FST_H */
diff --git a/storage/bdb/crypto/rijndael/rijndael-api-fst.c b/storage/bdb/crypto/rijndael/rijndael-api-fst.c
deleted file mode 100644
index 09475370f6b..00000000000
--- a/storage/bdb/crypto/rijndael/rijndael-api-fst.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/**
- * rijndael-api-fst.c
- *
- * @version 2.9 (December 2000)
- *
- * Optimised ANSI C code for the Rijndael cipher (now AES)
- *
- * @author Vincent Rijmen
- * @author Antoon Bosselaers
- * @author Paulo Barreto
- *
- * This code is hereby placed in the public domain.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Acknowledgements:
- *
- * We are deeply indebted to the following people for their bug reports,
- * fixes, and improvement suggestions to this implementation. Though we
- * tried to list all contributions, we apologise in advance for any
- * missing reference.
- *
- * Andrew Bales
- * Markus Friedl
- * John Skodon
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/crypto.h"
-
-#include "crypto/rijndael/rijndael-alg-fst.h"
-#include "crypto/rijndael/rijndael-api-fst.h"
-
-/*
- * __db_makeKey --
- *
- * PUBLIC: int __db_makeKey __P((keyInstance *, int, int, char *));
- */
-int
-__db_makeKey(key, direction, keyLen, keyMaterial)
- keyInstance *key;
- int direction;
- int keyLen;
- char *keyMaterial;
-{
- u8 cipherKey[MAXKB];
-
- if (key == NULL) {
- return BAD_KEY_INSTANCE;
- }
-
- if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
- key->direction = direction;
- } else {
- return BAD_KEY_DIR;
- }
-
- if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
- key->keyLen = keyLen;
- } else {
- return BAD_KEY_MAT;
- }
-
- if (keyMaterial != NULL) {
- memcpy(cipherKey, keyMaterial, key->keyLen/8);
- }
-
- if (direction == DIR_ENCRYPT) {
- key->Nr = __db_rijndaelKeySetupEnc(key->rk, cipherKey, keyLen);
- } else {
- key->Nr = __db_rijndaelKeySetupDec(key->rk, cipherKey, keyLen);
- }
- __db_rijndaelKeySetupEnc(key->ek, cipherKey, keyLen);
- return TRUE;
-}
-
-/*
- * __db_cipherInit --
- *
- * PUBLIC: int __db_cipherInit __P((cipherInstance *, int, char *));
- */
-int
-__db_cipherInit(cipher, mode, IV)
- cipherInstance *cipher;
- int mode;
- char *IV;
-{
- if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
- cipher->mode = mode;
- } else {
- return BAD_CIPHER_MODE;
- }
- if (IV != NULL) {
- memcpy(cipher->IV, IV, MAX_IV_SIZE);
- }
- return TRUE;
-}
-
-/*
- * __db_blockEncrypt --
- *
- * PUBLIC: int __db_blockEncrypt __P((cipherInstance *, keyInstance *, u_int8_t *,
- * PUBLIC: size_t, u_int8_t *));
- */
-int
-__db_blockEncrypt(cipher, key, input, inputLen, outBuffer)
- cipherInstance *cipher;
- keyInstance *key;
- u_int8_t *input;
- size_t inputLen;
- u_int8_t *outBuffer;
-{
- int i, k, t, numBlocks;
- u8 block[16], *iv;
- u32 tmpiv[4];
-
- if (cipher == NULL ||
- key == NULL ||
- key->direction == DIR_DECRYPT) {
- return BAD_CIPHER_STATE;
- }
- if (input == NULL || inputLen <= 0) {
- return 0; /* nothing to do */
- }
-
- numBlocks = (int)(inputLen/128);
-
- switch (cipher->mode) {
- case MODE_ECB:
- for (i = numBlocks; i > 0; i--) {
- __db_rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
- input += 16;
- outBuffer += 16;
- }
- break;
-
- case MODE_CBC:
- iv = cipher->IV;
- for (i = numBlocks; i > 0; i--) {
- memcpy(tmpiv, iv, MAX_IV_SIZE);
- ((u32*)block)[0] = ((u32*)input)[0] ^ tmpiv[0];
- ((u32*)block)[1] = ((u32*)input)[1] ^ tmpiv[1];
- ((u32*)block)[2] = ((u32*)input)[2] ^ tmpiv[2];
- ((u32*)block)[3] = ((u32*)input)[3] ^ tmpiv[3];
- __db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
- iv = outBuffer;
- input += 16;
- outBuffer += 16;
- }
- break;
-
- case MODE_CFB1:
- iv = cipher->IV;
- for (i = numBlocks; i > 0; i--) {
- memcpy(outBuffer, input, 16);
- for (k = 0; k < 128; k++) {
- __db_rijndaelEncrypt(key->ek, key->Nr, iv, block);
- outBuffer[k >> 3] ^= (block[0] & (u_int)0x80) >> (k & 7);
- for (t = 0; t < 15; t++) {
- iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
- }
- iv[15] = (iv[15] << 1) | ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
- }
- outBuffer += 16;
- input += 16;
- }
- break;
-
- default:
- return BAD_CIPHER_STATE;
- }
-
- return 128*numBlocks;
-}
-
-/**
- * Encrypt data partitioned in octets, using RFC 2040-like padding.
- *
- * @param input data to be encrypted (octet sequence)
- * @param inputOctets input length in octets (not bits)
- * @param outBuffer encrypted output data
- *
- * @return length in octets (not bits) of the encrypted output buffer.
- */
-/*
- * __db_padEncrypt --
- *
- * PUBLIC: int __db_padEncrypt __P((cipherInstance *, keyInstance *, u_int8_t *,
- * PUBLIC: int, u_int8_t *));
- */
-int
-__db_padEncrypt(cipher, key, input, inputOctets, outBuffer)
- cipherInstance *cipher;
- keyInstance *key;
- u_int8_t *input;
- int inputOctets;
- u_int8_t *outBuffer;
-{
- int i, numBlocks, padLen;
- u8 block[16], *iv;
- u32 tmpiv[4];
-
- if (cipher == NULL ||
- key == NULL ||
- key->direction == DIR_DECRYPT) {
- return BAD_CIPHER_STATE;
- }
- if (input == NULL || inputOctets <= 0) {
- return 0; /* nothing to do */
- }
-
- numBlocks = inputOctets/16;
-
- switch (cipher->mode) {
- case MODE_ECB:
- for (i = numBlocks; i > 0; i--) {
- __db_rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
- input += 16;
- outBuffer += 16;
- }
- padLen = 16 - (inputOctets - 16*numBlocks);
- DB_ASSERT(padLen > 0 && padLen <= 16);
- memcpy(block, input, 16 - padLen);
- memset(block + 16 - padLen, padLen, padLen);
- __db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
- break;
-
- case MODE_CBC:
- iv = cipher->IV;
- for (i = numBlocks; i > 0; i--) {
- memcpy(tmpiv, iv, MAX_IV_SIZE);
- ((u32*)block)[0] = ((u32*)input)[0] ^ tmpiv[0];
- ((u32*)block)[1] = ((u32*)input)[1] ^ tmpiv[1];
- ((u32*)block)[2] = ((u32*)input)[2] ^ tmpiv[2];
- ((u32*)block)[3] = ((u32*)input)[3] ^ tmpiv[3];
- __db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
- iv = outBuffer;
- input += 16;
- outBuffer += 16;
- }
- padLen = 16 - (inputOctets - 16*numBlocks);
- DB_ASSERT(padLen > 0 && padLen <= 16);
- for (i = 0; i < 16 - padLen; i++) {
- block[i] = input[i] ^ iv[i];
- }
- for (i = 16 - padLen; i < 16; i++) {
- block[i] = (u_int8_t)padLen ^ iv[i];
- }
- __db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
- break;
-
- default:
- return BAD_CIPHER_STATE;
- }
-
- return 16*(numBlocks + 1);
-}
-
-/*
- * __db_blockDecrypt --
- *
- * PUBLIC: int __db_blockDecrypt __P((cipherInstance *, keyInstance *, u_int8_t *,
- * PUBLIC: size_t, u_int8_t *));
- */
-int
-__db_blockDecrypt(cipher, key, input, inputLen, outBuffer)
- cipherInstance *cipher;
- keyInstance *key;
- u_int8_t *input;
- size_t inputLen;
- u_int8_t *outBuffer;
-{
- int i, k, t, numBlocks;
- u8 block[16], *iv;
- u32 tmpiv[4];
-
- if (cipher == NULL ||
- key == NULL ||
- (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
- return BAD_CIPHER_STATE;
- }
- if (input == NULL || inputLen <= 0) {
- return 0; /* nothing to do */
- }
-
- numBlocks = (int)(inputLen/128);
-
- switch (cipher->mode) {
- case MODE_ECB:
- for (i = numBlocks; i > 0; i--) {
- __db_rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
- input += 16;
- outBuffer += 16;
- }
- break;
-
- case MODE_CBC:
- memcpy(tmpiv, cipher->IV, MAX_IV_SIZE);
- for (i = numBlocks; i > 0; i--) {
- __db_rijndaelDecrypt(key->rk, key->Nr, input, block);
- ((u32*)block)[0] ^= tmpiv[0];
- ((u32*)block)[1] ^= tmpiv[1];
- ((u32*)block)[2] ^= tmpiv[2];
- ((u32*)block)[3] ^= tmpiv[3];
- memcpy(tmpiv, input, 16);
- memcpy(outBuffer, block, 16);
- input += 16;
- outBuffer += 16;
- }
- break;
-
- case MODE_CFB1:
- iv = cipher->IV;
- for (i = numBlocks; i > 0; i--) {
- memcpy(outBuffer, input, 16);
- for (k = 0; k < 128; k++) {
- __db_rijndaelEncrypt(key->ek, key->Nr, iv, block);
- for (t = 0; t < 15; t++) {
- iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
- }
- iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
- outBuffer[k >> 3] ^= (block[0] & (u_int)0x80) >> (k & 7);
- }
- outBuffer += 16;
- input += 16;
- }
- break;
-
- default:
- return BAD_CIPHER_STATE;
- }
-
- return 128*numBlocks;
-}
-
-/*
- * __db_padDecrypt --
- *
- * PUBLIC: int __db_padDecrypt __P((cipherInstance *, keyInstance *, u_int8_t *,
- * PUBLIC: int, u_int8_t *));
- */
-int
-__db_padDecrypt(cipher, key, input, inputOctets, outBuffer)
- cipherInstance *cipher;
- keyInstance *key;
- u_int8_t *input;
- int inputOctets;
- u_int8_t *outBuffer;
-{
- int i, numBlocks, padLen;
- u8 block[16];
- u32 tmpiv[4];
-
- if (cipher == NULL ||
- key == NULL ||
- key->direction == DIR_ENCRYPT) {
- return BAD_CIPHER_STATE;
- }
- if (input == NULL || inputOctets <= 0) {
- return 0; /* nothing to do */
- }
- if (inputOctets % 16 != 0) {
- return BAD_DATA;
- }
-
- numBlocks = inputOctets/16;
-
- switch (cipher->mode) {
- case MODE_ECB:
- /* all blocks but last */
- for (i = numBlocks - 1; i > 0; i--) {
- __db_rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
- input += 16;
- outBuffer += 16;
- }
- /* last block */
- __db_rijndaelDecrypt(key->rk, key->Nr, input, block);
- padLen = block[15];
- if (padLen >= 16) {
- return BAD_DATA;
- }
- for (i = 16 - padLen; i < 16; i++) {
- if (block[i] != padLen) {
- return BAD_DATA;
- }
- }
- memcpy(outBuffer, block, 16 - padLen);
- break;
-
- case MODE_CBC:
- /* all blocks but last */
- memcpy(tmpiv, cipher->IV, MAX_IV_SIZE);
- for (i = numBlocks - 1; i > 0; i--) {
- __db_rijndaelDecrypt(key->rk, key->Nr, input, block);
- ((u32*)block)[0] ^= tmpiv[0];
- ((u32*)block)[1] ^= tmpiv[1];
- ((u32*)block)[2] ^= tmpiv[2];
- ((u32*)block)[3] ^= tmpiv[3];
- memcpy(tmpiv, input, 16);
- memcpy(outBuffer, block, 16);
- input += 16;
- outBuffer += 16;
- }
- /* last block */
- __db_rijndaelDecrypt(key->rk, key->Nr, input, block);
- ((u32*)block)[0] ^= tmpiv[0];
- ((u32*)block)[1] ^= tmpiv[1];
- ((u32*)block)[2] ^= tmpiv[2];
- ((u32*)block)[3] ^= tmpiv[3];
- padLen = block[15];
- if (padLen <= 0 || padLen > 16) {
- return BAD_DATA;
- }
- for (i = 16 - padLen; i < 16; i++) {
- if (block[i] != padLen) {
- return BAD_DATA;
- }
- }
- memcpy(outBuffer, block, 16 - padLen);
- break;
-
- default:
- return BAD_CIPHER_STATE;
- }
-
- return 16*numBlocks - padLen;
-}
-
-#ifdef INTERMEDIATE_VALUE_KAT
-/**
- * cipherUpdateRounds:
- *
- * Encrypts/Decrypts exactly one full block a specified number of rounds.
- * Only used in the Intermediate Value Known Answer Test.
- *
- * Returns:
- * TRUE - on success
- * BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized)
- */
-/*
- * __db_cipherUpdateRounds --
- *
- * PUBLIC: int __db_cipherUpdateRounds __P((cipherInstance *, keyInstance *,
- * PUBLIC: u_int8_t *, int, u_int8_t *, int));
- */
-int
-__db_cipherUpdateRounds(cipher, key, input, inputLen, outBuffer, rounds)
- cipherInstance *cipher;
- keyInstance *key;
- u_int8_t *input;
- size_t inputLen;
- u_int8_t *outBuffer;
- int rounds;
-{
- u8 block[16];
-
- if (cipher == NULL || key == NULL) {
- return BAD_CIPHER_STATE;
- }
-
- memcpy(block, input, 16);
-
- switch (key->direction) {
- case DIR_ENCRYPT:
- __db_rijndaelEncryptRound(key->rk, key->Nr, block, rounds);
- break;
-
- case DIR_DECRYPT:
- __db_rijndaelDecryptRound(key->rk, key->Nr, block, rounds);
- break;
-
- default:
- return BAD_KEY_DIR;
- }
-
- memcpy(outBuffer, block, 16);
-
- return TRUE;
-}
-#endif /* INTERMEDIATE_VALUE_KAT */
diff --git a/storage/bdb/crypto/rijndael/rijndael-api-fst.h b/storage/bdb/crypto/rijndael/rijndael-api-fst.h
deleted file mode 100644
index caf0abc4aa7..00000000000
--- a/storage/bdb/crypto/rijndael/rijndael-api-fst.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * $Id: rijndael-api-fst.h,v 12.0 2004/11/17 03:43:17 bostic Exp $
- */
-/**
- * rijndael-api-fst.h
- *
- * @version 2.9 (December 2000)
- *
- * Optimised ANSI C code for the Rijndael cipher (now AES)
- *
- * @author Vincent Rijmen
- * @author Antoon Bosselaers
- * @author Paulo Barreto
- *
- * This code is hereby placed in the public domain.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Acknowledgements:
- *
- * We are deeply indebted to the following people for their bug reports,
- * fixes, and improvement suggestions to this implementation. Though we
- * tried to list all contributions, we apologise in advance for any
- * missing reference.
- *
- * Andrew Bales
- * Markus Friedl
- * John Skodon
- */
-
-#ifndef __RIJNDAEL_API_FST_H
-#define __RIJNDAEL_API_FST_H
-
-#include "crypto/rijndael/rijndael-alg-fst.h"
-
-/* Generic Defines */
-#define DIR_ENCRYPT 0 /* Are we encrpyting? */
-#define DIR_DECRYPT 1 /* Are we decrpyting? */
-#define MODE_ECB 1 /* Are we ciphering in ECB mode? */
-#define MODE_CBC 2 /* Are we ciphering in CBC mode? */
-#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
-#undef TRUE
-#define TRUE 1
-#undef FALSE
-#define FALSE 0
-#define BITSPERBLOCK 128 /* Default number of bits in a cipher block */
-
-/* Error Codes */
-#define BAD_KEY_DIR -1 /* Key direction is invalid, e.g., unknown value */
-#define BAD_KEY_MAT -2 /* Key material not of correct length */
-#define BAD_KEY_INSTANCE -3 /* Key passed is not valid */
-#define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */
-#define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */
-#define BAD_BLOCK_LENGTH -6
-#define BAD_CIPHER_INSTANCE -7
-#define BAD_DATA -8 /* Data contents are invalid, e.g., invalid padding */
-#define BAD_OTHER -9 /* Unknown error */
-
-/* Algorithm-specific Defines */
-#define MAX_KEY_SIZE 64 /* # of ASCII char's needed to represent a key */
-#define MAX_IV_SIZE 16 /* # bytes needed to represent an IV */
-
-/* Typedefs */
-
-/* The structure for key information */
-typedef struct {
- u_int8_t direction; /* Key used for encrypting or decrypting? */
- int keyLen; /* Length of the key */
- char keyMaterial[MAX_KEY_SIZE+1]; /* Raw key data in ASCII, e.g., user input or KAT values */
- int Nr; /* key-length-dependent number of rounds */
- u32 rk[4*(MAXNR + 1)]; /* key schedule */
- u32 ek[4*(MAXNR + 1)]; /* CFB1 key schedule (encryption only) */
-} keyInstance;
-
-/* The structure for cipher information */
-typedef struct { /* changed order of the components */
- u_int8_t mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */
- u_int8_t IV[MAX_IV_SIZE]; /* A possible Initialization Vector for ciphering */
-} cipherInstance;
-
-#endif /* __RIJNDAEL_API_FST_H */
diff --git a/storage/bdb/cxx/cxx_db.cpp b/storage/bdb/cxx/cxx_db.cpp
deleted file mode 100644
index 03e07f4d238..00000000000
--- a/storage/bdb/cxx/cxx_db.cpp
+++ /dev/null
@@ -1,657 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: cxx_db.cpp,v 12.4 2005/10/18 14:25:53 mjc Exp $
- */
-
-#include "db_config.h"
-
-#include
-#include
-
-#include "db_cxx.h"
-#include "dbinc/cxx_int.h"
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc_auto/db_auto.h"
-#include "dbinc_auto/crdel_auto.h"
-#include "dbinc/db_dispatch.h"
-#include "dbinc_auto/db_ext.h"
-#include "dbinc_auto/common_ext.h"
-
-// Helper macros for simple methods that pass through to the
-// underlying C method. It may return an error or raise an exception.
-// Note this macro expects that input _argspec is an argument
-// list element (e.g., "char *arg") and that _arglist is the arguments
-// that should be passed through to the C method (e.g., "(db, arg)")
-//
-#define DB_METHOD(_name, _argspec, _arglist, _retok) \
-int Db::_name _argspec \
-{ \
- int ret; \
- DB *db = unwrap(this); \
- \
- ret = db->_name _arglist; \
- if (!_retok(ret)) \
- DB_ERROR(env_, "Db::" # _name, ret, error_policy()); \
- return (ret); \
-}
-
-#define DB_DESTRUCTOR(_name, _argspec, _arglist, _retok) \
-int Db::_name _argspec \
-{ \
- int ret; \
- DB *db = unwrap(this); \
- \
- if (!db) { \
- DB_ERROR(env_, "Db::" # _name, EINVAL, error_policy()); \
- return (EINVAL); \
- } \
- cleanup(); \
- ret = db->_name _arglist; \
- if (!_retok(ret)) \
- DB_ERROR(env_, "Db::" # _name, ret, error_policy()); \
- return (ret); \
-}
-
-#define DB_METHOD_QUIET(_name, _argspec, _arglist) \
-int Db::_name _argspec \
-{ \
- DB *db = unwrap(this); \
- \
- return (db->_name _arglist); \
-}
-
-#define DB_METHOD_VOID(_name, _argspec, _arglist) \
-void Db::_name _argspec \
-{ \
- DB *db = unwrap(this); \
- \
- db->_name _arglist; \
-}
-
-// A truism for the Db object is that there is a valid
-// DB handle from the constructor until close().
-// After the close, the DB handle is invalid and
-// no operations are permitted on the Db (other than
-// destructor). Leaving the Db handle open and not
-// doing a close is generally considered an error.
-//
-// We used to allow Db objects to be closed and reopened.
-// This implied always keeping a valid DB object, and
-// coordinating the open objects between Db/DbEnv turned
-// out to be overly complicated. Now we do not allow this.
-
-Db::Db(DbEnv *env, u_int32_t flags)
-: imp_(0)
-, env_(env)
-, mpf_(0)
-, construct_error_(0)
-, flags_(0)
-, construct_flags_(flags)
-, append_recno_callback_(0)
-, associate_callback_(0)
-, bt_compare_callback_(0)
-, bt_prefix_callback_(0)
-, dup_compare_callback_(0)
-, feedback_callback_(0)
-, h_hash_callback_(0)
-{
- if (env_ == 0)
- flags_ |= DB_CXX_PRIVATE_ENV;
-
- if ((construct_error_ = initialize()) != 0)
- DB_ERROR(env_, "Db::Db", construct_error_, error_policy());
-}
-
-// If the DB handle is still open, we close it. This is to make stack
-// allocation of Db objects easier so that they are cleaned up in the error
-// path. If the environment was closed prior to this, it may cause a trap, but
-// an error message is generated during the environment close. Applications
-// should call close explicitly in normal (non-exceptional) cases to check the
-// return value.
-//
-Db::~Db()
-{
- DB *db;
-
- db = unwrap(this);
- if (db != NULL) {
- cleanup();
- (void)db->close(db, 0);
- }
-}
-
-// private method to initialize during constructor.
-// initialize must create a backing DB object,
-// and if that creates a new DB_ENV, it must be tied to a new DbEnv.
-//
-int Db::initialize()
-{
- DB *db;
- DB_ENV *cenv = unwrap(env_);
- int ret;
- u_int32_t cxx_flags;
-
- cxx_flags = construct_flags_ & DB_CXX_NO_EXCEPTIONS;
-
- // Create a new underlying DB object.
- // We rely on the fact that if a NULL DB_ENV* is given,
- // one is allocated by DB.
- //
- if ((ret = db_create(&db, cenv,
- construct_flags_ & ~cxx_flags)) != 0)
- return (ret);
-
- // Associate the DB with this object
- imp_ = db;
- db->api_internal = this;
-
- // Create a new DbEnv from a DB_ENV* if it was created locally.
- // It is deleted in Db::close().
- //
- if ((flags_ & DB_CXX_PRIVATE_ENV) != 0)
- env_ = new DbEnv(db->dbenv, cxx_flags);
-
- // Create a DbMpoolFile from the DB_MPOOLFILE* in the DB handle.
- mpf_ = new DbMpoolFile();
- mpf_->imp_ = db->mpf;
-
- return (0);
-}
-
-// private method to cleanup after destructor or during close.
-// If the environment was created by this Db object, we optionally
-// delete it, or return it so the caller can delete it after
-// last use.
-//
-void Db::cleanup()
-{
- DB *db = unwrap(this);
-
- if (db != NULL) {
- // extra safety
- imp_ = 0;
-
- // we must dispose of the DbEnv object if
- // we created it. This will be the case
- // if a NULL DbEnv was passed into the constructor.
- // The underlying DB_ENV object will be inaccessible
- // after the close, so we must clean it up now.
- //
- if ((flags_ & DB_CXX_PRIVATE_ENV) != 0) {
- env_->cleanup();
- delete env_;
- env_ = 0;
- }
-
- delete mpf_;
- }
-}
-
-// Return a tristate value corresponding to whether we should
-// throw exceptions on errors:
-// ON_ERROR_RETURN
-// ON_ERROR_THROW
-// ON_ERROR_UNKNOWN
-//
-int Db::error_policy()
-{
- if (env_ != NULL)
- return (env_->error_policy());
- else {
- // If the env_ is null, that means that the user
- // did not attach an environment, so the correct error
- // policy can be deduced from constructor flags
- // for this Db.
- //
- if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) {
- return (ON_ERROR_RETURN);
- }
- else {
- return (ON_ERROR_THROW);
- }
- }
-}
-
-DB_DESTRUCTOR(close, (u_int32_t flags), (db, flags), DB_RETOK_STD)
-DB_METHOD(compact, (DbTxn *txnid, Dbt *start, Dbt *stop,
- DB_COMPACT *c_data, u_int32_t flags, Dbt *end),
- (db, unwrap(txnid), start, stop, c_data, flags, end), DB_RETOK_STD)
-
-// The following cast implies that Dbc can be no larger than DBC
-DB_METHOD(cursor, (DbTxn *txnid, Dbc **cursorp, u_int32_t flags),
- (db, unwrap(txnid), (DBC **)cursorp, flags),
- DB_RETOK_STD)
-
-DB_METHOD(del, (DbTxn *txnid, Dbt *key, u_int32_t flags),
- (db, unwrap(txnid), key, flags),
- DB_RETOK_DBDEL)
-
-void Db::err(int error, const char *format, ...)
-{
- DB *db = unwrap(this);
-
- DB_REAL_ERR(db->dbenv, error, 1, 1, format);
-}
-
-void Db::errx(const char *format, ...)
-{
- DB *db = unwrap(this);
-
- DB_REAL_ERR(db->dbenv, 0, 0, 1, format);
-}
-
-DB_METHOD(fd, (int *fdp), (db, fdp), DB_RETOK_STD)
-
-int Db::get(DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags)
-{
- DB *db = unwrap(this);
- int ret;
-
- ret = db->get(db, unwrap(txnid), key, value, flags);
-
- if (!DB_RETOK_DBGET(ret)) {
- if (ret == DB_BUFFER_SMALL)
- DB_ERROR_DBT(env_, "Db::get", value, error_policy());
- else
- DB_ERROR(env_, "Db::get", ret, error_policy());
- }
-
- return (ret);
-}
-
-int Db::get_byteswapped(int *isswapped)
-{
- DB *db = (DB *)unwrapConst(this);
- return (db->get_byteswapped(db, isswapped));
-}
-
-DbEnv *Db::get_env()
-{
- DB *db = (DB *)unwrapConst(this);
- DB_ENV *dbenv = db->get_env(db);
- return (dbenv != NULL ? DbEnv::get_DbEnv(dbenv) : NULL);
-}
-
-DbMpoolFile *Db::get_mpf()
-{
- return (mpf_);
-}
-
-DB_METHOD(get_dbname, (const char **filenamep, const char **dbnamep),
- (db, filenamep, dbnamep), DB_RETOK_STD)
-
-DB_METHOD(get_open_flags, (u_int32_t *flagsp), (db, flagsp), DB_RETOK_STD)
-
-int Db::get_type(DBTYPE *dbtype)
-{
- DB *db = (DB *)unwrapConst(this);
- return (db->get_type(db, dbtype));
-}
-
-// Dbc is a "compatible" subclass of DBC - that is, no virtual functions
-// or even extra data members, so these casts, although technically
-// non-portable, "should" always be okay.
-DB_METHOD(join, (Dbc **curslist, Dbc **cursorp, u_int32_t flags),
- (db, (DBC **)curslist, (DBC **)cursorp, flags), DB_RETOK_STD)
-
-DB_METHOD(key_range,
- (DbTxn *txnid, Dbt *key, DB_KEY_RANGE *results, u_int32_t flags),
- (db, unwrap(txnid), key, results, flags), DB_RETOK_STD)
-
-// If an error occurred during the constructor, report it now.
-// Otherwise, call the underlying DB->open method.
-//
-int Db::open(DbTxn *txnid, const char *file, const char *database,
- DBTYPE type, u_int32_t flags, int mode)
-{
- int ret;
- DB *db = unwrap(this);
-
- if (construct_error_ != 0)
- ret = construct_error_;
- else
- ret = db->open(db, unwrap(txnid), file, database, type, flags,
- mode);
-
- if (!DB_RETOK_STD(ret))
- DB_ERROR(env_, "Db::open", ret, error_policy());
-
- return (ret);
-}
-
-int Db::pget(DbTxn *txnid, Dbt *key, Dbt *pkey, Dbt *value, u_int32_t flags)
-{
- DB *db = unwrap(this);
- int ret;
-
- ret = db->pget(db, unwrap(txnid), key, pkey, value, flags);
-
- /* The logic here is identical to Db::get - reuse the macro. */
- if (!DB_RETOK_DBGET(ret)) {
- if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(value))
- DB_ERROR_DBT(env_, "Db::pget", value, error_policy());
- else
- DB_ERROR(env_, "Db::pget", ret, error_policy());
- }
-
- return (ret);
-}
-
-DB_METHOD(put, (DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags),
- (db, unwrap(txnid), key, value, flags), DB_RETOK_DBPUT)
-
-DB_DESTRUCTOR(rename,
- (const char *file, const char *database, const char *newname,
- u_int32_t flags),
- (db, file, database, newname, flags), DB_RETOK_STD)
-
-DB_DESTRUCTOR(remove, (const char *file, const char *database, u_int32_t flags),
- (db, file, database, flags), DB_RETOK_STD)
-
-DB_METHOD(truncate, (DbTxn *txnid, u_int32_t *countp, u_int32_t flags),
- (db, unwrap(txnid), countp, flags), DB_RETOK_STD)
-
-DB_METHOD(stat, (DbTxn *txnid, void *sp, u_int32_t flags),
- (db, unwrap(txnid), sp, flags), DB_RETOK_STD)
-
-DB_METHOD(stat_print, (u_int32_t flags), (db, flags), DB_RETOK_STD)
-
-DB_METHOD(sync, (u_int32_t flags), (db, flags), DB_RETOK_STD)
-
-DB_METHOD(upgrade,
- (const char *name, u_int32_t flags), (db, name, flags), DB_RETOK_STD)
-
-////////////////////////////////////////////////////////////////////////
-//
-// callbacks
-//
-// *_intercept_c are 'glue' functions that must be declared
-// as extern "C" so to be typesafe. Using a C++ method, even
-// a static class method with 'correct' arguments, will not pass
-// the test; some picky compilers do not allow mixing of function
-// pointers to 'C' functions with function pointers to C++ functions.
-//
-// One wart with this scheme is that the *_callback_ method pointer
-// must be declared public to be accessible by the C intercept.
-// It's possible to accomplish the goal without this, and with
-// another public transfer method, but it's just too much overhead.
-// These callbacks are supposed to be *fast*.
-//
-// The DBTs we receive in these callbacks from the C layer may be
-// manufactured there, but we want to treat them as a Dbts.
-// Technically speaking, these DBTs were not constructed as a Dbts,
-// but it should be safe to cast them as such given that Dbt is a
-// *very* thin extension of the DBT. That is, Dbt has no additional
-// data elements, does not use virtual functions, virtual inheritance,
-// multiple inheritance, RTI, or any other language feature that
-// causes the structure to grow or be displaced. Although this may
-// sound risky, a design goal of C++ is complete structure
-// compatibility with C, and has the philosophy 'if you don't use it,
-// you shouldn't incur the overhead'. If the C/C++ compilers you're
-// using on a given machine do not have matching struct layouts, then
-// a lot more things will be broken than just this.
-//
-// The alternative, creating a Dbt here in the callback, and populating
-// it from the DBT, is just too slow and cumbersome to be very useful.
-
-// These macros avoid a lot of boilerplate code for callbacks
-
-#define DB_CALLBACK_C_INTERCEPT(_name, _rettype, _cargspec, \
- _return, _cxxargs) \
-extern "C" _rettype _db_##_name##_intercept_c _cargspec \
-{ \
- Db *cxxthis; \
- \
- DB_ASSERT(cthis != NULL); \
- cxxthis = Db::get_Db(cthis); \
- DB_ASSERT(cxxthis != NULL); \
- DB_ASSERT(cxxthis->_name##_callback_ != 0); \
- \
- _return (*cxxthis->_name##_callback_) _cxxargs; \
-}
-
-#define DB_SET_CALLBACK(_cxxname, _name, _cxxargspec, _cb) \
-int Db::_cxxname _cxxargspec \
-{ \
- DB *cthis = unwrap(this); \
- \
- _name##_callback_ = _cb; \
- return ((*(cthis->_cxxname))(cthis, \
- (_cb) ? _db_##_name##_intercept_c : NULL)); \
-}
-
-/* associate callback - doesn't quite fit the pattern because of the flags */
-DB_CALLBACK_C_INTERCEPT(associate,
- int, (DB *cthis, const DBT *key, const DBT *data, DBT *retval),
- return, (cxxthis, Dbt::get_const_Dbt(key), Dbt::get_const_Dbt(data),
- Dbt::get_Dbt(retval)))
-
-int Db::associate(DbTxn *txn, Db *secondary, int (*callback)(Db *, const Dbt *,
- const Dbt *, Dbt *), u_int32_t flags)
-{
- DB *cthis = unwrap(this);
-
- /* Since the secondary Db is used as the first argument
- * to the callback, we store the C++ callback on it
- * rather than on 'this'.
- */
- secondary->associate_callback_ = callback;
- return ((*(cthis->associate))(cthis, unwrap(txn), unwrap(secondary),
- (callback) ? _db_associate_intercept_c : NULL, flags));
-}
-
-DB_CALLBACK_C_INTERCEPT(feedback,
- void, (DB *cthis, int opcode, int pct),
- /* no return */ (void), (cxxthis, opcode, pct))
-
-DB_SET_CALLBACK(set_feedback, feedback,
- (void (*arg)(Db *cxxthis, int opcode, int pct)), arg)
-
-DB_CALLBACK_C_INTERCEPT(append_recno,
- int, (DB *cthis, DBT *data, db_recno_t recno),
- return, (cxxthis, Dbt::get_Dbt(data), recno))
-
-DB_SET_CALLBACK(set_append_recno, append_recno,
- (int (*arg)(Db *cxxthis, Dbt *data, db_recno_t recno)), arg)
-
-DB_CALLBACK_C_INTERCEPT(bt_compare,
- int, (DB *cthis, const DBT *data1, const DBT *data2),
- return,
- (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2)))
-
-DB_SET_CALLBACK(set_bt_compare, bt_compare,
- (int (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg)
-
-DB_CALLBACK_C_INTERCEPT(bt_prefix,
- size_t, (DB *cthis, const DBT *data1, const DBT *data2),
- return,
- (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2)))
-
-DB_SET_CALLBACK(set_bt_prefix, bt_prefix,
- (size_t (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg)
-
-DB_CALLBACK_C_INTERCEPT(dup_compare,
- int, (DB *cthis, const DBT *data1, const DBT *data2),
- return,
- (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2)))
-
-DB_SET_CALLBACK(set_dup_compare, dup_compare,
- (int (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg)
-
-DB_CALLBACK_C_INTERCEPT(h_hash,
- u_int32_t, (DB *cthis, const void *data, u_int32_t len),
- return, (cxxthis, data, len))
-
-DB_SET_CALLBACK(set_h_hash, h_hash,
- (u_int32_t (*arg)(Db *cxxthis, const void *data, u_int32_t len)), arg)
-
-// This is a 'glue' function declared as extern "C" so it will
-// be compatible with picky compilers that do not allow mixing
-// of function pointers to 'C' functions with function pointers
-// to C++ functions.
-//
-extern "C"
-int _verify_callback_c(void *handle, const void *str_arg)
-{
- char *str;
- __DB_STD(ostream) *out;
-
- str = (char *)str_arg;
- out = (__DB_STD(ostream) *)handle;
-
- (*out) << str;
- if (out->fail())
- return (EIO);
-
- return (0);
-}
-
-int Db::verify(const char *name, const char *subdb,
- __DB_STD(ostream) *ostr, u_int32_t flags)
-{
- DB *db = unwrap(this);
- int ret;
-
- if (!db)
- ret = EINVAL;
- else {
- // after a DB->verify (no matter if success or failure),
- // the underlying DB object must not be accessed,
- // so we clean up in advance.
- //
- cleanup();
-
- ret = __db_verify_internal(db, name, subdb, ostr,
- _verify_callback_c, flags);
- }
-
- if (!DB_RETOK_STD(ret))
- DB_ERROR(env_, "Db::verify", ret, error_policy());
-
- return (ret);
-}
-
-DB_METHOD(set_bt_compare, (bt_compare_fcn_type func),
- (db, func), DB_RETOK_STD)
-DB_METHOD(get_bt_minkey, (u_int32_t *bt_minkeyp),
- (db, bt_minkeyp), DB_RETOK_STD)
-DB_METHOD(set_bt_minkey, (u_int32_t bt_minkey),
- (db, bt_minkey), DB_RETOK_STD)
-DB_METHOD(set_bt_prefix, (bt_prefix_fcn_type func),
- (db, func), DB_RETOK_STD)
-DB_METHOD(set_dup_compare, (dup_compare_fcn_type func),
- (db, func), DB_RETOK_STD)
-DB_METHOD(get_encrypt_flags, (u_int32_t *flagsp),
- (db, flagsp), DB_RETOK_STD)
-DB_METHOD(set_encrypt, (const char *passwd, u_int32_t flags),
- (db, passwd, flags), DB_RETOK_STD)
-DB_METHOD_VOID(get_errfile, (FILE **errfilep), (db, errfilep))
-DB_METHOD_VOID(set_errfile, (FILE *errfile), (db, errfile))
-DB_METHOD_VOID(get_errpfx, (const char **errpfx), (db, errpfx))
-DB_METHOD_VOID(set_errpfx, (const char *errpfx), (db, errpfx))
-DB_METHOD(get_flags, (u_int32_t *flagsp), (db, flagsp),
- DB_RETOK_STD)
-DB_METHOD(set_flags, (u_int32_t flags), (db, flags),
- DB_RETOK_STD)
-DB_METHOD(get_h_ffactor, (u_int32_t *h_ffactorp),
- (db, h_ffactorp), DB_RETOK_STD)
-DB_METHOD(set_h_ffactor, (u_int32_t h_ffactor),
- (db, h_ffactor), DB_RETOK_STD)
-DB_METHOD(set_h_hash, (h_hash_fcn_type func),
- (db, func), DB_RETOK_STD)
-DB_METHOD(get_h_nelem, (u_int32_t *h_nelemp),
- (db, h_nelemp), DB_RETOK_STD)
-DB_METHOD(set_h_nelem, (u_int32_t h_nelem),
- (db, h_nelem), DB_RETOK_STD)
-DB_METHOD(get_lorder, (int *db_lorderp), (db, db_lorderp),
- DB_RETOK_STD)
-DB_METHOD(set_lorder, (int db_lorder), (db, db_lorder),
- DB_RETOK_STD)
-DB_METHOD_VOID(get_msgfile, (FILE **msgfilep), (db, msgfilep))
-DB_METHOD_VOID(set_msgfile, (FILE *msgfile), (db, msgfile))
-DB_METHOD(get_pagesize, (u_int32_t *db_pagesizep),
- (db, db_pagesizep), DB_RETOK_STD)
-DB_METHOD(set_pagesize, (u_int32_t db_pagesize),
- (db, db_pagesize), DB_RETOK_STD)
-DB_METHOD(get_re_delim, (int *re_delimp),
- (db, re_delimp), DB_RETOK_STD)
-DB_METHOD(set_re_delim, (int re_delim),
- (db, re_delim), DB_RETOK_STD)
-DB_METHOD(get_re_len, (u_int32_t *re_lenp),
- (db, re_lenp), DB_RETOK_STD)
-DB_METHOD(set_re_len, (u_int32_t re_len),
- (db, re_len), DB_RETOK_STD)
-DB_METHOD(get_re_pad, (int *re_padp),
- (db, re_padp), DB_RETOK_STD)
-DB_METHOD(set_re_pad, (int re_pad),
- (db, re_pad), DB_RETOK_STD)
-DB_METHOD(get_re_source, (const char **re_source),
- (db, re_source), DB_RETOK_STD)
-DB_METHOD(set_re_source, (const char *re_source),
- (db, re_source), DB_RETOK_STD)
-DB_METHOD(get_q_extentsize, (u_int32_t *extentsizep),
- (db, extentsizep), DB_RETOK_STD)
-DB_METHOD(set_q_extentsize, (u_int32_t extentsize),
- (db, extentsize), DB_RETOK_STD)
-
-DB_METHOD_QUIET(set_alloc, (db_malloc_fcn_type malloc_fcn,
- db_realloc_fcn_type realloc_fcn, db_free_fcn_type free_fcn),
- (db, malloc_fcn, realloc_fcn, free_fcn))
-
-void Db::set_errcall(void (*arg)(const DbEnv *, const char *, const char *))
-{
- env_->set_errcall(arg);
-}
-
-void Db::set_msgcall(void (*arg)(const DbEnv *, const char *))
-{
- env_->set_msgcall(arg);
-}
-
-void *Db::get_app_private() const
-{
- return unwrapConst(this)->app_private;
-}
-
-void Db::set_app_private(void *value)
-{
- unwrap(this)->app_private = value;
-}
-
-DB_METHOD(get_cachesize, (u_int32_t *gbytesp, u_int32_t *bytesp, int *ncachep),
- (db, gbytesp, bytesp, ncachep), DB_RETOK_STD)
-DB_METHOD(set_cachesize, (u_int32_t gbytes, u_int32_t bytes, int ncache),
- (db, gbytes, bytes, ncache), DB_RETOK_STD)
-
-int Db::set_paniccall(void (*callback)(DbEnv *, int))
-{
- return (env_->set_paniccall(callback));
-}
-
-__DB_STD(ostream) *Db::get_error_stream()
-{
- return env_->get_error_stream();
-}
-
-void Db::set_error_stream(__DB_STD(ostream) *error_stream)
-{
- env_->set_error_stream(error_stream);
-}
-
-__DB_STD(ostream) *Db::get_message_stream()
-{
- return env_->get_message_stream();
-}
-
-void Db::set_message_stream(__DB_STD(ostream) *message_stream)
-{
- env_->set_message_stream(message_stream);
-}
-
-DB_METHOD_QUIET(get_transactional, (), (db))
diff --git a/storage/bdb/cxx/cxx_dbc.cpp b/storage/bdb/cxx/cxx_dbc.cpp
deleted file mode 100644
index 8f73557222a..00000000000
--- a/storage/bdb/cxx/cxx_dbc.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: cxx_dbc.cpp,v 12.2 2005/09/30 07:38:25 mjc Exp $
- */
-
-#include "db_config.h"
-
-#include
-#include
-
-#include "db_cxx.h"
-#include "dbinc/cxx_int.h"
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc_auto/db_auto.h"
-#include "dbinc_auto/crdel_auto.h"
-#include "dbinc/db_dispatch.h"
-#include "dbinc_auto/db_ext.h"
-#include "dbinc_auto/common_ext.h"
-
-// Helper macro for simple methods that pass through to the
-// underlying C method. It may return an error or raise an exception.
-// Note this macro expects that input _argspec is an argument
-// list element (e.g., "char *arg") and that _arglist is the arguments
-// that should be passed through to the C method (e.g., "(db, arg)")
-//
-#define DBC_METHOD(_name, _argspec, _arglist, _retok) \
-int Dbc::_name _argspec \
-{ \
- int ret; \
- DBC *dbc = this; \
- \
- ret = dbc->c_##_name _arglist; \
- if (!_retok(ret)) \
- DB_ERROR(DbEnv::get_DbEnv(dbc->dbp->dbenv), \
- "Dbc::" # _name, ret, ON_ERROR_UNKNOWN); \
- return (ret); \
-}
-
-// It's private, and should never be called, but VC4.0 needs it resolved
-//
-Dbc::~Dbc()
-{
-}
-
-DBC_METHOD(close, (void), (dbc), DB_RETOK_STD)
-DBC_METHOD(count, (db_recno_t *countp, u_int32_t _flags),
- (dbc, countp, _flags), DB_RETOK_STD)
-DBC_METHOD(del, (u_int32_t _flags),
- (dbc, _flags), DB_RETOK_DBCDEL)
-
-int Dbc::dup(Dbc** cursorp, u_int32_t _flags)
-{
- int ret;
- DBC *dbc = this;
- DBC *new_cursor = 0;
-
- ret = dbc->c_dup(dbc, &new_cursor, _flags);
-
- if (DB_RETOK_STD(ret))
- // The following cast implies that Dbc can be no larger than DBC
- *cursorp = (Dbc*)new_cursor;
- else
- DB_ERROR(DbEnv::get_DbEnv(dbc->dbp->dbenv),
- "Dbc::dup", ret, ON_ERROR_UNKNOWN);
-
- return (ret);
-}
-
-int Dbc::get(Dbt* key, Dbt *data, u_int32_t _flags)
-{
- int ret;
- DBC *dbc = this;
-
- ret = dbc->c_get(dbc, key, data, _flags);
-
- if (!DB_RETOK_DBCGET(ret)) {
- if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(key))
- DB_ERROR_DBT(DbEnv::get_DbEnv(dbc->dbp->dbenv),
- "Dbc::get", key, ON_ERROR_UNKNOWN);
- else if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(data))
- DB_ERROR_DBT(DbEnv::get_DbEnv(dbc->dbp->dbenv),
- "Dbc::get", data, ON_ERROR_UNKNOWN);
- else
- DB_ERROR(DbEnv::get_DbEnv(dbc->dbp->dbenv),
- "Dbc::get", ret, ON_ERROR_UNKNOWN);
- }
-
- return (ret);
-}
-
-int Dbc::pget(Dbt* key, Dbt *pkey, Dbt *data, u_int32_t _flags)
-{
- int ret;
- DBC *dbc = this;
-
- ret = dbc->c_pget(dbc, key, pkey, data, _flags);
-
- /* Logic is the same as for Dbc::get - reusing macro. */
- if (!DB_RETOK_DBCGET(ret)) {
- if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(key))
- DB_ERROR_DBT(DbEnv::get_DbEnv(dbc->dbp->dbenv),
- "Dbc::pget", key, ON_ERROR_UNKNOWN);
- else if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(data))
- DB_ERROR_DBT(DbEnv::get_DbEnv(dbc->dbp->dbenv),
- "Dbc::pget", data, ON_ERROR_UNKNOWN);
- else
- DB_ERROR(DbEnv::get_DbEnv(dbc->dbp->dbenv),
- "Dbc::pget", ret, ON_ERROR_UNKNOWN);
- }
-
- return (ret);
-}
-
-DBC_METHOD(put, (Dbt* key, Dbt *data, u_int32_t _flags),
- (dbc, key, data, _flags), DB_RETOK_DBCPUT)
diff --git a/storage/bdb/cxx/cxx_dbt.cpp b/storage/bdb/cxx/cxx_dbt.cpp
deleted file mode 100644
index 8062c255be5..00000000000
--- a/storage/bdb/cxx/cxx_dbt.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: cxx_dbt.cpp,v 12.1 2005/06/16 20:20:58 bostic Exp $
- */
-
-#include "db_config.h"
-
-#include
-#include
-
-#include "db_cxx.h"
-#include "dbinc/cxx_int.h"
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc_auto/db_auto.h"
-#include "dbinc_auto/crdel_auto.h"
-#include "dbinc/db_dispatch.h"
-#include "dbinc_auto/db_ext.h"
-#include "dbinc_auto/common_ext.h"
-
-Dbt::Dbt()
-{
- DBT *dbt = this;
- memset(dbt, 0, sizeof(DBT));
-}
-
-Dbt::Dbt(void *data_arg, u_int32_t size_arg)
-{
- DBT *dbt = this;
- memset(dbt, 0, sizeof(DBT));
- set_data(data_arg);
- set_size(size_arg);
-}
-
-Dbt::~Dbt()
-{
-}
-
-Dbt::Dbt(const Dbt &that)
-{
- const DBT *from = &that;
- DBT *to = this;
- memcpy(to, from, sizeof(DBT));
-}
-
-Dbt &Dbt::operator = (const Dbt &that)
-{
- if (this != &that) {
- const DBT *from = &that;
- DBT *to = this;
- memcpy(to, from, sizeof(DBT));
- }
- return (*this);
-}
diff --git a/storage/bdb/cxx/cxx_env.cpp b/storage/bdb/cxx/cxx_env.cpp
deleted file mode 100644
index 62bbb0de381..00000000000
--- a/storage/bdb/cxx/cxx_env.cpp
+++ /dev/null
@@ -1,1054 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: cxx_env.cpp,v 12.14 2005/10/18 14:49:27 mjc Exp $
- */
-
-#include "db_config.h"
-
-#include
-#include // needed for set_error_stream
-#include
-
-#include "db_cxx.h"
-#include "dbinc/cxx_int.h"
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_am.h"
-#include "dbinc/log.h"
-#include "dbinc_auto/common_ext.h"
-#include "dbinc_auto/log_ext.h"
-
-#ifdef HAVE_CXX_STDHEADERS
-using std::cerr;
-#endif
-
-// Helper macros for simple methods that pass through to the
-// underlying C method. They may return an error or raise an exception.
-// These macros expect that input _argspec is an argument
-// list element (e.g., "char *arg") and that _arglist is the arguments
-// that should be passed through to the C method (e.g., "(dbenv, arg)")
-//
-#define DBENV_METHOD_ERR(_name, _argspec, _arglist, _on_err) \
-int DbEnv::_name _argspec \
-{ \
- DB_ENV *dbenv = unwrap(this); \
- int ret; \
- \
- if ((ret = dbenv->_name _arglist) != 0) { \
- _on_err; \
- } \
- return (ret); \
-}
-
-#define DBENV_METHOD(_name, _argspec, _arglist) \
- DBENV_METHOD_ERR(_name, _argspec, _arglist, \
- DB_ERROR(this, "DbEnv::" # _name, ret, error_policy()))
-
-#define DBENV_METHOD_QUIET(_name, _argspec, _arglist) \
-int DbEnv::_name _argspec \
-{ \
- DB_ENV *dbenv = unwrap(this); \
- \
- return (dbenv->_name _arglist); \
-}
-
-#define DBENV_METHOD_VOID(_name, _argspec, _arglist) \
-void DbEnv::_name _argspec \
-{ \
- DB_ENV *dbenv = unwrap(this); \
- \
- dbenv->_name _arglist; \
-}
-
-// The reason for a static variable is that some structures
-// (like Dbts) have no connection to any Db or DbEnv, so when
-// errors occur in their methods, we must have some reasonable
-// way to determine whether to throw or return errors.
-//
-// This variable is taken from flags whenever a DbEnv is constructed.
-// Normally there is only one DbEnv per program, and even if not,
-// there is typically a single policy of throwing or returning.
-//
-static int last_known_error_policy = ON_ERROR_UNKNOWN;
-
-// These 'glue' function are declared as extern "C" so they will
-// be compatible with picky compilers that do not allow mixing
-// of function pointers to 'C' functions with function pointers
-// to C++ functions.
-//
-extern "C"
-void _feedback_intercept_c(DB_ENV *env, int opcode, int pct)
-{
- DbEnv::_feedback_intercept(env, opcode, pct);
-}
-
-extern "C"
-void _paniccall_intercept_c(DB_ENV *env, int errval)
-{
- DbEnv::_paniccall_intercept(env, errval);
-}
-
-extern "C"
-void _stream_error_function_c(const DB_ENV *env,
- const char *prefix, const char *message)
-{
- DbEnv::_stream_error_function(env, prefix, message);
-}
-
-extern "C"
-void _stream_message_function_c(const DB_ENV *env, const char *message)
-{
- DbEnv::_stream_message_function(env, message);
-}
-
-extern "C"
-int _app_dispatch_intercept_c(DB_ENV *env, DBT *dbt, DB_LSN *lsn, db_recops op)
-{
- return (DbEnv::_app_dispatch_intercept(env, dbt, lsn, op));
-}
-
-extern "C"
-int _rep_send_intercept_c(DB_ENV *env, const DBT *cntrl, const DBT *data,
- const DB_LSN *lsn, int id, u_int32_t flags)
-{
- return (DbEnv::_rep_send_intercept(env,
- cntrl, data, lsn, id, flags));
-}
-
-extern "C"
-int _isalive_intercept_c(DB_ENV *env, pid_t pid, db_threadid_t thrid)
-{
- return (DbEnv::_isalive_intercept(env, pid, thrid));
-}
-
-extern "C"
-void _thread_id_intercept_c(DB_ENV *env, pid_t *pidp, db_threadid_t *thridp)
-{
- DbEnv::_thread_id_intercept(env, pidp, thridp);
-}
-
-extern "C"
-char *_thread_id_string_intercept_c(DB_ENV *env, pid_t pid,
- db_threadid_t thrid, char *buf)
-{
- return (DbEnv::_thread_id_string_intercept(env, pid, thrid, buf));
-}
-
-void DbEnv::_feedback_intercept(DB_ENV *env, int opcode, int pct)
-{
- DbEnv *cxxenv = DbEnv::get_DbEnv(env);
- if (cxxenv == 0) {
- DB_ERROR(0,
- "DbEnv::feedback_callback", EINVAL, ON_ERROR_UNKNOWN);
- return;
- }
- if (cxxenv->feedback_callback_ == 0) {
- DB_ERROR(DbEnv::get_DbEnv(env),
- "DbEnv::feedback_callback", EINVAL, cxxenv->error_policy());
- return;
- }
- (*cxxenv->feedback_callback_)(cxxenv, opcode, pct);
-}
-
-void DbEnv::_paniccall_intercept(DB_ENV *env, int errval)
-{
- DbEnv *cxxenv = DbEnv::get_DbEnv(env);
- if (cxxenv == 0) {
- DB_ERROR(0,
- "DbEnv::paniccall_callback", EINVAL, ON_ERROR_UNKNOWN);
- return;
- }
- if (cxxenv->paniccall_callback_ == 0) {
- DB_ERROR(cxxenv, "DbEnv::paniccall_callback", EINVAL,
- cxxenv->error_policy());
- return;
- }
- (*cxxenv->paniccall_callback_)(cxxenv, errval);
-}
-
-int DbEnv::_app_dispatch_intercept(DB_ENV *env, DBT *dbt, DB_LSN *lsn,
- db_recops op)
-{
- DbEnv *cxxenv = DbEnv::get_DbEnv(env);
- if (cxxenv == 0) {
- DB_ERROR(DbEnv::get_DbEnv(env),
- "DbEnv::app_dispatch_callback", EINVAL, ON_ERROR_UNKNOWN);
- return (EINVAL);
- }
- if (cxxenv->app_dispatch_callback_ == 0) {
- DB_ERROR(DbEnv::get_DbEnv(env),
- "DbEnv::app_dispatch_callback", EINVAL,
- cxxenv->error_policy());
- return (EINVAL);
- }
- Dbt *cxxdbt = (Dbt *)dbt;
- DbLsn *cxxlsn = (DbLsn *)lsn;
- return ((*cxxenv->app_dispatch_callback_)(cxxenv, cxxdbt, cxxlsn, op));
-}
-
-int DbEnv::_isalive_intercept(DB_ENV *env, pid_t pid, db_threadid_t thrid)
-{
- DbEnv *cxxenv = DbEnv::get_DbEnv(env);
- if (cxxenv == 0) {
- DB_ERROR(DbEnv::get_DbEnv(env),
- "DbEnv::isalive_callback", EINVAL, ON_ERROR_UNKNOWN);
- return (0);
- }
- return ((*cxxenv->isalive_callback_)(cxxenv, pid, thrid));
-}
-
-int DbEnv::_rep_send_intercept(DB_ENV *env, const DBT *cntrl, const DBT *data,
- const DB_LSN *lsn, int id, u_int32_t flags)
-{
- DbEnv *cxxenv = DbEnv::get_DbEnv(env);
- if (cxxenv == 0) {
- DB_ERROR(DbEnv::get_DbEnv(env),
- "DbEnv::rep_send_callback", EINVAL, ON_ERROR_UNKNOWN);
- return (EINVAL);
- }
- const Dbt *cxxcntrl = (const Dbt *)cntrl;
- const DbLsn *cxxlsn = (const DbLsn *)lsn;
- Dbt *cxxdata = (Dbt *)data;
- return ((*cxxenv->rep_send_callback_)(cxxenv,
- cxxcntrl, cxxdata, cxxlsn, id, flags));
-}
-
-void DbEnv::_thread_id_intercept(DB_ENV *env, pid_t *pidp, db_threadid_t *thridp)
-{
- DbEnv *cxxenv = DbEnv::get_DbEnv(env);
- if (cxxenv == 0) {
- DB_ERROR(DbEnv::get_DbEnv(env),
- "DbEnv::thread_id_callback", EINVAL, ON_ERROR_UNKNOWN);
- } else
- cxxenv->thread_id_callback_(cxxenv, pidp, thridp);
-}
-
-char *DbEnv::_thread_id_string_intercept(DB_ENV *env, pid_t pid,
- db_threadid_t thrid, char *buf)
-{
- DbEnv *cxxenv = DbEnv::get_DbEnv(env);
- if (cxxenv == 0) {
- DB_ERROR(DbEnv::get_DbEnv(env),
- "DbEnv::thread_id_string_callback", EINVAL, ON_ERROR_UNKNOWN);
- return (NULL);
- }
- return (cxxenv->thread_id_string_callback_(cxxenv, pid, thrid, buf));
-}
-
-// A truism for the DbEnv object is that there is a valid
-// DB_ENV handle from the constructor until close().
-// After the close, the DB_ENV handle is invalid and
-// no operations are permitted on the DbEnv (other than
-// destructor). Leaving the DbEnv handle open and not
-// doing a close is generally considered an error.
-//
-// We used to allow DbEnv objects to be closed and reopened.
-// This implied always keeping a valid DB_ENV object, and
-// coordinating the open objects between Db/DbEnv turned
-// out to be overly complicated. Now we do not allow this.
-
-DbEnv::DbEnv(u_int32_t flags)
-: imp_(0)
-, construct_error_(0)
-, construct_flags_(flags)
-, error_stream_(0)
-, message_stream_(0)
-, app_dispatch_callback_(0)
-, feedback_callback_(0)
-, paniccall_callback_(0)
-, rep_send_callback_(0)
-{
- if ((construct_error_ = initialize(0)) != 0)
- DB_ERROR(this, "DbEnv::DbEnv", construct_error_,
- error_policy());
-}
-
-DbEnv::DbEnv(DB_ENV *env, u_int32_t flags)
-: imp_(0)
-, construct_error_(0)
-, construct_flags_(flags)
-, error_stream_(0)
-, message_stream_(0)
-, app_dispatch_callback_(0)
-, feedback_callback_(0)
-, paniccall_callback_(0)
-, rep_send_callback_(0)
-{
- if ((construct_error_ = initialize(env)) != 0)
- DB_ERROR(this, "DbEnv::DbEnv", construct_error_,
- error_policy());
-}
-
-// If the DB_ENV handle is still open, we close it. This is to make stack
-// allocation of DbEnv objects easier so that they are cleaned up in the error
-// path. Note that the C layer catches cases where handles are open in the
-// environment at close time and reports an error. Applications should call
-// close explicitly in normal (non-exceptional) cases to check the return
-// value.
-//
-DbEnv::~DbEnv()
-{
- DB_ENV *env = unwrap(this);
-
- if (env != NULL) {
- cleanup();
- (void)env->close(env, 0);
- }
-}
-
-// called by destructors before the DB_ENV is destroyed.
-void DbEnv::cleanup()
-{
- DB_ENV *env = unwrap(this);
-
- if (env != NULL) {
- env->api1_internal = 0;
- imp_ = 0;
- }
-}
-
-int DbEnv::close(u_int32_t flags)
-{
- int ret;
- DB_ENV *env = unwrap(this);
-
- // after a close (no matter if success or failure),
- // the underlying DB_ENV object must not be accessed,
- // so we clean up in advance.
- //
- cleanup();
-
- // It's safe to throw an error after the close,
- // since our error mechanism does not peer into
- // the DB* structures.
- //
- if ((ret = env->close(env, flags)) != 0)
- DB_ERROR(this, "DbEnv::close", ret, error_policy());
-
- return (ret);
-}
-
-DBENV_METHOD(dbremove,
- (DbTxn *txn, const char *name, const char *subdb, u_int32_t flags),
- (dbenv, unwrap(txn), name, subdb, flags))
-DBENV_METHOD(dbrename, (DbTxn *txn, const char *name, const char *subdb,
- const char *newname, u_int32_t flags),
- (dbenv, unwrap(txn), name, subdb, newname, flags))
-
-void DbEnv::err(int error, const char *format, ...)
-{
- DB_ENV *env = unwrap(this);
-
- DB_REAL_ERR(env, error, 1, 1, format);
-}
-
-// Return a tristate value corresponding to whether we should
-// throw exceptions on errors:
-// ON_ERROR_RETURN
-// ON_ERROR_THROW
-// ON_ERROR_UNKNOWN
-//
-int DbEnv::error_policy()
-{
- if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) {
- return (ON_ERROR_RETURN);
- }
- else {
- return (ON_ERROR_THROW);
- }
-}
-
-void DbEnv::errx(const char *format, ...)
-{
- DB_ENV *env = unwrap(this);
-
- DB_REAL_ERR(env, 0, 0, 1, format);
-}
-
-void *DbEnv::get_app_private() const
-{
- return unwrapConst(this)->app_private;
-}
-
-DBENV_METHOD(failchk, (u_int32_t flags), (dbenv, flags))
-DBENV_METHOD(fileid_reset, (const char *file, u_int32_t flags),
- (dbenv, file, flags))
-DBENV_METHOD(get_home, (const char **homep), (dbenv, homep))
-DBENV_METHOD(get_open_flags, (u_int32_t *flagsp), (dbenv, flagsp))
-DBENV_METHOD(get_data_dirs, (const char ***dirspp), (dbenv, dirspp))
-
-bool DbEnv::is_bigendian()
-{
- return unwrap(this)->is_bigendian() ? true : false;
-}
-
-DBENV_METHOD(set_thread_count, (u_int32_t count), (dbenv, count))
-
-// used internally during constructor
-// to associate an existing DB_ENV with this DbEnv,
-// or create a new one.
-//
-int DbEnv::initialize(DB_ENV *env)
-{
- int ret;
-
- last_known_error_policy = error_policy();
-
- if (env == 0) {
- // Create a new DB_ENV environment.
- if ((ret = ::db_env_create(&env,
- construct_flags_ & ~DB_CXX_NO_EXCEPTIONS)) != 0)
- return (ret);
- }
- imp_ = env;
- env->api1_internal = this; // for DB_ENV* to DbEnv* conversion
- return (0);
-}
-
-// lock methods
-DBENV_METHOD(lock_detect, (u_int32_t flags, u_int32_t atype, int *aborted),
- (dbenv, flags, atype, aborted))
-DBENV_METHOD_ERR(lock_get,
- (u_int32_t locker, u_int32_t flags, const Dbt *obj,
- db_lockmode_t lock_mode, DbLock *lock),
- (dbenv, locker, flags, obj, lock_mode, &lock->lock_),
- DbEnv::runtime_error_lock_get(this, "DbEnv::lock_get", ret,
- DB_LOCK_GET, lock_mode, obj, *lock,
- -1, error_policy()))
-DBENV_METHOD(lock_id, (u_int32_t *idp), (dbenv, idp))
-DBENV_METHOD(lock_id_free, (u_int32_t id), (dbenv, id))
-DBENV_METHOD(lock_put, (DbLock *lock), (dbenv, &lock->lock_))
-DBENV_METHOD(lock_stat, (DB_LOCK_STAT **statp, u_int32_t flags),
- (dbenv, statp, flags))
-DBENV_METHOD(lock_stat_print, (u_int32_t flags), (dbenv, flags))
-DBENV_METHOD_ERR(lock_vec,
- (u_int32_t locker, u_int32_t flags, DB_LOCKREQ list[],
- int nlist, DB_LOCKREQ **elist_returned),
- (dbenv, locker, flags, list, nlist, elist_returned),
- DbEnv::runtime_error_lock_get(this, "DbEnv::lock_vec", ret,
- (*elist_returned)->op, (*elist_returned)->mode,
- Dbt::get_Dbt((*elist_returned)->obj), DbLock((*elist_returned)->lock),
- (*elist_returned) - list, error_policy()))
-// log methods
-DBENV_METHOD(log_archive, (char **list[], u_int32_t flags),
- (dbenv, list, flags))
-
-int DbEnv::log_compare(const DbLsn *lsn0, const DbLsn *lsn1)
-{
- return (::log_compare(lsn0, lsn1));
-}
-
-// The following cast implies that DbLogc can be no larger than DB_LOGC
-DBENV_METHOD(log_cursor, (DbLogc **cursorp, u_int32_t flags),
- (dbenv, (DB_LOGC **)cursorp, flags))
-DBENV_METHOD(log_file, (DbLsn *lsn, char *namep, size_t len),
- (dbenv, lsn, namep, len))
-DBENV_METHOD(log_flush, (const DbLsn *lsn), (dbenv, lsn))
-DBENV_METHOD(log_put, (DbLsn *lsn, const Dbt *data, u_int32_t flags),
- (dbenv, lsn, data, flags))
-
-int DbEnv::log_printf(DbTxn *txn, const char *fmt, ...)
-{
- DB_ENV *env = unwrap(this);
- va_list ap;
- int ret;
-
- va_start(ap, fmt);
- ret = __log_printf_pp(env, unwrap(txn), fmt, ap);
- va_end(ap);
-
- return (ret);
-}
-
-DBENV_METHOD(log_stat, (DB_LOG_STAT **spp, u_int32_t flags),
- (dbenv, spp, flags))
-DBENV_METHOD(log_stat_print, (u_int32_t flags), (dbenv, flags))
-
-DBENV_METHOD(lsn_reset, (const char *file, u_int32_t flags),
- (dbenv, file, flags))
-
-int DbEnv::memp_fcreate(DbMpoolFile **dbmfp, u_int32_t flags)
-{
- DB_ENV *env = unwrap(this);
- int ret;
- DB_MPOOLFILE *mpf;
-
- if (env == NULL)
- ret = EINVAL;
- else
- ret = env->memp_fcreate(env, &mpf, flags);
-
- if (DB_RETOK_STD(ret)) {
- *dbmfp = new DbMpoolFile();
- (*dbmfp)->imp_ = mpf;
- } else
- DB_ERROR(this, "DbMpoolFile::f_create", ret, ON_ERROR_UNKNOWN);
-
- return (ret);
-}
-
-DBENV_METHOD(memp_register,
- (int ftype, pgin_fcn_type pgin_fcn, pgout_fcn_type pgout_fcn),
- (dbenv, ftype, pgin_fcn, pgout_fcn))
-
-// memory pool methods
-DBENV_METHOD(memp_stat,
- (DB_MPOOL_STAT **gsp, DB_MPOOL_FSTAT ***fsp, u_int32_t flags),
- (dbenv, gsp, fsp, flags))
-DBENV_METHOD(memp_stat_print, (u_int32_t flags), (dbenv, flags))
-DBENV_METHOD(memp_sync, (DbLsn *sn), (dbenv, sn))
-DBENV_METHOD(memp_trickle, (int pct, int *nwrotep), (dbenv, pct, nwrotep))
-
-// If an error occurred during the constructor, report it now.
-// Otherwise, call the underlying DB->open method.
-//
-int DbEnv::open(const char *db_home, u_int32_t flags, int mode)
-{
- int ret;
- DB_ENV *env = unwrap(this);
-
- if (construct_error_ != 0)
- ret = construct_error_;
- else
- ret = env->open(env, db_home, flags, mode);
-
- if (!DB_RETOK_STD(ret))
- DB_ERROR(this, "DbEnv::open", ret, error_policy());
-
- return (ret);
-}
-
-int DbEnv::remove(const char *db_home, u_int32_t flags)
-{
- int ret;
- DB_ENV *env = unwrap(this);
-
- // after a remove (no matter if success or failure),
- // the underlying DB_ENV object must not be accessed,
- // so we clean up in advance.
- //
- cleanup();
-
- if ((ret = env->remove(env, db_home, flags)) != 0)
- DB_ERROR(this, "DbEnv::remove", ret, error_policy());
-
- return (ret);
-}
-
-// Report an error associated with the DbEnv.
-// error_policy is one of:
-// ON_ERROR_THROW throw an error
-// ON_ERROR_RETURN do nothing here, the caller will return an error
-// ON_ERROR_UNKNOWN defer the policy to policy saved in DbEnv::DbEnv
-//
-void DbEnv::runtime_error(DbEnv *env,
- const char *caller, int error, int error_policy)
-{
- if (error_policy == ON_ERROR_UNKNOWN)
- error_policy = last_known_error_policy;
- if (error_policy == ON_ERROR_THROW) {
- // Creating and throwing the object in two separate
- // statements seems to be necessary for HP compilers.
- switch (error) {
- case DB_LOCK_DEADLOCK:
- {
- DbDeadlockException dl_except(caller);
- dl_except.set_env(env);
- throw dl_except;
- }
- break;
- case DB_RUNRECOVERY:
- {
- DbRunRecoveryException rr_except(caller);
- rr_except.set_env(env);
- throw rr_except;
- }
- break;
- case DB_LOCK_NOTGRANTED:
- {
- DbLockNotGrantedException lng_except(caller);
- lng_except.set_env(env);
- throw lng_except;
- }
- break;
- case DB_REP_HANDLE_DEAD:
- {
- DbRepHandleDeadException dl_except(caller);
- dl_except.set_env(env);
- throw dl_except;
- }
- default:
- {
- DbException except(caller, error);
- except.set_env(env);
- throw except;
- }
- break;
- }
- }
-}
-
-// Like DbEnv::runtime_error, but issue a DbMemoryException
-// based on the fact that this Dbt is not large enough.
-void DbEnv::runtime_error_dbt(DbEnv *env,
- const char *caller, Dbt *dbt, int error_policy)
-{
- if (error_policy == ON_ERROR_UNKNOWN)
- error_policy = last_known_error_policy;
- if (error_policy == ON_ERROR_THROW) {
- // Creating and throwing the object in two separate
- // statements seems to be necessary for HP compilers.
- DbMemoryException except(caller, dbt);
- except.set_env(env);
- throw except;
- }
-}
-
-// Like DbEnv::runtime_error, but issue a DbLockNotGrantedException,
-// or a regular runtime error.
-// call regular runtime_error if it
-void DbEnv::runtime_error_lock_get(DbEnv *env,
- const char *caller, int error,
- db_lockop_t op, db_lockmode_t mode, const Dbt *obj,
- DbLock lock, int index, int error_policy)
-{
- if (error != DB_LOCK_NOTGRANTED) {
- runtime_error(env, caller, error, error_policy);
- return;
- }
-
- if (error_policy == ON_ERROR_UNKNOWN)
- error_policy = last_known_error_policy;
- if (error_policy == ON_ERROR_THROW) {
- // Creating and throwing the object in two separate
- // statements seems to be necessary for HP compilers.
- DbLockNotGrantedException except(caller, op, mode,
- obj, lock, index);
- except.set_env(env);
- throw except;
- }
-}
-
-void DbEnv::_stream_error_function(
- const DB_ENV *env, const char *prefix, const char *message)
-{
- const DbEnv *cxxenv = DbEnv::get_const_DbEnv(env);
- if (cxxenv == 0) {
- DB_ERROR(0,
- "DbEnv::stream_error", EINVAL, ON_ERROR_UNKNOWN);
- return;
- }
-
- if (cxxenv->error_callback_)
- cxxenv->error_callback_(cxxenv, prefix, message);
- else if (cxxenv->error_stream_) {
- // HP compilers need the extra casts, we don't know why.
- if (prefix) {
- (*cxxenv->error_stream_) << prefix;
- (*cxxenv->error_stream_) << (const char *)": ";
- }
- if (message)
- (*cxxenv->error_stream_) << (const char *)message;
- (*cxxenv->error_stream_) << (const char *)"\n";
- }
-}
-
-void DbEnv::_stream_message_function(const DB_ENV *env, const char *message)
-{
- const DbEnv *cxxenv = DbEnv::get_const_DbEnv(env);
- if (cxxenv == 0) {
- DB_ERROR(0,
- "DbEnv::stream_message", EINVAL, ON_ERROR_UNKNOWN);
- return;
- }
-
- if (cxxenv->message_callback_)
- cxxenv->message_callback_(cxxenv, message);
- else if (cxxenv->message_stream_) {
- // HP compilers need the extra casts, we don't know why.
- (*cxxenv->message_stream_) << (const char *)message;
- (*cxxenv->message_stream_) << (const char *)"\n";
- }
-}
-
-// static method
-char *DbEnv::strerror(int error)
-{
- return (db_strerror(error));
-}
-
-// We keep these alphabetical by field name,
-// for comparison with Java's list.
-//
-DBENV_METHOD(set_data_dir, (const char *dir), (dbenv, dir))
-DBENV_METHOD(get_encrypt_flags, (u_int32_t *flagsp),
- (dbenv, flagsp))
-DBENV_METHOD(set_encrypt, (const char *passwd, u_int32_t flags),
- (dbenv, passwd, flags))
-DBENV_METHOD_VOID(get_errfile, (FILE **errfilep), (dbenv, errfilep))
-DBENV_METHOD_VOID(set_errfile, (FILE *errfile), (dbenv, errfile))
-DBENV_METHOD_VOID(get_errpfx, (const char **errpfxp), (dbenv, errpfxp))
-DBENV_METHOD_VOID(set_errpfx, (const char *errpfx), (dbenv, errpfx))
-DBENV_METHOD(set_intermediate_dir, (int mode, u_int32_t flags),
- (dbenv, mode, flags))
-DBENV_METHOD(get_lg_bsize, (u_int32_t *bsizep), (dbenv, bsizep))
-DBENV_METHOD(set_lg_bsize, (u_int32_t bsize), (dbenv, bsize))
-DBENV_METHOD(get_lg_dir, (const char **dirp), (dbenv, dirp))
-DBENV_METHOD(set_lg_dir, (const char *dir), (dbenv, dir))
-DBENV_METHOD(get_lg_filemode, (int *modep), (dbenv, modep))
-DBENV_METHOD(set_lg_filemode, (int mode), (dbenv, mode))
-DBENV_METHOD(get_lg_max, (u_int32_t *maxp), (dbenv, maxp))
-DBENV_METHOD(set_lg_max, (u_int32_t max), (dbenv, max))
-DBENV_METHOD(get_lg_regionmax, (u_int32_t *regionmaxp), (dbenv, regionmaxp))
-DBENV_METHOD(set_lg_regionmax, (u_int32_t regionmax), (dbenv, regionmax))
-DBENV_METHOD(get_lk_conflicts, (const u_int8_t **lk_conflictsp, int *lk_maxp),
- (dbenv, lk_conflictsp, lk_maxp))
-DBENV_METHOD(set_lk_conflicts, (u_int8_t *lk_conflicts, int lk_max),
- (dbenv, lk_conflicts, lk_max))
-DBENV_METHOD(get_lk_detect, (u_int32_t *detectp), (dbenv, detectp))
-DBENV_METHOD(set_lk_detect, (u_int32_t detect), (dbenv, detect))
-DBENV_METHOD(set_lk_max, (u_int32_t max), (dbenv, max))
-DBENV_METHOD(get_lk_max_lockers, (u_int32_t *max_lockersp),
- (dbenv, max_lockersp))
-DBENV_METHOD(set_lk_max_lockers, (u_int32_t max_lockers), (dbenv, max_lockers))
-DBENV_METHOD(get_lk_max_locks, (u_int32_t *max_locksp), (dbenv, max_locksp))
-DBENV_METHOD(set_lk_max_locks, (u_int32_t max_locks), (dbenv, max_locks))
-DBENV_METHOD(get_lk_max_objects, (u_int32_t *max_objectsp),
- (dbenv, max_objectsp))
-DBENV_METHOD(set_lk_max_objects, (u_int32_t max_objects), (dbenv, max_objects))
-DBENV_METHOD(get_mp_max_openfd, (int *maxopenfdp), (dbenv, maxopenfdp))
-DBENV_METHOD(set_mp_max_openfd, (int maxopenfd), (dbenv, maxopenfd))
-DBENV_METHOD(get_mp_max_write, (int *maxwritep, int *maxwrite_sleepp), (dbenv, maxwritep, maxwrite_sleepp))
-DBENV_METHOD(set_mp_max_write, (int maxwrite, int maxwrite_sleep), (dbenv, maxwrite, maxwrite_sleep))
-DBENV_METHOD(get_mp_mmapsize, (size_t *mmapsizep), (dbenv, mmapsizep))
-DBENV_METHOD(set_mp_mmapsize, (size_t mmapsize), (dbenv, mmapsize))
-DBENV_METHOD_VOID(get_msgfile, (FILE **msgfilep), (dbenv, msgfilep))
-DBENV_METHOD_VOID(set_msgfile, (FILE *msgfile), (dbenv, msgfile))
-DBENV_METHOD(get_tmp_dir, (const char **tmp_dirp), (dbenv, tmp_dirp))
-DBENV_METHOD(set_tmp_dir, (const char *tmp_dir), (dbenv, tmp_dir))
-DBENV_METHOD(get_tx_max, (u_int32_t *tx_maxp), (dbenv, tx_maxp))
-DBENV_METHOD(set_tx_max, (u_int32_t tx_max), (dbenv, tx_max))
-
-DBENV_METHOD(stat_print, (u_int32_t flags), (dbenv, flags))
-
-DBENV_METHOD_QUIET(set_alloc,
- (db_malloc_fcn_type malloc_fcn, db_realloc_fcn_type realloc_fcn,
- db_free_fcn_type free_fcn),
- (dbenv, malloc_fcn, realloc_fcn, free_fcn))
-
-void DbEnv::set_app_private(void *value)
-{
- unwrap(this)->app_private = value;
-}
-
-DBENV_METHOD(get_cachesize,
- (u_int32_t *gbytesp, u_int32_t *bytesp, int *ncachep),
- (dbenv, gbytesp, bytesp, ncachep))
-DBENV_METHOD(set_cachesize,
- (u_int32_t gbytes, u_int32_t bytes, int ncache),
- (dbenv, gbytes, bytes, ncache))
-
-void DbEnv::set_errcall(void (*arg)(const DbEnv *, const char *, const char *))
-{
- DB_ENV *dbenv = unwrap(this);
-
- error_callback_ = arg;
- error_stream_ = 0;
-
- dbenv->set_errcall(dbenv, (arg == 0) ? 0 :
- _stream_error_function_c);
-}
-
-__DB_STD(ostream) *DbEnv::get_error_stream()
-{
- return (error_stream_);
-}
-
-void DbEnv::set_error_stream(__DB_STD(ostream) *stream)
-{
- DB_ENV *dbenv = unwrap(this);
-
- error_stream_ = stream;
- error_callback_ = 0;
-
- dbenv->set_errcall(dbenv, (stream == 0) ? 0 :
- _stream_error_function_c);
-}
-
-int DbEnv::set_feedback(void (*arg)(DbEnv *, int, int))
-{
- DB_ENV *dbenv = unwrap(this);
-
- feedback_callback_ = arg;
-
- return (dbenv->set_feedback(dbenv,
- arg == 0 ? 0 : _feedback_intercept_c));
-}
-
-DBENV_METHOD(get_flags, (u_int32_t *flagsp), (dbenv, flagsp))
-DBENV_METHOD(set_flags, (u_int32_t flags, int onoff), (dbenv, flags, onoff))
-
-void DbEnv::set_msgcall(void (*arg)(const DbEnv *, const char *))
-{
- DB_ENV *dbenv = unwrap(this);
-
- message_callback_ = arg;
- message_stream_ = 0;
-
- dbenv->set_msgcall(dbenv, (arg == 0) ? 0 :
- _stream_message_function_c);
-}
-
-__DB_STD(ostream) *DbEnv::get_message_stream()
-{
- return (message_stream_);
-}
-
-void DbEnv::set_message_stream(__DB_STD(ostream) *stream)
-{
- DB_ENV *dbenv = unwrap(this);
-
- message_stream_ = stream;
- message_callback_ = 0;
-
- dbenv->set_msgcall(dbenv, (stream == 0) ? 0 :
- _stream_message_function_c);
-}
-
-int DbEnv::set_paniccall(void (*arg)(DbEnv *, int))
-{
- DB_ENV *dbenv = unwrap(this);
-
- paniccall_callback_ = arg;
-
- return (dbenv->set_paniccall(dbenv,
- arg == 0 ? 0 : _paniccall_intercept_c));
-}
-
-DBENV_METHOD(set_rpc_server,
- (void *cl, char *host, long tsec, long ssec, u_int32_t flags),
- (dbenv, cl, host, tsec, ssec, flags))
-DBENV_METHOD(get_shm_key, (long *shm_keyp), (dbenv, shm_keyp))
-DBENV_METHOD(set_shm_key, (long shm_key), (dbenv, shm_key))
-
-int DbEnv::set_app_dispatch
- (int (*arg)(DbEnv *, Dbt *, DbLsn *, db_recops))
-{
- DB_ENV *dbenv = unwrap(this);
- int ret;
-
- app_dispatch_callback_ = arg;
- if ((ret = dbenv->set_app_dispatch(dbenv,
- arg == 0 ? 0 : _app_dispatch_intercept_c)) != 0)
- DB_ERROR(this, "DbEnv::set_app_dispatch", ret, error_policy());
-
- return (ret);
-}
-
-int DbEnv::set_isalive
- (int (*arg)(DbEnv *, pid_t, db_threadid_t))
-{
- DB_ENV *dbenv = unwrap(this);
- int ret;
-
- isalive_callback_ = arg;
- if ((ret = dbenv->set_isalive(dbenv,
- arg == 0 ? 0 : _isalive_intercept_c)) != 0)
- DB_ERROR(this, "DbEnv::set_isalive", ret, error_policy());
-
- return (ret);
-}
-
-DBENV_METHOD(get_tx_timestamp, (time_t *timestamp), (dbenv, timestamp))
-DBENV_METHOD(set_tx_timestamp, (time_t *timestamp), (dbenv, timestamp))
-DBENV_METHOD(get_verbose, (u_int32_t which, int *onoffp),
- (dbenv, which, onoffp))
-DBENV_METHOD(set_verbose, (u_int32_t which, int onoff), (dbenv, which, onoff))
-
-DBENV_METHOD(mutex_alloc,
- (u_int32_t flags, db_mutex_t *mutexp), (dbenv, flags, mutexp))
-DBENV_METHOD(mutex_free, (db_mutex_t mutex), (dbenv, mutex))
-DBENV_METHOD(mutex_get_align, (u_int32_t *argp), (dbenv, argp))
-DBENV_METHOD(mutex_get_increment, (u_int32_t *argp), (dbenv, argp))
-DBENV_METHOD(mutex_get_max, (u_int32_t *argp), (dbenv, argp))
-DBENV_METHOD(mutex_get_tas_spins, (u_int32_t *argp), (dbenv, argp))
-DBENV_METHOD(mutex_lock, (db_mutex_t mutex), (dbenv, mutex))
-DBENV_METHOD(mutex_set_align, (u_int32_t arg), (dbenv, arg))
-DBENV_METHOD(mutex_set_increment, (u_int32_t arg), (dbenv, arg))
-DBENV_METHOD(mutex_set_max, (u_int32_t arg), (dbenv, arg))
-DBENV_METHOD(mutex_set_tas_spins, (u_int32_t arg), (dbenv, arg))
-DBENV_METHOD(mutex_stat,
- (DB_MUTEX_STAT **statp, u_int32_t flags), (dbenv, statp, flags))
-DBENV_METHOD(mutex_stat_print, (u_int32_t flags), (dbenv, flags))
-DBENV_METHOD(mutex_unlock, (db_mutex_t mutex), (dbenv, mutex))
-
-int DbEnv::set_thread_id(void (*arg)(DbEnv *, pid_t *, db_threadid_t *))
-{
- DB_ENV *dbenv = unwrap(this);
- int ret;
-
- thread_id_callback_ = arg;
- if ((ret = dbenv->set_thread_id(dbenv,
- arg == 0 ? 0 : _thread_id_intercept_c)) != 0)
- DB_ERROR(this, "DbEnv::set_thread_id", ret, error_policy());
-
- return (ret);
-}
-
-int DbEnv::set_thread_id_string(
- char *(*arg)(DbEnv *, pid_t, db_threadid_t, char *))
-{
- DB_ENV *dbenv = unwrap(this);
- int ret;
-
- thread_id_string_callback_ = arg;
- if ((ret = dbenv->set_thread_id_string(dbenv,
- arg == 0 ? 0 : _thread_id_string_intercept_c)) != 0)
- DB_ERROR(this, "DbEnv::set_thread_id_string", ret,
- error_policy());
-
- return (ret);
-}
-
-int DbEnv::txn_begin(DbTxn *pid, DbTxn **tid, u_int32_t flags)
-{
- DB_ENV *env = unwrap(this);
- DB_TXN *txn;
- int ret;
-
- ret = env->txn_begin(env, unwrap(pid), &txn, flags);
- if (DB_RETOK_STD(ret))
- *tid = new DbTxn(txn);
- else
- DB_ERROR(this, "DbEnv::txn_begin", ret, error_policy());
-
- return (ret);
-}
-
-DBENV_METHOD(txn_checkpoint, (u_int32_t kbyte, u_int32_t min, u_int32_t flags),
- (dbenv, kbyte, min, flags))
-
-int DbEnv::txn_recover(DbPreplist *preplist, long count,
- long *retp, u_int32_t flags)
-{
- DB_ENV *dbenv = unwrap(this);
- DB_PREPLIST *c_preplist;
- long i;
- int ret;
-
- /*
- * We need to allocate some local storage for the
- * returned preplist, and that requires us to do
- * our own argument validation.
- */
- if (count <= 0)
- ret = EINVAL;
- else
- ret = __os_malloc(dbenv, sizeof(DB_PREPLIST) * count,
- &c_preplist);
-
- if (ret != 0) {
- DB_ERROR(this, "DbEnv::txn_recover", ret, error_policy());
- return (ret);
- }
-
- if ((ret =
- dbenv->txn_recover(dbenv, c_preplist, count, retp, flags)) != 0) {
- __os_free(dbenv, c_preplist);
- DB_ERROR(this, "DbEnv::txn_recover", ret, error_policy());
- return (ret);
- }
-
- for (i = 0; i < *retp; i++) {
- preplist[i].txn = new DbTxn();
- preplist[i].txn->imp_ = c_preplist[i].txn;
- memcpy(preplist[i].gid, c_preplist[i].gid,
- sizeof(preplist[i].gid));
- }
-
- __os_free(dbenv, c_preplist);
-
- return (0);
-}
-
-DBENV_METHOD(txn_stat, (DB_TXN_STAT **statp, u_int32_t flags),
- (dbenv, statp, flags))
-DBENV_METHOD(txn_stat_print, (u_int32_t flags), (dbenv, flags))
-
-int DbEnv::set_rep_transport(int myid,
- int (*arg)(DbEnv *, const Dbt *, const Dbt *, const DbLsn *, int, u_int32_t))
-{
- DB_ENV *dbenv = unwrap(this);
- int ret;
-
- rep_send_callback_ = arg;
- if ((ret = dbenv->set_rep_transport(dbenv, myid,
- arg == 0 ? 0 : _rep_send_intercept_c)) != 0)
- DB_ERROR(this, "DbEnv::set_rep_transport", ret, error_policy());
-
- return (ret);
-}
-
-DBENV_METHOD(rep_elect,
- (int nsites,
- int nvotes, int priority, u_int32_t timeout, int *eidp, u_int32_t flags),
- (dbenv, nsites, nvotes, priority, timeout, eidp, flags))
-DBENV_METHOD(rep_flush, (), (dbenv))
-DBENV_METHOD(rep_get_config, (u_int32_t which, int *onoffp),
- (dbenv, which, onoffp))
-DBENV_METHOD(set_rep_request, (u_int32_t min, u_int32_t max), (dbenv, min, max))
-
-int DbEnv::rep_process_message(Dbt *control,
- Dbt *rec, int *idp, DbLsn *ret_lsnp)
-{
- DB_ENV *dbenv = unwrap(this);
- int ret;
-
- ret = dbenv->rep_process_message(dbenv, control, rec, idp, ret_lsnp);
- if (!DB_RETOK_REPPMSG(ret))
- DB_ERROR(this, "DbEnv::rep_process_message", ret,
- error_policy());
-
- return (ret);
-}
-
-DBENV_METHOD(rep_set_config,
- (u_int32_t which, int onoff), (dbenv, which, onoff))
-DBENV_METHOD(rep_start,
- (Dbt *cookie, u_int32_t flags),
- (dbenv, (DBT *)cookie, flags))
-
-DBENV_METHOD(rep_stat, (DB_REP_STAT **statp, u_int32_t flags),
- (dbenv, statp, flags))
-DBENV_METHOD(rep_stat_print, (u_int32_t flags), (dbenv, flags))
-DBENV_METHOD(rep_sync, (u_int32_t flags), (dbenv, flags))
-
-DBENV_METHOD(get_rep_limit, (u_int32_t *gbytesp, u_int32_t *bytesp),
- (dbenv, gbytesp, bytesp))
-DBENV_METHOD(set_rep_limit, (u_int32_t gbytes, u_int32_t bytes),
- (dbenv, gbytes, bytes))
-
-DBENV_METHOD(get_timeout,
- (db_timeout_t *timeoutp, u_int32_t flags),
- (dbenv, timeoutp, flags))
-DBENV_METHOD(set_timeout,
- (db_timeout_t timeout, u_int32_t flags),
- (dbenv, timeout, flags))
-
-// static method
-char *DbEnv::version(int *major, int *minor, int *patch)
-{
- return (db_version(major, minor, patch));
-}
-
-// static method
-DbEnv *DbEnv::wrap_DB_ENV(DB_ENV *dbenv)
-{
- DbEnv *wrapped_env = get_DbEnv(dbenv);
- return (wrapped_env != NULL) ? wrapped_env : new DbEnv(dbenv, 0);
-}
diff --git a/storage/bdb/cxx/cxx_except.cpp b/storage/bdb/cxx/cxx_except.cpp
deleted file mode 100644
index b0bf7c0690e..00000000000
--- a/storage/bdb/cxx/cxx_except.cpp
+++ /dev/null
@@ -1,354 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: cxx_except.cpp,v 12.2 2005/10/14 12:20:04 mjc Exp $
- */
-
-#include "db_config.h"
-
-#include
-#include
-
-#include "db_cxx.h"
-#include "dbinc/cxx_int.h"
-
-// Note: would not be needed if we can inherit from exception
-// It does not appear to be possible to inherit from exception
-// with the current Microsoft library (VC5.0).
-//
-static char *dupString(const char *s)
-{
- char *r = new char[strlen(s)+1];
- strcpy(r, s);
- return (r);
-}
-
-////////////////////////////////////////////////////////////////////////
-// //
-// DbException //
-// //
-////////////////////////////////////////////////////////////////////////
-
-DbException::~DbException() throw()
-{
- delete [] what_;
-}
-
-DbException::DbException(int err)
-: err_(err)
-, env_(0)
-{
- describe(0, 0);
-}
-
-DbException::DbException(const char *description)
-: err_(0)
-, env_(0)
-{
- describe(0, description);
-}
-
-DbException::DbException(const char *description, int err)
-: err_(err)
-, env_(0)
-{
- describe(0, description);
-}
-
-DbException::DbException(const char *prefix, const char *description, int err)
-: err_(err)
-, env_(0)
-{
- describe(prefix, description);
-}
-
-DbException::DbException(const DbException &that)
-: __DB_STD(exception)()
-, what_(dupString(that.what_))
-, err_(that.err_)
-, env_(0)
-{
-}
-
-DbException &DbException::operator = (const DbException &that)
-{
- if (this != &that) {
- err_ = that.err_;
- delete [] what_;
- what_ = dupString(that.what_);
- }
- return (*this);
-}
-
-void DbException::describe(const char *prefix, const char *description)
-{
- char msgbuf[1024], *p, *end;
-
- p = msgbuf;
- end = msgbuf + sizeof(msgbuf) - 1;
-
- if (prefix != NULL) {
- strncpy(p, prefix, (p < end) ? end - p: 0);
- p += strlen(prefix);
- strncpy(p, ": ", (p < end) ? end - p: 0);
- p += 2;
- }
- if (description != NULL) {
- strncpy(p, description, (p < end) ? end - p: 0);
- p += strlen(description);
- if (err_ != 0) {
- strncpy(p, ": ", (p < end) ? end - p: 0);
- p += 2;
- }
- }
- if (err_ != 0) {
- strncpy(p, db_strerror(err_), (p < end) ? end - p: 0);
- p += strlen(db_strerror(err_));
- }
-
- /*
- * If the result was too long, the buffer will not be null-terminated,
- * so we need to fix that here before duplicating it.
- */
- if (p >= end)
- *end = '\0';
-
- what_ = dupString(msgbuf);
-}
-
-int DbException::get_errno() const
-{
- return (err_);
-}
-
-const char *DbException::what() const throw()
-{
- return (what_);
-}
-
-DbEnv *DbException::get_env() const
-{
- return env_;
-}
-
-void DbException::set_env(DbEnv *env)
-{
- env_= env;
-}
-
-////////////////////////////////////////////////////////////////////////
-// //
-// DbMemoryException //
-// //
-////////////////////////////////////////////////////////////////////////
-
-static const char *memory_err_desc = "Dbt not large enough for available data";
-DbMemoryException::~DbMemoryException() throw()
-{
-}
-
-DbMemoryException::DbMemoryException(Dbt *dbt)
-: DbException(memory_err_desc, ENOMEM)
-, dbt_(dbt)
-{
-}
-
-DbMemoryException::DbMemoryException(const char *prefix, Dbt *dbt)
-: DbException(prefix, memory_err_desc, ENOMEM)
-, dbt_(dbt)
-{
-}
-
-DbMemoryException::DbMemoryException(const DbMemoryException &that)
-: DbException(that)
-, dbt_(that.dbt_)
-{
-}
-
-DbMemoryException
-&DbMemoryException::operator =(const DbMemoryException &that)
-{
- if (this != &that) {
- DbException::operator=(that);
- dbt_ = that.dbt_;
- }
- return (*this);
-}
-
-Dbt *DbMemoryException::get_dbt() const
-{
- return (dbt_);
-}
-
-////////////////////////////////////////////////////////////////////////
-// //
-// DbDeadlockException //
-// //
-////////////////////////////////////////////////////////////////////////
-
-DbDeadlockException::~DbDeadlockException() throw()
-{
-}
-
-DbDeadlockException::DbDeadlockException(const char *description)
-: DbException(description, DB_LOCK_DEADLOCK)
-{
-}
-
-DbDeadlockException::DbDeadlockException(const DbDeadlockException &that)
-: DbException(that)
-{
-}
-
-DbDeadlockException
-&DbDeadlockException::operator =(const DbDeadlockException &that)
-{
- if (this != &that)
- DbException::operator=(that);
- return (*this);
-}
-
-////////////////////////////////////////////////////////////////////////
-// //
-// DbLockNotGrantedException //
-// //
-////////////////////////////////////////////////////////////////////////
-
-DbLockNotGrantedException::~DbLockNotGrantedException() throw()
-{
- delete lock_;
-}
-
-DbLockNotGrantedException::DbLockNotGrantedException(const char *prefix,
- db_lockop_t op, db_lockmode_t mode, const Dbt *obj, const DbLock lock,
- int index)
-: DbException(prefix, DbEnv::strerror(DB_LOCK_NOTGRANTED),
- DB_LOCK_NOTGRANTED)
-, op_(op)
-, mode_(mode)
-, obj_(obj)
-, lock_(new DbLock(lock))
-, index_(index)
-{
-}
-
-DbLockNotGrantedException::DbLockNotGrantedException(const char *description)
-: DbException(description, DB_LOCK_NOTGRANTED)
-, op_(DB_LOCK_GET)
-, mode_(DB_LOCK_NG)
-, obj_(NULL)
-, lock_(NULL)
-, index_(0)
-{
-}
-
-DbLockNotGrantedException::DbLockNotGrantedException
- (const DbLockNotGrantedException &that)
-: DbException(that)
-{
- op_ = that.op_;
- mode_ = that.mode_;
- obj_ = that.obj_;
- lock_ = (that.lock_ != NULL) ? new DbLock(*that.lock_) : NULL;
- index_ = that.index_;
-}
-
-DbLockNotGrantedException
-&DbLockNotGrantedException::operator =(const DbLockNotGrantedException &that)
-{
- if (this != &that) {
- DbException::operator=(that);
- op_ = that.op_;
- mode_ = that.mode_;
- obj_ = that.obj_;
- lock_ = (that.lock_ != NULL) ? new DbLock(*that.lock_) : NULL;
- index_ = that.index_;
- }
- return (*this);
-}
-
-db_lockop_t DbLockNotGrantedException::get_op() const
-{
- return op_;
-}
-
-db_lockmode_t DbLockNotGrantedException::get_mode() const
-{
- return mode_;
-}
-
-const Dbt* DbLockNotGrantedException::get_obj() const
-{
- return obj_;
-}
-
-DbLock* DbLockNotGrantedException::get_lock() const
-{
- return lock_;
-}
-
-int DbLockNotGrantedException::get_index() const
-{
- return index_;
-}
-
-////////////////////////////////////////////////////////////////////////
-// //
-// DbRepHandleDeadException //
-// //
-////////////////////////////////////////////////////////////////////////
-
-DbRepHandleDeadException::~DbRepHandleDeadException() throw()
-{
-}
-
-DbRepHandleDeadException::DbRepHandleDeadException(const char *description)
-: DbException(description, DB_REP_HANDLE_DEAD)
-{
-}
-
-DbRepHandleDeadException::DbRepHandleDeadException
- (const DbRepHandleDeadException &that)
-: DbException(that)
-{
-}
-
-DbRepHandleDeadException
-&DbRepHandleDeadException::operator =(const DbRepHandleDeadException &that)
-{
- if (this != &that)
- DbException::operator=(that);
- return (*this);
-}
-
-////////////////////////////////////////////////////////////////////////
-// //
-// DbRunRecoveryException //
-// //
-////////////////////////////////////////////////////////////////////////
-
-DbRunRecoveryException::~DbRunRecoveryException() throw()
-{
-}
-
-DbRunRecoveryException::DbRunRecoveryException(const char *description)
-: DbException(description, DB_RUNRECOVERY)
-{
-}
-
-DbRunRecoveryException::DbRunRecoveryException
- (const DbRunRecoveryException &that)
-: DbException(that)
-{
-}
-
-DbRunRecoveryException
-&DbRunRecoveryException::operator =(const DbRunRecoveryException &that)
-{
- if (this != &that)
- DbException::operator=(that);
- return (*this);
-}
diff --git a/storage/bdb/cxx/cxx_lock.cpp b/storage/bdb/cxx/cxx_lock.cpp
deleted file mode 100644
index 47f27ae3504..00000000000
--- a/storage/bdb/cxx/cxx_lock.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: cxx_lock.cpp,v 12.1 2005/06/16 20:20:59 bostic Exp $
- */
-
-#include "db_config.h"
-
-#include
-#include
-
-#include "db_cxx.h"
-#include "dbinc/cxx_int.h"
-
-////////////////////////////////////////////////////////////////////////
-// //
-// DbLock //
-// //
-////////////////////////////////////////////////////////////////////////
-
-DbLock::DbLock(DB_LOCK value)
-: lock_(value)
-{
-}
-
-DbLock::DbLock()
-{
- memset(&lock_, 0, sizeof(DB_LOCK));
-}
-
-DbLock::DbLock(const DbLock &that)
-: lock_(that.lock_)
-{
-}
-
-DbLock &DbLock::operator = (const DbLock &that)
-{
- lock_ = that.lock_;
- return (*this);
-}
diff --git a/storage/bdb/cxx/cxx_logc.cpp b/storage/bdb/cxx/cxx_logc.cpp
deleted file mode 100644
index 63d7fd9fe17..00000000000
--- a/storage/bdb/cxx/cxx_logc.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: cxx_logc.cpp,v 12.1 2005/06/16 20:21:00 bostic Exp $
- */
-
-#include "db_config.h"
-
-#include
-#include
-
-#include "db_cxx.h"
-#include "dbinc/cxx_int.h"
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc_auto/db_auto.h"
-#include "dbinc_auto/crdel_auto.h"
-#include "dbinc/db_dispatch.h"
-#include "dbinc_auto/db_ext.h"
-#include "dbinc_auto/common_ext.h"
-
-// It's private, and should never be called,
-// but some compilers need it resolved
-//
-DbLogc::~DbLogc()
-{
-}
-
-// The name _flags prevents a name clash with __db_log_cursor::flags
-int DbLogc::close(u_int32_t _flags)
-{
- DB_LOGC *logc = this;
- int ret;
- DbEnv *dbenv2 = DbEnv::get_DbEnv(logc->dbenv);
-
- ret = logc->close(logc, _flags);
-
- if (!DB_RETOK_STD(ret))
- DB_ERROR(dbenv2, "DbLogc::close", ret, ON_ERROR_UNKNOWN);
-
- return (ret);
-}
-
-// The name _flags prevents a name clash with __db_log_cursor::flags
-int DbLogc::get(DbLsn *lsn, Dbt *data, u_int32_t _flags)
-{
- DB_LOGC *logc = this;
- int ret;
-
- ret = logc->get(logc, lsn, data, _flags);
-
- if (!DB_RETOK_LGGET(ret)) {
- if (ret == DB_BUFFER_SMALL)
- DB_ERROR_DBT(DbEnv::get_DbEnv(logc->dbenv),
- "DbLogc::get", data, ON_ERROR_UNKNOWN);
- else
- DB_ERROR(DbEnv::get_DbEnv(logc->dbenv),
- "DbLogc::get", ret, ON_ERROR_UNKNOWN);
- }
-
- return (ret);
-}
diff --git a/storage/bdb/cxx/cxx_mpool.cpp b/storage/bdb/cxx/cxx_mpool.cpp
deleted file mode 100644
index 475a18b3e3f..00000000000
--- a/storage/bdb/cxx/cxx_mpool.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: cxx_mpool.cpp,v 12.1 2005/06/16 20:21:02 bostic Exp $
- */
-
-#include "db_config.h"
-
-#include
-
-#include "db_cxx.h"
-#include "dbinc/cxx_int.h"
-
-#include "db_int.h"
-
-// Helper macros for simple methods that pass through to the
-// underlying C method. It may return an error or raise an exception.
-// Note this macro expects that input _argspec is an argument
-// list element (e.g., "char *arg") and that _arglist is the arguments
-// that should be passed through to the C method (e.g., "(mpf, arg)")
-//
-#define DB_MPOOLFILE_METHOD(_name, _argspec, _arglist, _retok) \
-int DbMpoolFile::_name _argspec \
-{ \
- int ret; \
- DB_MPOOLFILE *mpf = unwrap(this); \
- \
- if (mpf == NULL) \
- ret = EINVAL; \
- else \
- ret = mpf->_name _arglist; \
- if (!_retok(ret)) \
- DB_ERROR(DbEnv::get_DbEnv(mpf->dbenv), \
- "DbMpoolFile::"#_name, ret, ON_ERROR_UNKNOWN); \
- return (ret); \
-}
-
-#define DB_MPOOLFILE_METHOD_VOID(_name, _argspec, _arglist) \
-void DbMpoolFile::_name _argspec \
-{ \
- DB_MPOOLFILE *mpf = unwrap(this); \
- \
- mpf->_name _arglist; \
-}
-
-////////////////////////////////////////////////////////////////////////
-// //
-// DbMpoolFile //
-// //
-////////////////////////////////////////////////////////////////////////
-
-DbMpoolFile::DbMpoolFile()
-: imp_(0)
-{
-}
-
-DbMpoolFile::~DbMpoolFile()
-{
-}
-
-int DbMpoolFile::close(u_int32_t flags)
-{
- DB_MPOOLFILE *mpf = unwrap(this);
- int ret;
- DbEnv *dbenv = DbEnv::get_DbEnv(mpf->dbenv);
-
- if (mpf == NULL)
- ret = EINVAL;
- else
- ret = mpf->close(mpf, flags);
-
- imp_ = 0; // extra safety
-
- // This may seem weird, but is legal as long as we don't access
- // any data before returning.
- delete this;
-
- if (!DB_RETOK_STD(ret))
- DB_ERROR(dbenv, "DbMpoolFile::close", ret, ON_ERROR_UNKNOWN);
-
- return (ret);
-}
-
-DB_MPOOLFILE_METHOD(get, (db_pgno_t *pgnoaddr, u_int32_t flags, void *pagep),
- (mpf, pgnoaddr, flags, pagep), DB_RETOK_MPGET)
-DB_MPOOLFILE_METHOD(open,
- (const char *file, u_int32_t flags, int mode, size_t pagesize),
- (mpf, file, flags, mode, pagesize), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(put, (void *pgaddr, u_int32_t flags),
- (mpf, pgaddr, flags), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(set, (void *pgaddr, u_int32_t flags),
- (mpf, pgaddr, flags), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(get_clear_len, (u_int32_t *lenp),
- (mpf, lenp), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(set_clear_len, (u_int32_t len),
- (mpf, len), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(get_fileid, (u_int8_t *fileid),
- (mpf, fileid), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(set_fileid, (u_int8_t *fileid),
- (mpf, fileid), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(get_flags, (u_int32_t *flagsp),
- (mpf, flagsp), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(set_flags, (u_int32_t flags, int onoff),
- (mpf, flags, onoff), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(get_ftype, (int *ftypep),
- (mpf, ftypep), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(set_ftype, (int ftype),
- (mpf, ftype), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(get_lsn_offset, (int32_t *offsetp),
- (mpf, offsetp), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(set_lsn_offset, (int32_t offset),
- (mpf, offset), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(get_maxsize, (u_int32_t *gbytesp, u_int32_t *bytesp),
- (mpf, gbytesp, bytesp), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(set_maxsize, (u_int32_t gbytes, u_int32_t bytes),
- (mpf, gbytes, bytes), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(get_pgcookie, (DBT *dbt),
- (mpf, dbt), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(set_pgcookie, (DBT *dbt),
- (mpf, dbt), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(get_priority, (DB_CACHE_PRIORITY *priorityp),
- (mpf, priorityp), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(set_priority, (DB_CACHE_PRIORITY priority),
- (mpf, priority), DB_RETOK_STD)
-DB_MPOOLFILE_METHOD(sync, (),
- (mpf), DB_RETOK_STD)
diff --git a/storage/bdb/cxx/cxx_multi.cpp b/storage/bdb/cxx/cxx_multi.cpp
deleted file mode 100644
index ca80bbafbc4..00000000000
--- a/storage/bdb/cxx/cxx_multi.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: cxx_multi.cpp,v 12.3 2005/09/30 07:40:20 mjc Exp $
- */
-
-#include "db_config.h"
-
-#include "db_cxx.h"
-
-DbMultipleIterator::DbMultipleIterator(const Dbt &dbt)
- : data_((u_int8_t*)dbt.get_data()),
- p_((u_int32_t*)(data_ + dbt.get_size() - sizeof(u_int32_t)))
-{
-}
-
-bool DbMultipleDataIterator::next(Dbt &data)
-{
- if (*p_ == (u_int32_t)-1) {
- data.set_data(0);
- data.set_size(0);
- p_ = 0;
- } else {
- data.set_data(data_ + *p_--);
- data.set_size(*p_--);
- if (data.get_size() == 0 && data.get_data() == data_)
- data.set_data(0);
- }
- return (p_ != 0);
-}
-
-bool DbMultipleKeyDataIterator::next(Dbt &key, Dbt &data)
-{
- if (*p_ == (u_int32_t)-1) {
- key.set_data(0);
- key.set_size(0);
- data.set_data(0);
- data.set_size(0);
- p_ = 0;
- } else {
- key.set_data(data_ + *p_--);
- key.set_size(*p_--);
- data.set_data(data_ + *p_--);
- data.set_size(*p_--);
- }
- return (p_ != 0);
-}
-
-bool DbMultipleRecnoDataIterator::next(db_recno_t &recno, Dbt &data)
-{
- if (*p_ == (u_int32_t)0) {
- recno = 0;
- data.set_data(0);
- data.set_size(0);
- p_ = 0;
- } else {
- recno = *p_--;
- data.set_data(data_ + *p_--);
- data.set_size(*p_--);
- }
- return (p_ != 0);
-}
diff --git a/storage/bdb/cxx/cxx_seq.cpp b/storage/bdb/cxx/cxx_seq.cpp
deleted file mode 100644
index ed8997f0340..00000000000
--- a/storage/bdb/cxx/cxx_seq.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: cxx_seq.cpp,v 12.2 2005/10/13 20:49:47 bostic Exp $
- */
-
-#include "db_config.h"
-
-#include
-#include
-
-#include "db_cxx.h"
-#include "dbinc/cxx_int.h"
-
-#include "db_int.h"
-
-// Helper macro for simple methods that pass through to the
-// underlying C method. It may return an error or raise an exception.
-// Note this macro expects that input _argspec is an argument
-// list element (e.g., "char *arg") and that _arglist is the arguments
-// that should be passed through to the C method (e.g., "(db, arg)")
-//
-#define DBSEQ_METHOD(_name, _argspec, _arglist, _destructor) \
-int DbSequence::_name _argspec \
-{ \
- int ret; \
- DB_SEQUENCE *seq = unwrap(this); \
- DbEnv *dbenv = DbEnv::get_DbEnv(seq->seq_dbp->dbenv); \
- \
- ret = seq->_name _arglist; \
- if (_destructor) \
- imp_ = 0; \
- if (!DB_RETOK_STD(ret)) \
- DB_ERROR(dbenv, \
- "DbSequence::" # _name, ret, ON_ERROR_UNKNOWN); \
- return (ret); \
-}
-
-DbSequence::DbSequence(Db *db, u_int32_t flags)
-: imp_(0)
-{
- DB_SEQUENCE *seq;
- int ret;
-
- if ((ret = db_sequence_create(&seq, unwrap(db), flags)) != 0)
- DB_ERROR(db->get_env(), "DbSequence::DbSequence", ret,
- ON_ERROR_UNKNOWN);
- else {
- imp_ = seq;
- seq->api_internal = this;
- }
-}
-
-DbSequence::DbSequence(DB_SEQUENCE *seq)
-: imp_(seq)
-{
- seq->api_internal = this;
-}
-
-DbSequence::~DbSequence()
-{
- DB_SEQUENCE *seq;
-
- seq = unwrap(this);
- if (seq != NULL)
- (void)seq->close(seq, 0);
-}
-
-DBSEQ_METHOD(open, (DbTxn *txnid, Dbt *key, u_int32_t flags),
- (seq, unwrap(txnid), key, flags), 0)
-DBSEQ_METHOD(initial_value, (db_seq_t value), (seq, value), 0)
-DBSEQ_METHOD(close, (u_int32_t flags), (seq, flags), 1)
-DBSEQ_METHOD(remove, (DbTxn *txnid, u_int32_t flags),
- (seq, unwrap(txnid), flags), 1)
-DBSEQ_METHOD(stat, (DB_SEQUENCE_STAT **sp, u_int32_t flags),
- (seq, sp, flags), 0)
-DBSEQ_METHOD(stat_print, (u_int32_t flags), (seq, flags), 0)
-
-DBSEQ_METHOD(get,
- (DbTxn *txnid, int32_t delta, db_seq_t *retp, u_int32_t flags),
- (seq, unwrap(txnid), delta, retp, flags), 0)
-DBSEQ_METHOD(get_cachesize, (int32_t *sizep), (seq, sizep), 0)
-DBSEQ_METHOD(set_cachesize, (int32_t size), (seq, size), 0)
-DBSEQ_METHOD(get_flags, (u_int32_t *flagsp), (seq, flagsp), 0)
-DBSEQ_METHOD(set_flags, (u_int32_t flags), (seq, flags), 0)
-DBSEQ_METHOD(get_range, (db_seq_t *minp, db_seq_t *maxp), (seq, minp, maxp), 0)
-DBSEQ_METHOD(set_range, (db_seq_t min, db_seq_t max), (seq, min, max), 0)
-
-Db *DbSequence::get_db()
-{
- DB_SEQUENCE *seq = unwrap(this);
- DB *db;
- (void)seq->get_db(seq, &db);
- return Db::get_Db(db);
-}
-
-Dbt *DbSequence::get_key()
-{
- DB_SEQUENCE *seq = unwrap(this);
- memset(&key_, 0, sizeof (DBT));
- (void)seq->get_key(seq, &key_);
- return Dbt::get_Dbt(&key_);
-}
-
-// static method
-DbSequence *DbSequence::wrap_DB_SEQUENCE(DB_SEQUENCE *seq)
-{
- DbSequence *wrapped_seq = get_DbSequence(seq);
- return (wrapped_seq != NULL) ? wrapped_seq : new DbSequence(seq);
-}
diff --git a/storage/bdb/cxx/cxx_txn.cpp b/storage/bdb/cxx/cxx_txn.cpp
deleted file mode 100644
index 64ee3b9fff5..00000000000
--- a/storage/bdb/cxx/cxx_txn.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: cxx_txn.cpp,v 12.2 2005/06/16 20:21:03 bostic Exp $
- */
-
-#include "db_config.h"
-
-#include
-
-#include "db_cxx.h"
-#include "dbinc/cxx_int.h"
-
-#include "db_int.h"
-#include "dbinc/txn.h"
-
-// Helper macro for simple methods that pass through to the
-// underlying C method. It may return an error or raise an exception.
-// Note this macro expects that input _argspec is an argument
-// list element (e.g., "char *arg") and that _arglist is the arguments
-// that should be passed through to the C method (e.g., "(db, arg)")
-//
-#define DBTXN_METHOD(_name, _delete, _argspec, _arglist) \
-int DbTxn::_name _argspec \
-{ \
- int ret; \
- DB_TXN *txn = unwrap(this); \
- DbEnv *dbenv = DbEnv::get_DbEnv(txn->mgrp->dbenv); \
- \
- ret = txn->_name _arglist; \
- /* Weird, but safe if we don't access this again. */ \
- if (_delete) \
- delete this; \
- if (!DB_RETOK_STD(ret)) \
- DB_ERROR(dbenv, "DbTxn::" # _name, ret, ON_ERROR_UNKNOWN); \
- return (ret); \
-}
-
-// private constructor, never called but needed by some C++ linkers
-DbTxn::DbTxn()
-: imp_(0)
-{
-}
-
-DbTxn::DbTxn(DB_TXN *txn)
-: imp_(txn)
-{
- txn->api_internal = this;
-}
-
-DbTxn::~DbTxn()
-{
-}
-
-DBTXN_METHOD(abort, 1, (), (txn))
-DBTXN_METHOD(commit, 1, (u_int32_t flags), (txn, flags))
-DBTXN_METHOD(discard, 1, (u_int32_t flags), (txn, flags))
-
-u_int32_t DbTxn::id()
-{
- DB_TXN *txn;
-
- txn = unwrap(this);
- return (txn->id(txn)); // no error
-}
-
-DBTXN_METHOD(get_name, 0, (const char **namep), (txn, namep))
-DBTXN_METHOD(prepare, 0, (u_int8_t *gid), (txn, gid))
-DBTXN_METHOD(set_name, 0, (const char *name), (txn, name))
-DBTXN_METHOD(set_timeout, 0, (db_timeout_t timeout, u_int32_t flags),
- (txn, timeout, flags))
-
-// static method
-DbTxn *DbTxn::wrap_DB_TXN(DB_TXN *txn)
-{
- DbTxn *wrapped_txn = get_DbTxn(txn);
- return (wrapped_txn != NULL) ? wrapped_txn : new DbTxn(txn);
-}
diff --git a/storage/bdb/db/crdel.src b/storage/bdb/db/crdel.src
deleted file mode 100644
index ba03fea9312..00000000000
--- a/storage/bdb/db/crdel.src
+++ /dev/null
@@ -1,80 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: crdel.src,v 12.2 2005/09/28 17:44:18 margo Exp $
- */
-
-PREFIX __crdel
-DBPRIVATE
-
-INCLUDE #ifndef NO_SYSTEM_INCLUDES
-INCLUDE #include
-INCLUDE
-INCLUDE #include
-INCLUDE #include
-INCLUDE #endif
-INCLUDE
-INCLUDE #include "db_int.h"
-INCLUDE #include "dbinc/crypto.h"
-INCLUDE #include "dbinc/db_page.h"
-INCLUDE #include "dbinc/db_dispatch.h"
-INCLUDE #include "dbinc/db_am.h"
-INCLUDE #include "dbinc/log.h"
-INCLUDE #include "dbinc/txn.h"
-INCLUDE
-
-/*
- * Metasub: log the creation of a subdatabase meta data page.
- *
- * fileid: identifies the file being acted upon.
- * pgno: page number on which to write this meta-data page
- * page: the actual meta-data page
- * lsn: lsn of the page.
- */
-BEGIN metasub 142
-DB fileid int32_t ld
-ARG pgno db_pgno_t lu
-PGDBT page DBT s
-POINTER lsn DB_LSN * lu
-END
-
-/*
- * Inmem_create: Log the creation of an in-memory database.
- *
- * name: Name of the database
- * fid: File id of the database
- */
-BEGIN inmem_create 138
-ARG fileid int32_t ld
-DBT name DBT s
-DBT fid DBT s
-ARG pgsize u_int32_t lu
-END
-
-/*
- * Inmem_rename: Log the renaming of an in-memory only database.
- *
- * oldname: database's starting name
- * newname: database's ending name
- * fid: fileid
- */
-BEGIN inmem_rename 139
-DBT oldname DBT s
-DBT newname DBT s
-DBT fid DBT s
-END
-
-/*
- * Inmem_remove: Log the removal of an in-memory only database.
- *
- * name: database's ending name
- * fid: fileid
- */
-BEGIN inmem_remove 140
-DBT name DBT s
-DBT fid DBT s
-END
-
diff --git a/storage/bdb/db/crdel_rec.c b/storage/bdb/db/crdel_rec.c
deleted file mode 100644
index a94c6cbbc1f..00000000000
--- a/storage/bdb/db/crdel_rec.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: crdel_rec.c,v 12.6 2005/10/20 18:57:04 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/fop.h"
-#include "dbinc/hash.h"
-#include "dbinc/log.h"
-#include "dbinc/mp.h"
-#include "dbinc/txn.h"
-
-/*
- * __crdel_metasub_recover --
- * Recovery function for metasub.
- *
- * PUBLIC: int __crdel_metasub_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__crdel_metasub_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- __crdel_metasub_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int cmp_p, modified, ret;
-
- pagep = NULL;
- COMPQUIET(info, NULL);
- REC_PRINT(__crdel_metasub_print);
- REC_INTRO(__crdel_metasub_read, 0, 0);
-
- if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- /* If this is an in-memory file, this might be OK. */
- if (F_ISSET(file_dbp, DB_AM_INMEM) && (ret = __memp_fget(mpf,
- &argp->pgno, DB_MPOOL_CREATE, &pagep)) == 0)
- LSN_NOT_LOGGED(LSN(pagep));
- else {
- *lsnp = argp->prev_lsn;
- ret = 0;
- goto out;
- }
- }
-
- modified = 0;
- cmp_p = log_compare(&LSN(pagep), &argp->lsn);
- CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn);
-
- if (cmp_p == 0 && DB_REDO(op)) {
- memcpy(pagep, argp->page.data, argp->page.size);
- LSN(pagep) = *lsnp;
- modified = 1;
-
- /*
- * If this was an in-memory database and we are re-creating
- * and this is the meta-data page, then we need to set up a
- * bunch of fields in the dbo as well.
- */
- if (F_ISSET(file_dbp, DB_AM_INMEM) &&
- argp->pgno == PGNO_BASE_MD &&
- (ret = __db_meta_setup(file_dbp->dbenv,
- file_dbp, file_dbp->dname, (DBMETA *)pagep, 0, 1)) != 0)
- goto out;
- } else if (DB_UNDO(op)) {
- /*
- * We want to undo this page creation. The page creation
- * happened in two parts. First, we called __bam_new which
- * was logged separately. Then we wrote the meta-data onto
- * the page. So long as we restore the LSN, then the recovery
- * for __bam_new will do everything else.
- *
- * Don't bother checking the lsn on the page. If we are
- * rolling back the next thing is that this page will get
- * freed. Opening the subdb will have reinitialized the
- * page, but not the lsn.
- */
- LSN(pagep) = argp->lsn;
- modified = 1;
- }
- if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
- pagep = NULL;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (pagep != NULL)
- (void)__memp_fput(mpf, pagep, 0);
- REC_CLOSE;
-}
-
-/*
- * __crdel_inmem_create_recover --
- * Recovery function for inmem_create.
- *
- * PUBLIC: int __crdel_inmem_create_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__crdel_inmem_create_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- DB *dbp;
- __crdel_inmem_create_args *argp;
- int do_close, ret, t_ret;
-
- COMPQUIET(info, NULL);
- dbp = NULL;
- do_close = 0;
- REC_PRINT(__crdel_inmem_create_print);
- REC_NOOP_INTRO(__crdel_inmem_create_read);
-
- /* First, see if the DB handle already exists. */
- if (argp->fileid == DB_LOGFILEID_INVALID) {
- if (DB_REDO(op))
- ret = ENOENT;
- else
- ret = 0;
- } else
- ret = __dbreg_id_to_db_int(dbenv,
- argp->txnid, &dbp, argp->fileid, 0, 0);
-
- if (DB_REDO(op)) {
- /*
- * If the dbreg failed, that means that we're creating a
- * tmp file.
- */
- if (ret != 0) {
- if ((ret = db_create(&dbp, dbenv, 0)) != 0)
- goto out;
-
- F_SET(dbp, DB_AM_RECOVER | DB_AM_INMEM);
- memcpy(dbp->fileid, argp->fid.data, DB_FILE_ID_LEN);
- if (((ret = __os_strdup(dbenv,
- argp->name.data, &dbp->dname)) != 0))
- goto out;
-
- /*
- * This DBP is never going to be entered into the
- * dbentry table, so if we leave it open here,
- * then we're going to lose it.
- */
- do_close = 1;
- }
-
- /* Now, set the fileid. */
- memcpy(dbp->fileid, argp->fid.data, argp->fid.size);
- if ((ret = __memp_set_fileid(dbp->mpf, dbp->fileid)) != 0)
- goto out;
- dbp->preserve_fid = 1;
- MAKE_INMEM(dbp);
- if ((ret = __db_dbenv_setup(dbp,
- NULL, NULL, argp->name.data, TXN_INVALID, 0)) != 0)
- goto out;
- ret = __db_dbenv_mpool(dbp, argp->name.data, 0);
-
- if (ret == ENOENT) {
- dbp->pgsize = argp->pgsize;
- if ((ret = __db_dbenv_mpool(dbp,
- argp->name.data, DB_CREATE)) != 0)
- goto out;
- } else if (ret != 0)
- goto out;
- }
-
- if (DB_UNDO(op)) {
- if (ret == 0)
- ret = __memp_nameop(dbenv, argp->fid.data, NULL,
- (const char *)argp->name.data, NULL, 1);
-
- if (ret == ENOENT || ret == DB_DELETED)
- ret = 0;
- else
- goto out;
- }
-
- *lsnp = argp->prev_lsn;
-
-out: if (dbp != NULL) {
- t_ret = 0;
- if (DB_UNDO(op))
- t_ret = __db_refresh(dbp, NULL, DB_NOSYNC, NULL, 0);
- else if (do_close || ret != 0)
- t_ret = __db_close(dbp, NULL, DB_NOSYNC);
- if (t_ret != 0 && ret == 0)
- ret = t_ret;
- }
- REC_NOOP_CLOSE;
-}
-
-/*
- * __crdel_inmem_rename_recover --
- * Recovery function for inmem_rename.
- *
- * PUBLIC: int __crdel_inmem_rename_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__crdel_inmem_rename_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- __crdel_inmem_rename_args *argp;
- u_int8_t *fileid;
- int ret;
-
- COMPQUIET(info, NULL);
- REC_PRINT(__crdel_inmem_rename_print);
- REC_NOOP_INTRO(__crdel_inmem_rename_read);
- fileid = argp->fid.data;
-
- /* Void out errors because the files may or may not still exist. */
- if (DB_REDO(op))
- (void)__memp_nameop(dbenv, fileid,
- (const char *)argp->newname.data,
- (const char *)argp->oldname.data,
- (const char *)argp->newname.data, 1);
-
- if (DB_UNDO(op))
- (void)__memp_nameop(dbenv, fileid,
- (const char *)argp->oldname.data,
- (const char *)argp->newname.data,
- (const char *)argp->oldname.data, 1);
-
- *lsnp = argp->prev_lsn;
- ret = 0;
-
- REC_NOOP_CLOSE;
-}
-
-/*
- * __crdel_inmem_remove_recover --
- * Recovery function for inmem_remove.
- *
- * PUBLIC: int __crdel_inmem_remove_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__crdel_inmem_remove_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- __crdel_inmem_remove_args *argp;
- int ret;
-
- COMPQUIET(info, NULL);
- REC_PRINT(__crdel_inmem_remove_print);
- REC_NOOP_INTRO(__crdel_inmem_remove_read);
-
- /*
- * Since removes are delayed; there is no undo for a remove; only redo.
- * The remove may fail, which is OK.
- */
- if (DB_REDO(op)) {
- (void)__memp_nameop(dbenv,
- argp->fid.data, NULL, argp->name.data, NULL, 1);
- }
-
- *lsnp = argp->prev_lsn;
- ret = 0;
-
- REC_NOOP_CLOSE;
-}
diff --git a/storage/bdb/db/db.c b/storage/bdb/db/db.c
deleted file mode 100644
index 432919133a2..00000000000
--- a/storage/bdb/db/db.c
+++ /dev/null
@@ -1,1509 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: db.c,v 12.22 2005/11/12 17:41:44 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/db_swap.h"
-#include "dbinc/btree.h"
-#include "dbinc/fop.h"
-#include "dbinc/hash.h"
-#include "dbinc/lock.h"
-#include "dbinc/log.h"
-#include "dbinc/mp.h"
-#include "dbinc/qam.h"
-#include "dbinc/txn.h"
-
-static int __db_disassociate __P((DB *));
-
-#ifdef CONFIG_TEST
-static void __db_makecopy __P((DB_ENV *, const char *, const char *));
-static int __db_testdocopy __P((DB_ENV *, const char *));
-static int __qam_testdocopy __P((DB *, const char *));
-#endif
-
-/*
- * DB.C --
- * This file contains the utility functions for the DBP layer.
- */
-
-/*
- * __db_master_open --
- * Open up a handle on a master database.
- *
- * PUBLIC: int __db_master_open __P((DB *,
- * PUBLIC: DB_TXN *, const char *, u_int32_t, int, DB **));
- */
-int
-__db_master_open(subdbp, txn, name, flags, mode, dbpp)
- DB *subdbp;
- DB_TXN *txn;
- const char *name;
- u_int32_t flags;
- int mode;
- DB **dbpp;
-{
- DB *dbp;
- int ret;
-
- *dbpp = NULL;
-
- /* Open up a handle on the main database. */
- if ((ret = db_create(&dbp, subdbp->dbenv, 0)) != 0)
- return (ret);
-
- /*
- * It's always a btree.
- * Run in the transaction we've created.
- * Set the pagesize in case we're creating a new database.
- * Flag that we're creating a database with subdatabases.
- */
- dbp->pgsize = subdbp->pgsize;
- F_SET(dbp, DB_AM_SUBDB);
- F_SET(dbp, F_ISSET(subdbp,
- DB_AM_RECOVER | DB_AM_SWAP |
- DB_AM_ENCRYPT | DB_AM_CHKSUM | DB_AM_NOT_DURABLE));
-
- /*
- * If there was a subdb specified, then we only want to apply
- * DB_EXCL to the subdb, not the actual file. We only got here
- * because there was a subdb specified.
- */
- LF_CLR(DB_EXCL);
- LF_SET(DB_RDWRMASTER);
- if ((ret = __db_open(dbp,
- txn, name, NULL, DB_BTREE, flags, mode, PGNO_BASE_MD)) != 0)
- goto err;
-
- /*
- * Verify that pagesize is the same on both. The items in dbp were now
- * initialized from the meta page. The items in dbp were set in
- * __db_dbopen when we either read or created the master file. Other
- * items such as checksum and encryption are checked when we read the
- * meta-page. So we do not check those here. However, if the
- * meta-page caused checksumming to be turned on and it wasn't already,
- * set it here.
- */
- if (F_ISSET(dbp, DB_AM_CHKSUM))
- F_SET(subdbp, DB_AM_CHKSUM);
- if (subdbp->pgsize != 0 && dbp->pgsize != subdbp->pgsize) {
- ret = EINVAL;
- __db_err(dbp->dbenv,
- "Different pagesize specified on existent file");
- goto err;
- }
-err:
- if (ret != 0 && !F_ISSET(dbp, DB_AM_DISCARD))
- (void)__db_close(dbp, txn, 0);
- else
- *dbpp = dbp;
- return (ret);
-}
-
-/*
- * __db_master_update --
- * Add/Open/Remove a subdatabase from a master database.
- *
- * PUBLIC: int __db_master_update __P((DB *, DB *, DB_TXN *, const char *,
- * PUBLIC: DBTYPE, mu_action, const char *, u_int32_t));
- */
-int
-__db_master_update(mdbp, sdbp, txn, subdb, type, action, newname, flags)
- DB *mdbp, *sdbp;
- DB_TXN *txn;
- const char *subdb;
- DBTYPE type;
- mu_action action;
- const char *newname;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DBC *dbc, *ndbc;
- DBT key, data, ndata;
- PAGE *p, *r;
- db_pgno_t t_pgno;
- int modify, ret, t_ret;
-
- dbenv = mdbp->dbenv;
- dbc = ndbc = NULL;
- p = NULL;
-
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
-
- /* Might we modify the master database? If so, we'll need to lock. */
- modify = (action != MU_OPEN || LF_ISSET(DB_CREATE)) ? 1 : 0;
-
- /*
- * Open up a cursor. If this is CDB and we're creating the database,
- * make it an update cursor.
- */
- if ((ret = __db_cursor(mdbp, txn, &dbc,
- (CDB_LOCKING(dbenv) && modify) ? DB_WRITECURSOR : 0)) != 0)
- goto err;
-
- /*
- * Point the cursor at the record.
- *
- * If we're removing or potentially creating an entry, lock the page
- * with DB_RMW.
- *
- * We do multiple cursor operations with the cursor in some cases and
- * subsequently access the data DBT information. Set DB_DBT_MALLOC so
- * we don't risk modification of the data between our uses of it.
- *
- * !!!
- * We don't include the name's nul termination in the database.
- */
- key.data = (void *)subdb;
- key.size = (u_int32_t)strlen(subdb);
- F_SET(&data, DB_DBT_MALLOC);
-
- ret = __db_c_get(dbc, &key, &data,
- DB_SET | ((STD_LOCKING(dbc) && modify) ? DB_RMW : 0));
-
- /*
- * What we do next--whether or not we found a record for the
- * specified subdatabase--depends on what the specified action is.
- * Handle ret appropriately as the first statement of each case.
- */
- switch (action) {
- case MU_REMOVE:
- /*
- * We should have found something if we're removing it. Note
- * that in the common case where the DB we're asking to remove
- * doesn't exist, we won't get this far; __db_subdb_remove
- * will already have returned an error from __db_open.
- */
- if (ret != 0)
- goto err;
-
- /*
- * Delete the subdatabase entry first; if this fails,
- * we don't want to touch the actual subdb pages.
- */
- if ((ret = __db_c_del(dbc, 0)) != 0)
- goto err;
-
- /*
- * We're handling actual data, not on-page meta-data,
- * so it hasn't been converted to/from opposite
- * endian architectures. Do it explicitly, now.
- */
- memcpy(&sdbp->meta_pgno, data.data, sizeof(db_pgno_t));
- DB_NTOHL(&sdbp->meta_pgno);
- if ((ret =
- __memp_fget(mdbp->mpf, &sdbp->meta_pgno, 0, &p)) != 0)
- goto err;
-
- /* Free the root on the master db if it was created. */
- if (TYPE(p) == P_BTREEMETA &&
- ((BTMETA *)p)->root != PGNO_INVALID) {
- if ((ret = __memp_fget(mdbp->mpf,
- &((BTMETA *)p)->root, 0, &r)) != 0)
- goto err;
-
- /* Free and put the page. */
- if ((ret = __db_free(dbc, r)) != 0) {
- r = NULL;
- goto err;
- }
- }
- /* Free and put the page. */
- if ((ret = __db_free(dbc, p)) != 0) {
- p = NULL;
- goto err;
- }
- p = NULL;
- break;
- case MU_RENAME:
- /* We should have found something if we're renaming it. */
- if (ret != 0)
- goto err;
-
- /*
- * Before we rename, we need to make sure we're not
- * overwriting another subdatabase, or else this operation
- * won't be undoable. Open a second cursor and check
- * for the existence of newname; it shouldn't appear under
- * us since we hold the metadata lock.
- */
- if ((ret = __db_cursor(mdbp, txn, &ndbc, 0)) != 0)
- goto err;
- key.data = (void *)newname;
- key.size = (u_int32_t)strlen(newname);
-
- /*
- * We don't actually care what the meta page of the potentially-
- * overwritten DB is; we just care about existence.
- */
- memset(&ndata, 0, sizeof(ndata));
- F_SET(&ndata, DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- if ((ret = __db_c_get(ndbc, &key, &ndata, DB_SET)) == 0) {
- /* A subdb called newname exists. Bail. */
- ret = EEXIST;
- __db_err(dbenv, "rename: database %s exists", newname);
- goto err;
- } else if (ret != DB_NOTFOUND)
- goto err;
-
- /*
- * Now do the put first; we don't want to lose our
- * sole reference to the subdb. Use the second cursor
- * so that the first one continues to point to the old record.
- */
- if ((ret = __db_c_put(ndbc, &key, &data, DB_KEYFIRST)) != 0)
- goto err;
- if ((ret = __db_c_del(dbc, 0)) != 0) {
- /*
- * If the delete fails, try to delete the record
- * we just put, in case we're not txn-protected.
- */
- (void)__db_c_del(ndbc, 0);
- goto err;
- }
-
- break;
- case MU_OPEN:
- /*
- * Get the subdatabase information. If it already exists,
- * copy out the page number and we're done.
- */
- switch (ret) {
- case 0:
- if (LF_ISSET(DB_CREATE) && LF_ISSET(DB_EXCL)) {
- ret = EEXIST;
- goto err;
- }
- memcpy(&sdbp->meta_pgno, data.data, sizeof(db_pgno_t));
- DB_NTOHL(&sdbp->meta_pgno);
- goto done;
- case DB_NOTFOUND:
- if (LF_ISSET(DB_CREATE))
- break;
- /*
- * No db_err, it is reasonable to remove a
- * nonexistent db.
- */
- ret = ENOENT;
- goto err;
- default:
- goto err;
- }
-
- /* Create a subdatabase. */
- if ((ret = __db_new(dbc,
- type == DB_HASH ? P_HASHMETA : P_BTREEMETA, &p)) != 0)
- goto err;
- sdbp->meta_pgno = PGNO(p);
-
- /*
- * XXX
- * We're handling actual data, not on-page meta-data, so it
- * hasn't been converted to/from opposite endian architectures.
- * Do it explicitly, now.
- */
- t_pgno = PGNO(p);
- DB_HTONL(&t_pgno);
- memset(&ndata, 0, sizeof(ndata));
- ndata.data = &t_pgno;
- ndata.size = sizeof(db_pgno_t);
- if ((ret = __db_c_put(dbc, &key, &ndata, DB_KEYLAST)) != 0)
- goto err;
- F_SET(sdbp, DB_AM_CREATED);
- break;
- }
-
-err:
-done: /*
- * If we allocated a page: if we're successful, mark the page dirty
- * and return it to the cache, otherwise, discard/free it.
- */
- if (p != NULL) {
- if (ret == 0) {
- if ((t_ret =
- __memp_fput(mdbp->mpf, p, DB_MPOOL_DIRTY)) != 0)
- ret = t_ret;
- } else
- (void)__memp_fput(mdbp->mpf, p, 0);
- }
-
- /* Discard the cursor(s) and data. */
- if (data.data != NULL)
- __os_ufree(dbenv, data.data);
- if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
- if (ndbc != NULL && (t_ret = __db_c_close(ndbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_dbenv_setup --
- * Set up the underlying environment during a db_open.
- *
- * PUBLIC: int __db_dbenv_setup __P((DB *,
- * PUBLIC: DB_TXN *, const char *, const char *, u_int32_t, u_int32_t));
- */
-int
-__db_dbenv_setup(dbp, txn, fname, dname, id, flags)
- DB *dbp;
- DB_TXN *txn;
- const char *fname, *dname;
- u_int32_t id, flags;
-{
- DB *ldbp;
- DB_ENV *dbenv;
- u_int32_t maxid;
- int ret;
-
- dbenv = dbp->dbenv;
-
- /* If we don't yet have an environment, it's time to create it. */
- if (!F_ISSET(dbenv, DB_ENV_OPEN_CALLED)) {
- /* Make sure we have at least DB_MINCACHE pages in our cache. */
- if (dbenv->mp_gbytes == 0 &&
- dbenv->mp_bytes < dbp->pgsize * DB_MINPAGECACHE &&
- (ret = __memp_set_cachesize(
- dbenv, 0, dbp->pgsize * DB_MINPAGECACHE, 0)) != 0)
- return (ret);
-
- if ((ret = __env_open(dbenv, NULL, DB_CREATE |
- DB_INIT_MPOOL | DB_PRIVATE | LF_ISSET(DB_THREAD), 0)) != 0)
- return (ret);
- }
-
- /* Join the underlying cache. */
- if ((!F_ISSET(dbp, DB_AM_INMEM) || dname == NULL) &&
- (ret = __db_dbenv_mpool(dbp, fname, flags)) != 0)
- return (ret);
-
- /* We may need a per-thread mutex. */
- if (LF_ISSET(DB_THREAD) && (ret = __mutex_alloc(
- dbenv, MTX_DB_HANDLE, DB_MUTEX_THREAD, &dbp->mutex)) != 0)
- return (ret);
-
- /*
- * Set up a bookkeeping entry for this database in the log region,
- * if such a region exists. Note that even if we're in recovery
- * or a replication client, where we won't log registries, we'll
- * still need an FNAME struct, so LOGGING_ON is the correct macro.
- */
- if (LOGGING_ON(dbenv) && dbp->log_filename == NULL &&
- (ret = __dbreg_setup(dbp,
- F_ISSET(dbp, DB_AM_INMEM) ? dname : fname, id)) != 0)
- return (ret);
-
- /*
- * If we're actively logging and our caller isn't a recovery function
- * that already did so, then assign this dbp a log fileid.
- */
- if (DBENV_LOGGING(dbenv) && !F_ISSET(dbp, DB_AM_RECOVER) &&
-#if !defined(DEBUG_ROP)
- !F_ISSET(dbp, DB_AM_RDONLY) &&
-#endif
- (ret = __dbreg_new_id(dbp, txn)) != 0)
- return (ret);
-
- /*
- * Insert ourselves into the DB_ENV's dblist. We allocate a
- * unique ID to each {fileid, meta page number} pair, and to
- * each temporary file (since they all have a zero fileid).
- * This ID gives us something to use to tell which DB handles
- * go with which databases in all the cursor adjustment
- * routines, where we don't want to do a lot of ugly and
- * expensive memcmps.
- */
- MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
- for (maxid = 0, ldbp = LIST_FIRST(&dbenv->dblist);
- ldbp != NULL; ldbp = LIST_NEXT(ldbp, dblistlinks)) {
- if (!F_ISSET(dbp, DB_AM_INMEM)) {
- if (memcmp(ldbp->fileid, dbp->fileid, DB_FILE_ID_LEN)
- == 0 && ldbp->meta_pgno == dbp->meta_pgno)
- break;
- } else if (dname != NULL) {
- if (F_ISSET(ldbp, DB_AM_INMEM) &&
- strcmp(ldbp->dname, dname) == 0)
- break;
- }
- if (ldbp->adj_fileid > maxid)
- maxid = ldbp->adj_fileid;
- }
-
- /*
- * If ldbp is NULL, we didn't find a match, or we weren't
- * really looking because fname is NULL. Assign the dbp an
- * adj_fileid one higher than the largest we found, and
- * insert it at the head of the master dbp list.
- *
- * If ldbp is not NULL, it is a match for our dbp. Give dbp
- * the same ID that ldbp has, and add it after ldbp so they're
- * together in the list.
- */
- if (ldbp == NULL) {
- dbp->adj_fileid = maxid + 1;
- LIST_INSERT_HEAD(&dbenv->dblist, dbp, dblistlinks);
- } else {
- dbp->adj_fileid = ldbp->adj_fileid;
- LIST_INSERT_AFTER(ldbp, dbp, dblistlinks);
- }
- MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
-
- return (0);
-}
-
-/*
- * __db_dbenv_mpool --
- * Set up the underlying environment cache during a db_open.
- *
- * PUBLIC: int __db_dbenv_mpool __P((DB *, const char *, u_int32_t));
- */
-int
-__db_dbenv_mpool(dbp, fname, flags)
- DB *dbp;
- const char *fname;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DBT pgcookie;
- DB_MPOOLFILE *mpf;
- DB_PGINFO pginfo;
- int fidset, ftype, ret;
- int32_t lsn_off;
- u_int8_t nullfid[DB_FILE_ID_LEN];
- u_int32_t clear_len;
-
- COMPQUIET(mpf, NULL);
-
- dbenv = dbp->dbenv;
- lsn_off = 0;
-
- /* It's possible that this database is already open. */
- if (F_ISSET(dbp, DB_AM_OPEN_CALLED))
- return (0);
-
- /*
- * If we need to pre- or post-process a file's pages on I/O, set the
- * file type. If it's a hash file, always call the pgin and pgout
- * routines. This means that hash files can never be mapped into
- * process memory. If it's a btree file and requires swapping, we
- * need to page the file in and out. This has to be right -- we can't
- * mmap files that are being paged in and out.
- */
- switch (dbp->type) {
- case DB_BTREE:
- case DB_RECNO:
- ftype = F_ISSET(dbp, DB_AM_SWAP | DB_AM_ENCRYPT | DB_AM_CHKSUM)
- ? DB_FTYPE_SET : DB_FTYPE_NOTSET;
- clear_len = CRYPTO_ON(dbenv) ?
- (dbp->pgsize != 0 ? dbp->pgsize : DB_CLEARLEN_NOTSET) :
- DB_PAGE_DB_LEN;
- break;
- case DB_HASH:
- ftype = DB_FTYPE_SET;
- clear_len = CRYPTO_ON(dbenv) ?
- (dbp->pgsize != 0 ? dbp->pgsize : DB_CLEARLEN_NOTSET) :
- DB_PAGE_DB_LEN;
- break;
- case DB_QUEUE:
- ftype = F_ISSET(dbp,
- DB_AM_SWAP | DB_AM_ENCRYPT | DB_AM_CHKSUM) ?
- DB_FTYPE_SET : DB_FTYPE_NOTSET;
-
- /*
- * If we came in here without a pagesize set, then we need
- * to mark the in-memory handle as having clear_len not
- * set, because we don't really know the clear length or
- * the page size yet (since the file doesn't yet exist).
- */
- clear_len = dbp->pgsize != 0 ? dbp->pgsize : DB_CLEARLEN_NOTSET;
- break;
- case DB_UNKNOWN:
- /*
- * If we're running in the verifier, our database might
- * be corrupt and we might not know its type--but we may
- * still want to be able to verify and salvage.
- *
- * If we can't identify the type, it's not going to be safe
- * to call __db_pgin--we pretty much have to give up all
- * hope of salvaging cross-endianness. Proceed anyway;
- * at worst, the database will just appear more corrupt
- * than it actually is, but at best, we may be able
- * to salvage some data even with no metadata page.
- */
- if (F_ISSET(dbp, DB_AM_VERIFYING)) {
- ftype = DB_FTYPE_NOTSET;
- clear_len = DB_PAGE_DB_LEN;
- break;
- }
-
- /*
- * This might be an in-memory file and we won't know its
- * file type until after we open it and read the meta-data
- * page.
- */
- if (F_ISSET(dbp, DB_AM_INMEM)) {
- clear_len = DB_CLEARLEN_NOTSET;
- ftype = DB_FTYPE_NOTSET;
- lsn_off = DB_LSN_OFF_NOTSET;
- break;
- }
- /* FALLTHROUGH */
- default:
- return (__db_unknown_type(dbenv, "DB->open", dbp->type));
- }
-
- mpf = dbp->mpf;
-
- memset(nullfid, 0, DB_FILE_ID_LEN);
- fidset = memcmp(nullfid, dbp->fileid, DB_FILE_ID_LEN);
- if (fidset)
- (void)__memp_set_fileid(mpf, dbp->fileid);
-
- (void)__memp_set_clear_len(mpf, clear_len);
- (void)__memp_set_ftype(mpf, ftype);
- (void)__memp_set_lsn_offset(mpf, lsn_off);
-
- pginfo.db_pagesize = dbp->pgsize;
- pginfo.flags =
- F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP));
- pginfo.type = dbp->type;
- pgcookie.data = &pginfo;
- pgcookie.size = sizeof(DB_PGINFO);
- (void)__memp_set_pgcookie(mpf, &pgcookie);
-
- if ((ret = __memp_fopen(mpf, NULL, fname,
- LF_ISSET(DB_CREATE | DB_DURABLE_UNKNOWN |
- DB_NOMMAP | DB_ODDFILESIZE | DB_RDONLY | DB_TRUNCATE) |
- (F_ISSET(dbenv, DB_ENV_DIRECT_DB) ? DB_DIRECT : 0) |
- (F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_TXN_NOT_DURABLE : 0),
- 0, dbp->pgsize)) != 0) {
- /*
- * The open didn't work; we need to reset the mpf,
- * retaining the in-memory semantics (if any).
- */
- (void)__memp_fclose(dbp->mpf, 0);
- (void)__memp_fcreate(dbenv, &dbp->mpf);
- if (F_ISSET(dbp, DB_AM_INMEM))
- MAKE_INMEM(dbp);
- return (ret);
- }
-
- /*
- * Set the open flag. We use it to mean that the dbp has gone
- * through mpf setup, including dbreg_register. Also, below,
- * the underlying access method open functions may want to do
- * things like acquire cursors, so the open flag has to be set
- * before calling them.
- */
- F_SET(dbp, DB_AM_OPEN_CALLED);
- if (!fidset && fname != NULL) {
- (void)__memp_get_fileid(dbp->mpf, dbp->fileid);
- dbp->preserve_fid = 1;
- }
-
- return (0);
-}
-
-/*
- * __db_close --
- * DB->close method.
- *
- * PUBLIC: int __db_close __P((DB *, DB_TXN *, u_int32_t));
- */
-int
-__db_close(dbp, txn, flags)
- DB *dbp;
- DB_TXN *txn;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- int db_ref, deferred_close, ret, t_ret;
-
- dbenv = dbp->dbenv;
- deferred_close = ret = 0;
-
- /*
- * Validate arguments, but as a DB handle destructor, we can't fail.
- *
- * Check for consistent transaction usage -- ignore errors. Only
- * internal callers specify transactions, so it's a serious problem
- * if we get error messages.
- */
- if (txn != NULL)
- (void)__db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0);
-
- /* Refresh the structure and close any underlying resources. */
- ret = __db_refresh(dbp, txn, flags, &deferred_close, 0);
-
- /*
- * If we've deferred the close because the logging of the close failed,
- * return our failure right away without destroying the handle.
- */
- if (deferred_close)
- return (ret);
-
- /* !!!
- * This code has an apparent race between the moment we read and
- * decrement dbenv->db_ref and the moment we check whether it's 0.
- * However, if the environment is DBLOCAL, the user shouldn't have a
- * reference to the dbenv handle anyway; the only way we can get
- * multiple dbps sharing a local dbenv is if we open them internally
- * during something like a subdatabase open. If any such thing is
- * going on while the user is closing the original dbp with a local
- * dbenv, someone's already badly screwed up, so there's no reason
- * to bother engineering around this possibility.
- */
- MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
- db_ref = --dbenv->db_ref;
- MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
- if (F_ISSET(dbenv, DB_ENV_DBLOCAL) && db_ref == 0 &&
- (t_ret = __env_close(dbenv, 0)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Free the database handle. */
- memset(dbp, CLEAR_BYTE, sizeof(*dbp));
- __os_free(dbenv, dbp);
-
- return (ret);
-}
-
-/*
- * __db_refresh --
- * Refresh the DB structure, releasing any allocated resources.
- * This does most of the work of closing files now because refresh
- * is what is used during abort processing (since we can't destroy
- * the actual handle) and during abort processing, we may have a
- * fully opened handle.
- *
- * PUBLIC: int __db_refresh __P((DB *, DB_TXN *, u_int32_t, int *, int));
- */
-int
-__db_refresh(dbp, txn, flags, deferred_closep, reuse)
- DB *dbp;
- DB_TXN *txn;
- u_int32_t flags;
- int *deferred_closep, reuse;
-{
- DB *sdbp;
- DBC *dbc;
- DB_ENV *dbenv;
- DB_LOCKREQ lreq;
- REGENV *renv;
- REGINFO *infop;
- u_int32_t save_flags;
- int resync, ret, t_ret;
-
- ret = 0;
-
- dbenv = dbp->dbenv;
- infop = dbenv->reginfo;
- if (infop != NULL)
- renv = infop->primary;
- else
- renv = NULL;
-
- /* If never opened, or not currently open, it's easy. */
- if (!F_ISSET(dbp, DB_AM_OPEN_CALLED))
- goto never_opened;
-
- /*
- * If we have any secondary indices, disassociate them from us.
- * We don't bother with the mutex here; it only protects some
- * of the ops that will make us core-dump mid-close anyway, and
- * if you're trying to do something with a secondary *while* you're
- * closing the primary, you deserve what you get. The disassociation
- * is mostly done just so we can close primaries and secondaries in
- * any order--but within one thread of control.
- */
- for (sdbp = LIST_FIRST(&dbp->s_secondaries);
- sdbp != NULL; sdbp = LIST_NEXT(sdbp, s_links)) {
- LIST_REMOVE(sdbp, s_links);
- if ((t_ret = __db_disassociate(sdbp)) != 0 && ret == 0)
- ret = t_ret;
- }
-
- /*
- * Sync the underlying access method. Do before closing the cursors
- * because DB->sync allocates cursors in order to write Recno backing
- * source text files.
- *
- * Sync is slow on some systems, notably Solaris filesystems where the
- * entire buffer cache is searched. If we're in recovery, don't flush
- * the file, it's not necessary.
- */
- if (!LF_ISSET(DB_NOSYNC) &&
- !F_ISSET(dbp, DB_AM_DISCARD | DB_AM_RECOVER) &&
- (t_ret = __db_sync(dbp)) != 0 && ret == 0)
- ret = t_ret;
-
- /*
- * Go through the active cursors and call the cursor recycle routine,
- * which resolves pending operations and moves the cursors onto the
- * free list. Then, walk the free list and call the cursor destroy
- * routine. Note that any failure on a close is considered "really
- * bad" and we just break out of the loop and force forward.
- */
- resync = TAILQ_FIRST(&dbp->active_queue) == NULL ? 0 : 1;
- while ((dbc = TAILQ_FIRST(&dbp->active_queue)) != NULL)
- if ((t_ret = __db_c_close(dbc)) != 0) {
- if (ret == 0)
- ret = t_ret;
- break;
- }
-
- while ((dbc = TAILQ_FIRST(&dbp->free_queue)) != NULL)
- if ((t_ret = __db_c_destroy(dbc)) != 0) {
- if (ret == 0)
- ret = t_ret;
- break;
- }
-
- /*
- * Close any outstanding join cursors. Join cursors destroy themselves
- * on close and have no separate destroy routine. We don't have to set
- * the resync flag here, because join cursors aren't write cursors.
- */
- while ((dbc = TAILQ_FIRST(&dbp->join_queue)) != NULL)
- if ((t_ret = __db_join_close(dbc)) != 0) {
- if (ret == 0)
- ret = t_ret;
- break;
- }
-
- /*
- * Sync the memory pool, even though we've already called DB->sync,
- * because closing cursors can dirty pages by deleting items they
- * referenced.
- *
- * Sync is slow on some systems, notably Solaris filesystems where the
- * entire buffer cache is searched. If we're in recovery, don't flush
- * the file, it's not necessary.
- */
- if (resync && !LF_ISSET(DB_NOSYNC) &&
- !F_ISSET(dbp, DB_AM_DISCARD | DB_AM_RECOVER) &&
- (t_ret = __memp_fsync(dbp->mpf)) != 0 && ret == 0)
- ret = t_ret;
-
-never_opened:
- /*
- * At this point, we haven't done anything to render the DB
- * handle unusable, at least by a transaction abort. Take the
- * opportunity now to log the file close. If this log fails
- * and we're in a transaction, we have to bail out of the attempted
- * close; we'll need a dbp in order to successfully abort the
- * transaction, and we can't conjure a new one up because we haven't
- * gotten out the dbreg_register record that represents the close.
- * In this case, we put off actually closing the dbp until we've
- * performed the abort.
- */
- if (!reuse && LOGGING_ON(dbp->dbenv)) {
- /*
- * Discard the log file id, if any. We want to log the close
- * if and only if this is not a recovery dbp or a client dbp,
- * or a dead dbp handle.
- */
- DB_ASSERT(renv != NULL);
- if (F_ISSET(dbp, DB_AM_RECOVER) || IS_REP_CLIENT(dbenv) ||
- dbp->timestamp != renv->rep_timestamp)
- t_ret = __dbreg_revoke_id(dbp, 0, DB_LOGFILEID_INVALID);
- else {
- if ((t_ret = __dbreg_close_id(dbp,
- txn, DBREG_CLOSE)) != 0 && txn != NULL) {
- /*
- * We're in a txn and the attempt to log the
- * close failed; let the txn subsystem know
- * that we need to destroy this dbp once we're
- * done with the abort, then bail from the
- * close.
- *
- * Note that if the attempt to put off the
- * close -also- fails--which it won't unless
- * we're out of heap memory--we're really
- * screwed. Panic.
- */
- if ((ret =
- __txn_closeevent(dbenv, txn, dbp)) != 0)
- return (__db_panic(dbenv, ret));
- if (deferred_closep != NULL)
- *deferred_closep = 1;
- return (t_ret);
- }
- /*
- * If dbreg_close_id failed and we were not in a
- * transaction, then we need to finish this close
- * because the caller can't do anything with the
- * handle after we return an error. We rely on
- * dbreg_close_id to mark the entry in some manner
- * so that we do not do a clean shutdown of this
- * environment. If shutdown isn't clean, then the
- * application *must* run recovery and that will
- * generate the RCLOSE record.
- */
- }
-
- if (ret == 0)
- ret = t_ret;
-
- /* Discard the log FNAME. */
- if ((t_ret = __dbreg_teardown(dbp)) != 0 && ret == 0)
- ret = t_ret;
- }
-
- /* Close any handle we've been holding since the open. */
- if (dbp->saved_open_fhp != NULL &&
- (t_ret = __os_closehandle(dbenv, dbp->saved_open_fhp)) != 0 &&
- ret == 0)
- ret = t_ret;
-
- /*
- * Remove this DB handle from the DB_ENV's dblist, if it's been added.
- *
- * Close our reference to the underlying cache while locked, we don't
- * want to race with a thread searching for our underlying cache link
- * while opening a DB handle.
- */
- MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
- if (!reuse && dbp->dblistlinks.le_prev != NULL) {
- LIST_REMOVE(dbp, dblistlinks);
- dbp->dblistlinks.le_prev = NULL;
- }
-
- /* Close the memory pool file handle. */
- if (dbp->mpf != NULL) {
- if ((t_ret = __memp_fclose(dbp->mpf,
- F_ISSET(dbp, DB_AM_DISCARD) ? DB_MPOOL_DISCARD : 0)) != 0 &&
- ret == 0)
- ret = t_ret;
- dbp->mpf = NULL;
- if (reuse &&
- (t_ret = __memp_fcreate(dbenv, &dbp->mpf)) != 0 &&
- ret == 0)
- ret = t_ret;
- }
-
- MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
-
- /*
- * Call the access specific close function.
- *
- * We do this here rather than in __db_close as we need to do this when
- * aborting an open so that file descriptors are closed and abort of
- * renames can succeed on platforms that lock open files (such as
- * Windows). In particular, we need to ensure that all the extents
- * associated with a queue are closed so that queue renames can be
- * aborted.
- *
- * It is also important that we do this before releasing the handle
- * lock, because dbremove and dbrename assume that once they have the
- * handle lock, it is safe to modify the underlying file(s).
- *
- * !!!
- * Because of where these functions are called in the DB handle close
- * process, these routines can't do anything that would dirty pages or
- * otherwise affect closing down the database. Specifically, we can't
- * abort and recover any of the information they control.
- */
- if ((t_ret = __bam_db_close(dbp)) != 0 && ret == 0)
- ret = t_ret;
- if ((t_ret = __ham_db_close(dbp)) != 0 && ret == 0)
- ret = t_ret;
- if ((t_ret = __qam_db_close(dbp, dbp->flags)) != 0 && ret == 0)
- ret = t_ret;
-
- /*
- * !!!
- * At this point, the access-method specific information has been
- * freed. From now on, we can use the dbp, but not touch any
- * access-method specific data.
- */
-
- if (!reuse && dbp->lid != DB_LOCK_INVALIDID) {
- /* We may have pending trade operations on this dbp. */
- if (txn != NULL)
- __txn_remlock(dbenv, txn, &dbp->handle_lock, dbp->lid);
-
- /* We may be holding the handle lock; release it. */
- lreq.op = DB_LOCK_PUT_ALL;
- lreq.obj = NULL;
- if ((t_ret = __lock_vec(dbenv,
- dbp->lid, 0, &lreq, 1, NULL)) != 0 && ret == 0)
- ret = t_ret;
-
- if ((t_ret = __lock_id_free(dbenv, dbp->lid)) != 0 && ret == 0)
- ret = t_ret;
- dbp->lid = DB_LOCK_INVALIDID;
- LOCK_INIT(dbp->handle_lock);
- }
-
- /*
- * If this is a temporary file (un-named in-memory file), then
- * discard the locker ID allocated as the fileid.
- */
- if (LOCKING_ON(dbenv) &&
- F_ISSET(dbp, DB_AM_INMEM) && !dbp->preserve_fid &&
- *(u_int32_t *)dbp->fileid != DB_LOCK_INVALIDID &&
- (t_ret = __lock_id_free(dbenv, *(u_int32_t *)dbp->fileid)) != 0 &&
- ret == 0)
- ret = t_ret;
-
- if (reuse) {
- /*
- * If we are reusing this dbp, then we're done now. Re-init
- * the handle, preserving important flags, and then return.
- * This code is borrowed from __db_init, which does more
- * than we can do here.
- */
- save_flags = F_ISSET(dbp, DB_AM_INMEM | DB_AM_TXN);
-
- /*
- * XXX If this is an XA handle, we'll want to specify
- * DB_XA_CREATE.
- */
- if ((ret = __bam_db_create(dbp)) != 0)
- return (ret);
- if ((ret = __ham_db_create(dbp)) != 0)
- return (ret);
- if ((ret = __qam_db_create(dbp)) != 0)
- return (ret);
-
- /* Restore flags */
- dbp->flags = dbp->orig_flags | save_flags;
-
- if (FLD_ISSET(save_flags, DB_AM_INMEM)) {
- /*
- * If this is inmem, then it may have a fileid
- * even if it was never opened, and we need to
- * clear out that fileid.
- */
- memset(dbp->fileid, 0, sizeof(dbp->fileid));
- MAKE_INMEM(dbp);
- }
- return (ret);
- }
-
- dbp->type = DB_UNKNOWN;
-
- /* Discard the thread mutex. */
- if ((t_ret = __mutex_free(dbenv, &dbp->mutex)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Discard any memory allocated for the file and database names. */
- if (dbp->fname != NULL) {
- __os_free(dbp->dbenv, dbp->fname);
- dbp->fname = NULL;
- }
- if (dbp->dname != NULL) {
- __os_free(dbp->dbenv, dbp->dname);
- dbp->dname = NULL;
- }
-
- /* Discard any memory used to store returned data. */
- if (dbp->my_rskey.data != NULL)
- __os_free(dbp->dbenv, dbp->my_rskey.data);
- if (dbp->my_rkey.data != NULL)
- __os_free(dbp->dbenv, dbp->my_rkey.data);
- if (dbp->my_rdata.data != NULL)
- __os_free(dbp->dbenv, dbp->my_rdata.data);
-
- /* For safety's sake; we may refresh twice. */
- memset(&dbp->my_rskey, 0, sizeof(DBT));
- memset(&dbp->my_rkey, 0, sizeof(DBT));
- memset(&dbp->my_rdata, 0, sizeof(DBT));
-
- /* Clear out fields that normally get set during open. */
- memset(dbp->fileid, 0, sizeof(dbp->fileid));
- dbp->adj_fileid = 0;
- dbp->meta_pgno = 0;
- dbp->cur_lid = DB_LOCK_INVALIDID;
- dbp->associate_lid = DB_LOCK_INVALIDID;
- dbp->cl_id = 0;
- dbp->open_flags = 0;
-
- /*
- * If we are being refreshed with a txn specified, then we need
- * to make sure that we clear out the lock handle field, because
- * releasing all the locks for this transaction will release this
- * lock and we don't want close to stumble upon this handle and
- * try to close it.
- */
- if (txn != NULL)
- LOCK_INIT(dbp->handle_lock);
-
- /* Reset flags to whatever the user configured. */
- dbp->flags = dbp->orig_flags;
-
- return (ret);
-}
-
-/*
- * __db_log_page
- * Log a meta-data or root page during a subdatabase create operation.
- *
- * PUBLIC: int __db_log_page __P((DB *, DB_TXN *, DB_LSN *, db_pgno_t, PAGE *));
- */
-int
-__db_log_page(dbp, txn, lsn, pgno, page)
- DB *dbp;
- DB_TXN *txn;
- DB_LSN *lsn;
- db_pgno_t pgno;
- PAGE *page;
-{
- DBT page_dbt;
- DB_LSN new_lsn;
- int ret;
-
- if (!LOGGING_ON(dbp->dbenv) || txn == NULL)
- return (0);
-
- memset(&page_dbt, 0, sizeof(page_dbt));
- page_dbt.size = dbp->pgsize;
- page_dbt.data = page;
-
- ret = __crdel_metasub_log(dbp, txn, &new_lsn, 0, pgno, &page_dbt, lsn);
-
- if (ret == 0)
- page->lsn = new_lsn;
- return (ret);
-}
-
-/*
- * __db_backup_name
- * Create the backup file name for a given file.
- *
- * PUBLIC: int __db_backup_name __P((DB_ENV *,
- * PUBLIC: const char *, DB_TXN *, char **));
- */
-#undef BACKUP_PREFIX
-#define BACKUP_PREFIX "__db"
-
-#undef MAX_LSN_TO_TEXT
-#define MAX_LSN_TO_TEXT 17
-
-int
-__db_backup_name(dbenv, name, txn, backup)
- DB_ENV *dbenv;
- const char *name;
- DB_TXN *txn;
- char **backup;
-{
- DB_LSN lsn;
- size_t len;
- int ret;
- char *p, *retp;
-
- /*
- * Part of the name may be a full path, so we need to make sure that
- * we allocate enough space for it, even in the case where we don't
- * use the entire filename for the backup name.
- */
- len = strlen(name) + strlen(BACKUP_PREFIX) + 1 + MAX_LSN_TO_TEXT;
- if ((ret = __os_malloc(dbenv, len, &retp)) != 0)
- return (ret);
-
- /*
- * Create the name. Backup file names are in one of three forms:
- *
- * In a transactional env: __db.LSN(8).LSN(8)
- * and
- * In VXWORKS (where we want 8.3 support)
- * and
- * in any other non-transactional env: __db.FILENAME
- *
- * If the transaction doesn't have a current LSN, we write a dummy
- * log record to force it, so we ensure all tmp names are unique.
- *
- * In addition, the name passed may contain an env-relative path.
- * In that case, put the __db. in the right place (in the last
- * component of the pathname).
- *
- * There are four cases here:
- * 1. simple path w/out transaction
- * 2. simple path + transaction
- * 3. multi-component path w/out transaction
- * 4. multi-component path + transaction
- */
- p = __db_rpath(name);
- if (txn == NULL) {
-#ifdef HAVE_VXWORKS
- { int i, n;
- /* On VxWorks we must support 8.3 names. */
- if (p == NULL) /* Case 1. */
- n = snprintf(retp,
- len, "%s%.4s.tmp", BACKUP_PREFIX, name);
- else /* Case 3. */
- n = snprintf(retp, len, "%.*s%s%.4s.tmp",
- (int)(p - name) + 1, name, BACKUP_PREFIX, p + 1);
-
- /*
- * Overwrite "." in the characters copied from the name.
- * If we backup 8 characters from the end, we're guaranteed
- * to a) include the four bytes we copied from the name
- * and b) not run off the beginning of the string.
- */
- for (i = 0, p = (retp + n) - 8; i < 4; p++, i++)
- if (*p == '.')
- *p = '_';
- }
-#else
- if (p == NULL) /* Case 1. */
- snprintf(retp, len, "%s.%s", BACKUP_PREFIX, name);
- else /* Case 3. */
- snprintf(retp, len, "%.*s%s.%s",
- (int)(p - name) + 1, name, BACKUP_PREFIX, p + 1);
-#endif
- } else {
- lsn = ((TXN_DETAIL *)txn->td)->last_lsn;
- if (IS_ZERO_LSN(lsn)) {
- /*
- * Write dummy log record. The two choices for dummy
- * log records are __db_noop_log and __db_debug_log;
- * unfortunately __db_noop_log requires a valid dbp,
- * and we aren't guaranteed to be able to pass one in
- * here.
- */
- if ((ret = __db_debug_log(dbenv,
- txn, &lsn, 0, NULL, 0, NULL, NULL, 0)) != 0) {
- __os_free(dbenv, retp);
- return (ret);
- }
- }
-
- if (p == NULL) /* Case 2. */
- snprintf(retp, len,
- "%s.%x.%x", BACKUP_PREFIX, lsn.file, lsn.offset);
- else /* Case 4. */
- snprintf(retp, len, "%.*s%x.%x",
- (int)(p - name) + 1, name, lsn.file, lsn.offset);
- }
-
- *backup = retp;
- return (0);
-}
-
-/*
- * __dblist_get --
- * Get the first element of dbenv->dblist with
- * dbp->adj_fileid matching adjid.
- *
- * PUBLIC: DB *__dblist_get __P((DB_ENV *, u_int32_t));
- */
-DB *
-__dblist_get(dbenv, adjid)
- DB_ENV *dbenv;
- u_int32_t adjid;
-{
- DB *dbp;
-
- for (dbp = LIST_FIRST(&dbenv->dblist);
- dbp != NULL && dbp->adj_fileid != adjid;
- dbp = LIST_NEXT(dbp, dblistlinks))
- ;
-
- return (dbp);
-}
-
-/*
- * __db_disassociate --
- * Destroy the association between a given secondary and its primary.
- */
-static int
-__db_disassociate(sdbp)
- DB *sdbp;
-{
- DBC *dbc;
- int ret, t_ret;
-
- ret = 0;
-
- sdbp->s_callback = NULL;
- sdbp->s_primary = NULL;
- sdbp->get = sdbp->stored_get;
- sdbp->close = sdbp->stored_close;
-
- /*
- * Complain, but proceed, if we have any active cursors. (We're in
- * the middle of a close, so there's really no turning back.)
- */
- if (sdbp->s_refcnt != 1 ||
- TAILQ_FIRST(&sdbp->active_queue) != NULL ||
- TAILQ_FIRST(&sdbp->join_queue) != NULL) {
- __db_err(sdbp->dbenv,
- "Closing a primary DB while a secondary DB has active cursors is unsafe");
- ret = EINVAL;
- }
- sdbp->s_refcnt = 0;
-
- while ((dbc = TAILQ_FIRST(&sdbp->free_queue)) != NULL)
- if ((t_ret = __db_c_destroy(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- F_CLR(sdbp, DB_AM_SECONDARY);
- return (ret);
-}
-
-#ifdef CONFIG_TEST
-/*
- * __db_testcopy
- * Create a copy of all backup files and our "main" DB.
- *
- * PUBLIC: #ifdef CONFIG_TEST
- * PUBLIC: int __db_testcopy __P((DB_ENV *, DB *, const char *));
- * PUBLIC: #endif
- */
-int
-__db_testcopy(dbenv, dbp, name)
- DB_ENV *dbenv;
- DB *dbp;
- const char *name;
-{
- DB_MPOOL *dbmp;
- DB_MPOOLFILE *mpf;
-
- DB_ASSERT(dbp != NULL || name != NULL);
-
- if (name == NULL) {
- dbmp = dbenv->mp_handle;
- mpf = dbp->mpf;
- name = R_ADDR(dbmp->reginfo, mpf->mfp->path_off);
- }
-
- if (dbp != NULL && dbp->type == DB_QUEUE)
- return (__qam_testdocopy(dbp, name));
- else
- return (__db_testdocopy(dbenv, name));
-}
-
-static int
-__qam_testdocopy(dbp, name)
- DB *dbp;
- const char *name;
-{
- QUEUE_FILELIST *filelist, *fp;
- char buf[256], *dir;
- int ret;
-
- filelist = NULL;
- if ((ret = __db_testdocopy(dbp->dbenv, name)) != 0)
- return (ret);
- if (dbp->mpf != NULL &&
- (ret = __qam_gen_filelist(dbp, &filelist)) != 0)
- return (ret);
-
- if (filelist == NULL)
- return (0);
- dir = ((QUEUE *)dbp->q_internal)->dir;
- for (fp = filelist; fp->mpf != NULL; fp++) {
- snprintf(buf, sizeof(buf),
- QUEUE_EXTENT, dir, PATH_SEPARATOR[0], name, fp->id);
- if ((ret = __db_testdocopy(dbp->dbenv, buf)) != 0)
- return (ret);
- }
-
- __os_free(dbp->dbenv, filelist);
- return (0);
-}
-
-/*
- * __db_testdocopy
- * Create a copy of all backup files and our "main" DB.
- *
- */
-static int
-__db_testdocopy(dbenv, name)
- DB_ENV *dbenv;
- const char *name;
-{
- size_t len;
- int dircnt, i, ret;
- char *backup, *copy, *dir, **namesp, *p, *real_name;
-
- dircnt = 0;
- copy = backup = NULL;
- namesp = NULL;
-
- /* Get the real backing file name. */
- if ((ret = __db_appname(dbenv,
- DB_APP_DATA, name, 0, NULL, &real_name)) != 0)
- return (ret);
-
- /*
- * Maximum size of file, including adding a ".afterop".
- */
- len = strlen(real_name) +
- strlen(BACKUP_PREFIX) + 1 + MAX_LSN_TO_TEXT + 9;
-
- if ((ret = __os_malloc(dbenv, len, ©)) != 0)
- goto err;
-
- if ((ret = __os_malloc(dbenv, len, &backup)) != 0)
- goto err;
-
- /*
- * First copy the file itself.
- */
- snprintf(copy, len, "%s.afterop", real_name);
- __db_makecopy(dbenv, real_name, copy);
-
- if ((ret = __os_strdup(dbenv, real_name, &dir)) != 0)
- goto err;
- __os_free(dbenv, real_name);
- real_name = NULL;
-
- /*
- * Create the name. Backup file names are of the form:
- *
- * __db.name.0x[lsn-file].0x[lsn-offset]
- *
- * which guarantees uniqueness. We want to look for the
- * backup name, followed by a '.0x' (so that if they have
- * files named, say, 'a' and 'abc' we won't match 'abc' when
- * looking for 'a'.
- */
- snprintf(backup, len, "%s.%s.0x", BACKUP_PREFIX, name);
-
- /*
- * We need the directory path to do the __os_dirlist.
- */
- p = __db_rpath(dir);
- if (p != NULL)
- *p = '\0';
- ret = __os_dirlist(dbenv, dir, &namesp, &dircnt);
-#if DIAGNOSTIC
- /*
- * XXX
- * To get the memory guard code to work because it uses strlen and we
- * just moved the end of the string somewhere sooner. This causes the
- * guard code to fail because it looks at one byte past the end of the
- * string.
- */
- *p = '/';
-#endif
- __os_free(dbenv, dir);
- if (ret != 0)
- goto err;
- for (i = 0; i < dircnt; i++) {
- /*
- * Need to check if it is a backup file for this.
- * No idea what namesp[i] may be or how long, so
- * must use strncmp and not memcmp. We don't want
- * to use strcmp either because we are only matching
- * the first part of the real file's name. We don't
- * know its LSN's.
- */
- if (strncmp(namesp[i], backup, strlen(backup)) == 0) {
- if ((ret = __db_appname(dbenv, DB_APP_DATA,
- namesp[i], 0, NULL, &real_name)) != 0)
- goto err;
-
- /*
- * This should not happen. Check that old
- * .afterop files aren't around.
- * If so, just move on.
- */
- if (strstr(real_name, ".afterop") != NULL) {
- __os_free(dbenv, real_name);
- real_name = NULL;
- continue;
- }
- snprintf(copy, len, "%s.afterop", real_name);
- __db_makecopy(dbenv, real_name, copy);
- __os_free(dbenv, real_name);
- real_name = NULL;
- }
- }
-
-err: if (backup != NULL)
- __os_free(dbenv, backup);
- if (copy != NULL)
- __os_free(dbenv, copy);
- if (namesp != NULL)
- __os_dirfree(dbenv, namesp, dircnt);
- if (real_name != NULL)
- __os_free(dbenv, real_name);
- return (ret);
-}
-
-static void
-__db_makecopy(dbenv, src, dest)
- DB_ENV *dbenv;
- const char *src, *dest;
-{
- DB_FH *rfhp, *wfhp;
- size_t rcnt, wcnt;
- char *buf;
-
- rfhp = wfhp = NULL;
-
- if (__os_malloc(dbenv, 1024, &buf) != 0)
- return;
-
- if (__os_open(dbenv,
- src, DB_OSO_RDONLY, __db_omode(OWNER_RW), &rfhp) != 0)
- goto err;
- if (__os_open(dbenv, dest,
- DB_OSO_CREATE | DB_OSO_TRUNC, __db_omode(OWNER_RW), &wfhp) != 0)
- goto err;
-
- for (;;)
- if (__os_read(dbenv, rfhp, buf, 1024, &rcnt) < 0 || rcnt == 0 ||
- __os_write(dbenv, wfhp, buf, rcnt, &wcnt) < 0)
- break;
-
-err: if (buf != NULL)
- __os_free(dbenv, buf);
- if (rfhp != NULL)
- (void)__os_closehandle(dbenv, rfhp);
- if (wfhp != NULL)
- (void)__os_closehandle(dbenv, wfhp);
-}
-#endif
diff --git a/storage/bdb/db/db.src b/storage/bdb/db/db.src
deleted file mode 100644
index 21fe754a3f7..00000000000
--- a/storage/bdb/db/db.src
+++ /dev/null
@@ -1,259 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db.src,v 12.2 2005/08/08 03:37:06 ubell Exp $
- */
-
-PREFIX __db
-DBPRIVATE
-
-INCLUDE #ifndef NO_SYSTEM_INCLUDES
-INCLUDE #include
-INCLUDE
-INCLUDE #include
-INCLUDE #include
-INCLUDE #endif
-INCLUDE
-INCLUDE #include "db_int.h"
-INCLUDE #include "dbinc/crypto.h"
-INCLUDE #include "dbinc/db_page.h"
-INCLUDE #include "dbinc/db_dispatch.h"
-INCLUDE #include "dbinc/db_am.h"
-INCLUDE #include "dbinc/log.h"
-INCLUDE #include "dbinc/txn.h"
-INCLUDE
-
-/*
- * addrem -- Add or remove an entry from a duplicate page.
- *
- * opcode: identifies if this is an add or delete.
- * fileid: file identifier of the file being modified.
- * pgno: duplicate page number.
- * indx: location at which to insert or delete.
- * nbytes: number of bytes added/removed to/from the page.
- * hdr: header for the data item.
- * dbt: data that is deleted or is to be added.
- * pagelsn: former lsn of the page.
- *
- * If the hdr was NULL then, the dbt is a regular B_KEYDATA.
- * If the dbt was NULL then the hdr is a complete item to be
- * pasted on the page.
- */
-BEGIN addrem 41
-ARG opcode u_int32_t lu
-DB fileid int32_t ld
-ARG pgno db_pgno_t lu
-ARG indx u_int32_t lu
-ARG nbytes u_int32_t lu
-PGDBT hdr DBT s
-DBT dbt DBT s
-POINTER pagelsn DB_LSN * lu
-END
-
-/*
- * big -- Handles addition and deletion of big key/data items.
- *
- * opcode: identifies get/put.
- * fileid: file identifier of the file being modified.
- * pgno: page onto which data is being added/removed.
- * prev_pgno: the page before the one we are logging.
- * next_pgno: the page after the one we are logging.
- * dbt: data being written onto the page.
- * pagelsn: former lsn of the orig_page.
- * prevlsn: former lsn of the prev_pgno.
- * nextlsn: former lsn of the next_pgno. This is not currently used, but
- * may be used later if we actually do overwrites of big key/
- * data items in place.
- */
-BEGIN big 43
-ARG opcode u_int32_t lu
-DB fileid int32_t ld
-ARG pgno db_pgno_t lu
-ARG prev_pgno db_pgno_t lu
-ARG next_pgno db_pgno_t lu
-DBT dbt DBT s
-POINTER pagelsn DB_LSN * lu
-POINTER prevlsn DB_LSN * lu
-POINTER nextlsn DB_LSN * lu
-END
-
-/*
- * ovref -- Handles increment/decrement of overflow page reference count.
- *
- * fileid: identifies the file being modified.
- * pgno: page number whose ref count is being incremented/decremented.
- * adjust: the adjustment being made.
- * lsn: the page's original lsn.
- */
-BEGIN ovref 44
-DB fileid int32_t ld
-ARG pgno db_pgno_t lu
-ARG adjust int32_t ld
-POINTER lsn DB_LSN * lu
-END
-
-/*
- * Debug -- log an operation upon entering an access method.
- * op: Operation (cursor, c_close, c_get, c_put, c_del,
- * get, put, delete).
- * fileid: identifies the file being acted upon.
- * key: key paramater
- * data: data parameter
- * flags: flags parameter
- */
-BEGIN debug 47
-DBT op DBT s
-ARG fileid int32_t ld
-DBT key DBT s
-DBT data DBT s
-ARG arg_flags u_int32_t lu
-END
-
-/*
- * noop -- do nothing, but get an LSN.
- */
-BEGIN noop 48
-DB fileid int32_t ld
-ARG pgno db_pgno_t lu
-POINTER prevlsn DB_LSN * lu
-END
-
-/*
- * pg_alloc: used to record allocating a new page.
- *
- * meta_lsn: the meta-data page's original lsn.
- * meta_pgno the meta-data page number.
- * page_lsn: the allocated page's original lsn.
- * pgno: the page allocated.
- * ptype: the type of the page allocated.
- * next: the next page on the free list.
- * last_pgno: the last page in the file after this op.
- */
-BEGIN pg_alloc 49
-DB fileid int32_t ld
-POINTER meta_lsn DB_LSN * lu
-ARG meta_pgno db_pgno_t lu
-POINTER page_lsn DB_LSN * lu
-ARG pgno db_pgno_t lu
-ARG ptype u_int32_t lu
-ARG next db_pgno_t lu
-ARG last_pgno db_pgno_t lu
-END
-
-/*
- * pg_free: used to record freeing a page.
- *
- * pgno: the page being freed.
- * meta_lsn: the meta-data page's original lsn.
- * meta_pgno: the meta-data page number.
- * header: the header from the free'd page.
- * next: the previous next pointer on the metadata page.
- * last_pgno: the last page in the file before this op.
- */
-BEGIN pg_free 50
-DB fileid int32_t ld
-ARG pgno db_pgno_t lu
-POINTER meta_lsn DB_LSN * lu
-ARG meta_pgno db_pgno_t lu
-PGDBT header DBT s
-ARG next db_pgno_t lu
-ARG last_pgno db_pgno_t lu
-END
-
-/*
- * cksum --
- * This log record is written when we're unable to checksum a page,
- * before returning DB_RUNRECOVERY. This log record causes normal
- * recovery to itself return DB_RUNRECOVERY, as only catastrophic
- * recovery can fix things.
- */
-BEGIN cksum 51
-END
-
-/*
- * pg_freedata: used to record freeing a page with data on it.
- *
- * pgno: the page being freed.
- * meta_lsn: the meta-data page's original lsn.
- * meta_pgno: the meta-data page number.
- * header: the header and index entries from the free'd page.
- * data: the data from the free'd page.
- * next: the previous next pointer on the metadata page.
- * last_pgno: the last page in the file before this op.
- */
-BEGIN pg_freedata 52
-DB fileid int32_t ld
-ARG pgno db_pgno_t lu
-POINTER meta_lsn DB_LSN * lu
-ARG meta_pgno db_pgno_t lu
-PGDBT header DBT s
-ARG next db_pgno_t lu
-ARG last_pgno db_pgno_t lu
-PGDBT data DBT s
-END
-
-/*
- * pg_prepare: used to record an aborted page in a prepared transaction.
- *
- * pgno: the page being freed.
- */
-BEGIN pg_prepare 53
-DB fileid int32_t ld
-ARG pgno db_pgno_t lu
-END
-
-/*
- * pg_new: used to record a new page put on the free list.
- *
- * pgno: the page being freed.
- * meta_lsn: the meta-data page's original lsn.
- * meta_pgno: the meta-data page number.
- * header: the header from the free'd page.
- * next: the previous next pointer on the metadata page.
- */
-BEGIN pg_new 54
-DB fileid int32_t ld
-ARG pgno db_pgno_t lu
-POINTER meta_lsn DB_LSN * lu
-ARG meta_pgno db_pgno_t lu
-PGDBT header DBT s
-ARG next db_pgno_t lu
-END
-
-/*
- * pg_init: used to reinitialize a page during truncate.
- *
- * pgno: the page being initialized.
- * header: the header from the page.
- * data: data that used to be on the page.
- */
-BEGIN pg_init 60
-DB fileid int32_t ld
-ARG pgno db_pgno_t lu
-PGDBT header DBT s
-PGDBT data DBT s
-END
-
-/*
- * pg_sort: sort the free list
- *
- * meta: meta page number
- * meta_lsn: lsn on meta page.
- * last_free: page number of new last free page.
- * last_lsn; lsn of last free page.
- * last_pgno: current last page number.
- * list: list of pages and lsns to sort.
- */
-BEGIN pg_sort 61
-DB fileid int32_t ld
-ARG meta db_pgno_t lu
-POINTER meta_lsn DB_LSN * lu
-ARG last_free db_pgno_t lu
-POINTER last_lsn DB_LSN * lu
-ARG last_pgno db_pgno_t lu
-DBT list DBT s
-END
-
diff --git a/storage/bdb/db/db_am.c b/storage/bdb/db/db_am.c
deleted file mode 100644
index 966f5f07123..00000000000
--- a/storage/bdb/db/db_am.c
+++ /dev/null
@@ -1,904 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1998-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_am.c,v 12.12 2005/11/01 00:44:09 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/btree.h"
-#include "dbinc/hash.h"
-#include "dbinc/lock.h"
-#include "dbinc/log.h"
-#include "dbinc/mp.h"
-#include "dbinc/qam.h"
-
-static int __db_append_primary __P((DBC *, DBT *, DBT *));
-static int __db_secondary_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
-
-/*
- * __db_cursor_int --
- * Internal routine to create a cursor.
- *
- * PUBLIC: int __db_cursor_int
- * PUBLIC: __P((DB *, DB_TXN *, DBTYPE, db_pgno_t, int, u_int32_t, DBC **));
- */
-int
-__db_cursor_int(dbp, txn, dbtype, root, is_opd, lockerid, dbcp)
- DB *dbp;
- DB_TXN *txn;
- DBTYPE dbtype;
- db_pgno_t root;
- int is_opd;
- u_int32_t lockerid;
- DBC **dbcp;
-{
- DBC *dbc;
- DBC_INTERNAL *cp;
- DB_ENV *dbenv;
- db_threadid_t tid;
- int allocated, ret;
- pid_t pid;
-
- dbenv = dbp->dbenv;
- allocated = 0;
-
- /*
- * If dbcp is non-NULL it is assumed to point to an area to initialize
- * as a cursor.
- *
- * Take one from the free list if it's available. Take only the
- * right type. With off page dups we may have different kinds
- * of cursors on the queue for a single database.
- */
- MUTEX_LOCK(dbenv, dbp->mutex);
- for (dbc = TAILQ_FIRST(&dbp->free_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
- if (dbtype == dbc->dbtype) {
- TAILQ_REMOVE(&dbp->free_queue, dbc, links);
- F_CLR(dbc, ~DBC_OWN_LID);
- break;
- }
- MUTEX_UNLOCK(dbenv, dbp->mutex);
-
- if (dbc == NULL) {
- if ((ret = __os_calloc(dbenv, 1, sizeof(DBC), &dbc)) != 0)
- return (ret);
- allocated = 1;
- dbc->flags = 0;
-
- dbc->dbp = dbp;
-
- /* Set up locking information. */
- if (LOCKING_ON(dbenv)) {
- /*
- * If we are not threaded, we share a locker ID among
- * all cursors opened in the environment handle,
- * allocating one if this is the first cursor.
- *
- * This relies on the fact that non-threaded DB handles
- * always have non-threaded environment handles, since
- * we set DB_THREAD on DB handles created with threaded
- * environment handles.
- */
- if (!DB_IS_THREADED(dbp)) {
- if (dbp->dbenv->env_lref == NULL &&
- (ret = __lock_id(dbenv, NULL,
- (DB_LOCKER **)&dbp->dbenv->env_lref)) != 0)
- goto err;
- dbc->lref = dbp->dbenv->env_lref;
- } else {
- if ((ret = __lock_id(dbenv, NULL,
- (DB_LOCKER **)&dbc->lref)) != 0)
- goto err;
- F_SET(dbc, DBC_OWN_LID);
- }
-
- /*
- * In CDB, secondary indices should share a lock file
- * ID with the primary; otherwise we're susceptible
- * to deadlocks. We also use __db_cursor_int rather
- * than __db_cursor to create secondary update cursors
- * in c_put and c_del; these won't acquire a new lock.
- *
- * !!!
- * Since this is in the one-time cursor allocation
- * code, we need to be sure to destroy, not just
- * close, all cursors in the secondary when we
- * associate.
- */
- if (CDB_LOCKING(dbenv) &&
- F_ISSET(dbp, DB_AM_SECONDARY))
- memcpy(dbc->lock.fileid,
- dbp->s_primary->fileid, DB_FILE_ID_LEN);
- else
- memcpy(dbc->lock.fileid,
- dbp->fileid, DB_FILE_ID_LEN);
-
- if (CDB_LOCKING(dbenv)) {
- if (F_ISSET(dbenv, DB_ENV_CDB_ALLDB)) {
- /*
- * If we are doing a single lock per
- * environment, set up the global
- * lock object just like we do to
- * single thread creates.
- */
- DB_ASSERT(sizeof(db_pgno_t) ==
- sizeof(u_int32_t));
- dbc->lock_dbt.size = sizeof(u_int32_t);
- dbc->lock_dbt.data = &dbc->lock.pgno;
- dbc->lock.pgno = 0;
- } else {
- dbc->lock_dbt.size = DB_FILE_ID_LEN;
- dbc->lock_dbt.data = dbc->lock.fileid;
- }
- } else {
- dbc->lock.type = DB_PAGE_LOCK;
- dbc->lock_dbt.size = sizeof(dbc->lock);
- dbc->lock_dbt.data = &dbc->lock;
- }
- }
- /* Init the DBC internal structure. */
- switch (dbtype) {
- case DB_BTREE:
- case DB_RECNO:
- if ((ret = __bam_c_init(dbc, dbtype)) != 0)
- goto err;
- break;
- case DB_HASH:
- if ((ret = __ham_c_init(dbc)) != 0)
- goto err;
- break;
- case DB_QUEUE:
- if ((ret = __qam_c_init(dbc)) != 0)
- goto err;
- break;
- case DB_UNKNOWN:
- default:
- ret = __db_unknown_type(dbenv, "DB->cursor", dbtype);
- goto err;
- }
-
- cp = dbc->internal;
- }
-
- /* Refresh the DBC structure. */
- dbc->dbtype = dbtype;
- RESET_RET_MEM(dbc);
-
- if ((dbc->txn = txn) != NULL)
- dbc->locker = txn->txnid;
- else if (LOCKING_ON(dbenv)) {
- /*
- * There are certain cases in which we want to create a
- * new cursor with a particular locker ID that is known
- * to be the same as (and thus not conflict with) an
- * open cursor.
- *
- * The most obvious case is cursor duplication; when we
- * call DBC->c_dup or __db_c_idup, we want to use the original
- * cursor's locker ID.
- *
- * Another case is when updating secondary indices. Standard
- * CDB locking would mean that we might block ourself: we need
- * to open an update cursor in the secondary while an update
- * cursor in the primary is open, and when the secondary and
- * primary are subdatabases or we're using env-wide locking,
- * this is disastrous.
- *
- * In these cases, our caller will pass a nonzero locker
- * ID into this function. Use this locker ID instead of
- * the default as the locker ID for our new cursor.
- */
- if (lockerid != DB_LOCK_INVALIDID)
- dbc->locker = lockerid;
- else {
- /*
- * If we are threaded then we need to set the
- * proper thread id into the locker.
- */
- if (DB_IS_THREADED(dbp)) {
- dbenv->thread_id(dbenv, &pid, &tid);
- __lock_set_thread_id(
- (DB_LOCKER *)dbc->lref, pid, tid);
- }
- dbc->locker = ((DB_LOCKER *)dbc->lref)->id;
- }
- }
-
- /*
- * These fields change when we are used as a secondary index, so
- * if the DB is a secondary, make sure they're set properly just
- * in case we opened some cursors before we were associated.
- *
- * __db_c_get is used by all access methods, so this should be safe.
- */
- if (F_ISSET(dbp, DB_AM_SECONDARY))
- dbc->c_get = __db_c_secondary_get_pp;
-
- if (is_opd)
- F_SET(dbc, DBC_OPD);
- if (F_ISSET(dbp, DB_AM_RECOVER))
- F_SET(dbc, DBC_RECOVER);
- if (F_ISSET(dbp, DB_AM_COMPENSATE))
- F_SET(dbc, DBC_COMPENSATE);
-
- /* Refresh the DBC internal structure. */
- cp = dbc->internal;
- cp->opd = NULL;
-
- cp->indx = 0;
- cp->page = NULL;
- cp->pgno = PGNO_INVALID;
- cp->root = root;
-
- switch (dbtype) {
- case DB_BTREE:
- case DB_RECNO:
- if ((ret = __bam_c_refresh(dbc)) != 0)
- goto err;
- break;
- case DB_HASH:
- case DB_QUEUE:
- break;
- case DB_UNKNOWN:
- default:
- ret = __db_unknown_type(dbenv, "DB->cursor", dbp->type);
- goto err;
- }
-
- /*
- * The transaction keeps track of how many cursors were opened within
- * it to catch application errors where the cursor isn't closed when
- * the transaction is resolved.
- */
- if (txn != NULL)
- ++txn->cursors;
-
- MUTEX_LOCK(dbenv, dbp->mutex);
- TAILQ_INSERT_TAIL(&dbp->active_queue, dbc, links);
- F_SET(dbc, DBC_ACTIVE);
- MUTEX_UNLOCK(dbenv, dbp->mutex);
-
- *dbcp = dbc;
- return (0);
-
-err: if (allocated)
- __os_free(dbenv, dbc);
- return (ret);
-}
-
-/*
- * __db_put --
- * Store a key/data pair.
- *
- * PUBLIC: int __db_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_put(dbp, txn, key, data, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key, *data;
- u_int32_t flags;
-{
- DBC *dbc;
- DBT tdata;
- DB_ENV *dbenv;
- int ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- if ((ret = __db_cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, txn, "DB->put", key, data, flags);
-
- SET_RET_MEM(dbc, dbp);
-
- /*
- * See the comment in __db_get().
- *
- * Note that the c_get in the DB_NOOVERWRITE case is safe to
- * do with this flag set; if it errors in any way other than
- * DB_NOTFOUND, we're going to close the cursor without doing
- * anything else, and if it returns DB_NOTFOUND then it's safe
- * to do a c_put(DB_KEYLAST) even if an access method moved the
- * cursor, since that's not position-dependent.
- */
- F_SET(dbc, DBC_TRANSIENT);
-
- switch (flags) {
- case DB_APPEND:
- /*
- * If there is an append callback, the value stored in
- * data->data may be replaced and then freed. To avoid
- * passing a freed pointer back to the user, just operate
- * on a copy of the data DBT.
- */
- tdata = *data;
-
- /*
- * Append isn't a normal put operation; call the appropriate
- * access method's append function.
- */
- switch (dbp->type) {
- case DB_QUEUE:
- if ((ret = __qam_append(dbc, key, &tdata)) != 0)
- goto err;
- break;
- case DB_RECNO:
- if ((ret = __ram_append(dbc, key, &tdata)) != 0)
- goto err;
- break;
- case DB_BTREE:
- case DB_HASH:
- case DB_UNKNOWN:
- default:
- /* The interface should prevent this. */
- DB_ASSERT(
- dbp->type == DB_QUEUE || dbp->type == DB_RECNO);
-
- ret = __db_ferr(dbenv, "DB->put", 0);
- goto err;
- }
-
- /*
- * Secondary indices: since we've returned zero from
- * an append function, we've just put a record, and done
- * so outside __db_c_put. We know we're not a secondary--
- * the interface prevents puts on them--but we may be a
- * primary. If so, update our secondary indices
- * appropriately.
- */
- DB_ASSERT(!F_ISSET(dbp, DB_AM_SECONDARY));
-
- if (LIST_FIRST(&dbp->s_secondaries) != NULL)
- ret = __db_append_primary(dbc, key, &tdata);
-
- /*
- * The append callback, if one exists, may have allocated
- * a new tdata.data buffer. If so, free it.
- */
- FREE_IF_NEEDED(dbp, &tdata);
-
- /* No need for a cursor put; we're done. */
- goto done;
- case DB_NOOVERWRITE:
- flags = 0;
- /*
- * Set DB_DBT_USERMEM, this might be a threaded application and
- * the flags checking will catch us. We don't want the actual
- * data, so request a partial of length 0.
- */
- memset(&tdata, 0, sizeof(tdata));
- F_SET(&tdata, DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- /*
- * If we're doing page-level locking, set the read-modify-write
- * flag, we're going to overwrite immediately.
- */
- if ((ret = __db_c_get(dbc, key, &tdata,
- DB_SET | (STD_LOCKING(dbc) ? DB_RMW : 0))) == 0)
- ret = DB_KEYEXIST;
- else if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
- ret = 0;
- break;
- default:
- /* Fall through to normal cursor put. */
- break;
- }
-
- if (ret == 0)
- ret = __db_c_put(dbc,
- key, data, flags == 0 ? DB_KEYLAST : flags);
-
-err:
-done: /* Close the cursor. */
- if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_del --
- * Delete the items referenced by a key.
- *
- * PUBLIC: int __db_del __P((DB *, DB_TXN *, DBT *, u_int32_t));
- */
-int
-__db_del(dbp, txn, key, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key;
- u_int32_t flags;
-{
- DBC *dbc;
- DBT data, lkey;
- u_int32_t f_init, f_next;
- int ret, t_ret;
-
- /* Allocate a cursor. */
- if ((ret = __db_cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0)
- goto err;
-
- DEBUG_LWRITE(dbc, txn, "DB->del", key, NULL, flags);
- COMPQUIET(flags, 0);
-
- /*
- * Walk a cursor through the key/data pairs, deleting as we go. Set
- * the DB_DBT_USERMEM flag, as this might be a threaded application
- * and the flags checking will catch us. We don't actually want the
- * keys or data, so request a partial of length 0.
- */
- memset(&lkey, 0, sizeof(lkey));
- F_SET(&lkey, DB_DBT_USERMEM | DB_DBT_PARTIAL);
- memset(&data, 0, sizeof(data));
- F_SET(&data, DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- /*
- * If locking (and we haven't already acquired CDB locks), set the
- * read-modify-write flag.
- */
- f_init = DB_SET;
- f_next = DB_NEXT_DUP;
- if (STD_LOCKING(dbc)) {
- f_init |= DB_RMW;
- f_next |= DB_RMW;
- }
-
- /*
- * Optimize the simple cases. For all AMs if we don't have secondaries
- * and are not a secondary and there are no dups then we can avoid a
- * bunch of overhead. For queue we don't need to fetch the record since
- * we delete by direct calculation from the record number.
- *
- * Hash permits an optimization in DB->del: since on-page duplicates are
- * stored in a single HKEYDATA structure, it's possible to delete an
- * entire set of them at once, and as the HKEYDATA has to be rebuilt
- * and re-put each time it changes, this is much faster than deleting
- * the duplicates one by one. Thus, if not pointing at an off-page
- * duplicate set, and we're not using secondary indices (in which case
- * we'd have to examine the items one by one anyway), let hash do this
- * "quick delete".
- *
- * !!!
- * Note that this is the only application-executed delete call in
- * Berkeley DB that does not go through the __db_c_del function.
- * If anything other than the delete itself (like a secondary index
- * update) has to happen there in a particular situation, the
- * conditions here should be modified not to use these optimizations.
- * The ordinary AM-independent alternative will work just fine;
- * it'll just be slower.
- */
- if (!F_ISSET(dbp, DB_AM_SECONDARY) &&
- LIST_FIRST(&dbp->s_secondaries) == NULL) {
-
-#ifdef HAVE_QUEUE
- if (dbp->type == DB_QUEUE) {
- ret = __qam_delete(dbc, key);
- goto done;
- }
-#endif
-
- /* Fetch the first record. */
- if ((ret = __db_c_get(dbc, key, &data, f_init)) != 0)
- goto err;
-
-#ifdef HAVE_HASH
- if (dbp->type == DB_HASH && dbc->internal->opd == NULL) {
- ret = __ham_quick_delete(dbc);
- goto done;
- }
-#endif
-
- if ((dbp->type == DB_BTREE || dbp->type == DB_RECNO) &&
- !F_ISSET(dbp, DB_AM_DUP)) {
- ret = dbc->c_am_del(dbc);
- goto done;
- }
- } else if ((ret = __db_c_get(dbc, key, &data, f_init)) != 0)
- goto err;
-
- /* Walk through the set of key/data pairs, deleting as we go. */
- for (;;) {
- if ((ret = __db_c_del(dbc, 0)) != 0)
- break;
- if ((ret = __db_c_get(dbc, &lkey, &data, f_next)) != 0) {
- if (ret == DB_NOTFOUND)
- ret = 0;
- break;
- }
- }
-
-done:
-err: /* Discard the cursor. */
- if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_sync --
- * Flush the database cache.
- *
- * PUBLIC: int __db_sync __P((DB *));
- */
-int
-__db_sync(dbp)
- DB *dbp;
-{
- int ret, t_ret;
-
- ret = 0;
-
- /* If the database was read-only, we're done. */
- if (F_ISSET(dbp, DB_AM_RDONLY))
- return (0);
-
- /* If it's a Recno tree, write the backing source text file. */
- if (dbp->type == DB_RECNO)
- ret = __ram_writeback(dbp);
-
- /* If the database was never backed by a database file, we're done. */
- if (F_ISSET(dbp, DB_AM_INMEM))
- return (ret);
-
- if (dbp->type == DB_QUEUE)
- ret = __qam_sync(dbp);
- else
- /* Flush any dirty pages from the cache to the backing file. */
- if ((t_ret = __memp_fsync(dbp->mpf)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_associate --
- * Associate another database as a secondary index to this one.
- *
- * PUBLIC: int __db_associate __P((DB *, DB_TXN *, DB *,
- * PUBLIC: int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t));
- */
-int
-__db_associate(dbp, txn, sdbp, callback, flags)
- DB *dbp, *sdbp;
- DB_TXN *txn;
- int (*callback) __P((DB *, const DBT *, const DBT *, DBT *));
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DBC *pdbc, *sdbc;
- DBT skey, key, data;
- int build, ret, t_ret;
-
- dbenv = dbp->dbenv;
- pdbc = sdbc = NULL;
- ret = 0;
-
- /*
- * Check to see if the secondary is empty -- and thus if we should
- * build it -- before we link it in and risk making it show up in other
- * threads. Do this first so that the databases remain unassociated on
- * error.
- */
- build = 0;
- if (LF_ISSET(DB_CREATE)) {
- if ((ret = __db_cursor(sdbp, txn, &sdbc, 0)) != 0)
- goto err;
-
- /*
- * We don't care about key or data; we're just doing
- * an existence check.
- */
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
- F_SET(&key, DB_DBT_PARTIAL | DB_DBT_USERMEM);
- F_SET(&data, DB_DBT_PARTIAL | DB_DBT_USERMEM);
- if ((ret = __db_c_get(sdbc, &key, &data,
- (STD_LOCKING(sdbc) ? DB_RMW : 0) |
- DB_FIRST)) == DB_NOTFOUND) {
- build = 1;
- ret = 0;
- }
-
- if ((t_ret = __db_c_close(sdbc)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Reset for later error check. */
- sdbc = NULL;
-
- if (ret != 0)
- goto err;
- }
-
- /*
- * Set up the database handle as a secondary.
- */
- sdbp->s_callback = callback;
- sdbp->s_primary = dbp;
-
- sdbp->stored_get = sdbp->get;
- sdbp->get = __db_secondary_get;
-
- sdbp->stored_close = sdbp->close;
- sdbp->close = __db_secondary_close_pp;
-
- F_SET(sdbp, DB_AM_SECONDARY);
-
- if (LF_ISSET(DB_IMMUTABLE_KEY))
- FLD_SET(sdbp->s_assoc_flags, DB_ASSOC_IMMUTABLE_KEY);
-
- /*
- * Add the secondary to the list on the primary. Do it here
- * so that we see any updates that occur while we're walking
- * the primary.
- */
- MUTEX_LOCK(dbenv, dbp->mutex);
-
- /* See __db_s_next for an explanation of secondary refcounting. */
- DB_ASSERT(sdbp->s_refcnt == 0);
- sdbp->s_refcnt = 1;
- LIST_INSERT_HEAD(&dbp->s_secondaries, sdbp, s_links);
- MUTEX_UNLOCK(dbenv, dbp->mutex);
-
- if (build) {
- /*
- * We loop through the primary, putting each item we
- * find into the new secondary.
- *
- * If we're using CDB, opening these two cursors puts us
- * in a bit of a locking tangle: CDB locks are done on the
- * primary, so that we stay deadlock-free, but that means
- * that updating the secondary while we have a read cursor
- * open on the primary will self-block. To get around this,
- * we force the primary cursor to use the same locker ID
- * as the secondary, so they won't conflict. This should
- * be harmless even if we're not using CDB.
- */
- if ((ret = __db_cursor(sdbp, txn, &sdbc,
- CDB_LOCKING(sdbp->dbenv) ? DB_WRITECURSOR : 0)) != 0)
- goto err;
- if ((ret = __db_cursor_int(dbp,
- txn, dbp->type, PGNO_INVALID, 0, sdbc->locker, &pdbc)) != 0)
- goto err;
-
- /* Lock out other threads, now that we have a locker ID. */
- dbp->associate_lid = sdbc->locker;
-
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
- while ((ret = __db_c_get(pdbc, &key, &data, DB_NEXT)) == 0) {
- memset(&skey, 0, sizeof(DBT));
- if ((ret = callback(sdbp, &key, &data, &skey)) != 0) {
- if (ret == DB_DONOTINDEX)
- continue;
- goto err;
- }
- SWAP_IF_NEEDED(dbp, sdbp, &key);
- if ((ret = __db_c_put(sdbc,
- &skey, &key, DB_UPDATE_SECONDARY)) != 0) {
- FREE_IF_NEEDED(sdbp, &skey);
- goto err;
- }
- SWAP_IF_NEEDED(dbp, sdbp, &key);
-
- FREE_IF_NEEDED(sdbp, &skey);
- }
- if (ret == DB_NOTFOUND)
- ret = 0;
- }
-
-err: if (sdbc != NULL && (t_ret = __db_c_close(sdbc)) != 0 && ret == 0)
- ret = t_ret;
-
- if (pdbc != NULL && (t_ret = __db_c_close(pdbc)) != 0 && ret == 0)
- ret = t_ret;
-
- dbp->associate_lid = DB_LOCK_INVALIDID;
-
- return (ret);
-}
-
-/*
- * __db_secondary_get --
- * This wrapper function for DB->pget() is the DB->get() function
- * on a database which has been made into a secondary index.
- */
-static int
-__db_secondary_get(sdbp, txn, skey, data, flags)
- DB *sdbp;
- DB_TXN *txn;
- DBT *skey, *data;
- u_int32_t flags;
-{
-
- DB_ASSERT(F_ISSET(sdbp, DB_AM_SECONDARY));
- return (__db_pget_pp(sdbp, txn, skey, NULL, data, flags));
-}
-
-/*
- * __db_secondary_close --
- * Wrapper function for DB->close() which we use on secondaries to
- * manage refcounting and make sure we don't close them underneath
- * a primary that is updating.
- *
- * PUBLIC: int __db_secondary_close __P((DB *, u_int32_t));
- */
-int
-__db_secondary_close(sdbp, flags)
- DB *sdbp;
- u_int32_t flags;
-{
- DB *primary;
- int doclose;
-
- doclose = 0;
- primary = sdbp->s_primary;
-
- MUTEX_LOCK(primary->dbenv, primary->mutex);
- /*
- * Check the refcount--if it was at 1 when we were called, no
- * thread is currently updating this secondary through the primary,
- * so it's safe to close it for real.
- *
- * If it's not safe to do the close now, we do nothing; the
- * database will actually be closed when the refcount is decremented,
- * which can happen in either __db_s_next or __db_s_done.
- */
- DB_ASSERT(sdbp->s_refcnt != 0);
- if (--sdbp->s_refcnt == 0) {
- LIST_REMOVE(sdbp, s_links);
- /* We don't want to call close while the mutex is held. */
- doclose = 1;
- }
- MUTEX_UNLOCK(primary->dbenv, primary->mutex);
-
- /*
- * sdbp->close is this function; call the real one explicitly if
- * need be.
- */
- return (doclose ? __db_close(sdbp, NULL, flags) : 0);
-}
-
-/*
- * __db_append_primary --
- * Perform the secondary index updates necessary to put(DB_APPEND)
- * a record to a primary database.
- */
-static int
-__db_append_primary(dbc, key, data)
- DBC *dbc;
- DBT *key, *data;
-{
- DB *dbp, *sdbp;
- DBC *sdbc, *pdbc;
- DBT oldpkey, pkey, pdata, skey;
- int cmp, ret, t_ret;
-
- dbp = dbc->dbp;
- sdbp = NULL;
- ret = 0;
-
- /*
- * Worrying about partial appends seems a little like worrying
- * about Linear A character encodings. But we support those
- * too if your application understands them.
- */
- pdbc = NULL;
- if (F_ISSET(data, DB_DBT_PARTIAL) || F_ISSET(key, DB_DBT_PARTIAL)) {
- /*
- * The dbc we were passed is all set to pass things
- * back to the user; we can't safely do a call on it.
- * Dup the cursor, grab the real data item (we don't
- * care what the key is--we've been passed it directly),
- * and use that instead of the data DBT we were passed.
- *
- * Note that we can get away with this simple get because
- * an appended item is by definition new, and the
- * correctly-constructed full data item from this partial
- * put is on the page waiting for us.
- */
- if ((ret = __db_c_idup(dbc, &pdbc, DB_POSITION)) != 0)
- return (ret);
- memset(&pkey, 0, sizeof(DBT));
- memset(&pdata, 0, sizeof(DBT));
-
- if ((ret = __db_c_get(pdbc, &pkey, &pdata, DB_CURRENT)) != 0)
- goto err;
-
- key = &pkey;
- data = &pdata;
- }
-
- /*
- * Loop through the secondary indices, putting a new item in
- * each that points to the appended item.
- *
- * This is much like the loop in "step 3" in __db_c_put, so
- * I'm not commenting heavily here; it was unclean to excerpt
- * just that section into a common function, but the basic
- * overview is the same here.
- */
- if ((ret = __db_s_first(dbp, &sdbp)) != 0)
- goto err;
- for (; sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp)) {
- memset(&skey, 0, sizeof(DBT));
- if ((ret = sdbp->s_callback(sdbp, key, data, &skey)) != 0) {
- if (ret == DB_DONOTINDEX)
- continue;
- goto err;
- }
-
- if ((ret = __db_cursor_int(sdbp, dbc->txn, sdbp->type,
- PGNO_INVALID, 0, dbc->locker, &sdbc)) != 0) {
- FREE_IF_NEEDED(sdbp, &skey);
- goto err;
- }
- if (CDB_LOCKING(sdbp->dbenv)) {
- DB_ASSERT(sdbc->mylock.off == LOCK_INVALID);
- F_SET(sdbc, DBC_WRITER);
- }
-
- /*
- * Since we know we have a new primary key, it can't be a
- * duplicate duplicate in the secondary. It can be a
- * duplicate in a secondary that doesn't support duplicates,
- * however, so we need to be careful to avoid an overwrite
- * (which would corrupt our index).
- */
- if (!F_ISSET(sdbp, DB_AM_DUP)) {
- memset(&oldpkey, 0, sizeof(DBT));
- F_SET(&oldpkey, DB_DBT_MALLOC);
- ret = __db_c_get(sdbc, &skey, &oldpkey,
- DB_SET | (STD_LOCKING(dbc) ? DB_RMW : 0));
- if (ret == 0) {
- cmp = __bam_defcmp(sdbp, &oldpkey, key);
- /*
- * XXX
- * This needs to use the right free function
- * as soon as this is possible.
- */
- __os_ufree(sdbp->dbenv,
- oldpkey.data);
- if (cmp != 0) {
- __db_err(sdbp->dbenv, "%s%s",
- "Append results in a non-unique secondary key in",
- " an index not configured to support duplicates");
- ret = EINVAL;
- goto err1;
- }
- } else if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY)
- goto err1;
- }
-
- ret = __db_c_put(sdbc, &skey, key, DB_UPDATE_SECONDARY);
-
-err1: FREE_IF_NEEDED(sdbp, &skey);
-
- if ((t_ret = __db_c_close(sdbc)) != 0 && ret == 0)
- ret = t_ret;
- if (ret != 0)
- goto err;
- }
-
-err: if (pdbc != NULL && (t_ret = __db_c_close(pdbc)) != 0 && ret == 0)
- ret = t_ret;
- if (sdbp != NULL && (t_ret = __db_s_done(sdbp)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
diff --git a/storage/bdb/db/db_cam.c b/storage/bdb/db/db_cam.c
deleted file mode 100644
index f7b93ad36b1..00000000000
--- a/storage/bdb/db/db_cam.c
+++ /dev/null
@@ -1,2367 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 2000-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_cam.c,v 12.21 2005/10/07 20:21:22 ubell Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/btree.h"
-#include "dbinc/hash.h"
-#include "dbinc/lock.h"
-#include "dbinc/mp.h"
-#include "dbinc/qam.h"
-
-static int __db_buildpartial __P((DB *, DBT *, DBT *, DBT *));
-static int __db_c_cleanup __P((DBC *, DBC *, int));
-static int __db_c_del_secondary __P((DBC *));
-static int __db_c_pget_recno __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __db_wrlock_err __P((DB_ENV *));
-
-#define CDB_LOCKING_INIT(dbp, dbc) \
- /* \
- * If we are running CDB, this had better be either a write \
- * cursor or an immediate writer. If it's a regular writer, \
- * that means we have an IWRITE lock and we need to upgrade \
- * it to a write lock. \
- */ \
- if (CDB_LOCKING((dbp)->dbenv)) { \
- if (!F_ISSET(dbc, DBC_WRITECURSOR | DBC_WRITER)) \
- return (__db_wrlock_err(dbp->dbenv)); \
- \
- if (F_ISSET(dbc, DBC_WRITECURSOR) && \
- (ret = __lock_get((dbp)->dbenv, \
- (dbc)->locker, DB_LOCK_UPGRADE, &(dbc)->lock_dbt, \
- DB_LOCK_WRITE, &(dbc)->mylock)) != 0) \
- return (ret); \
- }
-#define CDB_LOCKING_DONE(dbp, dbc) \
- /* Release the upgraded lock. */ \
- if (F_ISSET(dbc, DBC_WRITECURSOR)) \
- (void)__lock_downgrade( \
- (dbp)->dbenv, &(dbc)->mylock, DB_LOCK_IWRITE, 0);
-
-/*
- * __db_c_close --
- * DBC->c_close.
- *
- * PUBLIC: int __db_c_close __P((DBC *));
- */
-int
-__db_c_close(dbc)
- DBC *dbc;
-{
- DB *dbp;
- DBC *opd;
- DBC_INTERNAL *cp;
- DB_ENV *dbenv;
- int ret, t_ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
- cp = dbc->internal;
- opd = cp->opd;
- ret = 0;
-
- /*
- * Remove the cursor(s) from the active queue. We may be closing two
- * cursors at once here, a top-level one and a lower-level, off-page
- * duplicate one. The access-method specific cursor close routine must
- * close both of them in a single call.
- *
- * !!!
- * Cursors must be removed from the active queue before calling the
- * access specific cursor close routine, btree depends on having that
- * order of operations.
- */
- MUTEX_LOCK(dbenv, dbp->mutex);
-
- if (opd != NULL) {
- DB_ASSERT(F_ISSET(opd, DBC_ACTIVE));
- F_CLR(opd, DBC_ACTIVE);
- TAILQ_REMOVE(&dbp->active_queue, opd, links);
- }
- DB_ASSERT(F_ISSET(dbc, DBC_ACTIVE));
- F_CLR(dbc, DBC_ACTIVE);
- TAILQ_REMOVE(&dbp->active_queue, dbc, links);
-
- MUTEX_UNLOCK(dbenv, dbp->mutex);
-
- /* Call the access specific cursor close routine. */
- if ((t_ret =
- dbc->c_am_close(dbc, PGNO_INVALID, NULL)) != 0 && ret == 0)
- ret = t_ret;
-
- /*
- * Release the lock after calling the access method specific close
- * routine, a Btree cursor may have had pending deletes.
- */
- if (CDB_LOCKING(dbenv)) {
- /*
- * Also, be sure not to free anything if mylock.off is
- * INVALID; in some cases, such as idup'ed read cursors
- * and secondary update cursors, a cursor in a CDB
- * environment may not have a lock at all.
- */
- if ((t_ret = __LPUT(dbc, dbc->mylock)) != 0 && ret == 0)
- ret = t_ret;
-
- /* For safety's sake, since this is going on the free queue. */
- memset(&dbc->mylock, 0, sizeof(dbc->mylock));
- if (opd != NULL)
- memset(&opd->mylock, 0, sizeof(opd->mylock));
- }
-
- if (dbc->txn != NULL)
- dbc->txn->cursors--;
-
- /* Move the cursor(s) to the free queue. */
- MUTEX_LOCK(dbenv, dbp->mutex);
- if (opd != NULL) {
- if (dbc->txn != NULL)
- dbc->txn->cursors--;
- TAILQ_INSERT_TAIL(&dbp->free_queue, opd, links);
- opd = NULL;
- }
- TAILQ_INSERT_TAIL(&dbp->free_queue, dbc, links);
- MUTEX_UNLOCK(dbenv, dbp->mutex);
-
- return (ret);
-}
-
-/*
- * __db_c_destroy --
- * Destroy the cursor, called after DBC->c_close.
- *
- * PUBLIC: int __db_c_destroy __P((DBC *));
- */
-int
-__db_c_destroy(dbc)
- DBC *dbc;
-{
- DB *dbp;
- DB_ENV *dbenv;
- int ret, t_ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- /* Remove the cursor from the free queue. */
- MUTEX_LOCK(dbenv, dbp->mutex);
- TAILQ_REMOVE(&dbp->free_queue, dbc, links);
- MUTEX_UNLOCK(dbenv, dbp->mutex);
-
- /* Free up allocated memory. */
- if (dbc->my_rskey.data != NULL)
- __os_free(dbenv, dbc->my_rskey.data);
- if (dbc->my_rkey.data != NULL)
- __os_free(dbenv, dbc->my_rkey.data);
- if (dbc->my_rdata.data != NULL)
- __os_free(dbenv, dbc->my_rdata.data);
-
- /* Call the access specific cursor destroy routine. */
- ret = dbc->c_am_destroy == NULL ? 0 : dbc->c_am_destroy(dbc);
-
- /*
- * Release the lock id for this cursor.
- */
- if (LOCKING_ON(dbenv) &&
- F_ISSET(dbc, DBC_OWN_LID) &&
- (t_ret = __lock_id_free(dbenv,
- ((DB_LOCKER *)dbc->lref)->id)) != 0 && ret == 0)
- ret = t_ret;
-
- __os_free(dbenv, dbc);
-
- return (ret);
-}
-
-/*
- * __db_c_count --
- * Return a count of duplicate data items.
- *
- * PUBLIC: int __db_c_count __P((DBC *, db_recno_t *));
- */
-int
-__db_c_count(dbc, recnop)
- DBC *dbc;
- db_recno_t *recnop;
-{
- DB_ENV *dbenv;
- int ret;
-
- dbenv = dbc->dbp->dbenv;
-
- /*
- * Cursor Cleanup Note:
- * All of the cursors passed to the underlying access methods by this
- * routine are not duplicated and will not be cleaned up on return.
- * So, pages/locks that the cursor references must be resolved by the
- * underlying functions.
- */
- switch (dbc->dbtype) {
- case DB_QUEUE:
- case DB_RECNO:
- *recnop = 1;
- break;
- case DB_HASH:
- if (dbc->internal->opd == NULL) {
- if ((ret = __ham_c_count(dbc, recnop)) != 0)
- return (ret);
- break;
- }
- /* FALLTHROUGH */
- case DB_BTREE:
- if ((ret = __bam_c_count(dbc, recnop)) != 0)
- return (ret);
- break;
- case DB_UNKNOWN:
- default:
- return (__db_unknown_type(dbenv, "__db_c_count", dbc->dbtype));
- }
- return (0);
-}
-
-/*
- * __db_c_del --
- * DBC->c_del.
- *
- * PUBLIC: int __db_c_del __P((DBC *, u_int32_t));
- */
-int
-__db_c_del(dbc, flags)
- DBC *dbc;
- u_int32_t flags;
-{
- DB *dbp;
- DBC *opd;
- int ret, t_ret;
-
- dbp = dbc->dbp;
-
- /*
- * Cursor Cleanup Note:
- * All of the cursors passed to the underlying access methods by this
- * routine are not duplicated and will not be cleaned up on return.
- * So, pages/locks that the cursor references must be resolved by the
- * underlying functions.
- */
-
- CDB_LOCKING_INIT(dbp, dbc);
-
- /*
- * If we're a secondary index, and DB_UPDATE_SECONDARY isn't set
- * (which it only is if we're being called from a primary update),
- * then we need to call through to the primary and delete the item.
- *
- * Note that this will delete the current item; we don't need to
- * delete it ourselves as well, so we can just goto done.
- */
- if (flags != DB_UPDATE_SECONDARY && F_ISSET(dbp, DB_AM_SECONDARY)) {
- ret = __db_c_del_secondary(dbc);
- goto done;
- }
-
- /*
- * If we are a primary and have secondary indices, go through
- * and delete any secondary keys that point at the current record.
- */
- if (LIST_FIRST(&dbp->s_secondaries) != NULL &&
- (ret = __db_c_del_primary(dbc)) != 0)
- goto done;
-
- /*
- * Off-page duplicate trees are locked in the primary tree, that is,
- * we acquire a write lock in the primary tree and no locks in the
- * off-page dup tree. If the del operation is done in an off-page
- * duplicate tree, call the primary cursor's upgrade routine first.
- */
- opd = dbc->internal->opd;
- if (opd == NULL)
- ret = dbc->c_am_del(dbc);
- else
- if ((ret = dbc->c_am_writelock(dbc)) == 0)
- ret = opd->c_am_del(opd);
-
- /*
- * If this was an update that is supporting dirty reads
- * then we may have just swapped our read for a write lock
- * which is held by the surviving cursor. We need
- * to explicitly downgrade this lock. The closed cursor
- * may only have had a read lock.
- */
- if (F_ISSET(dbc->dbp, DB_AM_READ_UNCOMMITTED) &&
- dbc->internal->lock_mode == DB_LOCK_WRITE) {
- if ((t_ret =
- __TLPUT(dbc, dbc->internal->lock)) != 0 && ret == 0)
- ret = t_ret;
- if (t_ret == 0)
- dbc->internal->lock_mode = DB_LOCK_WWRITE;
- }
-
-done: CDB_LOCKING_DONE(dbp, dbc);
-
- return (ret);
-}
-
-/*
- * __db_c_dup --
- * Duplicate a cursor
- *
- * PUBLIC: int __db_c_dup __P((DBC *, DBC **, u_int32_t));
- */
-int
-__db_c_dup(dbc_orig, dbcp, flags)
- DBC *dbc_orig;
- DBC **dbcp;
- u_int32_t flags;
-{
- DBC *dbc_n, *dbc_nopd;
- int ret;
-
- dbc_n = dbc_nopd = NULL;
-
- /* Allocate a new cursor and initialize it. */
- if ((ret = __db_c_idup(dbc_orig, &dbc_n, flags)) != 0)
- goto err;
- *dbcp = dbc_n;
-
- /*
- * If the cursor references an off-page duplicate tree, allocate a
- * new cursor for that tree and initialize it.
- */
- if (dbc_orig->internal->opd != NULL) {
- if ((ret =
- __db_c_idup(dbc_orig->internal->opd, &dbc_nopd, flags)) != 0)
- goto err;
- dbc_n->internal->opd = dbc_nopd;
- }
- return (0);
-
-err: if (dbc_n != NULL)
- (void)__db_c_close(dbc_n);
- if (dbc_nopd != NULL)
- (void)__db_c_close(dbc_nopd);
-
- return (ret);
-}
-
-/*
- * __db_c_idup --
- * Internal version of __db_c_dup.
- *
- * PUBLIC: int __db_c_idup __P((DBC *, DBC **, u_int32_t));
- */
-int
-__db_c_idup(dbc_orig, dbcp, flags)
- DBC *dbc_orig, **dbcp;
- u_int32_t flags;
-{
- DB *dbp;
- DBC *dbc_n;
- DBC_INTERNAL *int_n, *int_orig;
- int ret;
-
- dbp = dbc_orig->dbp;
- dbc_n = *dbcp;
-
- if ((ret = __db_cursor_int(dbp, dbc_orig->txn, dbc_orig->dbtype,
- dbc_orig->internal->root, F_ISSET(dbc_orig, DBC_OPD),
- dbc_orig->locker, &dbc_n)) != 0)
- return (ret);
-
- /* Position the cursor if requested, acquiring the necessary locks. */
- if (flags == DB_POSITION) {
- int_n = dbc_n->internal;
- int_orig = dbc_orig->internal;
-
- dbc_n->flags |= dbc_orig->flags & ~DBC_OWN_LID;
-
- int_n->indx = int_orig->indx;
- int_n->pgno = int_orig->pgno;
- int_n->root = int_orig->root;
- int_n->lock_mode = int_orig->lock_mode;
-
- switch (dbc_orig->dbtype) {
- case DB_QUEUE:
- if ((ret = __qam_c_dup(dbc_orig, dbc_n)) != 0)
- goto err;
- break;
- case DB_BTREE:
- case DB_RECNO:
- if ((ret = __bam_c_dup(dbc_orig, dbc_n)) != 0)
- goto err;
- break;
- case DB_HASH:
- if ((ret = __ham_c_dup(dbc_orig, dbc_n)) != 0)
- goto err;
- break;
- case DB_UNKNOWN:
- default:
- ret = __db_unknown_type(dbp->dbenv,
- "__db_c_idup", dbc_orig->dbtype);
- goto err;
- }
- }
-
- /* Copy the locking flags to the new cursor. */
- F_SET(dbc_n, F_ISSET(dbc_orig,
- DBC_READ_COMMITTED | DBC_READ_UNCOMMITTED | DBC_WRITECURSOR));
-
- /*
- * If we're in CDB and this isn't an offpage dup cursor, then
- * we need to get a lock for the duplicated cursor.
- */
- if (CDB_LOCKING(dbp->dbenv) && !F_ISSET(dbc_n, DBC_OPD) &&
- (ret = __lock_get(dbp->dbenv, dbc_n->locker, 0,
- &dbc_n->lock_dbt, F_ISSET(dbc_orig, DBC_WRITECURSOR) ?
- DB_LOCK_IWRITE : DB_LOCK_READ, &dbc_n->mylock)) != 0)
- goto err;
-
- *dbcp = dbc_n;
- return (0);
-
-err: (void)__db_c_close(dbc_n);
- return (ret);
-}
-
-/*
- * __db_c_newopd --
- * Create a new off-page duplicate cursor.
- *
- * PUBLIC: int __db_c_newopd __P((DBC *, db_pgno_t, DBC *, DBC **));
- */
-int
-__db_c_newopd(dbc_parent, root, oldopd, dbcp)
- DBC *dbc_parent;
- db_pgno_t root;
- DBC *oldopd;
- DBC **dbcp;
-{
- DB *dbp;
- DBC *opd;
- DBTYPE dbtype;
- int ret;
-
- dbp = dbc_parent->dbp;
- dbtype = (dbp->dup_compare == NULL) ? DB_RECNO : DB_BTREE;
-
- /*
- * On failure, we want to default to returning the old off-page dup
- * cursor, if any; our caller can't be left with a dangling pointer
- * to a freed cursor. On error the only allowable behavior is to
- * close the cursor (and the old OPD cursor it in turn points to), so
- * this should be safe.
- */
- *dbcp = oldopd;
-
- if ((ret = __db_cursor_int(dbp,
- dbc_parent->txn, dbtype, root, 1, dbc_parent->locker, &opd)) != 0)
- return (ret);
-
- *dbcp = opd;
-
- /*
- * Check to see if we already have an off-page dup cursor that we've
- * passed in. If we do, close it. It'd be nice to use it again
- * if it's a cursor belonging to the right tree, but if we're doing
- * a cursor-relative operation this might not be safe, so for now
- * we'll take the easy way out and always close and reopen.
- *
- * Note that under no circumstances do we want to close the old
- * cursor without returning a valid new one; we don't want to
- * leave the main cursor in our caller with a non-NULL pointer
- * to a freed off-page dup cursor.
- */
- if (oldopd != NULL && (ret = __db_c_close(oldopd)) != 0)
- return (ret);
-
- return (0);
-}
-
-/*
- * __db_c_get --
- * Get using a cursor.
- *
- * PUBLIC: int __db_c_get __P((DBC *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_c_get(dbc_arg, key, data, flags)
- DBC *dbc_arg;
- DBT *key, *data;
- u_int32_t flags;
-{
- DB *dbp;
- DBC *dbc, *dbc_n, *opd;
- DBC_INTERNAL *cp, *cp_n;
- DB_MPOOLFILE *mpf;
- db_pgno_t pgno;
- u_int32_t multi, orig_ulen, tmp_flags, tmp_read_uncommitted, tmp_rmw;
- u_int8_t type;
- int key_small, ret, t_ret;
-
- COMPQUIET(orig_ulen, 0);
-
- key_small = 0;
-
- /*
- * Cursor Cleanup Note:
- * All of the cursors passed to the underlying access methods by this
- * routine are duplicated cursors. On return, any referenced pages
- * will be discarded, and, if the cursor is not intended to be used
- * again, the close function will be called. So, pages/locks that
- * the cursor references do not need to be resolved by the underlying
- * functions.
- */
- dbp = dbc_arg->dbp;
- mpf = dbp->mpf;
- dbc_n = NULL;
- opd = NULL;
-
- /* Clear OR'd in additional bits so we can check for flag equality. */
- tmp_rmw = LF_ISSET(DB_RMW);
- LF_CLR(DB_RMW);
-
- tmp_read_uncommitted =
- LF_ISSET(DB_READ_UNCOMMITTED) &&
- !F_ISSET(dbc_arg, DBC_READ_UNCOMMITTED);
- LF_CLR(DB_READ_UNCOMMITTED);
-
- multi = LF_ISSET(DB_MULTIPLE|DB_MULTIPLE_KEY);
- LF_CLR(DB_MULTIPLE|DB_MULTIPLE_KEY);
-
- /*
- * Return a cursor's record number. It has nothing to do with the
- * cursor get code except that it was put into the interface.
- */
- if (flags == DB_GET_RECNO) {
- if (tmp_rmw)
- F_SET(dbc_arg, DBC_RMW);
- if (tmp_read_uncommitted)
- F_SET(dbc_arg, DBC_READ_UNCOMMITTED);
- ret = __bam_c_rget(dbc_arg, data);
- if (tmp_rmw)
- F_CLR(dbc_arg, DBC_RMW);
- if (tmp_read_uncommitted)
- F_CLR(dbc_arg, DBC_READ_UNCOMMITTED);
- return (ret);
- }
-
- if (flags == DB_CONSUME || flags == DB_CONSUME_WAIT)
- CDB_LOCKING_INIT(dbp, dbc_arg);
-
- /*
- * If we have an off-page duplicates cursor, and the operation applies
- * to it, perform the operation. Duplicate the cursor and call the
- * underlying function.
- *
- * Off-page duplicate trees are locked in the primary tree, that is,
- * we acquire a write lock in the primary tree and no locks in the
- * off-page dup tree. If the DB_RMW flag was specified and the get
- * operation is done in an off-page duplicate tree, call the primary
- * cursor's upgrade routine first.
- */
- cp = dbc_arg->internal;
- if (cp->opd != NULL &&
- (flags == DB_CURRENT || flags == DB_GET_BOTHC ||
- flags == DB_NEXT || flags == DB_NEXT_DUP || flags == DB_PREV)) {
- if (tmp_rmw && (ret = dbc_arg->c_am_writelock(dbc_arg)) != 0)
- return (ret);
- if ((ret = __db_c_idup(cp->opd, &opd, DB_POSITION)) != 0)
- return (ret);
-
- switch (ret =
- opd->c_am_get(opd, key, data, flags, NULL)) {
- case 0:
- goto done;
- case DB_NOTFOUND:
- /*
- * Translate DB_NOTFOUND failures for the DB_NEXT and
- * DB_PREV operations into a subsequent operation on
- * the parent cursor.
- */
- if (flags == DB_NEXT || flags == DB_PREV) {
- if ((ret = __db_c_close(opd)) != 0)
- goto err;
- opd = NULL;
- break;
- }
- goto err;
- default:
- goto err;
- }
- }
-
- /*
- * Perform an operation on the main cursor. Duplicate the cursor,
- * upgrade the lock as required, and call the underlying function.
- */
- switch (flags) {
- case DB_CURRENT:
- case DB_GET_BOTHC:
- case DB_NEXT:
- case DB_NEXT_DUP:
- case DB_NEXT_NODUP:
- case DB_PREV:
- case DB_PREV_NODUP:
- tmp_flags = DB_POSITION;
- break;
- default:
- tmp_flags = 0;
- break;
- }
-
- if (tmp_read_uncommitted)
- F_SET(dbc_arg, DBC_READ_UNCOMMITTED);
-
- /*
- * If this cursor is going to be closed immediately, we don't
- * need to take precautions to clean it up on error.
- */
- if (F_ISSET(dbc_arg, DBC_TRANSIENT))
- dbc_n = dbc_arg;
- else {
- ret = __db_c_idup(dbc_arg, &dbc_n, tmp_flags);
- if (tmp_read_uncommitted)
- F_CLR(dbc_arg, DBC_READ_UNCOMMITTED);
-
- if (ret != 0)
- goto err;
- COPY_RET_MEM(dbc_arg, dbc_n);
- }
-
- if (tmp_rmw)
- F_SET(dbc_n, DBC_RMW);
-
- switch (multi) {
- case DB_MULTIPLE:
- F_SET(dbc_n, DBC_MULTIPLE);
- break;
- case DB_MULTIPLE_KEY:
- F_SET(dbc_n, DBC_MULTIPLE_KEY);
- break;
- case DB_MULTIPLE | DB_MULTIPLE_KEY:
- F_SET(dbc_n, DBC_MULTIPLE|DBC_MULTIPLE_KEY);
- break;
- case 0:
- default:
- break;
- }
-
- pgno = PGNO_INVALID;
- ret = dbc_n->c_am_get(dbc_n, key, data, flags, &pgno);
- if (tmp_rmw)
- F_CLR(dbc_n, DBC_RMW);
- if (tmp_read_uncommitted)
- F_CLR(dbc_arg, DBC_READ_UNCOMMITTED);
- F_CLR(dbc_n, DBC_MULTIPLE|DBC_MULTIPLE_KEY);
- if (ret != 0)
- goto err;
-
- cp_n = dbc_n->internal;
-
- /*
- * We may be referencing a new off-page duplicates tree. Acquire
- * a new cursor and call the underlying function.
- */
- if (pgno != PGNO_INVALID) {
- if ((ret = __db_c_newopd(dbc_arg,
- pgno, cp_n->opd, &cp_n->opd)) != 0)
- goto err;
-
- switch (flags) {
- case DB_FIRST:
- case DB_NEXT:
- case DB_NEXT_NODUP:
- case DB_SET:
- case DB_SET_RECNO:
- case DB_SET_RANGE:
- tmp_flags = DB_FIRST;
- break;
- case DB_LAST:
- case DB_PREV:
- case DB_PREV_NODUP:
- tmp_flags = DB_LAST;
- break;
- case DB_GET_BOTH:
- case DB_GET_BOTHC:
- case DB_GET_BOTH_RANGE:
- tmp_flags = flags;
- break;
- default:
- ret =
- __db_unknown_flag(dbp->dbenv, "__db_c_get", flags);
- goto err;
- }
- if ((ret = cp_n->opd->c_am_get(
- cp_n->opd, key, data, tmp_flags, NULL)) != 0)
- goto err;
- }
-
-done: /*
- * Return a key/data item. The only exception is that we don't return
- * a key if the user already gave us one, that is, if the DB_SET flag
- * was set. The DB_SET flag is necessary. In a Btree, the user's key
- * doesn't have to be the same as the key stored the tree, depending on
- * the magic performed by the comparison function. As we may not have
- * done any key-oriented operation here, the page reference may not be
- * valid. Fill it in as necessary. We don't have to worry about any
- * locks, the cursor must already be holding appropriate locks.
- *
- * XXX
- * If not a Btree and DB_SET_RANGE is set, we shouldn't return a key
- * either, should we?
- */
- cp_n = dbc_n == NULL ? dbc_arg->internal : dbc_n->internal;
- if (!F_ISSET(key, DB_DBT_ISSET)) {
- if (cp_n->page == NULL && (ret =
- __memp_fget(mpf, &cp_n->pgno, 0, &cp_n->page)) != 0)
- goto err;
-
- if ((ret = __db_ret(dbp, cp_n->page, cp_n->indx,
- key, &dbc_arg->rkey->data, &dbc_arg->rkey->ulen)) != 0) {
- /*
- * If the key DBT is too small, we still want to return
- * the size of the data. Otherwise applications are
- * forced to check each one with a separate call. We
- * don't want to copy the data, so we set the ulen to
- * zero before calling __db_ret.
- */
- if (ret == DB_BUFFER_SMALL &&
- F_ISSET(data, DB_DBT_USERMEM)) {
- key_small = 1;
- orig_ulen = data->ulen;
- data->ulen = 0;
- } else
- goto err;
- }
- }
- if (multi != 0) {
- /*
- * Even if fetching from the OPD cursor we need a duplicate
- * primary cursor if we are going after multiple keys.
- */
- if (dbc_n == NULL) {
- /*
- * Non-"_KEY" DB_MULTIPLE doesn't move the main cursor,
- * so it's safe to just use dbc_arg, unless dbc_arg
- * has an open OPD cursor whose state might need to
- * be preserved.
- */
- if ((!(multi & DB_MULTIPLE_KEY) &&
- dbc_arg->internal->opd == NULL) ||
- F_ISSET(dbc_arg, DBC_TRANSIENT))
- dbc_n = dbc_arg;
- else {
- if ((ret = __db_c_idup(dbc_arg,
- &dbc_n, DB_POSITION)) != 0)
- goto err;
- if ((ret = dbc_n->c_am_get(dbc_n,
- key, data, DB_CURRENT, &pgno)) != 0)
- goto err;
- }
- cp_n = dbc_n->internal;
- }
-
- /*
- * If opd is set then we dupped the opd that we came in with.
- * When we return we may have a new opd if we went to another
- * key.
- */
- if (opd != NULL) {
- DB_ASSERT(cp_n->opd == NULL);
- cp_n->opd = opd;
- opd = NULL;
- }
-
- /*
- * Bulk get doesn't use __db_retcopy, so data.size won't
- * get set up unless there is an error. Assume success
- * here. This is the only call to c_am_bulk, and it avoids
- * setting it exactly the same everywhere. If we have an
- * DB_BUFFER_SMALL error, it'll get overwritten with the
- * needed value.
- */
- data->size = data->ulen;
- ret = dbc_n->c_am_bulk(dbc_n, data, flags | multi);
- } else if (!F_ISSET(data, DB_DBT_ISSET)) {
- dbc = opd != NULL ? opd : cp_n->opd != NULL ? cp_n->opd : dbc_n;
- type = TYPE(dbc->internal->page);
- ret = __db_ret(dbp, dbc->internal->page, dbc->internal->indx +
- (type == P_LBTREE || type == P_HASH ? O_INDX : 0),
- data, &dbc_arg->rdata->data, &dbc_arg->rdata->ulen);
- }
-
-err: /* Don't pass DB_DBT_ISSET back to application level, error or no. */
- F_CLR(key, DB_DBT_ISSET);
- F_CLR(data, DB_DBT_ISSET);
-
- /* Cleanup and cursor resolution. */
- if (opd != NULL) {
- /*
- * To support dirty reads we must reget the write lock
- * if we have just stepped off a deleted record.
- * Since the OPD cursor does not know anything
- * about the referencing page or cursor we need
- * to peek at the OPD cursor and get the lock here.
- */
- if (F_ISSET(dbc_arg->dbp, DB_AM_READ_UNCOMMITTED) &&
- F_ISSET((BTREE_CURSOR *)
- dbc_arg->internal->opd->internal, C_DELETED))
- if ((t_ret =
- dbc_arg->c_am_writelock(dbc_arg)) != 0 && ret == 0)
- ret = t_ret;
- if ((t_ret = __db_c_cleanup(
- dbc_arg->internal->opd, opd, ret)) != 0 && ret == 0)
- ret = t_ret;
-
- }
-
- if ((t_ret = __db_c_cleanup(dbc_arg, dbc_n, ret)) != 0 && ret == 0)
- ret = t_ret;
-
- if (key_small) {
- data->ulen = orig_ulen;
- if (ret == 0)
- ret = DB_BUFFER_SMALL;
- }
-
- if (flags == DB_CONSUME || flags == DB_CONSUME_WAIT)
- CDB_LOCKING_DONE(dbp, dbc_arg);
- return (ret);
-}
-
-/*
- * __db_c_put --
- * Put using a cursor.
- *
- * PUBLIC: int __db_c_put __P((DBC *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_c_put(dbc_arg, key, data, flags)
- DBC *dbc_arg;
- DBT *key, *data;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB *dbp, *sdbp;
- DBC *dbc_n, *oldopd, *opd, *sdbc, *pdbc;
- DBT olddata, oldpkey, oldskey, newdata, pkey, skey, temppkey, tempskey;
- db_pgno_t pgno;
- int cmp, have_oldrec, ispartial, nodel, re_pad, ret, rmw, t_ret;
- u_int32_t re_len, size, tmp_flags;
-
- /*
- * Cursor Cleanup Note:
- * All of the cursors passed to the underlying access methods by this
- * routine are duplicated cursors. On return, any referenced pages
- * will be discarded, and, if the cursor is not intended to be used
- * again, the close function will be called. So, pages/locks that
- * the cursor references do not need to be resolved by the underlying
- * functions.
- */
- dbp = dbc_arg->dbp;
- dbenv = dbp->dbenv;
- sdbp = NULL;
- pdbc = dbc_n = NULL;
- memset(&newdata, 0, sizeof(DBT));
- ret = 0;
-
- /*
- * We do multiple cursor operations in some cases and subsequently
- * access the data DBT information. Set DB_DBT_MALLOC so we don't risk
- * modification of the data between our uses of it.
- */
- memset(&olddata, 0, sizeof(DBT));
- F_SET(&olddata, DB_DBT_MALLOC);
-
- /*
- * Putting to secondary indices is forbidden; when we need
- * to internally update one, we'll call this with a private
- * synonym for DB_KEYLAST, DB_UPDATE_SECONDARY, which does
- * the right thing but won't return an error from cputchk().
- */
- if (flags == DB_UPDATE_SECONDARY)
- flags = DB_KEYLAST;
-
- CDB_LOCKING_INIT(dbp, dbc_arg);
-
- /*
- * Check to see if we are a primary and have secondary indices.
- * If we are not, we save ourselves a good bit of trouble and
- * just skip to the "normal" put.
- */
- if (LIST_FIRST(&dbp->s_secondaries) == NULL)
- goto skip_s_update;
-
- /*
- * We have at least one secondary which we may need to update.
- *
- * There is a rather vile locking issue here. Secondary gets
- * will always involve acquiring a read lock in the secondary,
- * then acquiring a read lock in the primary. Ideally, we
- * would likewise perform puts by updating all the secondaries
- * first, then doing the actual put in the primary, to avoid
- * deadlock (since having multiple threads doing secondary
- * gets and puts simultaneously is probably a common case).
- *
- * However, if this put is a put-overwrite--and we have no way to
- * tell in advance whether it will be--we may need to delete
- * an outdated secondary key. In order to find that old
- * secondary key, we need to get the record we're overwriting,
- * before we overwrite it.
- *
- * (XXX: It would be nice to avoid this extra get, and have the
- * underlying put routines somehow pass us the old record
- * since they need to traverse the tree anyway. I'm saving
- * this optimization for later, as it's a lot of work, and it
- * would be hard to fit into this locking paradigm anyway.)
- *
- * The simple thing to do would be to go get the old record before
- * we do anything else. Unfortunately, though, doing so would
- * violate our "secondary, then primary" lock acquisition
- * ordering--even in the common case where no old primary record
- * exists, we'll still acquire and keep a lock on the page where
- * we're about to do the primary insert.
- *
- * To get around this, we do the following gyrations, which
- * hopefully solve this problem in the common case:
- *
- * 1) If this is a c_put(DB_CURRENT), go ahead and get the
- * old record. We already hold the lock on this page in
- * the primary, so no harm done, and we'll need the primary
- * key (which we weren't passed in this case) to do any
- * secondary puts anyway.
- *
- * 2) If we're doing a partial put, we need to perform the
- * get on the primary key right away, since we don't have
- * the whole datum that the secondary key is based on.
- * We may also need to pad out the record if the primary
- * has a fixed record length.
- *
- * 3) Loop through the secondary indices, putting into each a
- * new secondary key that corresponds to the new record.
- *
- * 4) If we haven't done so in (1) or (2), get the old primary
- * key/data pair. If one does not exist--the common case--we're
- * done with secondary indices, and can go straight on to the
- * primary put.
- *
- * 5) If we do have an old primary key/data pair, however, we need
- * to loop through all the secondaries a second time and delete
- * the old secondary in each.
- */
- memset(&pkey, 0, sizeof(DBT));
- have_oldrec = nodel = 0;
-
- /*
- * Primary indices can't have duplicates, so only DB_CURRENT,
- * DB_KEYFIRST, and DB_KEYLAST make any sense. Other flags
- * should have been caught by the checking routine, but
- * add a sprinkling of paranoia.
- */
- DB_ASSERT(flags == DB_CURRENT ||
- flags == DB_KEYFIRST || flags == DB_KEYLAST);
-
- /*
- * We'll want to use DB_RMW in a few places, but it's only legal
- * when locking is on.
- */
- rmw = STD_LOCKING(dbc_arg) ? DB_RMW : 0;
-
- if (flags == DB_CURRENT) { /* Step 1. */
- /*
- * This is safe to do on the cursor we already have;
- * error or no, it won't move.
- *
- * We use DB_RMW for all of these gets because we'll be
- * writing soon enough in the "normal" put code. In
- * transactional databases we'll hold those write locks
- * even if we close the cursor we're reading with.
- *
- * The DB_KEYEMPTY return needs special handling -- if the
- * cursor is on a deleted key, we return DB_NOTFOUND.
- */
- ret = __db_c_get(dbc_arg, &pkey, &olddata, rmw | DB_CURRENT);
- if (ret == DB_KEYEMPTY)
- ret = DB_NOTFOUND;
- if (ret != 0)
- goto err;
-
- have_oldrec = 1; /* We've looked for the old record. */
- } else {
- /*
- * Set pkey so we can use &pkey everywhere instead of key.
- * If DB_CURRENT is set and there is a key at the current
- * location, pkey will be overwritten before it's used.
- */
- pkey.data = key->data;
- pkey.size = key->size;
- }
-
- /*
- * Check for partial puts (step 2).
- */
- if (F_ISSET(data, DB_DBT_PARTIAL)) {
- if (!have_oldrec && !nodel) {
- /*
- * We're going to have to search the tree for the
- * specified key. Dup a cursor (so we have the same
- * locking info) and do a c_get.
- */
- if ((ret = __db_c_idup(dbc_arg, &pdbc, 0)) != 0)
- goto err;
-
- /* We should have gotten DB_CURRENT in step 1. */
- DB_ASSERT(flags != DB_CURRENT);
-
- ret = __db_c_get(pdbc, &pkey, &olddata, rmw | DB_SET);
- if (ret == DB_KEYEMPTY || ret == DB_NOTFOUND) {
- nodel = 1;
- ret = 0;
- }
- if ((t_ret = __db_c_close(pdbc)) != 0)
- ret = t_ret;
- if (ret != 0)
- goto err;
-
- have_oldrec = 1;
- }
-
- /*
- * Now build the new datum from olddata and the partial data we
- * were given. It's okay to do this if no record was returned
- * above: a partial put on an empty record is allowed, if a
- * little strange. The data is zero-padded.
- */
- if ((ret =
- __db_buildpartial(dbp, &olddata, data, &newdata)) != 0)
- goto err;
- ispartial = 1;
- } else
- ispartial = 0;
-
- /*
- * Handle fixed-length records. If the primary database has
- * fixed-length records, we need to pad out the datum before
- * we pass it into the callback function; we always index the
- * "real" record.
- */
- if ((dbp->type == DB_RECNO && F_ISSET(dbp, DB_AM_FIXEDLEN)) ||
- (dbp->type == DB_QUEUE)) {
- if (dbp->type == DB_QUEUE) {
- re_len = ((QUEUE *)dbp->q_internal)->re_len;
- re_pad = ((QUEUE *)dbp->q_internal)->re_pad;
- } else {
- re_len = ((BTREE *)dbp->bt_internal)->re_len;
- re_pad = ((BTREE *)dbp->bt_internal)->re_pad;
- }
-
- size = ispartial ? newdata.size : data->size;
- if (size > re_len) {
- ret = __db_rec_toobig(dbenv, size, re_len);
- goto err;
- } else if (size < re_len) {
- /*
- * If we're not doing a partial put, copy
- * data->data into newdata.data, then pad out
- * newdata.data.
- *
- * If we're doing a partial put, the data
- * we want are already in newdata.data; we
- * just need to pad.
- *
- * Either way, realloc is safe.
- */
- if ((ret =
- __os_realloc(dbenv, re_len, &newdata.data)) != 0)
- goto err;
- if (!ispartial)
- memcpy(newdata.data, data->data, size);
- memset((u_int8_t *)newdata.data + size, re_pad,
- re_len - size);
- newdata.size = re_len;
- ispartial = 1;
- }
- }
-
- /*
- * Loop through the secondaries. (Step 3.)
- *
- * Note that __db_s_first and __db_s_next will take care of
- * thread-locking and refcounting issues.
- */
- if ((ret = __db_s_first(dbp, &sdbp)) != 0)
- goto err;
- for (; sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp)) {
- /*
- * Don't process this secondary if the key is immutable and we
- * know that the old record exists. This optimization can't be
- * used if we have not checked for the old record yet.
- */
- if (have_oldrec && !nodel &&
- FLD_ISSET(sdbp->s_assoc_flags, DB_ASSOC_IMMUTABLE_KEY))
- continue;
-
- /*
- * Call the callback for this secondary, to get the
- * appropriate secondary key.
- */
- memset(&skey, 0, sizeof(DBT));
- if ((ret = sdbp->s_callback(sdbp,
- &pkey, ispartial ? &newdata : data, &skey)) != 0) {
- if (ret == DB_DONOTINDEX)
- /*
- * The callback returned a null value--don't
- * put this key in the secondary. Just
- * move on to the next one--we'll handle
- * any necessary deletes in step 5.
- */
- continue;
- goto err;
- }
-
- /*
- * Open a cursor in this secondary.
- *
- * Use the same locker ID as our primary cursor, so that
- * we're guaranteed that the locks don't conflict (e.g. in CDB
- * or if we're subdatabases that share and want to lock a
- * metadata page).
- */
- if ((ret = __db_cursor_int(sdbp, dbc_arg->txn, sdbp->type,
- PGNO_INVALID, 0, dbc_arg->locker, &sdbc)) != 0)
- goto err;
-
- /*
- * If we're in CDB, updates will fail since the new cursor
- * isn't a writer. However, we hold the WRITE lock in the
- * primary and will for as long as our new cursor lasts,
- * and the primary and secondary share a lock file ID,
- * so it's safe to consider this a WRITER. The close
- * routine won't try to put anything because we don't
- * really have a lock.
- */
- if (CDB_LOCKING(dbenv)) {
- DB_ASSERT(sdbc->mylock.off == LOCK_INVALID);
- F_SET(sdbc, DBC_WRITER);
- }
-
- /*
- * Swap the primary key to the byte order of this secondary, if
- * necessary. By doing this now, we can compare directly
- * against the data already in the secondary without having to
- * swap it after reading.
- */
- SWAP_IF_NEEDED(dbp, sdbp, &pkey);
-
- /*
- * There are three cases here--
- * 1) The secondary supports sorted duplicates.
- * If we attempt to put a secondary/primary pair
- * that already exists, that's a duplicate duplicate,
- * and c_put will return DB_KEYEXIST (see __db_duperr).
- * This will leave us with exactly one copy of the
- * secondary/primary pair, and this is just right--we'll
- * avoid deleting it later, as the old and new secondaries
- * will match (since the old secondary is the dup dup
- * that's already there).
- * 2) The secondary supports duplicates, but they're not
- * sorted. We need to avoid putting a duplicate
- * duplicate, because the matching old and new secondaries
- * will prevent us from deleting anything and we'll
- * wind up with two secondary records that point to the
- * same primary key. Do a c_get(DB_GET_BOTH); only
- * do the put if the secondary doesn't exist.
- * 3) The secondary doesn't support duplicates at all.
- * In this case, secondary keys must be unique; if
- * another primary key already exists for this
- * secondary key, we have to either overwrite it or
- * not put this one, and in either case we've
- * corrupted the secondary index. Do a c_get(DB_SET).
- * If the secondary/primary pair already exists, do
- * nothing; if the secondary exists with a different
- * primary, return an error; and if the secondary
- * does not exist, put it.
- */
- if (!F_ISSET(sdbp, DB_AM_DUP)) {
- /* Case 3. */
- memset(&oldpkey, 0, sizeof(DBT));
- F_SET(&oldpkey, DB_DBT_MALLOC);
- ret = __db_c_get(sdbc,
- &skey, &oldpkey, rmw | DB_SET);
- if (ret == 0) {
- cmp = __bam_defcmp(sdbp, &oldpkey, &pkey);
- __os_ufree(dbenv, oldpkey.data);
- if (cmp != 0) {
- __db_err(dbenv, "%s%s",
- "Put results in a non-unique secondary key in an ",
- "index not configured to support duplicates");
- ret = EINVAL;
- }
- }
- if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY)
- goto skipput;
- } else if (!F_ISSET(sdbp, DB_AM_DUPSORT)) {
- /* Case 2. */
- memset(&tempskey, 0, sizeof(DBT));
- tempskey.data = skey.data;
- tempskey.size = skey.size;
- memset(&temppkey, 0, sizeof(DBT));
- temppkey.data = pkey.data;
- temppkey.size = pkey.size;
- ret = __db_c_get(sdbc, &tempskey, &temppkey,
- rmw | DB_GET_BOTH);
- if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY)
- goto skipput;
- }
-
- ret = __db_c_put(sdbc, &skey, &pkey, DB_UPDATE_SECONDARY);
-
- /*
- * We don't know yet whether this was a put-overwrite that
- * in fact changed nothing. If it was, we may get DB_KEYEXIST.
- * This is not an error.
- */
- if (ret == DB_KEYEXIST)
- ret = 0;
-
-skipput: FREE_IF_NEEDED(sdbp, &skey)
-
- /* Make sure the primary key is back in native byte-order. */
- SWAP_IF_NEEDED(dbp, sdbp, &pkey);
-
- if ((t_ret = __db_c_close(sdbc)) != 0 && ret == 0)
- ret = t_ret;
-
- if (ret != 0)
- goto err;
- }
- if (ret != 0)
- goto err;
-
- /* If still necessary, go get the old primary key/data. (Step 4.) */
- if (!have_oldrec) {
- /* See the comments in step 2. This is real familiar. */
- if ((ret = __db_c_idup(dbc_arg, &pdbc, 0)) != 0)
- goto err;
- DB_ASSERT(flags != DB_CURRENT);
- pkey.data = key->data;
- pkey.size = key->size;
- ret = __db_c_get(pdbc, &pkey, &olddata, rmw | DB_SET);
- if (ret == DB_KEYEMPTY || ret == DB_NOTFOUND) {
- nodel = 1;
- ret = 0;
- }
- if ((t_ret = __db_c_close(pdbc)) != 0 && ret == 0)
- ret = t_ret;
- if (ret != 0)
- goto err;
- have_oldrec = 1;
- }
-
- /*
- * If we don't follow this goto, we do in fact have an old record
- * we may need to go delete. (Step 5).
- */
- if (nodel)
- goto skip_s_update;
-
- if ((ret = __db_s_first(dbp, &sdbp)) != 0)
- goto err;
- for (; sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp)) {
- /*
- * Don't process this secondary if the key is immutable. We
- * know that the old record exists, so this optimization can
- * always be used.
- */
- if (FLD_ISSET(sdbp->s_assoc_flags, DB_ASSOC_IMMUTABLE_KEY))
- continue;
-
- /*
- * Call the callback for this secondary to get the
- * old secondary key.
- */
- memset(&oldskey, 0, sizeof(DBT));
- if ((ret = sdbp->s_callback(sdbp,
- &pkey, &olddata, &oldskey)) != 0) {
- if (ret == DB_DONOTINDEX)
- /*
- * The callback returned a null value--there's
- * nothing to delete. Go on to the next
- * secondary.
- */
- continue;
- goto err;
- }
- memset(&skey, 0, sizeof(DBT));
- if ((ret = sdbp->s_callback(sdbp,
- &pkey, ispartial ? &newdata : data, &skey)) != 0 &&
- ret != DB_DONOTINDEX)
- goto err;
-
- /*
- * If there is no new secondary key, or if the old secondary
- * key is different from the new secondary key, then
- * we need to delete the old one.
- *
- * Note that bt_compare is (and must be) set no matter
- * what access method we're in.
- */
- sdbc = NULL;
- if (ret == DB_DONOTINDEX ||
- ((BTREE *)sdbp->bt_internal)->bt_compare(sdbp,
- &oldskey, &skey) != 0) {
- if ((ret = __db_cursor_int(
- sdbp, dbc_arg->txn, sdbp->type,
- PGNO_INVALID, 0, dbc_arg->locker, &sdbc)) != 0)
- goto err;
- if (CDB_LOCKING(dbenv)) {
- DB_ASSERT(sdbc->mylock.off == LOCK_INVALID);
- F_SET(sdbc, DBC_WRITER);
- }
-
- /*
- * Don't let c_get(DB_GET_BOTH) stomp on
- * our data. Use a temp DBT instead.
- */
- memset(&tempskey, 0, sizeof(DBT));
- tempskey.data = oldskey.data;
- tempskey.size = oldskey.size;
- SWAP_IF_NEEDED(dbp, sdbp, &pkey);
- memset(&temppkey, 0, sizeof(DBT));
- temppkey.data = pkey.data;
- temppkey.size = pkey.size;
- if ((ret = __db_c_get(sdbc,
- &tempskey, &temppkey, rmw | DB_GET_BOTH)) == 0)
- ret = __db_c_del(sdbc, DB_UPDATE_SECONDARY);
- else if (ret == DB_NOTFOUND)
- ret = __db_secondary_corrupt(dbp);
- SWAP_IF_NEEDED(dbp, sdbp, &pkey);
- }
-
- FREE_IF_NEEDED(sdbp, &skey);
- FREE_IF_NEEDED(sdbp, &oldskey);
- if (sdbc != NULL && (t_ret = __db_c_close(sdbc)) != 0 &&
- ret == 0)
- ret = t_ret;
- if (ret != 0)
- goto err;
- }
-
- /* Secondary index updates are now done. On to the "real" stuff. */
-
-skip_s_update:
- /*
- * If we have an off-page duplicates cursor, and the operation applies
- * to it, perform the operation. Duplicate the cursor and call the
- * underlying function.
- *
- * Off-page duplicate trees are locked in the primary tree, that is,
- * we acquire a write lock in the primary tree and no locks in the
- * off-page dup tree. If the put operation is done in an off-page
- * duplicate tree, call the primary cursor's upgrade routine first.
- */
- if (dbc_arg->internal->opd != NULL &&
- (flags == DB_AFTER || flags == DB_BEFORE || flags == DB_CURRENT)) {
- /*
- * A special case for hash off-page duplicates. Hash doesn't
- * support (and is documented not to support) put operations
- * relative to a cursor which references an already deleted
- * item. For consistency, apply the same criteria to off-page
- * duplicates as well.
- */
- if (dbc_arg->dbtype == DB_HASH && F_ISSET(
- ((BTREE_CURSOR *)(dbc_arg->internal->opd->internal)),
- C_DELETED)) {
- ret = DB_NOTFOUND;
- goto err;
- }
-
- if ((ret = dbc_arg->c_am_writelock(dbc_arg)) != 0 ||
- (ret = __db_c_dup(dbc_arg, &dbc_n, DB_POSITION)) != 0)
- goto err;
- opd = dbc_n->internal->opd;
- if ((ret = opd->c_am_put(
- opd, key, data, flags, NULL)) != 0)
- goto err;
- goto done;
- }
-
- /*
- * Perform an operation on the main cursor. Duplicate the cursor,
- * and call the underlying function.
- *
- * XXX: MARGO
- *
- tmp_flags = flags == DB_AFTER ||
- flags == DB_BEFORE || flags == DB_CURRENT ? DB_POSITION : 0;
- */
- tmp_flags = DB_POSITION;
-
- /*
- * If this cursor is going to be closed immediately, we don't
- * need to take precautions to clean it up on error.
- */
- if (F_ISSET(dbc_arg, DBC_TRANSIENT))
- dbc_n = dbc_arg;
- else if ((ret = __db_c_idup(dbc_arg, &dbc_n, tmp_flags)) != 0)
- goto err;
-
- pgno = PGNO_INVALID;
- if ((ret = dbc_n->c_am_put(dbc_n, key, data, flags, &pgno)) != 0)
- goto err;
-
- /*
- * We may be referencing a new off-page duplicates tree. Acquire
- * a new cursor and call the underlying function.
- */
- if (pgno != PGNO_INVALID) {
- oldopd = dbc_n->internal->opd;
- if ((ret = __db_c_newopd(dbc_arg, pgno, oldopd, &opd)) != 0) {
- dbc_n->internal->opd = opd;
- goto err;
- }
-
- dbc_n->internal->opd = opd;
-
- if ((ret = opd->c_am_put(
- opd, key, data, flags, NULL)) != 0)
- goto err;
- }
-
-done:
-err: /* Cleanup and cursor resolution. */
- if ((t_ret = __db_c_cleanup(dbc_arg, dbc_n, ret)) != 0 && ret == 0)
- ret = t_ret;
-
- /* If newdata or olddata were used, free their buffers. */
- if (newdata.data != NULL)
- __os_free(dbenv, newdata.data);
- if (olddata.data != NULL)
- __os_ufree(dbenv, olddata.data);
-
- CDB_LOCKING_DONE(dbp, dbc_arg);
-
- if (sdbp != NULL && (t_ret = __db_s_done(sdbp)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_duperr()
- * Error message: we don't currently support sorted duplicate duplicates.
- * PUBLIC: int __db_duperr __P((DB *, u_int32_t));
- */
-int
-__db_duperr(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
-
- /*
- * If we run into this error while updating a secondary index,
- * don't yell--there's no clean way to pass DB_NODUPDATA in along
- * with DB_UPDATE_SECONDARY, but we may run into this problem
- * in a normal, non-error course of events.
- *
- * !!!
- * If and when we ever permit duplicate duplicates in sorted-dup
- * databases, we need to either change the secondary index code
- * to check for dup dups, or we need to maintain the implicit
- * "DB_NODUPDATA" behavior for databases with DB_AM_SECONDARY set.
- */
- if (flags != DB_NODUPDATA && !F_ISSET(dbp, DB_AM_SECONDARY))
- __db_err(dbp->dbenv,
- "Duplicate data items are not supported with sorted data");
- return (DB_KEYEXIST);
-}
-
-/*
- * __db_c_cleanup --
- * Clean up duplicate cursors.
- */
-static int
-__db_c_cleanup(dbc, dbc_n, failed)
- DBC *dbc, *dbc_n;
- int failed;
-{
- DB *dbp;
- DBC *opd;
- DBC_INTERNAL *internal;
- DB_MPOOLFILE *mpf;
- int ret, t_ret;
-
- dbp = dbc->dbp;
- mpf = dbp->mpf;
- internal = dbc->internal;
- ret = 0;
-
- /* Discard any pages we're holding. */
- if (internal->page != NULL) {
- if ((t_ret =
- __memp_fput(mpf, internal->page, 0)) != 0 && ret == 0)
- ret = t_ret;
- internal->page = NULL;
- }
- opd = internal->opd;
- if (opd != NULL && opd->internal->page != NULL) {
- if ((t_ret =
- __memp_fput(mpf, opd->internal->page, 0)) != 0 && ret == 0)
- ret = t_ret;
- opd->internal->page = NULL;
- }
-
- /*
- * If dbc_n is NULL, there's no internal cursor swapping to be done
- * and no dbc_n to close--we probably did the entire operation on an
- * offpage duplicate cursor. Just return.
- *
- * If dbc and dbc_n are the same, we're either inside a DB->{put/get}
- * operation, and as an optimization we performed the operation on
- * the main cursor rather than on a duplicated one, or we're in a
- * bulk get that can't have moved the cursor (DB_MULTIPLE with the
- * initial c_get operation on an off-page dup cursor). Just
- * return--either we know we didn't move the cursor, or we're going
- * to close it before we return to application code, so we're sure
- * not to visibly violate the "cursor stays put on error" rule.
- */
- if (dbc_n == NULL || dbc == dbc_n)
- return (ret);
-
- if (dbc_n->internal->page != NULL) {
- if ((t_ret = __memp_fput(
- mpf, dbc_n->internal->page, 0)) != 0 && ret == 0)
- ret = t_ret;
- dbc_n->internal->page = NULL;
- }
- opd = dbc_n->internal->opd;
- if (opd != NULL && opd->internal->page != NULL) {
- if ((t_ret =
- __memp_fput(mpf, opd->internal->page, 0)) != 0 && ret == 0)
- ret = t_ret;
- opd->internal->page = NULL;
- }
-
- /*
- * If we didn't fail before entering this routine or just now when
- * freeing pages, swap the interesting contents of the old and new
- * cursors.
- */
- if (!failed && ret == 0) {
- dbc->internal = dbc_n->internal;
- dbc_n->internal = internal;
- }
-
- /*
- * Close the cursor we don't care about anymore. The close can fail,
- * but we only expect DB_LOCK_DEADLOCK failures. This violates our
- * "the cursor is unchanged on error" semantics, but since all you can
- * do with a DB_LOCK_DEADLOCK failure is close the cursor, I believe
- * that's OK.
- *
- * XXX
- * There's no way to recover from failure to close the old cursor.
- * All we can do is move to the new position and return an error.
- *
- * XXX
- * We might want to consider adding a flag to the cursor, so that any
- * subsequent operations other than close just return an error?
- */
- if ((t_ret = __db_c_close(dbc_n)) != 0 && ret == 0)
- ret = t_ret;
-
- /*
- * If this was an update that is supporting dirty reads
- * then we may have just swapped our read for a write lock
- * which is held by the surviving cursor. We need
- * to explicitly downgrade this lock. The closed cursor
- * may only have had a read lock.
- */
- if (F_ISSET(dbp, DB_AM_READ_UNCOMMITTED) &&
- dbc->internal->lock_mode == DB_LOCK_WRITE) {
- if ((t_ret =
- __TLPUT(dbc, dbc->internal->lock)) != 0 && ret == 0)
- ret = t_ret;
- if (t_ret == 0)
- dbc->internal->lock_mode = DB_LOCK_WWRITE;
- }
-
- return (ret);
-}
-
-/*
- * __db_c_secondary_get_pp --
- * This wrapper function for DBC->c_pget() is the DBC->c_get() function
- * for a secondary index cursor.
- *
- * PUBLIC: int __db_c_secondary_get_pp __P((DBC *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_c_secondary_get_pp(dbc, skey, data, flags)
- DBC *dbc;
- DBT *skey, *data;
- u_int32_t flags;
-{
-
- DB_ASSERT(F_ISSET(dbc->dbp, DB_AM_SECONDARY));
- return (__db_c_pget_pp(dbc, skey, NULL, data, flags));
-}
-
-/*
- * __db_c_pget --
- * Get a primary key/data pair through a secondary index.
- *
- * PUBLIC: int __db_c_pget __P((DBC *, DBT *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_c_pget(dbc, skey, pkey, data, flags)
- DBC *dbc;
- DBT *skey, *pkey, *data;
- u_int32_t flags;
-{
- DB *pdbp, *sdbp;
- DBC *dbc_n, *pdbc;
- DBT nullpkey;
- u_int32_t save_pkey_flags, tmp_flags, tmp_read_uncommitted, tmp_rmw;
- int pkeymalloc, ret, t_ret;
-
- sdbp = dbc->dbp;
- pdbp = sdbp->s_primary;
- dbc_n = NULL;
- pkeymalloc = t_ret = 0;
-
- /*
- * The challenging part of this function is getting the behavior
- * right for all the various permutations of DBT flags. The
- * next several blocks handle the various cases we need to
- * deal with specially.
- */
-
- /*
- * We may be called with a NULL pkey argument, if we've been
- * wrapped by a 2-DBT get call. If so, we need to use our
- * own DBT.
- */
- if (pkey == NULL) {
- memset(&nullpkey, 0, sizeof(DBT));
- pkey = &nullpkey;
- }
-
- /* Clear OR'd in additional bits so we can check for flag equality. */
- tmp_rmw = LF_ISSET(DB_RMW);
- LF_CLR(DB_RMW);
-
- tmp_read_uncommitted =
- LF_ISSET(DB_READ_UNCOMMITTED) &&
- !F_ISSET(dbc, DBC_READ_UNCOMMITTED);
- LF_CLR(DB_READ_UNCOMMITTED);
-
- /*
- * DB_GET_RECNO is a special case, because we're interested not in
- * the primary key/data pair, but rather in the primary's record
- * number.
- */
- if (flags == DB_GET_RECNO) {
- if (tmp_rmw)
- F_SET(dbc, DBC_RMW);
- if (tmp_read_uncommitted)
- F_SET(dbc, DBC_READ_UNCOMMITTED);
- ret = __db_c_pget_recno(dbc, pkey, data, flags);
- if (tmp_rmw)
- F_CLR(dbc, DBC_RMW);
- if (tmp_read_uncommitted)
- F_CLR(dbc, DBC_READ_UNCOMMITTED);
- return (ret);
- }
-
- /*
- * If the DBTs we've been passed don't have any of the
- * user-specified memory management flags set, we want to make sure
- * we return values using the DBTs dbc->rskey, dbc->rkey, and
- * dbc->rdata, respectively.
- *
- * There are two tricky aspects to this: first, we need to pass
- * skey and pkey *in* to the initial c_get on the secondary key,
- * since either or both may be looked at by it (depending on the
- * get flag). Second, we must not use a normal DB->get call
- * on the secondary, even though that's what we want to accomplish,
- * because the DB handle may be free-threaded. Instead,
- * we open a cursor, then take steps to ensure that we actually use
- * the rkey/rdata from the *secondary* cursor.
- *
- * We accomplish all this by passing in the DBTs we started out
- * with to the c_get, but swapping the contents of rskey and rkey,
- * respectively, into rkey and rdata; __db_ret will treat them like
- * the normal key/data pair in a c_get call, and will realloc them as
- * need be (this is "step 1"). Then, for "step 2", we swap back
- * rskey/rkey/rdata to normal, and do a get on the primary with the
- * secondary dbc appointed as the owner of the returned-data memory.
- *
- * Note that in step 2, we copy the flags field in case we need to
- * pass down a DB_DBT_PARTIAL or other flag that is compatible with
- * letting DB do the memory management.
- */
-
- /*
- * It is correct, though slightly sick, to attempt a partial get of a
- * primary key. However, if we do so here, we'll never find the
- * primary record; clear the DB_DBT_PARTIAL field of pkey just for the
- * duration of the next call.
- */
- save_pkey_flags = pkey->flags;
- F_CLR(pkey, DB_DBT_PARTIAL);
-
- /*
- * Now we can go ahead with the meat of this call. First, get the
- * primary key from the secondary index. (What exactly we get depends
- * on the flags, but the underlying cursor get will take care of the
- * dirty work.) Duplicate the cursor, in case the later get on the
- * primary fails.
- */
- switch (flags) {
- case DB_CURRENT:
- case DB_GET_BOTHC:
- case DB_NEXT:
- case DB_NEXT_DUP:
- case DB_NEXT_NODUP:
- case DB_PREV:
- case DB_PREV_NODUP:
- tmp_flags = DB_POSITION;
- break;
- default:
- tmp_flags = 0;
- break;
- }
-
- if (tmp_read_uncommitted)
- F_SET(dbc, DBC_READ_UNCOMMITTED);
-
- if ((ret = __db_c_dup(dbc, &dbc_n, tmp_flags)) != 0) {
- if (tmp_read_uncommitted)
- F_CLR(dbc, DBC_READ_UNCOMMITTED);
-
- return (ret);
- }
-
- F_SET(dbc_n, DBC_TRANSIENT);
-
- if (tmp_rmw)
- F_SET(dbc_n, DBC_RMW);
-
- /*
- * If we've been handed a primary key, it will be in native byte order,
- * so we need to swap it before reading from the secondary.
- */
- if (flags == DB_GET_BOTH || flags == DB_GET_BOTHC ||
- flags == DB_GET_BOTH_RANGE)
- SWAP_IF_NEEDED(pdbp, sdbp, pkey);
-
- /* Step 1. */
- dbc_n->rdata = dbc->rkey;
- dbc_n->rkey = dbc->rskey;
- ret = __db_c_get(dbc_n, skey, pkey, flags);
- /* Restore pkey's flags in case we stomped the PARTIAL flag. */
- pkey->flags = save_pkey_flags;
-
- if (tmp_read_uncommitted)
- F_CLR(dbc_n, DBC_READ_UNCOMMITTED);
- if (tmp_rmw)
- F_CLR(dbc_n, DBC_RMW);
-
- /*
- * We need to swap the primary key to native byte order if we read it
- * successfully, or if we swapped it on entry above. We can't return
- * with the application's data modified.
- */
- if (ret == 0 || flags == DB_GET_BOTH || flags == DB_GET_BOTHC ||
- flags == DB_GET_BOTH_RANGE)
- SWAP_IF_NEEDED(pdbp, sdbp, pkey);
-
- if (ret != 0)
- goto err;
-
- /*
- * Now we're ready for "step 2". If either or both of pkey and data do
- * not have memory management flags set--that is, if DB is managing
- * their memory--we need to swap around the rkey/rdata structures so
- * that we don't wind up trying to use memory managed by the primary
- * database cursor, which we'll close before we return.
- *
- * !!!
- * If you're carefully following the bouncing ball, you'll note that in
- * the DB-managed case, the buffer hanging off of pkey is the same as
- * dbc->rkey->data. This is just fine; we may well realloc and stomp
- * on it when we return, if we're doing a DB_GET_BOTH and need to
- * return a different partial or key (depending on the comparison
- * function), but this is safe.
- *
- * !!!
- * We need to use __db_cursor_int here rather than simply calling
- * pdbp->cursor, because otherwise, if we're in CDB, we'll allocate a
- * new locker ID and leave ourselves open to deadlocks. (Even though
- * we're only acquiring read locks, we'll still block if there are any
- * waiters.)
- */
- if ((ret = __db_cursor_int(pdbp,
- dbc->txn, pdbp->type, PGNO_INVALID, 0, dbc->locker, &pdbc)) != 0)
- goto err;
-
- if (tmp_read_uncommitted)
- F_SET(pdbc, DBC_READ_UNCOMMITTED);
- if (tmp_rmw)
- F_SET(pdbc, DBC_RMW);
- if (F_ISSET(dbc, DBC_READ_COMMITTED))
- F_SET(pdbc, DBC_READ_COMMITTED);
-
- /*
- * We're about to use pkey a second time. If DB_DBT_MALLOC is set on
- * it, we'll leak the memory we allocated the first time. Thus, set
- * DB_DBT_REALLOC instead so that we reuse that memory instead of
- * leaking it.
- *
- * !!!
- * This assumes that the user must always specify a compatible realloc
- * function if a malloc function is specified. I think this is a
- * reasonable requirement.
- */
- if (F_ISSET(pkey, DB_DBT_MALLOC)) {
- F_CLR(pkey, DB_DBT_MALLOC);
- F_SET(pkey, DB_DBT_REALLOC);
- pkeymalloc = 1;
- }
-
- /*
- * Do the actual get. Set DBC_TRANSIENT since we don't care about
- * preserving the position on error, and it's faster. SET_RET_MEM so
- * that the secondary DBC owns any returned-data memory.
- */
- F_SET(pdbc, DBC_TRANSIENT);
- SET_RET_MEM(pdbc, dbc);
- ret = __db_c_get(pdbc, pkey, data, DB_SET);
-
- /*
- * If the item wasn't found in the primary, this is a bug; our
- * secondary has somehow gotten corrupted, and contains elements that
- * don't correspond to anything in the primary. Complain.
- */
- if (ret == DB_NOTFOUND)
- ret = __db_secondary_corrupt(pdbp);
-
- /* Now close the primary cursor. */
- if ((t_ret = __db_c_close(pdbc)) != 0 && ret == 0)
- ret = t_ret;
-
-err: /* Cleanup and cursor resolution. */
- if ((t_ret = __db_c_cleanup(dbc, dbc_n, ret)) != 0 && ret == 0)
- ret = t_ret;
- if (pkeymalloc) {
- /*
- * If pkey had a MALLOC flag, we need to restore it; otherwise,
- * if the user frees the buffer but reuses the DBT without
- * NULL'ing its data field or changing the flags, we may drop
- * core.
- */
- F_CLR(pkey, DB_DBT_REALLOC);
- F_SET(pkey, DB_DBT_MALLOC);
- }
-
- return (ret);
-}
-
-/*
- * __db_c_pget_recno --
- * Perform a DB_GET_RECNO c_pget on a secondary index. Returns
- * the secondary's record number in the pkey field and the primary's
- * in the data field.
- */
-static int
-__db_c_pget_recno(sdbc, pkey, data, flags)
- DBC *sdbc;
- DBT *pkey, *data;
- u_int32_t flags;
-{
- DB *pdbp, *sdbp;
- DB_ENV *dbenv;
- DBC *pdbc;
- DBT discardme, primary_key;
- db_recno_t oob;
- u_int32_t rmw;
- int ret, t_ret;
-
- sdbp = sdbc->dbp;
- pdbp = sdbp->s_primary;
- dbenv = sdbp->dbenv;
- pdbc = NULL;
- ret = t_ret = 0;
-
- rmw = LF_ISSET(DB_RMW);
-
- memset(&discardme, 0, sizeof(DBT));
- F_SET(&discardme, DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- oob = RECNO_OOB;
-
- /*
- * If the primary is an rbtree, we want its record number, whether
- * or not the secondary is one too. Fetch the recno into "data".
- *
- * If it's not an rbtree, return RECNO_OOB in "data".
- */
- if (F_ISSET(pdbp, DB_AM_RECNUM)) {
- /*
- * Get the primary key, so we can find the record number
- * in the primary. (We're uninterested in the secondary key.)
- */
- memset(&primary_key, 0, sizeof(DBT));
- F_SET(&primary_key, DB_DBT_MALLOC);
- if ((ret = __db_c_get(sdbc,
- &discardme, &primary_key, rmw | DB_CURRENT)) != 0)
- return (ret);
-
- /*
- * Open a cursor on the primary, set it to the right record,
- * and fetch its recno into "data".
- *
- * (See __db_c_pget for comments on the use of __db_cursor_int.)
- *
- * SET_RET_MEM so that the secondary DBC owns any returned-data
- * memory.
- */
- if ((ret = __db_cursor_int(pdbp, sdbc->txn,
- pdbp->type, PGNO_INVALID, 0, sdbc->locker, &pdbc)) != 0)
- goto perr;
- SET_RET_MEM(pdbc, sdbc);
- if ((ret = __db_c_get(pdbc,
- &primary_key, &discardme, rmw | DB_SET)) != 0)
- goto perr;
-
- ret = __db_c_get(pdbc, &discardme, data, rmw | DB_GET_RECNO);
-
-perr: __os_ufree(sdbp->dbenv, primary_key.data);
- if (pdbc != NULL &&
- (t_ret = __db_c_close(pdbc)) != 0 && ret == 0)
- ret = t_ret;
- if (ret != 0)
- return (ret);
- } else if ((ret = __db_retcopy(dbenv, data, &oob,
- sizeof(oob), &sdbc->rkey->data, &sdbc->rkey->ulen)) != 0)
- return (ret);
-
- /*
- * If the secondary is an rbtree, we want its record number, whether
- * or not the primary is one too. Fetch the recno into "pkey".
- *
- * If it's not an rbtree, return RECNO_OOB in "pkey".
- */
- if (F_ISSET(sdbp, DB_AM_RECNUM))
- return (__db_c_get(sdbc, &discardme, pkey, flags));
- else
- return (__db_retcopy(dbenv, pkey, &oob,
- sizeof(oob), &sdbc->rdata->data, &sdbc->rdata->ulen));
-}
-
-/*
- * __db_wrlock_err -- do not have a write lock.
- */
-static int
-__db_wrlock_err(dbenv)
- DB_ENV *dbenv;
-{
- __db_err(dbenv, "Write attempted on read-only cursor");
- return (EPERM);
-}
-
-/*
- * __db_c_del_secondary --
- * Perform a delete operation on a secondary index: call through
- * to the primary and delete the primary record that this record
- * points to.
- *
- * Note that deleting the primary record will call c_del on all
- * the secondaries, including this one; thus, it is not necessary
- * to execute both this function and an actual delete.
- */
-static int
-__db_c_del_secondary(dbc)
- DBC *dbc;
-{
- DB *pdbp;
- DBC *pdbc;
- DBT skey, pkey;
- int ret, t_ret;
-
- memset(&skey, 0, sizeof(DBT));
- memset(&pkey, 0, sizeof(DBT));
- pdbp = dbc->dbp->s_primary;
-
- /*
- * Get the current item that we're pointing at.
- * We don't actually care about the secondary key, just
- * the primary.
- */
- F_SET(&skey, DB_DBT_PARTIAL | DB_DBT_USERMEM);
- if ((ret = __db_c_get(dbc, &skey, &pkey, DB_CURRENT)) != 0)
- return (ret);
-
- SWAP_IF_NEEDED(pdbp, dbc->dbp, &pkey);
-
- /*
- * Create a cursor on the primary with our locker ID,
- * so that when it calls back, we don't conflict.
- *
- * We create a cursor explicitly because there's no
- * way to specify the same locker ID if we're using
- * locking but not transactions if we use the DB->del
- * interface. This shouldn't be any less efficient
- * anyway.
- */
- if ((ret = __db_cursor_int(pdbp, dbc->txn,
- pdbp->type, PGNO_INVALID, 0, dbc->locker, &pdbc)) != 0)
- return (ret);
-
- /*
- * See comment in __db_c_put--if we're in CDB,
- * we already hold the locks we need, and we need to flag
- * the cursor as a WRITER so we don't run into errors
- * when we try to delete.
- */
- if (CDB_LOCKING(pdbp->dbenv)) {
- DB_ASSERT(pdbc->mylock.off == LOCK_INVALID);
- F_SET(pdbc, DBC_WRITER);
- }
-
- /*
- * Set the new cursor to the correct primary key. Then
- * delete it. We don't really care about the datum;
- * just reuse our skey DBT.
- *
- * If the primary get returns DB_NOTFOUND, something is amiss--
- * every record in the secondary should correspond to some record
- * in the primary.
- */
- if ((ret = __db_c_get(pdbc, &pkey, &skey,
- (STD_LOCKING(dbc) ? DB_RMW : 0) | DB_SET)) == 0)
- ret = __db_c_del(pdbc, 0);
- else if (ret == DB_NOTFOUND)
- ret = __db_secondary_corrupt(pdbp);
-
- if ((t_ret = __db_c_close(pdbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_c_del_primary --
- * Perform a delete operation on a primary index. Loop through
- * all the secondary indices which correspond to this primary
- * database, and delete any secondary keys that point at the current
- * record.
- *
- * PUBLIC: int __db_c_del_primary __P((DBC *));
- */
-int
-__db_c_del_primary(dbc)
- DBC *dbc;
-{
- DB *dbp, *sdbp;
- DBC *sdbc;
- DBT data, pkey, skey, temppkey, tempskey;
- int ret, t_ret;
-
- dbp = dbc->dbp;
-
- /*
- * If we're called at all, we have at least one secondary.
- * (Unfortunately, we can't assert this without grabbing the mutex.)
- * Get the current record so that we can construct appropriate
- * secondary keys as needed.
- */
- memset(&pkey, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
- if ((ret = __db_c_get(dbc, &pkey, &data, DB_CURRENT)) != 0)
- return (ret);
-
- if ((ret = __db_s_first(dbp, &sdbp)) != 0)
- goto err;
- for (; sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp)) {
- /*
- * Get the secondary key for this secondary and the current
- * item.
- */
- memset(&skey, 0, sizeof(DBT));
- if ((ret = sdbp->s_callback(sdbp, &pkey, &data, &skey)) != 0) {
- /*
- * If the current item isn't in this index, we
- * have no work to do. Proceed.
- */
- if (ret == DB_DONOTINDEX)
- continue;
-
- /* We had a substantive error. Bail. */
- FREE_IF_NEEDED(sdbp, &skey);
- goto err;
- }
-
- /* Open a secondary cursor. */
- if ((ret = __db_cursor_int(sdbp, dbc->txn, sdbp->type,
- PGNO_INVALID, 0, dbc->locker, &sdbc)) != 0)
- goto err;
- /* See comment above and in __db_c_put. */
- if (CDB_LOCKING(sdbp->dbenv)) {
- DB_ASSERT(sdbc->mylock.off == LOCK_INVALID);
- F_SET(sdbc, DBC_WRITER);
- }
-
- /*
- * Set the secondary cursor to the appropriate item.
- * Delete it.
- *
- * We want to use DB_RMW if locking is on; it's only
- * legal then, though.
- *
- * !!!
- * Don't stomp on any callback-allocated buffer in skey
- * when we do a c_get(DB_GET_BOTH); use a temp DBT instead.
- * Similarly, don't allow pkey to be invalidated when the
- * cursor is closed.
- */
- memset(&tempskey, 0, sizeof(DBT));
- tempskey.data = skey.data;
- tempskey.size = skey.size;
- SWAP_IF_NEEDED(dbp, sdbp, &pkey);
- memset(&temppkey, 0, sizeof(DBT));
- temppkey.data = pkey.data;
- temppkey.size = pkey.size;
- if ((ret = __db_c_get(sdbc, &tempskey, &temppkey,
- (STD_LOCKING(dbc) ? DB_RMW : 0) | DB_GET_BOTH)) == 0)
- ret = __db_c_del(sdbc, DB_UPDATE_SECONDARY);
- else if (ret == DB_NOTFOUND)
- ret = __db_secondary_corrupt(dbp);
- SWAP_IF_NEEDED(dbp, sdbp, &pkey);
-
- FREE_IF_NEEDED(sdbp, &skey);
-
- if ((t_ret = __db_c_close(sdbc)) != 0 && ret == 0)
- ret = t_ret;
- if (ret != 0)
- goto err;
- }
-
-err: if (sdbp != NULL && (t_ret = __db_s_done(sdbp)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
-
-/*
- * __db_s_first --
- * Get the first secondary, if any are present, from the primary.
- *
- * PUBLIC: int __db_s_first __P((DB *, DB **));
- */
-int
-__db_s_first(pdbp, sdbpp)
- DB *pdbp, **sdbpp;
-{
- DB *sdbp;
-
- MUTEX_LOCK(pdbp->dbenv, pdbp->mutex);
- sdbp = LIST_FIRST(&pdbp->s_secondaries);
-
- /* See __db_s_next. */
- if (sdbp != NULL)
- sdbp->s_refcnt++;
- MUTEX_UNLOCK(pdbp->dbenv, pdbp->mutex);
-
- *sdbpp = sdbp;
-
- return (0);
-}
-
-/*
- * __db_s_next --
- * Get the next secondary in the list.
- *
- * PUBLIC: int __db_s_next __P((DB **));
- */
-int
-__db_s_next(sdbpp)
- DB **sdbpp;
-{
- DB *sdbp, *pdbp, *closeme;
- int ret;
-
- /*
- * Secondary indices are kept in a linked list, s_secondaries,
- * off each primary DB handle. If a primary is free-threaded,
- * this list may only be traversed or modified while the primary's
- * thread mutex is held.
- *
- * The tricky part is that we don't want to hold the thread mutex
- * across the full set of secondary puts necessary for each primary
- * put, or we'll wind up essentially single-threading all the puts
- * to the handle; the secondary puts will each take about as
- * long as the primary does, and may require I/O. So we instead
- * hold the thread mutex only long enough to follow one link to the
- * next secondary, and then we release it before performing the
- * actual secondary put.
- *
- * The only danger here is that we might legitimately close a
- * secondary index in one thread while another thread is performing
- * a put and trying to update that same secondary index. To
- * prevent this from happening, we refcount the secondary handles.
- * If close is called on a secondary index handle while we're putting
- * to it, it won't really be closed--the refcount will simply drop,
- * and we'll be responsible for closing it here.
- */
- sdbp = *sdbpp;
- pdbp = sdbp->s_primary;
- closeme = NULL;
-
- MUTEX_LOCK(pdbp->dbenv, pdbp->mutex);
- DB_ASSERT(sdbp->s_refcnt != 0);
- if (--sdbp->s_refcnt == 0) {
- LIST_REMOVE(sdbp, s_links);
- closeme = sdbp;
- }
- sdbp = LIST_NEXT(sdbp, s_links);
- if (sdbp != NULL)
- sdbp->s_refcnt++;
- MUTEX_UNLOCK(pdbp->dbenv, pdbp->mutex);
-
- *sdbpp = sdbp;
-
- /*
- * closeme->close() is a wrapper; call __db_close explicitly.
- */
- ret = closeme != NULL ? __db_close(closeme, NULL, 0) : 0;
- return (ret);
-}
-
-/*
- * __db_s_done --
- * Properly decrement the refcount on a secondary database handle we're
- * using, without calling __db_s_next.
- *
- * PUBLIC: int __db_s_done __P((DB *));
- */
-int
-__db_s_done(sdbp)
- DB *sdbp;
-{
- DB *pdbp;
- int doclose;
-
- pdbp = sdbp->s_primary;
- doclose = 0;
-
- MUTEX_LOCK(pdbp->dbenv, pdbp->mutex);
- DB_ASSERT(sdbp->s_refcnt != 0);
- if (--sdbp->s_refcnt == 0) {
- LIST_REMOVE(sdbp, s_links);
- doclose = 1;
- }
- MUTEX_UNLOCK(pdbp->dbenv, pdbp->mutex);
-
- return (doclose ? __db_close(sdbp, NULL, 0) : 0);
-}
-
-/*
- * __db_buildpartial --
- * Build the record that will result after a partial put is applied to
- * an existing record.
- *
- * This should probably be merged with __bam_build, but that requires
- * a little trickery if we plan to keep the overflow-record optimization
- * in that function.
- */
-static int
-__db_buildpartial(dbp, oldrec, partial, newrec)
- DB *dbp;
- DBT *oldrec, *partial, *newrec;
-{
- int ret;
- u_int8_t *buf;
- u_int32_t len, nbytes;
-
- DB_ASSERT(F_ISSET(partial, DB_DBT_PARTIAL));
-
- memset(newrec, 0, sizeof(DBT));
-
- nbytes = __db_partsize(oldrec->size, partial);
- newrec->size = nbytes;
-
- if ((ret = __os_malloc(dbp->dbenv, nbytes, &buf)) != 0)
- return (ret);
- newrec->data = buf;
-
- /* Nul or pad out the buffer, for any part that isn't specified. */
- memset(buf,
- F_ISSET(dbp, DB_AM_FIXEDLEN) ? ((BTREE *)dbp->bt_internal)->re_pad :
- 0, nbytes);
-
- /* Copy in any leading data from the original record. */
- memcpy(buf, oldrec->data,
- partial->doff > oldrec->size ? oldrec->size : partial->doff);
-
- /* Copy the data from partial. */
- memcpy(buf + partial->doff, partial->data, partial->size);
-
- /* Copy any trailing data from the original record. */
- len = partial->doff + partial->dlen;
- if (oldrec->size > len)
- memcpy(buf + partial->doff + partial->size,
- (u_int8_t *)oldrec->data + len, oldrec->size - len);
-
- return (0);
-}
-
-/*
- * __db_partsize --
- * Given the number of bytes in an existing record and a DBT that
- * is about to be partial-put, calculate the size of the record
- * after the put.
- *
- * This code is called from __bam_partsize.
- *
- * PUBLIC: u_int32_t __db_partsize __P((u_int32_t, DBT *));
- */
-u_int32_t
-__db_partsize(nbytes, data)
- u_int32_t nbytes;
- DBT *data;
-{
-
- /*
- * There are really two cases here:
- *
- * Case 1: We are replacing some bytes that do not exist (i.e., they
- * are past the end of the record). In this case the number of bytes
- * we are replacing is irrelevant and all we care about is how many
- * bytes we are going to add from offset. So, the new record length
- * is going to be the size of the new bytes (size) plus wherever those
- * new bytes begin (doff).
- *
- * Case 2: All the bytes we are replacing exist. Therefore, the new
- * size is the oldsize (nbytes) minus the bytes we are replacing (dlen)
- * plus the bytes we are adding (size).
- */
- if (nbytes < data->doff + data->dlen) /* Case 1 */
- return (data->doff + data->size);
-
- return (nbytes + data->size - data->dlen); /* Case 2 */
-}
diff --git a/storage/bdb/db/db_conv.c b/storage/bdb/db/db_conv.c
deleted file mode 100644
index 53f4e638d5c..00000000000
--- a/storage/bdb/db/db_conv.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: db_conv.c,v 12.1 2005/06/16 20:21:09 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/crypto.h"
-#include "dbinc/hmac.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_swap.h"
-#include "dbinc/btree.h"
-#include "dbinc/hash.h"
-#include "dbinc/log.h"
-#include "dbinc/qam.h"
-
-/*
- * __db_pgin --
- * Primary page-swap routine.
- *
- * PUBLIC: int __db_pgin __P((DB_ENV *, db_pgno_t, void *, DBT *));
- */
-int
-__db_pgin(dbenv, pg, pp, cookie)
- DB_ENV *dbenv;
- db_pgno_t pg;
- void *pp;
- DBT *cookie;
-{
- DB dummydb, *dbp;
- DB_PGINFO *pginfo;
- DB_CIPHER *db_cipher;
- DB_LSN not_used;
- PAGE *pagep;
- size_t pg_off, pg_len, sum_len;
- int is_hmac, ret;
- u_int8_t *chksum, *iv;
-
- pginfo = (DB_PGINFO *)cookie->data;
- pagep = (PAGE *)pp;
-
- ret = is_hmac = 0;
- chksum = iv = NULL;
- memset(&dummydb, 0, sizeof(DB));
- dbp = &dummydb;
- dummydb.flags = pginfo->flags;
- db_cipher = (DB_CIPHER *)dbenv->crypto_handle;
- switch (pagep->type) {
- case P_HASHMETA:
- case P_BTREEMETA:
- case P_QAMMETA:
- /*
- * If checksumming is set on the meta-page, we must set
- * it in the dbp.
- */
- if (FLD_ISSET(((DBMETA *)pp)->metaflags, DBMETA_CHKSUM))
- F_SET(dbp, DB_AM_CHKSUM);
- else
- F_CLR(dbp, DB_AM_CHKSUM);
- if (((DBMETA *)pp)->encrypt_alg != 0 ||
- F_ISSET(dbp, DB_AM_ENCRYPT))
- is_hmac = 1;
- /*
- * !!!
- * For all meta pages it is required that the chksum
- * be at the same location. Use BTMETA to get to it
- * for any meta type.
- */
- chksum = ((BTMETA *)pp)->chksum;
- sum_len = DBMETASIZE;
- break;
- case P_INVALID:
- /*
- * We assume that we've read a file hole if we have
- * a zero LSN, zero page number and P_INVALID. Otherwise
- * we have an invalid page that might contain real data.
- */
- if (IS_ZERO_LSN(LSN(pagep)) && pagep->pgno == PGNO_INVALID) {
- sum_len = 0;
- break;
- }
- /* FALLTHROUGH */
- default:
- chksum = P_CHKSUM(dbp, pagep);
- sum_len = pginfo->db_pagesize;
- /*
- * If we are reading in a non-meta page, then if we have
- * a db_cipher then we are using hmac.
- */
- is_hmac = CRYPTO_ON(dbenv) ? 1 : 0;
- break;
- }
-
- /*
- * We expect a checksum error if there was a configuration problem.
- * If there is no configuration problem and we don't get a match,
- * it's fatal: panic the system.
- */
- if (F_ISSET(dbp, DB_AM_CHKSUM) && sum_len != 0) {
- if (F_ISSET(dbp, DB_AM_SWAP) && is_hmac == 0)
- P_32_SWAP(chksum);
- switch (ret = __db_check_chksum(
- dbenv, db_cipher, chksum, pp, sum_len, is_hmac)) {
- case 0:
- break;
- case -1:
- if (DBENV_LOGGING(dbenv))
- (void)__db_cksum_log(
- dbenv, NULL, ¬_used, DB_FLUSH);
- __db_err(dbenv,
- "checksum error: page %lu: catastrophic recovery required",
- (u_long)pg);
- return (__db_panic(dbenv, DB_RUNRECOVERY));
- default:
- return (ret);
- }
- }
- if (F_ISSET(dbp, DB_AM_ENCRYPT)) {
- DB_ASSERT(db_cipher != NULL);
- DB_ASSERT(F_ISSET(dbp, DB_AM_CHKSUM));
-
- pg_off = P_OVERHEAD(dbp);
- DB_ASSERT(db_cipher->adj_size(pg_off) == 0);
-
- switch (pagep->type) {
- case P_HASHMETA:
- case P_BTREEMETA:
- case P_QAMMETA:
- /*
- * !!!
- * For all meta pages it is required that the iv
- * be at the same location. Use BTMETA to get to it
- * for any meta type.
- */
- iv = ((BTMETA *)pp)->iv;
- pg_len = DBMETASIZE;
- break;
- case P_INVALID:
- if (IS_ZERO_LSN(LSN(pagep)) &&
- pagep->pgno == PGNO_INVALID) {
- pg_len = 0;
- break;
- }
- /* FALLTHROUGH */
- default:
- iv = P_IV(dbp, pagep);
- pg_len = pginfo->db_pagesize;
- break;
- }
- if (pg_len != 0 && (ret = db_cipher->decrypt(dbenv,
- db_cipher->data, iv, ((u_int8_t *)pagep) + pg_off,
- pg_len - pg_off)) != 0)
- return (ret);
- }
- switch (pagep->type) {
- case P_INVALID:
- if (pginfo->type == DB_QUEUE)
- return (__qam_pgin_out(dbenv, pg, pp, cookie));
- else
- return (__ham_pgin(dbenv, dbp, pg, pp, cookie));
- case P_HASH:
- case P_HASHMETA:
- return (__ham_pgin(dbenv, dbp, pg, pp, cookie));
- case P_BTREEMETA:
- case P_IBTREE:
- case P_IRECNO:
- case P_LBTREE:
- case P_LDUP:
- case P_LRECNO:
- case P_OVERFLOW:
- return (__bam_pgin(dbenv, dbp, pg, pp, cookie));
- case P_QAMMETA:
- case P_QAMDATA:
- return (__qam_pgin_out(dbenv, pg, pp, cookie));
- default:
- break;
- }
- return (__db_pgfmt(dbenv, pg));
-}
-
-/*
- * __db_pgout --
- * Primary page-swap routine.
- *
- * PUBLIC: int __db_pgout __P((DB_ENV *, db_pgno_t, void *, DBT *));
- */
-int
-__db_pgout(dbenv, pg, pp, cookie)
- DB_ENV *dbenv;
- db_pgno_t pg;
- void *pp;
- DBT *cookie;
-{
- DB dummydb, *dbp;
- DB_CIPHER *db_cipher;
- DB_PGINFO *pginfo;
- PAGE *pagep;
- size_t pg_off, pg_len, sum_len;
- int ret;
- u_int8_t *chksum, *iv, *key;
-
- pginfo = (DB_PGINFO *)cookie->data;
- pagep = (PAGE *)pp;
-
- chksum = iv = key = NULL;
- memset(&dummydb, 0, sizeof(DB));
- dbp = &dummydb;
- dummydb.flags = pginfo->flags;
- ret = 0;
- switch (pagep->type) {
- case P_INVALID:
- if (pginfo->type == DB_QUEUE)
- ret = __qam_pgin_out(dbenv, pg, pp, cookie);
- else
- ret = __ham_pgout(dbenv, dbp, pg, pp, cookie);
- break;
- case P_HASH:
- case P_HASHMETA:
- ret = __ham_pgout(dbenv, dbp, pg, pp, cookie);
- break;
- case P_BTREEMETA:
- case P_IBTREE:
- case P_IRECNO:
- case P_LBTREE:
- case P_LDUP:
- case P_LRECNO:
- case P_OVERFLOW:
- ret = __bam_pgout(dbenv, dbp, pg, pp, cookie);
- break;
- case P_QAMMETA:
- case P_QAMDATA:
- ret = __qam_pgin_out(dbenv, pg, pp, cookie);
- break;
- default:
- return (__db_pgfmt(dbenv, pg));
- }
- if (ret)
- return (ret);
-
- db_cipher = (DB_CIPHER *)dbenv->crypto_handle;
- if (F_ISSET(dbp, DB_AM_ENCRYPT)) {
-
- DB_ASSERT(db_cipher != NULL);
- DB_ASSERT(F_ISSET(dbp, DB_AM_CHKSUM));
-
- pg_off = P_OVERHEAD(dbp);
- DB_ASSERT(db_cipher->adj_size(pg_off) == 0);
-
- key = db_cipher->mac_key;
-
- switch (pagep->type) {
- case P_HASHMETA:
- case P_BTREEMETA:
- case P_QAMMETA:
- /*
- * !!!
- * For all meta pages it is required that the iv
- * be at the same location. Use BTMETA to get to it
- * for any meta type.
- */
- iv = ((BTMETA *)pp)->iv;
- pg_len = DBMETASIZE;
- break;
- default:
- iv = P_IV(dbp, pagep);
- pg_len = pginfo->db_pagesize;
- break;
- }
- if ((ret = db_cipher->encrypt(dbenv, db_cipher->data,
- iv, ((u_int8_t *)pagep) + pg_off, pg_len - pg_off)) != 0)
- return (ret);
- }
- if (F_ISSET(dbp, DB_AM_CHKSUM)) {
- switch (pagep->type) {
- case P_HASHMETA:
- case P_BTREEMETA:
- case P_QAMMETA:
- /*
- * !!!
- * For all meta pages it is required that the chksum
- * be at the same location. Use BTMETA to get to it
- * for any meta type.
- */
- chksum = ((BTMETA *)pp)->chksum;
- sum_len = DBMETASIZE;
- break;
- default:
- chksum = P_CHKSUM(dbp, pagep);
- sum_len = pginfo->db_pagesize;
- break;
- }
- __db_chksum(pp, sum_len, key, chksum);
- if (F_ISSET(dbp, DB_AM_SWAP) && !F_ISSET(dbp, DB_AM_ENCRYPT))
- P_32_SWAP(chksum);
- }
- return (0);
-}
-
-/*
- * __db_metaswap --
- * Byteswap the common part of the meta-data page.
- *
- * PUBLIC: void __db_metaswap __P((PAGE *));
- */
-void
-__db_metaswap(pg)
- PAGE *pg;
-{
- u_int8_t *p;
-
- p = (u_int8_t *)pg;
-
- /* Swap the meta-data information. */
- SWAP32(p); /* lsn.file */
- SWAP32(p); /* lsn.offset */
- SWAP32(p); /* pgno */
- SWAP32(p); /* magic */
- SWAP32(p); /* version */
- SWAP32(p); /* pagesize */
- p += 4; /* unused, page type, unused, unused */
- SWAP32(p); /* free */
- SWAP32(p); /* alloc_lsn part 1 */
- SWAP32(p); /* alloc_lsn part 2 */
- SWAP32(p); /* cached key count */
- SWAP32(p); /* cached record count */
- SWAP32(p); /* flags */
-}
-
-/*
- * __db_byteswap --
- * Byteswap a page.
- *
- * PUBLIC: int __db_byteswap
- * PUBLIC: __P((DB_ENV *, DB *, db_pgno_t, PAGE *, size_t, int));
- */
-int
-__db_byteswap(dbenv, dbp, pg, h, pagesize, pgin)
- DB_ENV *dbenv;
- DB *dbp;
- db_pgno_t pg;
- PAGE *h;
- size_t pagesize;
- int pgin;
-{
- BINTERNAL *bi;
- BKEYDATA *bk;
- BOVERFLOW *bo;
- RINTERNAL *ri;
- db_indx_t i, *inp, len, tmp;
- u_int8_t *p, *end;
-
- COMPQUIET(pg, 0);
-
- inp = P_INP(dbp, h);
- if (pgin) {
- M_32_SWAP(h->lsn.file);
- M_32_SWAP(h->lsn.offset);
- M_32_SWAP(h->pgno);
- M_32_SWAP(h->prev_pgno);
- M_32_SWAP(h->next_pgno);
- M_16_SWAP(h->entries);
- M_16_SWAP(h->hf_offset);
- }
-
- switch (h->type) {
- case P_HASH:
- for (i = 0; i < NUM_ENT(h); i++) {
- if (pgin)
- M_16_SWAP(inp[i]);
-
- switch (HPAGE_TYPE(dbp, h, i)) {
- case H_KEYDATA:
- break;
- case H_DUPLICATE:
- len = LEN_HKEYDATA(dbp, h, pagesize, i);
- p = HKEYDATA_DATA(P_ENTRY(dbp, h, i));
- for (end = p + len; p < end;) {
- if (pgin) {
- P_16_SWAP(p);
- memcpy(&tmp,
- p, sizeof(db_indx_t));
- p += sizeof(db_indx_t);
- } else {
- memcpy(&tmp,
- p, sizeof(db_indx_t));
- SWAP16(p);
- }
- p += tmp;
- SWAP16(p);
- }
- break;
- case H_OFFDUP:
- p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i));
- SWAP32(p); /* pgno */
- break;
- case H_OFFPAGE:
- p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i));
- SWAP32(p); /* pgno */
- SWAP32(p); /* tlen */
- break;
- default:
- return (__db_pgfmt(dbenv, pg));
- }
-
- }
-
- /*
- * The offsets in the inp array are used to determine
- * the size of entries on a page; therefore they
- * cannot be converted until we've done all the
- * entries.
- */
- if (!pgin)
- for (i = 0; i < NUM_ENT(h); i++)
- M_16_SWAP(inp[i]);
- break;
- case P_LBTREE:
- case P_LDUP:
- case P_LRECNO:
- for (i = 0; i < NUM_ENT(h); i++) {
- if (pgin)
- M_16_SWAP(inp[i]);
-
- /*
- * In the case of on-page duplicates, key information
- * should only be swapped once.
- */
- if (h->type == P_LBTREE && i > 1) {
- if (pgin) {
- if (inp[i] == inp[i - 2])
- continue;
- } else {
- M_16_SWAP(inp[i]);
- if (inp[i] == inp[i - 2])
- continue;
- M_16_SWAP(inp[i]);
- }
- }
-
- bk = GET_BKEYDATA(dbp, h, i);
- switch (B_TYPE(bk->type)) {
- case B_KEYDATA:
- M_16_SWAP(bk->len);
- break;
- case B_DUPLICATE:
- case B_OVERFLOW:
- bo = (BOVERFLOW *)bk;
- M_32_SWAP(bo->pgno);
- M_32_SWAP(bo->tlen);
- break;
- default:
- return (__db_pgfmt(dbenv, pg));
- }
-
- if (!pgin)
- M_16_SWAP(inp[i]);
- }
- break;
- case P_IBTREE:
- for (i = 0; i < NUM_ENT(h); i++) {
- if (pgin)
- M_16_SWAP(inp[i]);
-
- bi = GET_BINTERNAL(dbp, h, i);
- M_16_SWAP(bi->len);
- M_32_SWAP(bi->pgno);
- M_32_SWAP(bi->nrecs);
-
- switch (B_TYPE(bi->type)) {
- case B_KEYDATA:
- break;
- case B_DUPLICATE:
- case B_OVERFLOW:
- bo = (BOVERFLOW *)bi->data;
- M_32_SWAP(bo->pgno);
- M_32_SWAP(bo->tlen);
- break;
- default:
- return (__db_pgfmt(dbenv, pg));
- }
-
- if (!pgin)
- M_16_SWAP(inp[i]);
- }
- break;
- case P_IRECNO:
- for (i = 0; i < NUM_ENT(h); i++) {
- if (pgin)
- M_16_SWAP(inp[i]);
-
- ri = GET_RINTERNAL(dbp, h, i);
- M_32_SWAP(ri->pgno);
- M_32_SWAP(ri->nrecs);
-
- if (!pgin)
- M_16_SWAP(inp[i]);
- }
- break;
- case P_OVERFLOW:
- case P_INVALID:
- /* Nothing to do. */
- break;
- default:
- return (__db_pgfmt(dbenv, pg));
- }
-
- if (!pgin) {
- /* Swap the header information. */
- M_32_SWAP(h->lsn.file);
- M_32_SWAP(h->lsn.offset);
- M_32_SWAP(h->pgno);
- M_32_SWAP(h->prev_pgno);
- M_32_SWAP(h->next_pgno);
- M_16_SWAP(h->entries);
- M_16_SWAP(h->hf_offset);
- }
- return (0);
-}
diff --git a/storage/bdb/db/db_dispatch.c b/storage/bdb/db/db_dispatch.c
deleted file mode 100644
index 3c56b556219..00000000000
--- a/storage/bdb/db/db_dispatch.c
+++ /dev/null
@@ -1,1603 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1995, 1996
- * The President and Fellows of Harvard University. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: db_dispatch.c,v 12.12 2005/11/10 21:11:42 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#ifndef HAVE_FTRUNCATE
-#include "dbinc/db_shash.h"
-#endif
-#include "dbinc/hash.h"
-#ifndef HAVE_FTRUNCATE
-#include "dbinc/lock.h"
-#include "dbinc/mp.h"
-#endif
-#include "dbinc/log.h"
-#include "dbinc/fop.h"
-#include "dbinc/txn.h"
-
-#ifndef HAVE_FTRUNCATE
-static int __db_limbo_fix __P((DB *, DB_TXN *,
- DB_TXNLIST *, db_pgno_t *, DBMETA *, db_limbo_state));
-static int __db_limbo_bucket __P((DB_ENV *,
- DB_TXN *, DB_TXNLIST *, db_limbo_state));
-static int __db_limbo_move __P((DB_ENV *, DB_TXN *, DB_TXN *, DB_TXNLIST *));
-static int __db_limbo_prepare __P(( DB *, DB_TXN *, DB_TXNLIST *));
-static int __db_lock_move __P((DB_ENV *,
- u_int8_t *, db_pgno_t, db_lockmode_t, DB_TXN *, DB_TXN *));
-static int __db_txnlist_pgnoadd __P((DB_ENV *, DB_TXNHEAD *,
- int32_t, u_int8_t *, char *, db_pgno_t));
-#endif
-static int __db_txnlist_find_internal __P((DB_ENV *, DB_TXNHEAD *,
- db_txnlist_type, u_int32_t, u_int8_t *, DB_TXNLIST **,
- int, u_int32_t *));
-
-/*
- * __db_dispatch --
- *
- * This is the transaction dispatch function used by the db access methods.
- * It is designed to handle the record format used by all the access
- * methods (the one automatically generated by the db_{h,log,read}.sh
- * scripts in the tools directory). An application using a different
- * recovery paradigm will supply a different dispatch function to txn_open.
- *
- * PUBLIC: int __db_dispatch __P((DB_ENV *,
- * PUBLIC: int (**)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)),
- * PUBLIC: size_t, DBT *, DB_LSN *, db_recops, DB_TXNHEAD *));
- */
-int
-__db_dispatch(dbenv, dtab, dtabsize, db, lsnp, redo, info)
- DB_ENV *dbenv; /* The environment. */
- int (**dtab)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- size_t dtabsize; /* Size of the dtab. */
- DBT *db; /* The log record upon which to dispatch. */
- DB_LSN *lsnp; /* The lsn of the record being dispatched. */
- db_recops redo; /* Redo this op (or undo it). */
- DB_TXNHEAD *info; /* Transaction list. */
-{
- DB_LSN prev_lsn;
- u_int32_t rectype, status, txnid;
- int make_call, ret;
-
- memcpy(&rectype, db->data, sizeof(rectype));
- memcpy(&txnid, (u_int8_t *)db->data + sizeof(rectype), sizeof(txnid));
- make_call = ret = 0;
-
- /* If we don't have a dispatch table, it's hard to dispatch. */
- DB_ASSERT(dtab != NULL);
-
- /*
- * If we find a record that is in the user's number space and they
- * have specified a recovery routine, let them handle it. If they
- * didn't specify a recovery routine, then we expect that they've
- * followed all our rules and registered new recovery functions.
- */
- switch (redo) {
- case DB_TXN_ABORT:
- case DB_TXN_APPLY:
- case DB_TXN_PRINT:
- make_call = 1;
- break;
- case DB_TXN_OPENFILES:
- /*
- * We collect all the transactions that have
- * "begin" records, those with no previous LSN,
- * so that we do not abort partial transactions.
- * These are known to be undone, otherwise the
- * log would not have been freeable.
- */
- memcpy(&prev_lsn, (u_int8_t *)db->data +
- sizeof(rectype) + sizeof(txnid), sizeof(prev_lsn));
- if (txnid != 0 && prev_lsn.file == 0 && (ret =
- __db_txnlist_add(dbenv, info, txnid, TXN_OK, NULL)) != 0)
- return (ret);
-
- /* FALLTHROUGH */
- case DB_TXN_POPENFILES:
- if (rectype == DB___dbreg_register ||
- rectype == DB___txn_child ||
- rectype == DB___txn_ckp || rectype == DB___txn_recycle)
- return (dtab[rectype](dbenv, db, lsnp, redo, info));
- break;
- case DB_TXN_BACKWARD_ROLL:
- /*
- * Running full recovery in the backward pass. In general,
- * we only process records during this pass that belong
- * to aborted transactions. Unfortunately, there are several
- * exceptions:
- * 1. If this is a meta-record, one not associated with
- * a transaction, then we must always process it.
- * 2. If this is a transaction commit/abort, we must
- * always process it, so that we know the status of
- * every transaction.
- * 3. If this is a child commit, we need to process it
- * because the outcome of the child transaction depends
- * on the outcome of the parent.
- * 4. If this is a dbreg_register record, we must always
- * process is because they contain non-transactional
- * closes that must be properly handled.
- * 5. If this is a noop, we must always undo it so that we
- * properly handle any aborts before a file was closed.
- * 6. If this a file remove, we need to process it to
- * determine if the on-disk file is the same as the
- * one being described.
- */
- switch (rectype) {
- /*
- * These either do not belong to a transaction or (regop)
- * must be processed regardless of the status of the
- * transaction.
- */
- case DB___txn_regop:
- case DB___txn_recycle:
- case DB___txn_ckp:
- make_call = 1;
- break;
- /*
- * These belong to a transaction whose status must be
- * checked.
- */
- case DB___txn_child:
- case DB___db_noop:
- case DB___fop_file_remove:
- case DB___dbreg_register:
- make_call = 1;
-
- /* FALLTHROUGH */
- default:
- if (txnid == 0)
- break;
-
- ret = __db_txnlist_find(dbenv, info, txnid, &status);
-
- /* If not found, this is an incomplete abort. */
- if (ret == DB_NOTFOUND)
- return (__db_txnlist_add(dbenv,
- info, txnid, TXN_IGNORE, lsnp));
- if (ret != 0)
- return (ret);
-
- /*
- * If we ignore the transaction, ignore the operation
- * UNLESS this is a child commit in which case we need
- * to make sure that the child also gets marked as
- * ignore.
- */
- if (status == TXN_IGNORE && rectype != DB___txn_child) {
- make_call = 0;
- break;
- }
- if (status == TXN_COMMIT)
- break;
-
- /* Set make_call in case we came through default */
- make_call = 1;
- if (status == TXN_OK &&
- (ret = __db_txnlist_update(dbenv,
- info, txnid, rectype == DB___txn_xa_regop ?
- TXN_PREPARE : TXN_ABORT, NULL, &status, 0)) != 0)
- return (ret);
- }
- break;
- case DB_TXN_FORWARD_ROLL:
- /*
- * In the forward pass, if we haven't seen the transaction,
- * do nothing, else recover it.
- *
- * We need to always redo DB___db_noop records, so that we
- * properly handle any commits after the file was closed.
- */
- switch (rectype) {
- case DB___txn_recycle:
- case DB___txn_ckp:
- case DB___db_noop:
- make_call = 1;
- break;
-
- default:
- if (txnid == 0)
- status = 0;
- else {
- ret = __db_txnlist_find(dbenv,
- info, txnid, &status);
-
- if (ret == DB_NOTFOUND)
- /* Break out out of if clause. */
- ;
- else if (ret != 0)
- return (ret);
- else if (status == TXN_COMMIT) {
- make_call = 1;
- break;
- }
- }
-
-#ifndef HAVE_FTRUNCATE
- if (status != TXN_IGNORE &&
- (rectype == DB___ham_metagroup ||
- rectype == DB___ham_groupalloc ||
- rectype == DB___db_pg_alloc)) {
- /*
- * Because we do not have truncate
- * all allocation records must be reprocessed
- * during rollforward in case the file was
- * just created. It may not have been
- * present during the backward pass.
- */
- make_call = 1;
- redo = DB_TXN_BACKWARD_ALLOC;
- } else
-#endif
- if (rectype == DB___dbreg_register) {
- /*
- * This may be a transaction dbreg_register.
- * If it is, we only make the call on a COMMIT,
- * which we checked above. If it's not, then we
- * should always make the call, because we need
- * the file open information.
- */
- if (txnid == 0)
- make_call = 1;
- }
- }
- break;
- case DB_TXN_BACKWARD_ALLOC:
- default:
- return (__db_unknown_flag(
- dbenv, "__db_dispatch", (u_int32_t)redo));
- }
-
- if (make_call) {
- /*
- * If the debug flag is set then we are logging
- * records for a non-durable update so that they
- * may be examined for diagnostic purposes.
- * So only make the call if we are printing,
- * otherwise we need to extract the previous
- * lsn so undo will work properly.
- */
- if (rectype & DB_debug_FLAG) {
- if (redo == DB_TXN_PRINT)
- rectype &= ~DB_debug_FLAG;
- else {
- memcpy(lsnp,
- (u_int8_t *)db->data +
- sizeof(rectype) +
- sizeof(txnid), sizeof(*lsnp));
- return (0);
- }
- }
- if (rectype >= DB_user_BEGIN && dbenv->app_dispatch != NULL)
- return (dbenv->app_dispatch(dbenv, db, lsnp, redo));
- else {
- /*
- * The size of the dtab table argument is the same as
- * the standard table, use the standard table's size
- * as our sanity check.
- */
- if (rectype > dtabsize || dtab[rectype] == NULL) {
- __db_err(dbenv,
- "Illegal record type %lu in log",
- (u_long)rectype);
- return (EINVAL);
- }
- return (dtab[rectype](dbenv, db, lsnp, redo, info));
- }
- }
-
- return (0);
-}
-
-/*
- * __db_add_recovery --
- *
- * PUBLIC: int __db_add_recovery __P((DB_ENV *,
- * PUBLIC: int (***)(DB_ENV *, DBT *, DB_LSN *, db_recops, void *), size_t *,
- * PUBLIC: int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops, void *), u_int32_t));
- */
-int
-__db_add_recovery(dbenv, dtab, dtabsize, func, ndx)
- DB_ENV *dbenv;
- int (***dtab) __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- size_t *dtabsize;
- int (*func) __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- u_int32_t ndx;
-{
- size_t i, nsize;
- int ret;
-
- /* Check if we have to grow the table. */
- if (ndx >= *dtabsize) {
- nsize = ndx + 40;
- if ((ret =
- __os_realloc(dbenv, nsize * sizeof((*dtab)[0]), dtab)) != 0)
- return (ret);
- for (i = *dtabsize; i < nsize; ++i)
- (*dtab)[i] = NULL;
- *dtabsize = nsize;
- }
-
- (*dtab)[ndx] = func;
- return (0);
-}
-
-/*
- * __db_txnlist_init --
- * Initialize transaction linked list.
- *
- * PUBLIC: int __db_txnlist_init __P((DB_ENV *,
- * PUBLIC: u_int32_t, u_int32_t, DB_LSN *, DB_TXNHEAD **));
- */
-int
-__db_txnlist_init(dbenv, low_txn, hi_txn, trunc_lsn, retp)
- DB_ENV *dbenv;
- u_int32_t low_txn, hi_txn;
- DB_LSN *trunc_lsn;
- DB_TXNHEAD **retp;
-{
- DB_TXNHEAD *headp;
- u_int32_t size, tmp;
- int ret;
-
- /*
- * Size a hash table.
- * If low is zero then we are being called during rollback
- * and we need only one slot.
- * Hi maybe lower than low if we have recycled txnid's.
- * The numbers here are guesses about txn density, we can afford
- * to look at a few entries in each slot.
- */
- if (low_txn == 0)
- size = 1;
- else {
- if (hi_txn < low_txn) {
- tmp = hi_txn;
- hi_txn = low_txn;
- low_txn = tmp;
- }
- tmp = hi_txn - low_txn;
- /* See if we wrapped around. */
- if (tmp > (TXN_MAXIMUM - TXN_MINIMUM) / 2)
- tmp = (low_txn - TXN_MINIMUM) + (TXN_MAXIMUM - hi_txn);
- size = tmp / 5;
- if (size < 100)
- size = 100;
- }
- if ((ret = __os_malloc(dbenv,
- sizeof(DB_TXNHEAD) + size * sizeof(headp->head), &headp)) != 0)
- return (ret);
-
- memset(headp, 0, sizeof(DB_TXNHEAD) + size * sizeof(headp->head));
- headp->maxid = hi_txn;
- headp->generation = 0;
- headp->nslots = size;
- headp->gen_alloc = 8;
- if ((ret = __os_malloc(dbenv, headp->gen_alloc *
- sizeof(headp->gen_array[0]), &headp->gen_array)) != 0) {
- __os_free(dbenv, headp);
- return (ret);
- }
- headp->gen_array[0].generation = 0;
- headp->gen_array[0].txn_min = TXN_MINIMUM;
- headp->gen_array[0].txn_max = TXN_MAXIMUM;
- if (trunc_lsn != NULL) {
- headp->trunc_lsn = *trunc_lsn;
- headp->maxlsn = *trunc_lsn;
- } else {
- ZERO_LSN(headp->trunc_lsn);
- ZERO_LSN(headp->maxlsn);
- }
- ZERO_LSN(headp->ckplsn);
-
- *retp = headp;
- return (0);
-}
-
-/*
- * __db_txnlist_add --
- * Add an element to our transaction linked list.
- *
- * PUBLIC: int __db_txnlist_add __P((DB_ENV *,
- * PUBLIC: DB_TXNHEAD *, u_int32_t, u_int32_t, DB_LSN *));
- */
-int
-__db_txnlist_add(dbenv, hp, txnid, status, lsn)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
- u_int32_t txnid, status;
- DB_LSN *lsn;
-{
- DB_TXNLIST *elp;
- int ret;
-
- if ((ret = __os_malloc(dbenv, sizeof(DB_TXNLIST), &elp)) != 0)
- return (ret);
-
- LIST_INSERT_HEAD(&hp->head[DB_TXNLIST_MASK(hp, txnid)], elp, links);
-
- elp->type = TXNLIST_TXNID;
- elp->u.t.txnid = txnid;
- elp->u.t.status = status;
- elp->u.t.generation = hp->generation;
- if (txnid > hp->maxid)
- hp->maxid = txnid;
- if (lsn != NULL && IS_ZERO_LSN(hp->maxlsn) && status == TXN_COMMIT)
- hp->maxlsn = *lsn;
-
- DB_ASSERT(lsn == NULL ||
- status != TXN_COMMIT || log_compare(&hp->maxlsn, lsn) >= 0);
-
- return (0);
-}
-
-/*
- * __db_txnlist_remove --
- * Remove an element from our transaction linked list.
- *
- * PUBLIC: int __db_txnlist_remove __P((DB_ENV *, DB_TXNHEAD *, u_int32_t));
- */
-int
-__db_txnlist_remove(dbenv, hp, txnid)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
- u_int32_t txnid;
-{
- DB_TXNLIST *entry;
- u_int32_t status;
-
- return (__db_txnlist_find_internal(dbenv,
- hp, TXNLIST_TXNID, txnid, NULL, &entry, 1, &status));
-}
-
-/*
- * __db_txnlist_ckp --
- * Used to record the maximum checkpoint that will be retained
- * after recovery. Typically this is simply the max checkpoint, but
- * if we are doing client replication recovery or timestamp-based
- * recovery, we are going to virtually truncate the log and we need
- * to retain the last checkpoint before the truncation point.
- *
- * PUBLIC: void __db_txnlist_ckp __P((DB_ENV *, DB_TXNHEAD *, DB_LSN *));
- */
-void
-__db_txnlist_ckp(dbenv, hp, ckp_lsn)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
- DB_LSN *ckp_lsn;
-{
-
- COMPQUIET(dbenv, NULL);
-
- if (IS_ZERO_LSN(hp->ckplsn) && !IS_ZERO_LSN(hp->maxlsn) &&
- log_compare(&hp->maxlsn, ckp_lsn) >= 0)
- hp->ckplsn = *ckp_lsn;
-}
-
-/*
- * __db_txnlist_end --
- * Discard transaction linked list.
- *
- * PUBLIC: void __db_txnlist_end __P((DB_ENV *, DB_TXNHEAD *));
- */
-void
-__db_txnlist_end(dbenv, hp)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
-{
- u_int32_t i;
- DB_TXNLIST *p;
-
- if (hp == NULL)
- return;
-
- for (i = 0; i < hp->nslots; i++)
- while (hp != NULL && (p = LIST_FIRST(&hp->head[i])) != NULL) {
- switch (p->type) {
- case TXNLIST_LSN:
- __os_free(dbenv, p->u.l.lsn_stack);
- break;
- case TXNLIST_DELETE:
- case TXNLIST_PGNO:
- case TXNLIST_TXNID:
- default:
- /*
- * Possibly an incomplete DB_TXNLIST; just
- * free it.
- */
- break;
- }
- LIST_REMOVE(p, links);
- __os_free(dbenv, p);
- }
-
- if (hp->gen_array != NULL)
- __os_free(dbenv, hp->gen_array);
- __os_free(dbenv, hp);
-}
-
-/*
- * __db_txnlist_find --
- * Checks to see if a txnid with the current generation is in the
- * txnid list. This returns DB_NOTFOUND if the item isn't in the
- * list otherwise it returns (like __db_txnlist_find_internal)
- * the status of the transaction. A txnid of 0 means the record
- * was generated while not in a transaction.
- *
- * PUBLIC: int __db_txnlist_find __P((DB_ENV *,
- * PUBLIC: DB_TXNHEAD *, u_int32_t, u_int32_t *));
- */
-int
-__db_txnlist_find(dbenv, hp, txnid, statusp)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
- u_int32_t txnid, *statusp;
-{
- DB_TXNLIST *entry;
-
- if (txnid == 0)
- return (DB_NOTFOUND);
-
- return (__db_txnlist_find_internal(dbenv, hp,
- TXNLIST_TXNID, txnid, NULL, &entry, 0, statusp));
-}
-
-/*
- * __db_txnlist_update --
- * Change the status of an existing transaction entry.
- * Returns DB_NOTFOUND if no such entry exists.
- *
- * PUBLIC: int __db_txnlist_update __P((DB_ENV *, DB_TXNHEAD *,
- * PUBLIC: u_int32_t, u_int32_t, DB_LSN *, u_int32_t *, int));
- */
-int
-__db_txnlist_update(dbenv, hp, txnid, status, lsn, ret_status, add_ok)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
- u_int32_t txnid, status;
- DB_LSN *lsn;
- u_int32_t *ret_status;
- int add_ok;
-{
- DB_TXNLIST *elp;
- int ret;
-
- if (txnid == 0)
- return (DB_NOTFOUND);
-
- ret = __db_txnlist_find_internal(dbenv,
- hp, TXNLIST_TXNID, txnid, NULL, &elp, 0, ret_status);
-
- if (ret == DB_NOTFOUND && add_ok) {
- *ret_status = status;
- return (__db_txnlist_add(dbenv, hp, txnid, status, lsn));
- }
- if (ret != 0)
- return (ret);
-
- if (*ret_status == TXN_IGNORE)
- return (0);
-
- elp->u.t.status = status;
-
- if (lsn != NULL && IS_ZERO_LSN(hp->maxlsn) && status == TXN_COMMIT)
- hp->maxlsn = *lsn;
-
- return (ret);
-}
-
-/*
- * __db_txnlist_find_internal --
- * Find an entry on the transaction list. If the entry is not there or
- * the list pointer is not initialized we return DB_NOTFOUND. If the
- * item is found, we return the status. Currently we always call this
- * with an initialized list pointer but checking for NULL keeps it general.
- */
-static int
-__db_txnlist_find_internal(dbenv,
- hp, type, txnid, uid, txnlistp, delete, statusp)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
- db_txnlist_type type;
- u_int32_t txnid;
- u_int8_t uid[DB_FILE_ID_LEN];
- DB_TXNLIST **txnlistp;
- int delete;
- u_int32_t *statusp;
-{
- struct __db_headlink *head;
- DB_TXNLIST *p;
- u_int32_t generation, hash, i;
- int ret;
-
- ret = 0;
-
- if (hp == NULL)
- return (DB_NOTFOUND);
-
- switch (type) {
- case TXNLIST_TXNID:
- hash = txnid;
- /* Find the most recent generation containing this ID */
- for (i = 0; i <= hp->generation; i++)
- /* The range may wrap around the end. */
- if (hp->gen_array[i].txn_min <
- hp->gen_array[i].txn_max ?
- (txnid >= hp->gen_array[i].txn_min &&
- txnid <= hp->gen_array[i].txn_max) :
- (txnid >= hp->gen_array[i].txn_min ||
- txnid <= hp->gen_array[i].txn_max))
- break;
- DB_ASSERT(i <= hp->generation);
- generation = hp->gen_array[i].generation;
- break;
- case TXNLIST_PGNO:
- memcpy(&hash, uid, sizeof(hash));
- generation = 0;
- break;
- case TXNLIST_DELETE:
- case TXNLIST_LSN:
- default:
- return (__db_panic(dbenv, EINVAL));
- }
-
- head = &hp->head[DB_TXNLIST_MASK(hp, hash)];
-
- for (p = LIST_FIRST(head); p != NULL; p = LIST_NEXT(p, links)) {
- if (p->type != type)
- continue;
- switch (type) {
- case TXNLIST_TXNID:
- if (p->u.t.txnid != txnid ||
- generation != p->u.t.generation)
- continue;
- *statusp = p->u.t.status;
- break;
-
- case TXNLIST_PGNO:
- if (memcmp(uid, p->u.p.uid, DB_FILE_ID_LEN) != 0)
- continue;
- break;
- case TXNLIST_DELETE:
- case TXNLIST_LSN:
- default:
- return (__db_panic(dbenv, EINVAL));
- }
- if (delete == 1) {
- LIST_REMOVE(p, links);
- __os_free(dbenv, p);
- *txnlistp = NULL;
- } else if (p != LIST_FIRST(head)) {
- /* Move it to head of list. */
- LIST_REMOVE(p, links);
- LIST_INSERT_HEAD(head, p, links);
- *txnlistp = p;
- } else
- *txnlistp = p;
- return (ret);
- }
-
- return (DB_NOTFOUND);
-}
-
-/*
- * __db_txnlist_gen --
- * Change the current generation number.
- *
- * PUBLIC: int __db_txnlist_gen __P((DB_ENV *,
- * PUBLIC: DB_TXNHEAD *, int, u_int32_t, u_int32_t));
- */
-int
-__db_txnlist_gen(dbenv, hp, incr, min, max)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
- int incr;
- u_int32_t min, max;
-{
- int ret;
-
- /*
- * During recovery generation numbers keep track of "restart"
- * checkpoints and recycle records. Restart checkpoints occur
- * whenever we take a checkpoint and there are no outstanding
- * transactions. When that happens, we can reset transaction IDs
- * back to TXNID_MINIMUM. Currently we only do the reset
- * at then end of recovery. Recycle records occur when txnids
- * are exhausted during runtime. A free range of ids is identified
- * and logged. This code maintains a stack of ranges. A txnid
- * is given the generation number of the first range it falls into
- * in the stack.
- */
- if (incr < 0) {
- --hp->generation;
- memmove(hp->gen_array, &hp->gen_array[1],
- (hp->generation + 1) * sizeof(hp->gen_array[0]));
- } else {
- ++hp->generation;
- if (hp->generation >= hp->gen_alloc) {
- hp->gen_alloc *= 2;
- if ((ret = __os_realloc(dbenv, hp->gen_alloc *
- sizeof(hp->gen_array[0]), &hp->gen_array)) != 0)
- return (ret);
- }
- memmove(&hp->gen_array[1], &hp->gen_array[0],
- hp->generation * sizeof(hp->gen_array[0]));
- hp->gen_array[0].generation = hp->generation;
- hp->gen_array[0].txn_min = min;
- hp->gen_array[0].txn_max = max;
- }
- return (0);
-}
-
-/*
- * __db_txnlist_lsnadd --
- * Save the prev_lsn from a txn_child record.
- *
- * PUBLIC: int __db_txnlist_lsnadd __P((DB_ENV *, DB_TXNHEAD *, DB_LSN *));
- */
-int
-__db_txnlist_lsnadd(dbenv, hp, lsnp)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
- DB_LSN *lsnp;
-{
- DB_TXNLIST *elp;
- int ret;
-
- if (IS_ZERO_LSN(*lsnp))
- return (0);
-
- for (elp = LIST_FIRST(&hp->head[0]);
- elp != NULL; elp = LIST_NEXT(elp, links))
- if (elp->type == TXNLIST_LSN)
- break;
-
- if (elp == NULL) {
- if ((ret = __db_txnlist_lsninit(dbenv, hp, lsnp)) != 0)
- return (ret);
- return (DB_SURPRISE_KID);
- }
-
- if (elp->u.l.stack_indx == elp->u.l.stack_size) {
- elp->u.l.stack_size <<= 1;
- if ((ret = __os_realloc(dbenv, sizeof(DB_LSN) *
- elp->u.l.stack_size, &elp->u.l.lsn_stack)) != 0) {
- __db_txnlist_end(dbenv, hp);
- return (ret);
- }
- }
- elp->u.l.lsn_stack[elp->u.l.stack_indx++] = *lsnp;
-
- return (0);
-}
-
-/*
- * __db_txnlist_lsnget --
- *
- * PUBLIC: int __db_txnlist_lsnget __P((DB_ENV *,
- * PUBLIC: DB_TXNHEAD *, DB_LSN *, u_int32_t));
- * Get the lsn saved from a txn_child record.
- */
-int
-__db_txnlist_lsnget(dbenv, hp, lsnp, flags)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
- DB_LSN *lsnp;
- u_int32_t flags;
-{
- DB_TXNLIST *elp;
-
- COMPQUIET(dbenv, NULL);
- COMPQUIET(flags, 0);
-
- for (elp = LIST_FIRST(&hp->head[0]);
- elp != NULL; elp = LIST_NEXT(elp, links))
- if (elp->type == TXNLIST_LSN)
- break;
-
- if (elp == NULL || elp->u.l.stack_indx == 0) {
- ZERO_LSN(*lsnp);
- return (0);
- }
-
- *lsnp = elp->u.l.lsn_stack[--elp->u.l.stack_indx];
-
- return (0);
-}
-
-/*
- * __db_txnlist_lsninit --
- * Initialize a transaction list with an lsn array entry.
- *
- * PUBLIC: int __db_txnlist_lsninit __P((DB_ENV *, DB_TXNHEAD *, DB_LSN *));
- */
-int
-__db_txnlist_lsninit(dbenv, hp, lsnp)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
- DB_LSN *lsnp;
-{
- DB_TXNLIST *elp;
- int ret;
-
- elp = NULL;
-
- if ((ret = __os_malloc(dbenv, sizeof(DB_TXNLIST), &elp)) != 0)
- goto err;
- LIST_INSERT_HEAD(&hp->head[0], elp, links);
-
- elp->type = TXNLIST_LSN;
- if ((ret = __os_malloc(dbenv,
- sizeof(DB_LSN) * DB_LSN_STACK_SIZE, &elp->u.l.lsn_stack)) != 0)
- goto err;
- elp->u.l.stack_indx = 1;
- elp->u.l.stack_size = DB_LSN_STACK_SIZE;
- elp->u.l.lsn_stack[0] = *lsnp;
-
- return (0);
-
-err: __db_txnlist_end(dbenv, hp);
- return (ret);
-}
-
-#ifndef HAVE_FTRUNCATE
-/*
- * __db_add_limbo -- add pages to the limbo list.
- * Get the file information and call pgnoadd for each page.
- *
- * PUBLIC: #ifndef HAVE_FTRUNCATE
- * PUBLIC: int __db_add_limbo __P((DB_ENV *,
- * PUBLIC: DB_TXNHEAD *, int32_t, db_pgno_t, int32_t));
- * PUBLIC: #endif
- */
-int
-__db_add_limbo(dbenv, hp, fileid, pgno, count)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
- int32_t fileid;
- db_pgno_t pgno;
- int32_t count;
-{
- DB_LOG *dblp;
- FNAME *fnp;
- int ret;
-
- dblp = dbenv->lg_handle;
- if ((ret = __dbreg_id_to_fname(dblp, fileid, 0, &fnp)) != 0)
- return (ret);
-
- do {
- if ((ret =
- __db_txnlist_pgnoadd(dbenv, hp, fileid, fnp->ufid,
- R_ADDR(&dblp->reginfo, fnp->name_off), pgno)) != 0)
- return (ret);
- pgno++;
- } while (--count != 0);
-
- return (0);
-}
-
-/*
- * __db_do_the_limbo -- move pages from limbo to free.
- *
- * Limbo processing is what ensures that we correctly handle and
- * recover from page allocations. During recovery, for each database,
- * we process each in-question allocation, link them into the free list
- * and then write out the new meta-data page that contains the pointer
- * to the new beginning of the free list. On an abort, we use our
- * standard __db_free mechanism in a compensating transaction which logs
- * the specific modifications to the free list.
- *
- * If we run out of log space during an abort, then we can't write the
- * compensating transaction, so we abandon the idea of a compensating
- * transaction, and go back to processing how we do during recovery.
- * The reason that this is not the norm is that it's expensive: it requires
- * that we flush any database with an in-question allocation. Thus if
- * a compensating transaction fails, we never try to restart it.
- *
- * Since files may be open and closed within transactions (in particular,
- * the master database for subdatabases), we must be prepared to open
- * files during this process. If there is a compensating transaction, we
- * can open the files in that transaction. If this was an abort and there
- * is no compensating transaction, then we've got to perform these opens
- * in the context of the aborting transaction so that we do not deadlock.
- * During recovery, there's no locking, so this isn't an issue.
- *
- * What you want to keep in mind when reading this is that there are two
- * algorithms going on here: ctxn == NULL, then we're either in recovery
- * or our compensating transaction has failed and we're doing the
- * "create list and write meta-data page" algorithm. Otherwise, we're in
- * an abort and doing the "use compensating transaction" algorithm.
- *
- * PUBLIC: #ifndef HAVE_FTRUNCATE
- * PUBLIC: int __db_do_the_limbo __P((DB_ENV *,
- * PUBLIC: DB_TXN *, DB_TXN *, DB_TXNHEAD *, db_limbo_state));
- * PUBLIC: #endif
- */
-int
-__db_do_the_limbo(dbenv, ptxn, txn, hp, state)
- DB_ENV *dbenv;
- DB_TXN *ptxn, *txn;
- DB_TXNHEAD *hp;
- db_limbo_state state;
-{
- DB_TXNLIST *elp;
- u_int32_t h;
- int ret;
-
- ret = 0;
- /*
- * The slots correspond to hash buckets. We've hashed the
- * fileids into hash buckets and need to pick up all affected
- * files. (There will only be a single slot for an abort.)
- */
- for (h = 0; h < hp->nslots; h++) {
- if ((elp = LIST_FIRST(&hp->head[h])) == NULL)
- continue;
- if (ptxn != NULL) {
- if ((ret =
- __db_limbo_move(dbenv, ptxn, txn, elp)) != 0)
- goto err;
- } else if ((ret =
- __db_limbo_bucket(dbenv, txn, elp, state)) != 0)
- goto err;
- }
-
-err: if (ret != 0) {
- __db_err(dbenv, "Fatal error in abort of an allocation");
- ret = __db_panic(dbenv, ret);
- }
-
- return (ret);
-}
-
-/* Limbo support routines. */
-
-/*
- * __db_lock_move --
- * Move a lock from child to parent.
- */
-static int
-__db_lock_move(dbenv, fileid, pgno, mode, ptxn, txn)
- DB_ENV *dbenv;
- u_int8_t *fileid;
- db_pgno_t pgno;
- db_lockmode_t mode;
- DB_TXN *ptxn, *txn;
-{
- DBT lock_dbt;
- DB_LOCK lock;
- DB_LOCK_ILOCK lock_obj;
- DB_LOCKREQ req;
- int ret;
-
- lock_obj.pgno = pgno;
- memcpy(lock_obj.fileid, fileid, DB_FILE_ID_LEN);
- lock_obj.type = DB_PAGE_LOCK;
-
- memset(&lock_dbt, 0, sizeof(lock_dbt));
- lock_dbt.data = &lock_obj;
- lock_dbt.size = sizeof(lock_obj);
-
- if ((ret = __lock_get(dbenv,
- txn->txnid, 0, &lock_dbt, mode, &lock)) == 0) {
- memset(&req, 0, sizeof(req));
- req.lock = lock;
- req.op = DB_LOCK_TRADE;
- ret = __lock_vec(dbenv, ptxn->txnid, 0, &req, 1, NULL);
- }
- return (ret);
-}
-
-/*
- * __db_limbo_move
- * Move just the metapage lock to the parent.
- */
-static int
-__db_limbo_move(dbenv, ptxn, txn, elp)
- DB_ENV *dbenv;
- DB_TXN *ptxn, *txn;
- DB_TXNLIST *elp;
-{
- int ret;
-
- for (; elp != NULL; elp = LIST_NEXT(elp, links)) {
- if (elp->type != TXNLIST_PGNO || elp->u.p.locked == 1)
- continue;
- if ((ret = __db_lock_move(dbenv, elp->u.p.uid,
- PGNO_BASE_MD, DB_LOCK_WRITE, ptxn, txn)) != 0)
- return (ret);
- elp->u.p.locked = 1;
- }
-
- return (0);
-}
-/*
- * __db_limbo_bucket
- * Perform limbo processing for a single hash bucket in the txnlist.
- * txn is the transaction aborting in the case of an abort and ctxn is the
- * compensating transaction.
- */
-
-#define T_RESTORED(txn) ((txn) != NULL && F_ISSET(txn, TXN_RESTORED))
-static int
-__db_limbo_bucket(dbenv, txn, elp, state)
- DB_ENV *dbenv;
- DB_TXN *txn;
- DB_TXNLIST *elp;
- db_limbo_state state;
-{
- DB *dbp;
- DB_MPOOLFILE *mpf;
- DBMETA *meta;
- DB_TXN *ctxn, *t;
- FNAME *fname;
- db_pgno_t last_pgno, pgno;
- int dbp_created, in_retry, ret, t_ret;
-
- ctxn = NULL;
- in_retry = 0;
- meta = NULL;
- mpf = NULL;
- ret = 0;
- for (; elp != NULL; elp = LIST_NEXT(elp, links)) {
- if (elp->type != TXNLIST_PGNO)
- continue;
-retry: dbp_created = 0;
-
- /*
- * Pick the transaction in which to potentially
- * log compensations.
- */
- if (state == LIMBO_PREPARE)
- ctxn = txn;
- else if (!in_retry && state != LIMBO_RECOVER &&
- state != LIMBO_TIMESTAMP && !T_RESTORED(txn) &&
- (ret = __txn_compensate_begin(dbenv, &ctxn)) != 0)
- return (ret);
-
- /*
- * Either use the compensating transaction or
- * the one passed in, which will be null if recovering.
- */
- t = ctxn == NULL ? txn : ctxn;
-
- /* First try to get a dbp by fileid. */
- ret = __dbreg_id_to_db(dbenv, t, &dbp, elp->u.p.fileid, 0);
-
- /*
- * If the file was closed and reopened its id could change.
- * Look it up the hard way.
- */
- if (ret == DB_DELETED || ret == ENOENT ||
- ((ret == 0 &&
- memcmp(elp->u.p.uid, dbp->fileid, DB_FILE_ID_LEN) != 0))) {
- if ((ret = __dbreg_fid_to_fname(
- dbenv->lg_handle, elp->u.p.uid, 0, &fname)) == 0)
- ret = __dbreg_id_to_db(
- dbenv, t, &dbp, fname->id, 0);
- }
- /*
- * File is being destroyed. No need to worry about
- * dealing with recovery of allocations.
- */
- if (ret == DB_DELETED ||
- (ret == 0 && F_ISSET(dbp, DB_AM_DISCARD)))
- goto next;
-
- if (ret != 0) {
- if ((ret = db_create(&dbp, dbenv, 0)) != 0)
- goto err;
-
- /*
- * This tells the system not to lock, which is always
- * OK, whether this is an abort or recovery.
- */
- F_SET(dbp, DB_AM_COMPENSATE);
- dbp_created = 1;
-
- /* It is ok if the file is nolonger there. */
- ret = __db_open(dbp, t, elp->u.p.fname, NULL,
- DB_UNKNOWN, DB_ODDFILESIZE, __db_omode(OWNER_RW),
- PGNO_BASE_MD);
- if (ret == ENOENT)
- goto next;
- }
-
- /*
- * Verify that we are opening the same file that we were
- * referring to when we wrote this log record.
- */
- if (memcmp(elp->u.p.uid, dbp->fileid, DB_FILE_ID_LEN) != 0)
- goto next;
-
- mpf = dbp->mpf;
- last_pgno = PGNO_INVALID;
-
- if (meta == NULL &&
- (ctxn == NULL || state == LIMBO_COMPENSATE)) {
- pgno = PGNO_BASE_MD;
- if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0)
- goto err;
- last_pgno = meta->free;
- }
-
- if (state == LIMBO_PREPARE) {
- if ((ret = __db_limbo_prepare(dbp, ctxn, elp)) != 0)
- goto err;
- } else
- ret = __db_limbo_fix(dbp,
- ctxn, elp, &last_pgno, meta, state);
- /*
- * If we were doing compensating transactions, then we are
- * going to hope this error was due to running out of space.
- * We'll change modes (into the sync the file mode) and keep
- * trying. If we weren't doing compensating transactions,
- * then this is a real error and we're sunk.
- */
- if (ret != 0) {
- if (ret == DB_RUNRECOVERY || ctxn == NULL)
- goto err;
- in_retry = 1;
- if ((ret = __txn_abort(ctxn)) != 0)
- goto err;
- ctxn = NULL;
- goto retry;
- }
-
- if (state == LIMBO_PREPARE)
- ctxn = NULL;
-
- else if (ctxn != NULL) {
- /*
- * We only force compensation at the end of recovery.
- * We want the txn_commit to be logged so turn
- * off the recovery flag briefly.
- */
- if (state == LIMBO_COMPENSATE)
- F_CLR(
- (DB_LOG *)dbenv->lg_handle, DBLOG_RECOVER);
- ret = __txn_commit(ctxn, DB_TXN_NOSYNC);
- ctxn = NULL;
- if (state == LIMBO_COMPENSATE)
- F_SET(
- (DB_LOG *)dbenv->lg_handle, DBLOG_RECOVER);
- if (ret != 0)
- goto retry;
- }
-
- /*
- * This is where we handle the case where we're explicitly
- * putting together a free list. We need to decide whether
- * we have to write the meta-data page, and if we do, then
- * we need to sync it as well.
- */
- else if (last_pgno == meta->free) {
- /* No change to page; just put the page back. */
- if ((ret = __memp_fput(mpf, meta, 0)) != 0)
- goto err;
- meta = NULL;
- } else {
- /*
- * These changes are unlogged so we cannot have the
- * metapage pointing at pages that are not on disk.
- * Therefore, we flush the new free list, then update
- * the metapage. We have to put the meta-data page
- * first so that it isn't pinned when we try to sync.
- */
- if (!IS_RECOVERING(dbenv) && !T_RESTORED(txn))
- __db_err(dbenv, "Flushing free list to disk");
- if ((ret = __memp_fput(mpf, meta, 0)) != 0)
- goto err;
- meta = NULL;
- /*
- * If the sync fails then we cannot flush the
- * newly allocated pages. That is, the file
- * cannot be extended. Don't let the metapage
- * point at them.
- * We may lose these pages from the file if it
- * can be extended later. If there is never
- * space for the pages, then things will be ok.
- */
- if ((ret = __db_sync(dbp)) == 0) {
- pgno = PGNO_BASE_MD;
- if ((ret =
- __memp_fget(mpf, &pgno, 0, &meta)) != 0)
- goto err;
- meta->free = last_pgno;
- if ((ret = __memp_fput(mpf,
- meta, DB_MPOOL_DIRTY)) != 0)
- goto err;
- meta = NULL;
- } else {
- __db_err(dbenv,
- "%s: %s", dbp->fname, db_strerror(ret));
- __db_err(dbenv, "%s: %s %s", dbp->fname,
- "allocation flush failed, some free pages",
- "may not appear in the free list");
- ret = 0;
- }
- }
-
-next:
- /*
- * If we get here, either we have processed the list
- * or the db file has been deleted or could not be opened.
- */
- if (ctxn != NULL &&
- (t_ret = __txn_abort(ctxn)) != 0 && ret == 0)
- ret = t_ret;
-
- if (dbp_created &&
- (t_ret = __db_close(dbp, txn, DB_NOSYNC)) != 0 && ret == 0)
- ret = t_ret;
- dbp = NULL;
- if (state != LIMBO_PREPARE && state != LIMBO_TIMESTAMP) {
- __os_free(dbenv, elp->u.p.fname);
- __os_free(dbenv, elp->u.p.pgno_array);
- }
- if (ret == ENOENT)
- ret = 0;
- else if (ret != 0)
- goto err;
- }
-
-err: if (meta != NULL)
- (void)__memp_fput(mpf, meta, 0);
- return (ret);
-}
-
-/*
- * __db_limbo_fix --
- * Process a single limbo entry which describes all the page allocations
- * for a single file.
- */
-static int
-__db_limbo_fix(dbp, ctxn, elp, lastp, meta, state)
- DB *dbp;
- DB_TXN *ctxn;
- DB_TXNLIST *elp;
- db_pgno_t *lastp;
- DBMETA *meta;
- db_limbo_state state;
-{
- DBC *dbc;
- DBT ldbt;
- DB_MPOOLFILE *mpf;
- PAGE *freep, *pagep;
- db_pgno_t next, pgno;
- u_int32_t i;
- int ret, t_ret;
-
- /*
- * Loop through the entries for this txnlist element and
- * either link them into the free list or write a compensating
- * record for each.
- */
- dbc = NULL;
- mpf = dbp->mpf;
- pagep = NULL;
- ret = 0;
-
- for (i = 0; i < elp->u.p.nentries; i++) {
- pgno = elp->u.p.pgno_array[i];
-
- if (pgno == PGNO_INVALID)
- continue;
-
- if ((ret =
- __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep)) != 0) {
- if (ret != ENOSPC)
- goto err;
- continue;
- }
-
- if (state == LIMBO_COMPENSATE || IS_ZERO_LSN(LSN(pagep))) {
- if (ctxn == NULL) {
- /*
- * If this is a fatal recovery which
- * spans a previous crash this page may
- * be on the free list already.
- */
- for (next = *lastp; next != 0; ) {
- if (next == pgno)
- break;
- if ((ret = __memp_fget(mpf,
- &next, 0, &freep)) != 0)
- goto err;
- next = NEXT_PGNO(freep);
- if ((ret =
- __memp_fput(mpf, freep, 0)) != 0)
- goto err;
- }
-
- if (next != pgno) {
- P_INIT(pagep, dbp->pgsize, pgno,
- PGNO_INVALID, *lastp, 0, P_INVALID);
- /* Make the lsn non-zero but generic. */
- INIT_LSN(LSN(pagep));
- *lastp = pgno;
- }
- } else if (state == LIMBO_COMPENSATE) {
- /*
- * Generate a log record for what we did on the
- * LIMBO_TIMESTAMP pass. All pages here are
- * free so P_OVERHEAD is sufficient.
- */
- ZERO_LSN(pagep->lsn);
- memset(&ldbt, 0, sizeof(ldbt));
- ldbt.data = pagep;
- ldbt.size = P_OVERHEAD(dbp);
- if ((ret = __db_pg_new_log(dbp, ctxn,
- &LSN(meta), 0, pagep->pgno,
- &LSN(meta), PGNO_BASE_MD,
- &ldbt, pagep->next_pgno)) != 0)
- goto err;
- } else {
- if (dbc == NULL && (ret =
- __db_cursor(dbp, ctxn, &dbc, 0)) != 0)
- goto err;
- /*
- * If the dbp is compensating (because we
- * opened it), the dbc will automatically be
- * marked compensating, but in case we didn't
- * do the open, we have to mark it explicitly.
- */
- F_SET(dbc, DBC_COMPENSATE);
-
- /*
- * If aborting a txn for a different process
- * via XA or failchk, DB_AM_RECOVER will be
- * set but we need to log the compensating
- * transactions.
- */
- F_CLR(dbc, DBC_RECOVER);
-
- ret = __db_free(dbc, pagep);
- pagep = NULL;
-
- /*
- * On any error, we hope that the error was
- * caused due to running out of space, and we
- * switch modes, doing the processing where we
- * sync out files instead of doing compensating
- * transactions. If this was a real error and
- * not out of space, we assume that some other
- * call will fail real soon.
- */
- if (ret != 0) {
- /* Assume that this is out of space. */
- (void)__db_c_close(dbc);
- dbc = NULL;
- goto err;
- }
- }
- }
- else
- elp->u.p.pgno_array[i] = PGNO_INVALID;
-
- if (pagep != NULL) {
- ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY);
- pagep = NULL;
- }
- if (ret != 0)
- goto err;
- }
-
-err: if (pagep != NULL &&
- (t_ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0 && ret == 0)
- ret = t_ret;
- if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
-
-static int
-__db_limbo_prepare(dbp, txn, elp)
- DB *dbp;
- DB_TXN *txn;
- DB_TXNLIST *elp;
-{
- DB_LSN lsn;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- db_pgno_t pgno;
- u_int32_t i;
- int ret, t_ret;
-
- /*
- * Loop through the entries for this txnlist element and
- * output a prepare record for them.
- */
- pagep = NULL;
- ret = 0;
- mpf = dbp->mpf;
-
- for (i = 0; i < elp->u.p.nentries; i++) {
- pgno = elp->u.p.pgno_array[i];
-
- if ((ret =
- __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep)) != 0) {
- if (ret != ENOSPC)
- return (ret);
- continue;
- }
-
- if (IS_ZERO_LSN(LSN(pagep)))
- ret = __db_pg_prepare_log(dbp, txn, &lsn, 0, pgno);
-
- if ((t_ret = __memp_fput(mpf, pagep, 0)) != 0 && ret == 0)
- ret = t_ret;
-
- if (ret != 0)
- return (ret);
- }
-
- return (0);
-}
-
-#define DB_TXNLIST_MAX_PGNO 8 /* A nice even number. */
-
-/*
- * __db_txnlist_pgnoadd --
- * Find the txnlist entry for a file and add this pgno, or add the list
- * entry for the file and then add the pgno.
- */
-static int
-__db_txnlist_pgnoadd(dbenv, hp, fileid, uid, fname, pgno)
- DB_ENV *dbenv;
- DB_TXNHEAD *hp;
- int32_t fileid;
- u_int8_t uid[DB_FILE_ID_LEN];
- char *fname;
- db_pgno_t pgno;
-{
- DB_TXNLIST *elp;
- size_t len;
- u_int32_t hash, status;
- int ret;
-
- elp = NULL;
-
- if ((ret = __db_txnlist_find_internal(dbenv, hp,
- TXNLIST_PGNO, 0, uid, &elp, 0, &status)) != 0 && ret != DB_NOTFOUND)
- goto err;
-
- if (ret == DB_NOTFOUND || status != TXN_OK) {
- if ((ret =
- __os_malloc(dbenv, sizeof(DB_TXNLIST), &elp)) != 0)
- goto err;
- memcpy(&hash, uid, sizeof(hash));
- LIST_INSERT_HEAD(
- &hp->head[DB_TXNLIST_MASK(hp, hash)], elp, links);
- memcpy(elp->u.p.uid, uid, DB_FILE_ID_LEN);
-
- len = strlen(fname) + 1;
- if ((ret = __os_malloc(dbenv, len, &elp->u.p.fname)) != 0)
- goto err;
- memcpy(elp->u.p.fname, fname, len);
-
- elp->u.p.maxentry = 0;
- elp->u.p.locked = 0;
- elp->type = TXNLIST_PGNO;
- if ((ret = __os_malloc(dbenv,
- 8 * sizeof(db_pgno_t), &elp->u.p.pgno_array)) != 0)
- goto err;
- elp->u.p.maxentry = DB_TXNLIST_MAX_PGNO;
- elp->u.p.nentries = 0;
- } else if (elp->u.p.nentries == elp->u.p.maxentry) {
- elp->u.p.maxentry <<= 1;
- if ((ret = __os_realloc(dbenv, elp->u.p.maxentry *
- sizeof(db_pgno_t), &elp->u.p.pgno_array)) != 0)
- goto err;
- }
-
- elp->u.p.pgno_array[elp->u.p.nentries++] = pgno;
- /* Update to the latest fileid. Limbo will find it faster. */
- elp->u.p.fileid = fileid;
-
- return (0);
-
-err: return (ret);
-}
-#endif
-
-#ifdef DEBUG
-/*
- * __db_txnlist_print --
- * Print out the transaction list.
- *
- * PUBLIC: void __db_txnlist_print __P((DB_TXNHEAD *));
- */
-void
-__db_txnlist_print(hp)
- DB_TXNHEAD *hp;
-{
- DB_TXNLIST *p;
- u_int32_t i;
- char *txntype;
-
- printf("Maxid: %lu Generation: %lu\n",
- (u_long)hp->maxid, (u_long)hp->generation);
- for (i = 0; i < hp->nslots; i++)
- for (p = LIST_FIRST(&hp->head[i]);
- p != NULL; p = LIST_NEXT(p, links)) {
- if (p->type != TXNLIST_TXNID) {
- printf("Unrecognized type: %d\n", p->type);
- continue;
- }
- switch (p->u.t.status) {
- case TXN_OK:
- txntype = "OK";
- break;
- case TXN_COMMIT:
- txntype = "commit";
- break;
- case TXN_PREPARE:
- txntype = "prepare";
- break;
- case TXN_ABORT:
- txntype = "abort";
- break;
- case TXN_IGNORE:
- txntype = "ignore";
- break;
- case TXN_EXPECTED:
- txntype = "expected";
- break;
- case TXN_UNEXPECTED:
- txntype = "unexpected";
- break;
- default:
- txntype = "UNKNOWN";
- break;
- }
- printf("TXNID: %lx(%lu): %s\n",
- (u_long)p->u.t.txnid,
- (u_long)p->u.t.generation, txntype);
- }
-}
-#endif
diff --git a/storage/bdb/db/db_dup.c b/storage/bdb/db/db_dup.c
deleted file mode 100644
index 2f0732c6b5c..00000000000
--- a/storage/bdb/db/db_dup.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_dup.c,v 12.2 2005/06/16 20:21:10 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/mp.h"
-#include "dbinc/db_am.h"
-
-/*
- * __db_ditem --
- * Remove an item from a page.
- *
- * PUBLIC: int __db_ditem __P((DBC *, PAGE *, u_int32_t, u_int32_t));
- */
-int
-__db_ditem(dbc, pagep, indx, nbytes)
- DBC *dbc;
- PAGE *pagep;
- u_int32_t indx, nbytes;
-{
- DB *dbp;
- DBT ldbt;
- db_indx_t cnt, *inp, offset;
- int ret;
- u_int8_t *from;
-
- dbp = dbc->dbp;
- if (DBC_LOGGING(dbc)) {
- ldbt.data = P_ENTRY(dbp, pagep, indx);
- ldbt.size = nbytes;
- if ((ret = __db_addrem_log(dbp, dbc->txn,
- &LSN(pagep), 0, DB_REM_DUP, PGNO(pagep),
- (u_int32_t)indx, nbytes, &ldbt, NULL, &LSN(pagep))) != 0)
- return (ret);
- } else
- LSN_NOT_LOGGED(LSN(pagep));
-
- /*
- * If there's only a single item on the page, we don't have to
- * work hard.
- */
- if (NUM_ENT(pagep) == 1) {
- NUM_ENT(pagep) = 0;
- HOFFSET(pagep) = dbp->pgsize;
- return (0);
- }
-
- inp = P_INP(dbp, pagep);
- /*
- * Pack the remaining key/data items at the end of the page. Use
- * memmove(3), the regions may overlap.
- */
- from = (u_int8_t *)pagep + HOFFSET(pagep);
- DB_ASSERT(inp[indx] >= HOFFSET(pagep));
- memmove(from + nbytes, from, inp[indx] - HOFFSET(pagep));
- HOFFSET(pagep) += nbytes;
-
- /* Adjust the indices' offsets. */
- offset = inp[indx];
- for (cnt = 0; cnt < NUM_ENT(pagep); ++cnt)
- if (inp[cnt] < offset)
- inp[cnt] += nbytes;
-
- /* Shift the indices down. */
- --NUM_ENT(pagep);
- if (indx != NUM_ENT(pagep))
- memmove(&inp[indx], &inp[indx + 1],
- sizeof(db_indx_t) * (NUM_ENT(pagep) - indx));
-
- return (0);
-}
-
-/*
- * __db_pitem --
- * Put an item on a page.
- *
- * PUBLIC: int __db_pitem
- * PUBLIC: __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *));
- */
-int
-__db_pitem(dbc, pagep, indx, nbytes, hdr, data)
- DBC *dbc;
- PAGE *pagep;
- u_int32_t indx;
- u_int32_t nbytes;
- DBT *hdr, *data;
-{
- DB *dbp;
- BKEYDATA bk;
- DBT thdr;
- db_indx_t *inp;
- int ret;
- u_int8_t *p;
-
- dbp = dbc->dbp;
- if (nbytes > P_FREESPACE(dbp, pagep)) {
- DB_ASSERT(nbytes <= P_FREESPACE(dbp, pagep));
- return (EINVAL);
- }
- /*
- * Put a single item onto a page. The logic figuring out where to
- * insert and whether it fits is handled in the caller. All we do
- * here is manage the page shuffling. We cheat a little bit in that
- * we don't want to copy the dbt on a normal put twice. If hdr is
- * NULL, we create a BKEYDATA structure on the page, otherwise, just
- * copy the caller's information onto the page.
- *
- * This routine is also used to put entries onto the page where the
- * entry is pre-built, e.g., during recovery. In this case, the hdr
- * will point to the entry, and the data argument will be NULL.
- *
- * !!!
- * There's a tremendous potential for off-by-one errors here, since
- * the passed in header sizes must be adjusted for the structure's
- * placeholder for the trailing variable-length data field.
- */
- if (DBC_LOGGING(dbc)) {
- if ((ret = __db_addrem_log(dbp, dbc->txn,
- &LSN(pagep), 0, DB_ADD_DUP, PGNO(pagep),
- (u_int32_t)indx, nbytes, hdr, data, &LSN(pagep))) != 0)
- return (ret);
- } else
- LSN_NOT_LOGGED(LSN(pagep));
-
- if (hdr == NULL) {
- B_TSET(bk.type, B_KEYDATA, 0);
- bk.len = data == NULL ? 0 : data->size;
-
- thdr.data = &bk;
- thdr.size = SSZA(BKEYDATA, data);
- hdr = &thdr;
- }
- inp = P_INP(dbp, pagep);
-
- /* Adjust the index table, then put the item on the page. */
- if (indx != NUM_ENT(pagep))
- memmove(&inp[indx + 1], &inp[indx],
- sizeof(db_indx_t) * (NUM_ENT(pagep) - indx));
- HOFFSET(pagep) -= nbytes;
- inp[indx] = HOFFSET(pagep);
- ++NUM_ENT(pagep);
-
- p = P_ENTRY(dbp, pagep, indx);
- memcpy(p, hdr->data, hdr->size);
- if (data != NULL)
- memcpy(p + hdr->size, data->data, data->size);
-
- return (0);
-}
diff --git a/storage/bdb/db/db_iface.c b/storage/bdb/db/db_iface.c
deleted file mode 100644
index 37811a17a26..00000000000
--- a/storage/bdb/db/db_iface.c
+++ /dev/null
@@ -1,2438 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_iface.c,v 12.29 2005/11/08 14:49:44 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/btree.h"
-#ifndef HAVE_HASH
-#include "dbinc/hash.h" /* For __db_no_hash_am(). */
-#endif
-#ifndef HAVE_QUEUE
-#include "dbinc/qam.h" /* For __db_no_queue_am(). */
-#endif
-#include "dbinc/lock.h"
-#include "dbinc/log.h"
-#include "dbinc/mp.h"
-#include "dbinc/txn.h"
-
-static int __db_associate_arg __P((DB *, DB *,
- int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t));
-static int __db_c_del_arg __P((DBC *, u_int32_t));
-static int __db_c_get_arg __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __db_c_pget_arg __P((DBC *, DBT *, u_int32_t));
-static int __db_c_put_arg __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __db_curinval __P((const DB_ENV *));
-static int __db_cursor_arg __P((DB *, u_int32_t));
-static int __db_del_arg __P((DB *, u_int32_t));
-static int __db_get_arg __P((const DB *, const DBT *, DBT *, u_int32_t));
-static int __db_join_arg __P((DB *, DBC **, u_int32_t));
-static int __db_open_arg __P((DB *,
- DB_TXN *, const char *, const char *, DBTYPE, u_int32_t));
-static int __db_pget_arg __P((DB *, DBT *, u_int32_t));
-static int __db_put_arg __P((DB *, DBT *, DBT *, u_int32_t));
-static int __dbt_ferr __P((const DB *, const char *, const DBT *, int));
-
-/*
- * These functions implement the Berkeley DB API. They are organized in a
- * layered fashion. The interface functions (XXX_pp) perform all generic
- * error checks (for example, PANIC'd region, replication state change
- * in progress, inconsistent transaction usage), call function-specific
- * check routines (_arg) to check for proper flag usage, etc., do pre-amble
- * processing (incrementing handle counts, handling local transactions),
- * call the function and then do post-amble processing (local transactions,
- * decrement handle counts).
- *
- * The basic structure is:
- * Check for simple/generic errors (PANIC'd region)
- * Check if replication is changing state (increment handle count).
- * Call function-specific argument checking routine
- * Create internal transaction if necessary
- * Call underlying worker function
- * Commit/abort internal transaction if necessary
- * Decrement handle count
- */
-
-/*
- * __db_associate_pp --
- * DB->associate pre/post processing.
- *
- * PUBLIC: int __db_associate_pp __P((DB *, DB_TXN *, DB *,
- * PUBLIC: int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t));
- */
-int
-__db_associate_pp(dbp, txn, sdbp, callback, flags)
- DB *dbp, *sdbp;
- DB_TXN *txn;
- int (*callback) __P((DB *, const DBT *, const DBT *, DBT *));
- u_int32_t flags;
-{
- DBC *sdbc;
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret, txn_local;
-
- dbenv = dbp->dbenv;
- txn_local = 0;
-
- PANIC_CHECK(dbenv);
- STRIP_AUTO_COMMIT(flags);
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check &&
- (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- /*
- * Secondary cursors may have the primary's lock file ID, so we need
- * to make sure that no older cursors are lying around when we make
- * the transition.
- */
- if (TAILQ_FIRST(&sdbp->active_queue) != NULL ||
- TAILQ_FIRST(&sdbp->join_queue) != NULL) {
- __db_err(dbenv,
- "Databases may not become secondary indices while cursors are open");
- ret = EINVAL;
- goto err;
- }
-
- if ((ret = __db_associate_arg(dbp, sdbp, callback, flags)) != 0)
- goto err;
-
- /*
- * Create a local transaction as necessary, check for consistent
- * transaction usage, and, if we have no transaction but do have
- * locking on, acquire a locker id for the handle lock acquisition.
- */
- if (IS_DB_AUTO_COMMIT(dbp, txn)) {
- if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0)
- goto err;
- txn_local = 1;
- }
-
- /* Check for consistent transaction usage. */
- if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0)
- goto err;
-
- while ((sdbc = TAILQ_FIRST(&sdbp->free_queue)) != NULL)
- if ((ret = __db_c_destroy(sdbc)) != 0)
- goto err;
-
- ret = __db_associate(dbp, txn, sdbp, callback, flags);
-
-err: if (txn_local &&
- (t_ret = __db_txn_auto_resolve(dbenv, txn, 0, ret)) && ret == 0)
- ret = t_ret;
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_associate_arg --
- * Check DB->associate arguments.
- */
-static int
-__db_associate_arg(dbp, sdbp, callback, flags)
- DB *dbp, *sdbp;
- int (*callback) __P((DB *, const DBT *, const DBT *, DBT *));
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- int ret;
-
- dbenv = dbp->dbenv;
-
- if (F_ISSET(sdbp, DB_AM_SECONDARY)) {
- __db_err(dbenv,
- "Secondary index handles may not be re-associated");
- return (EINVAL);
- }
- if (F_ISSET(dbp, DB_AM_SECONDARY)) {
- __db_err(dbenv,
- "Secondary indices may not be used as primary databases");
- return (EINVAL);
- }
- if (F_ISSET(dbp, DB_AM_DUP)) {
- __db_err(dbenv,
- "Primary databases may not be configured with duplicates");
- return (EINVAL);
- }
- if (F_ISSET(dbp, DB_AM_RENUMBER)) {
- __db_err(dbenv,
- "Renumbering recno databases may not be used as primary databases");
- return (EINVAL);
- }
- if (dbp->dbenv != sdbp->dbenv &&
- (!F_ISSET(dbp->dbenv, DB_ENV_DBLOCAL) ||
- !F_ISSET(sdbp->dbenv, DB_ENV_DBLOCAL))) {
- __db_err(dbenv,
- "The primary and secondary must be opened in the same environment");
- return (EINVAL);
- }
- if ((DB_IS_THREADED(dbp) && !DB_IS_THREADED(sdbp)) ||
- (!DB_IS_THREADED(dbp) && DB_IS_THREADED(sdbp))) {
- __db_err(dbenv,
- "The DB_THREAD setting must be the same for primary and secondary");
- return (EINVAL);
- }
- if (callback == NULL &&
- (!F_ISSET(dbp, DB_AM_RDONLY) || !F_ISSET(sdbp, DB_AM_RDONLY))) {
- __db_err(dbenv,
- "Callback function may be NULL only when database handles are read-only");
- return (EINVAL);
- }
-
- if ((ret = __db_fchk(dbenv, "DB->associate", flags, DB_CREATE |
- DB_IMMUTABLE_KEY)) != 0)
- return (ret);
-
- return (0);
-}
-
-/*
- * __db_close_pp --
- * DB->close pre/post processing.
- *
- * PUBLIC: int __db_close_pp __P((DB *, u_int32_t));
- */
-int
-__db_close_pp(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- dbenv = dbp->dbenv;
- ret = 0;
-
- PANIC_CHECK(dbenv);
-
- /*
- * Close a DB handle -- as a handle destructor, we can't fail.
- *
- * !!!
- * The actual argument checking is simple, do it inline, outside of
- * the replication block.
- */
- if (flags != 0 && flags != DB_NOSYNC)
- ret = __db_ferr(dbenv, "DB->close", 0);
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (t_ret = __db_rep_enter(dbp, 0, 0, 0)) != 0) {
- handle_check = 0;
- if (ret == 0)
- ret = t_ret;
- }
-
- if ((t_ret = __db_close(dbp, NULL, flags)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_cursor_pp --
- * DB->cursor pre/post processing.
- *
- * PUBLIC: int __db_cursor_pp __P((DB *, DB_TXN *, DBC **, u_int32_t));
- */
-int
-__db_cursor_pp(dbp, txn, dbcp, flags)
- DB *dbp;
- DB_TXN *txn;
- DBC **dbcp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret;
-
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->cursor");
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- if (txn == NULL) {
- handle_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0;
- if (handle_check && (ret = __op_rep_enter(dbenv)) != 0) {
- handle_check = 0;
- goto err;
- }
- } else
- handle_check = 0;
- if ((ret = __db_cursor_arg(dbp, flags)) != 0)
- goto err;
-
- /*
- * Check for consistent transaction usage. For now, assume this
- * cursor might be used for read operations only (in which case
- * it may not require a txn). We'll check more stringently in
- * c_del and c_put. (Note this means the read-op txn tests have
- * to be a subset of the write-op ones.)
- */
- if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 1)) != 0)
- goto err;
-
- ret = __db_cursor(dbp, txn, dbcp, flags);
-
-err: /* Release replication block on error. */
- if (ret != 0 && handle_check)
- (void)__op_rep_exit(dbenv);
-
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_cursor --
- * DB->cursor.
- *
- * PUBLIC: int __db_cursor __P((DB *, DB_TXN *, DBC **, u_int32_t));
- */
-int
-__db_cursor(dbp, txn, dbcp, flags)
- DB *dbp;
- DB_TXN *txn;
- DBC **dbcp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DBC *dbc;
- db_lockmode_t mode;
- u_int32_t op;
- int ret;
-
- dbenv = dbp->dbenv;
-
- if ((ret = __db_cursor_int(dbp,
- txn, dbp->type, PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0)
- return (ret);
-
- /*
- * If this is CDB, do all the locking in the interface, which is
- * right here.
- */
- if (CDB_LOCKING(dbenv)) {
- op = LF_ISSET(DB_OPFLAGS_MASK);
- mode = (op == DB_WRITELOCK) ? DB_LOCK_WRITE :
- ((op == DB_WRITECURSOR) ? DB_LOCK_IWRITE : DB_LOCK_READ);
- if ((ret = __lock_get(dbenv, dbc->locker, 0,
- &dbc->lock_dbt, mode, &dbc->mylock)) != 0)
- goto err;
- if (op == DB_WRITECURSOR)
- F_SET(dbc, DBC_WRITECURSOR);
- if (op == DB_WRITELOCK)
- F_SET(dbc, DBC_WRITER);
- }
-
- if (LF_ISSET(DB_READ_UNCOMMITTED) ||
- (txn != NULL && F_ISSET(txn, TXN_READ_UNCOMMITTED)))
- F_SET(dbc, DBC_READ_UNCOMMITTED);
-
- if (LF_ISSET(DB_READ_COMMITTED) ||
- (txn != NULL && F_ISSET(txn, TXN_READ_COMMITTED)))
- F_SET(dbc, DBC_READ_COMMITTED);
-
- *dbcp = dbc;
- return (0);
-
-err: (void)__db_c_close(dbc);
- return (ret);
-}
-
-/*
- * __db_cursor_arg --
- * Check DB->cursor arguments.
- */
-static int
-__db_cursor_arg(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
-
- dbenv = dbp->dbenv;
-
- /*
- * DB_READ_COMMITTED and DB_READ_UNCOMMITTED are the only valid
- * bit-flags; they require locking.
- */
- if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED)) {
- if (!LOCKING_ON(dbenv))
- return (__db_fnl(dbenv, "DB->cursor"));
- LF_CLR(DB_READ_COMMITTED| DB_READ_UNCOMMITTED);
- }
-
- /* Check for invalid function flags. */
- switch (flags) {
- case 0:
- break;
- case DB_WRITECURSOR:
- if (DB_IS_READONLY(dbp))
- return (__db_rdonly(dbenv, "DB->cursor"));
- if (!CDB_LOCKING(dbenv))
- return (__db_ferr(dbenv, "DB->cursor", 0));
- break;
- case DB_WRITELOCK:
- if (DB_IS_READONLY(dbp))
- return (__db_rdonly(dbenv, "DB->cursor"));
- break;
- default:
- return (__db_ferr(dbenv, "DB->cursor", 0));
- }
-
- return (0);
-}
-
-/*
- * __db_del_pp --
- * DB->del pre/post processing.
- *
- * PUBLIC: int __db_del_pp __P((DB *, DB_TXN *, DBT *, u_int32_t));
- */
-int
-__db_del_pp(dbp, txn, key, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret, txn_local;
-
- dbenv = dbp->dbenv;
- txn_local = 0;
-
- PANIC_CHECK(dbenv);
- STRIP_AUTO_COMMIT(flags);
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->del");
-
-#if CONFIG_TEST
- if (IS_REP_MASTER(dbenv))
- DB_TEST_WAIT(dbenv, dbenv->test_check);
-#endif
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check &&
- (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- if ((ret = __db_del_arg(dbp, flags)) != 0)
- goto err;
-
- /* Create local transaction as necessary. */
- if (IS_DB_AUTO_COMMIT(dbp, txn)) {
- if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0)
- goto err;
- txn_local = 1;
- }
-
- /* Check for consistent transaction usage. */
- if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0)
- goto err;
-
- ret = __db_del(dbp, txn, key, flags);
-
-err: if (txn_local &&
- (t_ret = __db_txn_auto_resolve(dbenv, txn, 0, ret)) && ret == 0)
- ret = t_ret;
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_del_arg --
- * Check DB->delete arguments.
- */
-static int
-__db_del_arg(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
-
- dbenv = dbp->dbenv;
-
- /* Check for changes to a read-only tree. */
- if (DB_IS_READONLY(dbp))
- return (__db_rdonly(dbenv, "DB->del"));
-
- /* Check for invalid function flags. */
- switch (flags) {
- case 0:
- break;
- default:
- return (__db_ferr(dbenv, "DB->del", 0));
- }
-
- return (0);
-}
-
-/*
- * db_fd_pp --
- * DB->fd pre/post processing.
- *
- * PUBLIC: int __db_fd_pp __P((DB *, int *));
- */
-int
-__db_fd_pp(dbp, fdp)
- DB *dbp;
- int *fdp;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- DB_FH *fhp;
- int handle_check, ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->fd");
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0)
- goto err;
-
- /*
- * !!!
- * There's no argument checking to be done.
- *
- * !!!
- * The actual method call is simple, do it inline.
- *
- * XXX
- * Truly spectacular layering violation.
- */
- if ((ret = __mp_xxx_fh(dbp->mpf, &fhp)) == 0) {
- if (fhp == NULL) {
- *fdp = -1;
- __db_err(dbenv,
- "Database does not have a valid file handle");
- ret = ENOENT;
- } else
- *fdp = fhp->fd;
- }
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_get_pp --
- * DB->get pre/post processing.
- *
- * PUBLIC: int __db_get_pp __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_get_pp(dbp, txn, key, data, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key, *data;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- u_int32_t mode;
- int handle_check, ret, t_ret, txn_local;
-
- dbenv = dbp->dbenv;
- mode = 0;
- txn_local = 0;
-
- PANIC_CHECK(dbenv);
- STRIP_AUTO_COMMIT(flags);
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get");
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check &&
- (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- if ((ret = __db_get_arg(dbp, key, data, flags)) != 0)
- goto err;
-
- if (LF_ISSET(DB_READ_UNCOMMITTED))
- mode = DB_READ_UNCOMMITTED;
- else if ((flags & DB_OPFLAGS_MASK) == DB_CONSUME ||
- (flags & DB_OPFLAGS_MASK) == DB_CONSUME_WAIT) {
- mode = DB_WRITELOCK;
- if (IS_DB_AUTO_COMMIT(dbp, txn)) {
- if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0)
- goto err;
- txn_local = 1;
- }
- }
-
- /* Check for consistent transaction usage. */
- if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID,
- mode == DB_WRITELOCK || LF_ISSET(DB_RMW) ? 0 : 1)) != 0)
- goto err;
-
- ret = __db_get(dbp, txn, key, data, flags);
-
-err: if (txn_local &&
- (t_ret = __db_txn_auto_resolve(dbenv, txn, 0, ret)) && ret == 0)
- ret = t_ret;
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_get --
- * DB->get.
- *
- * PUBLIC: int __db_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_get(dbp, txn, key, data, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key, *data;
- u_int32_t flags;
-{
- DBC *dbc;
- u_int32_t mode;
- int ret, t_ret;
-
- mode = 0;
- if (LF_ISSET(DB_READ_UNCOMMITTED)) {
- mode = DB_READ_UNCOMMITTED;
- LF_CLR(DB_READ_UNCOMMITTED);
- } else if (LF_ISSET(DB_READ_COMMITTED)) {
- mode = DB_READ_COMMITTED;
- LF_CLR(DB_READ_COMMITTED);
- } else if ((flags & DB_OPFLAGS_MASK) == DB_CONSUME ||
- (flags & DB_OPFLAGS_MASK) == DB_CONSUME_WAIT)
- mode = DB_WRITELOCK;
-
- if ((ret = __db_cursor(dbp, txn, &dbc, mode)) != 0)
- return (ret);
-
- DEBUG_LREAD(dbc, txn, "DB->get", key, NULL, flags);
-
- /*
- * The DBC_TRANSIENT flag indicates that we're just doing a
- * single operation with this cursor, and that in case of
- * error we don't need to restore it to its old position--we're
- * going to close it right away. Thus, we can perform the get
- * without duplicating the cursor, saving some cycles in this
- * common case.
- */
- F_SET(dbc, DBC_TRANSIENT);
-
- /*
- * SET_RET_MEM indicates that if key and/or data have no DBT
- * flags set and DB manages the returned-data memory, that memory
- * will belong to this handle, not to the underlying cursor.
- */
- SET_RET_MEM(dbc, dbp);
-
- if (LF_ISSET(~(DB_RMW | DB_MULTIPLE)) == 0)
- LF_SET(DB_SET);
-
- ret = __db_c_get(dbc, key, data, flags);
-
- if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_get_arg --
- * DB->get argument checking, used by both DB->get and DB->pget.
- */
-static int
-__db_get_arg(dbp, key, data, flags)
- const DB *dbp;
- const DBT *key;
- DBT *data;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- int check_thread, dirty, multi, ret;
-
- dbenv = dbp->dbenv;
-
- /*
- * Check for read-modify-write validity. DB_RMW doesn't make sense
- * with CDB cursors since if you're going to write the cursor, you
- * had to create it with DB_WRITECURSOR. Regardless, we check for
- * LOCKING_ON and not STD_LOCKING, as we don't want to disallow it.
- * If this changes, confirm that DB does not itself set the DB_RMW
- * flag in a path where CDB may have been configured.
- */
- check_thread = dirty = 0;
- if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW)) {
- if (!LOCKING_ON(dbenv))
- return (__db_fnl(dbenv, "DB->get"));
- if ((ret = __db_fcchk(dbenv, "DB->get",
- flags, DB_READ_UNCOMMITTED, DB_READ_COMMITTED)) != 0)
- return (ret);
- if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED))
- dirty = 1;
- LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW);
- }
-
- multi = 0;
- if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) {
- if (LF_ISSET(DB_MULTIPLE_KEY))
- goto multi_err;
- multi = LF_ISSET(DB_MULTIPLE) ? 1 : 0;
- LF_CLR(DB_MULTIPLE);
- }
-
- /* Check for invalid function flags. */
- switch (flags) {
- case 0:
- case DB_GET_BOTH:
- break;
- case DB_SET_RECNO:
- check_thread = 1;
- if (!F_ISSET(dbp, DB_AM_RECNUM))
- goto err;
- break;
- case DB_CONSUME:
- case DB_CONSUME_WAIT:
- check_thread = 1;
- if (dirty) {
- __db_err(dbenv,
- "%s is not supported with DB_CONSUME or DB_CONSUME_WAIT",
- LF_ISSET(DB_READ_UNCOMMITTED) ?
- "DB_READ_UNCOMMITTED" : "DB_READ_COMMITTED");
- return (EINVAL);
- }
- if (multi)
-multi_err: return (__db_ferr(dbenv, "DB->get", 1));
- if (dbp->type == DB_QUEUE)
- break;
- /* FALLTHROUGH */
- default:
-err: return (__db_ferr(dbenv, "DB->get", 0));
- }
-
- /*
- * Check for invalid key/data flags.
- *
- * XXX: Dave Krinsky
- * Remember to modify this when we fix the flag-returning problem.
- */
- if ((ret = __dbt_ferr(dbp, "key", key, check_thread)) != 0)
- return (ret);
- if ((ret = __dbt_ferr(dbp, "data", data, 1)) != 0)
- return (ret);
-
- if (multi) {
- if (!F_ISSET(data, DB_DBT_USERMEM)) {
- __db_err(dbenv,
- "DB_MULTIPLE requires DB_DBT_USERMEM be set");
- return (EINVAL);
- }
- if (F_ISSET(key, DB_DBT_PARTIAL) ||
- F_ISSET(data, DB_DBT_PARTIAL)) {
- __db_err(dbenv,
- "DB_MULTIPLE does not support DB_DBT_PARTIAL");
- return (EINVAL);
- }
- if (data->ulen < 1024 ||
- data->ulen < dbp->pgsize || data->ulen % 1024 != 0) {
- __db_err(dbenv, "%s%s",
- "DB_MULTIPLE buffers must be ",
- "aligned, at least page size and multiples of 1KB");
- return (EINVAL);
- }
- }
-
- return (0);
-}
-
-/*
- * __db_join_pp --
- * DB->join pre/post processing.
- *
- * PUBLIC: int __db_join_pp __P((DB *, DBC **, DBC **, u_int32_t));
- */
-int
-__db_join_pp(primary, curslist, dbcp, flags)
- DB *primary;
- DBC **curslist, **dbcp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- dbenv = primary->dbenv;
-
- PANIC_CHECK(dbenv);
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret =
- __db_rep_enter(primary, 1, 0, curslist[0]->txn != NULL)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- if ((ret = __db_join_arg(primary, curslist, flags)) == 0)
- ret = __db_join(primary, curslist, dbcp, flags);
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_join_arg --
- * Check DB->join arguments.
- */
-static int
-__db_join_arg(primary, curslist, flags)
- DB *primary;
- DBC **curslist;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_TXN *txn;
- int i;
-
- dbenv = primary->dbenv;
-
- switch (flags) {
- case 0:
- case DB_JOIN_NOSORT:
- break;
- default:
- return (__db_ferr(dbenv, "DB->join", 0));
- }
-
- if (curslist == NULL || curslist[0] == NULL) {
- __db_err(dbenv,
- "At least one secondary cursor must be specified to DB->join");
- return (EINVAL);
- }
-
- txn = curslist[0]->txn;
- for (i = 1; curslist[i] != NULL; i++)
- if (curslist[i]->txn != txn) {
- __db_err(dbenv,
- "All secondary cursors must share the same transaction");
- return (EINVAL);
- }
-
- return (0);
-}
-
-/*
- * __db_key_range_pp --
- * DB->key_range pre/post processing.
- *
- * PUBLIC: int __db_key_range_pp
- * PUBLIC: __P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t));
- */
-int
-__db_key_range_pp(dbp, txn, key, kr, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key;
- DB_KEY_RANGE *kr;
- u_int32_t flags;
-{
- DBC *dbc;
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbp->dbenv);
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->key_range");
-
- /*
- * !!!
- * The actual argument checking is simple, do it inline, outside of
- * the replication block.
- */
- if (flags != 0)
- return (__db_ferr(dbenv, "DB->key_range", 0));
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check &&
- (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- /* Check for consistent transaction usage. */
- if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 1)) != 0)
- goto err;
-
- /*
- * !!!
- * The actual method call is simple, do it inline.
- */
- switch (dbp->type) {
- case DB_BTREE:
- /* Acquire a cursor. */
- if ((ret = __db_cursor(dbp, txn, &dbc, 0)) != 0)
- break;
-
- DEBUG_LWRITE(dbc, NULL, "bam_key_range", NULL, NULL, 0);
-
- ret = __bam_key_range(dbc, key, kr, flags);
-
- if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
- break;
- case DB_HASH:
- case DB_QUEUE:
- case DB_RECNO:
- ret = __dbh_am_chk(dbp, DB_OK_BTREE);
- break;
- case DB_UNKNOWN:
- default:
- ret = __db_unknown_type(dbenv, "DB->key_range", dbp->type);
- break;
- }
-
-err: /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_open_pp --
- * DB->open pre/post processing.
- *
- * PUBLIC: int __db_open_pp __P((DB *, DB_TXN *,
- * PUBLIC: const char *, const char *, DBTYPE, u_int32_t, int));
- */
-int
-__db_open_pp(dbp, txn, fname, dname, type, flags, mode)
- DB *dbp;
- DB_TXN *txn;
- const char *fname, *dname;
- DBTYPE type;
- u_int32_t flags;
- int mode;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, nosync, remove_me, ret, t_ret, txn_local;
-
- dbenv = dbp->dbenv;
- nosync = 1;
- remove_me = txn_local = 0;
- handle_check = 0;
-
- PANIC_CHECK(dbenv);
-
- ENV_ENTER(dbenv, ip);
-
- /*
- * Save the file and database names and flags. We do this here
- * because we don't pass all of the flags down into the actual
- * DB->open method call, we strip DB_AUTO_COMMIT at this layer.
- */
- if ((fname != NULL &&
- (ret = __os_strdup(dbenv, fname, &dbp->fname)) != 0))
- goto err;
- if ((dname != NULL &&
- (ret = __os_strdup(dbenv, dname, &dbp->dname)) != 0))
- goto err;
- dbp->open_flags = flags;
-
- /* Save the current DB handle flags for refresh. */
- dbp->orig_flags = dbp->flags;
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check &&
- (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- /*
- * Create local transaction as necessary, check for consistent
- * transaction usage.
- */
- if (IS_ENV_AUTO_COMMIT(dbenv, txn, flags)) {
- if ((ret = __db_txn_auto_init(dbenv, &txn)) != 0)
- goto err;
- txn_local = 1;
- } else
- if (txn != NULL && !TXN_ON(dbenv)) {
- ret = __db_not_txn_env(dbenv);
- goto err;
- }
- LF_CLR(DB_AUTO_COMMIT);
-
- /*
- * We check arguments after possibly creating a local transaction,
- * which is unusual -- the reason is some flags are illegal if any
- * kind of transaction is in effect.
- */
- if ((ret = __db_open_arg(dbp, txn, fname, dname, type, flags)) == 0)
- if ((ret = __db_open(dbp, txn, fname, dname, type,
- flags, mode, PGNO_BASE_MD)) != 0)
- goto txnerr;
-
- /*
- * You can open the database that describes the subdatabases in the
- * rest of the file read-only. The content of each key's data is
- * unspecified and applications should never be adding new records
- * or updating existing records. However, during recovery, we need
- * to open these databases R/W so we can redo/undo changes in them.
- * Likewise, we need to open master databases read/write during
- * rename and remove so we can be sure they're fully sync'ed, so
- * we provide an override flag for the purpose.
- */
- if (dname == NULL && !IS_RECOVERING(dbenv) && !LF_ISSET(DB_RDONLY) &&
- !LF_ISSET(DB_RDWRMASTER) && F_ISSET(dbp, DB_AM_SUBDB)) {
- __db_err(dbenv,
- "files containing multiple databases may only be opened read-only");
- ret = EINVAL;
- goto txnerr;
- }
-
- /*
- * Success: file creations have to be synchronous, otherwise we don't
- * care.
- */
- if (F_ISSET(dbp, DB_AM_CREATED | DB_AM_CREATED_MSTR))
- nosync = 0;
-
- /* Success: don't discard the file on close. */
- F_CLR(dbp, DB_AM_DISCARD | DB_AM_CREATED | DB_AM_CREATED_MSTR);
-
- /*
- * If not transactional, remove the databases/subdatabases. If we're
- * transactional, the child transaction abort cleans up.
- */
-txnerr: if (ret != 0 && txn == NULL) {
- remove_me = F_ISSET(dbp, DB_AM_CREATED);
- if (F_ISSET(dbp, DB_AM_CREATED_MSTR) ||
- (dname == NULL && remove_me))
- /* Remove file. */
- (void)__db_remove_int(dbp, txn, fname, NULL, DB_FORCE);
- else if (remove_me)
- /* Remove subdatabase. */
- (void)__db_remove_int(dbp, txn, fname, dname, DB_FORCE);
- }
-
- if (txn_local && (t_ret =
- __db_txn_auto_resolve(dbenv, txn, nosync, ret)) && ret == 0)
- ret = t_ret;
-
-err: /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_open_arg --
- * Check DB->open arguments.
- */
-static int
-__db_open_arg(dbp, txn, fname, dname, type, flags)
- DB *dbp;
- DB_TXN *txn;
- const char *fname, *dname;
- DBTYPE type;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- u_int32_t ok_flags;
- int ret;
-
- dbenv = dbp->dbenv;
-
- /* Validate arguments. */
-#undef OKFLAGS
-#define OKFLAGS \
- (DB_AUTO_COMMIT | DB_CREATE | DB_EXCL | DB_FCNTL_LOCKING | \
- DB_NOMMAP | DB_NO_AUTO_COMMIT | DB_RDONLY | DB_RDWRMASTER | \
- DB_READ_UNCOMMITTED | DB_THREAD | DB_TRUNCATE | DB_WRITEOPEN)
- if ((ret = __db_fchk(dbenv, "DB->open", flags, OKFLAGS)) != 0)
- return (ret);
- if (LF_ISSET(DB_EXCL) && !LF_ISSET(DB_CREATE))
- return (__db_ferr(dbenv, "DB->open", 1));
- if (LF_ISSET(DB_RDONLY) && LF_ISSET(DB_CREATE))
- return (__db_ferr(dbenv, "DB->open", 1));
-
-#ifdef HAVE_VXWORKS
- if (LF_ISSET(DB_TRUNCATE)) {
- __db_err(dbenv, "DB_TRUNCATE not supported on VxWorks");
- return (DB_OPNOTSUP);
- }
-#endif
- switch (type) {
- case DB_UNKNOWN:
- if (LF_ISSET(DB_CREATE|DB_TRUNCATE)) {
- __db_err(dbenv,
- "DB_UNKNOWN type specified with DB_CREATE or DB_TRUNCATE");
- return (EINVAL);
- }
- ok_flags = 0;
- break;
- case DB_BTREE:
- ok_flags = DB_OK_BTREE;
- break;
- case DB_HASH:
-#ifndef HAVE_HASH
- return (__db_no_hash_am(dbenv));
-#endif
- ok_flags = DB_OK_HASH;
- break;
- case DB_QUEUE:
-#ifndef HAVE_QUEUE
- return (__db_no_queue_am(dbenv));
-#endif
- ok_flags = DB_OK_QUEUE;
- break;
- case DB_RECNO:
- ok_flags = DB_OK_RECNO;
- break;
- default:
- __db_err(dbenv, "unknown type: %lu", (u_long)type);
- return (EINVAL);
- }
- if (ok_flags)
- DB_ILLEGAL_METHOD(dbp, ok_flags);
-
- /* The environment may have been created, but never opened. */
- if (!F_ISSET(dbenv, DB_ENV_DBLOCAL | DB_ENV_OPEN_CALLED)) {
- __db_err(dbenv, "environment not yet opened");
- return (EINVAL);
- }
-
- /*
- * Historically, you could pass in an environment that didn't have a
- * mpool, and DB would create a private one behind the scenes. This
- * no longer works.
- */
- if (!F_ISSET(dbenv, DB_ENV_DBLOCAL) && !MPOOL_ON(dbenv)) {
- __db_err(dbenv, "environment did not include a memory pool");
- return (EINVAL);
- }
-
- /*
- * You can't specify threads during DB->open if subsystems in the
- * environment weren't configured with them.
- */
- if (LF_ISSET(DB_THREAD) &&
- !F_ISSET(dbenv, DB_ENV_DBLOCAL | DB_ENV_THREAD)) {
- __db_err(dbenv, "environment not created using DB_THREAD");
- return (EINVAL);
- }
-
- /* DB_TRUNCATE is neither transaction recoverable nor lockable. */
- if (LF_ISSET(DB_TRUNCATE) && (LOCKING_ON(dbenv) || txn != NULL)) {
- __db_err(dbenv,
- "DB_TRUNCATE illegal with %s specified",
- LOCKING_ON(dbenv) ? "locking" : "transactions");
- return (EINVAL);
- }
-
- /* Subdatabase checks. */
- if (dname != NULL) {
- /* QAM can only be done on in-memory subdatabases. */
- if (type == DB_QUEUE && fname != NULL) {
- __db_err(dbenv, "Queue databases must be one-per-file");
- return (EINVAL);
- }
-
- /*
- * Named in-memory databases can't support certain flags,
- * so check here.
- */
- if (fname == NULL)
- F_CLR(dbp, DB_AM_CHKSUM | DB_AM_ENCRYPT);
- }
-
- return (0);
-}
-
-/*
- * __db_pget_pp --
- * DB->pget pre/post processing.
- *
- * PUBLIC: int __db_pget_pp
- * PUBLIC: __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_pget_pp(dbp, txn, skey, pkey, data, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *skey, *pkey, *data;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->pget");
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check &&
- (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- if ((ret = __db_pget_arg(dbp, pkey, flags)) != 0 ||
- (ret = __db_get_arg(dbp, skey, data, flags)) != 0)
- goto err;
-
- ret = __db_pget(dbp, txn, skey, pkey, data, flags);
-
-err: /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_pget --
- * DB->pget.
- *
- * PUBLIC: int __db_pget
- * PUBLIC: __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_pget(dbp, txn, skey, pkey, data, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *skey, *pkey, *data;
- u_int32_t flags;
-{
- DBC *dbc;
- u_int32_t mode;
- int ret, t_ret;
-
- if (LF_ISSET(DB_READ_UNCOMMITTED)) {
- mode = DB_READ_UNCOMMITTED;
- LF_CLR(DB_READ_UNCOMMITTED);
- } else if (LF_ISSET(DB_READ_COMMITTED)) {
- mode = DB_READ_COMMITTED;
- LF_CLR(DB_READ_COMMITTED);
- } else
- mode = 0;
-
- if ((ret = __db_cursor(dbp, txn, &dbc, mode)) != 0)
- return (ret);
-
- SET_RET_MEM(dbc, dbp);
-
- DEBUG_LREAD(dbc, txn, "__db_pget", skey, NULL, flags);
-
- /*
- * !!!
- * The actual method call is simple, do it inline.
- *
- * The underlying cursor pget will fill in a default DBT for null
- * pkeys, and use the cursor's returned-key memory internally to
- * store any intermediate primary keys. However, we've just set
- * the returned-key memory to the DB handle's key memory, which
- * is unsafe to use if the DB handle is threaded. If the pkey
- * argument is NULL, use the DBC-owned returned-key memory
- * instead; it'll go away when we close the cursor before we
- * return, but in this case that's just fine, as we're not
- * returning the primary key.
- */
- if (pkey == NULL)
- dbc->rkey = &dbc->my_rkey;
-
- /*
- * The cursor is just a perfectly ordinary secondary database cursor.
- * Call its c_pget() method to do the dirty work.
- */
- if (flags == 0 || flags == DB_RMW)
- flags |= DB_SET;
-
- ret = __db_c_pget(dbc, skey, pkey, data, flags);
-
- if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_pget_arg --
- * Check DB->pget arguments.
- */
-static int
-__db_pget_arg(dbp, pkey, flags)
- DB *dbp;
- DBT *pkey;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- int ret;
-
- dbenv = dbp->dbenv;
-
- if (!F_ISSET(dbp, DB_AM_SECONDARY)) {
- __db_err(dbenv,
- "DB->pget may only be used on secondary indices");
- return (EINVAL);
- }
-
- if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) {
- __db_err(dbenv,
- "DB_MULTIPLE and DB_MULTIPLE_KEY may not be used on secondary indices");
- return (EINVAL);
- }
-
- /* DB_CONSUME makes no sense on a secondary index. */
- LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW);
- switch (flags) {
- case DB_CONSUME:
- case DB_CONSUME_WAIT:
- return (__db_ferr(dbenv, "DB->pget", 0));
- default:
- /* __db_get_arg will catch the rest. */
- break;
- }
-
- /*
- * We allow the pkey field to be NULL, so that we can make the
- * two-DBT get calls into wrappers for the three-DBT ones.
- */
- if (pkey != NULL &&
- (ret = __dbt_ferr(dbp, "primary key", pkey, 1)) != 0)
- return (ret);
-
- /* But the pkey field can't be NULL if we're doing a DB_GET_BOTH. */
- if (pkey == NULL && flags == DB_GET_BOTH) {
- __db_err(dbenv,
- "DB_GET_BOTH on a secondary index requires a primary key");
- return (EINVAL);
- }
-
- return (0);
-}
-
-/*
- * __db_put_pp --
- * DB->put pre/post processing.
- *
- * PUBLIC: int __db_put_pp __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_put_pp(dbp, txn, key, data, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key, *data;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, txn_local, t_ret;
-
- dbenv = dbp->dbenv;
- txn_local = 0;
-
- PANIC_CHECK(dbenv);
- STRIP_AUTO_COMMIT(flags);
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->put");
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check &&
- (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- if ((ret = __db_put_arg(dbp, key, data, flags)) != 0)
- goto err;
-
- /* Create local transaction as necessary. */
- if (IS_DB_AUTO_COMMIT(dbp, txn)) {
- if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0)
- goto err;
- txn_local = 1;
- }
-
- /* Check for consistent transaction usage. */
- if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0)
- goto err;
-
- ret = __db_put(dbp, txn, key, data, flags);
-
-err: if (txn_local &&
- (t_ret = __db_txn_auto_resolve(dbenv, txn, 0, ret)) && ret == 0)
- ret = t_ret;
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_put_arg --
- * Check DB->put arguments.
- */
-static int
-__db_put_arg(dbp, key, data, flags)
- DB *dbp;
- DBT *key, *data;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- int ret, returnkey;
-
- dbenv = dbp->dbenv;
- returnkey = 0;
-
- /* Check for changes to a read-only tree. */
- if (DB_IS_READONLY(dbp))
- return (__db_rdonly(dbenv, "DB->put"));
-
- /* Check for puts on a secondary. */
- if (F_ISSET(dbp, DB_AM_SECONDARY)) {
- __db_err(dbenv, "DB->put forbidden on secondary indices");
- return (EINVAL);
- }
-
- /* Check for invalid function flags. */
- switch (flags) {
- case 0:
- case DB_NOOVERWRITE:
- break;
- case DB_APPEND:
- if (dbp->type != DB_RECNO && dbp->type != DB_QUEUE)
- goto err;
- returnkey = 1;
- break;
- case DB_NODUPDATA:
- if (F_ISSET(dbp, DB_AM_DUPSORT))
- break;
- /* FALLTHROUGH */
- default:
-err: return (__db_ferr(dbenv, "DB->put", 0));
- }
-
- /* Check for invalid key/data flags. */
- if ((ret = __dbt_ferr(dbp, "key", key, returnkey)) != 0)
- return (ret);
- if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)
- return (ret);
-
- /* Keys shouldn't have partial flags during a put. */
- if (F_ISSET(key, DB_DBT_PARTIAL))
- return (__db_ferr(dbenv, "key DBT", 0));
-
- /* Check for partial puts in the presence of duplicates. */
- if (F_ISSET(data, DB_DBT_PARTIAL) &&
- (F_ISSET(dbp, DB_AM_DUP) || F_ISSET(key, DB_DBT_DUPOK))) {
- __db_err(dbenv,
-"a partial put in the presence of duplicates requires a cursor operation");
- return (EINVAL);
- }
-
- return (0);
-}
-
-/*
- * __db_compact_pp --
- * DB->compact pre/post processing.
- *
- * PUBLIC: int __db_compact_pp __P((DB *, DB_TXN *,
- * PUBLIC: DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *));
- */
-int
-__db_compact_pp(dbp, txn, start, stop, c_data, flags, end)
- DB *dbp;
- DB_TXN *txn;
- DBT *start, *stop;
- DB_COMPACT *c_data;
- u_int32_t flags;
- DBT *end;
-{
- DB_COMPACT *dp, l_data;
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->compact");
-
- /*
- * !!!
- * The actual argument checking is simple, do it inline, outside of
- * the replication block.
- */
- if ((flags & ~DB_COMPACT_FLAGS) != 0)
- return (__db_ferr(dbenv, "DB->compact", 0));
-
- /* Check for changes to a read-only database. */
- if (DB_IS_READONLY(dbp))
- return (__db_rdonly(dbenv, "DB->compact"));
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- if (c_data == NULL) {
- dp = &l_data;
- memset(dp, 0, sizeof(*dp));
- } else
- dp = c_data;
-
- switch (dbp->type) {
- case DB_HASH:
- if (!LF_ISSET(DB_FREELIST_ONLY))
- goto err;
- /* FALLTHROUGH */
- case DB_BTREE:
- case DB_RECNO:
- ret = __bam_compact(dbp, txn, start, stop, dp, flags, end);
- break;
-
- default:
-err: ret = __dbh_am_chk(dbp, DB_OK_BTREE);
- break;
- }
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_sync_pp --
- * DB->sync pre/post processing.
- *
- * PUBLIC: int __db_sync_pp __P((DB *, u_int32_t));
- */
-int
-__db_sync_pp(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->sync");
-
- /*
- * !!!
- * The actual argument checking is simple, do it inline, outside of
- * the replication block.
- */
- if (flags != 0)
- return (__db_ferr(dbenv, "DB->sync", 0));
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- ret = __db_sync(dbp);
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_c_close_pp --
- * DBC->c_close pre/post processing.
- *
- * PUBLIC: int __db_c_close_pp __P((DBC *));
- */
-int
-__db_c_close_pp(dbc)
- DBC *dbc;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- DB *dbp;
- int handle_check, ret, t_ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
- ENV_ENTER(dbenv, ip);
-
- /*
- * If the cursor is already closed we have a serious problem, and we
- * assume that the cursor isn't on the active queue. Don't do any of
- * the remaining cursor close processing.
- */
- if (!F_ISSET(dbc, DBC_ACTIVE)) {
- if (dbp != NULL)
- __db_err(dbenv, "Closing already-closed cursor");
- DB_ASSERT(0);
- ret = EINVAL;
- goto err;
- }
-
- /* Check for replication block. */
- handle_check = dbc->txn == NULL && IS_ENV_REPLICATED(dbenv);
- ret = __db_c_close(dbc);
-
- /* Release replication block. */
- if (handle_check &&
- (t_ret = __op_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_c_count_pp --
- * DBC->c_count pre/post processing.
- *
- * PUBLIC: int __db_c_count_pp __P((DBC *, db_recno_t *, u_int32_t));
- */
-int
-__db_c_count_pp(dbc, recnop, flags)
- DBC *dbc;
- db_recno_t *recnop;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- DB *dbp;
- int ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
-
- /*
- * !!!
- * The actual argument checking is simple, do it inline, outside of
- * the replication block.
- *
- * The cursor must be initialized, return EINVAL for an invalid cursor.
- */
- if (flags != 0)
- return (__db_ferr(dbenv, "DBcursor->count", 0));
-
- if (!IS_INITIALIZED(dbc))
- return (__db_curinval(dbenv));
-
- ENV_ENTER(dbenv, ip);
-
- ret = __db_c_count(dbc, recnop);
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_c_del_pp --
- * DBC->c_del pre/post processing.
- *
- * PUBLIC: int __db_c_del_pp __P((DBC *, u_int32_t));
- */
-int
-__db_c_del_pp(dbc, flags)
- DBC *dbc;
- u_int32_t flags;
-{
- DB *dbp;
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
-
- if ((ret = __db_c_del_arg(dbc, flags)) != 0)
- return (ret);
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for consistent transaction usage. */
- if ((ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0)
- goto err;
-
- DEBUG_LWRITE(dbc, dbc->txn, "DBcursor->del", NULL, NULL, flags);
- ret = __db_c_del(dbc, flags);
-err:
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_c_del_arg --
- * Check DBC->c_del arguments.
- */
-static int
-__db_c_del_arg(dbc, flags)
- DBC *dbc;
- u_int32_t flags;
-{
- DB *dbp;
- DB_ENV *dbenv;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- /* Check for changes to a read-only tree. */
- if (DB_IS_READONLY(dbp))
- return (__db_rdonly(dbenv, "DBcursor->del"));
-
- /* Check for invalid function flags. */
- switch (flags) {
- case 0:
- break;
- case DB_UPDATE_SECONDARY:
- DB_ASSERT(F_ISSET(dbp, DB_AM_SECONDARY));
- break;
- default:
- return (__db_ferr(dbenv, "DBcursor->del", 0));
- }
-
- /*
- * The cursor must be initialized, return EINVAL for an invalid cursor,
- * otherwise 0.
- */
- if (!IS_INITIALIZED(dbc))
- return (__db_curinval(dbenv));
-
- return (0);
-}
-
-/*
- * __db_c_dup_pp --
- * DBC->c_dup pre/post processing.
- *
- * PUBLIC: int __db_c_dup_pp __P((DBC *, DBC **, u_int32_t));
- */
-int
-__db_c_dup_pp(dbc, dbcp, flags)
- DBC *dbc, **dbcp;
- u_int32_t flags;
-{
- DB *dbp;
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
-
- /*
- * !!!
- * The actual argument checking is simple, do it inline, outside of
- * the replication block.
- */
- if (flags != 0 && flags != DB_POSITION)
- return (__db_ferr(dbenv, "DBcursor->dup", 0));
-
- ENV_ENTER(dbenv, ip);
-
- ret = __db_c_dup(dbc, dbcp, flags);
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_c_get_pp --
- * DBC->c_get pre/post processing.
- *
- * PUBLIC: int __db_c_get_pp __P((DBC *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_c_get_pp(dbc, key, data, flags)
- DBC *dbc;
- DBT *key, *data;
- u_int32_t flags;
-{
- DB *dbp;
- DB_ENV *dbenv;
- int ret;
- DB_THREAD_INFO *ip;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
-
- if ((ret = __db_c_get_arg(dbc, key, data, flags)) != 0)
- return (ret);
-
- ENV_ENTER(dbenv, ip);
-
- DEBUG_LREAD(dbc, dbc->txn, "DBcursor->get",
- flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, NULL, flags);
- ret = __db_c_get(dbc, key, data, flags);
-
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_c_get_arg --
- * Common DBC->get argument checking, used by both DBC->get and DBC->pget.
- */
-static int
-__db_c_get_arg(dbc, key, data, flags)
- DBC *dbc;
- DBT *key, *data;
- u_int32_t flags;
-{
- DB *dbp;
- DB_ENV *dbenv;
- int dirty, multi, ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- /*
- * Typically in checking routines that modify the flags, we have
- * to save them and restore them, because the checking routine
- * calls the work routine. However, this is a pure-checking
- * routine which returns to a function that calls the work routine,
- * so it's OK that we do not save and restore the flags, even though
- * we modify them.
- *
- * Check for read-modify-write validity. DB_RMW doesn't make sense
- * with CDB cursors since if you're going to write the cursor, you
- * had to create it with DB_WRITECURSOR. Regardless, we check for
- * LOCKING_ON and not STD_LOCKING, as we don't want to disallow it.
- * If this changes, confirm that DB does not itself set the DB_RMW
- * flag in a path where CDB may have been configured.
- */
- dirty = 0;
- if (LF_ISSET(DB_READ_UNCOMMITTED | DB_RMW)) {
- if (!LOCKING_ON(dbenv))
- return (__db_fnl(dbenv, "DBcursor->get"));
- if (LF_ISSET(DB_READ_UNCOMMITTED))
- dirty = 1;
- LF_CLR(DB_READ_UNCOMMITTED | DB_RMW);
- }
-
- multi = 0;
- if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) {
- multi = 1;
- if (LF_ISSET(DB_MULTIPLE) && LF_ISSET(DB_MULTIPLE_KEY))
- goto multi_err;
- LF_CLR(DB_MULTIPLE | DB_MULTIPLE_KEY);
- }
-
- /* Check for invalid function flags. */
- switch (flags) {
- case DB_CONSUME:
- case DB_CONSUME_WAIT:
- if (dirty) {
- __db_err(dbenv,
- "DB_READ_UNCOMMITTED is not supported with DB_CONSUME or DB_CONSUME_WAIT");
- return (EINVAL);
- }
- if (dbp->type != DB_QUEUE)
- goto err;
- break;
- case DB_CURRENT:
- case DB_FIRST:
- case DB_GET_BOTH:
- case DB_GET_BOTH_RANGE:
- case DB_NEXT:
- case DB_NEXT_DUP:
- case DB_NEXT_NODUP:
- case DB_SET:
- case DB_SET_RANGE:
- break;
- case DB_LAST:
- case DB_PREV:
- case DB_PREV_NODUP:
- if (multi)
-multi_err: return (__db_ferr(dbenv, "DBcursor->get", 1));
- break;
- case DB_GET_BOTHC:
- if (dbp->type == DB_QUEUE)
- goto err;
- break;
- case DB_GET_RECNO:
- /*
- * The one situation in which this might be legal with a
- * non-RECNUM dbp is if dbp is a secondary and its primary is
- * DB_AM_RECNUM.
- */
- if (!F_ISSET(dbp, DB_AM_RECNUM) &&
- (!F_ISSET(dbp, DB_AM_SECONDARY) ||
- !F_ISSET(dbp->s_primary, DB_AM_RECNUM)))
- goto err;
- break;
- case DB_SET_RECNO:
- if (!F_ISSET(dbp, DB_AM_RECNUM))
- goto err;
- break;
- default:
-err: return (__db_ferr(dbenv, "DBcursor->get", 0));
- }
-
- /* Check for invalid key/data flags. */
- if ((ret = __dbt_ferr(dbp, "key", key, 0)) != 0)
- return (ret);
- if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)
- return (ret);
-
- if (multi) {
- if (!F_ISSET(data, DB_DBT_USERMEM)) {
- __db_err(dbenv,
- "DB_MULTIPLE/DB_MULTIPLE_KEY require DB_DBT_USERMEM be set");
- return (EINVAL);
- }
- if (F_ISSET(key, DB_DBT_PARTIAL) ||
- F_ISSET(data, DB_DBT_PARTIAL)) {
- __db_err(dbenv,
- "DB_MULTIPLE/DB_MULTIPLE_KEY do not support DB_DBT_PARTIAL");
- return (EINVAL);
- }
- if (data->ulen < 1024 ||
- data->ulen < dbp->pgsize || data->ulen % 1024 != 0) {
- __db_err(dbenv, "%s%s",
- "DB_MULTIPLE/DB_MULTIPLE_KEY buffers must be ",
- "aligned, at least page size and multiples of 1KB");
- return (EINVAL);
- }
- }
-
- /*
- * The cursor must be initialized for DB_CURRENT, DB_GET_RECNO and
- * DB_NEXT_DUP. Return EINVAL for an invalid cursor, otherwise 0.
- */
- if (!IS_INITIALIZED(dbc) && (flags == DB_CURRENT ||
- flags == DB_GET_RECNO || flags == DB_NEXT_DUP))
- return (__db_curinval(dbenv));
-
- /* Check for consistent transaction usage. */
- if (LF_ISSET(DB_RMW) &&
- (ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0)
- return (ret);
-
- return (0);
-}
-
-/*
- * __db_secondary_close_pp --
- * DB->close for secondaries
- *
- * PUBLIC: int __db_secondary_close_pp __P((DB *, u_int32_t));
- */
-int
-__db_secondary_close_pp(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- dbenv = dbp->dbenv;
- ret = 0;
-
- PANIC_CHECK(dbenv);
-
- /*
- * As a DB handle destructor, we can't fail.
- *
- * !!!
- * The actual argument checking is simple, do it inline, outside of
- * the replication block.
- */
- if (flags != 0 && flags != DB_NOSYNC)
- ret = __db_ferr(dbenv, "DB->close", 0);
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (t_ret = __db_rep_enter(dbp, 0, 0, 0)) != 0) {
- handle_check = 0;
- if (ret == 0)
- ret = t_ret;
- }
-
- if ((t_ret = __db_secondary_close(dbp, flags)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_c_pget_pp --
- * DBC->c_pget pre/post processing.
- *
- * PUBLIC: int __db_c_pget_pp __P((DBC *, DBT *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_c_pget_pp(dbc, skey, pkey, data, flags)
- DBC *dbc;
- DBT *skey, *pkey, *data;
- u_int32_t flags;
-{
- DB *dbp;
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
-
- if ((ret = __db_c_pget_arg(dbc, pkey, flags)) != 0 ||
- (ret = __db_c_get_arg(dbc, skey, data, flags)) != 0)
- return (ret);
-
- ENV_ENTER(dbenv, ip);
-
- ret = __db_c_pget(dbc, skey, pkey, data, flags);
-
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_c_pget_arg --
- * Check DBC->pget arguments.
- */
-static int
-__db_c_pget_arg(dbc, pkey, flags)
- DBC *dbc;
- DBT *pkey;
- u_int32_t flags;
-{
- DB *dbp;
- DB_ENV *dbenv;
- int ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- if (!F_ISSET(dbp, DB_AM_SECONDARY)) {
- __db_err(dbenv,
- "DBcursor->pget may only be used on secondary indices");
- return (EINVAL);
- }
-
- if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) {
- __db_err(dbenv,
- "DB_MULTIPLE and DB_MULTIPLE_KEY may not be used on secondary indices");
- return (EINVAL);
- }
-
- switch (LF_ISSET(~DB_RMW)) {
- case DB_CONSUME:
- case DB_CONSUME_WAIT:
- /* These flags make no sense on a secondary index. */
- return (__db_ferr(dbenv, "DBcursor->pget", 0));
- case DB_GET_BOTH:
- /* DB_GET_BOTH is "get both the primary and the secondary". */
- if (pkey == NULL) {
- __db_err(dbenv,
- "DB_GET_BOTH requires both a secondary and a primary key");
- return (EINVAL);
- }
- break;
- default:
- /* __db_c_get_arg will catch the rest. */
- break;
- }
-
- /*
- * We allow the pkey field to be NULL, so that we can make the
- * two-DBT get calls into wrappers for the three-DBT ones.
- */
- if (pkey != NULL &&
- (ret = __dbt_ferr(dbp, "primary key", pkey, 0)) != 0)
- return (ret);
-
- /* But the pkey field can't be NULL if we're doing a DB_GET_BOTH. */
- if (pkey == NULL && (flags & DB_OPFLAGS_MASK) == DB_GET_BOTH) {
- __db_err(dbenv,
- "DB_GET_BOTH on a secondary index requires a primary key");
- return (EINVAL);
- }
- return (0);
-}
-
-/*
- * __db_c_put_pp --
- * DBC->put pre/post processing.
- *
- * PUBLIC: int __db_c_put_pp __P((DBC *, DBT *, DBT *, u_int32_t));
- */
-int
-__db_c_put_pp(dbc, key, data, flags)
- DBC *dbc;
- DBT *key, *data;
- u_int32_t flags;
-{
- DB *dbp;
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
-
- if ((ret = __db_c_put_arg(dbc, key, data, flags)) != 0)
- return (ret);
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for consistent transaction usage. */
- if ((ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0)
- goto err;
-
- DEBUG_LWRITE(dbc, dbc->txn, "DBcursor->put",
- flags == DB_KEYFIRST || flags == DB_KEYLAST ||
- flags == DB_NODUPDATA || flags == DB_UPDATE_SECONDARY ?
- key : NULL, data, flags);
- ret =__db_c_put(dbc, key, data, flags);
-err:
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_c_put_arg --
- * Check DBC->put arguments.
- */
-static int
-__db_c_put_arg(dbc, key, data, flags)
- DBC *dbc;
- DBT *key, *data;
- u_int32_t flags;
-{
- DB *dbp;
- DB_ENV *dbenv;
- int key_flags, ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
- key_flags = 0;
-
- /* Check for changes to a read-only tree. */
- if (DB_IS_READONLY(dbp))
- return (__db_rdonly(dbenv, "DBcursor->put"));
-
- /* Check for puts on a secondary. */
- if (F_ISSET(dbp, DB_AM_SECONDARY)) {
- if (flags == DB_UPDATE_SECONDARY)
- flags = DB_KEYLAST;
- else {
- __db_err(dbenv,
- "DBcursor->put forbidden on secondary indices");
- return (EINVAL);
- }
- }
-
- /* Check for invalid function flags. */
- switch (flags) {
- case DB_AFTER:
- case DB_BEFORE:
- switch (dbp->type) {
- case DB_BTREE:
- case DB_HASH: /* Only with unsorted duplicates. */
- if (!F_ISSET(dbp, DB_AM_DUP))
- goto err;
- if (dbp->dup_compare != NULL)
- goto err;
- break;
- case DB_QUEUE: /* Not permitted. */
- goto err;
- case DB_RECNO: /* Only with mutable record numbers. */
- if (!F_ISSET(dbp, DB_AM_RENUMBER))
- goto err;
- key_flags = 1;
- break;
- case DB_UNKNOWN:
- default:
- goto err;
- }
- break;
- case DB_CURRENT:
- /*
- * If there is a comparison function, doing a DB_CURRENT
- * must not change the part of the data item that is used
- * for the comparison.
- */
- break;
- case DB_NODUPDATA:
- if (!F_ISSET(dbp, DB_AM_DUPSORT))
- goto err;
- /* FALLTHROUGH */
- case DB_KEYFIRST:
- case DB_KEYLAST:
- key_flags = 1;
- break;
- default:
-err: return (__db_ferr(dbenv, "DBcursor->put", 0));
- }
-
- /* Check for invalid key/data flags. */
- if (key_flags && (ret = __dbt_ferr(dbp, "key", key, 0)) != 0)
- return (ret);
- if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)
- return (ret);
-
- /* Keys shouldn't have partial flags during a put. */
- if (F_ISSET(key, DB_DBT_PARTIAL))
- return (__db_ferr(dbenv, "key DBT", 0));
-
- /*
- * The cursor must be initialized for anything other than DB_KEYFIRST
- * and DB_KEYLAST, return EINVAL for an invalid cursor, otherwise 0.
- */
- if (!IS_INITIALIZED(dbc) && flags != DB_KEYFIRST &&
- flags != DB_KEYLAST && flags != DB_NODUPDATA)
- return (__db_curinval(dbenv));
-
- return (0);
-}
-
-/*
- * __dbt_ferr --
- * Check a DBT for flag errors.
- */
-static int
-__dbt_ferr(dbp, name, dbt, check_thread)
- const DB *dbp;
- const char *name;
- const DBT *dbt;
- int check_thread;
-{
- DB_ENV *dbenv;
- int ret;
-
- dbenv = dbp->dbenv;
-
- /*
- * Check for invalid DBT flags. We allow any of the flags to be
- * specified to any DB or DBcursor call so that applications can
- * set DB_DBT_MALLOC when retrieving a data item from a secondary
- * database and then specify that same DBT as a key to a primary
- * database, without having to clear flags.
- */
- if ((ret = __db_fchk(dbenv, name, dbt->flags, DB_DBT_APPMALLOC |
- DB_DBT_MALLOC | DB_DBT_DUPOK | DB_DBT_REALLOC | DB_DBT_USERMEM |
- DB_DBT_PARTIAL)) != 0)
- return (ret);
- switch (F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERMEM)) {
- case 0:
- case DB_DBT_MALLOC:
- case DB_DBT_REALLOC:
- case DB_DBT_USERMEM:
- break;
- default:
- return (__db_ferr(dbenv, name, 1));
- }
-
- if (check_thread && DB_IS_THREADED(dbp) &&
- !F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERMEM)) {
- __db_err(dbenv,
- "DB_THREAD mandates memory allocation flag on DBT %s",
- name);
- return (EINVAL);
- }
- return (0);
-}
-
-/*
- * __db_curinval
- * Report that a cursor is in an invalid state.
- */
-static int
-__db_curinval(dbenv)
- const DB_ENV *dbenv;
-{
- __db_err(dbenv,
- "Cursor position must be set before performing this operation");
- return (EINVAL);
-}
-
-/*
- * __db_txn_auto_init --
- * Handle DB_AUTO_COMMIT initialization.
- *
- * PUBLIC: int __db_txn_auto_init __P((DB_ENV *, DB_TXN **));
- */
-int
-__db_txn_auto_init(dbenv, txnidp)
- DB_ENV *dbenv;
- DB_TXN **txnidp;
-{
- /*
- * Method calls where applications explicitly specify DB_AUTO_COMMIT
- * require additional validation: the DB_AUTO_COMMIT flag cannot be
- * specified if a transaction cookie is also specified, nor can the
- * flag be specified in a non-transactional environment.
- */
- if (*txnidp != NULL) {
- __db_err(dbenv,
- "DB_AUTO_COMMIT may not be specified along with a transaction handle");
- return (EINVAL);
- }
-
- if (!TXN_ON(dbenv)) {
- __db_err(dbenv,
- "DB_AUTO_COMMIT may not be specified in non-transactional environment");
- return (EINVAL);
- }
-
- /*
- * Our caller checked to see if replication is making a state change.
- * Don't call the user-level API (which would repeat that check).
- */
- return (__txn_begin(dbenv, NULL, txnidp, 0));
-}
-
-/*
- * __db_txn_auto_resolve --
- * Resolve local transactions.
- *
- * PUBLIC: int __db_txn_auto_resolve __P((DB_ENV *, DB_TXN *, int, int));
- */
-int
-__db_txn_auto_resolve(dbenv, txn, nosync, ret)
- DB_ENV *dbenv;
- DB_TXN *txn;
- int nosync, ret;
-{
- int t_ret;
-
- /*
- * We're resolving a transaction for the user, and must decrement the
- * replication handle count. Call the user-level API.
- */
- if (ret == 0)
- return (__txn_commit(txn, nosync ? DB_TXN_NOSYNC : 0));
-
- if ((t_ret = __txn_abort(txn)) != 0)
- return (__db_panic(dbenv, t_ret));
-
- return (ret);
-}
diff --git a/storage/bdb/db/db_join.c b/storage/bdb/db/db_join.c
deleted file mode 100644
index 720891ac07e..00000000000
--- a/storage/bdb/db/db_join.c
+++ /dev/null
@@ -1,942 +0,0 @@
-/*
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1998-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_join.c,v 12.6 2005/10/07 20:21:22 ubell Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_join.h"
-#include "dbinc/btree.h"
-
-static int __db_join_close_pp __P((DBC *));
-static int __db_join_cmp __P((const void *, const void *));
-static int __db_join_del __P((DBC *, u_int32_t));
-static int __db_join_get __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __db_join_get_pp __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __db_join_getnext __P((DBC *, DBT *, DBT *, u_int32_t, u_int32_t));
-static int __db_join_primget __P((DB *,
- DB_TXN *, u_int32_t, DBT *, DBT *, u_int32_t));
-static int __db_join_put __P((DBC *, DBT *, DBT *, u_int32_t));
-
-/*
- * Check to see if the Nth secondary cursor of join cursor jc is pointing
- * to a sorted duplicate set.
- */
-#define SORTED_SET(jc, n) ((jc)->j_curslist[(n)]->dbp->dup_compare != NULL)
-
-/*
- * This is the duplicate-assisted join functionality. Right now we're
- * going to write it such that we return one item at a time, although
- * I think we may need to optimize it to return them all at once.
- * It should be easier to get it working this way, and I believe that
- * changing it should be fairly straightforward.
- *
- * We optimize the join by sorting cursors from smallest to largest
- * cardinality. In most cases, this is indeed optimal. However, if
- * a cursor with large cardinality has very few data in common with the
- * first cursor, it is possible that the join will be made faster by
- * putting it earlier in the cursor list. Since we have no way to detect
- * cases like this, we simply provide a flag, DB_JOIN_NOSORT, which retains
- * the sort order specified by the caller, who may know more about the
- * structure of the data.
- *
- * The first cursor moves sequentially through the duplicate set while
- * the others search explicitly for the duplicate in question.
- *
- */
-
-/*
- * __db_join --
- * This is the interface to the duplicate-assisted join functionality.
- * In the same way that cursors mark a position in a database, a cursor
- * can mark a position in a join. While most cursors are created by the
- * cursor method of a DB, join cursors are created through an explicit
- * call to DB->join.
- *
- * The curslist is an array of existing, initialized cursors and primary
- * is the DB of the primary file. The data item that joins all the
- * cursors in the curslist is used as the key into the primary and that
- * key and data are returned. When no more items are left in the join
- * set, the c_next operation off the join cursor will return DB_NOTFOUND.
- *
- * PUBLIC: int __db_join __P((DB *, DBC **, DBC **, u_int32_t));
- */
-int
-__db_join(primary, curslist, dbcp, flags)
- DB *primary;
- DBC **curslist, **dbcp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DBC *dbc;
- JOIN_CURSOR *jc;
- size_t ncurs, nslots;
- u_int32_t i;
- int ret;
-
- dbenv = primary->dbenv;
- dbc = NULL;
- jc = NULL;
-
- if ((ret = __os_calloc(dbenv, 1, sizeof(DBC), &dbc)) != 0)
- goto err;
-
- if ((ret = __os_calloc(dbenv, 1, sizeof(JOIN_CURSOR), &jc)) != 0)
- goto err;
-
- if ((ret = __os_malloc(dbenv, 256, &jc->j_key.data)) != 0)
- goto err;
- jc->j_key.ulen = 256;
- F_SET(&jc->j_key, DB_DBT_USERMEM);
-
- F_SET(&jc->j_rdata, DB_DBT_REALLOC);
-
- for (jc->j_curslist = curslist;
- *jc->j_curslist != NULL; jc->j_curslist++)
- ;
-
- /*
- * The number of cursor slots we allocate is one greater than
- * the number of cursors involved in the join, because the
- * list is NULL-terminated.
- */
- ncurs = (size_t)(jc->j_curslist - curslist);
- nslots = ncurs + 1;
-
- /*
- * !!! -- A note on the various lists hanging off jc.
- *
- * j_curslist is the initial NULL-terminated list of cursors passed
- * into __db_join. The original cursors are not modified; pristine
- * copies are required because, in databases with unsorted dups, we
- * must reset all of the secondary cursors after the first each
- * time the first one is incremented, or else we will lose data
- * which happen to be sorted differently in two different cursors.
- *
- * j_workcurs is where we put those copies that we're planning to
- * work with. They're lazily c_dup'ed from j_curslist as we need
- * them, and closed when the join cursor is closed or when we need
- * to reset them to their original values (in which case we just
- * c_dup afresh).
- *
- * j_fdupcurs is an array of cursors which point to the first
- * duplicate in the duplicate set that contains the data value
- * we're currently interested in. We need this to make
- * __db_join_get correctly return duplicate duplicates; i.e., if a
- * given data value occurs twice in the set belonging to cursor #2,
- * and thrice in the set belonging to cursor #3, and once in all
- * the other cursors, successive calls to __db_join_get need to
- * return that data item six times. To make this happen, each time
- * cursor N is allowed to advance to a new datum, all cursors M
- * such that M > N have to be reset to the first duplicate with
- * that datum, so __db_join_get will return all the dup-dups again.
- * We could just reset them to the original cursor from j_curslist,
- * but that would be a bit slower in the unsorted case and a LOT
- * slower in the sorted one.
- *
- * j_exhausted is a list of boolean values which represent
- * whether or not their corresponding cursors are "exhausted",
- * i.e. whether the datum under the corresponding cursor has
- * been found not to exist in any unreturned combinations of
- * later secondary cursors, in which case they are ready to be
- * incremented.
- */
-
- /* We don't want to free regions whose callocs have failed. */
- jc->j_curslist = NULL;
- jc->j_workcurs = NULL;
- jc->j_fdupcurs = NULL;
- jc->j_exhausted = NULL;
-
- if ((ret = __os_calloc(dbenv, nslots, sizeof(DBC *),
- &jc->j_curslist)) != 0)
- goto err;
- if ((ret = __os_calloc(dbenv, nslots, sizeof(DBC *),
- &jc->j_workcurs)) != 0)
- goto err;
- if ((ret = __os_calloc(dbenv, nslots, sizeof(DBC *),
- &jc->j_fdupcurs)) != 0)
- goto err;
- if ((ret = __os_calloc(dbenv, nslots, sizeof(u_int8_t),
- &jc->j_exhausted)) != 0)
- goto err;
- for (i = 0; curslist[i] != NULL; i++) {
- jc->j_curslist[i] = curslist[i];
- jc->j_workcurs[i] = NULL;
- jc->j_fdupcurs[i] = NULL;
- jc->j_exhausted[i] = 0;
- }
- jc->j_ncurs = (u_int32_t)ncurs;
-
- /*
- * If DB_JOIN_NOSORT is not set, optimize secondary cursors by
- * sorting in order of increasing cardinality.
- */
- if (!LF_ISSET(DB_JOIN_NOSORT))
- qsort(jc->j_curslist, ncurs, sizeof(DBC *), __db_join_cmp);
-
- /*
- * We never need to reset the 0th cursor, so there's no
- * solid reason to use workcurs[0] rather than curslist[0] in
- * join_get. Nonetheless, it feels cleaner to do it for symmetry,
- * and this is the most logical place to copy it.
- *
- * !!!
- * There's no need to close the new cursor if we goto err only
- * because this is the last thing that can fail. Modifier of this
- * function beware!
- */
- if ((ret =
- __db_c_dup(jc->j_curslist[0], jc->j_workcurs, DB_POSITION)) != 0)
- goto err;
-
- dbc->c_close = __db_join_close_pp;
- dbc->c_del = __db_join_del;
- dbc->c_get = __db_join_get_pp;
- dbc->c_put = __db_join_put;
- dbc->internal = (DBC_INTERNAL *)jc;
- dbc->dbp = primary;
- jc->j_primary = primary;
-
- /* Stash the first cursor's transaction here for easy access. */
- dbc->txn = curslist[0]->txn;
-
- *dbcp = dbc;
-
- MUTEX_LOCK(dbenv, primary->mutex);
- TAILQ_INSERT_TAIL(&primary->join_queue, dbc, links);
- MUTEX_UNLOCK(dbenv, primary->mutex);
-
- return (0);
-
-err: if (jc != NULL) {
- if (jc->j_curslist != NULL)
- __os_free(dbenv, jc->j_curslist);
- if (jc->j_workcurs != NULL) {
- if (jc->j_workcurs[0] != NULL)
- (void)__db_c_close(jc->j_workcurs[0]);
- __os_free(dbenv, jc->j_workcurs);
- }
- if (jc->j_fdupcurs != NULL)
- __os_free(dbenv, jc->j_fdupcurs);
- if (jc->j_exhausted != NULL)
- __os_free(dbenv, jc->j_exhausted);
- __os_free(dbenv, jc);
- }
- if (dbc != NULL)
- __os_free(dbenv, dbc);
- return (ret);
-}
-
-/*
- * __db_join_close_pp --
- * DBC->c_close pre/post processing for join cursors.
- */
-static int
-__db_join_close_pp(dbc)
- DBC *dbc;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- DB *dbp;
- int handle_check, ret, t_ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
-
- ENV_ENTER(dbenv, ip);
-
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check &&
- (ret = __db_rep_enter(dbp, 1, 0, dbc->txn != NULL)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- ret = __db_join_close(dbc);
-
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-static int
-__db_join_put(dbc, key, data, flags)
- DBC *dbc;
- DBT *key;
- DBT *data;
- u_int32_t flags;
-{
- PANIC_CHECK(dbc->dbp->dbenv);
-
- COMPQUIET(key, NULL);
- COMPQUIET(data, NULL);
- COMPQUIET(flags, 0);
- return (EINVAL);
-}
-
-static int
-__db_join_del(dbc, flags)
- DBC *dbc;
- u_int32_t flags;
-{
- PANIC_CHECK(dbc->dbp->dbenv);
-
- COMPQUIET(flags, 0);
- return (EINVAL);
-}
-
-/*
- * __db_join_get_pp --
- * DBjoin->get pre/post processing.
- */
-static int
-__db_join_get_pp(dbc, key, data, flags)
- DBC *dbc;
- DBT *key, *data;
- u_int32_t flags;
-{
- DB *dbp;
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- u_int32_t handle_check, save_flags;
- int ret, t_ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- /* Save the original flags value. */
- save_flags = flags;
-
- PANIC_CHECK(dbenv);
-
- if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW)) {
- if (!LOCKING_ON(dbp->dbenv))
- return (__db_fnl(dbp->dbenv, "DBcursor->c_get"));
- LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW);
- }
-
- switch (flags) {
- case 0:
- case DB_JOIN_ITEM:
- break;
- default:
- return (__db_ferr(dbp->dbenv, "DBcursor->c_get", 0));
- }
-
- /*
- * A partial get of the key of a join cursor don't make much sense;
- * the entire key is necessary to query the primary database
- * and find the datum, and so regardless of the size of the key
- * it would not be a performance improvement. Since it would require
- * special handling, we simply disallow it.
- *
- * A partial get of the data, however, potentially makes sense (if
- * all possible data are a predictable large structure, for instance)
- * and causes us no headaches, so we permit it.
- */
- if (F_ISSET(key, DB_DBT_PARTIAL)) {
- __db_err(dbp->dbenv,
- "DB_DBT_PARTIAL may not be set on key during join_get");
- return (EINVAL);
- }
-
- ENV_ENTER(dbenv, ip);
-
- handle_check = IS_ENV_REPLICATED(dbp->dbenv);
- if (handle_check &&
- (ret = __db_rep_enter(dbp, 1, 0, dbc->txn != NULL)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- /* Restore the original flags value. */
- flags = save_flags;
-
- ret = __db_join_get(dbc, key, data, flags);
-
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-static int
-__db_join_get(dbc, key_arg, data_arg, flags)
- DBC *dbc;
- DBT *key_arg, *data_arg;
- u_int32_t flags;
-{
- DBT *key_n, key_n_mem;
- DB *dbp;
- DBC *cp;
- JOIN_CURSOR *jc;
- int db_manage_data, ret;
- u_int32_t i, j, operation, opmods;
-
- dbp = dbc->dbp;
- jc = (JOIN_CURSOR *)dbc->internal;
-
- operation = LF_ISSET(DB_OPFLAGS_MASK);
-
- /* !!!
- * If the set of flags here changes, check that __db_join_primget
- * is updated to handle them properly.
- */
- opmods = LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW);
-
- /*
- * Since we are fetching the key as a datum in the secondary indices,
- * we must be careful of caller-specified DB_DBT_* memory
- * management flags. If necessary, use a stack-allocated DBT;
- * we'll appropriately copy and/or allocate the data later.
- */
- if (F_ISSET(key_arg, DB_DBT_USERMEM) ||
- F_ISSET(key_arg, DB_DBT_MALLOC)) {
- /* We just use the default buffer; no need to go malloc. */
- key_n = &key_n_mem;
- memset(key_n, 0, sizeof(DBT));
- } else {
- /*
- * Either DB_DBT_REALLOC or the default buffer will work
- * fine if we have to reuse it, as we do.
- */
- key_n = key_arg;
- }
-
- /*
- * If our last attempt to do a get on the primary key failed,
- * short-circuit the join and try again with the same key.
- */
- if (F_ISSET(jc, JOIN_RETRY))
- goto samekey;
- F_CLR(jc, JOIN_RETRY);
-
-retry: ret = __db_c_get(jc->j_workcurs[0], &jc->j_key, key_n,
- opmods | (jc->j_exhausted[0] ? DB_NEXT_DUP : DB_CURRENT));
-
- if (ret == DB_BUFFER_SMALL) {
- jc->j_key.ulen <<= 1;
- if ((ret = __os_realloc(dbp->dbenv,
- jc->j_key.ulen, &jc->j_key.data)) != 0)
- goto mem_err;
- goto retry;
- }
-
- /*
- * If ret == DB_NOTFOUND, we're out of elements of the first
- * secondary cursor. This is how we finally finish the join
- * if all goes well.
- */
- if (ret != 0)
- goto err;
-
- /*
- * If jc->j_exhausted[0] == 1, we've just advanced the first cursor,
- * and we're going to want to advance all the cursors that point to
- * the first member of a duplicate duplicate set (j_fdupcurs[1..N]).
- * Close all the cursors in j_fdupcurs; we'll reopen them the
- * first time through the upcoming loop.
- */
- for (i = 1; i < jc->j_ncurs; i++) {
- if (jc->j_fdupcurs[i] != NULL &&
- (ret = __db_c_close(jc->j_fdupcurs[i])) != 0)
- goto err;
- jc->j_fdupcurs[i] = NULL;
- }
-
- /*
- * If jc->j_curslist[1] == NULL, we have only one cursor in the join.
- * Thus, we can safely increment that one cursor on each call
- * to __db_join_get, and we signal this by setting jc->j_exhausted[0]
- * right away.
- *
- * Otherwise, reset jc->j_exhausted[0] to 0, so that we don't
- * increment it until we know we're ready to.
- */
- if (jc->j_curslist[1] == NULL)
- jc->j_exhausted[0] = 1;
- else
- jc->j_exhausted[0] = 0;
-
- /* We have the first element; now look for it in the other cursors. */
- for (i = 1; i < jc->j_ncurs; i++) {
- DB_ASSERT(jc->j_curslist[i] != NULL);
- if (jc->j_workcurs[i] == NULL)
- /* If this is NULL, we need to dup curslist into it. */
- if ((ret = __db_c_dup(jc->j_curslist[i],
- &jc->j_workcurs[i], DB_POSITION)) != 0)
- goto err;
-
-retry2: cp = jc->j_workcurs[i];
-
- if ((ret = __db_join_getnext(cp, &jc->j_key, key_n,
- jc->j_exhausted[i], opmods)) == DB_NOTFOUND) {
- /*
- * jc->j_workcurs[i] has no more of the datum we're
- * interested in. Go back one cursor and get
- * a new dup. We can't just move to a new
- * element of the outer relation, because that way
- * we might miss duplicate duplicates in cursor i-1.
- *
- * If this takes us back to the first cursor,
- * -then- we can move to a new element of the outer
- * relation.
- */
- --i;
- jc->j_exhausted[i] = 1;
-
- if (i == 0) {
- for (j = 1; jc->j_workcurs[j] != NULL; j++) {
- /*
- * We're moving to a new element of
- * the first secondary cursor. If
- * that cursor is sorted, then any
- * other sorted cursors can be safely
- * reset to the first duplicate
- * duplicate in the current set if we
- * have a pointer to it (we can't just
- * leave them be, or we'll miss
- * duplicate duplicates in the outer
- * relation).
- *
- * If the first cursor is unsorted, or
- * if cursor j is unsorted, we can
- * make no assumptions about what
- * we're looking for next or where it
- * will be, so we reset to the very
- * beginning (setting workcurs NULL
- * will achieve this next go-round).
- *
- * XXX: This is likely to break
- * horribly if any two cursors are
- * both sorted, but have different
- * specified sort functions. For,
- * now, we dismiss this as pathology
- * and let strange things happen--we
- * can't make rope childproof.
- */
- if ((ret = __db_c_close(
- jc->j_workcurs[j])) != 0)
- goto err;
- if (!SORTED_SET(jc, 0) ||
- !SORTED_SET(jc, j) ||
- jc->j_fdupcurs[j] == NULL)
- /*
- * Unsafe conditions;
- * reset fully.
- */
- jc->j_workcurs[j] = NULL;
- else
- /* Partial reset suffices. */
- if ((__db_c_dup(
- jc->j_fdupcurs[j],
- &jc->j_workcurs[j],
- DB_POSITION)) != 0)
- goto err;
- jc->j_exhausted[j] = 0;
- }
- goto retry;
- /* NOTREACHED */
- }
-
- /*
- * We're about to advance the cursor and need to
- * reset all of the workcurs[j] where j>i, so that
- * we don't miss any duplicate duplicates.
- */
- for (j = i + 1;
- jc->j_workcurs[j] != NULL;
- j++) {
- if ((ret =
- __db_c_close(jc->j_workcurs[j])) != 0)
- goto err;
- jc->j_exhausted[j] = 0;
- if (jc->j_fdupcurs[j] == NULL)
- jc->j_workcurs[j] = NULL;
- else if ((ret = __db_c_dup(jc->j_fdupcurs[j],
- &jc->j_workcurs[j], DB_POSITION)) != 0)
- goto err;
- }
- goto retry2;
- /* NOTREACHED */
- }
-
- if (ret == DB_BUFFER_SMALL) {
- jc->j_key.ulen <<= 1;
- if ((ret = __os_realloc(dbp->dbenv, jc->j_key.ulen,
- &jc->j_key.data)) != 0) {
-mem_err: __db_err(dbp->dbenv,
- "Allocation failed for join key, len = %lu",
- (u_long)jc->j_key.ulen);
- goto err;
- }
- goto retry2;
- }
-
- if (ret != 0)
- goto err;
-
- /*
- * If we made it this far, we've found a matching
- * datum in cursor i. Mark the current cursor
- * unexhausted, so we don't miss any duplicate
- * duplicates the next go-round--unless this is the
- * very last cursor, in which case there are none to
- * miss, and we'll need that exhausted flag to finally
- * get a DB_NOTFOUND and move on to the next datum in
- * the outermost cursor.
- */
- if (i + 1 != jc->j_ncurs)
- jc->j_exhausted[i] = 0;
- else
- jc->j_exhausted[i] = 1;
-
- /*
- * If jc->j_fdupcurs[i] is NULL and the ith cursor's dups are
- * sorted, then we're here for the first time since advancing
- * cursor 0, and we have a new datum of interest.
- * jc->j_workcurs[i] points to the beginning of a set of
- * duplicate duplicates; store this into jc->j_fdupcurs[i].
- */
- if (SORTED_SET(jc, i) && jc->j_fdupcurs[i] == NULL && (ret =
- __db_c_dup(cp, &jc->j_fdupcurs[i], DB_POSITION)) != 0)
- goto err;
- }
-
-err: if (ret != 0)
- return (ret);
-
- if (0) {
-samekey: /*
- * Get the key we tried and failed to return last time;
- * it should be the current datum of all the secondary cursors.
- */
- if ((ret = __db_c_get(jc->j_workcurs[0],
- &jc->j_key, key_n, DB_CURRENT | opmods)) != 0)
- return (ret);
- F_CLR(jc, JOIN_RETRY);
- }
-
- /*
- * ret == 0; we have a key to return.
- *
- * If DB_DBT_USERMEM or DB_DBT_MALLOC is set, we need to copy the key
- * back into the dbt we were given for the key; call __db_retcopy.
- * Otherwise, assert that we do not need to copy anything and proceed.
- */
- DB_ASSERT(F_ISSET(
- key_arg, DB_DBT_USERMEM | DB_DBT_MALLOC) || key_n == key_arg);
-
- if (F_ISSET(key_arg, DB_DBT_USERMEM | DB_DBT_MALLOC) &&
- (ret = __db_retcopy(dbp->dbenv,
- key_arg, key_n->data, key_n->size, NULL, NULL)) != 0) {
- /*
- * The retcopy failed, most commonly because we have a user
- * buffer for the key which is too small. Set things up to
- * retry next time, and return.
- */
- F_SET(jc, JOIN_RETRY);
- return (ret);
- }
-
- /*
- * If DB_JOIN_ITEM is set, we return it; otherwise we do the lookup
- * in the primary and then return.
- *
- * Note that we use key_arg here; it is safe (and appropriate)
- * to do so.
- */
- if (operation == DB_JOIN_ITEM)
- return (0);
-
- /*
- * If data_arg->flags == 0--that is, if DB is managing the
- * data DBT's memory--it's not safe to just pass the DBT
- * through to the primary get call, since we don't want that
- * memory to belong to the primary DB handle (and if the primary
- * is free-threaded, it can't anyway).
- *
- * Instead, use memory that is managed by the join cursor, in
- * jc->j_rdata.
- */
- if (!F_ISSET(data_arg, DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERMEM))
- db_manage_data = 1;
- else
- db_manage_data = 0;
- if ((ret = __db_join_primget(jc->j_primary,
- jc->j_curslist[0]->txn, jc->j_curslist[0]->locker, key_arg,
- db_manage_data ? &jc->j_rdata : data_arg, opmods)) != 0) {
- if (ret == DB_NOTFOUND)
- /*
- * If ret == DB_NOTFOUND, the primary and secondary
- * are out of sync; every item in each secondary
- * should correspond to something in the primary,
- * or we shouldn't have done the join this way.
- * Wail.
- */
- ret = __db_secondary_corrupt(jc->j_primary);
- else
- /*
- * The get on the primary failed for some other
- * reason, most commonly because we're using a user
- * buffer that's not big enough. Flag our failure
- * so we can return the same key next time.
- */
- F_SET(jc, JOIN_RETRY);
- }
- if (db_manage_data && ret == 0) {
- data_arg->data = jc->j_rdata.data;
- data_arg->size = jc->j_rdata.size;
- }
-
- return (ret);
-}
-
-/*
- * __db_join_close --
- * DBC->c_close for join cursors.
- *
- * PUBLIC: int __db_join_close __P((DBC *));
- */
-int
-__db_join_close(dbc)
- DBC *dbc;
-{
- DB *dbp;
- DB_ENV *dbenv;
- JOIN_CURSOR *jc;
- int ret, t_ret;
- u_int32_t i;
-
- jc = (JOIN_CURSOR *)dbc->internal;
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
- ret = t_ret = 0;
-
- /*
- * Remove from active list of join cursors. Note that this
- * must happen before any action that can fail and return, or else
- * __db_close may loop indefinitely.
- */
- MUTEX_LOCK(dbenv, dbp->mutex);
- TAILQ_REMOVE(&dbp->join_queue, dbc, links);
- MUTEX_UNLOCK(dbenv, dbp->mutex);
-
- PANIC_CHECK(dbenv);
-
- /*
- * Close any open scratch cursors. In each case, there may
- * not be as many outstanding as there are cursors in
- * curslist, but we want to close whatever's there.
- *
- * If any close fails, there's no reason not to close everything else;
- * we'll just return the error code of the last one to fail. There's
- * not much the caller can do anyway, since these cursors only exist
- * hanging off a db-internal data structure that they shouldn't be
- * mucking with.
- */
- for (i = 0; i < jc->j_ncurs; i++) {
- if (jc->j_workcurs[i] != NULL &&
- (t_ret = __db_c_close(jc->j_workcurs[i])) != 0)
- ret = t_ret;
- if (jc->j_fdupcurs[i] != NULL &&
- (t_ret = __db_c_close(jc->j_fdupcurs[i])) != 0)
- ret = t_ret;
- }
-
- __os_free(dbenv, jc->j_exhausted);
- __os_free(dbenv, jc->j_curslist);
- __os_free(dbenv, jc->j_workcurs);
- __os_free(dbenv, jc->j_fdupcurs);
- __os_free(dbenv, jc->j_key.data);
- if (jc->j_rdata.data != NULL)
- __os_ufree(dbenv, jc->j_rdata.data);
- __os_free(dbenv, jc);
- __os_free(dbenv, dbc);
-
- return (ret);
-}
-
-/*
- * __db_join_getnext --
- * This function replaces the DBC_CONTINUE and DBC_KEYSET
- * functionality inside the various cursor get routines.
- *
- * If exhausted == 0, we're not done with the current datum;
- * return it if it matches "matching", otherwise search
- * using DB_GET_BOTHC (which is faster than iteratively doing
- * DB_NEXT_DUP) forward until we find one that does.
- *
- * If exhausted == 1, we are done with the current datum, so just
- * leap forward to searching NEXT_DUPs.
- *
- * If no matching datum exists, returns DB_NOTFOUND, else 0.
- */
-static int
-__db_join_getnext(dbc, key, data, exhausted, opmods)
- DBC *dbc;
- DBT *key, *data;
- u_int32_t exhausted, opmods;
-{
- int ret, cmp;
- DB *dbp;
- DBT ldata;
- int (*func) __P((DB *, const DBT *, const DBT *));
-
- dbp = dbc->dbp;
- func = (dbp->dup_compare == NULL) ? __bam_defcmp : dbp->dup_compare;
-
- switch (exhausted) {
- case 0:
- /*
- * We don't want to step on data->data; use a new
- * DBT and malloc so we don't step on dbc's rdata memory.
- */
- memset(&ldata, 0, sizeof(DBT));
- F_SET(&ldata, DB_DBT_MALLOC);
- if ((ret = __db_c_get(dbc,
- key, &ldata, opmods | DB_CURRENT)) != 0)
- break;
- cmp = func(dbp, data, &ldata);
- if (cmp == 0) {
- /*
- * We have to return the real data value. Copy
- * it into data, then free the buffer we malloc'ed
- * above.
- */
- if ((ret = __db_retcopy(dbp->dbenv, data, ldata.data,
- ldata.size, &data->data, &data->size)) != 0)
- return (ret);
- __os_ufree(dbp->dbenv, ldata.data);
- return (0);
- }
-
- /*
- * Didn't match--we want to fall through and search future
- * dups. We just forget about ldata and free
- * its buffer--data contains the value we're searching for.
- */
- __os_ufree(dbp->dbenv, ldata.data);
- /* FALLTHROUGH */
- case 1:
- ret = __db_c_get(dbc, key, data, opmods | DB_GET_BOTHC);
- break;
- default:
- ret = EINVAL;
- break;
- }
-
- return (ret);
-}
-
-/*
- * __db_join_cmp --
- * Comparison function for sorting DBCs in cardinality order.
- */
-static int
-__db_join_cmp(a, b)
- const void *a, *b;
-{
- DBC *dbca, *dbcb;
- db_recno_t counta, countb;
-
- dbca = *((DBC * const *)a);
- dbcb = *((DBC * const *)b);
-
- if (__db_c_count(dbca, &counta) != 0 ||
- __db_c_count(dbcb, &countb) != 0)
- return (0);
-
- return ((long)counta - (long)countb);
-}
-
-/*
- * __db_join_primget --
- * Perform a DB->get in the primary, being careful not to use a new
- * locker ID if we're doing CDB locking.
- */
-static int
-__db_join_primget(dbp, txn, lockerid, key, data, flags)
- DB *dbp;
- DB_TXN *txn;
- u_int32_t lockerid;
- DBT *key, *data;
- u_int32_t flags;
-{
- DBC *dbc;
- u_int32_t rmw;
- int ret, t_ret;
-
- if ((ret = __db_cursor_int(dbp,
- txn, dbp->type, PGNO_INVALID, 0, lockerid, &dbc)) != 0)
- return (ret);
-
- /*
- * The only allowable flags here are the two flags copied into "opmods"
- * in __db_join_get, DB_RMW and DB_READ_UNCOMMITTED. The former is an
- * op on the c_get call, the latter on the cursor call. It's a DB bug
- * if we allow any other flags down in here.
- */
- rmw = LF_ISSET(DB_RMW);
- if (LF_ISSET(DB_READ_UNCOMMITTED) ||
- (txn != NULL && F_ISSET(txn, TXN_READ_UNCOMMITTED)))
- F_SET(dbc, DBC_READ_UNCOMMITTED);
-
- if (LF_ISSET(DB_READ_COMMITTED) ||
- (txn != NULL && F_ISSET(txn, TXN_READ_COMMITTED)))
- F_SET(dbc, DBC_READ_COMMITTED);
-
- LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW);
- DB_ASSERT(flags == 0);
-
- F_SET(dbc, DBC_TRANSIENT);
-
- /*
- * This shouldn't be necessary, thanks to the fact that join cursors
- * swap in their own DB_DBT_REALLOC'ed buffers, but just for form's
- * sake, we mirror what __db_get does.
- */
- SET_RET_MEM(dbc, dbp);
-
- ret = __db_c_get(dbc, key, data, DB_SET | rmw);
-
- if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_secondary_corrupt --
- * Report that a secondary index appears corrupt, as it has a record
- * that does not correspond to a record in the primary or vice versa.
- *
- * PUBLIC: int __db_secondary_corrupt __P((DB *));
- */
-int
-__db_secondary_corrupt(dbp)
- DB *dbp;
-{
- __db_err(dbp->dbenv,
- "Secondary index corrupt: not consistent with primary");
- return (DB_SECONDARY_BAD);
-}
diff --git a/storage/bdb/db/db_meta.c b/storage/bdb/db/db_meta.c
deleted file mode 100644
index c1264d38fb1..00000000000
--- a/storage/bdb/db/db_meta.c
+++ /dev/null
@@ -1,1065 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: db_meta.c,v 12.22 2005/10/27 01:46:34 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/lock.h"
-#include "dbinc/mp.h"
-#include "dbinc/db_am.h"
-
-static void __db_init_meta __P((DB *, void *, db_pgno_t, u_int32_t));
-#ifdef HAVE_FTRUNCATE
-static void __db_freelist_sort __P((struct pglist *, u_int32_t));
-static int __db_pglistcmp __P((const void *, const void *));
-static int __db_truncate_freelist __P((DBC *, DBMETA *,
- PAGE *, db_pgno_t *, u_int32_t, u_int32_t));
-#endif
-
-/*
- * __db_init_meta --
- * Helper function for __db_new that initializes the important fields in
- * a meta-data page (used instead of P_INIT). We need to make sure that we
- * retain the page number and LSN of the existing page.
- */
-static void
-__db_init_meta(dbp, p, pgno, pgtype)
- DB *dbp;
- void *p;
- db_pgno_t pgno;
- u_int32_t pgtype;
-{
- DB_LSN save_lsn;
- DBMETA *meta;
-
- meta = (DBMETA *)p;
- save_lsn = meta->lsn;
- memset(meta, 0, sizeof(DBMETA));
- meta->lsn = save_lsn;
- meta->pagesize = dbp->pgsize;
- if (F_ISSET(dbp, DB_AM_CHKSUM))
- FLD_SET(meta->metaflags, DBMETA_CHKSUM);
- meta->pgno = pgno;
- meta->type = (u_int8_t)pgtype;
-}
-
-/*
- * __db_new --
- * Get a new page, preferably from the freelist.
- *
- * PUBLIC: int __db_new __P((DBC *, u_int32_t, PAGE **));
- */
-int
-__db_new(dbc, type, pagepp)
- DBC *dbc;
- u_int32_t type;
- PAGE **pagepp;
-{
- DBMETA *meta;
- DB *dbp;
- DB_LOCK metalock;
- DB_LSN lsn;
- DB_MPOOLFILE *mpf;
- PAGE *h;
- db_pgno_t last, *list, pgno, newnext;
- u_int32_t meta_flags;
- int extend, ret, t_ret;
-
- meta = NULL;
- meta_flags = 0;
- dbp = dbc->dbp;
- mpf = dbp->mpf;
- h = NULL;
- newnext = PGNO_INVALID;
-
- pgno = PGNO_BASE_MD;
- if ((ret = __db_lget(dbc,
- LCK_ALWAYS, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0)
- goto err;
- if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0)
- goto err;
- last = meta->last_pgno;
- if (meta->free == PGNO_INVALID) {
- if (FLD_ISSET(type, P_DONTEXTEND)) {
- *pagepp = NULL;
- goto err;
- }
- last = pgno = meta->last_pgno + 1;
- ZERO_LSN(lsn);
- extend = 1;
- } else {
- pgno = meta->free;
- if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0)
- goto err;
-
- /*
- * We want to take the first page off the free list and
- * then set meta->free to the that page's next_pgno, but
- * we need to log the change first.
- */
- newnext = h->next_pgno;
- lsn = h->lsn;
- extend = 0;
- }
-
- FLD_CLR(type, P_DONTEXTEND);
-
- /*
- * Log the allocation before fetching the new page. If we
- * don't have room in the log then we don't want to tell
- * mpool to extend the file.
- */
- if (DBC_LOGGING(dbc)) {
- if ((ret = __db_pg_alloc_log(dbp, dbc->txn, &LSN(meta), 0,
- &LSN(meta), PGNO_BASE_MD, &lsn,
- pgno, (u_int32_t)type, newnext, meta->last_pgno)) != 0)
- goto err;
- } else
- LSN_NOT_LOGGED(LSN(meta));
-
- meta_flags = DB_MPOOL_DIRTY;
- meta->free = newnext;
-
- if (extend == 1) {
- if ((ret = __memp_fget(mpf, &pgno, DB_MPOOL_NEW, &h)) != 0)
- goto err;
- DB_ASSERT(last == pgno);
- meta->last_pgno = pgno;
- ZERO_LSN(h->lsn);
- h->pgno = pgno;
- }
- LSN(h) = LSN(meta);
-
- DB_ASSERT(TYPE(h) == P_INVALID);
-
- if (TYPE(h) != P_INVALID)
- return (__db_panic(dbp->dbenv, EINVAL));
-
- ret = __memp_fput(mpf, (PAGE *)meta, DB_MPOOL_DIRTY);
- meta = NULL;
- if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0)
- ret = t_ret;
- if (ret != 0)
- goto err;
-
- switch (type) {
- case P_BTREEMETA:
- case P_HASHMETA:
- case P_QAMMETA:
- __db_init_meta(dbp, h, h->pgno, type);
- break;
- default:
- P_INIT(h, dbp->pgsize,
- h->pgno, PGNO_INVALID, PGNO_INVALID, 0, type);
- break;
- }
-
- /* Fix up the sorted free list if necessary. */
-#ifdef HAVE_FTRUNCATE
- if (extend == 0) {
- u_int32_t nelems = 0;
-
- if ((ret = __memp_get_freelist(dbp->mpf, &nelems, &list)) != 0)
- goto err;
- if (nelems != 0) {
- DB_ASSERT(h->pgno == list[0]);
- memmove(list, &list[1], (nelems - 1) * sizeof(*list));
- if ((ret = __memp_extend_freelist(
- dbp->mpf, nelems - 1, &list)) != 0)
- goto err;
- }
- }
-#else
- COMPQUIET(list, NULL);
-#endif
-
- /*
- * If dirty reads are enabled and we are in a transaction, we could
- * abort this allocation after the page(s) pointing to this
- * one have their locks downgraded. This would permit dirty readers
- * to access this page which is ok, but they must be off the
- * page when we abort. We never lock overflow pages or off page
- * duplicate trees.
- */
- if (type != P_OVERFLOW && !F_ISSET(dbc, DBC_OPD) &&
- F_ISSET(dbc->dbp, DB_AM_READ_UNCOMMITTED) && dbc->txn != NULL) {
- if ((ret = __db_lget(dbc, 0,
- h->pgno, DB_LOCK_WWRITE, 0, &metalock)) != 0)
- goto err;
- }
-
- *pagepp = h;
- return (0);
-
-err: if (h != NULL)
- (void)__memp_fput(mpf, h, 0);
- if (meta != NULL)
- (void)__memp_fput(mpf, meta, meta_flags);
- (void)__TLPUT(dbc, metalock);
- return (ret);
-}
-
-/*
- * __db_free --
- * Add a page to the head of the freelist.
- *
- * PUBLIC: int __db_free __P((DBC *, PAGE *));
- */
-int
-__db_free(dbc, h)
- DBC *dbc;
- PAGE *h;
-{
- DBMETA *meta;
- DB *dbp;
- DBT ddbt, ldbt;
- DB_LOCK metalock;
- DB_MPOOLFILE *mpf;
- db_pgno_t last_pgno, *lp, next_pgno, pgno, prev_pgno;
- u_int32_t dirty_flag, lflag, nelem;
- int do_truncate, ret, t_ret;
-#ifdef HAVE_FTRUNCATE
- db_pgno_t *list;
- u_int32_t position, start;
-#endif
-
- dbp = dbc->dbp;
- mpf = dbp->mpf;
- prev_pgno = PGNO_INVALID;
- nelem = 0;
- meta = NULL;
- do_truncate = 0;
- lp = NULL;
-
- /*
- * Retrieve the metadata page. If we are not keeping a sorted
- * free list put the page at the head of the the free list.
- * If we are keeping a sorted free list, for truncation,
- * then figure out where this page belongs and either
- * link it in or truncate the file as much as possible.
- * If either the lock get or page get routines
- * fail, then we need to put the page with which we were called
- * back because our caller assumes we take care of it.
- */
- dirty_flag = 0;
- pgno = PGNO_BASE_MD;
- if ((ret = __db_lget(dbc,
- LCK_ALWAYS, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0)
- goto err;
- if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0)
- goto err1;
-
- last_pgno = meta->last_pgno;
- next_pgno = meta->free;
-
- DB_ASSERT(h->pgno != next_pgno);
-
-#ifdef HAVE_FTRUNCATE
- /*
- * If we are maintaining a sorted free list see if we either have a
- * new truncation point or the page goes somewhere in the middle of
- * the list. If it goes in the middle of the list, we will drop the
- * meta page and get the previous page.
- */
- if ((ret = __memp_get_freelist(mpf, &nelem, &list)) != 0)
- goto err;
- if (list == NULL)
- goto no_sort;
-
- if (h->pgno != last_pgno) {
- /*
- * Put the page number in the sorted list.
- * Finds its position and the previous page,
- * extend the list, make room and insert.
- */
- position = 0;
- if (nelem != 0) {
- __db_freelist_pos(h->pgno, list, nelem, &position);
-
- DB_ASSERT(h->pgno != list[position]);
-
- /* Get the previous page if this is not the smallest. */
- if (position != 0 || h->pgno > list[0])
- prev_pgno = list[position];
- }
-
- /* Put the page number into the list. */
- if ((ret = __memp_extend_freelist(mpf, nelem + 1, &list)) != 0)
- return (ret);
- if (prev_pgno != PGNO_INVALID)
- lp = &list[position + 1];
- else
- lp = list;
- if (nelem != 0 && position != nelem)
- memmove(lp + 1, lp,
- (size_t)((u_int8_t*)&list[nelem] - (u_int8_t*)lp));
- *lp = h->pgno;
- } else if (nelem != 0) {
- /* Find the truncation point. */
- for (lp = &list[nelem - 1]; lp >= list; lp--)
- if (--last_pgno != *lp)
- break;
- if (lp < list || last_pgno < h->pgno - 1)
- do_truncate = 1;
- last_pgno = meta->last_pgno;
- }
-
-no_sort:
- if (prev_pgno != PGNO_INVALID) {
- if ((ret = __memp_fput(mpf, meta, 0)) != 0)
- goto err1;
- meta = NULL;
- pgno = prev_pgno;
- if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0)
- goto err1;
- next_pgno = NEXT_PGNO(meta);
- }
-#endif
-
- /* Log the change. */
- if (DBC_LOGGING(dbc)) {
- memset(&ldbt, 0, sizeof(ldbt));
- ldbt.data = h;
- ldbt.size = P_OVERHEAD(dbp);
- switch (h->type) {
- case P_HASH:
- case P_IBTREE:
- case P_IRECNO:
- case P_LBTREE:
- case P_LRECNO:
- case P_LDUP:
- if (h->entries > 0) {
- ldbt.size += h->entries * sizeof(db_indx_t);
- ddbt.data = (u_int8_t *)h + HOFFSET(h);
- ddbt.size = dbp->pgsize - HOFFSET(h);
- if ((ret = __db_pg_freedata_log(dbp, dbc->txn,
- &LSN(meta), 0, h->pgno, &LSN(meta), pgno,
- &ldbt, next_pgno, last_pgno, &ddbt)) != 0)
- goto err1;
- goto logged;
- }
- break;
- case P_HASHMETA:
- ldbt.size = sizeof(HMETA);
- break;
- case P_BTREEMETA:
- ldbt.size = sizeof(BTMETA);
- break;
- case P_OVERFLOW:
- ldbt.size += OV_LEN(h);
- break;
- default:
- DB_ASSERT(h->type != P_QAMDATA);
- }
-
- /*
- * If we are truncating the file, we need to make sure
- * the logging happens before the truncation. If we
- * are truncating multiple pages we don't need to flush the
- * log here as it will be flushed by __db_truncate_freelist.
- */
- lflag = 0;
-#ifdef HAVE_FTRUNCATE
- if (do_truncate == 0 && h->pgno == last_pgno)
- lflag = DB_FLUSH;
-#endif
- if ((ret = __db_pg_free_log(dbp,
- dbc->txn, &LSN(meta), lflag, h->pgno,
- &LSN(meta), pgno, &ldbt, next_pgno, last_pgno)) != 0)
- goto err1;
- } else
- LSN_NOT_LOGGED(LSN(meta));
-logged: LSN(h) = LSN(meta);
-
-#ifdef HAVE_FTRUNCATE
- if (do_truncate) {
- start = (u_int32_t) (lp - list) + 1;
- meta->last_pgno--;
- ret = __db_truncate_freelist(
- dbc, meta, h, list, start, nelem);
- h = NULL;
- } else if (h->pgno == last_pgno) {
- if ((ret = __memp_fput(mpf, h, DB_MPOOL_DISCARD)) != 0)
- goto err;
- /* Give the page back to the OS. */
- if ((ret = __memp_ftruncate(mpf, last_pgno, 0)) != 0)
- goto err;
- DB_ASSERT(meta->pgno == PGNO_BASE_MD);
- meta->last_pgno--;
- h = NULL;
- } else
-#endif
-
- {
- /*
- * If we are not truncating the page then we
- * reinitialize it and put it at the head of
- * the free list.
- */
- P_INIT(h, dbp->pgsize,
- h->pgno, PGNO_INVALID, next_pgno, 0, P_INVALID);
-#ifdef DIAGNOSTIC
- memset((u_int8_t *) h + P_OVERHEAD(dbp),
- CLEAR_BYTE, dbp->pgsize - P_OVERHEAD(dbp));
-#endif
- if (prev_pgno == PGNO_INVALID)
- meta->free = h->pgno;
- else
- NEXT_PGNO(meta) = h->pgno;
- }
-
- /* Discard the metadata or previous page. */
-err1: if (meta != NULL && (t_ret =
- __memp_fput(mpf, (PAGE *)meta, DB_MPOOL_DIRTY)) != 0 && ret == 0)
- ret = t_ret;
- if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0)
- ret = t_ret;
-
- /* Discard the caller's page reference. */
- dirty_flag = DB_MPOOL_DIRTY;
-err: if (h != NULL &&
- (t_ret = __memp_fput(mpf, h, dirty_flag)) != 0 && ret == 0)
- ret = t_ret;
-
- /*
- * XXX
- * We have to unlock the caller's page in the caller!
- */
- return (ret);
-}
-
-#ifdef HAVE_FTRUNCATE
-/*
- * __db_freelist_pos -- find the position of a page in the freelist.
- * The list is sorted, we do a binary search.
- *
- * PUBLIC: #ifdef HAVE_FTRUNCATE
- * PUBLIC: void __db_freelist_pos __P((db_pgno_t,
- * PUBLIC: db_pgno_t *, u_int32_t, u_int32_t *));
- * PUBLIC: #endif
- */
-void
-__db_freelist_pos(pgno, list, nelem, posp)
- db_pgno_t pgno;
- db_pgno_t *list;
- u_int32_t nelem;
- u_int32_t *posp;
-{
- u_int32_t base, indx, lim;
-
- indx = 0;
- for (base = 0, lim = nelem; lim != 0; lim >>= 1) {
- indx = base + (lim >> 1);
- if (pgno == list[indx]) {
- *posp = indx;
- return;
- }
- if (pgno > list[indx]) {
- base = indx + 1;
- --lim;
- }
- }
- if (base != 0)
- base--;
- *posp = base;
- return;
-}
-
-static int
-__db_pglistcmp(a, b)
- const void *a, *b;
-{
- struct pglist *ap, *bp;
-
- ap = (struct pglist *)a;
- bp = (struct pglist *)b;
-
- return ((ap->pgno > bp->pgno) ? 1 : (ap->pgno < bp->pgno) ? -1: 0);
-}
-
-/*
- * __db_freelist_sort -- sort a list of free pages.
- */
-static void
-__db_freelist_sort(list, nelems)
- struct pglist *list;
- u_int32_t nelems;
-{
- qsort(list, (size_t)nelems, sizeof(struct pglist), __db_pglistcmp);
-}
-
-/*
- * __db_pg_truncate -- sort the freelist and find the truncation point.
- *
- * PUBLIC: #ifdef HAVE_FTRUNCATE
- * PUBLIC: int __db_pg_truncate __P((DB_MPOOLFILE *, struct pglist *list,
- * PUBLIC: DB_COMPACT *, u_int32_t *, db_pgno_t *, DB_LSN *, int));
- * PUBLIC: #endif
- */
-int
-__db_pg_truncate(mpf, list, c_data, nelemp, last_pgno, lsnp, in_recovery)
- DB_MPOOLFILE *mpf;
- struct pglist *list;
- DB_COMPACT *c_data;
- u_int32_t *nelemp;
- db_pgno_t *last_pgno;
- DB_LSN *lsnp;
- int in_recovery;
-{
- PAGE *h;
- struct pglist *lp;
- db_pgno_t pgno;
- u_int32_t nelems;
- int modified, ret;
-
- ret = 0;
-
- nelems = *nelemp;
- /* Sort the list */
- __db_freelist_sort(list, nelems);
-
- /* Find the truncation point. */
- pgno = *last_pgno;
- lp = &list[nelems - 1];
- while (nelems != 0) {
- if (lp->pgno != pgno)
- break;
- pgno--;
- nelems--;
- lp--;
- }
-
- /*
- * Figure out what (if any) pages can be truncated immediately and
- * record the place from which we can truncate, so we can do the
- * memp_ftruncate below. We also use this to avoid ever putting
- * these pages on the freelist, which we are about to relink.
- */
- for (lp = list; lp < &list[nelems]; lp++) {
- if ((ret = __memp_fget(mpf, &lp->pgno, 0, &h)) != 0) {
- /* Page may have been truncated later. */
- if (in_recovery && ret == DB_PAGE_NOTFOUND) {
- ret = 0;
- continue;
- }
- goto err;
- }
- modified = 0;
- if (!in_recovery || log_compare(&LSN(h), &lp->lsn) == 0) {
- if (lp == &list[nelems - 1])
- NEXT_PGNO(h) = PGNO_INVALID;
- else
- NEXT_PGNO(h) = lp[1].pgno;
- DB_ASSERT(NEXT_PGNO(h) < *last_pgno);
-
- LSN(h) = *lsnp;
- modified = 1;
- }
- if ((ret = __memp_fput(mpf, h,
- modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto err;
- }
-
- if (pgno != *last_pgno) {
- if ((ret = __memp_ftruncate(mpf,
- pgno + 1, in_recovery ? MP_TRUNC_RECOVER : 0)) != 0)
- goto err;
- if (c_data)
- c_data->compact_pages_truncated += *last_pgno - pgno;
- *last_pgno = pgno;
- }
- *nelemp = nelems;
-
-err: return (ret);
-}
-
-/*
- * __db_free_truncate --
- * Truncate free pages at the end of the file.
- *
- * PUBLIC: #ifdef HAVE_FTRUNCATE
- * PUBLIC: int __db_free_truncate __P((DB *, DB_TXN *, u_int32_t,
- * PUBLIC: DB_COMPACT *, struct pglist **, u_int32_t *, db_pgno_t *));
- * PUBLIC: #endif
- */
-int
-__db_free_truncate(dbp, txn, flags, c_data, listp, nelemp, last_pgnop)
- DB *dbp;
- DB_TXN *txn;
- u_int32_t flags;
- DB_COMPACT *c_data;
- struct pglist **listp;
- u_int32_t *nelemp;
- db_pgno_t *last_pgnop;
-{
- DBC *dbc;
- DB_ENV *dbenv;
- DBMETA *meta;
- DBT ddbt;
- DB_LOCK metalock;
- DB_LSN null_lsn;
- DB_MPOOLFILE *mpf;
- PAGE *h;
- db_pgno_t pgno;
- u_int32_t nelems;
- struct pglist *list, *lp;
- int ret, t_ret;
- size_t size;
-
- COMPQUIET(flags, 0);
- list = NULL;
- meta = NULL;
- dbenv = dbp->dbenv;
- mpf = dbp->mpf;
- h = NULL;
- nelems = 0;
- if (listp != NULL) {
- *listp = NULL;
- DB_ASSERT(nelemp != NULL);
- *nelemp = 0;
- }
-
- if ((ret = __db_cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0)
- return (ret);
-
- pgno = PGNO_BASE_MD;
- if ((ret = __db_lget(dbc,
- LCK_ALWAYS, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0)
- goto err;
- if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0)
- goto err;
-
- if (last_pgnop != NULL)
- *last_pgnop = meta->last_pgno;
- if ((pgno = meta->free) == PGNO_INVALID)
- goto done;
-
- size = 128;
- if ((ret = __os_malloc(dbenv, size * sizeof(*list), &list)) != 0)
- goto err;
- lp = list;
-
- do {
- if (lp == &list[size]) {
- size *= 2;
- if ((ret = __os_realloc(dbenv,
- size * sizeof(*list), &list)) != 0)
- goto err;
- lp = &list[size / 2];
- }
- if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0)
- goto err;
-
- lp->pgno = pgno;
- lp->lsn = LSN(h);
- pgno = NEXT_PGNO(h);
- if ((ret = __memp_fput(mpf, h, 0)) != 0)
- goto err;
- lp++;
- } while (pgno != PGNO_INVALID);
- nelems = (u_int32_t)(lp - list);
-
- /* Log the current state of the free list */
- if (DBC_LOGGING(dbc)) {
- ddbt.data = list;
- ddbt.size = nelems * sizeof(*lp);
- ZERO_LSN(null_lsn);
- if ((ret = __db_pg_sort_log(dbp,
- dbc->txn, &LSN(meta), DB_FLUSH, PGNO_BASE_MD, &LSN(meta),
- PGNO_INVALID, &null_lsn, meta->last_pgno, &ddbt)) != 0)
- goto err;
- } else
- LSN_NOT_LOGGED(LSN(meta));
-
- if ((ret = __db_pg_truncate(mpf, list, c_data,
- &nelems, &meta->last_pgno, &LSN(meta), 0)) != 0)
- goto err;
-
- if (nelems == 0)
- meta->free = PGNO_INVALID;
- else
- meta->free = list[0].pgno;
-
-done: if (last_pgnop != NULL)
- *last_pgnop = meta->last_pgno;
-
- /*
- * The truncate point is the number of pages in the free
- * list back from the last page. The number of pages
- * in the free list are the number that we can swap in.
- */
- if (c_data)
- c_data->compact_truncate = (u_int32_t)meta->last_pgno - nelems;
-
- if (nelems != 0 && listp != NULL) {
- *listp = list;
- *nelemp = nelems;
- list = NULL;
- }
-
-err: if (list != NULL)
- __os_free(dbenv, list);
- if (meta != NULL && (t_ret =
- __memp_fput(mpf, (PAGE *)meta, DB_MPOOL_DIRTY)) != 0 && ret == 0)
- ret = t_ret;
- if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0)
- ret = t_ret;
- if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
-
-static int
-__db_truncate_freelist(dbc, meta, h, list, start, nelem)
- DBC *dbc;
- DBMETA *meta;
- PAGE *h;
- db_pgno_t *list;
- u_int32_t start, nelem;
-{
- DB *dbp;
- DB_LSN null_lsn;
- DB_MPOOLFILE *mpf;
- DBT ddbt;
- PAGE *last_free, *pg;
- db_pgno_t *lp;
- struct pglist *plist, *pp;
- int ret;
-
- dbp = dbc->dbp;
- mpf = dbp->mpf;
- plist = NULL;
- last_free = NULL;
-
- if (start != 0 &&
- (ret = __memp_fget(mpf, &list[start - 1], 0, &last_free)) != 0)
- goto err;
-
- if (DBC_LOGGING(dbc)) {
- if ((ret = __os_malloc(dbp->dbenv,
- (nelem - start) * sizeof(*pp), &plist)) != 0)
- goto err;
-
- pp = plist;
- for (lp = &list[start]; lp < &list[nelem]; lp++) {
- pp->pgno = *lp;
- if ((ret = __memp_fget(mpf, lp, 0, &pg)) != 0)
- goto err;
- pp->lsn = LSN(pg);
- if ((ret = __memp_fput(mpf, pg, DB_MPOOL_DISCARD)) != 0)
- goto err;
- pp++;
- }
- ddbt.data = plist;
- ddbt.size = (nelem - start) * sizeof(*pp);
- ZERO_LSN(null_lsn);
- if (last_free != NULL) {
- if ((ret = __db_pg_sort_log(dbp, dbc->txn, &LSN(meta),
- DB_FLUSH, PGNO(meta), &LSN(meta), PGNO(last_free),
- &LSN(last_free), meta->last_pgno, &ddbt)) != 0)
- goto err;
- } else if ((ret = __db_pg_sort_log(dbp, dbc->txn,
- &LSN(meta), DB_FLUSH, PGNO(meta), &LSN(meta),
- PGNO_INVALID, &null_lsn, meta->last_pgno, &ddbt)) != 0)
- goto err;
- } else
- LSN_NOT_LOGGED(LSN(meta));
- if (last_free != NULL)
- LSN(last_free) = LSN(meta);
-
- if ((ret = __memp_fput(mpf, h, DB_MPOOL_DISCARD)) != 0)
- goto err;
- h = NULL;
- if ((ret = __memp_ftruncate(mpf, list[start], 0)) != 0)
- goto err;
- meta->last_pgno = list[start] - 1;
-
- if (start == 0)
- meta->free = PGNO_INVALID;
- else {
- NEXT_PGNO(last_free) = PGNO_INVALID;
- if ((ret = __memp_fput(mpf, last_free, DB_MPOOL_DIRTY)) != 0)
- goto err;
- last_free = NULL;
- }
-
- /* Shrink the number of elements in the list. */
- ret = __memp_extend_freelist(mpf, start, &list);
-
-err: if (plist != NULL)
- __os_free(dbp->dbenv, plist);
-
- /* We need to put the page on error. */
- if (h != NULL)
- (void)__memp_fput(mpf, h, 0);
- if (last_free != NULL)
- (void)__memp_fput(mpf, last_free, 0);
-
- return (ret);
-}
-#endif
-
-#ifdef DEBUG
-/*
- * __db_lprint --
- * Print out the list of locks currently held by a cursor.
- *
- * PUBLIC: int __db_lprint __P((DBC *));
- */
-int
-__db_lprint(dbc)
- DBC *dbc;
-{
- DB_ENV *dbenv;
- DB *dbp;
- DB_LOCKREQ req;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
-
- if (LOCKING_ON(dbenv)) {
- req.op = DB_LOCK_DUMP;
- (void)__lock_vec(dbenv, dbc->locker, 0, &req, 1, NULL);
- }
- return (0);
-}
-#endif
-
-/*
- * __db_lget --
- * The standard lock get call.
- *
- * PUBLIC: int __db_lget __P((DBC *,
- * PUBLIC: int, db_pgno_t, db_lockmode_t, u_int32_t, DB_LOCK *));
- */
-int
-__db_lget(dbc, action, pgno, mode, lkflags, lockp)
- DBC *dbc;
- int action;
- db_pgno_t pgno;
- db_lockmode_t mode;
- u_int32_t lkflags;
- DB_LOCK *lockp;
-{
- DB *dbp;
- DB_ENV *dbenv;
- DB_LOCKREQ couple[3], *reqp;
- DB_TXN *txn;
- int has_timeout, i, ret;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
- txn = dbc->txn;
-
- /*
- * We do not always check if we're configured for locking before
- * calling __db_lget to acquire the lock.
- */
- if (CDB_LOCKING(dbenv) ||
- !LOCKING_ON(dbenv) || F_ISSET(dbc, DBC_COMPENSATE) ||
- (F_ISSET(dbc, DBC_RECOVER) &&
- (action != LCK_ROLLBACK || IS_REP_CLIENT(dbenv))) ||
- (action != LCK_ALWAYS && F_ISSET(dbc, DBC_OPD))) {
- LOCK_INIT(*lockp);
- return (0);
- }
-
- dbc->lock.pgno = pgno;
- if (lkflags & DB_LOCK_RECORD)
- dbc->lock.type = DB_RECORD_LOCK;
- else
- dbc->lock.type = DB_PAGE_LOCK;
- lkflags &= ~DB_LOCK_RECORD;
- if (action == LCK_ROLLBACK)
- lkflags |= DB_LOCK_ABORT;
-
- /*
- * If the transaction enclosing this cursor has DB_LOCK_NOWAIT set,
- * pass that along to the lock call.
- */
- if (DB_NONBLOCK(dbc))
- lkflags |= DB_LOCK_NOWAIT;
-
- if (F_ISSET(dbc, DBC_READ_UNCOMMITTED) && mode == DB_LOCK_READ)
- mode = DB_LOCK_READ_UNCOMMITTED;
-
- has_timeout = F_ISSET(dbc, DBC_RECOVER) ||
- (txn != NULL && F_ISSET(txn, TXN_LOCKTIMEOUT));
-
- /*
- * Transactional locking.
- * Hold on to the previous read lock only if we are in full isolation.
- * COUPLE_ALWAYS indicates we are holding an interior node which need
- * not be isolated.
- * Downgrade write locks if we are supporting dirty readers.
- */
- if ((action != LCK_COUPLE && action != LCK_COUPLE_ALWAYS) ||
- !LOCK_ISSET(*lockp))
- action = 0;
- else if (dbc->txn == NULL || action == LCK_COUPLE_ALWAYS)
- action = LCK_COUPLE;
- else if (F_ISSET(dbc,
- DBC_READ_COMMITTED) && lockp->mode == DB_LOCK_READ)
- action = LCK_COUPLE;
- else if (F_ISSET(dbc,
- DBC_READ_UNCOMMITTED) && lockp->mode == DB_LOCK_READ_UNCOMMITTED)
- action = LCK_COUPLE;
- else if (F_ISSET(dbc->dbp,
- DB_AM_READ_UNCOMMITTED) && lockp->mode == DB_LOCK_WRITE)
- action = LCK_DOWNGRADE;
- else
- action = 0;
-
- i = 0;
- switch (action) {
- default:
- if (has_timeout)
- goto couple;
- ret = __lock_get(dbenv,
- dbc->locker, lkflags, &dbc->lock_dbt, mode, lockp);
- break;
-
- case LCK_DOWNGRADE:
- couple[0].op = DB_LOCK_GET;
- couple[0].obj = NULL;
- couple[0].lock = *lockp;
- couple[0].mode = DB_LOCK_WWRITE;
- UMRW_SET(couple[0].timeout);
- i++;
- /* FALLTHROUGH */
- case LCK_COUPLE:
-couple: couple[i].op = has_timeout? DB_LOCK_GET_TIMEOUT : DB_LOCK_GET;
- couple[i].obj = &dbc->lock_dbt;
- couple[i].mode = mode;
- UMRW_SET(couple[i].timeout);
- i++;
- if (has_timeout)
- couple[0].timeout =
- F_ISSET(dbc, DBC_RECOVER) ? 0 : txn->lock_timeout;
- if (action == LCK_COUPLE || action == LCK_DOWNGRADE) {
- couple[i].op = DB_LOCK_PUT;
- couple[i].lock = *lockp;
- i++;
- }
-
- ret = __lock_vec(dbenv,
- dbc->locker, lkflags, couple, i, &reqp);
- if (ret == 0 || reqp == &couple[i - 1])
- *lockp = i == 1 ? couple[0].lock : couple[i - 2].lock;
- break;
- }
-
- if (txn != NULL && ret == DB_LOCK_DEADLOCK)
- F_SET(txn, TXN_DEADLOCK);
- return ((ret == DB_LOCK_NOTGRANTED &&
- !F_ISSET(dbenv, DB_ENV_TIME_NOTGRANTED)) ? DB_LOCK_DEADLOCK : ret);
-}
-
-/*
- * __db_lput --
- * The standard lock put call.
- *
- * PUBLIC: int __db_lput __P((DBC *, DB_LOCK *));
- */
-int
-__db_lput(dbc, lockp)
- DBC *dbc;
- DB_LOCK *lockp;
-{
- DB_ENV *dbenv;
- DB_LOCKREQ couple[2], *reqp;
- int action, ret;
-
- /*
- * Transactional locking.
- * Hold on to the read locks only if we are in full isolation.
- * Downgrade write locks if we are supporting dirty readers.
- */
- if (F_ISSET(dbc->dbp,
- DB_AM_READ_UNCOMMITTED) && lockp->mode == DB_LOCK_WRITE)
- action = LCK_DOWNGRADE;
- else if (dbc->txn == NULL)
- action = LCK_COUPLE;
- else if (F_ISSET(dbc,
- DBC_READ_COMMITTED) && lockp->mode == DB_LOCK_READ)
- action = LCK_COUPLE;
- else if (F_ISSET(dbc,
- DBC_READ_UNCOMMITTED) && lockp->mode == DB_LOCK_READ_UNCOMMITTED)
- action = LCK_COUPLE;
- else
- action = 0;
-
- dbenv = dbc->dbp->dbenv;
- switch (action) {
- case LCK_COUPLE:
- ret = __lock_put(dbenv, lockp);
- break;
- case LCK_DOWNGRADE:
- couple[0].op = DB_LOCK_GET;
- couple[0].obj = NULL;
- couple[0].mode = DB_LOCK_WWRITE;
- couple[0].lock = *lockp;
- UMRW_SET(couple[0].timeout);
- couple[1].op = DB_LOCK_PUT;
- couple[1].lock = *lockp;
- ret = __lock_vec(dbenv, dbc->locker, 0, couple, 2, &reqp);
- if (ret == 0 || reqp == &couple[1])
- *lockp = couple[0].lock;
- break;
- default:
- ret = 0;
- break;
- }
-
- return (ret);
-}
diff --git a/storage/bdb/db/db_method.c b/storage/bdb/db/db_method.c
deleted file mode 100644
index 141392148e7..00000000000
--- a/storage/bdb/db/db_method.c
+++ /dev/null
@@ -1,867 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1999-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_method.c,v 12.15 2005/11/08 03:24:58 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#ifdef HAVE_RPC
-#include
-#endif
-
-#include
-#endif
-
-#ifdef HAVE_RPC
-#include "db_server.h"
-#endif
-
-#include "db_int.h"
-#include "dbinc/crypto.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/btree.h"
-#include "dbinc/hash.h"
-#include "dbinc/lock.h"
-#include "dbinc/mp.h"
-#include "dbinc/qam.h"
-#include "dbinc/txn.h"
-
-#ifdef HAVE_RPC
-#include "dbinc_auto/rpc_client_ext.h"
-#endif
-
-static int __db_get_byteswapped __P((DB *, int *));
-static int __db_get_dbname __P((DB *, const char **, const char **));
-static DB_ENV *__db_get_env __P((DB *));
-static DB_MPOOLFILE *__db_get_mpf __P((DB *));
-static int __db_get_transactional __P((DB *));
-static int __db_get_type __P((DB *, DBTYPE *dbtype));
-static int __db_init __P((DB_ENV *, DB *, u_int32_t));
-static int __db_set_alloc __P((DB *, void *(*)(size_t),
- void *(*)(void *, size_t), void (*)(void *)));
-static int __db_set_append_recno __P((DB *, int (*)(DB *, DBT *, db_recno_t)));
-static int __db_get_cachesize __P((DB *, u_int32_t *, u_int32_t *, int *));
-static int __db_set_cachesize __P((DB *, u_int32_t, u_int32_t, int));
-static int __db_set_dup_compare
- __P((DB *, int (*)(DB *, const DBT *, const DBT *)));
-static int __db_get_encrypt_flags __P((DB *, u_int32_t *));
-static int __db_set_encrypt __P((DB *, const char *, u_int32_t));
-static int __db_set_feedback __P((DB *, void (*)(DB *, int, int)));
-static void __db_map_flags __P((DB *, u_int32_t *, u_int32_t *));
-static int __db_get_pagesize __P((DB *, u_int32_t *));
-static int __db_set_paniccall __P((DB *, void (*)(DB_ENV *, int)));
-static void __db_set_errcall
- __P((DB *, void (*)(const DB_ENV *, const char *, const char *)));
-static void __db_get_errfile __P((DB *, FILE **));
-static void __db_set_errfile __P((DB *, FILE *));
-static void __db_get_errpfx __P((DB *, const char **));
-static void __db_set_errpfx __P((DB *, const char *));
-static void __db_set_msgcall
- __P((DB *, void (*)(const DB_ENV *, const char *)));
-static void __db_get_msgfile __P((DB *, FILE **));
-static void __db_set_msgfile __P((DB *, FILE *));
-static void __dbh_err __P((DB *, int, const char *, ...));
-static void __dbh_errx __P((DB *, const char *, ...));
-
-/*
- * db_create --
- * DB constructor.
- *
- * EXTERN: int db_create __P((DB **, DB_ENV *, u_int32_t));
- */
-int
-db_create(dbpp, dbenv, flags)
- DB **dbpp;
- DB_ENV *dbenv;
- u_int32_t flags;
-{
- DB *dbp;
- DB_THREAD_INFO *ip;
- DB_REP *db_rep;
- int ret;
-
- /* Check for invalid function flags. */
- switch (flags) {
- case 0:
- break;
- case DB_XA_CREATE:
- if (dbenv != NULL) {
- __db_err(dbenv,
- "XA applications may not specify an environment to db_create");
- return (EINVAL);
- }
-
- /*
- * If it's an XA database, open it within the XA environment,
- * taken from the global list of environments. (When the XA
- * transaction manager called our xa_start() routine the
- * "current" environment was moved to the start of the list.
- */
- dbenv = TAILQ_FIRST(&DB_GLOBAL(db_envq));
- break;
- default:
- return (__db_ferr(dbenv, "db_create", 0));
- }
-
- ip = NULL;
- if (dbenv != NULL)
- ENV_ENTER(dbenv, ip);
- /* Allocate the DB. */
- if ((ret = __os_calloc(dbenv, 1, sizeof(*dbp), &dbp)) != 0) {
- if (dbenv != NULL)
- ENV_LEAVE(dbenv, ip);
- return (ret);
- }
-
- if ((ret = __db_init(dbenv, dbp, flags)) != 0)
- goto err;
-
- /* If we don't have an environment yet, allocate a local one. */
- if (dbenv == NULL) {
- if ((ret = db_env_create(&dbenv, 0)) != 0)
- goto err;
- F_SET(dbenv, DB_ENV_DBLOCAL);
- ENV_ENTER(dbenv, ip);
- }
- dbp->dbenv = dbenv;
- MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
- ++dbenv->db_ref;
- MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
-
- /*
- * Set the replication timestamp; it's 0 if we're not in a replicated
- * environment. Don't acquire a lock to read the value, even though
- * it's opaque: all we check later is value equality, nothing else.
- */
- dbp->timestamp = REP_ON(dbenv) ?
- ((REGENV *)((REGINFO *)dbenv->reginfo)->primary)->rep_timestamp : 0;
- /*
- * Set the replication generation number for fid management; valid
- * replication generations start at 1. Don't acquire a lock to
- * read the value. All we check later is value equality.
- */
- db_rep = dbenv->rep_handle;
- dbp->fid_gen =
- (REP_ON(dbenv) && db_rep->region != NULL) ?
- ((REP *)db_rep->region)->gen : 0;
-
- /* If not RPC, open a backing DB_MPOOLFILE handle in the memory pool. */
- if (!RPC_ON(dbenv) &&
- (ret = __memp_fcreate(dbenv, &dbp->mpf)) != 0)
- goto err;
-
- dbp->type = DB_UNKNOWN;
-
- *dbpp = dbp;
- return (0);
-
-err: if (dbp->mpf != NULL)
- (void)__memp_fclose(dbp->mpf, 0);
- if (dbenv != NULL && F_ISSET(dbenv, DB_ENV_DBLOCAL))
- (void)__env_close(dbenv, 0);
- __os_free(dbenv, dbp);
- *dbpp = NULL;
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_init --
- * Initialize a DB structure.
- */
-static int
-__db_init(dbenv, dbp, flags)
- DB_ENV *dbenv;
- DB *dbp;
- u_int32_t flags;
-{
- int ret;
-
- dbp->lid = DB_LOCK_INVALIDID;
- LOCK_INIT(dbp->handle_lock);
-
- TAILQ_INIT(&dbp->free_queue);
- TAILQ_INIT(&dbp->active_queue);
- TAILQ_INIT(&dbp->join_queue);
- LIST_INIT(&dbp->s_secondaries);
-
- FLD_SET(dbp->am_ok,
- DB_OK_BTREE | DB_OK_HASH | DB_OK_QUEUE | DB_OK_RECNO);
-
- /* DB PUBLIC HANDLE LIST BEGIN */
- dbp->associate = __db_associate_pp;
- dbp->close = __db_close_pp;
- dbp->compact = __db_compact_pp;
- dbp->cursor = __db_cursor_pp;
- dbp->del = __db_del_pp;
- dbp->dump = __db_dump_pp;
- dbp->err = __dbh_err;
- dbp->errx = __dbh_errx;
- dbp->fd = __db_fd_pp;
- dbp->get = __db_get_pp;
- dbp->get_byteswapped = __db_get_byteswapped;
- dbp->get_cachesize = __db_get_cachesize;
- dbp->get_dbname = __db_get_dbname;
- dbp->get_encrypt_flags = __db_get_encrypt_flags;
- dbp->get_env = __db_get_env;
- dbp->get_errfile = __db_get_errfile;
- dbp->get_errpfx = __db_get_errpfx;
- dbp->get_flags = __db_get_flags;
- dbp->get_lorder = __db_get_lorder;
- dbp->get_mpf = __db_get_mpf;
- dbp->get_msgfile = __db_get_msgfile;
- dbp->get_open_flags = __db_get_open_flags;
- dbp->get_pagesize = __db_get_pagesize;
- dbp->get_transactional = __db_get_transactional;
- dbp->get_type = __db_get_type;
- dbp->join = __db_join_pp;
- dbp->key_range = __db_key_range_pp;
- dbp->open = __db_open_pp;
- dbp->pget = __db_pget_pp;
- dbp->put = __db_put_pp;
- dbp->remove = __db_remove_pp;
- dbp->rename = __db_rename_pp;
- dbp->set_alloc = __db_set_alloc;
- dbp->set_append_recno = __db_set_append_recno;
- dbp->set_cachesize = __db_set_cachesize;
- dbp->set_dup_compare = __db_set_dup_compare;
- dbp->set_encrypt = __db_set_encrypt;
- dbp->set_errcall = __db_set_errcall;
- dbp->set_errfile = __db_set_errfile;
- dbp->set_errpfx = __db_set_errpfx;
- dbp->set_feedback = __db_set_feedback;
- dbp->set_flags = __db_set_flags;
- dbp->set_lorder = __db_set_lorder;
- dbp->set_msgcall = __db_set_msgcall;
- dbp->set_msgfile = __db_set_msgfile;
- dbp->set_pagesize = __db_set_pagesize;
- dbp->set_paniccall = __db_set_paniccall;
- dbp->stat = __db_stat_pp;
- dbp->stat_print = __db_stat_print_pp;
- dbp->sync = __db_sync_pp;
- dbp->truncate = __db_truncate_pp;
- dbp->upgrade = __db_upgrade_pp;
- dbp->verify = __db_verify_pp;
- /* DB PUBLIC HANDLE LIST END */
-
- /* Access method specific. */
- if ((ret = __bam_db_create(dbp)) != 0)
- return (ret);
- if ((ret = __ham_db_create(dbp)) != 0)
- return (ret);
- if ((ret = __qam_db_create(dbp)) != 0)
- return (ret);
-
- /*
- * XA specific: must be last, as we replace methods set by the
- * access methods.
- */
- if (LF_ISSET(DB_XA_CREATE) && (ret = __db_xa_create(dbp)) != 0)
- return (ret);
-
-#ifdef HAVE_RPC
- /*
- * RPC specific: must be last, as we replace methods set by the
- * access methods.
- */
- if (dbenv != NULL && RPC_ON(dbenv)) {
- __dbcl_dbp_init(dbp);
- /*
- * !!!
- * We wrap the DB->open method for RPC, and the rpc.src file
- * can't handle that.
- */
- dbp->open = __dbcl_db_open_wrap;
- if ((ret = __dbcl_db_create(dbp, dbenv, flags)) != 0)
- return (ret);
- }
-#else
- COMPQUIET(dbenv, NULL);
-#endif
-
- return (0);
-}
-
-/*
- * __dbh_am_chk --
- * Error if an unreasonable method is called.
- *
- * PUBLIC: int __dbh_am_chk __P((DB *, u_int32_t));
- */
-int
-__dbh_am_chk(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- /*
- * We start out allowing any access methods to be called, and as the
- * application calls the methods the options become restricted. The
- * idea is to quit as soon as an illegal method combination is called.
- */
- if ((LF_ISSET(DB_OK_BTREE) && FLD_ISSET(dbp->am_ok, DB_OK_BTREE)) ||
- (LF_ISSET(DB_OK_HASH) && FLD_ISSET(dbp->am_ok, DB_OK_HASH)) ||
- (LF_ISSET(DB_OK_QUEUE) && FLD_ISSET(dbp->am_ok, DB_OK_QUEUE)) ||
- (LF_ISSET(DB_OK_RECNO) && FLD_ISSET(dbp->am_ok, DB_OK_RECNO))) {
- FLD_CLR(dbp->am_ok, ~flags);
- return (0);
- }
-
- __db_err(dbp->dbenv,
- "call implies an access method which is inconsistent with previous calls");
- return (EINVAL);
-}
-
-/*
- * __dbh_err --
- * Error message, including the standard error string.
- */
-static void
-#ifdef STDC_HEADERS
-__dbh_err(DB *dbp, int error, const char *fmt, ...)
-#else
-__dbh_err(dbp, error, fmt, va_alist)
- DB *dbp;
- int error;
- const char *fmt;
- va_dcl
-#endif
-{
- DB_REAL_ERR(dbp->dbenv, error, 1, 1, fmt);
-}
-
-/*
- * __dbh_errx --
- * Error message.
- */
-static void
-#ifdef STDC_HEADERS
-__dbh_errx(DB *dbp, const char *fmt, ...)
-#else
-__dbh_errx(dbp, fmt, va_alist)
- DB *dbp;
- const char *fmt;
- va_dcl
-#endif
-{
- DB_REAL_ERR(dbp->dbenv, 0, 0, 1, fmt);
-}
-
-/*
- * __db_get_byteswapped --
- * Return if database requires byte swapping.
- */
-static int
-__db_get_byteswapped(dbp, isswapped)
- DB *dbp;
- int *isswapped;
-{
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_byteswapped");
-
- *isswapped = F_ISSET(dbp, DB_AM_SWAP) ? 1 : 0;
- return (0);
-}
-
-/*
- * __db_get_dbname --
- * Get the name of the database as passed to DB->open.
- */
-static int
-__db_get_dbname(dbp, fnamep, dnamep)
- DB *dbp;
- const char **fnamep, **dnamep;
-{
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_dbname");
-
- if (fnamep != NULL)
- *fnamep = dbp->fname;
- if (dnamep != NULL)
- *dnamep = dbp->dname;
- return (0);
-}
-
-/*
- * __db_get_env --
- * Get the DB_ENV handle that was passed to db_create.
- */
-static DB_ENV *
-__db_get_env(dbp)
- DB *dbp;
-{
- return (dbp->dbenv);
-}
-
-/*
- * __db_get_mpf --
- * Get the underlying DB_MPOOLFILE handle.
- */
-static DB_MPOOLFILE *
-__db_get_mpf(dbp)
- DB *dbp;
-{
- return (dbp->mpf);
-}
-
-/*
- * get_transactional --
- * Get whether this database was created in a transaction.
- */
-static int
-__db_get_transactional(dbp)
- DB *dbp;
-{
- return (F_ISSET(dbp, DB_AM_TXN) ? 1 : 0);
-}
-
-/*
- * __db_get_type --
- * Return type of underlying database.
- */
-static int
-__db_get_type(dbp, dbtype)
- DB *dbp;
- DBTYPE *dbtype;
-{
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_type");
-
- *dbtype = dbp->type;
- return (0);
-}
-
-/*
- * __db_set_append_recno --
- * Set record number append routine.
- */
-static int
-__db_set_append_recno(dbp, func)
- DB *dbp;
- int (*func) __P((DB *, DBT *, db_recno_t));
-{
- DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_append_recno");
- DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
-
- dbp->db_append_recno = func;
-
- return (0);
-}
-
-/*
- * __db_get_cachesize --
- * Get underlying cache size.
- */
-static int
-__db_get_cachesize(dbp, cache_gbytesp, cache_bytesp, ncachep)
- DB *dbp;
- u_int32_t *cache_gbytesp, *cache_bytesp;
- int *ncachep;
-{
- DB_ILLEGAL_IN_ENV(dbp, "DB->get_cachesize");
-
- return (__memp_get_cachesize(dbp->dbenv,
- cache_gbytesp, cache_bytesp, ncachep));
-}
-
-/*
- * __db_set_cachesize --
- * Set underlying cache size.
- */
-static int
-__db_set_cachesize(dbp, cache_gbytes, cache_bytes, ncache)
- DB *dbp;
- u_int32_t cache_gbytes, cache_bytes;
- int ncache;
-{
- DB_ILLEGAL_IN_ENV(dbp, "DB->set_cachesize");
- DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_cachesize");
-
- return (__memp_set_cachesize(
- dbp->dbenv, cache_gbytes, cache_bytes, ncache));
-}
-
-/*
- * __db_set_dup_compare --
- * Set duplicate comparison routine.
- */
-static int
-__db_set_dup_compare(dbp, func)
- DB *dbp;
- int (*func) __P((DB *, const DBT *, const DBT *));
-{
- int ret;
-
- DB_ILLEGAL_AFTER_OPEN(dbp, "DB->dup_compare");
- DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH);
-
- if ((ret = __db_set_flags(dbp, DB_DUPSORT)) != 0)
- return (ret);
-
- dbp->dup_compare = func;
-
- return (0);
-}
-
-/*
- * __db_get_encrypt_flags --
- */
-static int
-__db_get_encrypt_flags(dbp, flagsp)
- DB *dbp;
- u_int32_t *flagsp;
-{
- DB_ILLEGAL_IN_ENV(dbp, "DB->get_encrypt_flags");
-
- return (__env_get_encrypt_flags(dbp->dbenv, flagsp));
-}
-
-/*
- * __db_set_encrypt --
- * Set database passwd.
- */
-static int
-__db_set_encrypt(dbp, passwd, flags)
- DB *dbp;
- const char *passwd;
- u_int32_t flags;
-{
- DB_CIPHER *db_cipher;
- int ret;
-
- DB_ILLEGAL_IN_ENV(dbp, "DB->set_encrypt");
- DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_encrypt");
-
- if ((ret = __env_set_encrypt(dbp->dbenv, passwd, flags)) != 0)
- return (ret);
-
- /*
- * In a real env, this gets initialized with the region. In a local
- * env, we must do it here.
- */
- db_cipher = (DB_CIPHER *)dbp->dbenv->crypto_handle;
- if (!F_ISSET(db_cipher, CIPHER_ANY) &&
- (ret = db_cipher->init(dbp->dbenv, db_cipher)) != 0)
- return (ret);
-
- return (__db_set_flags(dbp, DB_ENCRYPT));
-}
-
-static void
-__db_set_errcall(dbp, errcall)
- DB *dbp;
- void (*errcall) __P((const DB_ENV *, const char *, const char *));
-{
- __env_set_errcall(dbp->dbenv, errcall);
-}
-
-static void
-__db_get_errfile(dbp, errfilep)
- DB *dbp;
- FILE **errfilep;
-{
- __env_get_errfile(dbp->dbenv, errfilep);
-}
-
-static void
-__db_set_errfile(dbp, errfile)
- DB *dbp;
- FILE *errfile;
-{
- __env_set_errfile(dbp->dbenv, errfile);
-}
-
-static void
-__db_get_errpfx(dbp, errpfxp)
- DB *dbp;
- const char **errpfxp;
-{
- __env_get_errpfx(dbp->dbenv, errpfxp);
-}
-
-static void
-__db_set_errpfx(dbp, errpfx)
- DB *dbp;
- const char *errpfx;
-{
- __env_set_errpfx(dbp->dbenv, errpfx);
-}
-
-static int
-__db_set_feedback(dbp, feedback)
- DB *dbp;
- void (*feedback) __P((DB *, int, int));
-{
- dbp->db_feedback = feedback;
- return (0);
-}
-
-/*
- * __db_map_flags --
- * Maps between public and internal flag values.
- * This function doesn't check for validity, so it can't fail.
- */
-static void
-__db_map_flags(dbp, inflagsp, outflagsp)
- DB *dbp;
- u_int32_t *inflagsp, *outflagsp;
-{
- COMPQUIET(dbp, NULL);
-
- if (FLD_ISSET(*inflagsp, DB_CHKSUM)) {
- FLD_SET(*outflagsp, DB_AM_CHKSUM);
- FLD_CLR(*inflagsp, DB_CHKSUM);
- }
- if (FLD_ISSET(*inflagsp, DB_ENCRYPT)) {
- FLD_SET(*outflagsp, DB_AM_ENCRYPT | DB_AM_CHKSUM);
- FLD_CLR(*inflagsp, DB_ENCRYPT);
- }
- if (FLD_ISSET(*inflagsp, DB_TXN_NOT_DURABLE)) {
- FLD_SET(*outflagsp, DB_AM_NOT_DURABLE);
- FLD_CLR(*inflagsp, DB_TXN_NOT_DURABLE);
- }
-}
-
-/*
- * __db_get_flags --
- * The DB->get_flags method.
- *
- * PUBLIC: int __db_get_flags __P((DB *, u_int32_t *));
- */
-int
-__db_get_flags(dbp, flagsp)
- DB *dbp;
- u_int32_t *flagsp;
-{
- static const u_int32_t db_flags[] = {
- DB_CHKSUM,
- DB_DUP,
- DB_DUPSORT,
- DB_ENCRYPT,
- DB_INORDER,
- DB_RECNUM,
- DB_RENUMBER,
- DB_REVSPLITOFF,
- DB_SNAPSHOT,
- DB_TXN_NOT_DURABLE,
- 0
- };
- u_int32_t f, flags, mapped_flag;
- int i;
-
- flags = 0;
- for (i = 0; (f = db_flags[i]) != 0; i++) {
- mapped_flag = 0;
- __db_map_flags(dbp, &f, &mapped_flag);
- __bam_map_flags(dbp, &f, &mapped_flag);
- __ram_map_flags(dbp, &f, &mapped_flag);
-#ifdef HAVE_QUEUE
- __qam_map_flags(dbp, &f, &mapped_flag);
-#endif
- DB_ASSERT(f == 0);
- if (F_ISSET(dbp, mapped_flag) == mapped_flag)
- LF_SET(db_flags[i]);
- }
-
- *flagsp = flags;
- return (0);
-}
-
-/*
- * __db_set_flags --
- * DB->set_flags.
- *
- * PUBLIC: int __db_set_flags __P((DB *, u_int32_t));
- */
-int
-__db_set_flags(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- int ret;
-
- dbenv = dbp->dbenv;
-
- if (LF_ISSET(DB_ENCRYPT) && !CRYPTO_ON(dbenv)) {
- __db_err(dbenv,
- "Database environment not configured for encryption");
- return (EINVAL);
- }
- if (LF_ISSET(DB_TXN_NOT_DURABLE))
- ENV_REQUIRES_CONFIG(dbenv,
- dbenv->tx_handle, "DB_NOT_DURABLE", DB_INIT_TXN);
-
- __db_map_flags(dbp, &flags, &dbp->flags);
-
- if ((ret = __bam_set_flags(dbp, &flags)) != 0)
- return (ret);
- if ((ret = __ram_set_flags(dbp, &flags)) != 0)
- return (ret);
-#ifdef HAVE_QUEUE
- if ((ret = __qam_set_flags(dbp, &flags)) != 0)
- return (ret);
-#endif
-
- return (flags == 0 ? 0 : __db_ferr(dbenv, "DB->set_flags", 0));
-}
-
-/*
- * __db_get_lorder --
- * Get whether lorder is swapped or not.
- *
- * PUBLIC: int __db_get_lorder __P((DB *, int *));
- */
-int
-__db_get_lorder(dbp, db_lorderp)
- DB *dbp;
- int *db_lorderp;
-{
- int ret;
-
- /* Flag if the specified byte order requires swapping. */
- switch (ret = __db_byteorder(dbp->dbenv, 1234)) {
- case 0:
- *db_lorderp = F_ISSET(dbp, DB_AM_SWAP) ? 4321 : 1234;
- break;
- case DB_SWAPBYTES:
- *db_lorderp = F_ISSET(dbp, DB_AM_SWAP) ? 1234 : 4321;
- break;
- default:
- return (ret);
- /* NOTREACHED */
- }
-
- return (0);
-}
-
-/*
- * __db_set_lorder --
- * Set whether lorder is swapped or not.
- *
- * PUBLIC: int __db_set_lorder __P((DB *, int));
- */
-int
-__db_set_lorder(dbp, db_lorder)
- DB *dbp;
- int db_lorder;
-{
- int ret;
-
- DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_lorder");
-
- /* Flag if the specified byte order requires swapping. */
- switch (ret = __db_byteorder(dbp->dbenv, db_lorder)) {
- case 0:
- F_CLR(dbp, DB_AM_SWAP);
- break;
- case DB_SWAPBYTES:
- F_SET(dbp, DB_AM_SWAP);
- break;
- default:
- return (ret);
- /* NOTREACHED */
- }
- return (0);
-}
-
-static int
-__db_set_alloc(dbp, mal_func, real_func, free_func)
- DB *dbp;
- void *(*mal_func) __P((size_t));
- void *(*real_func) __P((void *, size_t));
- void (*free_func) __P((void *));
-{
- DB_ILLEGAL_IN_ENV(dbp, "DB->set_alloc");
- DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_alloc");
-
- return (__env_set_alloc(dbp->dbenv, mal_func, real_func, free_func));
-}
-
-static void
-__db_set_msgcall(dbp, msgcall)
- DB *dbp;
- void (*msgcall) __P((const DB_ENV *, const char *));
-{
- __env_set_msgcall(dbp->dbenv, msgcall);
-}
-
-static void
-__db_get_msgfile(dbp, msgfilep)
- DB *dbp;
- FILE **msgfilep;
-{
- __env_get_msgfile(dbp->dbenv, msgfilep);
-}
-
-static void
-__db_set_msgfile(dbp, msgfile)
- DB *dbp;
- FILE *msgfile;
-{
- __env_set_msgfile(dbp->dbenv, msgfile);
-}
-
-static int
-__db_get_pagesize(dbp, db_pagesizep)
- DB *dbp;
- u_int32_t *db_pagesizep;
-{
- *db_pagesizep = dbp->pgsize;
- return (0);
-}
-
-/*
- * __db_set_pagesize --
- * DB->set_pagesize
- *
- * PUBLIC: int __db_set_pagesize __P((DB *, u_int32_t));
- */
-int
-__db_set_pagesize(dbp, db_pagesize)
- DB *dbp;
- u_int32_t db_pagesize;
-{
- DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_pagesize");
-
- if (db_pagesize < DB_MIN_PGSIZE) {
- __db_err(dbp->dbenv, "page sizes may not be smaller than %lu",
- (u_long)DB_MIN_PGSIZE);
- return (EINVAL);
- }
- if (db_pagesize > DB_MAX_PGSIZE) {
- __db_err(dbp->dbenv, "page sizes may not be larger than %lu",
- (u_long)DB_MAX_PGSIZE);
- return (EINVAL);
- }
-
- /*
- * We don't want anything that's not a power-of-2, as we rely on that
- * for alignment of various types on the pages.
- */
- if (!POWER_OF_TWO(db_pagesize)) {
- __db_err(dbp->dbenv, "page sizes must be a power-of-2");
- return (EINVAL);
- }
-
- /*
- * XXX
- * Should we be checking for a page size that's not a multiple of 512,
- * so that we never try and write less than a disk sector?
- */
- dbp->pgsize = db_pagesize;
-
- return (0);
-}
-
-static int
-__db_set_paniccall(dbp, paniccall)
- DB *dbp;
- void (*paniccall) __P((DB_ENV *, int));
-{
- return (__env_set_paniccall(dbp->dbenv, paniccall));
-}
diff --git a/storage/bdb/db/db_open.c b/storage/bdb/db/db_open.c
deleted file mode 100644
index a397c92bc53..00000000000
--- a/storage/bdb/db/db_open.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_open.c,v 12.13 2005/10/12 17:45:53 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/db_swap.h"
-#include "dbinc/btree.h"
-#include "dbinc/crypto.h"
-#include "dbinc/hmac.h"
-#include "dbinc/fop.h"
-#include "dbinc/hash.h"
-#include "dbinc/lock.h"
-#include "dbinc/log.h"
-#include "dbinc/mp.h"
-#include "dbinc/qam.h"
-#include "dbinc/txn.h"
-
-/*
- * __db_open --
- * DB->open method.
- *
- * This routine gets called in three different ways:
- *
- * 1. It can be called to open a file/database. In this case, subdb will
- * be NULL and meta_pgno will be PGNO_BASE_MD.
- * 2. It can be called to open a subdatabase during normal operation. In
- * this case, name and subname will both be non-NULL and meta_pgno will
- * be PGNO_BASE_MD (also PGNO_INVALID).
- * 3. It can be called to open an in-memory database (name == NULL;
- * subname = name).
- * 4. It can be called during recovery to open a file/database, in which case
- * name will be non-NULL, subname will be NULL, and meta-pgno will be
- * PGNO_BASE_MD.
- * 5. It can be called during recovery to open a subdatabase, in which case
- * name will be non-NULL, subname may be NULL and meta-pgno will be
- * a valid pgno (i.e., not PGNO_BASE_MD).
- * 6. It can be called during recovery to open an in-memory database.
- *
- * PUBLIC: int __db_open __P((DB *, DB_TXN *,
- * PUBLIC: const char *, const char *, DBTYPE, u_int32_t, int, db_pgno_t));
- */
-int
-__db_open(dbp, txn, fname, dname, type, flags, mode, meta_pgno)
- DB *dbp;
- DB_TXN *txn;
- const char *fname, *dname;
- DBTYPE type;
- u_int32_t flags;
- int mode;
- db_pgno_t meta_pgno;
-{
- DB_ENV *dbenv;
- int ret;
- u_int32_t id;
-
- dbenv = dbp->dbenv;
- id = TXN_INVALID;
-
- DB_TEST_RECOVERY(dbp, DB_TEST_PREOPEN, ret, fname);
-
- /*
- * If the environment was configured with threads, the DB handle
- * must also be free-threaded, so we force the DB_THREAD flag on.
- * (See SR #2033 for why this is a requirement--recovery needs
- * to be able to grab a dbp using __db_fileid_to_dbp, and it has
- * no way of knowing which dbp goes with which thread, so whichever
- * one it finds has to be usable in any of them.)
- */
- if (F_ISSET(dbenv, DB_ENV_THREAD))
- LF_SET(DB_THREAD);
-
- /* Convert any DB->open flags. */
- if (LF_ISSET(DB_RDONLY))
- F_SET(dbp, DB_AM_RDONLY);
- if (LF_ISSET(DB_READ_UNCOMMITTED))
- F_SET(dbp, DB_AM_READ_UNCOMMITTED);
-
- if (txn != NULL)
- F_SET(dbp, DB_AM_TXN);
-
- /* Fill in the type. */
- dbp->type = type;
-
- /*
- * If both fname and subname are NULL, it's always a create, so make
- * sure that we have both DB_CREATE and a type specified. It would
- * be nice if this checking were done in __db_open where most of the
- * interface checking is done, but this interface (__db_dbopen) is
- * used by the recovery and limbo system, so we need to safeguard
- * this interface as well.
- */
- if (fname == NULL) {
- if (dname == NULL) {
- if (!LF_ISSET(DB_CREATE)) {
- __db_err(dbenv,
- "DB_CREATE must be specified to create databases.");
- return (ENOENT);
- }
-
- F_SET(dbp, DB_AM_INMEM);
- F_SET(dbp, DB_AM_CREATED);
-
- if (dbp->type == DB_UNKNOWN) {
- __db_err(dbenv,
- "DBTYPE of unknown without existing file");
- return (EINVAL);
- }
-
- if (dbp->pgsize == 0)
- dbp->pgsize = DB_DEF_IOSIZE;
-
- /*
- * If the file is a temporary file and we're
- * doing locking, then we have to create a
- * unique file ID. We can't use our normal
- * dev/inode pair (or whatever this OS uses
- * in place of dev/inode pairs) because no
- * backing file will be created until the
- * mpool cache is filled forcing the buffers
- * to disk. Grab a random locker ID to use
- * as a file ID. The created ID must never
- * match a potential real file ID -- we know
- * it won't because real file IDs contain a
- * time stamp after the dev/inode pair, and
- * we're simply storing a 4-byte value.
-
- * !!!
- * Store the locker in the file id structure
- * -- we can get it from there as necessary,
- * and it saves having two copies.
- */
- if (LOCKING_ON(dbenv) && (ret = __lock_id(dbenv,
- (u_int32_t *)dbp->fileid, NULL)) != 0)
- return (ret);
- } else
- MAKE_INMEM(dbp);
-
- /*
- * Normally we would do handle locking here, however, with
- * in-memory files, we cannot do any database manipulation
- * until the mpool is open, so it happens later.
- */
- } else if (dname == NULL && meta_pgno == PGNO_BASE_MD) {
- /* Open/create the underlying file. Acquire locks. */
- if ((ret =
- __fop_file_setup(dbp, txn, fname, mode, flags, &id)) != 0)
- return (ret);
- } else {
- if ((ret = __fop_subdb_setup(dbp,
- txn, fname, dname, mode, flags)) != 0)
- return (ret);
- meta_pgno = dbp->meta_pgno;
- }
-
- /*
- * If we created the file, set the truncate flag for the mpool. This
- * isn't for anything we've done, it's protection against stupid user
- * tricks: if the user deleted a file behind Berkeley DB's back, we
- * may still have pages in the mpool that match the file's "unique" ID.
- *
- * Note that if we're opening a subdatabase, we don't want to set
- * the TRUNCATE flag even if we just created the file--we already
- * opened and updated the master using access method interfaces,
- * so we don't want to get rid of any pages that are in the mpool.
- * If we created the file when we opened the master, we already hit
- * this check in a non-subdatabase context then.
- */
- if (dname == NULL && F_ISSET(dbp, DB_AM_CREATED))
- LF_SET(DB_TRUNCATE);
-
- /* Set up the underlying environment. */
- if ((ret = __db_dbenv_setup(dbp, txn, fname, dname, id, flags)) != 0)
- return (ret);
-
- /* For in-memory databases, we now need to open/create the database. */
- if (F_ISSET(dbp, DB_AM_INMEM)) {
- if (dname == NULL)
- ret = __db_new_file(dbp, txn, NULL, NULL);
- else {
- id = TXN_INVALID;
- if ((ret = __fop_file_setup(dbp,
- txn, dname, mode, flags, &id)) == 0 &&
- DBENV_LOGGING(dbenv) && !F_ISSET(dbp, DB_AM_RECOVER)
-#if !defined(DEBUG_ROP)
- && !F_ISSET(dbp, DB_AM_RDONLY)
-#endif
- )
- ret = __dbreg_log_id(dbp,
- txn, dbp->log_filename->id, 1);
- }
- if (ret != 0)
- goto err;
- }
-
- switch (dbp->type) {
- case DB_BTREE:
- ret = __bam_open(dbp, txn, fname, meta_pgno, flags);
- break;
- case DB_HASH:
- ret = __ham_open(dbp, txn, fname, meta_pgno, flags);
- break;
- case DB_RECNO:
- ret = __ram_open(dbp, txn, fname, meta_pgno, flags);
- break;
- case DB_QUEUE:
- ret = __qam_open(
- dbp, txn, fname, meta_pgno, mode, flags);
- break;
- case DB_UNKNOWN:
- return (
- __db_unknown_type(dbenv, "__db_dbopen", dbp->type));
- }
- if (ret != 0)
- goto err;
-
- DB_TEST_RECOVERY(dbp, DB_TEST_POSTOPEN, ret, fname);
-
- /*
- * Temporary files don't need handle locks, so we only have to check
- * for a handle lock downgrade or lockevent in the case of named
- * files.
- */
- if (!F_ISSET(dbp, DB_AM_RECOVER) && (fname != NULL || dname != NULL)
- && LOCK_ISSET(dbp->handle_lock)) {
- if (txn != NULL)
- ret = __txn_lockevent(dbenv,
- txn, dbp, &dbp->handle_lock, dbp->lid);
- else if (LOCKING_ON(dbenv))
- /* Trade write handle lock for read handle lock. */
- ret = __lock_downgrade(dbenv,
- &dbp->handle_lock, DB_LOCK_READ, 0);
- }
-DB_TEST_RECOVERY_LABEL
-err:
- return (ret);
-}
-
-/*
- * __db_get_open_flags --
- * Accessor for flags passed into DB->open call
- *
- * PUBLIC: int __db_get_open_flags __P((DB *, u_int32_t *));
- */
-int
-__db_get_open_flags(dbp, flagsp)
- DB *dbp;
- u_int32_t *flagsp;
-{
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_open_flags");
-
- *flagsp = dbp->open_flags;
- return (0);
-}
-
-/*
- * __db_new_file --
- * Create a new database file.
- *
- * PUBLIC: int __db_new_file __P((DB *, DB_TXN *, DB_FH *, const char *));
- */
-int
-__db_new_file(dbp, txn, fhp, name)
- DB *dbp;
- DB_TXN *txn;
- DB_FH *fhp;
- const char *name;
-{
- int ret;
-
- switch (dbp->type) {
- case DB_BTREE:
- case DB_RECNO:
- ret = __bam_new_file(dbp, txn, fhp, name);
- break;
- case DB_HASH:
- ret = __ham_new_file(dbp, txn, fhp, name);
- break;
- case DB_QUEUE:
- ret = __qam_new_file(dbp, txn, fhp, name);
- break;
- case DB_UNKNOWN:
- default:
- __db_err(dbp->dbenv,
- "%s: Invalid type %d specified", name, dbp->type);
- ret = EINVAL;
- break;
- }
-
- DB_TEST_RECOVERY(dbp, DB_TEST_POSTLOGMETA, ret, name);
- /* Sync the file in preparation for moving it into place. */
- if (ret == 0 && fhp != NULL)
- ret = __os_fsync(dbp->dbenv, fhp);
-
- DB_TEST_RECOVERY(dbp, DB_TEST_POSTSYNC, ret, name);
-
-DB_TEST_RECOVERY_LABEL
- return (ret);
-}
-
-/*
- * __db_init_subdb --
- * Initialize the dbp for a subdb.
- *
- * PUBLIC: int __db_init_subdb __P((DB *, DB *, const char *, DB_TXN *));
- */
-int
-__db_init_subdb(mdbp, dbp, name, txn)
- DB *mdbp, *dbp;
- const char *name;
- DB_TXN *txn;
-{
- DBMETA *meta;
- DB_MPOOLFILE *mpf;
- int ret, t_ret;
-
- ret = 0;
- if (!F_ISSET(dbp, DB_AM_CREATED)) {
- /* Subdb exists; read meta-data page and initialize. */
- mpf = mdbp->mpf;
- if ((ret = __memp_fget(mpf, &dbp->meta_pgno, 0, &meta)) != 0)
- goto err;
- ret = __db_meta_setup(mdbp->dbenv, dbp, name, meta, 0, 0);
- if ((t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0)
- ret = t_ret;
- /*
- * If __db_meta_setup found that the meta-page hadn't
- * been written out during recovery, we can just return.
- */
- if (ret == ENOENT)
- ret = 0;
- goto err;
- }
-
- /* Handle the create case here. */
- switch (dbp->type) {
- case DB_BTREE:
- case DB_RECNO:
- ret = __bam_new_subdb(mdbp, dbp, txn);
- break;
- case DB_HASH:
- ret = __ham_new_subdb(mdbp, dbp, txn);
- break;
- case DB_QUEUE:
- ret = EINVAL;
- break;
- case DB_UNKNOWN:
- default:
- __db_err(dbp->dbenv,
- "Invalid subdatabase type %d specified", dbp->type);
- return (EINVAL);
- }
-
-err: return (ret);
-}
-
-/*
- * __db_chk_meta --
- * Take a buffer containing a meta-data page and check it for a valid LSN,
- * checksum (and verify the checksum if necessary) and possibly decrypt it.
- *
- * Return 0 on success, >0 (errno) on error, -1 on checksum mismatch.
- *
- * PUBLIC: int __db_chk_meta __P((DB_ENV *, DB *, DBMETA *, int));
- */
-int
-__db_chk_meta(dbenv, dbp, meta, do_metachk)
- DB_ENV *dbenv;
- DB *dbp;
- DBMETA *meta;
- int do_metachk;
-{
- DB_LSN cur_lsn, swap_lsn;
- int is_hmac, ret, swapped;
- u_int32_t magic, orig_chk;
- u_int8_t *chksum;
-
- ret = 0;
- swapped = 0;
-
- if (FLD_ISSET(meta->metaflags, DBMETA_CHKSUM)) {
- if (dbp != NULL)
- F_SET(dbp, DB_AM_CHKSUM);
-
- is_hmac = meta->encrypt_alg == 0 ? 0 : 1;
- chksum = ((BTMETA *)meta)->chksum;
-
- /*
- * If we need to swap, the checksum function overwrites the
- * original checksum with 0, so we need to save a copy of the
- * original for swapping later.
- */
- orig_chk = *(u_int32_t *)chksum;
-
- /*
- * We cannot add this to __db_metaswap because that gets done
- * later after we've verified the checksum or decrypted.
- */
- if (do_metachk) {
- swapped = 0;
-chk_retry: if ((ret = __db_check_chksum(dbenv,
- (DB_CIPHER *)dbenv->crypto_handle, chksum, meta,
- DBMETASIZE, is_hmac)) != 0) {
- if (is_hmac || swapped)
- return (ret);
-
- M_32_SWAP(orig_chk);
- swapped = 1;
- *(u_int32_t *)chksum = orig_chk;
- goto chk_retry;
- }
- }
- } else if (dbp != NULL)
- F_CLR(dbp, DB_AM_CHKSUM);
-
-#ifdef HAVE_CRYPTO
- ret = __crypto_decrypt_meta(dbenv, dbp, (u_int8_t *)meta, do_metachk);
-#endif
-
- /* Now that we're decrypted, we can check LSN. */
- if (LOGGING_ON(dbenv)) {
- /*
- * This gets called both before and after swapping, so we
- * need to check ourselves. If we already swapped it above,
- * we'll know that here.
- */
-
- swap_lsn = meta->lsn;
- magic = meta->magic;
-lsn_retry:
- if (swapped) {
- M_32_SWAP(swap_lsn.file);
- M_32_SWAP(swap_lsn.offset);
- M_32_SWAP(magic);
- }
- switch (magic) {
- case DB_BTREEMAGIC:
- case DB_HASHMAGIC:
- case DB_QAMMAGIC:
- case DB_RENAMEMAGIC:
- break;
- default:
- if (swapped)
- return (EINVAL);
- swapped = 1;
- goto lsn_retry;
- }
- if (!IS_REP_CLIENT(dbenv) &&
- !IS_NOT_LOGGED_LSN(swap_lsn) && !IS_ZERO_LSN(swap_lsn)) {
- /* Need to do check. */
- if ((ret = __log_current_lsn(dbenv,
- &cur_lsn, NULL, NULL)) != 0)
- return (ret);
- if (log_compare(&swap_lsn, &cur_lsn) > 0) {
- __db_err(dbenv,
- "file %s (meta pgno = %lu) has LSN [%lu][%lu].",
- dbp->fname == NULL
- ? "unknown" : dbp->fname,
- (u_long)dbp->meta_pgno,
- (u_long)swap_lsn.file,
- (u_long)swap_lsn.offset);
- __db_err(dbenv, "end of log is [%lu][%lu]",
- (u_long)cur_lsn.file,
- (u_long)cur_lsn.offset);
- return (EINVAL);
- }
- }
- }
- return (ret);
-}
-
-/*
- * __db_meta_setup --
- *
- * Take a buffer containing a meta-data page and figure out if it's
- * valid, and if so, initialize the dbp from the meta-data page.
- *
- * PUBLIC: int __db_meta_setup __P((DB_ENV *,
- * PUBLIC: DB *, const char *, DBMETA *, u_int32_t, int));
- */
-int
-__db_meta_setup(dbenv, dbp, name, meta, oflags, do_metachk)
- DB_ENV *dbenv;
- DB *dbp;
- const char *name;
- DBMETA *meta;
- u_int32_t oflags;
- int do_metachk;
-{
- u_int32_t flags, magic;
- int ret;
-
- ret = 0;
-
- /*
- * Figure out what access method we're dealing with, and then
- * call access method specific code to check error conditions
- * based on conflicts between the found file and application
- * arguments. A found file overrides some user information --
- * we don't consider it an error, for example, if the user set
- * an expected byte order and the found file doesn't match it.
- */
- F_CLR(dbp, DB_AM_SWAP | DB_AM_IN_RENAME);
- magic = meta->magic;
-
-swap_retry:
- switch (magic) {
- case DB_BTREEMAGIC:
- case DB_HASHMAGIC:
- case DB_QAMMAGIC:
- case DB_RENAMEMAGIC:
- break;
- case 0:
- /*
- * The only time this should be 0 is if we're in the
- * midst of opening a subdb during recovery and that
- * subdatabase had its meta-data page allocated, but
- * not yet initialized.
- */
- if (F_ISSET(dbp, DB_AM_SUBDB) && ((IS_RECOVERING(dbenv) &&
- F_ISSET((DB_LOG *) dbenv->lg_handle, DBLOG_FORCE_OPEN)) ||
- meta->pgno != PGNO_INVALID))
- return (ENOENT);
-
- goto bad_format;
- default:
- if (F_ISSET(dbp, DB_AM_SWAP))
- goto bad_format;
-
- M_32_SWAP(magic);
- F_SET(dbp, DB_AM_SWAP);
- goto swap_retry;
- }
-
- /*
- * We can only check the meta page if we are sure we have a meta page.
- * If it is random data, then this check can fail. So only now can we
- * checksum and decrypt. Don't distinguish between configuration and
- * checksum match errors here, because we haven't opened the database
- * and even a checksum error isn't a reason to panic the environment.
- */
- if ((ret = __db_chk_meta(dbenv, dbp, meta, do_metachk)) != 0) {
- if (ret == -1)
- __db_err(dbenv,
- "%s: metadata page checksum error", name);
- goto bad_format;
- }
-
- switch (magic) {
- case DB_BTREEMAGIC:
- if (dbp->type != DB_UNKNOWN &&
- dbp->type != DB_RECNO && dbp->type != DB_BTREE)
- goto bad_format;
-
- flags = meta->flags;
- if (F_ISSET(dbp, DB_AM_SWAP))
- M_32_SWAP(flags);
- if (LF_ISSET(BTM_RECNO))
- dbp->type = DB_RECNO;
- else
- dbp->type = DB_BTREE;
- if ((oflags & DB_TRUNCATE) == 0 && (ret =
- __bam_metachk(dbp, name, (BTMETA *)meta)) != 0)
- return (ret);
- break;
- case DB_HASHMAGIC:
- if (dbp->type != DB_UNKNOWN && dbp->type != DB_HASH)
- goto bad_format;
-
- dbp->type = DB_HASH;
- if ((oflags & DB_TRUNCATE) == 0 && (ret =
- __ham_metachk(dbp, name, (HMETA *)meta)) != 0)
- return (ret);
- break;
- case DB_QAMMAGIC:
- if (dbp->type != DB_UNKNOWN && dbp->type != DB_QUEUE)
- goto bad_format;
- dbp->type = DB_QUEUE;
- if ((oflags & DB_TRUNCATE) == 0 && (ret =
- __qam_metachk(dbp, name, (QMETA *)meta)) != 0)
- return (ret);
- break;
- case DB_RENAMEMAGIC:
- F_SET(dbp, DB_AM_IN_RENAME);
-
- /* Copy the file's ID. */
- memcpy(dbp->fileid, ((DBMETA *)meta)->uid, DB_FILE_ID_LEN);
-
- break;
- default:
- goto bad_format;
- }
- return (0);
-
-bad_format:
- if (F_ISSET(dbp, DB_AM_RECOVER))
- ret = ENOENT;
- else
- __db_err(dbenv, "%s: unexpected file type or format", name);
- return (ret == 0 ? EINVAL : ret);
-}
diff --git a/storage/bdb/db/db_overflow.c b/storage/bdb/db/db_overflow.c
deleted file mode 100644
index 818ee91a8b2..00000000000
--- a/storage/bdb/db/db_overflow.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: db_overflow.c,v 12.3 2005/08/08 17:30:51 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/db_am.h"
-#include "dbinc/mp.h"
-
-/*
- * Big key/data code.
- *
- * Big key and data entries are stored on linked lists of pages. The initial
- * reference is a structure with the total length of the item and the page
- * number where it begins. Each entry in the linked list contains a pointer
- * to the next page of data, and so on.
- */
-
-/*
- * __db_goff --
- * Get an offpage item.
- *
- * PUBLIC: int __db_goff __P((DB *, DBT *,
- * PUBLIC: u_int32_t, db_pgno_t, void **, u_int32_t *));
- */
-int
-__db_goff(dbp, dbt, tlen, pgno, bpp, bpsz)
- DB *dbp;
- DBT *dbt;
- u_int32_t tlen;
- db_pgno_t pgno;
- void **bpp;
- u_int32_t *bpsz;
-{
- DB_ENV *dbenv;
- DB_MPOOLFILE *mpf;
- PAGE *h;
- db_indx_t bytes;
- u_int32_t curoff, needed, start;
- u_int8_t *p, *src;
- int ret;
-
- dbenv = dbp->dbenv;
- mpf = dbp->mpf;
-
- /*
- * Check if the buffer is big enough; if it is not and we are
- * allowed to malloc space, then we'll malloc it. If we are
- * not (DB_DBT_USERMEM), then we'll set the dbt and return
- * appropriately.
- */
- if (F_ISSET(dbt, DB_DBT_PARTIAL)) {
- start = dbt->doff;
- if (start > tlen)
- needed = 0;
- else if (dbt->dlen > tlen - start)
- needed = tlen - start;
- else
- needed = dbt->dlen;
- } else {
- start = 0;
- needed = tlen;
- }
-
- /* Allocate any necessary memory. */
- if (F_ISSET(dbt, DB_DBT_USERMEM)) {
- if (needed > dbt->ulen) {
- dbt->size = needed;
- return (DB_BUFFER_SMALL);
- }
- } else if (F_ISSET(dbt, DB_DBT_MALLOC)) {
- if ((ret = __os_umalloc(dbenv, needed, &dbt->data)) != 0)
- return (ret);
- } else if (F_ISSET(dbt, DB_DBT_REALLOC)) {
- if ((ret = __os_urealloc(dbenv, needed, &dbt->data)) != 0)
- return (ret);
- } else if (bpsz != NULL && (*bpsz == 0 || *bpsz < needed)) {
- if ((ret = __os_realloc(dbenv, needed, bpp)) != 0)
- return (ret);
- *bpsz = needed;
- dbt->data = *bpp;
- } else if (bpp != NULL)
- dbt->data = *bpp;
- else {
- DB_ASSERT(
- F_ISSET(dbt,
- DB_DBT_USERMEM | DB_DBT_MALLOC | DB_DBT_REALLOC) ||
- bpsz != NULL || bpp != NULL);
- return (DB_BUFFER_SMALL);
- }
-
- /*
- * Step through the linked list of pages, copying the data on each
- * one into the buffer. Never copy more than the total data length.
- */
- dbt->size = needed;
- for (curoff = 0, p = dbt->data; pgno != PGNO_INVALID && needed > 0;) {
- if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0)
- return (ret);
-
- /* Check if we need any bytes from this page. */
- if (curoff + OV_LEN(h) >= start) {
- src = (u_int8_t *)h + P_OVERHEAD(dbp);
- bytes = OV_LEN(h);
- if (start > curoff) {
- src += start - curoff;
- bytes -= start - curoff;
- }
- if (bytes > needed)
- bytes = needed;
- memcpy(p, src, bytes);
- p += bytes;
- needed -= bytes;
- }
- curoff += OV_LEN(h);
- pgno = h->next_pgno;
- (void)__memp_fput(mpf, h, 0);
- }
- return (0);
-}
-
-/*
- * __db_poff --
- * Put an offpage item.
- *
- * PUBLIC: int __db_poff __P((DBC *, const DBT *, db_pgno_t *));
- */
-int
-__db_poff(dbc, dbt, pgnop)
- DBC *dbc;
- const DBT *dbt;
- db_pgno_t *pgnop;
-{
- DB *dbp;
- DBT tmp_dbt;
- DB_LSN new_lsn, null_lsn;
- DB_MPOOLFILE *mpf;
- PAGE *pagep, *lastp;
- db_indx_t pagespace;
- u_int32_t sz;
- u_int8_t *p;
- int ret, t_ret;
-
- /*
- * Allocate pages and copy the key/data item into them. Calculate the
- * number of bytes we get for pages we fill completely with a single
- * item.
- */
- dbp = dbc->dbp;
- mpf = dbp->mpf;
- pagespace = P_MAXSPACE(dbp, dbp->pgsize);
-
- ret = 0;
- lastp = NULL;
- for (p = dbt->data,
- sz = dbt->size; sz > 0; p += pagespace, sz -= pagespace) {
- /*
- * Reduce pagespace so we terminate the loop correctly and
- * don't copy too much data.
- */
- if (sz < pagespace)
- pagespace = sz;
-
- /*
- * Allocate and initialize a new page and copy all or part of
- * the item onto the page. If sz is less than pagespace, we
- * have a partial record.
- */
- if ((ret = __db_new(dbc, P_OVERFLOW, &pagep)) != 0)
- break;
- if (DBC_LOGGING(dbc)) {
- tmp_dbt.data = p;
- tmp_dbt.size = pagespace;
- ZERO_LSN(null_lsn);
- if ((ret = __db_big_log(dbp, dbc->txn,
- &new_lsn, 0, DB_ADD_BIG, PGNO(pagep),
- lastp ? PGNO(lastp) : PGNO_INVALID,
- PGNO_INVALID, &tmp_dbt, &LSN(pagep),
- lastp == NULL ? &null_lsn : &LSN(lastp),
- &null_lsn)) != 0) {
- if (lastp != NULL)
- (void)__memp_fput(mpf,
- lastp, DB_MPOOL_DIRTY);
- lastp = pagep;
- break;
- }
- } else
- LSN_NOT_LOGGED(new_lsn);
-
- /* Move LSN onto page. */
- if (lastp != NULL)
- LSN(lastp) = new_lsn;
- LSN(pagep) = new_lsn;
-
- OV_LEN(pagep) = pagespace;
- OV_REF(pagep) = 1;
- memcpy((u_int8_t *)pagep + P_OVERHEAD(dbp), p, pagespace);
-
- /*
- * If this is the first entry, update the user's info.
- * Otherwise, update the entry on the last page filled
- * in and release that page.
- */
- if (lastp == NULL)
- *pgnop = PGNO(pagep);
- else {
- lastp->next_pgno = PGNO(pagep);
- pagep->prev_pgno = PGNO(lastp);
- (void)__memp_fput(mpf, lastp, DB_MPOOL_DIRTY);
- }
- lastp = pagep;
- }
- if (lastp != NULL &&
- (t_ret = __memp_fput(mpf, lastp, DB_MPOOL_DIRTY)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
-
-/*
- * __db_ovref --
- * Increment/decrement the reference count on an overflow page.
- *
- * PUBLIC: int __db_ovref __P((DBC *, db_pgno_t, int32_t));
- */
-int
-__db_ovref(dbc, pgno, adjust)
- DBC *dbc;
- db_pgno_t pgno;
- int32_t adjust;
-{
- DB *dbp;
- DB_MPOOLFILE *mpf;
- PAGE *h;
- int ret;
-
- dbp = dbc->dbp;
- mpf = dbp->mpf;
-
- if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0)
- return (ret);
-
- if (DBC_LOGGING(dbc)) {
- if ((ret = __db_ovref_log(dbp,
- dbc->txn, &LSN(h), 0, h->pgno, adjust, &LSN(h))) != 0) {
- (void)__memp_fput(mpf, h, 0);
- return (ret);
- }
- } else
- LSN_NOT_LOGGED(LSN(h));
- OV_REF(h) += adjust;
-
- (void)__memp_fput(mpf, h, DB_MPOOL_DIRTY);
- return (0);
-}
-
-/*
- * __db_doff --
- * Delete an offpage chain of overflow pages.
- *
- * PUBLIC: int __db_doff __P((DBC *, db_pgno_t));
- */
-int
-__db_doff(dbc, pgno)
- DBC *dbc;
- db_pgno_t pgno;
-{
- DB *dbp;
- PAGE *pagep;
- DB_LSN null_lsn;
- DB_MPOOLFILE *mpf;
- DBT tmp_dbt;
- int ret;
-
- dbp = dbc->dbp;
- mpf = dbp->mpf;
-
- do {
- if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0)
- return (ret);
-
- DB_ASSERT(TYPE(pagep) == P_OVERFLOW);
- /*
- * If it's referenced by more than one key/data item,
- * decrement the reference count and return.
- */
- if (OV_REF(pagep) > 1) {
- (void)__memp_fput(mpf, pagep, 0);
- return (__db_ovref(dbc, pgno, -1));
- }
-
- if (DBC_LOGGING(dbc)) {
- tmp_dbt.data = (u_int8_t *)pagep + P_OVERHEAD(dbp);
- tmp_dbt.size = OV_LEN(pagep);
- ZERO_LSN(null_lsn);
- if ((ret = __db_big_log(dbp, dbc->txn,
- &LSN(pagep), 0, DB_REM_BIG,
- PGNO(pagep), PREV_PGNO(pagep),
- NEXT_PGNO(pagep), &tmp_dbt,
- &LSN(pagep), &null_lsn, &null_lsn)) != 0) {
- (void)__memp_fput(mpf, pagep, 0);
- return (ret);
- }
- } else
- LSN_NOT_LOGGED(LSN(pagep));
- pgno = pagep->next_pgno;
- OV_LEN(pagep) = 0;
- if ((ret = __db_free(dbc, pagep)) != 0)
- return (ret);
- } while (pgno != PGNO_INVALID);
-
- return (0);
-}
-
-/*
- * __db_moff --
- * Match on overflow pages.
- *
- * Given a starting page number and a key, return <0, 0, >0 to indicate if the
- * key on the page is less than, equal to or greater than the key specified.
- * We optimize this by doing chunk at a time comparison unless the user has
- * specified a comparison function. In this case, we need to materialize
- * the entire object and call their comparison routine.
- *
- * PUBLIC: int __db_moff __P((DB *, const DBT *, db_pgno_t, u_int32_t,
- * PUBLIC: int (*)(DB *, const DBT *, const DBT *), int *));
- */
-int
-__db_moff(dbp, dbt, pgno, tlen, cmpfunc, cmpp)
- DB *dbp;
- const DBT *dbt;
- db_pgno_t pgno;
- u_int32_t tlen;
- int (*cmpfunc) __P((DB *, const DBT *, const DBT *)), *cmpp;
-{
- DBT local_dbt;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- void *buf;
- u_int32_t bufsize, cmp_bytes, key_left;
- u_int8_t *p1, *p2;
- int ret;
-
- mpf = dbp->mpf;
-
- /*
- * If there is a user-specified comparison function, build a
- * contiguous copy of the key, and call it.
- */
- if (cmpfunc != NULL) {
- memset(&local_dbt, 0, sizeof(local_dbt));
- buf = NULL;
- bufsize = 0;
-
- if ((ret = __db_goff(dbp,
- &local_dbt, tlen, pgno, &buf, &bufsize)) != 0)
- return (ret);
- /* Pass the key as the first argument */
- *cmpp = cmpfunc(dbp, dbt, &local_dbt);
- __os_free(dbp->dbenv, buf);
- return (0);
- }
-
- /* While there are both keys to compare. */
- for (*cmpp = 0, p1 = dbt->data,
- key_left = dbt->size; key_left > 0 && pgno != PGNO_INVALID;) {
- if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0)
- return (ret);
-
- cmp_bytes = OV_LEN(pagep) < key_left ? OV_LEN(pagep) : key_left;
- tlen -= cmp_bytes;
- key_left -= cmp_bytes;
- for (p2 = (u_int8_t *)pagep + P_OVERHEAD(dbp);
- cmp_bytes-- > 0; ++p1, ++p2)
- if (*p1 != *p2) {
- *cmpp = (long)*p1 - (long)*p2;
- break;
- }
- pgno = NEXT_PGNO(pagep);
- if ((ret = __memp_fput(mpf, pagep, 0)) != 0)
- return (ret);
- if (*cmpp != 0)
- return (0);
- }
- if (key_left > 0) /* DBT is longer than the page key. */
- *cmpp = 1;
- else if (tlen > 0) /* DBT is shorter than the page key. */
- *cmpp = -1;
- else
- *cmpp = 0;
-
- return (0);
-}
diff --git a/storage/bdb/db/db_ovfl_vrfy.c b/storage/bdb/db/db_ovfl_vrfy.c
deleted file mode 100644
index ceff4d2569c..00000000000
--- a/storage/bdb/db/db_ovfl_vrfy.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: db_ovfl_vrfy.c,v 12.1 2005/06/16 20:21:13 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/db_am.h"
-#include "dbinc/db_verify.h"
-#include "dbinc/mp.h"
-
-/*
- * __db_vrfy_overflow --
- * Verify overflow page.
- *
- * PUBLIC: int __db_vrfy_overflow __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
- * PUBLIC: u_int32_t));
- */
-int
-__db_vrfy_overflow(dbp, vdp, h, pgno, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- PAGE *h;
- db_pgno_t pgno;
- u_int32_t flags;
-{
- VRFY_PAGEINFO *pip;
- int isbad, ret, t_ret;
-
- isbad = 0;
- if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
- return (ret);
-
- if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) {
- if (ret == DB_VERIFY_BAD)
- isbad = 1;
- else
- goto err;
- }
-
- pip->refcount = OV_REF(h);
- if (pip->refcount < 1) {
- EPRINT((dbp->dbenv,
- "Page %lu: overflow page has zero reference count",
- (u_long)pgno));
- isbad = 1;
- }
-
- /* Just store for now. */
- pip->olen = HOFFSET(h);
-
-err: if ((t_ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0)
- ret = t_ret;
- return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
-}
-
-/*
- * __db_vrfy_ovfl_structure --
- * Walk a list of overflow pages, avoiding cycles and marking
- * pages seen.
- *
- * PUBLIC: int __db_vrfy_ovfl_structure
- * PUBLIC: __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, u_int32_t));
- */
-int
-__db_vrfy_ovfl_structure(dbp, vdp, pgno, tlen, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- db_pgno_t pgno;
- u_int32_t tlen;
- u_int32_t flags;
-{
- DB *pgset;
- VRFY_PAGEINFO *pip;
- db_pgno_t next, prev;
- int isbad, ret, seen_cnt, t_ret;
- u_int32_t refcount;
-
- pgset = vdp->pgset;
- DB_ASSERT(pgset != NULL);
- isbad = 0;
-
- /* This shouldn't happen, but just to be sure. */
- if (!IS_VALID_PGNO(pgno))
- return (DB_VERIFY_BAD);
-
- /*
- * Check the first prev_pgno; it ought to be PGNO_INVALID,
- * since there's no prev page.
- */
- if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
- return (ret);
-
- /* The refcount is stored on the first overflow page. */
- refcount = pip->refcount;
-
- if (pip->type != P_OVERFLOW) {
- EPRINT((dbp->dbenv,
- "Page %lu: overflow page of invalid type %lu",
- (u_long)pgno, (u_long)pip->type));
- ret = DB_VERIFY_BAD;
- goto err; /* Unsafe to continue. */
- }
-
- prev = pip->prev_pgno;
- if (prev != PGNO_INVALID) {
- EPRINT((dbp->dbenv,
- "Page %lu: first page in overflow chain has a prev_pgno %lu",
- (u_long)pgno, (u_long)prev));
- isbad = 1;
- }
-
- for (;;) {
- /*
- * We may have seen this page elsewhere, if the overflow entry
- * has been promoted to an internal page; we just want to
- * make sure that each overflow page is seen exactly as many
- * times as its refcount dictates.
- *
- * Note that this code also serves to keep us from looping
- * infinitely if there's a cycle in an overflow chain.
- */
- if ((ret = __db_vrfy_pgset_get(pgset, pgno, &seen_cnt)) != 0)
- goto err;
- if ((u_int32_t)seen_cnt > refcount) {
- EPRINT((dbp->dbenv,
- "Page %lu: encountered too many times in overflow traversal",
- (u_long)pgno));
- ret = DB_VERIFY_BAD;
- goto err;
- }
- if ((ret = __db_vrfy_pgset_inc(pgset, pgno)) != 0)
- goto err;
-
- /*
- * Each overflow page can be referenced multiple times,
- * because it's possible for overflow Btree keys to get
- * promoted to internal pages. We want to make sure that
- * each page is referenced from a Btree leaf (or Hash data
- * page, which we consider a "leaf" here) exactly once; if
- * the parent was a leaf, set a flag to indicate that we've
- * seen this page in a leaf context.
- *
- * If the parent is not a leaf--in which case it's a Btree
- * internal page--we don't need to bother doing any further
- * verification, as we'll do it when we hit the leaf (or
- * complain that we never saw the leaf). Only the first
- * page in an overflow chain should ever have a refcount
- * greater than 1, and the combination of the LEAFSEEN check
- * and the fact that we bail after the first page for
- * non-leaves should ensure this.
- *
- * Note that each "child" of a page, such as an overflow page,
- * is stored and verified in a structure check exactly once,
- * so this code does not need to contend with the fact that
- * overflow chains used as Btree duplicate keys may be
- * referenced multiply from a single Btree leaf page.
- */
- if (LF_ISSET(ST_OVFL_LEAF)) {
- if (F_ISSET(pip, VRFY_OVFL_LEAFSEEN)) {
- EPRINT((dbp->dbenv,
- "Page %lu: overflow page linked twice from leaf or data page",
- (u_long)pgno));
- ret = DB_VERIFY_BAD;
- goto err;
- }
- F_SET(pip, VRFY_OVFL_LEAFSEEN);
- }
-
- /*
- * We want to verify each overflow chain only once, and
- * although no chain should be linked more than once from a
- * leaf page, we can't guarantee that it'll be linked that
- * once if it's linked from an internal page and the key
- * is gone.
- *
- * seen_cnt is the number of times we'd encountered this page
- * before calling this function.
- */
- if (seen_cnt == 0) {
- /*
- * Keep a running tab on how much of the item we've
- * seen.
- */
- tlen -= pip->olen;
-
- /* Send the application feedback about our progress. */
- if (!LF_ISSET(DB_SALVAGE))
- __db_vrfy_struct_feedback(dbp, vdp);
- } else
- goto done;
-
- next = pip->next_pgno;
-
- /* Are we there yet? */
- if (next == PGNO_INVALID)
- break;
-
- /*
- * We've already checked this when we saved it, but just
- * to be sure...
- */
- if (!IS_VALID_PGNO(next)) {
- DB_ASSERT(0);
- EPRINT((dbp->dbenv,
- "Page %lu: bad next_pgno %lu on overflow page",
- (u_long)pgno, (u_long)next));
- ret = DB_VERIFY_BAD;
- goto err;
- }
-
- if ((ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 ||
- (ret = __db_vrfy_getpageinfo(vdp, next, &pip)) != 0)
- return (ret);
- if (pip->prev_pgno != pgno) {
- EPRINT((dbp->dbenv,
- "Page %lu: bad prev_pgno %lu on overflow page (should be %lu)",
- (u_long)next, (u_long)pip->prev_pgno,
- (u_long)pgno));
- isbad = 1;
- /*
- * It's safe to continue because we have separate
- * cycle detection.
- */
- }
-
- pgno = next;
- }
-
- if (tlen > 0) {
- isbad = 1;
- EPRINT((dbp->dbenv,
- "Page %lu: overflow item incomplete", (u_long)pgno));
- }
-
-done:
-err: if ((t_ret =
- __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0)
- ret = t_ret;
- return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
-}
-
-/*
- * __db_safe_goff --
- * Get an overflow item, very carefully, from an untrusted database,
- * in the context of the salvager.
- *
- * PUBLIC: int __db_safe_goff __P((DB *, VRFY_DBINFO *, db_pgno_t,
- * PUBLIC: DBT *, void *, u_int32_t));
- */
-int
-__db_safe_goff(dbp, vdp, pgno, dbt, buf, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- db_pgno_t pgno;
- DBT *dbt;
- void *buf;
- u_int32_t flags;
-{
- DB_MPOOLFILE *mpf;
- PAGE *h;
- int ret, t_ret;
- u_int32_t bytesgot, bytes;
- u_int8_t *src, *dest;
-
- mpf = dbp->mpf;
- h = NULL;
- ret = t_ret = 0;
- bytesgot = bytes = 0;
-
- while ((pgno != PGNO_INVALID) && (IS_VALID_PGNO(pgno))) {
- /*
- * Mark that we're looking at this page; if we've seen it
- * already, quit.
- */
- if ((ret = __db_salvage_markdone(vdp, pgno)) != 0)
- break;
-
- if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0)
- break;
-
- /*
- * Make sure it's really an overflow page, unless we're
- * being aggressive, in which case we pretend it is.
- */
- if (!LF_ISSET(DB_AGGRESSIVE) && TYPE(h) != P_OVERFLOW) {
- ret = DB_VERIFY_BAD;
- break;
- }
-
- src = (u_int8_t *)h + P_OVERHEAD(dbp);
- bytes = OV_LEN(h);
-
- if (bytes + P_OVERHEAD(dbp) > dbp->pgsize)
- bytes = dbp->pgsize - P_OVERHEAD(dbp);
-
- if ((ret = __os_realloc(dbp->dbenv,
- bytesgot + bytes, buf)) != 0)
- break;
-
- dest = *(u_int8_t **)buf + bytesgot;
- bytesgot += bytes;
-
- memcpy(dest, src, bytes);
-
- pgno = NEXT_PGNO(h);
-
- if ((ret = __memp_fput(mpf, h, 0)) != 0)
- break;
- h = NULL;
- }
-
- /*
- * If we're being aggressive, salvage a partial datum if there
- * was an error somewhere along the way.
- */
- if (ret == 0 || LF_ISSET(DB_AGGRESSIVE)) {
- dbt->size = bytesgot;
- dbt->data = *(void **)buf;
- }
-
- /* If we broke out on error, don't leave pages pinned. */
- if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
diff --git a/storage/bdb/db/db_pr.c b/storage/bdb/db/db_pr.c
deleted file mode 100644
index 4618d4f4754..00000000000
--- a/storage/bdb/db/db_pr.c
+++ /dev/null
@@ -1,1614 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_pr.c,v 12.17 2005/11/08 03:13:30 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#include
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/btree.h"
-#include "dbinc/hash.h"
-#include "dbinc/mp.h"
-#include "dbinc/qam.h"
-#include "dbinc/db_verify.h"
-
-/*
- * __db_loadme --
- * A nice place to put a breakpoint.
- *
- * PUBLIC: void __db_loadme __P((void));
- */
-void
-__db_loadme()
-{
- pid_t pid;
- db_threadid_t tid;
-
- __os_id(NULL, &pid, &tid);
-}
-
-#ifdef HAVE_STATISTICS
-static int __db_bmeta __P((DB *, BTMETA *, u_int32_t));
-static int __db_hmeta __P((DB *, HMETA *, u_int32_t));
-static void __db_meta __P((DB *, DBMETA *, FN const *, u_int32_t));
-static const char *__db_pagetype_to_string __P((u_int32_t));
-static void __db_prdb __P((DB *, u_int32_t));
-static void __db_proff __P((DB_ENV *, DB_MSGBUF *, void *));
-static int __db_prtree __P((DB *, u_int32_t));
-static int __db_qmeta __P((DB *, QMETA *, u_int32_t));
-
-/*
- * __db_dumptree --
- * Dump the tree to a file.
- *
- * PUBLIC: int __db_dumptree __P((DB *, char *, char *));
- */
-int
-__db_dumptree(dbp, op, name)
- DB *dbp;
- char *op, *name;
-{
- DB_ENV *dbenv;
- FILE *fp, *orig_fp;
- u_int32_t flags;
- int ret;
-
- dbenv = dbp->dbenv;
-
- for (flags = 0; *op != '\0'; ++op)
- switch (*op) {
- case 'a':
- LF_SET(DB_PR_PAGE);
- break;
- case 'h':
- break;
- case 'r':
- LF_SET(DB_PR_RECOVERYTEST);
- break;
- default:
- return (EINVAL);
- }
-
- if (name != NULL) {
- if ((fp = fopen(name, "w")) == NULL)
- return (__os_get_errno());
-
- orig_fp = dbenv->db_msgfile;
- dbenv->db_msgfile = fp;
- } else
- fp = orig_fp = NULL;
-
- __db_prdb(dbp, flags);
-
- __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
-
- ret = __db_prtree(dbp, flags);
-
- if (fp != NULL) {
- (void)fclose(fp);
- dbenv->db_msgfile = orig_fp;
- }
-
- return (ret);
-}
-
-static const FN __db_flags_fn[] = {
- { DB_AM_CHKSUM, "checksumming" },
- { DB_AM_CL_WRITER, "client replica writer" },
- { DB_AM_COMPENSATE, "created by compensating transaction" },
- { DB_AM_CREATED, "database created" },
- { DB_AM_CREATED_MSTR, "encompassing file created" },
- { DB_AM_DBM_ERROR, "dbm/ndbm error" },
- { DB_AM_DELIMITER, "variable length" },
- { DB_AM_DISCARD, "discard cached pages" },
- { DB_AM_DUP, "duplicates" },
- { DB_AM_DUPSORT, "sorted duplicates" },
- { DB_AM_ENCRYPT, "encrypted" },
- { DB_AM_FIXEDLEN, "fixed-length records" },
- { DB_AM_INMEM, "in-memory" },
- { DB_AM_IN_RENAME, "file is being renamed" },
- { DB_AM_NOT_DURABLE, "changes not logged" },
- { DB_AM_OPEN_CALLED, "open called" },
- { DB_AM_PAD, "pad value" },
- { DB_AM_PGDEF, "default page size" },
- { DB_AM_RDONLY, "read-only" },
- { DB_AM_READ_UNCOMMITTED, "read-uncommitted" },
- { DB_AM_RECNUM, "Btree record numbers" },
- { DB_AM_RECOVER, "opened for recovery" },
- { DB_AM_RENUMBER, "renumber" },
- { DB_AM_REVSPLITOFF, "no reverse splits" },
- { DB_AM_SECONDARY, "secondary" },
- { DB_AM_SNAPSHOT, "load on open" },
- { DB_AM_SUBDB, "subdatabases" },
- { DB_AM_SWAP, "needswap" },
- { DB_AM_TXN, "transactional" },
- { DB_AM_VERIFYING, "verifier" },
- { 0, NULL }
-};
-
-/*
- * __db_get_flags_fn --
- * Return the __db_flags_fn array.
- *
- * PUBLIC: const FN * __db_get_flags_fn __P((void));
- */
-const FN *
-__db_get_flags_fn()
-{
- return (__db_flags_fn);
-}
-
-/*
- * __db_prdb --
- * Print out the DB structure information.
- */
-static void
-__db_prdb(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DB_MSGBUF mb;
- DB_ENV *dbenv;
- BTREE *bt;
- HASH *h;
- QUEUE *q;
-
- dbenv = dbp->dbenv;
-
- DB_MSGBUF_INIT(&mb);
- __db_msg(dbenv, "In-memory DB structure:");
- __db_msgadd(dbenv, &mb, "%s: %#lx",
- __db_dbtype_to_string(dbp->type), (u_long)dbp->flags);
- __db_prflags(dbenv, &mb, dbp->flags, __db_flags_fn, " (", ")");
- DB_MSGBUF_FLUSH(dbenv, &mb);
-
- switch (dbp->type) {
- case DB_BTREE:
- case DB_RECNO:
- bt = dbp->bt_internal;
- __db_msg(dbenv, "bt_meta: %lu bt_root: %lu",
- (u_long)bt->bt_meta, (u_long)bt->bt_root);
- __db_msg(dbenv, "bt_minkey: %lu", (u_long)bt->bt_minkey);
- if (!LF_ISSET(DB_PR_RECOVERYTEST))
- __db_msg(dbenv, "bt_compare: %#lx bt_prefix: %#lx",
- P_TO_ULONG(bt->bt_compare),
- P_TO_ULONG(bt->bt_prefix));
- __db_msg(dbenv, "bt_lpgno: %lu", (u_long)bt->bt_lpgno);
- if (dbp->type == DB_RECNO) {
- __db_msg(dbenv,
- "re_pad: %#lx re_delim: %#lx re_len: %lu re_source: %s",
- (u_long)bt->re_pad, (u_long)bt->re_delim,
- (u_long)bt->re_len,
- bt->re_source == NULL ? "" : bt->re_source);
- __db_msg(dbenv,
- "re_modified: %d re_eof: %d re_last: %lu",
- bt->re_modified, bt->re_eof, (u_long)bt->re_last);
- }
- break;
- case DB_HASH:
- h = dbp->h_internal;
- __db_msg(dbenv, "meta_pgno: %lu", (u_long)h->meta_pgno);
- __db_msg(dbenv, "h_ffactor: %lu", (u_long)h->h_ffactor);
- __db_msg(dbenv, "h_nelem: %lu", (u_long)h->h_nelem);
- if (!LF_ISSET(DB_PR_RECOVERYTEST))
- __db_msg(dbenv, "h_hash: %#lx", P_TO_ULONG(h->h_hash));
- break;
- case DB_QUEUE:
- q = dbp->q_internal;
- __db_msg(dbenv, "q_meta: %lu", (u_long)q->q_meta);
- __db_msg(dbenv, "q_root: %lu", (u_long)q->q_root);
- __db_msg(dbenv, "re_pad: %#lx re_len: %lu",
- (u_long)q->re_pad, (u_long)q->re_len);
- __db_msg(dbenv, "rec_page: %lu", (u_long)q->rec_page);
- __db_msg(dbenv, "page_ext: %lu", (u_long)q->page_ext);
- break;
- case DB_UNKNOWN:
- default:
- break;
- }
-}
-
-/*
- * __db_prtree --
- * Print out the entire tree.
- */
-static int
-__db_prtree(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DB_MPOOLFILE *mpf;
- PAGE *h;
- db_pgno_t i, last;
- int ret;
-
- mpf = dbp->mpf;
-
- if (dbp->type == DB_QUEUE)
- return (__db_prqueue(dbp, flags));
-
- /*
- * Find out the page number of the last page in the database, then
- * dump each page.
- */
- if ((ret = __memp_last_pgno(mpf, &last)) != 0)
- return (ret);
- for (i = 0; i <= last; ++i) {
- if ((ret = __memp_fget(mpf, &i, 0, &h)) != 0)
- return (ret);
- (void)__db_prpage(dbp, h, flags);
- if ((ret = __memp_fput(mpf, h, 0)) != 0)
- return (ret);
- }
-
- return (0);
-}
-
-/*
- * __db_meta --
- * Print out common metadata information.
- */
-static void
-__db_meta(dbp, dbmeta, fn, flags)
- DB *dbp;
- DBMETA *dbmeta;
- FN const *fn;
- u_int32_t flags;
-{
- DB_MSGBUF mb;
- DB_ENV *dbenv;
- DB_MPOOLFILE *mpf;
- PAGE *h;
- db_pgno_t pgno;
- u_int8_t *p;
- int cnt, ret;
- const char *sep;
-
- dbenv = dbp->dbenv;
- mpf = dbp->mpf;
- DB_MSGBUF_INIT(&mb);
-
- __db_msg(dbenv, "\tmagic: %#lx", (u_long)dbmeta->magic);
- __db_msg(dbenv, "\tversion: %lu", (u_long)dbmeta->version);
- __db_msg(dbenv, "\tpagesize: %lu", (u_long)dbmeta->pagesize);
- __db_msg(dbenv, "\ttype: %lu", (u_long)dbmeta->type);
- __db_msg(dbenv, "\tkeys: %lu\trecords: %lu",
- (u_long)dbmeta->key_count, (u_long)dbmeta->record_count);
-
- /*
- * If we're doing recovery testing, don't display the free list,
- * it may have changed and that makes the dump diff not work.
- */
- if (!LF_ISSET(DB_PR_RECOVERYTEST)) {
- __db_msgadd(
- dbenv, &mb, "\tfree list: %lu", (u_long)dbmeta->free);
- for (pgno = dbmeta->free,
- cnt = 0, sep = ", "; pgno != PGNO_INVALID;) {
- if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) {
- DB_MSGBUF_FLUSH(dbenv, &mb);
- __db_msg(dbenv,
- "Unable to retrieve free-list page: %lu: %s",
- (u_long)pgno, db_strerror(ret));
- break;
- }
- pgno = h->next_pgno;
- (void)__memp_fput(mpf, h, 0);
- __db_msgadd(dbenv, &mb, "%s%lu", sep, (u_long)pgno);
- if (++cnt % 10 == 0) {
- DB_MSGBUF_FLUSH(dbenv, &mb);
- cnt = 0;
- sep = "\t";
- } else
- sep = ", ";
- }
- DB_MSGBUF_FLUSH(dbenv, &mb);
- __db_msg(dbenv, "\tlast_pgno: %lu", (u_long)dbmeta->last_pgno);
- }
-
- if (fn != NULL) {
- DB_MSGBUF_FLUSH(dbenv, &mb);
- __db_msgadd(dbenv, &mb, "\tflags: %#lx", (u_long)dbmeta->flags);
- __db_prflags(dbenv, &mb, dbmeta->flags, fn, " (", ")");
- }
-
- DB_MSGBUF_FLUSH(dbenv, &mb);
- __db_msgadd(dbenv, &mb, "\tuid: ");
- for (p = (u_int8_t *)dbmeta->uid,
- cnt = 0; cnt < DB_FILE_ID_LEN; ++cnt) {
- __db_msgadd(dbenv, &mb, "%x", *p++);
- if (cnt < DB_FILE_ID_LEN - 1)
- __db_msgadd(dbenv, &mb, " ");
- }
- DB_MSGBUF_FLUSH(dbenv, &mb);
-}
-
-/*
- * __db_bmeta --
- * Print out the btree meta-data page.
- */
-static int
-__db_bmeta(dbp, h, flags)
- DB *dbp;
- BTMETA *h;
- u_int32_t flags;
-{
- static const FN fn[] = {
- { BTM_DUP, "duplicates" },
- { BTM_RECNO, "recno" },
- { BTM_RECNUM, "btree:recnum" },
- { BTM_FIXEDLEN, "recno:fixed-length" },
- { BTM_RENUMBER, "recno:renumber" },
- { BTM_SUBDB, "multiple-databases" },
- { BTM_DUPSORT, "sorted duplicates" },
- { 0, NULL }
- };
- DB_ENV *dbenv;
-
- dbenv = dbp->dbenv;
-
- __db_meta(dbp, (DBMETA *)h, fn, flags);
-
- __db_msg(dbenv, "\tminkey: %lu", (u_long)h->minkey);
- if (dbp->type == DB_RECNO)
- __db_msg(dbenv, "\tre_len: %#lx re_pad: %#lx",
- (u_long)h->re_len, (u_long)h->re_pad);
- __db_msg(dbenv, "\troot: %lu", (u_long)h->root);
-
- return (0);
-}
-
-/*
- * __db_hmeta --
- * Print out the hash meta-data page.
- */
-static int
-__db_hmeta(dbp, h, flags)
- DB *dbp;
- HMETA *h;
- u_int32_t flags;
-{
- DB_MSGBUF mb;
- static const FN fn[] = {
- { DB_HASH_DUP, "duplicates" },
- { DB_HASH_SUBDB, "multiple-databases" },
- { DB_HASH_DUPSORT, "sorted duplicates" },
- { 0, NULL }
- };
- DB_ENV *dbenv;
- int i;
-
- dbenv = dbp->dbenv;
- DB_MSGBUF_INIT(&mb);
-
- __db_meta(dbp, (DBMETA *)h, fn, flags);
-
- __db_msg(dbenv, "\tmax_bucket: %lu", (u_long)h->max_bucket);
- __db_msg(dbenv, "\thigh_mask: %#lx", (u_long)h->high_mask);
- __db_msg(dbenv, "\tlow_mask: %#lx", (u_long)h->low_mask);
- __db_msg(dbenv, "\tffactor: %lu", (u_long)h->ffactor);
- __db_msg(dbenv, "\tnelem: %lu", (u_long)h->nelem);
- __db_msg(dbenv, "\th_charkey: %#lx", (u_long)h->h_charkey);
- __db_msgadd(dbenv, &mb, "\tspare points: ");
- for (i = 0; i < NCACHED; i++)
- __db_msgadd(dbenv, &mb, "%lu ", (u_long)h->spares[i]);
- DB_MSGBUF_FLUSH(dbenv, &mb);
-
- return (0);
-}
-
-/*
- * __db_qmeta --
- * Print out the queue meta-data page.
- */
-static int
-__db_qmeta(dbp, h, flags)
- DB *dbp;
- QMETA *h;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
-
- dbenv = dbp->dbenv;
-
- __db_meta(dbp, (DBMETA *)h, NULL, flags);
-
- __db_msg(dbenv, "\tfirst_recno: %lu", (u_long)h->first_recno);
- __db_msg(dbenv, "\tcur_recno: %lu", (u_long)h->cur_recno);
- __db_msg(dbenv, "\tre_len: %#lx re_pad: %lu",
- (u_long)h->re_len, (u_long)h->re_pad);
- __db_msg(dbenv, "\trec_page: %lu", (u_long)h->rec_page);
- __db_msg(dbenv, "\tpage_ext: %lu", (u_long)h->page_ext);
-
- return (0);
-}
-
-/*
- * __db_prnpage
- * -- Print out a specific page.
- *
- * PUBLIC: int __db_prnpage __P((DB *, db_pgno_t));
- */
-int
-__db_prnpage(dbp, pgno)
- DB *dbp;
- db_pgno_t pgno;
-{
- DB_MPOOLFILE *mpf;
- PAGE *h;
- int ret, t_ret;
-
- mpf = dbp->mpf;
-
- if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0)
- return (ret);
-
- ret = __db_prpage(dbp, h, DB_PR_PAGE);
-
- if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_prpage
- * -- Print out a page.
- *
- * PUBLIC: int __db_prpage __P((DB *, PAGE *, u_int32_t));
- */
-int
-__db_prpage(dbp, h, flags)
- DB *dbp;
- PAGE *h;
- u_int32_t flags;
-{
- BINTERNAL *bi;
- BKEYDATA *bk;
- DB_ENV *dbenv;
- DB_MSGBUF mb;
- HOFFPAGE a_hkd;
- QAMDATA *qp, *qep;
- RINTERNAL *ri;
- db_indx_t dlen, len, i, *inp;
- db_pgno_t pgno;
- db_recno_t recno;
- u_int32_t pagesize, qlen;
- u_int8_t *ep, *hk, *p;
- int deleted, ret;
- const char *s;
- void *sp;
-
- dbenv = dbp->dbenv;
- DB_MSGBUF_INIT(&mb);
-
- /*
- * If we're doing recovery testing and this page is P_INVALID,
- * assume it's a page that's on the free list, and don't display it.
- */
- if (LF_ISSET(DB_PR_RECOVERYTEST) && TYPE(h) == P_INVALID)
- return (0);
-
- if ((s = __db_pagetype_to_string(TYPE(h))) == NULL) {
- __db_msg(dbenv, "ILLEGAL PAGE TYPE: page: %lu type: %lu",
- (u_long)h->pgno, (u_long)TYPE(h));
- return (1);
- }
-
- /*
- * !!!
- * Find out the page size. We don't want to do it the "right" way,
- * by reading the value from the meta-data page, that's going to be
- * slow. Reach down into the mpool region.
- */
- pagesize = (u_int32_t)dbp->mpf->mfp->stat.st_pagesize;
-
- /* Page number, page type. */
- __db_msgadd(dbenv, &mb, "page %lu: %s:", (u_long)h->pgno, s);
-
- /*
- * LSNs on a metadata page will be different from the original after an
- * abort, in some cases. Don't display them if we're testing recovery.
- */
- if (!LF_ISSET(DB_PR_RECOVERYTEST) ||
- (TYPE(h) != P_BTREEMETA && TYPE(h) != P_HASHMETA &&
- TYPE(h) != P_QAMMETA && TYPE(h) != P_QAMDATA))
- __db_msgadd(dbenv, &mb, " LSN [%lu][%lu]:",
- (u_long)LSN(h).file, (u_long)LSN(h).offset);
-
- /*
- * Page level (only applicable for Btree/Recno, but we always display
- * it, for no particular reason.
- */
- __db_msgadd(dbenv, &mb, " level %lu", (u_long)h->level);
-
- /* Record count. */
- if (TYPE(h) == P_IBTREE ||
- TYPE(h) == P_IRECNO || (TYPE(h) == P_LRECNO &&
- h->pgno == ((BTREE *)dbp->bt_internal)->bt_root))
- __db_msgadd(dbenv, &mb, " records: %lu", (u_long)RE_NREC(h));
- DB_MSGBUF_FLUSH(dbenv, &mb);
-
- switch (TYPE(h)) {
- case P_BTREEMETA:
- return (__db_bmeta(dbp, (BTMETA *)h, flags));
- case P_HASHMETA:
- return (__db_hmeta(dbp, (HMETA *)h, flags));
- case P_QAMMETA:
- return (__db_qmeta(dbp, (QMETA *)h, flags));
- case P_QAMDATA: /* Should be meta->start. */
- if (!LF_ISSET(DB_PR_PAGE))
- return (0);
-
- qlen = ((QUEUE *)dbp->q_internal)->re_len;
- recno = (h->pgno - 1) * QAM_RECNO_PER_PAGE(dbp) + 1;
- i = 0;
- qep = (QAMDATA *)((u_int8_t *)h + pagesize - qlen);
- for (qp = QAM_GET_RECORD(dbp, h, i); qp < qep;
- recno++, i++, qp = QAM_GET_RECORD(dbp, h, i)) {
- if (!F_ISSET(qp, QAM_SET))
- continue;
-
- __db_msgadd(dbenv, &mb, "%s",
- F_ISSET(qp, QAM_VALID) ? "\t" : " D");
- __db_msgadd(dbenv, &mb, "[%03lu] %4lu ", (u_long)recno,
- (u_long)((u_int8_t *)qp - (u_int8_t *)h));
- __db_pr(dbenv, &mb, qp->data, qlen);
- }
- return (0);
- default:
- break;
- }
-
- s = "\t";
- if (TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO) {
- __db_msgadd(dbenv, &mb, "%sprev: %4lu next: %4lu",
- s, (u_long)PREV_PGNO(h), (u_long)NEXT_PGNO(h));
- s = " ";
- }
- if (TYPE(h) == P_OVERFLOW) {
- __db_msgadd(dbenv, &mb,
- "%sref cnt: %4lu ", s, (u_long)OV_REF(h));
- __db_pr(dbenv, &mb, (u_int8_t *)h + P_OVERHEAD(dbp), OV_LEN(h));
- return (0);
- }
- __db_msgadd(dbenv, &mb, "%sentries: %4lu", s, (u_long)NUM_ENT(h));
- __db_msgadd(dbenv, &mb, " offset: %4lu", (u_long)HOFFSET(h));
- DB_MSGBUF_FLUSH(dbenv, &mb);
-
- if (TYPE(h) == P_INVALID || !LF_ISSET(DB_PR_PAGE))
- return (0);
-
- ret = 0;
- inp = P_INP(dbp, h);
- for (i = 0; i < NUM_ENT(h); i++) {
- if ((uintptr_t)(P_ENTRY(dbp, h, i) - (u_int8_t *)h) <
- (uintptr_t)(P_OVERHEAD(dbp)) ||
- (size_t)(P_ENTRY(dbp, h, i) - (u_int8_t *)h) >= pagesize) {
- __db_msg(dbenv,
- "ILLEGAL PAGE OFFSET: indx: %lu of %lu",
- (u_long)i, (u_long)inp[i]);
- ret = EINVAL;
- continue;
- }
- deleted = 0;
- switch (TYPE(h)) {
- case P_HASH:
- case P_IBTREE:
- case P_IRECNO:
- sp = P_ENTRY(dbp, h, i);
- break;
- case P_LBTREE:
- sp = P_ENTRY(dbp, h, i);
- deleted = i % 2 == 0 &&
- B_DISSET(GET_BKEYDATA(dbp, h, i + O_INDX)->type);
- break;
- case P_LDUP:
- case P_LRECNO:
- sp = P_ENTRY(dbp, h, i);
- deleted = B_DISSET(GET_BKEYDATA(dbp, h, i)->type);
- break;
- default:
- goto type_err;
- }
- __db_msgadd(dbenv, &mb, "%s", deleted ? " D" : "\t");
- __db_msgadd(
- dbenv, &mb, "[%03lu] %4lu ", (u_long)i, (u_long)inp[i]);
- switch (TYPE(h)) {
- case P_HASH:
- hk = sp;
- switch (HPAGE_PTYPE(hk)) {
- case H_OFFDUP:
- memcpy(&pgno,
- HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
- __db_msgadd(dbenv, &mb,
- "%4lu [offpage dups]", (u_long)pgno);
- DB_MSGBUF_FLUSH(dbenv, &mb);
- break;
- case H_DUPLICATE:
- /*
- * If this is the first item on a page, then
- * we cannot figure out how long it is, so
- * we only print the first one in the duplicate
- * set.
- */
- if (i != 0)
- len = LEN_HKEYDATA(dbp, h, 0, i);
- else
- len = 1;
-
- __db_msgadd(dbenv, &mb, "Duplicates:");
- DB_MSGBUF_FLUSH(dbenv, &mb);
- for (p = HKEYDATA_DATA(hk),
- ep = p + len; p < ep;) {
- memcpy(&dlen, p, sizeof(db_indx_t));
- p += sizeof(db_indx_t);
- __db_msgadd(dbenv, &mb, "\t\t");
- __db_pr(dbenv, &mb, p, dlen);
- p += sizeof(db_indx_t) + dlen;
- }
- break;
- case H_KEYDATA:
- __db_pr(dbenv, &mb, HKEYDATA_DATA(hk),
- LEN_HKEYDATA(dbp, h, i == 0 ?
- pagesize : 0, i));
- break;
- case H_OFFPAGE:
- memcpy(&a_hkd, hk, HOFFPAGE_SIZE);
- __db_msgadd(dbenv, &mb,
- "overflow: total len: %4lu page: %4lu",
- (u_long)a_hkd.tlen, (u_long)a_hkd.pgno);
- DB_MSGBUF_FLUSH(dbenv, &mb);
- break;
- default:
- DB_MSGBUF_FLUSH(dbenv, &mb);
- __db_msg(dbenv, "ILLEGAL HASH PAGE TYPE: %lu",
- (u_long)HPAGE_PTYPE(hk));
- ret = EINVAL;
- break;
- }
- break;
- case P_IBTREE:
- bi = sp;
- __db_msgadd(dbenv, &mb,
- "count: %4lu pgno: %4lu type: %lu ",
- (u_long)bi->nrecs, (u_long)bi->pgno,
- (u_long)bi->type);
- switch (B_TYPE(bi->type)) {
- case B_KEYDATA:
- __db_pr(dbenv, &mb, bi->data, bi->len);
- break;
- case B_DUPLICATE:
- case B_OVERFLOW:
- __db_proff(dbenv, &mb, bi->data);
- break;
- default:
- DB_MSGBUF_FLUSH(dbenv, &mb);
- __db_msg(dbenv, "ILLEGAL BINTERNAL TYPE: %lu",
- (u_long)B_TYPE(bi->type));
- ret = EINVAL;
- break;
- }
- break;
- case P_IRECNO:
- ri = sp;
- __db_msgadd(dbenv, &mb, "entries %4lu pgno %4lu",
- (u_long)ri->nrecs, (u_long)ri->pgno);
- DB_MSGBUF_FLUSH(dbenv, &mb);
- break;
- case P_LBTREE:
- case P_LDUP:
- case P_LRECNO:
- bk = sp;
- switch (B_TYPE(bk->type)) {
- case B_KEYDATA:
- __db_pr(dbenv, &mb, bk->data, bk->len);
- break;
- case B_DUPLICATE:
- case B_OVERFLOW:
- __db_proff(dbenv, &mb, bk);
- break;
- default:
- DB_MSGBUF_FLUSH(dbenv, &mb);
- __db_msg(dbenv,
- "ILLEGAL DUPLICATE/LBTREE/LRECNO TYPE: %lu",
- (u_long)B_TYPE(bk->type));
- ret = EINVAL;
- break;
- }
- break;
- default:
-type_err: DB_MSGBUF_FLUSH(dbenv, &mb);
- __db_msg(dbenv,
- "ILLEGAL PAGE TYPE: %lu", (u_long)TYPE(h));
- ret = EINVAL;
- continue;
- }
- }
- return (ret);
-}
-
-/*
- * __db_pr --
- * Print out a data element.
- *
- * PUBLIC: void __db_pr __P((DB_ENV *, DB_MSGBUF *, u_int8_t *, u_int32_t));
- */
-void
-__db_pr(dbenv, mbp, p, len)
- DB_ENV *dbenv;
- DB_MSGBUF *mbp;
- u_int8_t *p;
- u_int32_t len;
-{
- u_int32_t i;
-
- __db_msgadd(dbenv, mbp, "len: %3lu", (u_long)len);
- if (len != 0) {
- __db_msgadd(dbenv, mbp, " data: ");
- for (i = len <= 20 ? len : 20; i > 0; --i, ++p) {
- if (isprint((int)*p) || *p == '\n')
- __db_msgadd(dbenv, mbp, "%c", *p);
- else
- __db_msgadd(dbenv, mbp, "%#.2x", (u_int)*p);
- }
- if (len > 20)
- __db_msgadd(dbenv, mbp, "...");
- }
- DB_MSGBUF_FLUSH(dbenv, mbp);
-}
-
-/*
- * __db_proff --
- * Print out an off-page element.
- */
-static void
-__db_proff(dbenv, mbp, vp)
- DB_ENV *dbenv;
- DB_MSGBUF *mbp;
- void *vp;
-{
- BOVERFLOW *bo;
-
- bo = vp;
- switch (B_TYPE(bo->type)) {
- case B_OVERFLOW:
- __db_msgadd(dbenv, mbp, "overflow: total len: %4lu page: %4lu",
- (u_long)bo->tlen, (u_long)bo->pgno);
- break;
- case B_DUPLICATE:
- __db_msgadd(
- dbenv, mbp, "duplicate: page: %4lu", (u_long)bo->pgno);
- break;
- default:
- /* NOTREACHED */
- break;
- }
- DB_MSGBUF_FLUSH(dbenv, mbp);
-}
-
-/*
- * __db_prflags --
- * Print out flags values.
- *
- * PUBLIC: void __db_prflags __P((DB_ENV *, DB_MSGBUF *,
- * PUBLIC: u_int32_t, const FN *, const char *, const char *));
- */
-void
-__db_prflags(dbenv, mbp, flags, fn, prefix, suffix)
- DB_ENV *dbenv;
- DB_MSGBUF *mbp;
- u_int32_t flags;
- FN const *fn;
- const char *prefix, *suffix;
-{
- DB_MSGBUF mb;
- const FN *fnp;
- int found, standalone;
- const char *sep;
-
- /*
- * If it's a standalone message, output the suffix (which will be the
- * label), regardless of whether we found anything or not, and flush
- * the line.
- */
- if (mbp == NULL) {
- standalone = 1;
- mbp = &mb;
- DB_MSGBUF_INIT(mbp);
- } else
- standalone = 0;
-
- sep = prefix == NULL ? "" : prefix;
- for (found = 0, fnp = fn; fnp->mask != 0; ++fnp)
- if (LF_ISSET(fnp->mask)) {
- __db_msgadd(dbenv, mbp, "%s%s", sep, fnp->name);
- sep = ", ";
- found = 1;
- }
-
- if ((standalone || found) && suffix != NULL)
- __db_msgadd(dbenv, mbp, "%s", suffix);
- if (standalone)
- DB_MSGBUF_FLUSH(dbenv, mbp);
-}
-
-/*
- * __db_lockmode_to_string --
- * Return the name of the lock mode.
- *
- * PUBLIC: const char * __db_lockmode_to_string __P((db_lockmode_t));
- */
-const char *
-__db_lockmode_to_string(mode)
- db_lockmode_t mode;
-{
- switch (mode) {
- case DB_LOCK_NG:
- return ("Not granted");
- case DB_LOCK_READ:
- return ("Shared/read");
- case DB_LOCK_WRITE:
- return ("Exclusive/write");
- case DB_LOCK_WAIT:
- return ("Wait for event");
- case DB_LOCK_IWRITE:
- return ("Intent exclusive/write");
- case DB_LOCK_IREAD:
- return ("Intent shared/read");
- case DB_LOCK_IWR:
- return ("Intent to read/write");
- case DB_LOCK_READ_UNCOMMITTED:
- return ("Read uncommitted");
- case DB_LOCK_WWRITE:
- return ("Was written");
- default:
- break;
- }
- return ("UNKNOWN LOCK MODE");
-}
-
-/*
- * __db_pagetype_to_string --
- * Return the name of the specified page type.
- */
-static const char *
-__db_pagetype_to_string(type)
- u_int32_t type;
-{
- char *s;
-
- s = NULL;
- switch (type) {
- case P_BTREEMETA:
- s = "btree metadata";
- break;
- case P_LDUP:
- s = "duplicate";
- break;
- case P_HASH:
- s = "hash";
- break;
- case P_HASHMETA:
- s = "hash metadata";
- break;
- case P_IBTREE:
- s = "btree internal";
- break;
- case P_INVALID:
- s = "invalid";
- break;
- case P_IRECNO:
- s = "recno internal";
- break;
- case P_LBTREE:
- s = "btree leaf";
- break;
- case P_LRECNO:
- s = "recno leaf";
- break;
- case P_OVERFLOW:
- s = "overflow";
- break;
- case P_QAMMETA:
- s = "queue metadata";
- break;
- case P_QAMDATA:
- s = "queue";
- break;
- default:
- /* Just return a NULL. */
- break;
- }
- return (s);
-}
-
-#else /* !HAVE_STATISTICS */
-
-/*
- * __db_dumptree --
- * Dump the tree to a file.
- *
- * PUBLIC: int __db_dumptree __P((DB *, char *, char *));
- */
-int
-__db_dumptree(dbp, op, name)
- DB *dbp;
- char *op, *name;
-{
- COMPQUIET(op, NULL);
- COMPQUIET(name, NULL);
-
- return (__db_stat_not_built(dbp->dbenv));
-}
-
-/*
- * __db_get_flags_fn --
- * Return the __db_flags_fn array.
- *
- * PUBLIC: const FN * __db_get_flags_fn __P((void));
- */
-const FN *
-__db_get_flags_fn()
-{
- static const FN __db_flags_fn[] = {
- { 0, NULL }
- };
-
- /*
- * !!!
- * The Tcl API uses this interface, stub it off.
- */
- return (__db_flags_fn);
-}
-#endif
-
-/*
- * __db_dump_pp --
- * DB->dump pre/post processing.
- *
- * PUBLIC: int __db_dump_pp __P((DB *, const char *,
- * PUBLIC: int (*)(void *, const void *), void *, int, int));
- */
-int
-__db_dump_pp(dbp, subname, callback, handle, pflag, keyflag)
- DB *dbp;
- const char *subname;
- int (*callback) __P((void *, const void *));
- void *handle;
- int pflag, keyflag;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->dump");
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 1)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- ret = __db_dump(dbp, subname, callback, handle, pflag, keyflag);
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_dump --
- * DB->dump.
- *
- * PUBLIC: int __db_dump __P((DB *, const char *,
- * PUBLIC: int (*)(void *, const void *), void *, int, int));
- */
-int
-__db_dump(dbp, subname, callback, handle, pflag, keyflag)
- DB *dbp;
- const char *subname;
- int (*callback) __P((void *, const void *));
- void *handle;
- int pflag, keyflag;
-{
- DB_ENV *dbenv;
- DBC *dbcp;
- DBT key, data;
- DBT keyret, dataret;
- db_recno_t recno;
- int is_recno, ret, t_ret;
- void *pointer;
-
- dbenv = dbp->dbenv;
-
- if ((ret = __db_prheader(
- dbp, subname, pflag, keyflag, handle, callback, NULL, 0)) != 0)
- return (ret);
-
- /*
- * Get a cursor and step through the database, printing out each
- * key/data pair.
- */
- if ((ret = __db_cursor(dbp, NULL, &dbcp, 0)) != 0)
- return (ret);
-
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- if ((ret = __os_malloc(dbenv, 1024 * 1024, &data.data)) != 0)
- goto err;
- data.ulen = 1024 * 1024;
- data.flags = DB_DBT_USERMEM;
- is_recno = (dbp->type == DB_RECNO || dbp->type == DB_QUEUE);
- keyflag = is_recno ? keyflag : 1;
- if (is_recno) {
- keyret.data = &recno;
- keyret.size = sizeof(recno);
- }
-
-retry: while ((ret =
- __db_c_get(dbcp, &key, &data, DB_NEXT | DB_MULTIPLE_KEY)) == 0) {
- DB_MULTIPLE_INIT(pointer, &data);
- for (;;) {
- if (is_recno)
- DB_MULTIPLE_RECNO_NEXT(pointer, &data,
- recno, dataret.data, dataret.size);
- else
- DB_MULTIPLE_KEY_NEXT(pointer,
- &data, keyret.data,
- keyret.size, dataret.data, dataret.size);
-
- if (dataret.data == NULL)
- break;
-
- if ((keyflag &&
- (ret = __db_prdbt(&keyret, pflag, " ",
- handle, callback, is_recno)) != 0) ||
- (ret = __db_prdbt(&dataret, pflag, " ",
- handle, callback, 0)) != 0)
- goto err;
- }
- }
- if (ret == DB_BUFFER_SMALL) {
- data.size = (u_int32_t)DB_ALIGN(data.size, 1024);
- if ((ret = __os_realloc(dbenv, data.size, &data.data)) != 0)
- goto err;
- data.ulen = data.size;
- goto retry;
- }
- if (ret == DB_NOTFOUND)
- ret = 0;
-
- if ((t_ret = __db_prfooter(handle, callback)) != 0 && ret == 0)
- ret = t_ret;
-
-err: if ((t_ret = __db_c_close(dbcp)) != 0 && ret == 0)
- ret = t_ret;
- if (data.data != NULL)
- __os_free(dbenv, data.data);
-
- return (ret);
-}
-
-/*
- * __db_prdbt --
- * Print out a DBT data element.
- *
- * PUBLIC: int __db_prdbt __P((DBT *, int, const char *, void *,
- * PUBLIC: int (*)(void *, const void *), int));
- */
-int
-__db_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno)
- DBT *dbtp;
- int checkprint;
- const char *prefix;
- void *handle;
- int (*callback) __P((void *, const void *));
- int is_recno;
-{
- static const u_char hex[] = "0123456789abcdef";
- db_recno_t recno;
- size_t len;
- int ret;
-#define DBTBUFLEN 100
- u_int8_t *p, *hp;
- char buf[DBTBUFLEN], hbuf[DBTBUFLEN];
-
- /*
- * !!!
- * This routine is the routine that dumps out items in the format
- * used by db_dump(1) and db_load(1). This means that the format
- * cannot change.
- */
- if (prefix != NULL && (ret = callback(handle, prefix)) != 0)
- return (ret);
- if (is_recno) {
- /*
- * We're printing a record number, and this has to be done
- * in a platform-independent way. So we use the numeral in
- * straight ASCII.
- */
- (void)__ua_memcpy(&recno, dbtp->data, sizeof(recno));
- snprintf(buf, DBTBUFLEN, "%lu", (u_long)recno);
-
- /* If we're printing data as hex, print keys as hex too. */
- if (!checkprint) {
- for (len = strlen(buf), p = (u_int8_t *)buf,
- hp = (u_int8_t *)hbuf; len-- > 0; ++p) {
- *hp++ = hex[(u_int8_t)(*p & 0xf0) >> 4];
- *hp++ = hex[*p & 0x0f];
- }
- *hp = '\0';
- ret = callback(handle, hbuf);
- } else
- ret = callback(handle, buf);
-
- if (ret != 0)
- return (ret);
- } else if (checkprint) {
- for (len = dbtp->size, p = dbtp->data; len--; ++p)
- if (isprint((int)*p)) {
- if (*p == '\\' &&
- (ret = callback(handle, "\\")) != 0)
- return (ret);
- snprintf(buf, DBTBUFLEN, "%c", *p);
- if ((ret = callback(handle, buf)) != 0)
- return (ret);
- } else {
- snprintf(buf, DBTBUFLEN, "\\%c%c",
- hex[(u_int8_t)(*p & 0xf0) >> 4],
- hex[*p & 0x0f]);
- if ((ret = callback(handle, buf)) != 0)
- return (ret);
- }
- } else
- for (len = dbtp->size, p = dbtp->data; len--; ++p) {
- snprintf(buf, DBTBUFLEN, "%c%c",
- hex[(u_int8_t)(*p & 0xf0) >> 4],
- hex[*p & 0x0f]);
- if ((ret = callback(handle, buf)) != 0)
- return (ret);
- }
-
- return (callback(handle, "\n"));
-}
-
-/*
- * __db_prheader --
- * Write out header information in the format expected by db_load.
- *
- * PUBLIC: int __db_prheader __P((DB *, const char *, int, int, void *,
- * PUBLIC: int (*)(void *, const void *), VRFY_DBINFO *, db_pgno_t));
- */
-int
-__db_prheader(dbp, subname, pflag, keyflag, handle, callback, vdp, meta_pgno)
- DB *dbp;
- const char *subname;
- int pflag, keyflag;
- void *handle;
- int (*callback) __P((void *, const void *));
- VRFY_DBINFO *vdp;
- db_pgno_t meta_pgno;
-{
- DBT dbt;
- DB_ENV *dbenv;
- DBTYPE dbtype;
- VRFY_PAGEINFO *pip;
- u_int32_t flags, tmp_u_int32;
- size_t buflen;
- char *buf;
- int using_vdp, ret, t_ret, tmp_int;
-
- ret = 0;
- buf = NULL;
- COMPQUIET(buflen, 0);
-
- /*
- * If dbp is NULL, then pip is guaranteed to be non-NULL; we only ever
- * call __db_prheader with a NULL dbp from one case inside __db_prdbt,
- * and this is a special subdatabase for "lost" items. In this case
- * we have a vdp (from which we'll get a pip). In all other cases, we
- * will have a non-NULL dbp (and vdp may or may not be NULL depending
- * on whether we're salvaging).
- */
- DB_ASSERT(dbp != NULL || vdp != NULL);
-
- if (dbp == NULL)
- dbenv = NULL;
- else
- dbenv = dbp->dbenv;
-
- /*
- * If we've been passed a verifier statistics object, use that; we're
- * being called in a context where dbp->stat is unsafe.
- *
- * Also, the verifier may set the pflag on a per-salvage basis. If so,
- * respect that.
- */
- if (vdp != NULL) {
- if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &pip)) != 0)
- return (ret);
-
- if (F_ISSET(vdp, SALVAGE_PRINTABLE))
- pflag = 1;
- using_vdp = 1;
- } else {
- pip = NULL;
- using_vdp = 0;
- }
-
- /*
- * If dbp is NULL, make it a btree. Otherwise, set dbtype to whatever
- * appropriate type for the specified meta page, or the type of the dbp.
- */
- if (dbp == NULL)
- dbtype = DB_BTREE;
- else if (using_vdp)
- switch (pip->type) {
- case P_BTREEMETA:
- if (F_ISSET(pip, VRFY_IS_RECNO))
- dbtype = DB_RECNO;
- else
- dbtype = DB_BTREE;
- break;
- case P_HASHMETA:
- dbtype = DB_HASH;
- break;
- case P_QAMMETA:
- dbtype = DB_QUEUE;
- break;
- default:
- /*
- * If the meta page is of a bogus type, it's because
- * we have a badly corrupt database. (We must be in
- * the verifier for pip to be non-NULL.) Pretend we're
- * a Btree and salvage what we can.
- */
- DB_ASSERT(F_ISSET(dbp, DB_AM_VERIFYING));
- dbtype = DB_BTREE;
- break;
- }
- else
- dbtype = dbp->type;
-
- if ((ret = callback(handle, "VERSION=3\n")) != 0)
- goto err;
- if (pflag) {
- if ((ret = callback(handle, "format=print\n")) != 0)
- goto err;
- } else if ((ret = callback(handle, "format=bytevalue\n")) != 0)
- goto err;
-
- /*
- * 64 bytes is long enough, as a minimum bound, for any of the
- * fields besides subname. Subname uses __db_prdbt and therefore
- * does not need buffer space here.
- */
- buflen = 64;
- if ((ret = __os_malloc(dbenv, buflen, &buf)) != 0)
- goto err;
- if (subname != NULL) {
- snprintf(buf, buflen, "database=");
- if ((ret = callback(handle, buf)) != 0)
- goto err;
- memset(&dbt, 0, sizeof(dbt));
- dbt.data = (char *)subname;
- dbt.size = (u_int32_t)strlen(subname);
- if ((ret = __db_prdbt(&dbt, 1, NULL, handle, callback, 0)) != 0)
- goto err;
- }
- switch (dbtype) {
- case DB_BTREE:
- if ((ret = callback(handle, "type=btree\n")) != 0)
- goto err;
- if (using_vdp)
- tmp_int = F_ISSET(pip, VRFY_HAS_RECNUMS) ? 1 : 0;
- else {
- if ((ret = __db_get_flags(dbp, &flags)) != 0) {
- __db_err(dbenv,
- "DB->get_flags: %s", db_strerror(ret));
- goto err;
- }
- tmp_int = F_ISSET(dbp, DB_AM_RECNUM) ? 1 : 0;
- }
- if (tmp_int && (ret = callback(handle, "recnum=1\n")) != 0)
- goto err;
-
- if (using_vdp)
- tmp_u_int32 = pip->bt_minkey;
- else
- if ((ret =
- __bam_get_bt_minkey(dbp, &tmp_u_int32)) != 0) {
- __db_err(dbenv,
- "DB->get_bt_minkey: %s", db_strerror(ret));
- goto err;
- }
- if (tmp_u_int32 != 0 && tmp_u_int32 != DEFMINKEYPAGE) {
- snprintf(buf, buflen,
- "bt_minkey=%lu\n", (u_long)tmp_u_int32);
- if ((ret = callback(handle, buf)) != 0)
- goto err;
- }
- break;
- case DB_HASH:
-#ifdef HAVE_HASH
- if ((ret = callback(handle, "type=hash\n")) != 0)
- goto err;
- if (using_vdp)
- tmp_u_int32 = pip->h_ffactor;
- else
- if ((ret =
- __ham_get_h_ffactor(dbp, &tmp_u_int32)) != 0) {
- __db_err(dbenv,
- "DB->get_h_ffactor: %s", db_strerror(ret));
- goto err;
- }
- if (tmp_u_int32 != 0) {
- snprintf(buf, buflen,
- "h_ffactor=%lu\n", (u_long)tmp_u_int32);
- if ((ret = callback(handle, buf)) != 0)
- goto err;
- }
-
- if (using_vdp)
- tmp_u_int32 = pip->h_nelem;
- else
- if ((ret = __ham_get_h_nelem(dbp, &tmp_u_int32)) != 0) {
- __db_err(dbenv,
- "DB->get_h_nelem: %s", db_strerror(ret));
- goto err;
- }
- /*
- * Hash databases have an h_nelem field of 0 or 1, neither
- * of those values is interesting.
- */
- if (tmp_u_int32 > 1) {
- snprintf(buf, buflen,
- "h_nelem=%lu\n", (u_long)tmp_u_int32);
- if ((ret = callback(handle, buf)) != 0)
- goto err;
- }
- break;
-#else
- ret = __db_no_hash_am(dbenv);
- goto err;
-#endif
- case DB_QUEUE:
-#ifdef HAVE_QUEUE
- if ((ret = callback(handle, "type=queue\n")) != 0)
- goto err;
- if (using_vdp)
- tmp_u_int32 = vdp->re_len;
- else
- if ((ret = __ram_get_re_len(dbp, &tmp_u_int32)) != 0) {
- __db_err(dbenv,
- "DB->get_re_len: %s", db_strerror(ret));
- goto err;
- }
- snprintf(buf, buflen, "re_len=%lu\n", (u_long)tmp_u_int32);
- if ((ret = callback(handle, buf)) != 0)
- goto err;
-
- if (using_vdp)
- tmp_int = (int)vdp->re_pad;
- else
- if ((ret = __ram_get_re_pad(dbp, &tmp_int)) != 0) {
- __db_err(dbenv,
- "DB->get_re_pad: %s", db_strerror(ret));
- goto err;
- }
- if (tmp_int != 0 && tmp_int != ' ') {
- snprintf(buf, buflen, "re_pad=%#x\n", tmp_int);
- if ((ret = callback(handle, buf)) != 0)
- goto err;
- }
-
- if (using_vdp)
- tmp_u_int32 = vdp->page_ext;
- else
- if ((ret =
- __qam_get_extentsize(dbp, &tmp_u_int32)) != 0) {
- __db_err(dbenv, "DB->get_q_extentsize: %s",
- db_strerror(ret));
- goto err;
- }
- if (tmp_u_int32 != 0) {
- snprintf(buf, buflen,
- "extentsize=%lu\n", (u_long)tmp_u_int32);
- if ((ret = callback(handle, buf)) != 0)
- goto err;
- }
- break;
-#else
- ret = __db_no_queue_am(dbenv);
- goto err;
-#endif
- case DB_RECNO:
- if ((ret = callback(handle, "type=recno\n")) != 0)
- goto err;
- if (using_vdp)
- tmp_int = F_ISSET(pip, VRFY_IS_RRECNO) ? 1 : 0;
- else
- tmp_int = F_ISSET(dbp, DB_AM_RENUMBER) ? 1 : 0;
- if (tmp_int != 0 &&
- (ret = callback(handle, "renumber=1\n")) != 0)
- goto err;
-
- if (using_vdp)
- tmp_int = F_ISSET(pip, VRFY_IS_FIXEDLEN) ? 1 : 0;
- else
- tmp_int = F_ISSET(dbp, DB_AM_FIXEDLEN) ? 1 : 0;
- if (tmp_int) {
- if (using_vdp)
- tmp_u_int32 = pip->re_len;
- else
- if ((ret =
- __ram_get_re_len(dbp, &tmp_u_int32)) != 0) {
- __db_err(dbenv, "DB->get_re_len: %s",
- db_strerror(ret));
- goto err;
- }
- snprintf(buf, buflen,
- "re_len=%lu\n", (u_long)tmp_u_int32);
- if ((ret = callback(handle, buf)) != 0)
- goto err;
-
- if (using_vdp)
- tmp_int = (int)pip->re_pad;
- else
- if ((ret =
- __ram_get_re_pad(dbp, &tmp_int)) != 0) {
- __db_err(dbenv, "DB->get_re_pad: %s",
- db_strerror(ret));
- goto err;
- }
- if (tmp_int != 0 && tmp_int != ' ') {
- snprintf(buf,
- buflen, "re_pad=%#x\n", (u_int)tmp_int);
- if ((ret = callback(handle, buf)) != 0)
- goto err;
- }
- }
- break;
- case DB_UNKNOWN:
- DB_ASSERT(0); /* Impossible. */
- __db_err(dbenv,
- "Unknown or unsupported DB type in __db_prheader");
- ret = EINVAL;
- goto err;
- }
-
- if (using_vdp) {
- if (F_ISSET(pip, VRFY_HAS_CHKSUM))
- if ((ret = callback(handle, "chksum=1\n")) != 0)
- goto err;
- if (F_ISSET(pip, VRFY_HAS_DUPS))
- if ((ret = callback(handle, "duplicates=1\n")) != 0)
- goto err;
- if (F_ISSET(pip, VRFY_HAS_DUPSORT))
- if ((ret = callback(handle, "dupsort=1\n")) != 0)
- goto err;
- /*
- * !!!
- * We don't know if the page size was the default if we're
- * salvaging. It doesn't seem that interesting to have, so
- * we ignore it for now.
- */
- } else {
- if (F_ISSET(dbp, DB_AM_CHKSUM))
- if ((ret = callback(handle, "chksum=1\n")) != 0)
- goto err;
- if (F_ISSET(dbp, DB_AM_DUP))
- if ((ret = callback(handle, "duplicates=1\n")) != 0)
- goto err;
- if (F_ISSET(dbp, DB_AM_DUPSORT))
- if ((ret = callback(handle, "dupsort=1\n")) != 0)
- goto err;
- if (!F_ISSET(dbp, DB_AM_PGDEF)) {
- snprintf(buf, buflen,
- "db_pagesize=%lu\n", (u_long)dbp->pgsize);
- if ((ret = callback(handle, buf)) != 0)
- goto err;
- }
- }
-
- if (keyflag && (ret = callback(handle, "keys=1\n")) != 0)
- goto err;
-
- ret = callback(handle, "HEADER=END\n");
-
-err: if (using_vdp &&
- (t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0)
- ret = t_ret;
- if (buf != NULL)
- __os_free(dbenv, buf);
-
- return (ret);
-}
-
-/*
- * __db_prfooter --
- * Print the footer that marks the end of a DB dump. This is trivial,
- * but for consistency's sake we don't want to put its literal contents
- * in multiple places.
- *
- * PUBLIC: int __db_prfooter __P((void *, int (*)(void *, const void *)));
- */
-int
-__db_prfooter(handle, callback)
- void *handle;
- int (*callback) __P((void *, const void *));
-{
- return (callback(handle, "DATA=END\n"));
-}
-
-/*
- * __db_pr_callback --
- * Callback function for using pr_* functions from C.
- *
- * PUBLIC: int __db_pr_callback __P((void *, const void *));
- */
-int
-__db_pr_callback(handle, str_arg)
- void *handle;
- const void *str_arg;
-{
- char *str;
- FILE *f;
-
- str = (char *)str_arg;
- f = (FILE *)handle;
-
- if (fprintf(f, "%s", str) != (int)strlen(str))
- return (EIO);
-
- return (0);
-}
-
-/*
- * __db_dbtype_to_string --
- * Return the name of the database type.
- *
- * PUBLIC: const char * __db_dbtype_to_string __P((DBTYPE));
- */
-const char *
-__db_dbtype_to_string(type)
- DBTYPE type;
-{
- switch (type) {
- case DB_BTREE:
- return ("btree");
- case DB_HASH:
- return ("hash");
- case DB_RECNO:
- return ("recno");
- case DB_QUEUE:
- return ("queue");
- case DB_UNKNOWN:
- default:
- break;
- }
- return ("UNKNOWN TYPE");
-}
diff --git a/storage/bdb/db/db_rec.c b/storage/bdb/db/db_rec.c
deleted file mode 100644
index e0c13f255c1..00000000000
--- a/storage/bdb/db/db_rec.c
+++ /dev/null
@@ -1,1266 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_rec.c,v 12.12 2005/10/27 01:03:01 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/log.h"
-#include "dbinc/mp.h"
-#include "dbinc/hash.h"
-
-static int __db_pg_free_recover_int __P((DB_ENV *,
- __db_pg_freedata_args *, DB *, DB_LSN *, DB_MPOOLFILE *, db_recops, int));
-
-/*
- * PUBLIC: int __db_addrem_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- *
- * This log message is generated whenever we add or remove a duplicate
- * to/from a duplicate page. On recover, we just do the opposite.
- */
-int
-__db_addrem_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- __db_addrem_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- u_int32_t change;
- int cmp_n, cmp_p, ret;
-
- pagep = NULL;
- COMPQUIET(info, NULL);
- REC_PRINT(__db_addrem_print);
- REC_INTRO(__db_addrem_read, 1, 1);
-
- REC_FGET(mpf, argp->pgno, &pagep, done);
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
- CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn);
- change = 0;
- if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_ADD_DUP) ||
- (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_REM_DUP)) {
-
- /* Need to redo an add, or undo a delete. */
- if ((ret = __db_pitem(dbc, pagep, argp->indx, argp->nbytes,
- argp->hdr.size == 0 ? NULL : &argp->hdr,
- argp->dbt.size == 0 ? NULL : &argp->dbt)) != 0)
- goto out;
-
- change = DB_MPOOL_DIRTY;
-
- } else if ((cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_ADD_DUP) ||
- (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_REM_DUP)) {
- /* Need to undo an add, or redo a delete. */
- if ((ret = __db_ditem(dbc,
- pagep, argp->indx, argp->nbytes)) != 0)
- goto out;
- change = DB_MPOOL_DIRTY;
- }
-
- if (change) {
- if (DB_REDO(op))
- LSN(pagep) = *lsnp;
- else
- LSN(pagep) = argp->pagelsn;
- }
-
- if ((ret = __memp_fput(mpf, pagep, change)) != 0)
- goto out;
- pagep = NULL;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (pagep != NULL)
- (void)__memp_fput(mpf, pagep, 0);
- REC_CLOSE;
-}
-
-/*
- * PUBLIC: int __db_big_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__db_big_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- __db_big_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- u_int32_t change;
- int cmp_n, cmp_p, ret;
-
- pagep = NULL;
- COMPQUIET(info, NULL);
- REC_PRINT(__db_big_print);
- REC_INTRO(__db_big_read, 1, 0);
-
- REC_FGET(mpf, argp->pgno, &pagep, ppage);
-
- /*
- * There are three pages we need to check. The one on which we are
- * adding data, the previous one whose next_pointer may have
- * been updated, and the next one whose prev_pointer may have
- * been updated.
- */
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
- CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn);
- change = 0;
- if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_ADD_BIG) ||
- (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_REM_BIG)) {
- /* We are either redo-ing an add, or undoing a delete. */
- P_INIT(pagep, file_dbp->pgsize, argp->pgno, argp->prev_pgno,
- argp->next_pgno, 0, P_OVERFLOW);
- OV_LEN(pagep) = argp->dbt.size;
- OV_REF(pagep) = 1;
- memcpy((u_int8_t *)pagep + P_OVERHEAD(file_dbp), argp->dbt.data,
- argp->dbt.size);
- PREV_PGNO(pagep) = argp->prev_pgno;
- change = DB_MPOOL_DIRTY;
- } else if ((cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_ADD_BIG) ||
- (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_REM_BIG)) {
- /*
- * We are either undo-ing an add or redo-ing a delete.
- * The page is about to be reclaimed in either case, so
- * there really isn't anything to do here.
- */
- change = DB_MPOOL_DIRTY;
- }
- if (change)
- LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn;
-
- if ((ret = __memp_fput(mpf, pagep, change)) != 0)
- goto out;
- pagep = NULL;
-
- /*
- * We only delete a whole chain of overflow.
- * Each page is handled individually
- */
- if (argp->opcode == DB_REM_BIG)
- goto done;
-
- /* Now check the previous page. */
-ppage: if (argp->prev_pgno != PGNO_INVALID) {
- change = 0;
- REC_FGET(mpf, argp->prev_pgno, &pagep, npage);
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->prevlsn);
- CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->prevlsn);
-
- if (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_ADD_BIG) {
- /* Redo add, undo delete. */
- NEXT_PGNO(pagep) = argp->pgno;
- change = DB_MPOOL_DIRTY;
- } else if (cmp_n == 0 &&
- DB_UNDO(op) && argp->opcode == DB_ADD_BIG) {
- /* Redo delete, undo add. */
- NEXT_PGNO(pagep) = argp->next_pgno;
- change = DB_MPOOL_DIRTY;
- }
- if (change)
- LSN(pagep) = DB_REDO(op) ? *lsnp : argp->prevlsn;
- if ((ret = __memp_fput(mpf, pagep, change)) != 0)
- goto out;
- }
- pagep = NULL;
-
- /* Now check the next page. Can only be set on a delete. */
-npage: if (argp->next_pgno != PGNO_INVALID) {
- change = 0;
- REC_FGET(mpf, argp->next_pgno, &pagep, done);
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->nextlsn);
- CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->nextlsn);
- if (cmp_p == 0 && DB_REDO(op)) {
- PREV_PGNO(pagep) = PGNO_INVALID;
- change = DB_MPOOL_DIRTY;
- } else if (cmp_n == 0 && DB_UNDO(op)) {
- PREV_PGNO(pagep) = argp->pgno;
- change = DB_MPOOL_DIRTY;
- }
- if (change)
- LSN(pagep) = DB_REDO(op) ? *lsnp : argp->nextlsn;
- if ((ret = __memp_fput(mpf, pagep, change)) != 0)
- goto out;
- }
- pagep = NULL;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (pagep != NULL)
- (void)__memp_fput(mpf, pagep, 0);
- REC_CLOSE;
-}
-
-/*
- * __db_ovref_recover --
- * Recovery function for __db_ovref().
- *
- * PUBLIC: int __db_ovref_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__db_ovref_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- __db_ovref_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int cmp, modified, ret;
-
- pagep = NULL;
- COMPQUIET(info, NULL);
- REC_PRINT(__db_ovref_print);
- REC_INTRO(__db_ovref_read, 1, 0);
-
- REC_FGET(mpf, argp->pgno, &pagep, done);
-
- modified = 0;
- cmp = log_compare(&LSN(pagep), &argp->lsn);
- CHECK_LSN(dbenv, op, cmp, &LSN(pagep), &argp->lsn);
- if (cmp == 0 && DB_REDO(op)) {
- /* Need to redo update described. */
- OV_REF(pagep) += argp->adjust;
-
- pagep->lsn = *lsnp;
- modified = 1;
- } else if (log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) {
- /* Need to undo update described. */
- OV_REF(pagep) -= argp->adjust;
-
- pagep->lsn = argp->lsn;
- modified = 1;
- }
- if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
- pagep = NULL;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (pagep != NULL)
- (void)__memp_fput(mpf, pagep, 0);
- REC_CLOSE;
-}
-
-/*
- * __db_debug_recover --
- * Recovery function for debug.
- *
- * PUBLIC: int __db_debug_recover __P((DB_ENV *,
- * PUBLIC: DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__db_debug_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- __db_debug_args *argp;
- int ret;
-
- COMPQUIET(dbenv, NULL);
- COMPQUIET(op, DB_TXN_ABORT);
- COMPQUIET(info, NULL);
-
- REC_PRINT(__db_debug_print);
- REC_NOOP_INTRO(__db_debug_read);
-
- *lsnp = argp->prev_lsn;
- ret = 0;
-
- REC_NOOP_CLOSE;
-}
-
-/*
- * __db_noop_recover --
- * Recovery function for noop.
- *
- * PUBLIC: int __db_noop_recover __P((DB_ENV *,
- * PUBLIC: DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__db_noop_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- __db_noop_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- u_int32_t change;
- int cmp_n, cmp_p, ret;
-
- pagep = NULL;
- COMPQUIET(info, NULL);
- REC_PRINT(__db_noop_print);
- REC_INTRO(__db_noop_read, 0, 0);
-
- REC_FGET(mpf, argp->pgno, &pagep, done);
-
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->prevlsn);
- CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->prevlsn);
- change = 0;
- if (cmp_p == 0 && DB_REDO(op)) {
- LSN(pagep) = *lsnp;
- change = DB_MPOOL_DIRTY;
- } else if (cmp_n == 0 && DB_UNDO(op)) {
- LSN(pagep) = argp->prevlsn;
- change = DB_MPOOL_DIRTY;
- }
- ret = __memp_fput(mpf, pagep, change);
- pagep = NULL;
-
-done: *lsnp = argp->prev_lsn;
-out: if (pagep != NULL)
- (void)__memp_fput(mpf, pagep, 0);
- REC_CLOSE;
-}
-
-/*
- * __db_pg_alloc_recover --
- * Recovery function for pg_alloc.
- *
- * PUBLIC: int __db_pg_alloc_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__db_pg_alloc_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- __db_pg_alloc_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DBMETA *meta;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- db_pgno_t pgno;
- int cmp_n, cmp_p, created, level, meta_modified, modified, ret;
-
- meta = NULL;
- pagep = NULL;
- created = meta_modified = modified = 0;
- REC_PRINT(__db_pg_alloc_print);
- REC_INTRO(__db_pg_alloc_read, 0, 0);
-
- /*
- * Fix up the metadata page. If we're redoing the operation, we have
- * to get the metadata page and update its LSN and its free pointer.
- * If we're undoing the operation and the page was ever created, we put
- * it on the freelist.
- */
- pgno = PGNO_BASE_MD;
- if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0) {
- /* The metadata page must always exist on redo. */
- if (DB_REDO(op)) {
- ret = __db_pgerr(file_dbp, pgno, ret);
- goto out;
- } else
- goto done;
- }
- cmp_n = log_compare(lsnp, &LSN(meta));
- cmp_p = log_compare(&LSN(meta), &argp->meta_lsn);
- CHECK_LSN(dbenv, op, cmp_p, &LSN(meta), &argp->meta_lsn);
- if (cmp_p == 0 && DB_REDO(op)) {
- /* Need to redo update described. */
- LSN(meta) = *lsnp;
- meta->free = argp->next;
- meta_modified = 1;
- if (argp->pgno > meta->last_pgno)
- meta->last_pgno = argp->pgno;
- } else if (cmp_n == 0 && DB_UNDO(op)) {
- /* Need to undo update described. */
- LSN(meta) = argp->meta_lsn;
- /*
- * If the page has a zero LSN then its newly created
- * and will be truncated or go into limbo rather than
- * directly on the free list.
- */
- if (!IS_ZERO_LSN(argp->page_lsn))
- meta->free = argp->pgno;
-#ifdef HAVE_FTRUNCATE
- /*
- * With truncate we will restore the file to
- * its original length. Without truncate
- * the last_pgno never goes backward.
- */
- meta->last_pgno = argp->last_pgno;
-#endif
- meta_modified = 1;
- }
-
-#ifdef HAVE_FTRUNCATE
- /*
- * Check to see if we are keeping a sorted
- * freelist, if so put this back in the in
- * memory list. It must be the first element.
- */
- if (op == DB_TXN_ABORT && !IS_ZERO_LSN(argp->page_lsn)) {
- db_pgno_t *list;
- u_int32_t nelem;
-
- if ((ret = __memp_get_freelist(mpf, &nelem, &list)) != 0)
- goto out;
- if (list != NULL) {
- if ((ret =
- __memp_extend_freelist(mpf, nelem + 1, &list)) != 0)
- goto out;
- if (nelem != 0)
- memmove(list + 1, list, nelem * sizeof(list));
- *list = argp->pgno;
- }
- }
-#endif
-
- /*
- * Fix up the allocated page. If the page does not exist
- * and we can truncate it then don't create it.
- * Otherwise if we're redoing the operation, we have
- * to get the page (creating it if it doesn't exist), and update its
- * LSN. If we're undoing the operation, we have to reset the page's
- * LSN and put it on the free list, or into limbo..
- */
- if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- /*
- * We have to be able to identify if a page was newly
- * created so we can recover it properly. We cannot simply
- * look for an empty header, because hash uses a pgin
- * function that will set the header. Instead, we explicitly
- * try for the page without CREATE and if that fails, then
- * create it.
- */
-#ifdef HAVE_FTRUNCATE
- if (DB_UNDO(op))
- goto do_truncate;
-#endif
- if ((ret = __memp_fget(
- mpf, &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) {
- if (DB_UNDO(op) && ret == ENOSPC)
- goto do_truncate;
- ret = __db_pgerr(file_dbp, argp->pgno, ret);
- goto out;
- }
- created = modified = 1;
- }
-
- /* Fix up the allocated page. */
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), &argp->page_lsn);
-
- /*
- * If an initial allocation is aborted and then reallocated during
- * an archival restore the log record will have an LSN for the page
- * but the page will be empty.
- * If we we rolled back this allocation previously during an
- * archive restore, the page may have INIT_LSN from the limbo list.
- */
- if (IS_ZERO_LSN(LSN(pagep)) ||
- (IS_ZERO_LSN(argp->page_lsn) && IS_INIT_LSN(LSN(pagep))))
- cmp_p = 0;
-
- CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->page_lsn);
- /*
- * Another special case we have to handle is if we ended up with a
- * page of all 0's which can happen if we abort between allocating a
- * page in mpool and initializing it. In that case, even if we're
- * undoing, we need to re-initialize the page.
- */
- if (DB_REDO(op) && cmp_p == 0) {
- /* Need to redo update described. */
- switch (argp->ptype) {
- case P_LBTREE:
- case P_LRECNO:
- case P_LDUP:
- level = LEAFLEVEL;
- break;
- default:
- level = 0;
- break;
- }
- P_INIT(pagep, file_dbp->pgsize,
- argp->pgno, PGNO_INVALID, PGNO_INVALID, level, argp->ptype);
-
- pagep->lsn = *lsnp;
- modified = 1;
- } else if (DB_UNDO(op) && (cmp_n == 0 || created)) {
- /*
- * This is where we handle the case of a 0'd page (pagep->pgno
- * is equal to PGNO_INVALID).
- * Undo the allocation, reinitialize the page and
- * link its next pointer to the free list.
- */
- P_INIT(pagep, file_dbp->pgsize,
- argp->pgno, PGNO_INVALID, argp->next, 0, P_INVALID);
-
- pagep->lsn = argp->page_lsn;
- modified = 1;
- }
-
-do_truncate:
- /*
- * If the page was newly created, give it back, if
- * possible. Otherwise put it into limbo.
- */
- if ((pagep == NULL || IS_ZERO_LSN(LSN(pagep))) &&
- IS_ZERO_LSN(argp->page_lsn) && DB_UNDO(op)) {
-#ifdef HAVE_FTRUNCATE
- COMPQUIET(info, NULL);
- /* Discard the page. */
- if (pagep != NULL) {
- if ((ret =
- __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0)
- goto out;
- pagep = NULL;
- /* Give the page back to the OS. */
- if (meta->last_pgno <= argp->pgno &&
- (ret = __memp_ftruncate(mpf, argp->pgno, 0)) != 0)
- goto out;
- }
-#else
- /* Put the page in limbo.*/
- if ((ret = __db_add_limbo(dbenv,
- info, argp->fileid, argp->pgno, 1)) != 0)
- goto out;
- /* The last_pgno grows if this was a new page. */
- if (argp->pgno > meta->last_pgno) {
- meta->last_pgno = argp->pgno;
- meta_modified = 1;
- }
-#endif
- }
-
- if (pagep != NULL &&
- (ret = __memp_fput(mpf,
- pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
- pagep = NULL;
-
- if ((ret = __memp_fput(mpf,
- meta, meta_modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
- meta = NULL;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: if (pagep != NULL)
- (void)__memp_fput(mpf, pagep, 0);
- if (meta != NULL)
- (void)__memp_fput(mpf, meta, 0);
- if (ret == ENOENT && op == DB_TXN_BACKWARD_ALLOC)
- ret = 0;
- REC_CLOSE;
-}
-
-/*
- * __db_pg_free_recover_int --
- */
-static int
-__db_pg_free_recover_int(dbenv, argp, file_dbp, lsnp, mpf, op, data)
- DB_ENV *dbenv;
- __db_pg_freedata_args *argp;
- DB *file_dbp;
- DB_LSN *lsnp;
- DB_MPOOLFILE *mpf;
- db_recops op;
- int data;
-{
- DBMETA *meta;
- DB_LSN copy_lsn;
- PAGE *pagep, *prevp;
- int cmp_n, cmp_p, is_meta, meta_modified, modified, ret;
-
- meta = NULL;
- pagep = NULL;
- prevp = NULL;
- meta_modified = modified = 0;
-
- /*
- * Get the "metapage". This will either be the metapage
- * or the previous page in the free list if we are doing
- * sorted allocations. If its a previous page then
- * we will not be truncating.
- */
- is_meta = argp->meta_pgno == PGNO_BASE_MD;
-
- REC_FGET(mpf, argp->meta_pgno, &meta, check_meta);
-
- if (argp->meta_pgno != PGNO_BASE_MD)
- prevp = (PAGE *)meta;
-
- cmp_n = log_compare(lsnp, &LSN(meta));
- cmp_p = log_compare(&LSN(meta), &argp->meta_lsn);
- CHECK_LSN(dbenv, op, cmp_p, &LSN(meta), &argp->meta_lsn);
-
- /*
- * Fix up the metadata page. If we're redoing or undoing the operation
- * we get the page and update its LSN, last and free pointer.
- */
- if (cmp_p == 0 && DB_REDO(op)) {
-#ifdef HAVE_FTRUNCATE
- /*
- * If we are at the end of the file truncate, otherwise
- * put on the free list.
- */
- if (argp->pgno == argp->last_pgno)
- meta->last_pgno = argp->pgno - 1;
- else if (prevp == NULL)
- meta->free = argp->pgno;
- else
- NEXT_PGNO(prevp) = argp->pgno;
-#else
- /* Need to redo the deallocation. */
- if (prevp == NULL)
- meta->free = argp->pgno;
- else
- NEXT_PGNO(prevp) = argp->pgno;
- /*
- * If this was a compensating transaction and
- * we are a replica, then we never executed the
- * original allocation which incremented meta->free.
- */
- if (prevp == NULL && meta->last_pgno < meta->free)
- meta->last_pgno = meta->free;
-#endif
- LSN(meta) = *lsnp;
- meta_modified = 1;
- } else if (cmp_n == 0 && DB_UNDO(op)) {
- /* Need to undo the deallocation. */
- if (prevp == NULL)
- meta->free = argp->next;
- else
- NEXT_PGNO(prevp) = argp->next;
- LSN(meta) = argp->meta_lsn;
- if (prevp == NULL && meta->last_pgno < argp->pgno)
- meta->last_pgno = argp->pgno;
- meta_modified = 1;
- }
-
-check_meta:
- if (ret != 0 && is_meta) {
- /* The metadata page must always exist. */
- ret = __db_pgerr(file_dbp, argp->meta_pgno, ret);
- goto out;
- }
-
- /*
- * Get the freed page. If we support truncate then don't
- * create the page if we are going to free it. If we're
- * redoing the operation we get the page and explicitly discard
- * its contents, then update its LSN. If we're undoing the
- * operation, we get the page and restore its header.
- * If we don't support truncate, then we must create the page
- * and roll it back.
- */
-#ifdef HAVE_FTRUNCATE
- if (DB_REDO(op) || (is_meta && meta->last_pgno < argp->pgno)) {
- if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
- if (ret == DB_PAGE_NOTFOUND)
- goto done;
- goto out;
- }
- } else
-#endif
- if ((ret =
- __memp_fget(mpf, &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
-
- (void)__ua_memcpy(©_lsn, &LSN(argp->header.data), sizeof(DB_LSN));
- cmp_n = IS_ZERO_LSN(LSN(pagep)) ? 0 : log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), ©_lsn);
-
-#ifdef HAVE_FTRUNCATE
- /*
- * This page got extended by a later allocation,
- * but its allocation was not in the scope of this
- * recovery pass.
- */
- if (IS_ZERO_LSN(LSN(pagep)))
- cmp_p = 0;
-#endif
-
- CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), ©_lsn);
- if (DB_REDO(op) &&
- (cmp_p == 0 ||
- (IS_ZERO_LSN(copy_lsn) &&
- log_compare(&LSN(pagep), &argp->meta_lsn) <= 0))) {
- /* Need to redo the deallocation. */
-#ifdef HAVE_FTRUNCATE
- /*
- * The page can be truncated if it was truncated at runtime
- * and the current metapage reflects the truncation.
- */
- if (is_meta && meta->last_pgno <= argp->pgno &&
- argp->last_pgno <= argp->pgno) {
- if ((ret =
- __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0)
- goto out;
- pagep = NULL;
- if ((ret = __memp_ftruncate(mpf, argp->pgno, 0)) != 0)
- goto out;
- } else if (argp->last_pgno == argp->pgno) {
- /* The page was truncated at runtime, zero it out. */
- P_INIT(pagep, 0, PGNO_INVALID,
- PGNO_INVALID, PGNO_INVALID, 0, P_INVALID);
- ZERO_LSN(pagep->lsn);
- modified = 1;
- } else
-#endif
- {
- P_INIT(pagep, file_dbp->pgsize,
- argp->pgno, PGNO_INVALID, argp->next, 0, P_INVALID);
- pagep->lsn = *lsnp;
-
- modified = 1;
- }
- } else if (cmp_n == 0 && DB_UNDO(op)) {
- /* Need to reallocate the page. */
- memcpy(pagep, argp->header.data, argp->header.size);
- if (data)
- memcpy((u_int8_t*)pagep + HOFFSET(pagep),
- argp->data.data, argp->data.size);
-
- modified = 1;
- }
- if (pagep != NULL &&
- (ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
- pagep = NULL;
-#ifdef HAVE_FTRUNCATE
- /*
- * If we are keeping an in memory free list remove this
- * element from the list.
- */
- if (op == DB_TXN_ABORT && argp->pgno != argp->last_pgno) {
- db_pgno_t *lp;
- u_int32_t nelem, pos;
-
- if ((ret = __memp_get_freelist(mpf, &nelem, &lp)) != 0)
- goto out;
- if (lp != NULL) {
- pos = 0;
- if (!is_meta && nelem != 0) {
- __db_freelist_pos(argp->pgno, lp, nelem, &pos);
-
- DB_ASSERT(argp->pgno == lp[pos]);
- DB_ASSERT(argp->meta_pgno == lp[pos - 1]);
- }
-
- if (nelem != 0 && pos != nelem)
- memmove(&lp[pos], &lp[pos + 1],
- (nelem - pos) * sizeof(*lp));
-
- /* Shrink the list */
- if ((ret =
- __memp_extend_freelist(mpf, nelem - 1, &lp)) != 0)
- goto out;
- }
- }
-done:
-#endif
- if (meta != NULL && (ret = __memp_fput(mpf,
- meta, meta_modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
- meta = NULL;
-
- ret = 0;
-
-out: if (pagep != NULL)
- (void)__memp_fput(mpf, pagep, 0);
- if (meta != NULL)
- (void)__memp_fput(mpf, meta, 0);
-
- return (ret);
-}
-
-/*
- * __db_pg_free_recover --
- * Recovery function for pg_free.
- *
- * PUBLIC: int __db_pg_free_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__db_pg_free_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- __db_pg_free_args *argp;
- int ret;
-
- COMPQUIET(info, NULL);
- REC_PRINT(__db_pg_free_print);
- REC_INTRO(__db_pg_free_read, 1, 0);
-
- ret = __db_pg_free_recover_int(dbenv,
- (__db_pg_freedata_args *)argp, file_dbp, lsnp, mpf, op, 0);
-
-done: *lsnp = argp->prev_lsn;
-out:
- REC_CLOSE;
-}
-
-/*
- * __db_pg_new_recover --
- * A new page from the file was put on the free list.
- * This record is only generated during a LIMBO_COMPENSATE.
- *
- * PUBLIC: int __db_pg_new_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__db_pg_new_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
-#ifndef HAVE_FTRUNCATE
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- __db_pg_free_args *argp;
- int ret;
-
- REC_PRINT(__db_pg_free_print);
- REC_INTRO(__db_pg_free_read, 1, 0);
- COMPQUIET(op, DB_TXN_ABORT);
-
- if ((ret =
- __db_add_limbo(dbenv, info, argp->fileid, argp->pgno, 1)) == 0)
- *lsnp = argp->prev_lsn;
-
-done:
-out:
- REC_CLOSE;
-#else
- COMPQUIET(dbenv, NULL);
- COMPQUIET(dbtp, NULL);
- COMPQUIET(lsnp, NULL);
- COMPQUIET(op, DB_TXN_PRINT);
- COMPQUIET(info, NULL);
- return (0);
-#endif
-}
-
-/*
- * __db_pg_freedata_recover --
- * Recovery function for pg_freedata.
- *
- * PUBLIC: int __db_pg_freedata_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__db_pg_freedata_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- __db_pg_freedata_args *argp;
- int ret;
-
- COMPQUIET(info, NULL);
- REC_PRINT(__db_pg_freedata_print);
- REC_INTRO(__db_pg_freedata_read, 1, 0);
-
- ret = __db_pg_free_recover_int(dbenv, argp, file_dbp, lsnp, mpf, op, 1);
-
-done: *lsnp = argp->prev_lsn;
-out:
- REC_CLOSE;
-}
-
-/*
- * __db_cksum_recover --
- * Recovery function for checksum failure log record.
- *
- * PUBLIC: int __db_cksum_recover __P((DB_ENV *,
- * PUBLIC: DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__db_cksum_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- __db_cksum_args *argp;
-
- int ret;
-
- COMPQUIET(info, NULL);
- COMPQUIET(lsnp, NULL);
- COMPQUIET(op, DB_TXN_ABORT);
-
- REC_PRINT(__db_cksum_print);
-
- if ((ret = __db_cksum_read(dbenv, dbtp->data, &argp)) != 0)
- return (ret);
-
- /*
- * We had a checksum failure -- the only option is to run catastrophic
- * recovery.
- */
- if (F_ISSET(dbenv, DB_ENV_FATAL))
- ret = 0;
- else {
- __db_err(dbenv,
- "Checksum failure requires catastrophic recovery");
- ret = __db_panic(dbenv, DB_RUNRECOVERY);
- }
-
- __os_free(dbenv, argp);
- return (ret);
-}
-
-/*
- * __db_pg_prepare_recover --
- * Recovery function for pg_prepare.
- *
- * PUBLIC: int __db_pg_prepare_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__db_pg_prepare_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
-#ifndef HAVE_FTRUNCATE
- __db_pg_prepare_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int ret, t_ret;
-
- REC_PRINT(__db_pg_prepare_print);
- REC_INTRO(__db_pg_prepare_read, 1, 0);
-
- mpf = file_dbp->mpf;
-
- /*
- * If this made it into the limbo list at prepare time then
- * it was a new free page allocated by an aborted subtransaction.
- * Only that subtransaction could have toched the page.
- * All other pages in the free list at this point are
- * either of the same nature or were put there by this subtransactions
- * other subtransactions that followed this one. If
- * they were put there by this subtransaction the log records
- * of the following allocations will reflect that.
- * Note that only one transaction could have had the
- * metapage locked at the point of the crash.
- * All this is to say that we can P_INIT this page without
- * loosing other pages on the free list because they
- * will be linked in by records earlier in the log for
- * this transaction which we will roll back.
- */
- if (op == DB_TXN_ABORT) {
- if ((ret = __memp_fget(
- mpf, &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- P_INIT(pagep, file_dbp->pgsize,
- argp->pgno, PGNO_INVALID, PGNO_INVALID, 0, P_INVALID);
- ZERO_LSN(pagep->lsn);
- ret = __db_add_limbo(dbenv, info, argp->fileid, argp->pgno, 1);
- if ((t_ret =
- __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0 && ret == 0)
- ret = t_ret;
- }
-
-done: if (ret == 0)
- *lsnp = argp->prev_lsn;
-out: REC_CLOSE;
-#else
- COMPQUIET(dbenv, NULL);
- COMPQUIET(dbtp, NULL);
- COMPQUIET(lsnp, NULL);
- COMPQUIET(op, DB_TXN_PRINT);
- COMPQUIET(info, NULL);
- return (0);
-#endif
-
-}
-
-/*
- * __db_pg_init_recover --
- * Recovery function to reinit pages for truncate.
- *
- * PUBLIC: int __db_pg_init_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__db_pg_init_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
- __db_pg_init_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DB_LSN copy_lsn;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- int cmp_n, cmp_p, modified, ret, type;
-
- COMPQUIET(info, NULL);
- REC_PRINT(__db_pg_init_print);
- REC_INTRO(__db_pg_init_read, 1, 0);
-
- mpf = file_dbp->mpf;
- REC_FGET(mpf, argp->pgno, &pagep, done);
-
- modified = 0;
- (void)__ua_memcpy(©_lsn, &LSN(argp->header.data), sizeof(DB_LSN));
- cmp_n = log_compare(lsnp, &LSN(pagep));
- cmp_p = log_compare(&LSN(pagep), ©_lsn);
- CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), ©_lsn);
-
- if (cmp_p == 0 && DB_REDO(op)) {
- if (TYPE(pagep) == P_HASH)
- type = P_HASH;
- else
- type = file_dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE;
- P_INIT(pagep, file_dbp->pgsize, PGNO(pagep), PGNO_INVALID,
- PGNO_INVALID, TYPE(pagep) == P_HASH ? 0 : 1, type);
- pagep->lsn = *lsnp;
- modified = 1;
- } else if (cmp_n == 0 && DB_UNDO(op)) {
- /* Put the data back on the page. */
- memcpy(pagep, argp->header.data, argp->header.size);
- if (argp->data.size > 0)
- memcpy((u_int8_t*)pagep + HOFFSET(pagep),
- argp->data.data, argp->data.size);
-
- modified = 1;
- }
- if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
-out:
- REC_CLOSE;
-}
-
-/*
- * __db_pg_sort_recover --
- * Recovery function for pg_sort.
- *
- * PUBLIC: int __db_pg_sort_recover
- * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
- */
-int
-__db_pg_sort_recover(dbenv, dbtp, lsnp, op, info)
- DB_ENV *dbenv;
- DBT *dbtp;
- DB_LSN *lsnp;
- db_recops op;
- void *info;
-{
-#ifdef HAVE_FTRUNCATE
- __db_pg_sort_args *argp;
- DB *file_dbp;
- DBC *dbc;
- DBMETA *meta;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- db_pgno_t pgno, *list;
- u_int32_t felem, nelem;
- struct pglist *pglist, *lp;
- int modified, ret;
-
- COMPQUIET(info, NULL);
-
- REC_PRINT(__db_pg_sort_print);
- REC_INTRO(__db_pg_sort_read, 1, 1);
-
- modified = 0;
-
- pglist = (struct pglist *) argp->list.data;
- nelem = argp->list.size / sizeof(struct pglist);
- if (DB_REDO(op)) {
- pgno = argp->last_pgno;
- if ((ret = __db_pg_truncate(mpf,
- pglist, NULL, &nelem, &pgno, lsnp, 1)) != 0)
- goto out;
-
- if (argp->last_free != PGNO_INVALID) {
- if ((ret = __memp_fget(mpf,
- &argp->last_free, 0, &meta)) == 0) {
- if (log_compare(&LSN(meta),
- &argp->last_lsn) == 0) {
- NEXT_PGNO(meta) = PGNO_INVALID;
- LSN(meta) = *lsnp;
- modified = 1;
- }
- if ((ret = __memp_fput(mpf,
- meta, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
- meta = NULL;
- modified = 0;
- } else if (ret != DB_PAGE_NOTFOUND)
- goto out;
- }
- if ((ret = __memp_fget(mpf, &argp->meta, 0, &meta)) != 0)
- goto out;
- if (log_compare(&LSN(meta), &argp->meta_lsn) == 0) {
- if (argp->last_free == PGNO_INVALID) {
- if (nelem == 0)
- meta->free = PGNO_INVALID;
- else
- meta->free = pglist->pgno;
- }
- meta->last_pgno = pgno;
- LSN(meta) = *lsnp;
- modified = 1;
- }
- } else {
- /* Put the free list back in its original order. */
- for (lp = pglist; lp < &pglist[nelem]; lp++) {
- if ((ret = __memp_fget(mpf,
- &lp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)
- goto out;
- if (IS_ZERO_LSN(LSN(pagep)) ||
- log_compare(&LSN(pagep), lsnp) == 0) {
- if (lp == &pglist[nelem - 1])
- pgno = PGNO_INVALID;
- else
- pgno = lp[1].pgno;
-
- P_INIT(pagep, file_dbp->pgsize,
- lp->pgno, PGNO_INVALID, pgno, 0, P_INVALID);
- LSN(pagep) = lp->lsn;
- modified = 1;
- }
- if ((ret = __memp_fput(mpf,
- pagep, modified ? DB_MPOOL_DIRTY: 0)) != 0)
- goto out;
- }
- if (argp->last_free != PGNO_INVALID) {
- if ((ret = __memp_fget(mpf,
- &argp->last_free, 0, &meta)) == 0) {
- if (log_compare(&LSN(meta), lsnp) == 0) {
- NEXT_PGNO(meta) = pglist->pgno;
- LSN(meta) = argp->last_lsn;
- modified = 1;
- }
- if ((ret = __memp_fput(mpf,
- meta, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
- } else if (ret != DB_PAGE_NOTFOUND)
- goto out;
- modified = 0;
- meta = NULL;
- }
- if ((ret = __memp_fget(mpf, &argp->meta, 0, &meta)) != 0)
- goto out;
- if (log_compare(&LSN(meta), lsnp) == 0) {
- meta->last_pgno = argp->last_pgno;
- if (argp->last_pgno == PGNO_INVALID)
- meta->free = pglist->pgno;
- LSN(meta) = argp->meta_lsn;
- modified = 1;
- }
- }
- if (op == DB_TXN_ABORT) {
- if ((ret = __memp_get_freelist(mpf, &felem, &list)) != 0)
- goto out;
- if (list != NULL) {
- DB_ASSERT(felem == 0 ||
- argp->last_free == list[felem - 1]);
- if ((ret = __memp_extend_freelist(
- mpf, felem + nelem, &list)) != 0)
- goto out;
- for (lp = pglist; lp < &pglist[nelem]; lp++)
- list[felem++] = lp->pgno;
- }
- }
-
- if ((ret = __memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)) != 0)
- goto out;
-
-done: *lsnp = argp->prev_lsn;
- ret = 0;
-
-out: REC_CLOSE;
-#else
- /*
- * If HAVE_FTRUNCATE is not defined, we'll never see pg_sort records
- * to recover.
- */
- COMPQUIET(dbenv, NULL);
- COMPQUIET(dbtp, NULL);
- COMPQUIET(lsnp, NULL);
- COMPQUIET(op, DB_TXN_ABORT);
- COMPQUIET(info, NULL);
- return (EINVAL);
-#endif
-}
diff --git a/storage/bdb/db/db_reclaim.c b/storage/bdb/db/db_reclaim.c
deleted file mode 100644
index ed68bc6eae7..00000000000
--- a/storage/bdb/db/db_reclaim.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_reclaim.c,v 12.2 2005/06/16 20:21:14 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/btree.h"
-#include "dbinc/mp.h"
-
-/*
- * __db_traverse_big
- * Traverse a chain of overflow pages and call the callback routine
- * on each one. The calling convention for the callback is:
- * callback(dbp, page, cookie, did_put),
- * where did_put is a return value indicating if the page in question has
- * already been returned to the mpool.
- *
- * PUBLIC: int __db_traverse_big __P((DB *,
- * PUBLIC: db_pgno_t, int (*)(DB *, PAGE *, void *, int *), void *));
- */
-int
-__db_traverse_big(dbp, pgno, callback, cookie)
- DB *dbp;
- db_pgno_t pgno;
- int (*callback) __P((DB *, PAGE *, void *, int *));
- void *cookie;
-{
- DB_MPOOLFILE *mpf;
- PAGE *p;
- int did_put, ret;
-
- mpf = dbp->mpf;
-
- do {
- did_put = 0;
- if ((ret = __memp_fget(mpf, &pgno, 0, &p)) != 0)
- return (ret);
- /*
- * If we are freeing pages only process the overflow
- * chain if the head of the chain has a refcount of 1.
- */
- pgno = NEXT_PGNO(p);
- if (callback == __db_truncate_callback && OV_REF(p) != 1)
- pgno = PGNO_INVALID;
- if ((ret = callback(dbp, p, cookie, &did_put)) == 0 &&
- !did_put)
- ret = __memp_fput(mpf, p, 0);
- } while (ret == 0 && pgno != PGNO_INVALID);
-
- return (ret);
-}
-
-/*
- * __db_reclaim_callback
- * This is the callback routine used during a delete of a subdatabase.
- * we are traversing a btree or hash table and trying to free all the
- * pages. Since they share common code for duplicates and overflow
- * items, we traverse them identically and use this routine to do the
- * actual free. The reason that this is callback is because hash uses
- * the same traversal code for statistics gathering.
- *
- * PUBLIC: int __db_reclaim_callback __P((DB *, PAGE *, void *, int *));
- */
-int
-__db_reclaim_callback(dbp, p, cookie, putp)
- DB *dbp;
- PAGE *p;
- void *cookie;
- int *putp;
-{
- int ret;
-
- /*
- * We don't want to log the free of the root with the subdb.
- * If we abort then the subdb may not be openable to undo
- * the free.
- */
-
- if ((dbp->type == DB_BTREE || dbp->type == DB_RECNO) &&
- PGNO(p) == ((BTREE *)dbp->bt_internal)->bt_root)
- return (0);
- if ((ret = __db_free(cookie, p)) != 0)
- return (ret);
- *putp = 1;
-
- return (0);
-}
-
-/*
- * __db_truncate_callback
- * This is the callback routine used during a truncate.
- * we are traversing a btree or hash table and trying to free all the
- * pages.
- *
- * PUBLIC: int __db_truncate_callback __P((DB *, PAGE *, void *, int *));
- */
-int
-__db_truncate_callback(dbp, p, cookie, putp)
- DB *dbp;
- PAGE *p;
- void *cookie;
- int *putp;
-{
- DB_MPOOLFILE *mpf;
- DBT ddbt, ldbt;
- db_indx_t indx, len, off, tlen, top;
- db_trunc_param *param;
- u_int8_t *hk, type;
- int ret;
-
- top = NUM_ENT(p);
- mpf = dbp->mpf;
- param = cookie;
- *putp = 1;
-
- switch (TYPE(p)) {
- case P_LBTREE:
- /* Skip for off-page duplicates and deleted items. */
- for (indx = 0; indx < top; indx += P_INDX) {
- type = GET_BKEYDATA(dbp, p, indx + O_INDX)->type;
- if (!B_DISSET(type) && B_TYPE(type) != B_DUPLICATE)
- ++param->count;
- }
- /* FALLTHROUGH */
- case P_IBTREE:
- case P_IRECNO:
- case P_INVALID:
- if (dbp->type != DB_HASH &&
- ((BTREE *)dbp->bt_internal)->bt_root == PGNO(p)) {
- type = dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE;
- goto reinit;
- }
- break;
- case P_OVERFLOW:
- if (DBC_LOGGING(param->dbc)) {
- if ((ret = __db_ovref_log(dbp, param->dbc->txn,
- &LSN(p), 0, p->pgno, -1, &LSN(p))) != 0)
- return (ret);
- } else
- LSN_NOT_LOGGED(LSN(p));
- if (--OV_REF(p) != 0)
- *putp = 0;
- break;
- case P_LRECNO:
- for (indx = 0; indx < top; indx += O_INDX) {
- type = GET_BKEYDATA(dbp, p, indx)->type;
- if (!B_DISSET(type))
- ++param->count;
- }
-
- if (((BTREE *)dbp->bt_internal)->bt_root == PGNO(p)) {
- type = P_LRECNO;
- goto reinit;
- }
- break;
- case P_LDUP:
- /* Correct for deleted items. */
- for (indx = 0; indx < top; indx += O_INDX)
- if (!B_DISSET(GET_BKEYDATA(dbp, p, indx)->type))
- ++param->count;
-
- break;
- case P_HASH:
- /* Correct for on-page duplicates and deleted items. */
- for (indx = 0; indx < top; indx += P_INDX) {
- switch (*H_PAIRDATA(dbp, p, indx)) {
- case H_OFFDUP:
- break;
- case H_OFFPAGE:
- case H_KEYDATA:
- ++param->count;
- break;
- case H_DUPLICATE:
- tlen = LEN_HDATA(dbp, p, 0, indx);
- hk = H_PAIRDATA(dbp, p, indx);
- for (off = 0; off < tlen;
- off += len + 2 * sizeof(db_indx_t)) {
- ++param->count;
- memcpy(&len,
- HKEYDATA_DATA(hk)
- + off, sizeof(db_indx_t));
- }
- break;
- default:
- return (__db_pgfmt(dbp->dbenv, p->pgno));
- }
- }
- /* Don't free the head of the bucket. */
- if (PREV_PGNO(p) == PGNO_INVALID) {
- type = P_HASH;
-
-reinit: *putp = 0;
- if (DBC_LOGGING(param->dbc)) {
- memset(&ldbt, 0, sizeof(ldbt));
- memset(&ddbt, 0, sizeof(ddbt));
- ldbt.data = p;
- ldbt.size = P_OVERHEAD(dbp);
- ldbt.size += p->entries * sizeof(db_indx_t);
- ddbt.data = (u_int8_t *)p + HOFFSET(p);
- ddbt.size = dbp->pgsize - HOFFSET(p);
- if ((ret = __db_pg_init_log(dbp,
- param->dbc->txn, &LSN(p), 0,
- p->pgno, &ldbt, &ddbt)) != 0)
- return (ret);
- } else
- LSN_NOT_LOGGED(LSN(p));
-
- P_INIT(p, dbp->pgsize, PGNO(p), PGNO_INVALID,
- PGNO_INVALID, type == P_HASH ? 0 : 1, type);
- }
- break;
- default:
- return (__db_pgfmt(dbp->dbenv, p->pgno));
- }
-
- if (*putp == 1) {
- if ((ret = __db_free(param->dbc, p)) != 0)
- return (ret);
- } else {
- if ((ret = __memp_fput(mpf, p, DB_MPOOL_DIRTY)) != 0)
- return (ret);
- *putp = 1;
- }
-
- return (0);
-}
diff --git a/storage/bdb/db/db_remove.c b/storage/bdb/db/db_remove.c
deleted file mode 100644
index c37c1876dd7..00000000000
--- a/storage/bdb/db/db_remove.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 2001-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_remove.c,v 12.16 2005/10/27 01:25:53 mjc Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/fop.h"
-#include "dbinc/btree.h"
-#include "dbinc/hash.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/lock.h"
-#include "dbinc/mp.h"
-#include "dbinc/txn.h"
-
-static int __db_dbtxn_remove __P((DB *, DB_TXN *, const char *, const char *));
-static int __db_subdb_remove __P((DB *, DB_TXN *, const char *, const char *));
-
-/*
- * __env_dbremove_pp
- * DB_ENV->dbremove pre/post processing.
- *
- * PUBLIC: int __env_dbremove_pp __P((DB_ENV *,
- * PUBLIC: DB_TXN *, const char *, const char *, u_int32_t));
- */
-int
-__env_dbremove_pp(dbenv, txn, name, subdb, flags)
- DB_ENV *dbenv;
- DB_TXN *txn;
- const char *name, *subdb;
- u_int32_t flags;
-{
- DB *dbp;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret, txn_local;
-
- dbp = NULL;
- txn_local = 0;
-
- PANIC_CHECK(dbenv);
- ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->dbremove");
-
- /*
- * The actual argument checking is simple, do it inline, outside of
- * the replication block.
- */
- if ((ret = __db_fchk(dbenv, "DB->remove", flags, DB_AUTO_COMMIT)) != 0)
- return (ret);
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret = __env_rep_enter(dbenv, 1)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- /*
- * Create local transaction as necessary, check for consistent
- * transaction usage.
- */
- if (IS_ENV_AUTO_COMMIT(dbenv, txn, flags)) {
- if ((ret = __db_txn_auto_init(dbenv, &txn)) != 0)
- goto err;
- txn_local = 1;
- } else
- if (txn != NULL && !TXN_ON(dbenv)) {
- ret = __db_not_txn_env(dbenv);
- goto err;
- }
- LF_CLR(DB_AUTO_COMMIT);
-
- if ((ret = db_create(&dbp, dbenv, 0)) != 0)
- goto err;
-
- ret = __db_remove_int(dbp, txn, name, subdb, flags);
-
- if (txn_local) {
- /*
- * We created the DBP here and when we commit/abort, we'll
- * release all the transactional locks, including the handle
- * lock; mark the handle cleared explicitly.
- */
- LOCK_INIT(dbp->handle_lock);
- dbp->lid = DB_LOCK_INVALIDID;
- } else if (txn != NULL) {
- /*
- * We created this handle locally so we need to close it
- * and clean it up. Unfortunately, it's holding transactional
- * locks that need to persist until the end of transaction.
- * If we invalidate the locker id (dbp->lid), then the close
- * won't free these locks prematurely.
- */
- dbp->lid = DB_LOCK_INVALIDID;
- }
-
-err: if (txn_local && (t_ret =
- __db_txn_auto_resolve(dbenv, txn, 0, ret)) != 0 && ret == 0)
- ret = t_ret;
-
- /*
- * We never opened this dbp for real, so don't include a transaction
- * handle, and use NOSYNC to avoid calling into mpool.
- *
- * !!!
- * Note we're reversing the order of operations: we started the txn and
- * then opened the DB handle; we're resolving the txn and then closing
- * closing the DB handle -- it's safer.
- */
- if (dbp != NULL &&
- (t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0)
- ret = t_ret;
-
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_remove_pp
- * DB->remove pre/post processing.
- *
- * PUBLIC: int __db_remove_pp
- * PUBLIC: __P((DB *, const char *, const char *, u_int32_t));
- */
-int
-__db_remove_pp(dbp, name, subdb, flags)
- DB *dbp;
- const char *name, *subdb;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
-
- /*
- * Validate arguments, continuing to destroy the handle on failure.
- *
- * Cannot use DB_ILLEGAL_AFTER_OPEN directly because it returns.
- *
- * !!!
- * We have a serious problem if we're here with a handle used to open
- * a database -- we'll destroy the handle, and the application won't
- * ever be able to close the database.
- */
- if (F_ISSET(dbp, DB_AM_OPEN_CALLED)) {
- ret = __db_mi_open(dbenv, "DB->remove", 1);
- return (ret);
- }
-
- /* Validate arguments. */
- if ((ret = __db_fchk(dbenv, "DB->remove", flags, 0)) != 0)
- return (ret);
-
- /* Check for consistent transaction usage. */
- if ((ret = __db_check_txn(dbp, NULL, DB_LOCK_INVALIDID, 0)) != 0)
- return (ret);
-
- ENV_ENTER(dbenv, ip);
-
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret = __db_rep_enter(dbp, 1, 1, 0)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- /* Remove the file. */
- ret = __db_remove(dbp, NULL, name, subdb, flags);
-
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_remove
- * DB->remove method.
- *
- * PUBLIC: int __db_remove
- * PUBLIC: __P((DB *, DB_TXN *, const char *, const char *, u_int32_t));
- */
-int
-__db_remove(dbp, txn, name, subdb, flags)
- DB *dbp;
- DB_TXN *txn;
- const char *name, *subdb;
- u_int32_t flags;
-{
- int ret, t_ret;
-
- ret = __db_remove_int(dbp, txn, name, subdb, flags);
-
- if ((t_ret = __db_close(dbp, txn, DB_NOSYNC)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_remove_int
- * Worker function for the DB->remove method.
- *
- * PUBLIC: int __db_remove_int __P((DB *,
- * PUBLIC: DB_TXN *, const char *, const char *, u_int32_t));
- */
-int
-__db_remove_int(dbp, txn, name, subdb, flags)
- DB *dbp;
- DB_TXN *txn;
- const char *name, *subdb;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- int ret;
- char *real_name, *tmpname;
-
- dbenv = dbp->dbenv;
- real_name = tmpname = NULL;
-
- if (name == NULL && subdb == NULL) {
- __db_err(dbenv, "Remove on temporary files invalid");
- ret = EINVAL;
- goto err;
- }
-
- if (name == NULL) {
- MAKE_INMEM(dbp);
- real_name = (char *)subdb;
- } else if (subdb != NULL) {
- ret = __db_subdb_remove(dbp, txn, name, subdb);
- goto err;
- }
-
- /* Handle transactional file removes separately. */
- if (txn != NULL) {
- ret = __db_dbtxn_remove(dbp, txn, name, subdb);
- goto err;
- }
-
- /*
- * The remaining case is a non-transactional file remove.
- *
- * Find the real name of the file.
- */
- if (!F_ISSET(dbp, DB_AM_INMEM) && (ret =
- __db_appname(dbenv, DB_APP_DATA, name, 0, NULL, &real_name)) != 0)
- goto err;
-
- /*
- * If this is a file and force is set, remove the temporary file, which
- * may have been left around. Ignore errors because the temporary file
- * might not exist.
- */
- if (!F_ISSET(dbp, DB_AM_INMEM) && LF_ISSET(DB_FORCE) &&
- (ret = __db_backup_name(dbenv, real_name, NULL, &tmpname)) == 0)
- (void)__os_unlink(dbenv, tmpname);
-
- if ((ret = __fop_remove_setup(dbp, NULL, real_name, 0)) != 0)
- goto err;
-
- if (dbp->db_am_remove != NULL &&
- (ret = dbp->db_am_remove(dbp, NULL, name, subdb)) != 0)
- goto err;
-
- ret = F_ISSET(dbp, DB_AM_INMEM) ?
- __db_inmem_remove(dbp, NULL, real_name) :
- __fop_remove(dbenv, NULL, dbp->fileid, name, DB_APP_DATA,
- F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0);
-
-err: if (!F_ISSET(dbp, DB_AM_INMEM) && real_name != NULL)
- __os_free(dbenv, real_name);
- if (tmpname != NULL)
- __os_free(dbenv, tmpname);
-
- return (ret);
-}
-
-/*
- * __db_inmem_remove --
- * Removal of a named in-memory database.
- * PUBLIC: int __db_inmem_remove __P((DB *, DB_TXN *, const char *));
- */
-int
-__db_inmem_remove(dbp, txn, name)
- DB *dbp;
- DB_TXN *txn;
- const char *name;
-{
- DB_ENV *dbenv;
- DB_LSN lsn;
- DBT fid_dbt, name_dbt;
- u_int32_t locker;
- int ret;
-
- dbenv = dbp->dbenv;
- locker = DB_LOCK_INVALIDID;
-
- DB_ASSERT(name != NULL);
-
- /* This had better exist if we are trying to do a remove. */
- (void)__memp_set_flags(dbp->mpf, DB_MPOOL_NOFILE, 1);
- if ((ret = __memp_fopen(dbp->mpf, NULL, name, 0, 0, 0)) != 0)
- return (ret);
- if ((ret = __memp_get_fileid(dbp->mpf, dbp->fileid)) != 0)
- goto err;
- dbp->preserve_fid = 1;
-
- if (LOCKING_ON(dbenv)) {
- if (dbp->lid == DB_LOCK_INVALIDID &&
- (ret = __lock_id(dbenv, &dbp->lid, NULL)) != 0)
- goto err;
- locker = txn == NULL ? dbp->lid : txn->txnid;
- }
-
- /*
- * In a transactional environment, we'll play the same game
- * that we play for databases in the file system -- create a
- * temporary database and put it in with the current name
- * and then rename this one to another name. We'll then use
- * a commit-time event to remove the entry.
- */
-
- if ((ret = __fop_lock_handle(dbenv,
- dbp, locker, DB_LOCK_WRITE, NULL, 0)) != 0)
- goto err;
-
- if (LOGGING_ON(dbenv)) {
- memset(&fid_dbt, 0, sizeof(fid_dbt));
- fid_dbt.data = dbp->fileid;
- fid_dbt.size = DB_FILE_ID_LEN;
- memset(&name_dbt, 0, sizeof(name_dbt));
- name_dbt.data = (void *)name;
- name_dbt.size = (u_int32_t)strlen(name) + 1;
-
- if (txn != NULL && (ret =
- __txn_remevent(dbenv, txn, name, dbp->fileid, 1)) != 0)
- goto err;
-
- if ((ret = __crdel_inmem_remove_log(dbenv,
- txn, &lsn, 0, &name_dbt, &fid_dbt)) != 0)
- goto err;
- }
-
- if (txn == NULL)
- ret = __memp_nameop(dbenv, dbp->fileid, NULL, name, NULL, 1);
-
-err: return (ret);
-}
-
-/*
- * __db_subdb_remove --
- * Remove a subdatabase.
- */
-static int
-__db_subdb_remove(dbp, txn, name, subdb)
- DB *dbp;
- DB_TXN *txn;
- const char *name, *subdb;
-{
- DB *mdbp, *sdbp;
- int ret, t_ret;
-
- mdbp = sdbp = NULL;
-
- /* Open the subdatabase. */
- if ((ret = db_create(&sdbp, dbp->dbenv, 0)) != 0)
- goto err;
- if ((ret = __db_open(sdbp,
- txn, name, subdb, DB_UNKNOWN, DB_WRITEOPEN, 0, PGNO_BASE_MD)) != 0)
- goto err;
-
- DB_TEST_RECOVERY(sdbp, DB_TEST_PREDESTROY, ret, name);
-
- /* Free up the pages in the subdatabase. */
- switch (sdbp->type) {
- case DB_BTREE:
- case DB_RECNO:
- if ((ret = __bam_reclaim(sdbp, txn)) != 0)
- goto err;
- break;
- case DB_HASH:
- if ((ret = __ham_reclaim(sdbp, txn)) != 0)
- goto err;
- break;
- case DB_QUEUE:
- case DB_UNKNOWN:
- default:
- ret = __db_unknown_type(
- sdbp->dbenv, "__db_subdb_remove", sdbp->type);
- goto err;
- }
-
- /*
- * Remove the entry from the main database and free the subdatabase
- * metadata page.
- */
- if ((ret = __db_master_open(sdbp, txn, name, 0, 0, &mdbp)) != 0)
- goto err;
-
- if ((ret = __db_master_update(
- mdbp, sdbp, txn, subdb, sdbp->type, MU_REMOVE, NULL, 0)) != 0)
- goto err;
-
- DB_TEST_RECOVERY(sdbp, DB_TEST_POSTDESTROY, ret, name);
-
-DB_TEST_RECOVERY_LABEL
-err:
- /* Close the main and subdatabases. */
- if ((t_ret = __db_close(sdbp, txn, 0)) != 0 && ret == 0)
- ret = t_ret;
-
- if (mdbp != NULL &&
- (t_ret = __db_close(mdbp, txn, DB_NOSYNC)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-static int
-__db_dbtxn_remove(dbp, txn, name, subdb)
- DB *dbp;
- DB_TXN *txn;
- const char *name, *subdb;
-{
- DB_ENV *dbenv;
- int ret;
- char *tmpname;
-
- dbenv = dbp->dbenv;
- tmpname = NULL;
-
- /*
- * This is a transactional remove, so we have to keep the name
- * of the file locked until the transaction commits. As a result,
- * we implement remove by renaming the file to some other name
- * (which creates a dummy named file as a placeholder for the
- * file being rename/dremoved) and then deleting that file as
- * a delayed remove at commit.
- */
- if ((ret = __db_backup_name(dbenv,
- F_ISSET(dbp, DB_AM_INMEM) ? subdb : name, txn, &tmpname)) != 0)
- return (ret);
-
- DB_TEST_RECOVERY(dbp, DB_TEST_PREDESTROY, ret, name);
-
- if ((ret = __db_rename_int(dbp, txn, name, subdb, tmpname)) != 0)
- goto err;
-
- /*
- * The internal removes will also translate into delayed removes.
- */
- if (dbp->db_am_remove != NULL &&
- (ret = dbp->db_am_remove(dbp, txn, tmpname, NULL)) != 0)
- goto err;
-
- ret = F_ISSET(dbp, DB_AM_INMEM) ?
- __db_inmem_remove(dbp, txn, tmpname) :
- __fop_remove(dbenv, txn, dbp->fileid, tmpname, DB_APP_DATA,
- F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0);
-
- DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, name);
-
-err:
-DB_TEST_RECOVERY_LABEL
- if (tmpname != NULL)
- __os_free(dbenv, tmpname);
-
- return (ret);
-}
diff --git a/storage/bdb/db/db_rename.c b/storage/bdb/db/db_rename.c
deleted file mode 100644
index 827d772751d..00000000000
--- a/storage/bdb/db/db_rename.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 2001-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_rename.c,v 12.11 2005/10/07 20:21:22 ubell Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/db_am.h"
-#include "dbinc/fop.h"
-#include "dbinc/lock.h"
-#include "dbinc/log.h"
-#include "dbinc/mp.h"
-
-static int __db_subdb_rename __P((DB *,
- DB_TXN *, const char *, const char *, const char *));
-
-/*
- * __env_dbrename_pp
- * DB_ENV->dbrename pre/post processing.
- *
- * PUBLIC: int __env_dbrename_pp __P((DB_ENV *, DB_TXN *,
- * PUBLIC: const char *, const char *, const char *, u_int32_t));
- */
-int
-__env_dbrename_pp(dbenv, txn, name, subdb, newname, flags)
- DB_ENV *dbenv;
- DB_TXN *txn;
- const char *name, *subdb, *newname;
- u_int32_t flags;
-{
- DB *dbp;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret, txn_local;
-
- dbp = NULL;
- txn_local = 0;
-
- PANIC_CHECK(dbenv);
- ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->dbrename");
-
- /*
- * The actual argument checking is simple, do it inline, outside of
- * the replication block.
- */
- if ((ret = __db_fchk(dbenv, "DB->rename", flags, DB_AUTO_COMMIT)) != 0)
- return (ret);
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret = __env_rep_enter(dbenv, 1)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- /*
- * Create local transaction as necessary, check for consistent
- * transaction usage.
- */
- if (IS_ENV_AUTO_COMMIT(dbenv, txn, flags)) {
- if ((ret = __db_txn_auto_init(dbenv, &txn)) != 0)
- goto err;
- txn_local = 1;
- } else
- if (txn != NULL && !TXN_ON(dbenv)) {
- ret = __db_not_txn_env(dbenv);
- goto err;
- }
-
- LF_CLR(DB_AUTO_COMMIT);
-
- if ((ret = db_create(&dbp, dbenv, 0)) != 0)
- goto err;
-
- ret = __db_rename_int(dbp, txn, name, subdb, newname);
-
- if (txn_local) {
- /*
- * We created the DBP here and when we commit/abort, we'll
- * release all the transactional locks, including the handle
- * lock; mark the handle cleared explicitly.
- */
- LOCK_INIT(dbp->handle_lock);
- dbp->lid = DB_LOCK_INVALIDID;
- } else if (txn != NULL) {
- /*
- * We created this handle locally so we need to close it
- * and clean it up. Unfortunately, it's holding transactional
- * locks that need to persist until the end of transaction.
- * If we invalidate the locker id (dbp->lid), then the close
- * won't free these locks prematurely.
- */
- dbp->lid = DB_LOCK_INVALIDID;
- }
-
-err: if (txn_local && (t_ret =
- __db_txn_auto_resolve(dbenv, txn, 0, ret)) != 0 && ret == 0)
- ret = t_ret;
-
- /*
- * We never opened this dbp for real, so don't include a transaction
- * handle, and use NOSYNC to avoid calling into mpool.
- *
- * !!!
- * Note we're reversing the order of operations: we started the txn and
- * then opened the DB handle; we're resolving the txn and then closing
- * closing the DB handle -- it's safer.
- */
- if (dbp != NULL &&
- (t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0)
- ret = t_ret;
-
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_rename_pp
- * DB->rename pre/post processing.
- *
- * PUBLIC: int __db_rename_pp __P((DB *,
- * PUBLIC: const char *, const char *, const char *, u_int32_t));
- */
-int
-__db_rename_pp(dbp, name, subdb, newname, flags)
- DB *dbp;
- const char *name, *subdb, *newname;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- dbenv = dbp->dbenv;
- handle_check = 0;
-
- PANIC_CHECK(dbenv);
-
- /*
- * Validate arguments, continuing to destroy the handle on failure.
- *
- * Cannot use DB_ILLEGAL_AFTER_OPEN directly because it returns.
- *
- * !!!
- * We have a serious problem if we're here with a handle used to open
- * a database -- we'll destroy the handle, and the application won't
- * ever be able to close the database.
- */
- if (F_ISSET(dbp, DB_AM_OPEN_CALLED))
- return (__db_mi_open(dbenv, "DB->rename", 1));
-
- /* Validate arguments. */
- if ((ret = __db_fchk(dbenv, "DB->rename", flags, 0)) != 0)
- return (ret);
-
- /* Check for consistent transaction usage. */
- if ((ret = __db_check_txn(dbp, NULL, DB_LOCK_INVALIDID, 0)) != 0)
- return (ret);
-
- ENV_ENTER(dbenv, ip);
-
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret = __db_rep_enter(dbp, 1, 1, 0)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- /* Rename the file. */
- ret = __db_rename(dbp, NULL, name, subdb, newname);
-
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_rename
- * DB->rename method.
- *
- * PUBLIC: int __db_rename
- * PUBLIC: __P((DB *, DB_TXN *, const char *, const char *, const char *));
- */
-int
-__db_rename(dbp, txn, name, subdb, newname)
- DB *dbp;
- DB_TXN *txn;
- const char *name, *subdb, *newname;
-{
- int ret, t_ret;
-
- ret = __db_rename_int(dbp, txn, name, subdb, newname);
-
- if ((t_ret = __db_close(dbp, txn, DB_NOSYNC)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_rename_int
- * Worker function for DB->rename method; the close of the dbp is
- * left in the wrapper routine.
- *
- * PUBLIC: int __db_rename_int
- * PUBLIC: __P((DB *, DB_TXN *, const char *, const char *, const char *));
- */
-int
-__db_rename_int(dbp, txn, name, subdb, newname)
- DB *dbp;
- DB_TXN *txn;
- const char *name, *subdb, *newname;
-{
- DB_ENV *dbenv;
- int ret;
- char *old, *real_name;
-
- dbenv = dbp->dbenv;
- real_name = NULL;
-
- DB_TEST_RECOVERY(dbp, DB_TEST_PREDESTROY, ret, name);
-
- if (name == NULL && subdb == NULL) {
- __db_err(dbenv, "Rename on temporary files invalid");
- ret = EINVAL;
- goto err;
- }
-
- if (name == NULL)
- MAKE_INMEM(dbp);
- else if (subdb != NULL) {
- ret = __db_subdb_rename(dbp, txn, name, subdb, newname);
- goto err;
- }
-
- /*
- * From here on down, this pertains to files or in-memory databases.
- *
- * Find the real name of the file.
- */
- if (F_ISSET(dbp, DB_AM_INMEM)) {
- old = (char *)subdb;
- real_name = (char *)subdb;
- } else {
- if ((ret = __db_appname(dbenv,
- DB_APP_DATA, name, 0, NULL, &real_name)) != 0)
- goto err;
- old = (char *)name;
- }
-
- if ((ret = __fop_remove_setup(dbp, txn, real_name, 0)) != 0)
- goto err;
-
- if (dbp->db_am_rename != NULL &&
- (ret = dbp->db_am_rename(dbp, txn, name, subdb, newname)) != 0)
- goto err;
-
- /*
- * The transactional case and non-transactional case are
- * quite different. In the non-transactional case, we simply
- * do the rename. In the transactional case, since we need
- * the ability to back out and maintain locking, we have to
- * create a temporary object as a placeholder. This is all
- * taken care of in the fop layer.
- */
- if (txn != NULL) {
- if ((ret = __fop_dummy(dbp, txn, old, newname, 0)) != 0)
- goto err;
- } else {
- if ((ret = __fop_dbrename(dbp, old, newname)) != 0)
- goto err;
- }
-
- /*
- * I am pretty sure that we haven't gotten a dbreg id, so calling
- * dbreg_filelist_update is not necessary.
- */
- DB_ASSERT(dbp->log_filename == NULL ||
- dbp->log_filename->id == DB_LOGFILEID_INVALID);
-
- DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, newname);
-
-DB_TEST_RECOVERY_LABEL
-err: if (!F_ISSET(dbp, DB_AM_INMEM) && real_name != NULL)
- __os_free(dbenv, real_name);
-
- return (ret);
-}
-
-/*
- * __db_subdb_rename --
- * Rename a subdatabase.
- */
-static int
-__db_subdb_rename(dbp, txn, name, subdb, newname)
- DB *dbp;
- DB_TXN *txn;
- const char *name, *subdb, *newname;
-{
- DB *mdbp;
- DB_ENV *dbenv;
- PAGE *meta;
- int ret, t_ret;
-
- mdbp = NULL;
- meta = NULL;
- dbenv = dbp->dbenv;
-
- /*
- * We have not opened this dbp so it isn't marked as a subdb,
- * but it ought to be.
- */
- F_SET(dbp, DB_AM_SUBDB);
-
- /*
- * Rename the entry in the main database. We need to first
- * get the meta-data page number (via MU_OPEN) so that we can
- * read the meta-data page and obtain a handle lock. Once we've
- * done that, we can proceed to do the rename in the master.
- */
- if ((ret = __db_master_open(dbp, txn, name, 0, 0, &mdbp)) != 0)
- goto err;
-
- if ((ret = __db_master_update(mdbp, dbp, txn, subdb, dbp->type,
- MU_OPEN, NULL, 0)) != 0)
- goto err;
-
- if ((ret = __memp_fget(mdbp->mpf, &dbp->meta_pgno, 0, &meta)) != 0)
- goto err;
- memcpy(dbp->fileid, ((DBMETA *)meta)->uid, DB_FILE_ID_LEN);
- if ((ret = __fop_lock_handle(dbenv,
- dbp, mdbp->lid, DB_LOCK_WRITE, NULL, NOWAIT_FLAG(txn))) != 0)
- goto err;
-
- ret = __memp_fput(mdbp->mpf, meta, 0);
- meta = NULL;
- if (ret != 0)
- goto err;
-
- if ((ret = __db_master_update(mdbp, dbp, txn,
- subdb, dbp->type, MU_RENAME, newname, 0)) != 0)
- goto err;
-
- DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, name);
-
-DB_TEST_RECOVERY_LABEL
-err:
- if (meta != NULL &&
- (t_ret = __memp_fput(mdbp->mpf, meta, 0)) != 0 && ret == 0)
- ret = t_ret;
-
- if (mdbp != NULL &&
- (t_ret = __db_close(mdbp, txn, DB_NOSYNC)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
diff --git a/storage/bdb/db/db_ret.c b/storage/bdb/db/db_ret.c
deleted file mode 100644
index 39446ea443c..00000000000
--- a/storage/bdb/db/db_ret.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_ret.c,v 12.1 2005/06/16 20:21:14 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_am.h"
-
-/*
- * __db_ret --
- * Build return DBT.
- *
- * PUBLIC: int __db_ret __P((DB *,
- * PUBLIC: PAGE *, u_int32_t, DBT *, void **, u_int32_t *));
- */
-int
-__db_ret(dbp, h, indx, dbt, memp, memsize)
- DB *dbp;
- PAGE *h;
- u_int32_t indx;
- DBT *dbt;
- void **memp;
- u_int32_t *memsize;
-{
- BKEYDATA *bk;
- HOFFPAGE ho;
- BOVERFLOW *bo;
- u_int32_t len;
- u_int8_t *hk;
- void *data;
-
- switch (TYPE(h)) {
- case P_HASH:
- hk = P_ENTRY(dbp, h, indx);
- if (HPAGE_PTYPE(hk) == H_OFFPAGE) {
- memcpy(&ho, hk, sizeof(HOFFPAGE));
- return (__db_goff(dbp, dbt,
- ho.tlen, ho.pgno, memp, memsize));
- }
- len = LEN_HKEYDATA(dbp, h, dbp->pgsize, indx);
- data = HKEYDATA_DATA(hk);
- break;
- case P_LBTREE:
- case P_LDUP:
- case P_LRECNO:
- bk = GET_BKEYDATA(dbp, h, indx);
- if (B_TYPE(bk->type) == B_OVERFLOW) {
- bo = (BOVERFLOW *)bk;
- return (__db_goff(dbp, dbt,
- bo->tlen, bo->pgno, memp, memsize));
- }
- len = bk->len;
- data = bk->data;
- break;
- default:
- return (__db_pgfmt(dbp->dbenv, h->pgno));
- }
-
- return (__db_retcopy(dbp->dbenv, dbt, data, len, memp, memsize));
-}
-
-/*
- * __db_retcopy --
- * Copy the returned data into the user's DBT, handling special flags.
- *
- * PUBLIC: int __db_retcopy __P((DB_ENV *, DBT *,
- * PUBLIC: void *, u_int32_t, void **, u_int32_t *));
- */
-int
-__db_retcopy(dbenv, dbt, data, len, memp, memsize)
- DB_ENV *dbenv;
- DBT *dbt;
- void *data;
- u_int32_t len;
- void **memp;
- u_int32_t *memsize;
-{
- int ret;
-
- ret = 0;
-
- /* If returning a partial record, reset the length. */
- if (F_ISSET(dbt, DB_DBT_PARTIAL)) {
- data = (u_int8_t *)data + dbt->doff;
- if (len > dbt->doff) {
- len -= dbt->doff;
- if (len > dbt->dlen)
- len = dbt->dlen;
- } else
- len = 0;
- }
-
- /*
- * Allocate memory to be owned by the application: DB_DBT_MALLOC,
- * DB_DBT_REALLOC.
- *
- * !!!
- * We always allocate memory, even if we're copying out 0 bytes. This
- * guarantees consistency, i.e., the application can always free memory
- * without concern as to how many bytes of the record were requested.
- *
- * Use the memory specified by the application: DB_DBT_USERMEM.
- *
- * !!!
- * If the length we're going to copy is 0, the application-supplied
- * memory pointer is allowed to be NULL.
- */
- if (F_ISSET(dbt, DB_DBT_MALLOC)) {
- ret = __os_umalloc(dbenv, len, &dbt->data);
- } else if (F_ISSET(dbt, DB_DBT_REALLOC)) {
- if (dbt->data == NULL || dbt->size == 0 || dbt->size < len)
- ret = __os_urealloc(dbenv, len, &dbt->data);
- } else if (F_ISSET(dbt, DB_DBT_USERMEM)) {
- if (len != 0 && (dbt->data == NULL || dbt->ulen < len))
- ret = DB_BUFFER_SMALL;
- } else if (memp == NULL || memsize == NULL) {
- ret = EINVAL;
- } else {
- if (len != 0 && (*memsize == 0 || *memsize < len)) {
- if ((ret = __os_realloc(dbenv, len, memp)) == 0)
- *memsize = len;
- else
- *memsize = 0;
- }
- if (ret == 0)
- dbt->data = *memp;
- }
-
- if (ret == 0 && len != 0)
- memcpy(dbt->data, data, len);
-
- /*
- * Return the length of the returned record in the DBT size field.
- * This satisfies the requirement that if we're using user memory
- * and insufficient memory was provided, return the amount necessary
- * in the size field.
- */
- dbt->size = len;
-
- return (ret);
-}
diff --git a/storage/bdb/db/db_setid.c b/storage/bdb/db/db_setid.c
deleted file mode 100644
index 4ba3ae9b4d2..00000000000
--- a/storage/bdb/db/db_setid.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 2000-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_setid.c,v 12.8 2005/10/18 14:17:08 mjc Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/db_swap.h"
-#include "dbinc/db_am.h"
-#include "dbinc/mp.h"
-
-static int __env_fileid_reset __P((DB_ENV *, const char *, int));
-
-/*
- * __env_fileid_reset_pp --
- * DB_ENV->fileid_reset pre/post processing.
- *
- * PUBLIC: int __env_fileid_reset_pp __P((DB_ENV *, const char *, u_int32_t));
- */
-int
-__env_fileid_reset_pp(dbenv, name, flags)
- DB_ENV *dbenv;
- const char *name;
- u_int32_t flags;
-{
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- PANIC_CHECK(dbenv);
- ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->fileid_reset");
-
- /*
- * !!!
- * The actual argument checking is simple, do it inline, outside of
- * the replication block.
- */
- if (flags != 0 && flags != DB_ENCRYPT)
- return (__db_ferr(dbenv, "DB_ENV->fileid_reset", 0));
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret = __env_rep_enter(dbenv, 1)) != 0)
- goto err;
-
- ret = __env_fileid_reset(dbenv, name, LF_ISSET(DB_ENCRYPT) ? 1 : 0);
-
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __env_fileid_reset --
- * Reset the file IDs for every database in the file.
- */
-static int
-__env_fileid_reset(dbenv, name, encrypted)
- DB_ENV *dbenv;
- const char *name;
- int encrypted;
-{
- DB *dbp;
- DBC *dbcp;
- DBT key, data;
- DB_MPOOLFILE *mpf;
- db_pgno_t pgno;
- int t_ret, ret;
- void *pagep;
- char *real_name;
- u_int8_t fileid[DB_FILE_ID_LEN];
-
- dbp = NULL;
- dbcp = NULL;
- real_name = NULL;
-
- /* Get the real backing file name. */
- if ((ret =
- __db_appname(dbenv, DB_APP_DATA, name, 0, NULL, &real_name)) != 0)
- return (ret);
-
- /* Get a new file ID. */
- if ((ret = __os_fileid(dbenv, real_name, 1, fileid)) != 0)
- goto err;
-
- /* Create the DB object. */
- if ((ret = db_create(&dbp, dbenv, 0)) != 0)
- goto err;
-
- /* If configured with a password, the databases are encrypted. */
- if (encrypted && (ret = __db_set_flags(dbp, DB_ENCRYPT)) != 0)
- goto err;
-
- /*
- * Open the DB file.
- *
- * !!!
- * Note DB_RDWRMASTER flag, we need to open the master database file
- * for writing in this case.
- */
- if ((ret = __db_open(dbp, NULL,
- name, NULL, DB_UNKNOWN, DB_RDWRMASTER, 0, PGNO_BASE_MD)) != 0)
- goto err;
-
- mpf = dbp->mpf;
-
- pgno = PGNO_BASE_MD;
- if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0)
- goto err;
- memcpy(((DBMETA *)pagep)->uid, fileid, DB_FILE_ID_LEN);
- if ((ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0)
- goto err;
-
- /*
- * If the database file doesn't support subdatabases, we only have
- * to update a single metadata page. Otherwise, we have to open a
- * cursor and step through the master database, and update all of
- * the subdatabases' metadata pages.
- */
- if (!F_ISSET(dbp, DB_AM_SUBDB))
- goto err;
-
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- if ((ret = __db_cursor(dbp, NULL, &dbcp, 0)) != 0)
- goto err;
- while ((ret = __db_c_get(dbcp, &key, &data, DB_NEXT)) == 0) {
- /*
- * XXX
- * We're handling actual data, not on-page meta-data, so it
- * hasn't been converted to/from opposite endian architectures.
- * Do it explicitly, now.
- */
- memcpy(&pgno, data.data, sizeof(db_pgno_t));
- DB_NTOHL(&pgno);
- if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0)
- goto err;
- memcpy(((DBMETA *)pagep)->uid, fileid, DB_FILE_ID_LEN);
- if ((ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0)
- goto err;
- }
- if (ret == DB_NOTFOUND)
- ret = 0;
-
-err: if (dbcp != NULL && (t_ret = __db_c_close(dbcp)) != 0 && ret == 0)
- ret = t_ret;
- if (dbp != NULL && (t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0)
- ret = t_ret;
- if (real_name != NULL)
- __os_free(dbenv, real_name);
-
- return (ret);
-}
diff --git a/storage/bdb/db/db_setlsn.c b/storage/bdb/db/db_setlsn.c
deleted file mode 100644
index ef07fc49925..00000000000
--- a/storage/bdb/db/db_setlsn.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 2000-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_setlsn.c,v 12.8 2005/10/21 19:17:40 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/db_am.h"
-#include "dbinc/mp.h"
-
-static int __env_lsn_reset __P((DB_ENV *, const char *, int));
-
-/*
- * __env_lsn_reset_pp --
- * DB_ENV->lsn_reset pre/post processing.
- *
- * PUBLIC: int __env_lsn_reset_pp __P((DB_ENV *, const char *, u_int32_t));
- */
-int
-__env_lsn_reset_pp(dbenv, name, flags)
- DB_ENV *dbenv;
- const char *name;
- u_int32_t flags;
-{
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- PANIC_CHECK(dbenv);
- ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->lsn_reset");
-
- /*
- * !!!
- * The actual argument checking is simple, do it inline, outside of
- * the replication block.
- */
- if (flags != 0 && flags != DB_ENCRYPT)
- return (__db_ferr(dbenv, "DB_ENV->lsn_reset", 0));
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret = __env_rep_enter(dbenv, 1)) != 0)
- goto err;
-
- ret = __env_lsn_reset(dbenv, name, LF_ISSET(DB_ENCRYPT) ? 1 : 0);
-
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __env_lsn_reset --
- * Reset the LSNs for every page in the file.
- */
-static int
-__env_lsn_reset(dbenv, name, encrypted)
- DB_ENV *dbenv;
- const char *name;
- int encrypted;
-{
- DB *dbp;
- DB_MPOOLFILE *mpf;
- PAGE *pagep;
- db_pgno_t pgno;
- int t_ret, ret;
-
- /* Create the DB object. */
- if ((ret = db_create(&dbp, dbenv, 0)) != 0)
- return (ret);
-
- /* If configured with a password, the databases are encrypted. */
- if (encrypted && (ret = __db_set_flags(dbp, DB_ENCRYPT)) != 0)
- goto err;
-
- /*
- * Open the DB file.
- *
- * !!!
- * Note DB_RDWRMASTER flag, we need to open the master database file
- * for writing in this case.
- */
- if ((ret = __db_open(dbp, NULL,
- name, NULL, DB_UNKNOWN, DB_RDWRMASTER, 0, PGNO_BASE_MD)) != 0)
- goto err;
-
- /* Reset the LSN on every page of the database file. */
- mpf = dbp->mpf;
- for (pgno = 0;
- (ret = __memp_fget(mpf, &pgno, 0, &pagep)) == 0; ++pgno) {
- LSN_NOT_LOGGED(pagep->lsn);
- if ((ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0)
- goto err;
- }
-
- if (ret == DB_PAGE_NOTFOUND)
- ret = 0;
-
-err: if ((t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
diff --git a/storage/bdb/db/db_stati.c b/storage/bdb/db/db_stati.c
deleted file mode 100644
index fb0bf4bee4f..00000000000
--- a/storage/bdb/db/db_stati.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_stati.c,v 12.10 2005/11/08 03:13:31 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#if TIME_WITH_SYS_TIME
-#include
-#include
-#else
-#if HAVE_SYS_TIME_H
-#include
-#else
-#include
-#endif
-#endif
-
-#include
-#endif
-
-#include "db_int.h"
-
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/btree.h"
-#include "dbinc/hash.h"
-#include "dbinc/qam.h"
-#include "dbinc/lock.h"
-#include "dbinc/log.h"
-#include "dbinc/mp.h"
-
-#ifdef HAVE_STATISTICS
-static int __db_print_all __P((DB *, u_int32_t));
-static int __db_print_citem __P((DBC *));
-static int __db_print_cursor __P((DB *));
-static int __db_print_stats __P((DB *, u_int32_t));
-static int __db_stat_arg __P((DB *, u_int32_t));
-
-/*
- * __db_stat_pp --
- * DB->stat pre/post processing.
- *
- * PUBLIC: int __db_stat_pp __P((DB *, DB_TXN *, void *, u_int32_t));
- */
-int
-__db_stat_pp(dbp, txn, spp, flags)
- DB *dbp;
- DB_TXN *txn;
- void *spp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbp->dbenv);
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->stat");
-
- if ((ret = __db_stat_arg(dbp, flags)) != 0)
- return (ret);
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- ret = __db_stat(dbp, txn, spp, flags);
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_stat --
- * DB->stat.
- *
- * PUBLIC: int __db_stat __P((DB *, DB_TXN *, void *, u_int32_t));
- */
-int
-__db_stat(dbp, txn, spp, flags)
- DB *dbp;
- DB_TXN *txn;
- void *spp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DBC *dbc;
- int ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- /* Acquire a cursor. */
- if ((ret = __db_cursor(dbp, txn,
- &dbc, LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED))) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, NULL, "DB->stat", NULL, NULL, flags);
- LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED);
-
- switch (dbp->type) {
- case DB_BTREE:
- case DB_RECNO:
- ret = __bam_stat(dbc, spp, flags);
- break;
- case DB_HASH:
- ret = __ham_stat(dbc, spp, flags);
- break;
- case DB_QUEUE:
- ret = __qam_stat(dbc, spp, flags);
- break;
- case DB_UNKNOWN:
- default:
- ret = (__db_unknown_type(dbenv, "DB->stat", dbp->type));
- break;
- }
-
- if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_stat_arg --
- * Check DB->stat arguments.
- */
-static int
-__db_stat_arg(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
-
- dbenv = dbp->dbenv;
-
- /* Check for invalid function flags. */
- LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED);
- switch (flags) {
- case 0:
- case DB_FAST_STAT:
- case DB_CACHED_COUNTS: /* Deprecated and undocumented. */
- break;
- case DB_RECORDCOUNT: /* Deprecated and undocumented. */
- if (dbp->type == DB_RECNO)
- break;
- if (dbp->type == DB_BTREE && F_ISSET(dbp, DB_AM_RECNUM))
- break;
- /* FALLTHROUGH */
- default:
- return (__db_ferr(dbenv, "DB->stat", 0));
- }
-
- return (0);
-}
-
-/*
- * __db_stat_print_pp --
- * DB->stat_print pre/post processing.
- *
- * PUBLIC: int __db_stat_print_pp __P((DB *, u_int32_t));
- */
-int
-__db_stat_print_pp(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
- DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->stat");
-
- /*
- * !!!
- * The actual argument checking is simple, do it inline.
- */
- if ((ret = __db_fchk(dbenv,
- "DB->stat_print", flags, DB_FAST_STAT | DB_STAT_ALL)) != 0)
- return (ret);
-
- ENV_ENTER(dbenv, ip);
-
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- ret = __db_stat_print(dbp, flags);
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
-err: ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_stat_print --
- * DB->stat_print.
- *
- * PUBLIC: int __db_stat_print __P((DB *, u_int32_t));
- */
-int
-__db_stat_print(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- int ret;
- time_t now;
-
- (void)time(&now);
- __db_msg(dbp->dbenv, "%.24s\tLocal time", ctime(&now));
-
- if (LF_ISSET(DB_STAT_ALL) && (ret = __db_print_all(dbp, flags)) != 0)
- return (ret);
-
- if ((ret = __db_print_stats(dbp, flags)) != 0)
- return (ret);
-
- return (0);
-}
-
-/*
- * __db_print_stats --
- * Display default DB handle statistics.
- */
-static int
-__db_print_stats(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- DBC *dbc;
- DB_ENV *dbenv;
- int ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- /* Acquire a cursor. */
- if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, NULL, "DB->stat_print", NULL, NULL, 0);
-
- switch (dbp->type) {
- case DB_BTREE:
- case DB_RECNO:
- ret = __bam_stat_print(dbc, flags);
- break;
- case DB_HASH:
- ret = __ham_stat_print(dbc, flags);
- break;
- case DB_QUEUE:
- ret = __qam_stat_print(dbc, flags);
- break;
- case DB_UNKNOWN:
- default:
- ret = (__db_unknown_type(dbenv, "DB->stat_print", dbp->type));
- break;
- }
-
- if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_print_all --
- * Display debugging DB handle statistics.
- */
-static int
-__db_print_all(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- static const FN fn[] = {
- { DB_AM_CHKSUM, "DB_AM_CHKSUM" },
- { DB_AM_CL_WRITER, "DB_AM_CL_WRITER" },
- { DB_AM_COMPENSATE, "DB_AM_COMPENSATE" },
- { DB_AM_CREATED, "DB_AM_CREATED" },
- { DB_AM_CREATED_MSTR, "DB_AM_CREATED_MSTR" },
- { DB_AM_DBM_ERROR, "DB_AM_DBM_ERROR" },
- { DB_AM_DELIMITER, "DB_AM_DELIMITER" },
- { DB_AM_DISCARD, "DB_AM_DISCARD" },
- { DB_AM_DUP, "DB_AM_DUP" },
- { DB_AM_DUPSORT, "DB_AM_DUPSORT" },
- { DB_AM_ENCRYPT, "DB_AM_ENCRYPT" },
- { DB_AM_FIXEDLEN, "DB_AM_FIXEDLEN" },
- { DB_AM_INMEM, "DB_AM_INMEM" },
- { DB_AM_IN_RENAME, "DB_AM_IN_RENAME" },
- { DB_AM_NOT_DURABLE, "DB_AM_NOT_DURABLE" },
- { DB_AM_OPEN_CALLED, "DB_AM_OPEN_CALLED" },
- { DB_AM_PAD, "DB_AM_PAD" },
- { DB_AM_PGDEF, "DB_AM_PGDEF" },
- { DB_AM_RDONLY, "DB_AM_RDONLY" },
- { DB_AM_READ_UNCOMMITTED, "DB_AM_READ_UNCOMMITTED" },
- { DB_AM_RECNUM, "DB_AM_RECNUM" },
- { DB_AM_RECOVER, "DB_AM_RECOVER" },
- { DB_AM_RENUMBER, "DB_AM_RENUMBER" },
- { DB_AM_REVSPLITOFF, "DB_AM_REVSPLITOFF" },
- { DB_AM_SECONDARY, "DB_AM_SECONDARY" },
- { DB_AM_SNAPSHOT, "DB_AM_SNAPSHOT" },
- { DB_AM_SUBDB, "DB_AM_SUBDB" },
- { DB_AM_SWAP, "DB_AM_SWAP" },
- { DB_AM_TXN, "DB_AM_TXN" },
- { DB_AM_VERIFYING, "DB_AM_VERIFYING" },
- { 0, NULL }
- };
- DB_ENV *dbenv;
-
- dbenv = dbp->dbenv;
-
- __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
- __db_msg(dbenv, "DB handle information:");
- STAT_ULONG("Page size", dbp->pgsize);
- STAT_ISSET("Append recno", dbp->db_append_recno);
- STAT_ISSET("Feedback", dbp->db_feedback);
- STAT_ISSET("Dup compare", dbp->dup_compare);
- STAT_ISSET("App private", dbp->app_private);
- STAT_ISSET("DbEnv", dbp->dbenv);
- STAT_STRING("Type", __db_dbtype_to_string(dbp->type));
-
- __mutex_print_debug_single(dbenv, "Thread mutex", dbp->mutex, flags);
-
- STAT_STRING("File", dbp->fname);
- STAT_STRING("Database", dbp->dname);
- STAT_HEX("Open flags", dbp->open_flags);
-
- __db_print_fileid(dbenv, dbp->fileid, "\tFile ID");
-
- STAT_ULONG("Cursor adjust ID", dbp->adj_fileid);
- STAT_ULONG("Meta pgno", dbp->meta_pgno);
- STAT_ULONG("Locker ID", dbp->lid);
- STAT_ULONG("Handle lock", dbp->cur_lid);
- STAT_ULONG("Associate lock", dbp->associate_lid);
- STAT_ULONG("RPC remote ID", dbp->cl_id);
-
- __db_msg(dbenv,
- "%.24s\tReplication handle timestamp",
- dbp->timestamp == 0 ? "0" : ctime(&dbp->timestamp));
-
- STAT_ISSET("Secondary callback", dbp->s_callback);
- STAT_ISSET("Primary handle", dbp->s_primary);
-
- STAT_ISSET("api internal", dbp->api_internal);
- STAT_ISSET("Btree/Recno internal", dbp->bt_internal);
- STAT_ISSET("Hash internal", dbp->h_internal);
- STAT_ISSET("Queue internal", dbp->q_internal);
- STAT_ISSET("XA internal", dbp->xa_internal);
-
- __db_prflags(dbenv, NULL, dbp->flags, fn, NULL, "\tFlags");
-
- if (dbp->log_filename == NULL)
- STAT_ISSET("File naming information", dbp->log_filename);
- else
- __dbreg_print_fname(dbenv, dbp->log_filename);
-
- (void)__db_print_cursor(dbp);
-
- return (0);
-}
-
-/*
- * __db_print_cursor --
- * Display the cursor active and free queues.
- */
-static int
-__db_print_cursor(dbp)
- DB *dbp;
-{
- DB_ENV *dbenv;
- DBC *dbc;
- int ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- __db_msg(dbenv, "%s", DB_GLOBAL(db_line));
- __db_msg(dbenv, "DB handle cursors:");
-
- ret = 0;
- MUTEX_LOCK(dbp->dbenv, dbp->mutex);
- __db_msg(dbenv, "Active queue:");
- for (dbc = TAILQ_FIRST(&dbp->active_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
- if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0)
- ret = t_ret;
- __db_msg(dbenv, "Join queue:");
- for (dbc = TAILQ_FIRST(&dbp->join_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
- if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0)
- ret = t_ret;
- __db_msg(dbenv, "Free queue:");
- for (dbc = TAILQ_FIRST(&dbp->free_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
- if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0)
- ret = t_ret;
- MUTEX_UNLOCK(dbp->dbenv, dbp->mutex);
-
- return (ret);
-}
-
-static
-int __db_print_citem(dbc)
- DBC *dbc;
-{
- static const FN fn[] = {
- { DBC_ACTIVE, "DBC_ACTIVE" },
- { DBC_COMPENSATE, "DBC_COMPENSATE" },
- { DBC_MULTIPLE, "DBC_MULTIPLE" },
- { DBC_MULTIPLE_KEY, "DBC_MULTIPLE_KEY" },
- { DBC_OPD, "DBC_OPD" },
- { DBC_OWN_LID, "DBC_OWN_LID" },
- { DBC_READ_COMMITTED, "DBC_READ_COMMITTED" },
- { DBC_READ_UNCOMMITTED, "DBC_READ_UNCOMMITTED" },
- { DBC_RECOVER, "DBC_RECOVER" },
- { DBC_RMW, "DBC_RMW" },
- { DBC_TRANSIENT, "DBC_TRANSIENT" },
- { DBC_WRITECURSOR, "DBC_WRITECURSOR" },
- { DBC_WRITER, "DBC_WRITER" },
- { 0, NULL }
- };
- DB *dbp;
- DBC_INTERNAL *cp;
- DB_ENV *dbenv;
-
- dbp = dbc->dbp;
- dbenv = dbp->dbenv;
- cp = dbc->internal;
-
- STAT_POINTER("DBC", dbc);
- STAT_POINTER("Associated dbp", dbc->dbp);
- STAT_POINTER("Associated txn", dbc->txn);
- STAT_POINTER("Internal", cp);
- STAT_HEX("Default locker ID",
- dbc->lref == NULL ? 0 : ((DB_LOCKER *)dbc->lref)->id);
- STAT_HEX("Locker", dbc->locker);
- STAT_STRING("Type", __db_dbtype_to_string(dbc->dbtype));
-
- STAT_POINTER("Off-page duplicate cursor", cp->opd);
- STAT_POINTER("Referenced page", cp->page);
- STAT_ULONG("Root", cp->root);
- STAT_ULONG("Page number", cp->pgno);
- STAT_ULONG("Page index", cp->indx);
- STAT_STRING("Lock mode", __db_lockmode_to_string(cp->lock_mode));
- __db_prflags(dbenv, NULL, dbc->flags, fn, NULL, "\tFlags");
-
- switch (dbc->dbtype) {
- case DB_BTREE:
- case DB_RECNO:
- __bam_print_cursor(dbc);
- break;
- case DB_HASH:
- __ham_print_cursor(dbc);
- break;
- case DB_UNKNOWN:
- DB_ASSERT(dbp->type != DB_UNKNOWN);
- /* FALLTHROUGH */
- case DB_QUEUE:
- default:
- break;
- }
- return (0);
-}
-
-#else /* !HAVE_STATISTICS */
-
-int
-__db_stat_pp(dbp, txn, spp, flags)
- DB *dbp;
- DB_TXN *txn;
- void *spp;
- u_int32_t flags;
-{
- COMPQUIET(spp, NULL);
- COMPQUIET(txn, NULL);
- COMPQUIET(flags, 0);
-
- return (__db_stat_not_built(dbp->dbenv));
-}
-
-int
-__db_stat_print_pp(dbp, flags)
- DB *dbp;
- u_int32_t flags;
-{
- COMPQUIET(flags, 0);
-
- return (__db_stat_not_built(dbp->dbenv));
-}
-#endif
diff --git a/storage/bdb/db/db_truncate.c b/storage/bdb/db/db_truncate.c
deleted file mode 100644
index c6b740969fb..00000000000
--- a/storage/bdb/db/db_truncate.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 2001-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_truncate.c,v 12.10 2005/10/21 19:22:59 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/btree.h"
-#include "dbinc/hash.h"
-#include "dbinc/qam.h"
-#include "dbinc/lock.h"
-#include "dbinc/log.h"
-#include "dbinc/txn.h"
-
-static int __db_cursor_check __P((DB *));
-
-/*
- * __db_truncate_pp
- * DB->truncate pre/post processing.
- *
- * PUBLIC: int __db_truncate_pp __P((DB *, DB_TXN *, u_int32_t *, u_int32_t));
- */
-int
-__db_truncate_pp(dbp, txn, countp, flags)
- DB *dbp;
- DB_TXN *txn;
- u_int32_t *countp, flags;
-{
- DB_ENV *dbenv;
- DB_THREAD_INFO *ip;
- int handle_check, ret, t_ret, txn_local;
-
- dbenv = dbp->dbenv;
- txn_local = 0;
- handle_check = 0;
-
- PANIC_CHECK(dbenv);
- STRIP_AUTO_COMMIT(flags);
-
- /* Check for invalid flags. */
- if (F_ISSET(dbp, DB_AM_SECONDARY)) {
- __db_err(dbenv,
- "DB->truncate forbidden on secondary indices");
- return (EINVAL);
- }
- if ((ret = __db_fchk(dbenv, "DB->truncate", flags, 0)) != 0)
- return (ret);
-
- ENV_ENTER(dbenv, ip);
-
- /*
- * Make sure there are no active cursors on this db. Since we drop
- * pages we cannot really adjust cursors.
- */
- if (__db_cursor_check(dbp) != 0) {
- __db_err(dbenv,
- "DB->truncate not permitted with active cursors");
- goto err;
- }
-
-#if CONFIG_TEST
- if (IS_REP_MASTER(dbenv))
- DB_TEST_WAIT(dbenv, dbenv->test_check);
-#endif
- /* Check for replication block. */
- handle_check = IS_ENV_REPLICATED(dbenv);
- if (handle_check &&
- (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) {
- handle_check = 0;
- goto err;
- }
-
- /*
- * Check for changes to a read-only database.
- * This must be after the replication block so that we
- * cannot race master/client state changes.
- */
- if (DB_IS_READONLY(dbp)) {
- ret = __db_rdonly(dbenv, "DB->truncate");
- goto err;
- }
-
- /*
- * Create local transaction as necessary, check for consistent
- * transaction usage.
- */
- if (IS_DB_AUTO_COMMIT(dbp, txn)) {
- if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0)
- goto err;
- txn_local = 1;
- }
-
- /* Check for consistent transaction usage. */
- if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0)
- goto err;
-
- ret = __db_truncate(dbp, txn, countp);
-
-err: if (txn_local &&
- (t_ret = __db_txn_auto_resolve(dbenv, txn, 0, ret)) && ret == 0)
- ret = t_ret;
-
- /* Release replication block. */
- if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0)
- ret = t_ret;
-
- ENV_LEAVE(dbenv, ip);
- return (ret);
-}
-
-/*
- * __db_truncate
- * DB->truncate.
- *
- * PUBLIC: int __db_truncate __P((DB *, DB_TXN *, u_int32_t *));
- */
-int
-__db_truncate(dbp, txn, countp)
- DB *dbp;
- DB_TXN *txn;
- u_int32_t *countp;
-{
- DB *sdbp;
- DBC *dbc;
- DB_ENV *dbenv;
- u_int32_t scount;
- int ret, t_ret;
-
- dbenv = dbp->dbenv;
- dbc = NULL;
- ret = 0;
-
- /*
- * Run through all secondaries and truncate them first. The count
- * returned is the count of the primary only. QUEUE uses normal
- * processing to truncate so it will update the secondaries normally.
- */
- if (dbp->type != DB_QUEUE && LIST_FIRST(&dbp->s_secondaries) != NULL) {
- if ((ret = __db_s_first(dbp, &sdbp)) != 0)
- return (ret);
- for (; sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp))
- if ((ret = __db_truncate(sdbp, txn, &scount)) != 0)
- break;
- if (sdbp != NULL)
- (void)__db_s_done(sdbp);
- if (ret != 0)
- return (ret);
- }
-
- DB_TEST_RECOVERY(dbp, DB_TEST_PREDESTROY, ret, NULL);
-
- /* Acquire a cursor. */
- if ((ret = __db_cursor(dbp, txn, &dbc, 0)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, txn, "DB->truncate", NULL, NULL, 0);
-
- switch (dbp->type) {
- case DB_BTREE:
- case DB_RECNO:
- ret = __bam_truncate(dbc, countp);
- break;
- case DB_HASH:
- ret = __ham_truncate(dbc, countp);
- break;
- case DB_QUEUE:
- ret = __qam_truncate(dbc, countp);
- break;
- case DB_UNKNOWN:
- default:
- ret = __db_unknown_type(dbenv, "DB->truncate", dbp->type);
- break;
- }
-
- /* Discard the cursor. */
- if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, NULL);
-
-DB_TEST_RECOVERY_LABEL
-
- return (ret);
-}
-
-/*
- * __db_cursor_check --
- * See if there are any active cursors on this db.
- */
-static int
-__db_cursor_check(dbp)
- DB *dbp;
-{
- DB *ldbp;
- DBC *dbc;
- DB_ENV *dbenv;
- int found;
-
- dbenv = dbp->dbenv;
-
- MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
- for (found = 0, ldbp = __dblist_get(dbenv, dbp->adj_fileid);
- ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
- ldbp = LIST_NEXT(ldbp, dblistlinks)) {
- MUTEX_LOCK(dbenv, dbp->mutex);
- for (dbc = TAILQ_FIRST(&ldbp->active_queue);
- dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {
- if (IS_INITIALIZED(dbc)) {
- found = 1;
- break;
- }
- }
- MUTEX_UNLOCK(dbenv, dbp->mutex);
- if (found == 1)
- break;
- }
- MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
-
- return (found);
-}
diff --git a/storage/bdb/db/db_upg.c b/storage/bdb/db/db_upg.c
deleted file mode 100644
index 674202d5bb7..00000000000
--- a/storage/bdb/db/db_upg.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_upg.c,v 12.1 2005/06/16 20:21:15 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_swap.h"
-#include "dbinc/btree.h"
-#include "dbinc/hash.h"
-#include "dbinc/qam.h"
-
-static int (* const func_31_list[P_PAGETYPE_MAX])
- __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)) = {
- NULL, /* P_INVALID */
- NULL, /* __P_DUPLICATE */
- __ham_31_hash, /* P_HASH */
- NULL, /* P_IBTREE */
- NULL, /* P_IRECNO */
- __bam_31_lbtree, /* P_LBTREE */
- NULL, /* P_LRECNO */
- NULL, /* P_OVERFLOW */
- __ham_31_hashmeta, /* P_HASHMETA */
- __bam_31_btreemeta, /* P_BTREEMETA */
- NULL, /* P_QAMMETA */
- NULL, /* P_QAMDATA */
- NULL, /* P_LDUP */
-};
-
-static int __db_page_pass __P((DB *, char *, u_int32_t, int (* const [])
- (DB *, char *, u_int32_t, DB_FH *, PAGE *, int *), DB_FH *));
-
-/*
- * __db_upgrade_pp --
- * DB->upgrade pre/post processing.
- *
- * PUBLIC: int __db_upgrade_pp __P((DB *, const char *, u_int32_t));
- */
-int
-__db_upgrade_pp(dbp, fname, flags)
- DB *dbp;
- const char *fname;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- int ret;
-
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbp->dbenv);
-
- /*
- * !!!
- * The actual argument checking is simple, do it inline.
- */
- if ((ret = __db_fchk(dbenv, "DB->upgrade", flags, DB_DUPSORT)) != 0)
- return (ret);
-
- return (__db_upgrade(dbp, fname, flags));
-}
-
-/*
- * __db_upgrade --
- * Upgrade an existing database.
- *
- * PUBLIC: int __db_upgrade __P((DB *, const char *, u_int32_t));
- */
-int
-__db_upgrade(dbp, fname, flags)
- DB *dbp;
- const char *fname;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_FH *fhp;
- size_t n;
- int ret, t_ret;
- u_int8_t mbuf[256];
- char *real_name;
-
- dbenv = dbp->dbenv;
- fhp = NULL;
-
- /* Get the real backing file name. */
- if ((ret = __db_appname(dbenv,
- DB_APP_DATA, fname, 0, NULL, &real_name)) != 0)
- return (ret);
-
- /* Open the file. */
- if ((ret = __os_open(dbenv, real_name, 0, 0, &fhp)) != 0) {
- __db_err(dbenv, "%s: %s", real_name, db_strerror(ret));
- return (ret);
- }
-
- /* Initialize the feedback. */
- if (dbp->db_feedback != NULL)
- dbp->db_feedback(dbp, DB_UPGRADE, 0);
-
- /*
- * Read the metadata page. We read 256 bytes, which is larger than
- * any access method's metadata page and smaller than any disk sector.
- */
- if ((ret = __os_read(dbenv, fhp, mbuf, sizeof(mbuf), &n)) != 0)
- goto err;
-
- switch (((DBMETA *)mbuf)->magic) {
- case DB_BTREEMAGIC:
- switch (((DBMETA *)mbuf)->version) {
- case 6:
- /*
- * Before V7 not all pages had page types, so we do the
- * single meta-data page by hand.
- */
- if ((ret =
- __bam_30_btreemeta(dbp, real_name, mbuf)) != 0)
- goto err;
- if ((ret = __os_seek(dbenv,
- fhp, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0)
- goto err;
- if ((ret = __os_write(dbenv, fhp, mbuf, 256, &n)) != 0)
- goto err;
- /* FALLTHROUGH */
- case 7:
- /*
- * We need the page size to do more. Rip it out of
- * the meta-data page.
- */
- memcpy(&dbp->pgsize, mbuf + 20, sizeof(u_int32_t));
-
- if ((ret = __db_page_pass(
- dbp, real_name, flags, func_31_list, fhp)) != 0)
- goto err;
- /* FALLTHROUGH */
- case 8:
- case 9:
- break;
- default:
- __db_err(dbenv, "%s: unsupported btree version: %lu",
- real_name, (u_long)((DBMETA *)mbuf)->version);
- ret = DB_OLD_VERSION;
- goto err;
- }
- break;
- case DB_HASHMAGIC:
- switch (((DBMETA *)mbuf)->version) {
- case 4:
- case 5:
- /*
- * Before V6 not all pages had page types, so we do the
- * single meta-data page by hand.
- */
- if ((ret =
- __ham_30_hashmeta(dbp, real_name, mbuf)) != 0)
- goto err;
- if ((ret = __os_seek(dbenv,
- fhp, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0)
- goto err;
- if ((ret = __os_write(dbenv, fhp, mbuf, 256, &n)) != 0)
- goto err;
-
- /*
- * Before V6, we created hash pages one by one as they
- * were needed, using hashhdr.ovfl_point to reserve
- * a block of page numbers for them. A consequence
- * of this was that, if no overflow pages had been
- * created, the current doubling might extend past
- * the end of the database file.
- *
- * In DB 3.X, we now create all the hash pages
- * belonging to a doubling atomically; it's not
- * safe to just save them for later, because when
- * we create an overflow page we'll just create
- * a new last page (whatever that may be). Grow
- * the database to the end of the current doubling.
- */
- if ((ret =
- __ham_30_sizefix(dbp, fhp, real_name, mbuf)) != 0)
- goto err;
- /* FALLTHROUGH */
- case 6:
- /*
- * We need the page size to do more. Rip it out of
- * the meta-data page.
- */
- memcpy(&dbp->pgsize, mbuf + 20, sizeof(u_int32_t));
-
- if ((ret = __db_page_pass(
- dbp, real_name, flags, func_31_list, fhp)) != 0)
- goto err;
- /* FALLTHROUGH */
- case 7:
- case 8:
- break;
- default:
- __db_err(dbenv, "%s: unsupported hash version: %lu",
- real_name, (u_long)((DBMETA *)mbuf)->version);
- ret = DB_OLD_VERSION;
- goto err;
- }
- break;
- case DB_QAMMAGIC:
- switch (((DBMETA *)mbuf)->version) {
- case 1:
- /*
- * If we're in a Queue database, the only page that
- * needs upgrading is the meta-database page, don't
- * bother with a full pass.
- */
- if ((ret = __qam_31_qammeta(dbp, real_name, mbuf)) != 0)
- return (ret);
- /* FALLTHROUGH */
- case 2:
- if ((ret = __qam_32_qammeta(dbp, real_name, mbuf)) != 0)
- return (ret);
- if ((ret = __os_seek(dbenv,
- fhp, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0)
- goto err;
- if ((ret = __os_write(dbenv, fhp, mbuf, 256, &n)) != 0)
- goto err;
- /* FALLTHROUGH */
- case 3:
- case 4:
- break;
- default:
- __db_err(dbenv, "%s: unsupported queue version: %lu",
- real_name, (u_long)((DBMETA *)mbuf)->version);
- ret = DB_OLD_VERSION;
- goto err;
- }
- break;
- default:
- M_32_SWAP(((DBMETA *)mbuf)->magic);
- switch (((DBMETA *)mbuf)->magic) {
- case DB_BTREEMAGIC:
- case DB_HASHMAGIC:
- case DB_QAMMAGIC:
- __db_err(dbenv,
- "%s: DB->upgrade only supported on native byte-order systems",
- real_name);
- break;
- default:
- __db_err(dbenv,
- "%s: unrecognized file type", real_name);
- break;
- }
- ret = EINVAL;
- goto err;
- }
-
- ret = __os_fsync(dbenv, fhp);
-
-err: if (fhp != NULL &&
- (t_ret = __os_closehandle(dbenv, fhp)) != 0 && ret == 0)
- ret = t_ret;
- __os_free(dbenv, real_name);
-
- /* We're done. */
- if (dbp->db_feedback != NULL)
- dbp->db_feedback(dbp, DB_UPGRADE, 100);
-
- return (ret);
-}
-
-/*
- * __db_page_pass --
- * Walk the pages of the database, upgrading whatever needs it.
- */
-static int
-__db_page_pass(dbp, real_name, flags, fl, fhp)
- DB *dbp;
- char *real_name;
- u_int32_t flags;
- int (* const fl[P_PAGETYPE_MAX])
- __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
- DB_FH *fhp;
-{
- DB_ENV *dbenv;
- PAGE *page;
- db_pgno_t i, pgno_last;
- size_t n;
- int dirty, ret;
-
- dbenv = dbp->dbenv;
-
- /* Determine the last page of the file. */
- if ((ret = __db_lastpgno(dbp, real_name, fhp, &pgno_last)) != 0)
- return (ret);
-
- /* Allocate memory for a single page. */
- if ((ret = __os_malloc(dbenv, dbp->pgsize, &page)) != 0)
- return (ret);
-
- /* Walk the file, calling the underlying conversion functions. */
- for (i = 0; i < pgno_last; ++i) {
- if (dbp->db_feedback != NULL)
- dbp->db_feedback(
- dbp, DB_UPGRADE, (int)((i * 100)/pgno_last));
- if ((ret = __os_seek(dbenv,
- fhp, dbp->pgsize, i, 0, 0, DB_OS_SEEK_SET)) != 0)
- break;
- if ((ret = __os_read(dbenv, fhp, page, dbp->pgsize, &n)) != 0)
- break;
- dirty = 0;
- if (fl[TYPE(page)] != NULL && (ret = fl[TYPE(page)]
- (dbp, real_name, flags, fhp, page, &dirty)) != 0)
- break;
- if (dirty) {
- if ((ret = __os_seek(dbenv,
- fhp, dbp->pgsize, i, 0, 0, DB_OS_SEEK_SET)) != 0)
- break;
- if ((ret = __os_write(dbenv,
- fhp, page, dbp->pgsize, &n)) != 0)
- break;
- }
- }
-
- __os_free(dbp->dbenv, page);
- return (ret);
-}
-
-/*
- * __db_lastpgno --
- * Return the current last page number of the file.
- *
- * PUBLIC: int __db_lastpgno __P((DB *, char *, DB_FH *, db_pgno_t *));
- */
-int
-__db_lastpgno(dbp, real_name, fhp, pgno_lastp)
- DB *dbp;
- char *real_name;
- DB_FH *fhp;
- db_pgno_t *pgno_lastp;
-{
- DB_ENV *dbenv;
- db_pgno_t pgno_last;
- u_int32_t mbytes, bytes;
- int ret;
-
- dbenv = dbp->dbenv;
-
- if ((ret = __os_ioinfo(dbenv,
- real_name, fhp, &mbytes, &bytes, NULL)) != 0) {
- __db_err(dbenv, "%s: %s", real_name, db_strerror(ret));
- return (ret);
- }
-
- /* Page sizes have to be a power-of-two. */
- if (bytes % dbp->pgsize != 0) {
- __db_err(dbenv,
- "%s: file size not a multiple of the pagesize", real_name);
- return (EINVAL);
- }
- pgno_last = mbytes * (MEGABYTE / dbp->pgsize);
- pgno_last += bytes / dbp->pgsize;
-
- *pgno_lastp = pgno_last;
- return (0);
-}
diff --git a/storage/bdb/db/db_upg_opd.c b/storage/bdb/db/db_upg_opd.c
deleted file mode 100644
index 23838be9ca8..00000000000
--- a/storage/bdb/db/db_upg_opd.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_upg_opd.c,v 12.1 2005/06/16 20:21:15 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/btree.h"
-
-static int __db_build_bi __P((DB *, DB_FH *, PAGE *, PAGE *, u_int32_t, int *));
-static int __db_build_ri __P((DB *, DB_FH *, PAGE *, PAGE *, u_int32_t, int *));
-static int __db_up_ovref __P((DB *, DB_FH *, db_pgno_t));
-
-#define GET_PAGE(dbp, fhp, pgno, page) { \
- if ((ret = __os_seek(dbp->dbenv, \
- fhp, (dbp)->pgsize, pgno, 0, 0, DB_OS_SEEK_SET)) != 0) \
- goto err; \
- if ((ret = __os_read(dbp->dbenv, \
- fhp, page, (dbp)->pgsize, &n)) != 0) \
- goto err; \
-}
-#define PUT_PAGE(dbp, fhp, pgno, page) { \
- if ((ret = __os_seek(dbp->dbenv, \
- fhp, (dbp)->pgsize, pgno, 0, 0, DB_OS_SEEK_SET)) != 0) \
- goto err; \
- if ((ret = __os_write(dbp->dbenv, \
- fhp, page, (dbp)->pgsize, &n)) != 0) \
- goto err; \
-}
-
-/*
- * __db_31_offdup --
- * Convert 3.0 off-page duplicates to 3.1 off-page duplicates.
- *
- * PUBLIC: int __db_31_offdup __P((DB *, char *, DB_FH *, int, db_pgno_t *));
- */
-int
-__db_31_offdup(dbp, real_name, fhp, sorted, pgnop)
- DB *dbp;
- char *real_name;
- DB_FH *fhp;
- int sorted;
- db_pgno_t *pgnop;
-{
- PAGE *ipage, *page;
- db_indx_t indx;
- db_pgno_t cur_cnt, i, next_cnt, pgno, *pgno_cur, pgno_last;
- db_pgno_t *pgno_next, pgno_max, *tmp;
- db_recno_t nrecs;
- size_t n;
- int level, nomem, ret;
-
- ipage = page = NULL;
- pgno_cur = pgno_next = NULL;
-
- /* Allocate room to hold a page. */
- if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &page)) != 0)
- goto err;
-
- /*
- * Walk the chain of 3.0 off-page duplicates. Each one is converted
- * in place to a 3.1 off-page duplicate page. If the duplicates are
- * sorted, they are converted to a Btree leaf page, otherwise to a
- * Recno leaf page.
- */
- for (nrecs = 0, cur_cnt = pgno_max = 0,
- pgno = *pgnop; pgno != PGNO_INVALID;) {
- if (pgno_max == cur_cnt) {
- pgno_max += 20;
- if ((ret = __os_realloc(dbp->dbenv, pgno_max *
- sizeof(db_pgno_t), &pgno_cur)) != 0)
- goto err;
- }
- pgno_cur[cur_cnt++] = pgno;
-
- GET_PAGE(dbp, fhp, pgno, page);
- nrecs += NUM_ENT(page);
- LEVEL(page) = LEAFLEVEL;
- TYPE(page) = sorted ? P_LDUP : P_LRECNO;
- /*
- * !!!
- * DB didn't zero the LSNs on off-page duplicates pages.
- */
- ZERO_LSN(LSN(page));
- PUT_PAGE(dbp, fhp, pgno, page);
-
- pgno = NEXT_PGNO(page);
- }
-
- /* If we only have a single page, it's easy. */
- if (cur_cnt <= 1)
- goto done;
-
- /*
- * pgno_cur is the list of pages we just converted. We're
- * going to walk that list, but we'll need to create a new
- * list while we do so.
- */
- if ((ret = __os_malloc(dbp->dbenv,
- cur_cnt * sizeof(db_pgno_t), &pgno_next)) != 0)
- goto err;
-
- /* Figure out where we can start allocating new pages. */
- if ((ret = __db_lastpgno(dbp, real_name, fhp, &pgno_last)) != 0)
- goto err;
-
- /* Allocate room for an internal page. */
- if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &ipage)) != 0)
- goto err;
- PGNO(ipage) = PGNO_INVALID;
-
- /*
- * Repeatedly walk the list of pages, building internal pages, until
- * there's only one page at a level.
- */
- for (level = LEAFLEVEL + 1; cur_cnt > 1; ++level) {
- for (indx = 0, i = next_cnt = 0; i < cur_cnt;) {
- if (indx == 0) {
- P_INIT(ipage, dbp->pgsize, pgno_last,
- PGNO_INVALID, PGNO_INVALID,
- level, sorted ? P_IBTREE : P_IRECNO);
- ZERO_LSN(LSN(ipage));
-
- pgno_next[next_cnt++] = pgno_last++;
- }
-
- GET_PAGE(dbp, fhp, pgno_cur[i], page);
-
- /*
- * If the duplicates are sorted, put the first item on
- * the lower-level page onto a Btree internal page. If
- * the duplicates are not sorted, create an internal
- * Recno structure on the page. If either case doesn't
- * fit, push out the current page and start a new one.
- */
- nomem = 0;
- if (sorted) {
- if ((ret = __db_build_bi(
- dbp, fhp, ipage, page, indx, &nomem)) != 0)
- goto err;
- } else
- if ((ret = __db_build_ri(
- dbp, fhp, ipage, page, indx, &nomem)) != 0)
- goto err;
- if (nomem) {
- indx = 0;
- PUT_PAGE(dbp, fhp, PGNO(ipage), ipage);
- } else {
- ++indx;
- ++NUM_ENT(ipage);
- ++i;
- }
- }
-
- /*
- * Push out the last internal page. Set the top-level record
- * count if we've reached the top.
- */
- if (next_cnt == 1)
- RE_NREC_SET(ipage, nrecs);
- PUT_PAGE(dbp, fhp, PGNO(ipage), ipage);
-
- /* Swap the current and next page number arrays. */
- cur_cnt = next_cnt;
- tmp = pgno_cur;
- pgno_cur = pgno_next;
- pgno_next = tmp;
- }
-
-done: *pgnop = pgno_cur[0];
-
-err: if (pgno_cur != NULL)
- __os_free(dbp->dbenv, pgno_cur);
- if (pgno_next != NULL)
- __os_free(dbp->dbenv, pgno_next);
- if (ipage != NULL)
- __os_free(dbp->dbenv, ipage);
- if (page != NULL)
- __os_free(dbp->dbenv, page);
-
- return (ret);
-}
-
-/*
- * __db_build_bi --
- * Build a BINTERNAL entry for a parent page.
- */
-static int
-__db_build_bi(dbp, fhp, ipage, page, indx, nomemp)
- DB *dbp;
- DB_FH *fhp;
- PAGE *ipage, *page;
- u_int32_t indx;
- int *nomemp;
-{
- BINTERNAL bi, *child_bi;
- BKEYDATA *child_bk;
- u_int8_t *p;
- int ret;
- db_indx_t *inp;
-
- inp = P_INP(dbp, ipage);
- switch (TYPE(page)) {
- case P_IBTREE:
- child_bi = GET_BINTERNAL(dbp, page, 0);
- if (P_FREESPACE(dbp, ipage) < BINTERNAL_PSIZE(child_bi->len)) {
- *nomemp = 1;
- return (0);
- }
- inp[indx] =
- HOFFSET(ipage) -= BINTERNAL_SIZE(child_bi->len);
- p = P_ENTRY(dbp, ipage, indx);
-
- bi.len = child_bi->len;
- B_TSET(bi.type, child_bi->type, 0);
- bi.pgno = PGNO(page);
- bi.nrecs = __bam_total(dbp, page);
- memcpy(p, &bi, SSZA(BINTERNAL, data));
- p += SSZA(BINTERNAL, data);
- memcpy(p, child_bi->data, child_bi->len);
-
- /* Increment the overflow ref count. */
- if (B_TYPE(child_bi->type) == B_OVERFLOW)
- if ((ret = __db_up_ovref(dbp, fhp,
- ((BOVERFLOW *)(child_bi->data))->pgno)) != 0)
- return (ret);
- break;
- case P_LDUP:
- child_bk = GET_BKEYDATA(dbp, page, 0);
- switch (B_TYPE(child_bk->type)) {
- case B_KEYDATA:
- if (P_FREESPACE(dbp, ipage) <
- BINTERNAL_PSIZE(child_bk->len)) {
- *nomemp = 1;
- return (0);
- }
- inp[indx] =
- HOFFSET(ipage) -= BINTERNAL_SIZE(child_bk->len);
- p = P_ENTRY(dbp, ipage, indx);
-
- bi.len = child_bk->len;
- B_TSET(bi.type, child_bk->type, 0);
- bi.pgno = PGNO(page);
- bi.nrecs = __bam_total(dbp, page);
- memcpy(p, &bi, SSZA(BINTERNAL, data));
- p += SSZA(BINTERNAL, data);
- memcpy(p, child_bk->data, child_bk->len);
- break;
- case B_OVERFLOW:
- if (P_FREESPACE(dbp, ipage) <
- BINTERNAL_PSIZE(BOVERFLOW_SIZE)) {
- *nomemp = 1;
- return (0);
- }
- inp[indx] =
- HOFFSET(ipage) -= BINTERNAL_SIZE(BOVERFLOW_SIZE);
- p = P_ENTRY(dbp, ipage, indx);
-
- bi.len = BOVERFLOW_SIZE;
- B_TSET(bi.type, child_bk->type, 0);
- bi.pgno = PGNO(page);
- bi.nrecs = __bam_total(dbp, page);
- memcpy(p, &bi, SSZA(BINTERNAL, data));
- p += SSZA(BINTERNAL, data);
- memcpy(p, child_bk, BOVERFLOW_SIZE);
-
- /* Increment the overflow ref count. */
- if ((ret = __db_up_ovref(dbp, fhp,
- ((BOVERFLOW *)child_bk)->pgno)) != 0)
- return (ret);
- break;
- default:
- return (__db_pgfmt(dbp->dbenv, PGNO(page)));
- }
- break;
- default:
- return (__db_pgfmt(dbp->dbenv, PGNO(page)));
- }
-
- return (0);
-}
-
-/*
- * __db_build_ri --
- * Build a RINTERNAL entry for an internal parent page.
- */
-static int
-__db_build_ri(dbp, fhp, ipage, page, indx, nomemp)
- DB *dbp;
- DB_FH *fhp;
- PAGE *ipage, *page;
- u_int32_t indx;
- int *nomemp;
-{
- RINTERNAL ri;
- db_indx_t *inp;
-
- COMPQUIET(fhp, NULL);
- inp = P_INP(dbp, ipage);
- if (P_FREESPACE(dbp, ipage) < RINTERNAL_PSIZE) {
- *nomemp = 1;
- return (0);
- }
-
- ri.pgno = PGNO(page);
- ri.nrecs = __bam_total(dbp, page);
- inp[indx] = HOFFSET(ipage) -= RINTERNAL_SIZE;
- memcpy(P_ENTRY(dbp, ipage, indx), &ri, RINTERNAL_SIZE);
-
- return (0);
-}
-
-/*
- * __db_up_ovref --
- * Increment/decrement the reference count on an overflow page.
- */
-static int
-__db_up_ovref(dbp, fhp, pgno)
- DB *dbp;
- DB_FH *fhp;
- db_pgno_t pgno;
-{
- PAGE *page;
- size_t n;
- int ret;
-
- /* Allocate room to hold a page. */
- if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &page)) != 0)
- return (ret);
-
- GET_PAGE(dbp, fhp, pgno, page);
- ++OV_REF(page);
- PUT_PAGE(dbp, fhp, pgno, page);
-
-err: __os_free(dbp->dbenv, page);
-
- return (ret);
-}
diff --git a/storage/bdb/db/db_vrfy.c b/storage/bdb/db/db_vrfy.c
deleted file mode 100644
index 4f33e451099..00000000000
--- a/storage/bdb/db/db_vrfy.c
+++ /dev/null
@@ -1,2592 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 2000-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_vrfy.c,v 12.14 2005/10/07 16:49:47 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_shash.h"
-#include "dbinc/db_swap.h"
-#include "dbinc/db_verify.h"
-#include "dbinc/btree.h"
-#include "dbinc/hash.h"
-#include "dbinc/lock.h"
-#include "dbinc/mp.h"
-#include "dbinc/qam.h"
-#include "dbinc/txn.h"
-
-/*
- * This is the code for DB->verify, the DB database consistency checker.
- * For now, it checks all subdatabases in a database, and verifies
- * everything it knows how to (i.e. it's all-or-nothing, and one can't
- * check only for a subset of possible problems).
- */
-
-static u_int __db_guesspgsize __P((DB_ENV *, DB_FH *));
-static int __db_is_valid_magicno __P((u_int32_t, DBTYPE *));
-static int __db_is_valid_pagetype __P((u_int32_t));
-static int __db_meta2pgset
- __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, DB *));
-static int __db_salvage_subdbpg __P((DB *, VRFY_DBINFO *,
- PAGE *, void *, int (*)(void *, const void *), u_int32_t));
-static int __db_salvage_subdbs __P((DB *, VRFY_DBINFO *, void *,
- int(*)(void *, const void *), u_int32_t, int *));
-static int __db_salvage_unknowns __P((DB *, VRFY_DBINFO *, void *,
- int (*)(void *, const void *), u_int32_t));
-static int __db_verify __P((DB *, const char *, const char *,
- void *, int (*)(void *, const void *), u_int32_t));
-static int __db_verify_arg __P((DB *, const char *, void *, u_int32_t));
-static int __db_vrfy_freelist
- __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t));
-static int __db_vrfy_invalid
- __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
-static int __db_vrfy_orderchkonly __P((DB *,
- VRFY_DBINFO *, const char *, const char *, u_int32_t));
-static int __db_vrfy_pagezero __P((DB *, VRFY_DBINFO *, DB_FH *, u_int32_t));
-static int __db_vrfy_subdbs
- __P((DB *, VRFY_DBINFO *, const char *, u_int32_t));
-static int __db_vrfy_structure
- __P((DB *, VRFY_DBINFO *, const char *, db_pgno_t, u_int32_t));
-static int __db_vrfy_walkpages __P((DB *, VRFY_DBINFO *,
- void *, int (*)(void *, const void *), u_int32_t));
-
-#define VERIFY_FLAGS \
- (DB_AGGRESSIVE | \
- DB_NOORDERCHK | DB_ORDERCHKONLY | DB_PRINTABLE | DB_SALVAGE | DB_UNREF)
-
-/*
- * __db_verify_pp --
- * DB->verify public interface.
- *
- * PUBLIC: int __db_verify_pp
- * PUBLIC: __P((DB *, const char *, const char *, FILE *, u_int32_t));
- */
-int
-__db_verify_pp(dbp, file, database, outfile, flags)
- DB *dbp;
- const char *file, *database;
- FILE *outfile;
- u_int32_t flags;
-{
- /*
- * __db_verify_pp is a wrapper to __db_verify_internal, which lets
- * us pass appropriate equivalents to FILE * in from the non-C APIs.
- */
- return (__db_verify_internal(dbp,
- file, database, outfile, __db_pr_callback, flags));
-}
-
-/*
- * __db_verify_internal --
- *
- * PUBLIC: int __db_verify_internal __P((DB *, const char *,
- * PUBLIC: const char *, void *, int (*)(void *, const void *), u_int32_t));
- */
-int
-__db_verify_internal(dbp, fname, dname, handle, callback, flags)
- DB *dbp;
- const char *fname, *dname;
- void *handle;
- int (*callback) __P((void *, const void *));
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- int ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- PANIC_CHECK(dbenv);
- DB_ILLEGAL_AFTER_OPEN(dbp, "DB->verify");
-
-#ifdef HAVE_FTRUNCATE
- /*
- * If we're using ftruncate to abort page-allocation functions, there
- * should never be unreferenced pages. Always check for unreferenced
- * pages on those systems.
- */
- if (!LF_ISSET(DB_SALVAGE))
- LF_SET(DB_UNREF);
-#endif
-
- if ((ret = __db_verify_arg(dbp, dname, handle, flags)) == 0)
- ret = __db_verify(dbp, fname, dname, handle, callback, flags);
-
- /* Db.verify is a DB handle destructor. */
- if ((t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_verify_arg --
- * Check DB->verify arguments.
- */
-static int
-__db_verify_arg(dbp, dname, handle, flags)
- DB *dbp;
- const char *dname;
- void *handle;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- int ret;
-
- dbenv = dbp->dbenv;
-
- if ((ret = __db_fchk(dbenv, "DB->verify", flags, VERIFY_FLAGS)) != 0)
- return (ret);
-
- /*
- * DB_SALVAGE is mutually exclusive with the other flags except
- * DB_AGGRESSIVE, DB_PRINTABLE.
- *
- * DB_AGGRESSIVE and DB_PRINTABLE are only meaningful when salvaging.
- *
- * DB_SALVAGE requires an output stream.
- */
- if (LF_ISSET(DB_SALVAGE)) {
- if (LF_ISSET(~(DB_AGGRESSIVE | DB_PRINTABLE | DB_SALVAGE)))
- return (__db_ferr(dbenv, "DB->verify", 1));
- if (handle == NULL) {
- __db_err(dbenv,
- "DB_SALVAGE requires a an output handle");
- return (EINVAL);
- }
- } else
- if (LF_ISSET(DB_AGGRESSIVE | DB_PRINTABLE))
- return (__db_ferr(dbenv, "DB->verify", 1));
-
- /*
- * DB_ORDERCHKONLY is mutually exclusive with DB_SALVAGE and
- * DB_NOORDERCHK, and requires a database name.
- */
- if ((ret = __db_fcchk(dbenv, "DB->verify", flags,
- DB_ORDERCHKONLY, DB_SALVAGE | DB_NOORDERCHK)) != 0)
- return (ret);
- if (LF_ISSET(DB_ORDERCHKONLY) && dname == NULL) {
- __db_err(dbenv, "DB_ORDERCHKONLY requires a database name");
- return (EINVAL);
- }
- return (0);
-}
-
-/*
- * __db_verify --
- * Walk the entire file page-by-page, either verifying with or without
- * dumping in db_dump -d format, or DB_SALVAGE-ing whatever key/data
- * pairs can be found and dumping them in standard (db_load-ready)
- * dump format.
- *
- * (Salvaging isn't really a verification operation, but we put it
- * here anyway because it requires essentially identical top-level
- * code.)
- *
- * flags may be 0, DB_NOORDERCHK, DB_ORDERCHKONLY, or DB_SALVAGE
- * (and optionally DB_AGGRESSIVE).
- */
-static int
-__db_verify(dbp, name, subdb, handle, callback, flags)
- DB *dbp;
- const char *name, *subdb;
- void *handle;
- int (*callback) __P((void *, const void *));
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_FH *fhp;
- VRFY_DBINFO *vdp;
- int has_subdbs, isbad, ret, t_ret;
- char *real_name;
-
- dbenv = dbp->dbenv;
- fhp = NULL;
- vdp = NULL;
- real_name = NULL;
- has_subdbs = isbad = ret = 0;
-
- F_SET(dbp, DB_AM_VERIFYING);
-
- /* Initialize any feedback function. */
- if (!LF_ISSET(DB_SALVAGE) && dbp->db_feedback != NULL)
- dbp->db_feedback(dbp, DB_VERIFY, 0);
-
- /*
- * We don't know how large the cache is, and if the database
- * in question uses a small page size--which we don't know
- * yet!--it may be uncomfortably small for the default page
- * size [#2143]. However, the things we need temporary
- * databases for in dbinfo are largely tiny, so using a
- * 1024-byte pagesize is probably not going to be a big hit,
- * and will make us fit better into small spaces.
- */
- if ((ret = __db_vrfy_dbinfo_create(dbenv, 1024, &vdp)) != 0)
- goto err;
-
- /*
- * Note whether the user has requested that we use printable
- * chars where possible. We won't get here with this flag if
- * we're not salvaging.
- */
- if (LF_ISSET(DB_PRINTABLE))
- F_SET(vdp, SALVAGE_PRINTABLE);
-
- /* Find the real name of the file. */
- if ((ret = __db_appname(dbenv,
- DB_APP_DATA, name, 0, NULL, &real_name)) != 0)
- goto err;
-
- /*
- * Our first order of business is to verify page 0, which is
- * the metadata page for the master database of subdatabases
- * or of the only database in the file. We want to do this by hand
- * rather than just calling __db_open in case it's corrupt--various
- * things in __db_open might act funny.
- *
- * Once we know the metadata page is healthy, I believe that it's
- * safe to open the database normally and then use the page swapping
- * code, which makes life easier.
- */
- if ((ret = __os_open(dbenv, real_name, DB_OSO_RDONLY, 0, &fhp)) != 0)
- goto err;
-
- /* Verify the metadata page 0; set pagesize and type. */
- if ((ret = __db_vrfy_pagezero(dbp, vdp, fhp, flags)) != 0) {
- if (ret == DB_VERIFY_BAD)
- isbad = 1;
- else
- goto err;
- }
-
- /*
- * We can assume at this point that dbp->pagesize and dbp->type are
- * set correctly, or at least as well as they can be, and that
- * locking, logging, and txns are not in use. Thus we can trust
- * the memp code not to look at the page, and thus to be safe
- * enough to use.
- *
- * The dbp is not open, but the file is open in the fhp, and we
- * cannot assume that __db_open is safe. Call __db_dbenv_setup,
- * the [safe] part of __db_open that initializes the environment--
- * and the mpool--manually.
- */
- if ((ret = __db_dbenv_setup(dbp, NULL,
- name, subdb, TXN_INVALID, DB_ODDFILESIZE | DB_RDONLY)) != 0)
- goto err;
-
- /*
- * Set our name in the Queue subsystem; we may need it later
- * to deal with extents.
- */
- if (dbp->type == DB_QUEUE &&
- (ret = __qam_set_ext_data(dbp, name)) != 0)
- goto err;
-
- /* Mark the dbp as opened, so that we correctly handle its close. */
- F_SET(dbp, DB_AM_OPEN_CALLED);
-
- /* Find out the page number of the last page in the database. */
- if ((ret = __memp_last_pgno(dbp->mpf, &vdp->last_pgno)) != 0)
- goto err;
-
- /*
- * DB_ORDERCHKONLY is a special case; our file consists of
- * several subdatabases, which use different hash, bt_compare,
- * and/or dup_compare functions. Consequently, we couldn't verify
- * sorting and hashing simply by calling DB->verify() on the file.
- * DB_ORDERCHKONLY allows us to come back and check those things; it
- * requires a subdatabase, and assumes that everything but that
- * database's sorting/hashing is correct.
- */
- if (LF_ISSET(DB_ORDERCHKONLY)) {
- ret = __db_vrfy_orderchkonly(dbp, vdp, name, subdb, flags);
- goto done;
- }
-
- /*
- * When salvaging, we use a db to keep track of whether we've seen a
- * given overflow or dup page in the course of traversing normal data.
- * If in the end we have not, we assume its key got lost and print it
- * with key "UNKNOWN".
- */
- if (LF_ISSET(DB_SALVAGE)) {
- if ((ret = __db_salvage_init(vdp)) != 0)
- goto err;
-
- /*
- * If we're not being aggressive, attempt to crack subdatabases.
- * "has_subdbs" will indicate whether the attempt has succeeded
- * (even in part), meaning that we have some semblance of
- * subdatabases; on the walkpages pass, we print out whichever
- * data pages we have not seen.
- */
- if (!LF_ISSET(DB_AGGRESSIVE) && __db_salvage_subdbs(
- dbp, vdp, handle, callback, flags, &has_subdbs) != 0)
- isbad = 1;
-
- /*
- * If we have subdatabases, flag if any keys are found that
- * don't belong to a subdatabase -- they'll need to have an
- * "__OTHER__" subdatabase header printed first.
- */
- if (has_subdbs)
- F_SET(vdp, SALVAGE_PRINTHEADER);
- }
-
- if ((ret =
- __db_vrfy_walkpages(dbp, vdp, handle, callback, flags)) != 0) {
- if (ret == DB_VERIFY_BAD)
- isbad = 1;
- else
- goto err;
- }
-
- /* If we're verifying, verify inter-page structure. */
- if (!LF_ISSET(DB_SALVAGE) && isbad == 0)
- if ((ret =
- __db_vrfy_structure(dbp, vdp, name, 0, flags)) != 0) {
- if (ret == DB_VERIFY_BAD)
- isbad = 1;
- else
- goto err;
- }
-
- /*
- * If we're salvaging, output with key UNKNOWN any overflow or dup pages
- * we haven't been able to put in context. Then destroy the salvager's
- * state-saving database.
- */
- if (LF_ISSET(DB_SALVAGE)) {
- if ((ret = __db_salvage_unknowns(dbp,
- vdp, handle, callback, flags)) != 0)
- isbad = 1;
- /* No return value, since there's little we can do. */
- __db_salvage_destroy(vdp);
- }
-
- /* Don't display a footer for a database holding other databases. */
- if (LF_ISSET(DB_SALVAGE) &&
- (!has_subdbs || F_ISSET(vdp, SALVAGE_PRINTFOOTER)))
- (void)__db_prfooter(handle, callback);
-
-done: err:
- /* Send feedback that we're done. */
- if (!LF_ISSET(DB_SALVAGE) && dbp->db_feedback != NULL)
- dbp->db_feedback(dbp, DB_VERIFY, 100);
-
- if (fhp != NULL &&
- (t_ret = __os_closehandle(dbenv, fhp)) != 0 && ret == 0)
- ret = t_ret;
- if (vdp != NULL &&
- (t_ret = __db_vrfy_dbinfo_destroy(dbenv, vdp)) != 0 && ret == 0)
- ret = t_ret;
- if (real_name != NULL)
- __os_free(dbenv, real_name);
-
- /*
- * DB_VERIFY_FATAL is a private error, translate to a public one.
- *
- * If we didn't find a page, it's probably a page number was corrupted.
- * Return the standard corruption error.
- *
- * Otherwise, if we found corruption along the way, set the return.
- */
- if (ret == DB_VERIFY_FATAL ||
- ret == DB_PAGE_NOTFOUND || (ret == 0 && isbad == 1))
- ret = DB_VERIFY_BAD;
-
- /* Make sure there's a public complaint if we found corruption. */
- if (ret != 0)
- __db_err(dbenv, "%s: %s", name, db_strerror(ret));
-
- return (ret);
-}
-
-/*
- * __db_vrfy_pagezero --
- * Verify the master metadata page. Use seek, read, and a local buffer
- * rather than the DB paging code, for safety.
- *
- * Must correctly (or best-guess) set dbp->type and dbp->pagesize.
- */
-static int
-__db_vrfy_pagezero(dbp, vdp, fhp, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- DB_FH *fhp;
- u_int32_t flags;
-{
- DBMETA *meta;
- DB_ENV *dbenv;
- VRFY_PAGEINFO *pip;
- db_pgno_t freelist;
- size_t nr;
- int isbad, ret, swapped;
- u_int8_t mbuf[DBMETASIZE];
-
- isbad = ret = swapped = 0;
- freelist = 0;
- dbenv = dbp->dbenv;
- meta = (DBMETA *)mbuf;
- dbp->type = DB_UNKNOWN;
-
- if ((ret = __db_vrfy_getpageinfo(vdp, PGNO_BASE_MD, &pip)) != 0)
- return (ret);
-
- /*
- * Seek to the metadata page.
- * Note that if we're just starting a verification, dbp->pgsize
- * may be zero; this is okay, as we want page zero anyway and
- * 0*0 == 0.
- */
- if ((ret = __os_seek(dbenv, fhp, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0 ||
- (ret = __os_read(dbenv, fhp, mbuf, DBMETASIZE, &nr)) != 0) {
- __db_err(dbenv,
- "Metadata page %lu cannot be read: %s",
- (u_long)PGNO_BASE_MD, db_strerror(ret));
- return (ret);
- }
-
- if (nr != DBMETASIZE) {
- EPRINT((dbenv,
- "Page %lu: Incomplete metadata page",
- (u_long)PGNO_BASE_MD));
- return (DB_VERIFY_FATAL);
- }
-
- if ((ret = __db_chk_meta(dbenv, dbp, meta, 1)) != 0) {
- EPRINT((dbenv,
- "Page %lu: metadata page corrupted", (u_long)PGNO_BASE_MD));
- isbad = 1;
- if (ret != -1) {
- EPRINT((dbenv,
- "Page %lu: could not check metadata page",
- (u_long)PGNO_BASE_MD));
- return (DB_VERIFY_FATAL);
- }
- }
-
- /*
- * Check all of the fields that we can.
- *
- * 08-11: Current page number. Must == pgno.
- * Note that endianness doesn't matter--it's zero.
- */
- if (meta->pgno != PGNO_BASE_MD) {
- isbad = 1;
- EPRINT((dbenv, "Page %lu: pgno incorrectly set to %lu",
- (u_long)PGNO_BASE_MD, (u_long)meta->pgno));
- }
-
- /* 12-15: Magic number. Must be one of valid set. */
- if (__db_is_valid_magicno(meta->magic, &dbp->type))
- swapped = 0;
- else {
- M_32_SWAP(meta->magic);
- if (__db_is_valid_magicno(meta->magic,
- &dbp->type))
- swapped = 1;
- else {
- isbad = 1;
- EPRINT((dbenv,
- "Page %lu: bad magic number %lu",
- (u_long)PGNO_BASE_MD, (u_long)meta->magic));
- }
- }
-
- /*
- * 16-19: Version. Must be current; for now, we
- * don't support verification of old versions.
- */
- if (swapped)
- M_32_SWAP(meta->version);
- if ((dbp->type == DB_BTREE &&
- (meta->version > DB_BTREEVERSION ||
- meta->version < DB_BTREEOLDVER)) ||
- (dbp->type == DB_HASH &&
- (meta->version > DB_HASHVERSION ||
- meta->version < DB_HASHOLDVER)) ||
- (dbp->type == DB_QUEUE &&
- (meta->version > DB_QAMVERSION ||
- meta->version < DB_QAMOLDVER))) {
- isbad = 1;
- EPRINT((dbenv,
- "Page %lu: unsupported DB version %lu; extraneous errors may result",
- (u_long)PGNO_BASE_MD, (u_long)meta->version));
- }
-
- /*
- * 20-23: Pagesize. Must be power of two,
- * greater than 512, and less than 64K.
- */
- if (swapped)
- M_32_SWAP(meta->pagesize);
- if (IS_VALID_PAGESIZE(meta->pagesize))
- dbp->pgsize = meta->pagesize;
- else {
- isbad = 1;
- EPRINT((dbenv, "Page %lu: bad page size %lu",
- (u_long)PGNO_BASE_MD, (u_long)meta->pagesize));
-
- /*
- * Now try to settle on a pagesize to use.
- * If the user-supplied one is reasonable,
- * use it; else, guess.
- */
- if (!IS_VALID_PAGESIZE(dbp->pgsize))
- dbp->pgsize = __db_guesspgsize(dbenv, fhp);
- }
-
- /*
- * 25: Page type. Must be correct for dbp->type,
- * which is by now set as well as it can be.
- */
- /* Needs no swapping--only one byte! */
- if ((dbp->type == DB_BTREE && meta->type != P_BTREEMETA) ||
- (dbp->type == DB_HASH && meta->type != P_HASHMETA) ||
- (dbp->type == DB_QUEUE && meta->type != P_QAMMETA)) {
- isbad = 1;
- EPRINT((dbenv, "Page %lu: bad page type %lu",
- (u_long)PGNO_BASE_MD, (u_long)meta->type));
- }
-
- /*
- * 26: Meta-flags.
- */
- if (meta->metaflags != 0) {
- if (meta->metaflags == DBMETA_CHKSUM)
- F_SET(pip, VRFY_HAS_CHKSUM);
- else {
- isbad = 1;
- EPRINT((dbenv,
- "Page %lu: bad meta-data flags value %#lx",
- (u_long)PGNO_BASE_MD, (u_long)meta->metaflags));
- }
- }
-
- /*
- * 28-31: Free list page number.
- * We'll verify its sensibility when we do inter-page
- * verification later; for now, just store it.
- */
- if (swapped)
- M_32_SWAP(meta->free);
- freelist = meta->free;
-
- /*
- * Initialize vdp->pages to fit a single pageinfo structure for
- * this one page. We'll realloc later when we know how many
- * pages there are.
- */
- pip->pgno = PGNO_BASE_MD;
- pip->type = meta->type;
-
- /*
- * Signal that we still have to check the info specific to
- * a given type of meta page.
- */
- F_SET(pip, VRFY_INCOMPLETE);
-
- pip->free = freelist;
-
- if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0)
- return (ret);
-
- /* Set up the dbp's fileid. We don't use the regular open path. */
- memcpy(dbp->fileid, meta->uid, DB_FILE_ID_LEN);
-
- if (swapped == 1)
- F_SET(dbp, DB_AM_SWAP);
-
- return (isbad ? DB_VERIFY_BAD : 0);
-}
-
-/*
- * __db_vrfy_walkpages --
- * Main loop of the verifier/salvager. Walks through,
- * page by page, and verifies all pages and/or prints all data pages.
- */
-static int
-__db_vrfy_walkpages(dbp, vdp, handle, callback, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- void *handle;
- int (*callback) __P((void *, const void *));
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DB_MPOOLFILE *mpf;
- PAGE *h;
- db_pgno_t i;
- int ret, t_ret, isbad;
-
- dbenv = dbp->dbenv;
- mpf = dbp->mpf;
- h = NULL;
- ret = isbad = t_ret = 0;
-
- for (i = 0; i <= vdp->last_pgno; i++) {
- /*
- * If DB_SALVAGE is set, we inspect our database of completed
- * pages, and skip any we've already printed in the subdb pass.
- */
- if (LF_ISSET(DB_SALVAGE) && (__db_salvage_isdone(vdp, i) != 0))
- continue;
-
- /*
- * If an individual page get fails, keep going if and only
- * if we're salvaging.
- */
- if ((t_ret = __memp_fget(mpf, &i, 0, &h)) != 0) {
- if (ret == 0)
- ret = t_ret;
- if (LF_ISSET(DB_SALVAGE))
- continue;
- return (ret);
- }
-
- if (LF_ISSET(DB_SALVAGE)) {
- /*
- * We pretty much don't want to quit unless a
- * bomb hits. May as well return that something
- * was screwy, however.
- */
- if ((t_ret = __db_salvage(dbp,
- vdp, i, h, handle, callback, flags)) != 0) {
- if (ret == 0)
- ret = t_ret;
- isbad = 1;
- }
- } else {
- /*
- * If we are not salvaging, and we get any error
- * other than DB_VERIFY_BAD, return immediately;
- * it may not be safe to proceed. If we get
- * DB_VERIFY_BAD, keep going; listing more errors
- * may make it easier to diagnose problems and
- * determine the magnitude of the corruption.
- *
- * Verify info common to all page types.
- */
- if (i != PGNO_BASE_MD) {
- ret = __db_vrfy_common(dbp, vdp, h, i, flags);
- if (ret == DB_VERIFY_BAD)
- isbad = 1;
- else if (ret != 0)
- goto err;
- }
-
- switch (TYPE(h)) {
- case P_INVALID:
- ret = __db_vrfy_invalid(dbp, vdp, h, i, flags);
- break;
- case __P_DUPLICATE:
- isbad = 1;
- EPRINT((dbenv,
- "Page %lu: old-style duplicate page",
- (u_long)i));
- break;
- case P_HASH:
- ret = __ham_vrfy(dbp, vdp, h, i, flags);
- break;
- case P_IBTREE:
- case P_IRECNO:
- case P_LBTREE:
- case P_LDUP:
- ret = __bam_vrfy(dbp, vdp, h, i, flags);
- break;
- case P_LRECNO:
- ret = __ram_vrfy_leaf(dbp, vdp, h, i, flags);
- break;
- case P_OVERFLOW:
- ret = __db_vrfy_overflow(dbp, vdp, h, i, flags);
- break;
- case P_HASHMETA:
- ret = __ham_vrfy_meta(dbp,
- vdp, (HMETA *)h, i, flags);
- break;
- case P_BTREEMETA:
- ret = __bam_vrfy_meta(dbp,
- vdp, (BTMETA *)h, i, flags);
- break;
- case P_QAMMETA:
- ret = __qam_vrfy_meta(dbp,
- vdp, (QMETA *)h, i, flags);
- break;
- case P_QAMDATA:
- ret = __qam_vrfy_data(dbp,
- vdp, (QPAGE *)h, i, flags);
- break;
- default:
- EPRINT((dbenv,
- "Page %lu: unknown page type %lu",
- (u_long)i, (u_long)TYPE(h)));
- isbad = 1;
- break;
- }
-
- /*
- * Set up error return.
- */
- if (ret == DB_VERIFY_BAD)
- isbad = 1;
- else if (ret != 0)
- goto err;
-
- /*
- * Provide feedback to the application about our
- * progress. The range 0-50% comes from the fact
- * that this is the first of two passes through the
- * database (front-to-back, then top-to-bottom).
- */
- if (dbp->db_feedback != NULL)
- dbp->db_feedback(dbp, DB_VERIFY,
- (int)((i + 1) * 50 / (vdp->last_pgno + 1)));
- }
-
- /*
- * Just as with the page get, bail if and only if we're
- * not salvaging.
- */
- if ((t_ret = __memp_fput(mpf, h, 0)) != 0) {
- if (ret == 0)
- ret = t_ret;
- if (!LF_ISSET(DB_SALVAGE))
- return (ret);
- }
- }
-
- /*
- * If we've seen a Queue metadata page, we may need to walk Queue
- * extent pages that won't show up between 0 and vdp->last_pgno.
- */
- if (F_ISSET(vdp, VRFY_QMETA_SET) && (t_ret =
- __qam_vrfy_walkqueue(dbp, vdp, handle, callback, flags)) != 0) {
- if (ret == 0)
- ret = t_ret;
- if (t_ret == DB_VERIFY_BAD)
- isbad = 1;
- else if (!LF_ISSET(DB_SALVAGE))
- return (ret);
- }
-
- if (0) {
-err: if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0)
- return (ret == 0 ? t_ret : ret);
- }
-
- return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);
-}
-
-/*
- * __db_vrfy_structure--
- * After a beginning-to-end walk through the database has been
- * completed, put together the information that has been collected
- * to verify the overall database structure.
- *
- * Should only be called if we want to do a database verification,
- * i.e. if DB_SALVAGE is not set.
- */
-static int
-__db_vrfy_structure(dbp, vdp, dbname, meta_pgno, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- const char *dbname;
- db_pgno_t meta_pgno;
- u_int32_t flags;
-{
- DB *pgset;
- DB_ENV *dbenv;
- VRFY_PAGEINFO *pip;
- db_pgno_t i;
- int ret, isbad, hassubs, p;
-
- isbad = 0;
- pip = NULL;
- dbenv = dbp->dbenv;
- pgset = vdp->pgset;
-
- /*
- * Providing feedback here is tricky; in most situations,
- * we fetch each page one more time, but we do so in a top-down
- * order that depends on the access method. Worse, we do this
- * recursively in btree, such that on any call where we're traversing
- * a subtree we don't know where that subtree is in the whole database;
- * worse still, any given database may be one of several subdbs.
- *
- * The solution is to decrement a counter vdp->pgs_remaining each time
- * we verify (and call feedback on) a page. We may over- or
- * under-count, but the structure feedback function will ensure that we
- * never give a percentage under 50 or over 100. (The first pass
- * covered the range 0-50%.)
- */
- if (dbp->db_feedback != NULL)
- vdp->pgs_remaining = vdp->last_pgno + 1;
-
- /*
- * Call the appropriate function to downwards-traverse the db type.
- */
- switch (dbp->type) {
- case DB_BTREE:
- case DB_RECNO:
- if ((ret = __bam_vrfy_structure(dbp, vdp, 0, flags)) != 0) {
- if (ret == DB_VERIFY_BAD)
- isbad = 1;
- else
- goto err;
- }
-
- /*
- * If we have subdatabases and we know that the database is,
- * thus far, sound, it's safe to walk the tree of subdatabases.
- * Do so, and verify the structure of the databases within.
- */
- if ((ret = __db_vrfy_getpageinfo(vdp, 0, &pip)) != 0)
- goto err;
- hassubs = F_ISSET(pip, VRFY_HAS_SUBDBS) ? 1 : 0;
- if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0)
- goto err;
- pip = NULL;
-
- if (isbad == 0 && hassubs)
- if ((ret =
- __db_vrfy_subdbs(dbp, vdp, dbname, flags)) != 0) {
- if (ret == DB_VERIFY_BAD)
- isbad = 1;
- else
- goto err;
- }
- break;
- case DB_HASH:
- if ((ret = __ham_vrfy_structure(dbp, vdp, 0, flags)) != 0) {
- if (ret == DB_VERIFY_BAD)
- isbad = 1;
- else
- goto err;
- }
- break;
- case DB_QUEUE:
- if ((ret = __qam_vrfy_structure(dbp, vdp, flags)) != 0) {
- if (ret == DB_VERIFY_BAD)
- isbad = 1;
- }
-
- /*
- * Queue pages may be unreferenced and totally zeroed, if
- * they're empty; queue doesn't have much structure, so
- * this is unlikely to be wrong in any troublesome sense.
- * Skip to "err".
- */
- goto err;
- case DB_UNKNOWN:
- default:
- /* This should only happen if the verifier is somehow broken. */
- DB_ASSERT(0);
- ret = EINVAL;
- goto err;
- }
-
- /* Walk free list. */
- if ((ret =
- __db_vrfy_freelist(dbp, vdp, meta_pgno, flags)) == DB_VERIFY_BAD)
- isbad = 1;
-
- /*
- * If structure checks up until now have failed, it's likely that
- * checking what pages have been missed will result in oodles of
- * extraneous error messages being EPRINTed. Skip to the end
- * if this is the case; we're going to be printing at least one
- * error anyway, and probably all the more salient ones.
- */
- if (ret != 0 || isbad == 1)
- goto err;
-
- /*
- * Make sure no page has been missed and that no page is still marked
- * "all zeroes" (only certain hash pages can be, and they're unmarked
- * in __ham_vrfy_structure).
- */
- for (i = 0; i < vdp->last_pgno + 1; i++) {
- if ((ret = __db_vrfy_getpageinfo(vdp, i, &pip)) != 0)
- goto err;
- if ((ret = __db_vrfy_pgset_get(pgset, i, &p)) != 0)
- goto err;
- if (pip->type == P_OVERFLOW) {
- if ((u_int32_t)p != pip->refcount) {
- EPRINT((dbenv,
- "Page %lu: overflow refcount %lu, referenced %lu times",
- (u_long)i,
- (u_long)pip->refcount, (u_long)p));
- isbad = 1;
- }
- } else if (p == 0 && LF_ISSET(DB_UNREF)) {
- EPRINT((dbenv,
- "Page %lu: unreferenced page", (u_long)i));
- isbad = 1;
- }
-
- if (F_ISSET(pip, VRFY_IS_ALLZEROES)) {
- EPRINT((dbenv,
- "Page %lu: totally zeroed page", (u_long)i));
- isbad = 1;
- }
- if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0)
- goto err;
- pip = NULL;
- }
-
-err: if (pip != NULL)
- (void)__db_vrfy_putpageinfo(dbenv, vdp, pip);
-
- return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);
-}
-
-/*
- * __db_is_valid_pagetype
- */
-static int
-__db_is_valid_pagetype(type)
- u_int32_t type;
-{
- switch (type) {
- case P_INVALID: /* Order matches ordinal value. */
- case P_HASH:
- case P_IBTREE:
- case P_IRECNO:
- case P_LBTREE:
- case P_LRECNO:
- case P_OVERFLOW:
- case P_HASHMETA:
- case P_BTREEMETA:
- case P_QAMMETA:
- case P_QAMDATA:
- case P_LDUP:
- return (1);
- default:
- break;
- }
- return (0);
-}
-
-/*
- * __db_is_valid_magicno
- */
-static int
-__db_is_valid_magicno(magic, typep)
- u_int32_t magic;
- DBTYPE *typep;
-{
- switch (magic) {
- case DB_BTREEMAGIC:
- *typep = DB_BTREE;
- return (1);
- case DB_HASHMAGIC:
- *typep = DB_HASH;
- return (1);
- case DB_QAMMAGIC:
- *typep = DB_QUEUE;
- return (1);
- default:
- break;
- }
- *typep = DB_UNKNOWN;
- return (0);
-}
-
-/*
- * __db_vrfy_common --
- * Verify info common to all page types.
- *
- * PUBLIC: int __db_vrfy_common
- * PUBLIC: __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
- */
-int
-__db_vrfy_common(dbp, vdp, h, pgno, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- PAGE *h;
- db_pgno_t pgno;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- VRFY_PAGEINFO *pip;
- int ret, t_ret;
- u_int8_t *p;
-
- dbenv = dbp->dbenv;
-
- if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
- return (ret);
-
- pip->pgno = pgno;
- F_CLR(pip, VRFY_IS_ALLZEROES);
-
- /*
- * Hash expands the table by leaving some pages between the
- * old last and the new last totally zeroed. Its pgin function
- * should fix things, but we might not be using that (e.g. if
- * we're a subdatabase).
- *
- * Queue will create sparse files if sparse record numbers are used.
- */
- if (pgno != 0 && PGNO(h) == 0) {
- for (p = (u_int8_t *)h; p < (u_int8_t *)h + dbp->pgsize; p++)
- if (*p != 0) {
- EPRINT((dbenv,
- "Page %lu: partially zeroed page",
- (u_long)pgno));
- ret = DB_VERIFY_BAD;
- goto err;
- }
- /*
- * It's totally zeroed; mark it as a hash, and we'll
- * check that that makes sense structurally later.
- * (The queue verification doesn't care, since queues
- * don't really have much in the way of structure.)
- */
- pip->type = P_HASH;
- F_SET(pip, VRFY_IS_ALLZEROES);
- ret = 0;
- goto err; /* well, not really an err. */
- }
-
- if (PGNO(h) != pgno) {
- EPRINT((dbenv, "Page %lu: bad page number %lu",
- (u_long)pgno, (u_long)h->pgno));
- ret = DB_VERIFY_BAD;
- }
-
- if (!__db_is_valid_pagetype(h->type)) {
- EPRINT((dbenv, "Page %lu: bad page type %lu",
- (u_long)pgno, (u_long)h->type));
- ret = DB_VERIFY_BAD;
- }
- pip->type = h->type;
-
-err: if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0)
- ret = t_ret;
-
- return (ret);
-}
-
-/*
- * __db_vrfy_invalid --
- * Verify P_INVALID page.
- * (Yes, there's not much to do here.)
- */
-static int
-__db_vrfy_invalid(dbp, vdp, h, pgno, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- PAGE *h;
- db_pgno_t pgno;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- VRFY_PAGEINFO *pip;
- int ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
- return (ret);
- pip->next_pgno = pip->prev_pgno = 0;
-
- if (!IS_VALID_PGNO(NEXT_PGNO(h))) {
- EPRINT((dbenv, "Page %lu: invalid next_pgno %lu",
- (u_long)pgno, (u_long)NEXT_PGNO(h)));
- ret = DB_VERIFY_BAD;
- } else
- pip->next_pgno = NEXT_PGNO(h);
-
- if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
-
-/*
- * __db_vrfy_datapage --
- * Verify elements common to data pages (P_HASH, P_LBTREE,
- * P_IBTREE, P_IRECNO, P_LRECNO, P_OVERFLOW, P_DUPLICATE)--i.e.,
- * those defined in the PAGE structure.
- *
- * Called from each of the per-page routines, after the
- * all-page-type-common elements of pip have been verified and filled
- * in.
- *
- * PUBLIC: int __db_vrfy_datapage
- * PUBLIC: __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
- */
-int
-__db_vrfy_datapage(dbp, vdp, h, pgno, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- PAGE *h;
- db_pgno_t pgno;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- VRFY_PAGEINFO *pip;
- int isbad, ret, t_ret;
-
- dbenv = dbp->dbenv;
-
- if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
- return (ret);
- isbad = 0;
-
- /*
- * prev_pgno and next_pgno: store for inter-page checks,
- * verify that they point to actual pages and not to self.
- *
- * !!!
- * Internal btree pages do not maintain these fields (indeed,
- * they overload them). Skip.
- */
- if (TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO) {
- if (!IS_VALID_PGNO(PREV_PGNO(h)) || PREV_PGNO(h) == pip->pgno) {
- isbad = 1;
- EPRINT((dbenv, "Page %lu: invalid prev_pgno %lu",
- (u_long)pip->pgno, (u_long)PREV_PGNO(h)));
- }
- if (!IS_VALID_PGNO(NEXT_PGNO(h)) || NEXT_PGNO(h) == pip->pgno) {
- isbad = 1;
- EPRINT((dbenv, "Page %lu: invalid next_pgno %lu",
- (u_long)pip->pgno, (u_long)NEXT_PGNO(h)));
- }
- pip->prev_pgno = PREV_PGNO(h);
- pip->next_pgno = NEXT_PGNO(h);
- }
-
- /*
- * Verify the number of entries on the page.
- * There is no good way to determine if this is accurate; the
- * best we can do is verify that it's not more than can, in theory,
- * fit on the page. Then, we make sure there are at least
- * this many valid elements in inp[], and hope that this catches
- * most cases.
- */
- if (TYPE(h) != P_OVERFLOW) {
- if (BKEYDATA_PSIZE(0) * NUM_ENT(h) > dbp->pgsize) {
- isbad = 1;
- EPRINT((dbenv, "Page %lu: too many entries: %lu",
- (u_long)pgno, (u_long)NUM_ENT(h)));
- }
- pip->entries = NUM_ENT(h);
- }
-
- /*
- * btree level. Should be zero unless we're a btree;
- * if we are a btree, should be between LEAFLEVEL and MAXBTREELEVEL,
- * and we need to save it off.
- */
- switch (TYPE(h)) {
- case P_IBTREE:
- case P_IRECNO:
- if (LEVEL(h) < LEAFLEVEL + 1) {
- isbad = 1;
- EPRINT((dbenv, "Page %lu: bad btree level %lu",
- (u_long)pgno, (u_long)LEVEL(h)));
- }
- pip->bt_level = LEVEL(h);
- break;
- case P_LBTREE:
- case P_LDUP:
- case P_LRECNO:
- if (LEVEL(h) != LEAFLEVEL) {
- isbad = 1;
- EPRINT((dbenv,
- "Page %lu: btree leaf page has incorrect level %lu",
- (u_long)pgno, (u_long)LEVEL(h)));
- }
- break;
- default:
- if (LEVEL(h) != 0) {
- isbad = 1;
- EPRINT((dbenv,
- "Page %lu: nonzero level %lu in non-btree database",
- (u_long)pgno, (u_long)LEVEL(h)));
- }
- break;
- }
-
- /*
- * Even though inp[] occurs in all PAGEs, we look at it in the
- * access-method-specific code, since btree and hash treat
- * item lengths very differently, and one of the most important
- * things we want to verify is that the data--as specified
- * by offset and length--cover the right part of the page
- * without overlaps, gaps, or violations of the page boundary.
- */
- if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0)
- ret = t_ret;
-
- return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
-}
-
-/*
- * __db_vrfy_meta--
- * Verify the access-method common parts of a meta page, using
- * normal mpool routines.
- *
- * PUBLIC: int __db_vrfy_meta
- * PUBLIC: __P((DB *, VRFY_DBINFO *, DBMETA *, db_pgno_t, u_int32_t));
- */
-int
-__db_vrfy_meta(dbp, vdp, meta, pgno, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- DBMETA *meta;
- db_pgno_t pgno;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- DBTYPE dbtype, magtype;
- VRFY_PAGEINFO *pip;
- int isbad, ret, t_ret;
-
- isbad = 0;
- dbenv = dbp->dbenv;
-
- if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
- return (ret);
-
- /* type plausible for a meta page */
- switch (meta->type) {
- case P_BTREEMETA:
- dbtype = DB_BTREE;
- break;
- case P_HASHMETA:
- dbtype = DB_HASH;
- break;
- case P_QAMMETA:
- dbtype = DB_QUEUE;
- break;
- default:
- /* The verifier should never let us get here. */
- DB_ASSERT(0);
- ret = EINVAL;
- goto err;
- }
-
- /* magic number valid */
- if (!__db_is_valid_magicno(meta->magic, &magtype)) {
- isbad = 1;
- EPRINT((dbenv,
- "Page %lu: invalid magic number", (u_long)pgno));
- }
- if (magtype != dbtype) {
- isbad = 1;
- EPRINT((dbenv,
- "Page %lu: magic number does not match database type",
- (u_long)pgno));
- }
-
- /* version */
- if ((dbtype == DB_BTREE &&
- (meta->version > DB_BTREEVERSION ||
- meta->version < DB_BTREEOLDVER)) ||
- (dbtype == DB_HASH &&
- (meta->version > DB_HASHVERSION ||
- meta->version < DB_HASHOLDVER)) ||
- (dbtype == DB_QUEUE &&
- (meta->version > DB_QAMVERSION ||
- meta->version < DB_QAMOLDVER))) {
- isbad = 1;
- EPRINT((dbenv,
- "Page %lu: unsupported database version %lu; extraneous errors may result",
- (u_long)pgno, (u_long)meta->version));
- }
-
- /* pagesize */
- if (meta->pagesize != dbp->pgsize) {
- isbad = 1;
- EPRINT((dbenv, "Page %lu: invalid pagesize %lu",
- (u_long)pgno, (u_long)meta->pagesize));
- }
-
- /* Flags */
- if (meta->metaflags != 0) {
- if (meta->metaflags == DBMETA_CHKSUM)
- F_SET(pip, VRFY_HAS_CHKSUM);
- else {
- isbad = 1;
- EPRINT((dbenv,
- "Page %lu: bad meta-data flags value %#lx",
- (u_long)PGNO_BASE_MD, (u_long)meta->metaflags));
- }
- }
-
- /*
- * Free list.
- *
- * If this is not the main, master-database meta page, it
- * should not have a free list.
- */
- if (pgno != PGNO_BASE_MD && meta->free != PGNO_INVALID) {
- isbad = 1;
- EPRINT((dbenv,
- "Page %lu: nonempty free list on subdatabase metadata page",
- (u_long)pgno));
- }
-
- /* Can correctly be PGNO_INVALID--that's just the end of the list. */
- if (meta->free != PGNO_INVALID && IS_VALID_PGNO(meta->free))
- pip->free = meta->free;
- else if (!IS_VALID_PGNO(meta->free)) {
- isbad = 1;
- EPRINT((dbenv,
- "Page %lu: nonsensical free list pgno %lu",
- (u_long)pgno, (u_long)meta->free));
- }
-
- /*
- * We have now verified the common fields of the metadata page.
- * Clear the flag that told us they had been incompletely checked.
- */
- F_CLR(pip, VRFY_INCOMPLETE);
-
-err: if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0)
- ret = t_ret;
-
- return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
-}
-
-/*
- * __db_vrfy_freelist --
- * Walk free list, checking off pages and verifying absence of
- * loops.
- */
-static int
-__db_vrfy_freelist(dbp, vdp, meta, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- db_pgno_t meta;
- u_int32_t flags;
-{
- DB *pgset;
- DB_ENV *dbenv;
- VRFY_PAGEINFO *pip;
- db_pgno_t cur_pgno, next_pgno;
- int p, ret, t_ret;
-
- pgset = vdp->pgset;
- DB_ASSERT(pgset != NULL);
- dbenv = dbp->dbenv;
-
- if ((ret = __db_vrfy_getpageinfo(vdp, meta, &pip)) != 0)
- return (ret);
- for (next_pgno = pip->free;
- next_pgno != PGNO_INVALID; next_pgno = pip->next_pgno) {
- cur_pgno = pip->pgno;
- if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0)
- return (ret);
-
- /* This shouldn't happen, but just in case. */
- if (!IS_VALID_PGNO(next_pgno)) {
- EPRINT((dbenv,
- "Page %lu: invalid next_pgno %lu on free list page",
- (u_long)cur_pgno, (u_long)next_pgno));
- return (DB_VERIFY_BAD);
- }
-
- /* Detect cycles. */
- if ((ret = __db_vrfy_pgset_get(pgset, next_pgno, &p)) != 0)
- return (ret);
- if (p != 0) {
- EPRINT((dbenv,
- "Page %lu: page %lu encountered a second time on free list",
- (u_long)cur_pgno, (u_long)next_pgno));
- return (DB_VERIFY_BAD);
- }
- if ((ret = __db_vrfy_pgset_inc(pgset, next_pgno)) != 0)
- return (ret);
-
- if ((ret = __db_vrfy_getpageinfo(vdp, next_pgno, &pip)) != 0)
- return (ret);
-
- if (pip->type != P_INVALID) {
- EPRINT((dbenv,
- "Page %lu: non-invalid page %lu on free list",
- (u_long)cur_pgno, (u_long)next_pgno));
- ret = DB_VERIFY_BAD; /* unsafe to continue */
- break;
- }
- }
-
- if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0)
- ret = t_ret;
- return (ret);
-}
-
-/*
- * __db_vrfy_subdbs --
- * Walk the known-safe master database of subdbs with a cursor,
- * verifying the structure of each subdatabase we encounter.
- */
-static int
-__db_vrfy_subdbs(dbp, vdp, dbname, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- const char *dbname;
- u_int32_t flags;
-{
- DB *mdbp;
- DBC *dbc;
- DBT key, data;
- DB_ENV *dbenv;
- VRFY_PAGEINFO *pip;
- db_pgno_t meta_pgno;
- int ret, t_ret, isbad;
- u_int8_t type;
-
- isbad = 0;
- dbc = NULL;
- dbenv = dbp->dbenv;
-
- if ((ret =
- __db_master_open(dbp, NULL, dbname, DB_RDONLY, 0, &mdbp)) != 0)
- return (ret);
-
- if ((ret = __db_cursor_int(mdbp,
- NULL, DB_BTREE, PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0)
- goto err;
-
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
- while ((ret = __db_c_get(dbc, &key, &data, DB_NEXT)) == 0) {
- if (data.size != sizeof(db_pgno_t)) {
- EPRINT((dbenv,
- "Subdatabase entry not page-number size"));
- isbad = 1;
- goto err;
- }
- memcpy(&meta_pgno, data.data, data.size);
- /*
- * Subdatabase meta pgnos are stored in network byte
- * order for cross-endian compatibility. Swap if appropriate.
- */
- DB_NTOHL(&meta_pgno);
- if (meta_pgno == PGNO_INVALID || meta_pgno > vdp->last_pgno) {
- EPRINT((dbenv,
- "Subdatabase entry references invalid page %lu",
- (u_long)meta_pgno));
- isbad = 1;
- goto err;
- }
- if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &pip)) != 0)
- goto err;
- type = pip->type;
- if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0)
- goto err;
- switch (type) {
- case P_BTREEMETA:
- if ((ret = __bam_vrfy_structure(
- dbp, vdp, meta_pgno, flags)) != 0) {
- if (ret == DB_VERIFY_BAD)
- isbad = 1;
- else
- goto err;
- }
- break;
- case P_HASHMETA:
- if ((ret = __ham_vrfy_structure(
- dbp, vdp, meta_pgno, flags)) != 0) {
- if (ret == DB_VERIFY_BAD)
- isbad = 1;
- else
- goto err;
- }
- break;
- case P_QAMMETA:
- default:
- EPRINT((dbenv,
- "Subdatabase entry references page %lu of invalid type %lu",
- (u_long)meta_pgno, (u_long)type));
- ret = DB_VERIFY_BAD;
- goto err;
- }
- }
-
- if (ret == DB_NOTFOUND)
- ret = 0;
-
-err: if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- if ((t_ret = __db_close(mdbp, NULL, 0)) != 0 && ret == 0)
- ret = t_ret;
-
- return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
-}
-
-/*
- * __db_vrfy_struct_feedback --
- * Provide feedback during top-down database structure traversal.
- * (See comment at the beginning of __db_vrfy_structure.)
- *
- * PUBLIC: void __db_vrfy_struct_feedback __P((DB *, VRFY_DBINFO *));
- */
-void
-__db_vrfy_struct_feedback(dbp, vdp)
- DB *dbp;
- VRFY_DBINFO *vdp;
-{
- int progress;
-
- if (dbp->db_feedback == NULL)
- return;
-
- if (vdp->pgs_remaining > 0)
- vdp->pgs_remaining--;
-
- /* Don't allow a feedback call of 100 until we're really done. */
- progress = 100 - (int)(vdp->pgs_remaining * 50 / (vdp->last_pgno + 1));
- dbp->db_feedback(dbp, DB_VERIFY, progress == 100 ? 99 : progress);
-}
-
-/*
- * __db_vrfy_orderchkonly --
- * Do an sort-order/hashing check on a known-otherwise-good subdb.
- */
-static int
-__db_vrfy_orderchkonly(dbp, vdp, name, subdb, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- const char *name, *subdb;
- u_int32_t flags;
-{
- BTMETA *btmeta;
- DB *mdbp, *pgset;
- DBC *pgsc;
- DBT key, data;
- DB_ENV *dbenv;
- DB_MPOOLFILE *mpf;
- HASH *h_internal;
- HMETA *hmeta;
- PAGE *h, *currpg;
- db_pgno_t meta_pgno, p, pgno;
- u_int32_t bucket;
- int t_ret, ret;
-
- pgset = NULL;
- pgsc = NULL;
- dbenv = dbp->dbenv;
- mpf = dbp->mpf;
- currpg = h = NULL;
-
- LF_CLR(DB_NOORDERCHK);
-
- /* Open the master database and get the meta_pgno for the subdb. */
- if ((ret = __db_master_open(dbp, NULL, name, DB_RDONLY, 0, &mdbp)) != 0)
- goto err;
-
- memset(&key, 0, sizeof(key));
- key.data = (void *)subdb;
- key.size = (u_int32_t)strlen(subdb);
- memset(&data, 0, sizeof(data));
- if ((ret = __db_get(mdbp, NULL, &key, &data, 0)) != 0)
- goto err;
-
- if (data.size != sizeof(db_pgno_t)) {
- EPRINT((dbenv, "Subdatabase entry of invalid size"));
- ret = DB_VERIFY_BAD;
- goto err;
- }
-
- memcpy(&meta_pgno, data.data, data.size);
-
- /*
- * Subdatabase meta pgnos are stored in network byte
- * order for cross-endian compatibility. Swap if appropriate.
- */
- DB_NTOHL(&meta_pgno);
-
- if ((ret = __memp_fget(mpf, &meta_pgno, 0, &h)) != 0)
- goto err;
-
- if ((ret = __db_vrfy_pgset(dbenv, dbp->pgsize, &pgset)) != 0)
- goto err;
-
- switch (TYPE(h)) {
- case P_BTREEMETA:
- btmeta = (BTMETA *)h;
- if (F_ISSET(&btmeta->dbmeta, BTM_RECNO)) {
- /* Recnos have no order to check. */
- ret = 0;
- goto err;
- }
- if ((ret =
- __db_meta2pgset(dbp, vdp, meta_pgno, flags, pgset)) != 0)
- goto err;
- if ((ret = __db_cursor_int(pgset, NULL, dbp->type,
- PGNO_INVALID, 0, DB_LOCK_INVALIDID, &pgsc)) != 0)
- goto err;
- while ((ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) {
- if ((ret = __memp_fget(mpf, &p, 0, &currpg)) != 0)
- goto err;
- if ((ret = __bam_vrfy_itemorder(dbp,
- NULL, currpg, p, NUM_ENT(currpg), 1,
- F_ISSET(&btmeta->dbmeta, BTM_DUP), flags)) != 0)
- goto err;
- if ((ret = __memp_fput(mpf, currpg, 0)) != 0)
- goto err;
- currpg = NULL;
- }
-
- /*
- * The normal exit condition for the loop above is DB_NOTFOUND.
- * If we see that, zero it and continue on to cleanup.
- * Otherwise, it's a real error and will be returned.
- */
- if (ret == DB_NOTFOUND)
- ret = 0;
- break;
- case P_HASHMETA:
- hmeta = (HMETA *)h;
- h_internal = (HASH *)dbp->h_internal;
- /*
- * Make sure h_charkey is right.
- */
- if (h_internal == NULL) {
- EPRINT((dbenv,
- "Page %lu: DB->h_internal field is NULL",
- (u_long)meta_pgno));
- ret = DB_VERIFY_BAD;
- goto err;
- }
- if (h_internal->h_hash == NULL)
- h_internal->h_hash = hmeta->dbmeta.version < 5
- ? __ham_func4 : __ham_func5;
- if (hmeta->h_charkey !=
- h_internal->h_hash(dbp, CHARKEY, sizeof(CHARKEY))) {
- EPRINT((dbenv,
- "Page %lu: incorrect hash function for database",
- (u_long)meta_pgno));
- ret = DB_VERIFY_BAD;
- goto err;
- }
-
- /*
- * Foreach bucket, verify hashing on each page in the
- * corresponding chain of pages.
- */
- for (bucket = 0; bucket <= hmeta->max_bucket; bucket++) {
- pgno = BS_TO_PAGE(bucket, hmeta->spares);
- while (pgno != PGNO_INVALID) {
- if ((ret = __memp_fget(mpf,
- &pgno, 0, &currpg)) != 0)
- goto err;
- if ((ret = __ham_vrfy_hashing(dbp,
- NUM_ENT(currpg), hmeta, bucket, pgno,
- flags, h_internal->h_hash)) != 0)
- goto err;
- pgno = NEXT_PGNO(currpg);
- if ((ret = __memp_fput(mpf, currpg, 0)) != 0)
- goto err;
- currpg = NULL;
- }
- }
- break;
- default:
- EPRINT((dbenv, "Page %lu: database metapage of bad type %lu",
- (u_long)meta_pgno, (u_long)TYPE(h)));
- ret = DB_VERIFY_BAD;
- break;
- }
-
-err: if (pgsc != NULL && (t_ret = __db_c_close(pgsc)) != 0 && ret == 0)
- ret = t_ret;
- if (pgset != NULL &&
- (t_ret = __db_close(pgset, NULL, 0)) != 0 && ret == 0)
- ret = t_ret;
- if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0)
- ret = t_ret;
- if (currpg != NULL && (t_ret = __memp_fput(mpf, currpg, 0)) != 0)
- ret = t_ret;
- if ((t_ret = __db_close(mdbp, NULL, 0)) != 0)
- ret = t_ret;
- return (ret);
-}
-
-/*
- * __db_salvage --
- * Walk through a page, salvaging all likely or plausible (w/
- * DB_AGGRESSIVE) key/data pairs.
- *
- * PUBLIC: int __db_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t,
- * PUBLIC: PAGE *, void *, int (*)(void *, const void *), u_int32_t));
- */
-int
-__db_salvage(dbp, vdp, pgno, h, handle, callback, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- db_pgno_t pgno;
- PAGE *h;
- void *handle;
- int (*callback) __P((void *, const void *));
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- VRFY_PAGEINFO *pip;
- int keyflag, ret, t_ret;
-
- DB_ASSERT(LF_ISSET(DB_SALVAGE));
-
- dbenv = dbp->dbenv;
-
- /*
- * !!!
- * We dump record numbers when salvaging Queue databases, but not for
- * immutable Recno databases. The problem is we can't figure out the
- * record number from the database page in the Recno case, while the
- * offset in the file is sufficient for Queue.
- */
- keyflag = 0;
-
- /* If we got this page in the subdb pass, we can safely skip it. */
- if (__db_salvage_isdone(vdp, pgno))
- return (0);
-
- switch (TYPE(h)) {
- case P_HASHMETA:
- ret = __ham_vrfy_meta(dbp, vdp, (HMETA *)h, pgno, flags);
- break;
- case P_BTREEMETA:
- ret = __bam_vrfy_meta(dbp, vdp, (BTMETA *)h, pgno, flags);
- break;
- case P_QAMMETA:
- keyflag = 1;
- ret = __qam_vrfy_meta(dbp, vdp, (QMETA *)h, pgno, flags);
- break;
- case P_HASH:
- return (__ham_salvage(
- dbp, vdp, pgno, h, handle, callback, flags));
- case P_LBTREE:
- return (__bam_salvage(dbp,
- vdp, pgno, P_LBTREE, h, handle, callback, NULL, flags));
- case P_LDUP:
- return (__db_salvage_markneeded(vdp, pgno, SALVAGE_LDUP));
- case P_OVERFLOW:
- return (__db_salvage_markneeded(vdp, pgno, SALVAGE_OVERFLOW));
- case P_LRECNO:
- /*
- * Recnos are tricky -- they may represent dup pages, or
- * they may be subdatabase/regular database pages in their
- * own right. If the former, they need to be printed with a
- * key, preferably when we hit the corresponding datum in
- * a btree/hash page. If the latter, there is no key.
- *
- * If a database is sufficiently frotzed, we're not going
- * to be able to get this right, so we best-guess: just
- * mark it needed now, and if we're really a normal recno
- * database page, the "unknowns" pass will pick us up.
- */
- return (__db_salvage_markneeded(vdp, pgno, SALVAGE_LRECNO));
- case P_QAMDATA:
- return (__qam_salvage(dbp,
- vdp, pgno, h, handle, callback, flags));
- case P_IBTREE:
- case P_INVALID:
- case P_IRECNO:
- case __P_DUPLICATE:
- default:
- /* XXX: Should we be more aggressive here? */
- return (0);
- }
- if (ret != 0)
- return (ret);
-
- /*
- * We have to display the dump header if it's a metadata page. It's
- * our last chance as the page was marked "seen" in the vrfy routine,
- * and we won't see the page again. We don't display headers for
- * the first database in a multi-database file, that database simply
- * contains a list of subdatabases.
- */
- if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
- return (ret);
- if (!F_ISSET(pip, VRFY_HAS_SUBDBS))
- ret = __db_prheader(
- dbp, NULL, 0, keyflag, handle, callback, vdp, pgno);
- if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
-
-/*
- * __db_salvage_unknowns --
- * Walk through the salvager database, printing with key "UNKNOWN"
- * any pages we haven't dealt with.
- */
-static int
-__db_salvage_unknowns(dbp, vdp, handle, callback, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- void *handle;
- int (*callback) __P((void *, const void *));
- u_int32_t flags;
-{
- DBC *dbc;
- DBT unkdbt, key, *dbt;
- DB_ENV *dbenv;
- DB_MPOOLFILE *mpf;
- PAGE *h;
- db_pgno_t pgno;
- u_int32_t pgtype;
- int ret, t_ret;
- void *ovflbuf;
-
- dbc = NULL;
- dbenv = dbp->dbenv;
- mpf = dbp->mpf;
-
- memset(&unkdbt, 0, sizeof(DBT));
- unkdbt.size = (u_int32_t)strlen("UNKNOWN") + 1;
- unkdbt.data = "UNKNOWN";
-
- if ((ret = __os_malloc(dbenv, dbp->pgsize, &ovflbuf)) != 0)
- return (ret);
-
- /*
- * We make two passes -- in the first pass, skip SALVAGE_OVERFLOW
- * pages, because they may be referenced by the standard database
- * pages that we're resolving.
- */
- while ((t_ret =
- __db_salvage_getnext(vdp, &dbc, &pgno, &pgtype, 1)) == 0) {
- if ((t_ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) {
- if (ret == 0)
- ret = t_ret;
- continue;
- }
-
- dbt = NULL;
- switch (pgtype) {
- case SALVAGE_LDUP:
- case SALVAGE_LRECNODUP:
- dbt = &unkdbt;
- /* FALLTHROUGH */
- case SALVAGE_LBTREE:
- case SALVAGE_LRECNO:
- if ((t_ret = __bam_salvage(dbp, vdp, pgno, pgtype,
- h, handle, callback, dbt, flags)) != 0 && ret == 0)
- ret = t_ret;
- break;
- case SALVAGE_OVERFLOW:
- DB_ASSERT(0); /* Shouldn't ever happen. */
- break;
- case SALVAGE_HASH:
- if ((t_ret = __ham_salvage(dbp, vdp,
- pgno, h, handle, callback, flags)) != 0 && ret == 0)
- ret = t_ret;
- break;
- case SALVAGE_INVALID:
- case SALVAGE_IGNORE:
- default:
- /*
- * Shouldn't happen, but if it does, just do what the
- * nice man says.
- */
- DB_ASSERT(0);
- break;
- }
- if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
- ret = t_ret;
- }
-
- /* We should have reached the end of the database. */
- if (t_ret == DB_NOTFOUND)
- t_ret = 0;
- if (t_ret != 0 && ret == 0)
- ret = t_ret;
-
- /* Re-open the cursor so we traverse the database again. */
- if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
- dbc = NULL;
-
- /* Now, deal with any remaining overflow pages. */
- while ((t_ret =
- __db_salvage_getnext(vdp, &dbc, &pgno, &pgtype, 0)) == 0) {
- if ((t_ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) {
- if (ret == 0)
- ret = t_ret;
- continue;
- }
-
- switch (pgtype) {
- case SALVAGE_OVERFLOW:
- /*
- * XXX:
- * This may generate multiple "UNKNOWN" keys in
- * a database with no dups. What to do?
- */
- if ((t_ret = __db_safe_goff(dbp,
- vdp, pgno, &key, &ovflbuf, flags)) != 0 ||
- ((vdp->type == DB_BTREE || vdp->type == DB_HASH) &&
- (t_ret = __db_vrfy_prdbt(&unkdbt,
- 0, " ", handle, callback, 0, vdp)) != 0) ||
- (t_ret = __db_vrfy_prdbt(
- &key, 0, " ", handle, callback, 0, vdp)) != 0)
- if (ret == 0)
- ret = t_ret;
- break;
- default:
- DB_ASSERT(0); /* Shouldn't ever happen. */
- break;
- }
- if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
- ret = t_ret;
- }
-
- /* We should have reached the end of the database. */
- if (t_ret == DB_NOTFOUND)
- t_ret = 0;
- if (t_ret != 0 && ret == 0)
- ret = t_ret;
-
- if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
- ret = t_ret;
-
- __os_free(dbenv, ovflbuf);
-
- return (ret);
-}
-
-/*
- * Offset of the ith inp array entry, which we can compare to the offset
- * the entry stores.
- */
-#define INP_OFFSET(dbp, h, i) \
- ((db_indx_t)((u_int8_t *)((P_INP(dbp,(h))) + (i)) - (u_int8_t *)(h)))
-
-/*
- * __db_vrfy_inpitem --
- * Verify that a single entry in the inp array is sane, and update
- * the high water mark and current item offset. (The former of these is
- * used for state information between calls, and is required; it must
- * be initialized to the pagesize before the first call.)
- *
- * Returns DB_VERIFY_FATAL if inp has collided with the data,
- * since verification can't continue from there; returns DB_VERIFY_BAD
- * if anything else is wrong.
- *
- * PUBLIC: int __db_vrfy_inpitem __P((DB *, PAGE *,
- * PUBLIC: db_pgno_t, u_int32_t, int, u_int32_t, u_int32_t *, u_int32_t *));
- */
-int
-__db_vrfy_inpitem(dbp, h, pgno, i, is_btree, flags, himarkp, offsetp)
- DB *dbp;
- PAGE *h;
- db_pgno_t pgno;
- u_int32_t i;
- int is_btree;
- u_int32_t flags, *himarkp, *offsetp;
-{
- BKEYDATA *bk;
- DB_ENV *dbenv;
- db_indx_t *inp, offset, len;
-
- dbenv = dbp->dbenv;
-
- DB_ASSERT(himarkp != NULL);
- inp = P_INP(dbp, h);
-
- /*
- * Check that the inp array, which grows from the beginning of the
- * page forward, has not collided with the data, which grow from the
- * end of the page backward.
- */
- if (inp + i >= (db_indx_t *)((u_int8_t *)h + *himarkp)) {
- /* We've collided with the data. We need to bail. */
- EPRINT((dbenv, "Page %lu: entries listing %lu overlaps data",
- (u_long)pgno, (u_long)i));
- return (DB_VERIFY_FATAL);
- }
-
- offset = inp[i];
-
- /*
- * Check that the item offset is reasonable: it points somewhere
- * after the inp array and before the end of the page.
- */
- if (offset <= INP_OFFSET(dbp, h, i) || offset > dbp->pgsize) {
- EPRINT((dbenv, "Page %lu: bad offset %lu at page index %lu",
- (u_long)pgno, (u_long)offset, (u_long)i));
- return (DB_VERIFY_BAD);
- }
-
- /* Update the high-water mark (what HOFFSET should be) */
- if (offset < *himarkp)
- *himarkp = offset;
-
- if (is_btree) {
- /*
- * Check alignment; if it's unaligned, it's unsafe to
- * manipulate this item.
- */
- if (offset != DB_ALIGN(offset, sizeof(u_int32_t))) {
- EPRINT((dbenv,
- "Page %lu: unaligned offset %lu at page index %lu",
- (u_long)pgno, (u_long)offset, (u_long)i));
- return (DB_VERIFY_BAD);
- }
-
- /*
- * Check that the item length remains on-page.
- */
- bk = GET_BKEYDATA(dbp, h, i);
-
- /*
- * We need to verify the type of the item here;
- * we can't simply assume that it will be one of the
- * expected three. If it's not a recognizable type,
- * it can't be considered to have a verifiable
- * length, so it's not possible to certify it as safe.
- */
- switch (B_TYPE(bk->type)) {
- case B_KEYDATA:
- len = bk->len;
- break;
- case B_DUPLICATE:
- case B_OVERFLOW:
- len = BOVERFLOW_SIZE;
- break;
- default:
- EPRINT((dbenv,
- "Page %lu: item %lu of unrecognizable type",
- (u_long)pgno, (u_long)i));
- return (DB_VERIFY_BAD);
- }
-
- if ((size_t)(offset + len) > dbp->pgsize) {
- EPRINT((dbenv,
- "Page %lu: item %lu extends past page boundary",
- (u_long)pgno, (u_long)i));
- return (DB_VERIFY_BAD);
- }
- }
-
- if (offsetp != NULL)
- *offsetp = offset;
- return (0);
-}
-
-/*
- * __db_vrfy_duptype--
- * Given a page number and a set of flags to __bam_vrfy_subtree,
- * verify that the dup tree type is correct--i.e., it's a recno
- * if DUPSORT is not set and a btree if it is.
- *
- * PUBLIC: int __db_vrfy_duptype
- * PUBLIC: __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t));
- */
-int
-__db_vrfy_duptype(dbp, vdp, pgno, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- db_pgno_t pgno;
- u_int32_t flags;
-{
- DB_ENV *dbenv;
- VRFY_PAGEINFO *pip;
- int ret, isbad;
-
- dbenv = dbp->dbenv;
- isbad = 0;
-
- if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
- return (ret);
-
- switch (pip->type) {
- case P_IBTREE:
- case P_LDUP:
- if (!LF_ISSET(ST_DUPSORT)) {
- EPRINT((dbenv,
- "Page %lu: sorted duplicate set in unsorted-dup database",
- (u_long)pgno));
- isbad = 1;
- }
- break;
- case P_IRECNO:
- case P_LRECNO:
- if (LF_ISSET(ST_DUPSORT)) {
- EPRINT((dbenv,
- "Page %lu: unsorted duplicate set in sorted-dup database",
- (u_long)pgno));
- isbad = 1;
- }
- break;
- default:
- /*
- * If the page is entirely zeroed, its pip->type will be a lie
- * (we assumed it was a hash page, as they're allowed to be
- * zeroed); handle this case specially.
- */
- if (F_ISSET(pip, VRFY_IS_ALLZEROES))
- ZEROPG_ERR_PRINT(dbenv, pgno, "duplicate page");
- else
- EPRINT((dbenv,
- "Page %lu: duplicate page of inappropriate type %lu",
- (u_long)pgno, (u_long)pip->type));
- isbad = 1;
- break;
- }
-
- if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0)
- return (ret);
- return (isbad == 1 ? DB_VERIFY_BAD : 0);
-}
-
-/*
- * __db_salvage_duptree --
- * Attempt to salvage a given duplicate tree, given its alleged root.
- *
- * The key that corresponds to this dup set has been passed to us
- * in DBT *key. Because data items follow keys, though, it has been
- * printed once already.
- *
- * The basic idea here is that pgno ought to be a P_LDUP, a P_LRECNO, a
- * P_IBTREE, or a P_IRECNO. If it's an internal page, use the verifier
- * functions to make sure it's safe; if it's not, we simply bail and the
- * data will have to be printed with no key later on. if it is safe,
- * recurse on each of its children.
- *
- * Whether or not it's safe, if it's a leaf page, __bam_salvage it.
- *
- * At all times, use the DB hanging off vdp to mark and check what we've
- * done, so each page gets printed exactly once and we don't get caught
- * in any cycles.
- *
- * PUBLIC: int __db_salvage_duptree __P((DB *, VRFY_DBINFO *, db_pgno_t,
- * PUBLIC: DBT *, void *, int (*)(void *, const void *), u_int32_t));
- */
-int
-__db_salvage_duptree(dbp, vdp, pgno, key, handle, callback, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- db_pgno_t pgno;
- DBT *key;
- void *handle;
- int (*callback) __P((void *, const void *));
- u_int32_t flags;
-{
- DB_MPOOLFILE *mpf;
- PAGE *h;
- int ret, t_ret;
-
- mpf = dbp->mpf;
-
- if (pgno == PGNO_INVALID || !IS_VALID_PGNO(pgno))
- return (DB_VERIFY_BAD);
-
- /* We have a plausible page. Try it. */
- if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0)
- return (ret);
-
- switch (TYPE(h)) {
- case P_IBTREE:
- case P_IRECNO:
- if ((ret = __db_vrfy_common(dbp, vdp, h, pgno, flags)) != 0)
- goto err;
- if ((ret = __bam_vrfy(dbp,
- vdp, h, pgno, flags | DB_NOORDERCHK)) != 0 ||
- (ret = __db_salvage_markdone(vdp, pgno)) != 0)
- goto err;
- /*
- * We have a known-healthy internal page. Walk it.
- */
- if ((ret = __bam_salvage_walkdupint(dbp, vdp, h, key,
- handle, callback, flags)) != 0)
- goto err;
- break;
- case P_LRECNO:
- case P_LDUP:
- if ((ret = __bam_salvage(dbp,
- vdp, pgno, TYPE(h), h, handle, callback, key, flags)) != 0)
- goto err;
- break;
- default:
- ret = DB_VERIFY_BAD;
- goto err;
- }
-
-err: if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
-
-/*
- * __db_salvage_subdbs --
- * Check and see if this database has subdbs; if so, try to salvage
- * them independently.
- */
-static int
-__db_salvage_subdbs(dbp, vdp, handle, callback, flags, hassubsp)
- DB *dbp;
- VRFY_DBINFO *vdp;
- void *handle;
- int (*callback) __P((void *, const void *));
- u_int32_t flags;
- int *hassubsp;
-{
- DB *pgset;
- DBC *pgsc;
- DB_ENV *dbenv;
- DB_MPOOLFILE *mpf;
- PAGE *h;
- VRFY_PAGEINFO *pip;
- db_pgno_t p, meta_pgno;
- int ret, t_ret;
-
- *hassubsp = 0;
-
- dbenv = dbp->dbenv;
- pgset = NULL;
- pgsc = NULL;
- mpf = dbp->mpf;
- h = NULL;
- pip = NULL;
- ret = 0;
-
- /*
- * Check to make sure the page is OK and find out if it contains
- * subdatabases.
- */
- meta_pgno = PGNO_BASE_MD;
- if ((t_ret = __memp_fget(mpf, &meta_pgno, 0, &h)) == 0 &&
- (t_ret = __db_vrfy_common(dbp, vdp, h, PGNO_BASE_MD, flags)) == 0 &&
- (t_ret = __db_salvage(
- dbp, vdp, PGNO_BASE_MD, h, handle, callback, flags)) == 0 &&
- (t_ret = __db_vrfy_getpageinfo(vdp, 0, &pip)) == 0)
- if (F_ISSET(pip, VRFY_HAS_SUBDBS))
- *hassubsp = 1;
- if (pip != NULL &&
- (t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0)
- ret = t_ret;
- if (h != NULL) {
- if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
- ret = t_ret;
- h = NULL;
- }
- if (ret != 0 || *hassubsp == 0)
- return (ret);
-
- /*
- * We have subdbs. Try to crack them.
- *
- * To do so, get a set of leaf pages in the master database, and then
- * walk each of the valid ones, salvaging subdbs as we go. If any
- * prove invalid, just drop them; we'll pick them up on a later pass.
- */
- if ((ret = __db_vrfy_pgset(dbenv, dbp->pgsize, &pgset)) != 0)
- goto err;
- if ((ret = __db_meta2pgset(dbp, vdp, PGNO_BASE_MD, flags, pgset)) != 0)
- goto err;
- if ((ret = __db_cursor(pgset, NULL, &pgsc, 0)) != 0)
- goto err;
- while ((t_ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) {
- if ((t_ret = __memp_fget(mpf, &p, 0, &h)) == 0 &&
- (t_ret = __db_vrfy_common(dbp, vdp, h, p, flags)) == 0 &&
- (t_ret =
- __bam_vrfy(dbp, vdp, h, p, flags | DB_NOORDERCHK)) == 0)
- t_ret = __db_salvage_subdbpg(
- dbp, vdp, h, handle, callback, flags);
- if (t_ret != 0 && ret == 0)
- ret = t_ret;
- if (h != NULL) {
- if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
- ret = t_ret;
- h = NULL;
- }
- }
-
- if (t_ret != DB_NOTFOUND && ret == 0)
- ret = t_ret;
-
-err: if (pgsc != NULL && (t_ret = __db_c_close(pgsc)) != 0 && ret == 0)
- ret = t_ret;
- if (pgset != NULL &&
- (t_ret = __db_close(pgset, NULL, 0)) != 0 && ret ==0)
- ret = t_ret;
- if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0)
- ret = t_ret;
- return (ret);
-}
-
-/*
- * __db_salvage_subdbpg --
- * Given a known-good leaf page in the master database, salvage all
- * leaf pages corresponding to each subdb.
- */
-static int
-__db_salvage_subdbpg(dbp, vdp, master, handle, callback, flags)
- DB *dbp;
- VRFY_DBINFO *vdp;
- PAGE *master;
- void *handle;
- int (*callback) __P((void *, const void *));
- u_int32_t flags;
-{
- BKEYDATA *bkkey, *bkdata;
- BOVERFLOW *bo;
- DB *pgset;
- DBC *pgsc;
- DBT key;
- DB_ENV *dbenv;
- DB_MPOOLFILE *mpf;
- PAGE *subpg;
- db_indx_t i;
- db_pgno_t meta_pgno, p;
- int ret, err_ret, t_ret;
- char *subdbname;
-
- dbenv = dbp->dbenv;
- mpf = dbp->mpf;
- ret = err_ret = 0;
- subdbname = NULL;
-
- if ((ret = __db_vrfy_pgset(dbenv, dbp->pgsize, &pgset)) != 0)
- return (ret);
-
- /*
- * For each entry, get and salvage the set of pages
- * corresponding to that entry.
- */
- for (i = 0; i < NUM_ENT(master); i += P_INDX) {
- bkkey = GET_BKEYDATA(dbp, master, i);
- bkdata = GET_BKEYDATA(dbp, master, i + O_INDX);
-
- /* Get the subdatabase name. */
- if (B_TYPE(bkkey->type) == B_OVERFLOW) {
- /*
- * We can, in principle anyway, have a subdb
- * name so long it overflows. Ick.
- */
- bo = (BOVERFLOW *)bkkey;
- if ((ret = __db_safe_goff(dbp, vdp,
- bo->pgno, &key, &subdbname, flags)) != 0) {
- err_ret = DB_VERIFY_BAD;
- continue;
- }
-
- /* Nul-terminate it. */
- if ((ret = __os_realloc(dbenv,
- key.size + 1, &subdbname)) != 0)
- goto err;
- subdbname[key.size] = '\0';
- } else if (B_TYPE(bkkey->type) == B_KEYDATA) {
- if ((ret = __os_realloc(dbenv,
- bkkey->len + 1, &subdbname)) != 0)
- goto err;
- memcpy(subdbname, bkkey->data, bkkey->len);
- subdbname[bkkey->len] = '\0';
- }
-
- /* Get the corresponding pgno. */
- if (bkdata->len != sizeof(db_pgno_t)) {
- err_ret = DB_VERIFY_BAD;
- continue;
- }
- memcpy(&meta_pgno,
- (db_pgno_t *)bkdata->data, sizeof(db_pgno_t));
-
- /*
- * Subdatabase meta pgnos are stored in network byte
- * order for cross-endian compatibility. Swap if appropriate.
- */
- DB_NTOHL(&meta_pgno);
-
- /* If we can't get the subdb meta page, just skip the subdb. */
- if (!IS_VALID_PGNO(meta_pgno) ||
- (ret = __memp_fget(mpf, &meta_pgno, 0, &subpg)) != 0) {
- err_ret = ret;
- continue;
- }
-
- /*
- * Verify the subdatabase meta page. This has two functions.
- * First, if it's bad, we have no choice but to skip the subdb
- * and let the pages just get printed on a later pass. Second,
- * the access-method-specific meta verification routines record
- * the various state info (such as the presence of dups)
- * that we need for __db_prheader().
- */
- if ((ret =
- __db_vrfy_common(dbp, vdp, subpg, meta_pgno, flags)) != 0) {
- err_ret = ret;
- (void)__memp_fput(mpf, subpg, 0);
- continue;
- }
- switch (TYPE(subpg)) {
- case P_BTREEMETA:
- if ((ret = __bam_vrfy_meta(dbp,
- vdp, (BTMETA *)subpg, meta_pgno, flags)) != 0) {
- err_ret = ret;
- (void)__memp_fput(mpf, subpg, 0);
- continue;
- }
- break;
- case P_HASHMETA:
- if ((ret = __ham_vrfy_meta(dbp,
- vdp, (HMETA *)subpg, meta_pgno, flags)) != 0) {
- err_ret = ret;
- (void)__memp_fput(mpf, subpg, 0);
- continue;
- }
- break;
- default:
- /* This isn't an appropriate page; skip this subdb. */
- err_ret = DB_VERIFY_BAD;
- continue;
- }
-
- if ((ret = __memp_fput(mpf, subpg, 0)) != 0) {
- err_ret = ret;
- continue;
- }
-
- /* Print a subdatabase header. */
- if ((ret = __db_prheader(dbp,
- subdbname, 0, 0, handle, callback, vdp, meta_pgno)) != 0)
- goto err;
-
- if ((ret = __db_meta2pgset(dbp, vdp, meta_pgno,
- flags, pgset)) != 0) {
- err_ret = ret;
- continue;
- }
-
- if ((ret = __db_cursor(pgset, NULL, &pgsc, 0)) != 0)
- goto err;
- while ((ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) {
- if ((ret = __memp_fget(mpf, &p, 0, &subpg)) != 0) {
- err_ret = ret;
- continue;
- }
- if ((ret = __db_salvage(dbp, vdp, p, subpg,
- handle, callback, flags)) != 0)
- err_ret = ret;
- if ((ret = __memp_fput(mpf, subpg, 0)) != 0)
- err_ret = ret;
- }
-
- if (ret != DB_NOTFOUND)
- goto err;
-
- if ((ret = __db_c_close(pgsc)) != 0)
- goto err;
- if ((ret = __db_prfooter(handle, callback)) != 0)
- goto err;
- }
-err: if (subdbname)
- __os_free(dbenv, subdbname);
-
- if ((t_ret = __db_close(pgset, NULL, 0)) != 0)
- ret = t_ret;
-
- if ((t_ret = __db_salvage_markdone(vdp, PGNO(master))) != 0)
- return (t_ret);
-
- return ((err_ret != 0) ? err_ret : ret);
-}
-
-/*
- * __db_meta2pgset --
- * Given a known-safe meta page number, return the set of pages
- * corresponding to the database it represents. Return DB_VERIFY_BAD if
- * it's not a suitable meta page or is invalid.
- */
-static int
-__db_meta2pgset(dbp, vdp, pgno, flags, pgset)
- DB *dbp;
- VRFY_DBINFO *vdp;
- db_pgno_t pgno;
- u_int32_t flags;
- DB *pgset;
-{
- DB_MPOOLFILE *mpf;
- PAGE *h;
- int ret, t_ret;
-
- mpf = dbp->mpf;
-
- if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0)
- return (ret);
-
- switch (TYPE(h)) {
- case P_BTREEMETA:
- ret = __bam_meta2pgset(dbp, vdp, (BTMETA *)h, flags, pgset);
- break;
- case P_HASHMETA:
- ret = __ham_meta2pgset(dbp, vdp, (HMETA *)h, flags, pgset);
- break;
- default:
- ret = DB_VERIFY_BAD;
- break;
- }
-
- if ((t_ret = __memp_fput(mpf, h, 0)) != 0)
- return (t_ret);
- return (ret);
-}
-
-/*
- * __db_guesspgsize --
- * Try to guess what the pagesize is if the one on the meta page
- * and the one in the db are invalid.
- */
-static u_int
-__db_guesspgsize(dbenv, fhp)
- DB_ENV *dbenv;
- DB_FH *fhp;
-{
- db_pgno_t i;
- size_t nr;
- u_int32_t guess;
- u_int8_t type;
-
- for (guess = DB_MAX_PGSIZE; guess >= DB_MIN_PGSIZE; guess >>= 1) {
- /*
- * We try to read three pages ahead after the first one
- * and make sure we have plausible types for all of them.
- * If the seeks fail, continue with a smaller size;
- * we're probably just looking past the end of the database.
- * If they succeed and the types are reasonable, also continue
- * with a size smaller; we may be looking at pages N,
- * 2N, and 3N for some N > 1.
- *
- * As soon as we hit an invalid type, we stop and return
- * our previous guess; that last one was probably the page size.
- */
- for (i = 1; i <= 3; i++) {
- if (__os_seek(dbenv, fhp, guess,
- i, SSZ(DBMETA, type), 0, DB_OS_SEEK_SET) != 0)
- break;
- if (__os_read(dbenv,
- fhp, &type, 1, &nr) != 0 || nr == 0)
- break;
- if (type == P_INVALID || type >= P_PAGETYPE_MAX)
- return (guess << 1);
- }
- }
-
- /*
- * If we're just totally confused--the corruption takes up most of the
- * beginning pages of the database--go with the default size.
- */
- return (DB_DEF_IOSIZE);
-}
diff --git a/storage/bdb/db/db_vrfy_stub.c b/storage/bdb/db/db_vrfy_stub.c
deleted file mode 100644
index 46f0b1134e1..00000000000
--- a/storage/bdb/db/db_vrfy_stub.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_vrfy_stub.c,v 12.1 2005/06/16 20:21:15 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef HAVE_VERIFY
-#ifndef NO_SYSTEM_INCLUDES
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_am.h"
-#include "dbinc/db_verify.h"
-
-/*
- * If the library wasn't compiled with the verification support, various
- * routines aren't available. Stub them here, returning an appropriate
- * error.
- */
-
-static int __db_novrfy __P((DB_ENV *));
-
-/*
- * __db_novrfy --
- * Error when a Berkeley DB build doesn't include the access method.
- */
-static int
-__db_novrfy(dbenv)
- DB_ENV *dbenv;
-{
- __db_err(dbenv,
- "library build did not include support for database verification");
- return (DB_OPNOTSUP);
-}
-
-int
-__db_verify_pp(dbp, file, database, outfile, flags)
- DB *dbp;
- const char *file, *database;
- FILE *outfile;
- u_int32_t flags;
-{
- int ret;
-
- COMPQUIET(file, NULL);
- COMPQUIET(database, NULL);
- COMPQUIET(outfile, NULL);
- COMPQUIET(flags, 0);
-
- ret = __db_novrfy(dbp->dbenv);
-
- /* The verify method is a destructor. */
- (void)__db_close(dbp, NULL, 0);
-
- return (ret);
-}
-
-int
-__db_verify_internal(dbp, name, subdb, handle, callback, flags)
- DB *dbp;
- const char *name, *subdb;
- void *handle;
- int (*callback) __P((void *, const void *));
- u_int32_t flags;
-{
- COMPQUIET(dbp, NULL);
- COMPQUIET(name, NULL);
- COMPQUIET(subdb, NULL);
- COMPQUIET(handle, NULL);
- COMPQUIET(callback, NULL);
- COMPQUIET(flags, 0);
- return (0);
-}
-
-int
-__db_vrfy_getpageinfo(vdp, pgno, pipp)
- VRFY_DBINFO *vdp;
- db_pgno_t pgno;
- VRFY_PAGEINFO **pipp;
-{
- COMPQUIET(pgno, 0);
- COMPQUIET(pipp, NULL);
- return (__db_novrfy(vdp->pgdbp->dbenv));
-}
-
-int
-__db_vrfy_putpageinfo(dbenv, vdp, pip)
- DB_ENV *dbenv;
- VRFY_DBINFO *vdp;
- VRFY_PAGEINFO *pip;
-{
- COMPQUIET(vdp, NULL);
- COMPQUIET(pip, NULL);
- return (__db_novrfy(dbenv));
-}
-#endif /* !HAVE_VERIFY */
diff --git a/storage/bdb/db/db_vrfyutil.c b/storage/bdb/db/db_vrfyutil.c
deleted file mode 100644
index f1508872238..00000000000
--- a/storage/bdb/db/db_vrfyutil.c
+++ /dev/null
@@ -1,898 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 2000-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_vrfyutil.c,v 12.5 2005/06/16 20:21:15 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#endif
-
-#include "db_int.h"
-#include "dbinc/db_page.h"
-#include "dbinc/db_verify.h"
-#include "dbinc/db_am.h"
-
-static int __db_vrfy_childinc __P((DBC *, VRFY_CHILDINFO *));
-static int __db_vrfy_pageinfo_create __P((DB_ENV *, VRFY_PAGEINFO **));
-
-/*
- * __db_vrfy_dbinfo_create --
- * Allocate and initialize a VRFY_DBINFO structure.
- *
- * PUBLIC: int __db_vrfy_dbinfo_create
- * PUBLIC: __P((DB_ENV *, u_int32_t, VRFY_DBINFO **));
- */
-int
-__db_vrfy_dbinfo_create(dbenv, pgsize, vdpp)
- DB_ENV *dbenv;
- u_int32_t pgsize;
- VRFY_DBINFO **vdpp;
-{
- DB *cdbp, *pgdbp, *pgset;
- VRFY_DBINFO *vdp;
- int ret;
-
- vdp = NULL;
- cdbp = pgdbp = pgset = NULL;
-
- if ((ret = __os_calloc(NULL, 1, sizeof(VRFY_DBINFO), &vdp)) != 0)
- goto err;
-
- if ((ret = db_create(&cdbp, dbenv, 0)) != 0)
- goto err;
-
- if ((ret = __db_set_flags(cdbp, DB_DUP)) != 0)
- goto err;
-
- if ((ret = __db_set_pagesize(cdbp, pgsize)) != 0)
- goto err;
-
- if ((ret = __db_open(cdbp,
- NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) != 0)
- goto err;
-
- if ((ret = db_create(&pgdbp, dbenv, 0)) != 0)
- goto err;
-
- if ((ret = __db_set_pagesize(pgdbp, pgsize)) != 0)
- goto err;
-
- if ((ret = __db_open(pgdbp,
- NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) != 0)
- goto err;
-
- if ((ret = __db_vrfy_pgset(dbenv, pgsize, &pgset)) != 0)
- goto err;
-
- LIST_INIT(&vdp->subdbs);
- LIST_INIT(&vdp->activepips);
-
- vdp->cdbp = cdbp;
- vdp->pgdbp = pgdbp;
- vdp->pgset = pgset;
- *vdpp = vdp;
- return (0);
-
-err: if (cdbp != NULL)
- (void)__db_close(cdbp, NULL, 0);
- if (pgdbp != NULL)
- (void)__db_close(pgdbp, NULL, 0);
- if (vdp != NULL)
- __os_free(dbenv, vdp);
- return (ret);
-}
-
-/*
- * __db_vrfy_dbinfo_destroy --
- * Destructor for VRFY_DBINFO. Destroys VRFY_PAGEINFOs and deallocates
- * structure.
- *
- * PUBLIC: int __db_vrfy_dbinfo_destroy __P((DB_ENV *, VRFY_DBINFO *));
- */
-int
-__db_vrfy_dbinfo_destroy(dbenv, vdp)
- DB_ENV *dbenv;
- VRFY_DBINFO *vdp;
-{
- VRFY_CHILDINFO *c;
- int t_ret, ret;
-
- ret = 0;
-
- /*
- * Discard active page structures. Ideally there wouldn't be any,
- * but in some error cases we may not have cleared them all out.
- */
- while (LIST_FIRST(&vdp->activepips) != NULL)
- if ((t_ret = __db_vrfy_putpageinfo(
- dbenv, vdp, LIST_FIRST(&vdp->activepips))) != 0) {
- if (ret == 0)
- ret = t_ret;
- break;
- }
-
- /* Discard subdatabase list structures. */
- while ((c = LIST_FIRST(&vdp->subdbs)) != NULL) {
- LIST_REMOVE(c, links);
- __os_free(NULL, c);
- }
-
- if ((t_ret = __db_close(vdp->pgdbp, NULL, 0)) != 0)
- ret = t_ret;
-
- if ((t_ret = __db_close(vdp->cdbp, NULL, 0)) != 0 && ret == 0)
- ret = t_ret;
-
- if ((t_ret = __db_close(vdp->pgset, NULL, 0)) != 0 && ret == 0)
- ret = t_ret;
-
- if (vdp->extents != NULL)
- __os_free(dbenv, vdp->extents);
- __os_free(dbenv, vdp);
- return (ret);
-}
-
-/*
- * __db_vrfy_getpageinfo --
- * Get a PAGEINFO structure for a given page, creating it if necessary.
- *
- * PUBLIC: int __db_vrfy_getpageinfo
- * PUBLIC: __P((VRFY_DBINFO *, db_pgno_t, VRFY_PAGEINFO **));
- */
-int
-__db_vrfy_getpageinfo(vdp, pgno, pipp)
- VRFY_DBINFO *vdp;
- db_pgno_t pgno;
- VRFY_PAGEINFO **pipp;
-{
- DBT key, data;
- DB *pgdbp;
- VRFY_PAGEINFO *pip;
- int ret;
-
- /*
- * We want a page info struct. There are three places to get it from,
- * in decreasing order of preference:
- *
- * 1. vdp->activepips. If it's already "checked out", we're
- * already using it, we return the same exact structure with a
- * bumped refcount. This is necessary because this code is
- * replacing array accesses, and it's common for f() to make some
- * changes to a pip, and then call g() and h() which each make
- * changes to the same pip. vdps are never shared between threads
- * (they're never returned to the application), so this is safe.
- * 2. The pgdbp. It's not in memory, but it's in the database, so
- * get it, give it a refcount of 1, and stick it on activepips.
- * 3. malloc. It doesn't exist yet; create it, then stick it on
- * activepips. We'll put it in the database when we putpageinfo
- * later.
- */
-
- /* Case 1. */
- for (pip = LIST_FIRST(&vdp->activepips); pip != NULL;
- pip = LIST_NEXT(pip, links))
- if (pip->pgno == pgno)
- /* Found it. */
- goto found;
-
- /* Case 2. */
- pgdbp = vdp->pgdbp;
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
- F_SET(&data, DB_DBT_MALLOC);
- key.data = &pgno;
- key.size = sizeof(db_pgno_t);
-
- if ((ret = __db_get(pgdbp, NULL, &key, &data, 0)) == 0) {
- /* Found it. */
- DB_ASSERT(data.size == sizeof(VRFY_PAGEINFO));
- pip = data.data;
- LIST_INSERT_HEAD(&vdp->activepips, pip, links);
- goto found;
- } else if (ret != DB_NOTFOUND) /* Something nasty happened. */
- return (ret);
-
- /* Case 3 */
- if ((ret = __db_vrfy_pageinfo_create(pgdbp->dbenv, &pip)) != 0)
- return (ret);
-
- LIST_INSERT_HEAD(&vdp->activepips, pip, links);
-found: pip->pi_refcount++;
-
- *pipp = pip;
- return (0);
-}
-
-/*
- * __db_vrfy_putpageinfo --
- * Put back a VRFY_PAGEINFO that we're done with.
- *
- * PUBLIC: int __db_vrfy_putpageinfo __P((DB_ENV *,
- * PUBLIC: VRFY_DBINFO *, VRFY_PAGEINFO *));
- */
-int
-__db_vrfy_putpageinfo(dbenv, vdp, pip)
- DB_ENV *dbenv;
- VRFY_DBINFO *vdp;
- VRFY_PAGEINFO *pip;
-{
- DBT key, data;
- DB *pgdbp;
- VRFY_PAGEINFO *p;
- int ret;
-
- if (--pip->pi_refcount > 0)
- return (0);
-
- pgdbp = vdp->pgdbp;
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
-
- key.data = &pip->pgno;
- key.size = sizeof(db_pgno_t);
- data.data = pip;
- data.size = sizeof(VRFY_PAGEINFO);
-
- if ((ret = __db_put(pgdbp, NULL, &key, &data, 0)) != 0)
- return (ret);
-
- for (p =
- LIST_FIRST(&vdp->activepips); p != NULL; p = LIST_NEXT(p, links))
- if (p == pip)
- break;
- if (p != NULL)
- LIST_REMOVE(p, links);
-
- __os_ufree(dbenv, p);
- return (0);
-}
-
-/*
- * __db_vrfy_pgset --
- * Create a temporary database for the storing of sets of page numbers.
- * (A mapping from page number to int, used by the *_meta2pgset functions,
- * as well as for keeping track of which pages the verifier has seen.)
- *
- * PUBLIC: int __db_vrfy_pgset __P((DB_ENV *, u_int32_t, DB **));
- */
-int
-__db_vrfy_pgset(dbenv, pgsize, dbpp)
- DB_ENV *dbenv;
- u_int32_t pgsize;
- DB **dbpp;
-{
- DB *dbp;
- int ret;
-
- if ((ret = db_create(&dbp, dbenv, 0)) != 0)
- return (ret);
- if ((ret = __db_set_pagesize(dbp, pgsize)) != 0)
- goto err;
- if ((ret = __db_open(dbp,
- NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) == 0)
- *dbpp = dbp;
- else
-err: (void)__db_close(dbp, NULL, 0);
-
- return (ret);
-}
-
-/*
- * __db_vrfy_pgset_get --
- * Get the value associated in a page set with a given pgno. Return
- * a 0 value (and succeed) if we've never heard of this page.
- *
- * PUBLIC: int __db_vrfy_pgset_get __P((DB *, db_pgno_t, int *));
- */
-int
-__db_vrfy_pgset_get(dbp, pgno, valp)
- DB *dbp;
- db_pgno_t pgno;
- int *valp;
-{
- DBT key, data;
- int ret, val;
-
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
-
- key.data = &pgno;
- key.size = sizeof(db_pgno_t);
- data.data = &val;
- data.ulen = sizeof(int);
- F_SET(&data, DB_DBT_USERMEM);
-
- if ((ret = __db_get(dbp, NULL, &key, &data, 0)) == 0) {
- DB_ASSERT(data.size == sizeof(int));
- } else if (ret == DB_NOTFOUND)
- val = 0;
- else
- return (ret);
-
- *valp = val;
- return (0);
-}
-
-/*
- * __db_vrfy_pgset_inc --
- * Increment the value associated with a pgno by 1.
- *
- * PUBLIC: int __db_vrfy_pgset_inc __P((DB *, db_pgno_t));
- */
-int
-__db_vrfy_pgset_inc(dbp, pgno)
- DB *dbp;
- db_pgno_t pgno;
-{
- DBT key, data;
- int ret;
- int val;
-
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
-
- val = 0;
-
- key.data = &pgno;
- key.size = sizeof(db_pgno_t);
- data.data = &val;
- data.ulen = sizeof(int);
- F_SET(&data, DB_DBT_USERMEM);
-
- if ((ret = __db_get(dbp, NULL, &key, &data, 0)) == 0) {
- DB_ASSERT(data.size == sizeof(int));
- } else if (ret != DB_NOTFOUND)
- return (ret);
-
- data.size = sizeof(int);
- ++val;
-
- return (__db_put(dbp, NULL, &key, &data, 0));
-}
-
-/*
- * __db_vrfy_pgset_next --
- * Given a cursor open in a pgset database, get the next page in the
- * set.
- *
- * PUBLIC: int __db_vrfy_pgset_next __P((DBC *, db_pgno_t *));
- */
-int
-__db_vrfy_pgset_next(dbc, pgnop)
- DBC *dbc;
- db_pgno_t *pgnop;
-{
- DBT key, data;
- db_pgno_t pgno;
- int ret;
-
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
- /* We don't care about the data, just the keys. */
- F_SET(&data, DB_DBT_USERMEM | DB_DBT_PARTIAL);
- F_SET(&key, DB_DBT_USERMEM);
- key.data = &pgno;
- key.ulen = sizeof(db_pgno_t);
-
- if ((ret = __db_c_get(dbc, &key, &data, DB_NEXT)) != 0)
- return (ret);
-
- DB_ASSERT(key.size == sizeof(db_pgno_t));
- *pgnop = pgno;
-
- return (0);
-}
-
-/*
- * __db_vrfy_childcursor --
- * Create a cursor to walk the child list with. Returns with a nonzero
- * final argument if the specified page has no children.
- *
- * PUBLIC: int __db_vrfy_childcursor __P((VRFY_DBINFO *, DBC **));
- */
-int
-__db_vrfy_childcursor(vdp, dbcp)
- VRFY_DBINFO *vdp;
- DBC **dbcp;
-{
- DB *cdbp;
- DBC *dbc;
- int ret;
-
- cdbp = vdp->cdbp;
-
- if ((ret = __db_cursor(cdbp, NULL, &dbc, 0)) == 0)
- *dbcp = dbc;
-
- return (ret);
-}
-
-/*
- * __db_vrfy_childput --
- * Add a child structure to the set for a given page.
- *
- * PUBLIC: int __db_vrfy_childput
- * PUBLIC: __P((VRFY_DBINFO *, db_pgno_t, VRFY_CHILDINFO *));
- */
-int
-__db_vrfy_childput(vdp, pgno, cip)
- VRFY_DBINFO *vdp;
- db_pgno_t pgno;
- VRFY_CHILDINFO *cip;
-{
- DB *cdbp;
- DBC *cc;
- DBT key, data;
- VRFY_CHILDINFO *oldcip;
- int ret;
-
- cdbp = vdp->cdbp;
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
-
- key.data = &pgno;
- key.size = sizeof(db_pgno_t);
-
- /*
- * We want to avoid adding multiple entries for a single child page;
- * we only need to verify each child once, even if a child (such
- * as an overflow key) is multiply referenced.
- *
- * However, we also need to make sure that when walking the list
- * of children, we encounter them in the order they're referenced
- * on a page. (This permits us, for example, to verify the
- * prev_pgno/next_pgno chain of Btree leaf pages.)
- *
- * Check the child database to make sure that this page isn't
- * already a child of the specified page number. If it's not,
- * put it at the end of the duplicate set.
- */
- if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0)
- return (ret);
- for (ret = __db_vrfy_ccset(cc, pgno, &oldcip); ret == 0;
- ret = __db_vrfy_ccnext(cc, &oldcip))
- if (oldcip->pgno == cip->pgno) {
- /*
- * Found a matching child. Increment its reference
- * count--we've run into it again--but don't put it
- * again.
- */
- if ((ret = __db_vrfy_childinc(cc, oldcip)) != 0 ||
- (ret = __db_vrfy_ccclose(cc)) != 0)
- return (ret);
- return (0);
- }
- if (ret != DB_NOTFOUND) {
- (void)__db_vrfy_ccclose(cc);
- return (ret);
- }
- if ((ret = __db_vrfy_ccclose(cc)) != 0)
- return (ret);
-
- cip->refcnt = 1;
- data.data = cip;
- data.size = sizeof(VRFY_CHILDINFO);
-
- return (__db_put(cdbp, NULL, &key, &data, 0));
-}
-
-/*
- * __db_vrfy_childinc --
- * Increment the refcount of the VRFY_CHILDINFO struct that the child
- * cursor is pointing to. (The caller has just retrieved this struct, and
- * passes it in as cip to save us a get.)
- */
-static int
-__db_vrfy_childinc(dbc, cip)
- DBC *dbc;
- VRFY_CHILDINFO *cip;
-{
- DBT key, data;
-
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
-
- cip->refcnt++;
- data.data = cip;
- data.size = sizeof(VRFY_CHILDINFO);
-
- return (__db_c_put(dbc, &key, &data, DB_CURRENT));
-}
-
-/*
- * __db_vrfy_ccset --
- * Sets a cursor created with __db_vrfy_childcursor to the first
- * child of the given pgno, and returns it in the third arg.
- *
- * PUBLIC: int __db_vrfy_ccset __P((DBC *, db_pgno_t, VRFY_CHILDINFO **));
- */
-int
-__db_vrfy_ccset(dbc, pgno, cipp)
- DBC *dbc;
- db_pgno_t pgno;
- VRFY_CHILDINFO **cipp;
-{
- DBT key, data;
- int ret;
-
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
-
- key.data = &pgno;
- key.size = sizeof(db_pgno_t);
-
- if ((ret = __db_c_get(dbc, &key, &data, DB_SET)) != 0)
- return (ret);
-
- DB_ASSERT(data.size == sizeof(VRFY_CHILDINFO));
- *cipp = (VRFY_CHILDINFO *)data.data;
-
- return (0);
-}
-
-/*
- * __db_vrfy_ccnext --
- * Gets the next child of the given cursor created with
- * __db_vrfy_childcursor, and returns it in the memory provided in the
- * second arg.
- *
- * PUBLIC: int __db_vrfy_ccnext __P((DBC *, VRFY_CHILDINFO **));
- */
-int
-__db_vrfy_ccnext(dbc, cipp)
- DBC *dbc;
- VRFY_CHILDINFO **cipp;
-{
- DBT key, data;
- int ret;
-
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
-
- if ((ret = __db_c_get(dbc, &key, &data, DB_NEXT_DUP)) != 0)
- return (ret);
-
- DB_ASSERT(data.size == sizeof(VRFY_CHILDINFO));
- *cipp = (VRFY_CHILDINFO *)data.data;
-
- return (0);
-}
-
-/*
- * __db_vrfy_ccclose --
- * Closes the cursor created with __db_vrfy_childcursor.
- *
- * This doesn't actually do anything interesting now, but it's
- * not inconceivable that we might change the internal database usage
- * and keep the interfaces the same, and a function call here or there
- * seldom hurts anyone.
- *
- * PUBLIC: int __db_vrfy_ccclose __P((DBC *));
- */
-int
-__db_vrfy_ccclose(dbc)
- DBC *dbc;
-{
-
- return (__db_c_close(dbc));
-}
-
-/*
- * __db_vrfy_pageinfo_create --
- * Constructor for VRFY_PAGEINFO; allocates and initializes.
- */
-static int
-__db_vrfy_pageinfo_create(dbenv, pipp)
- DB_ENV *dbenv;
- VRFY_PAGEINFO **pipp;
-{
- VRFY_PAGEINFO *pip;
- int ret;
-
- /*
- * pageinfo structs are sometimes allocated here and sometimes
- * allocated by fetching them from a database with DB_DBT_MALLOC.
- * There's no easy way for the destructor to tell which was
- * used, and so we always allocate with __os_umalloc so we can free
- * with __os_ufree.
- */
- if ((ret = __os_umalloc(dbenv, sizeof(VRFY_PAGEINFO), &pip)) != 0)
- return (ret);
- memset(pip, 0, sizeof(VRFY_PAGEINFO));
-
- *pipp = pip;
- return (0);
-}
-
-/*
- * __db_salvage_init --
- * Set up salvager database.
- *
- * PUBLIC: int __db_salvage_init __P((VRFY_DBINFO *));
- */
-int
-__db_salvage_init(vdp)
- VRFY_DBINFO *vdp;
-{
- DB *dbp;
- int ret;
-
- if ((ret = db_create(&dbp, NULL, 0)) != 0)
- return (ret);
-
- if ((ret = __db_set_pagesize(dbp, 1024)) != 0)
- goto err;
-
- if ((ret = __db_open(dbp,
- NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0, PGNO_BASE_MD)) != 0)
- goto err;
-
- vdp->salvage_pages = dbp;
- return (0);
-
-err: (void)__db_close(dbp, NULL, 0);
- return (ret);
-}
-
-/*
- * __db_salvage_destroy --
- * Close salvager database.
- * PUBLIC: void __db_salvage_destroy __P((VRFY_DBINFO *));
- */
-void
-__db_salvage_destroy(vdp)
- VRFY_DBINFO *vdp;
-{
- (void)__db_close(vdp->salvage_pages, NULL, 0);
-}
-
-/*
- * __db_salvage_getnext --
- * Get the next (first) unprinted page in the database of pages we need to
- * print still. Delete entries for any already-printed pages we encounter
- * in this search, as well as the page we're returning.
- *
- * PUBLIC: int __db_salvage_getnext
- * PUBLIC: __P((VRFY_DBINFO *, DBC **, db_pgno_t *, u_int32_t *, int));
- */
-int
-__db_salvage_getnext(vdp, dbcp, pgnop, pgtypep, skip_overflow)
- VRFY_DBINFO *vdp;
- DBC **dbcp;
- db_pgno_t *pgnop;
- u_int32_t *pgtypep;
- int skip_overflow;
-{
- DB *dbp;
- DBT key, data;
- int ret;
- u_int32_t pgtype;
-
- dbp = vdp->salvage_pages;
-
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
-
- if (*dbcp == NULL &&
- (ret = __db_cursor(dbp, NULL, dbcp, 0)) != 0)
- return (ret);
-
- while ((ret = __db_c_get(*dbcp, &key, &data, DB_NEXT)) == 0) {
- DB_ASSERT(data.size == sizeof(u_int32_t));
- memcpy(&pgtype, data.data, sizeof(pgtype));
-
- if (skip_overflow && pgtype == SALVAGE_OVERFLOW)
- continue;
-
- if ((ret = __db_c_del(*dbcp, 0)) != 0)
- return (ret);
- if (pgtype != SALVAGE_IGNORE) {
- DB_ASSERT(key.size == sizeof(db_pgno_t));
- DB_ASSERT(data.size == sizeof(u_int32_t));
-
- *pgnop = *(db_pgno_t *)key.data;
- *pgtypep = *(u_int32_t *)data.data;
- break;
- }
- }
-
- return (ret);
-}
-
-/*
- * __db_salvage_isdone --
- * Return whether or not the given pgno is already marked
- * SALVAGE_IGNORE (meaning that we don't need to print it again).
- *
- * Returns DB_KEYEXIST if it is marked, 0 if not, or another error on
- * error.
- *
- * PUBLIC: int __db_salvage_isdone __P((VRFY_DBINFO *, db_pgno_t));
- */
-int
-__db_salvage_isdone(vdp, pgno)
- VRFY_DBINFO *vdp;
- db_pgno_t pgno;
-{
- DBT key, data;
- DB *dbp;
- int ret;
- u_int32_t currtype;
-
- dbp = vdp->salvage_pages;
-
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
-
- currtype = SALVAGE_INVALID;
- data.data = &currtype;
- data.ulen = sizeof(u_int32_t);
- data.flags = DB_DBT_USERMEM;
-
- key.data = &pgno;
- key.size = sizeof(db_pgno_t);
-
- /*
- * Put an entry for this page, with pgno as key and type as data,
- * unless it's already there and is marked done.
- * If it's there and is marked anything else, that's fine--we
- * want to mark it done.
- */
- if ((ret = __db_get(dbp, NULL, &key, &data, 0)) == 0) {
- /*
- * The key's already here. Check and see if it's already
- * marked done. If it is, return DB_KEYEXIST. If it's not,
- * return 0.
- */
- if (currtype == SALVAGE_IGNORE)
- return (DB_KEYEXIST);
- else
- return (0);
- } else if (ret != DB_NOTFOUND)
- return (ret);
-
- /* The pgno is not yet marked anything; return 0. */
- return (0);
-}
-
-/*
- * __db_salvage_markdone --
- * Mark as done a given page.
- *
- * PUBLIC: int __db_salvage_markdone __P((VRFY_DBINFO *, db_pgno_t));
- */
-int
-__db_salvage_markdone(vdp, pgno)
- VRFY_DBINFO *vdp;
- db_pgno_t pgno;
-{
- DBT key, data;
- DB *dbp;
- int pgtype, ret;
- u_int32_t currtype;
-
- pgtype = SALVAGE_IGNORE;
- dbp = vdp->salvage_pages;
-
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
-
- currtype = SALVAGE_INVALID;
- data.data = &currtype;
- data.ulen = sizeof(u_int32_t);
- data.flags = DB_DBT_USERMEM;
-
- key.data = &pgno;
- key.size = sizeof(db_pgno_t);
-
- /*
- * Put an entry for this page, with pgno as key and type as data,
- * unless it's already there and is marked done.
- * If it's there and is marked anything else, that's fine--we
- * want to mark it done, but db_salvage_isdone only lets
- * us know if it's marked IGNORE.
- *
- * We don't want to return DB_KEYEXIST, though; this will
- * likely get passed up all the way and make no sense to the
- * application. Instead, use DB_VERIFY_BAD to indicate that
- * we've seen this page already--it probably indicates a
- * multiply-linked page.
- */
- if ((ret = __db_salvage_isdone(vdp, pgno)) != 0)
- return (ret == DB_KEYEXIST ? DB_VERIFY_BAD : ret);
-
- data.size = sizeof(u_int32_t);
- data.data = &pgtype;
-
- return (__db_put(dbp, NULL, &key, &data, 0));
-}
-
-/*
- * __db_salvage_markneeded --
- * If it has not yet been printed, make note of the fact that a page
- * must be dealt with later.
- *
- * PUBLIC: int __db_salvage_markneeded
- * PUBLIC: __P((VRFY_DBINFO *, db_pgno_t, u_int32_t));
- */
-int
-__db_salvage_markneeded(vdp, pgno, pgtype)
- VRFY_DBINFO *vdp;
- db_pgno_t pgno;
- u_int32_t pgtype;
-{
- DB *dbp;
- DBT key, data;
- int ret;
-
- dbp = vdp->salvage_pages;
-
- memset(&key, 0, sizeof(DBT));
- memset(&data, 0, sizeof(DBT));
-
- key.data = &pgno;
- key.size = sizeof(db_pgno_t);
-
- data.data = &pgtype;
- data.size = sizeof(u_int32_t);
-
- /*
- * Put an entry for this page, with pgno as key and type as data,
- * unless it's already there, in which case it's presumably
- * already been marked done.
- */
- ret = __db_put(dbp, NULL, &key, &data, DB_NOOVERWRITE);
- return (ret == DB_KEYEXIST ? 0 : ret);
-}
-
-/*
- * __db_vrfy_prdbt --
- * Print out a DBT data element from a verification routine.
- *
- * PUBLIC: int __db_vrfy_prdbt __P((DBT *, int, const char *, void *,
- * PUBLIC: int (*)(void *, const void *), int, VRFY_DBINFO *));
- */
-int
-__db_vrfy_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno, vdp)
- DBT *dbtp;
- int checkprint;
- const char *prefix;
- void *handle;
- int (*callback) __P((void *, const void *));
- int is_recno;
- VRFY_DBINFO *vdp;
-{
- if (vdp != NULL) {
- /*
- * If vdp is non-NULL, we might be the first key in the
- * "fake" subdatabase used for key/data pairs we can't
- * associate with a known subdb.
- *
- * Check and clear the SALVAGE_PRINTHEADER flag; if
- * it was set, print a subdatabase header.
- */
- if (F_ISSET(vdp, SALVAGE_PRINTHEADER)) {
- (void)__db_prheader(
- NULL, "__OTHER__", 0, 0, handle, callback, vdp, 0);
- F_CLR(vdp, SALVAGE_PRINTHEADER);
- F_SET(vdp, SALVAGE_PRINTFOOTER);
- }
-
- /*
- * Even if the printable flag wasn't set by our immediate
- * caller, it may be set on a salvage-wide basis.
- */
- if (F_ISSET(vdp, SALVAGE_PRINTABLE))
- checkprint = 1;
- }
- return (
- __db_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno));
-}
diff --git a/storage/bdb/db185/db185.c b/storage/bdb/db185/db185.c
deleted file mode 100644
index 59b3260e4f1..00000000000
--- a/storage/bdb/db185/db185.c
+++ /dev/null
@@ -1,583 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db185.c,v 12.2 2005/10/06 14:36:51 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef lint
-static const char copyright[] =
- "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#include
-#endif
-
-#include "db_int.h"
-#include "db185_int.h"
-
-static int db185_close __P((DB185 *));
-static int db185_compare __P((DB *, const DBT *, const DBT *));
-static int db185_del __P((const DB185 *, const DBT185 *, u_int));
-static int db185_fd __P((const DB185 *));
-static int db185_get __P((const DB185 *, const DBT185 *, DBT185 *, u_int));
-static u_int32_t
- db185_hash __P((DB *, const void *, u_int32_t));
-static size_t db185_prefix __P((DB *, const DBT *, const DBT *));
-static int db185_put __P((const DB185 *, DBT185 *, const DBT185 *, u_int));
-static int db185_seq __P((const DB185 *, DBT185 *, DBT185 *, u_int));
-static int db185_sync __P((const DB185 *, u_int));
-
-/*
- * EXTERN: #ifdef _DB185_INT_H_
- * EXTERN: DB185 *__db185_open
- * EXTERN: __P((const char *, int, int, DBTYPE, const void *));
- * EXTERN: #else
- * EXTERN: DB *__db185_open
- * EXTERN: __P((const char *, int, int, DBTYPE, const void *));
- * EXTERN: #endif
- */
-DB185 *
-__db185_open(file, oflags, mode, type, openinfo)
- const char *file;
- int oflags, mode;
- DBTYPE type;
- const void *openinfo;
-{
- const BTREEINFO *bi;
- const HASHINFO *hi;
- const RECNOINFO *ri;
- DB *dbp;
- DB185 *db185p;
- DB_FH *fhp;
- int ret;
-
- dbp = NULL;
- db185p = NULL;
-
- if ((ret = db_create(&dbp, NULL, 0)) != 0)
- goto err;
-
- if ((ret = __os_calloc(NULL, 1, sizeof(DB185), &db185p)) != 0)
- goto err;
-
- /*
- * !!!
- * The DBTYPE enum wasn't initialized in DB 185, so it's off-by-one
- * from DB 2.0.
- */
- switch (type) {
- case 0: /* DB_BTREE */
- type = DB_BTREE;
- if ((bi = openinfo) != NULL) {
- if (bi->flags & ~R_DUP)
- goto einval;
- if (bi->flags & R_DUP)
- (void)dbp->set_flags(dbp, DB_DUP);
- if (bi->cachesize != 0)
- (void)dbp->set_cachesize
- (dbp, 0, bi->cachesize, 0);
- if (bi->minkeypage != 0)
- (void)dbp->set_bt_minkey(dbp, bi->minkeypage);
- if (bi->psize != 0)
- (void)dbp->set_pagesize(dbp, bi->psize);
- if (bi->prefix != NULL) {
- db185p->prefix = bi->prefix;
- dbp->set_bt_prefix(dbp, db185_prefix);
- }
- if (bi->compare != NULL) {
- db185p->compare = bi->compare;
- dbp->set_bt_compare(dbp, db185_compare);
- }
- if (bi->lorder != 0)
- dbp->set_lorder(dbp, bi->lorder);
- }
- break;
- case 1: /* DB_HASH */
- type = DB_HASH;
- if ((hi = openinfo) != NULL) {
- if (hi->bsize != 0)
- (void)dbp->set_pagesize(dbp, hi->bsize);
- if (hi->ffactor != 0)
- (void)dbp->set_h_ffactor(dbp, hi->ffactor);
- if (hi->nelem != 0)
- (void)dbp->set_h_nelem(dbp, hi->nelem);
- if (hi->cachesize != 0)
- (void)dbp->set_cachesize
- (dbp, 0, hi->cachesize, 0);
- if (hi->hash != NULL) {
- db185p->hash = hi->hash;
- (void)dbp->set_h_hash(dbp, db185_hash);
- }
- if (hi->lorder != 0)
- dbp->set_lorder(dbp, hi->lorder);
- }
-
- break;
- case 2: /* DB_RECNO */
- type = DB_RECNO;
-
- /* DB 1.85 did renumbering by default. */
- (void)dbp->set_flags(dbp, DB_RENUMBER);
-
- /*
- * !!!
- * The file name given to DB 1.85 recno is the name of the DB
- * 2.0 backing file. If the file doesn't exist, create it if
- * the user has the O_CREAT flag set, DB 1.85 did it for you,
- * and DB 2.0 doesn't.
- *
- * !!!
- * Setting the file name to NULL specifies that we're creating
- * a temporary backing file, in DB 2.X. If we're opening the
- * DB file read-only, change the flags to read-write, because
- * temporary backing files cannot be opened read-only, and DB
- * 2.X will return an error. We are cheating here -- if the
- * application does a put on the database, it will succeed --
- * although that would be a stupid thing for the application
- * to do.
- *
- * !!!
- * Note, the file name in DB 1.85 was a const -- we don't do
- * that in DB 2.0, so do that cast.
- */
- if (file != NULL) {
- if (oflags & O_CREAT && __os_exists(file, NULL) != 0)
- if (__os_openhandle(NULL, file,
- oflags, mode, &fhp) == 0)
- (void)__os_closehandle(NULL, fhp);
- (void)dbp->set_re_source(dbp, file);
-
- if (O_RDONLY)
- oflags &= ~O_RDONLY;
- oflags |= O_RDWR;
- file = NULL;
- }
-
- if ((ri = openinfo) != NULL) {
- /*
- * !!!
- * We can't support the bfname field.
- */
-#define BFMSG \
- "Berkeley DB: DB 1.85's recno bfname field is not supported.\n"
- if (ri->bfname != NULL) {
- dbp->errx(dbp, "%s", BFMSG);
- goto einval;
- }
-
- if (ri->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT))
- goto einval;
- if (ri->flags & R_FIXEDLEN) {
- if (ri->bval != 0)
- (void)dbp->set_re_pad(dbp, ri->bval);
- if (ri->reclen != 0)
- (void)dbp->set_re_len(dbp, ri->reclen);
- } else
- if (ri->bval != 0)
- (void)dbp->set_re_delim(dbp, ri->bval);
-
- /*
- * !!!
- * We ignore the R_NOKEY flag, but that's okay, it was
- * only an optimization that was never implemented.
- */
- if (ri->flags & R_SNAPSHOT)
- (void)dbp->set_flags(dbp, DB_SNAPSHOT);
-
- if (ri->cachesize != 0)
- (void)dbp->set_cachesize
- (dbp, 0, ri->cachesize, 0);
- if (ri->psize != 0)
- (void)dbp->set_pagesize(dbp, ri->psize);
- if (ri->lorder != 0)
- dbp->set_lorder(dbp, ri->lorder);
- }
- break;
- default:
- goto einval;
- }
-
- db185p->close = db185_close;
- db185p->del = db185_del;
- db185p->fd = db185_fd;
- db185p->get = db185_get;
- db185p->put = db185_put;
- db185p->seq = db185_seq;
- db185p->sync = db185_sync;
-
- /*
- * Store a reference so we can indirect from the DB 1.85 structure
- * to the underlying DB structure, and vice-versa. This has to be
- * done BEFORE the DB::open method call because the hash callback
- * is exercised as part of hash database initialization.
- */
- db185p->dbp = dbp;
- dbp->api_internal = db185p;
-
- /* Open the database. */
- if ((ret = dbp->open(dbp, NULL,
- file, NULL, type, __db_oflags(oflags), mode)) != 0)
- goto err;
-
- /* Create the cursor used for sequential ops. */
- if ((ret = dbp->cursor(dbp, NULL, &((DB185 *)db185p)->dbc, 0)) != 0)
- goto err;
-
- return (db185p);
-
-einval: ret = EINVAL;
-
-err: if (db185p != NULL)
- __os_free(NULL, db185p);
- if (dbp != NULL)
- (void)dbp->close(dbp, 0);
-
- __os_set_errno(ret);
- return (NULL);
-}
-
-static int
-db185_close(db185p)
- DB185 *db185p;
-{
- DB *dbp;
- int ret;
-
- dbp = db185p->dbp;
-
- ret = dbp->close(dbp, 0);
-
- __os_free(NULL, db185p);
-
- if (ret == 0)
- return (0);
-
- __os_set_errno(ret);
- return (-1);
-}
-
-static int
-db185_del(db185p, key185, flags)
- const DB185 *db185p;
- const DBT185 *key185;
- u_int flags;
-{
- DB *dbp;
- DBT key;
- int ret;
-
- dbp = db185p->dbp;
-
- memset(&key, 0, sizeof(key));
- key.data = key185->data;
- key.size = key185->size;
-
- if (flags & ~R_CURSOR)
- goto einval;
- if (flags & R_CURSOR)
- ret = db185p->dbc->c_del(db185p->dbc, 0);
- else
- ret = dbp->del(dbp, NULL, &key, 0);
-
- switch (ret) {
- case 0:
- return (0);
- case DB_NOTFOUND:
- return (1);
- }
-
- if (0) {
-einval: ret = EINVAL;
- }
- __os_set_errno(ret);
- return (-1);
-}
-
-static int
-db185_fd(db185p)
- const DB185 *db185p;
-{
- DB *dbp;
- int fd, ret;
-
- dbp = db185p->dbp;
-
- if ((ret = dbp->fd(dbp, &fd)) == 0)
- return (fd);
-
- __os_set_errno(ret);
- return (-1);
-}
-
-static int
-db185_get(db185p, key185, data185, flags)
- const DB185 *db185p;
- const DBT185 *key185;
- DBT185 *data185;
- u_int flags;
-{
- DB *dbp;
- DBT key, data;
- int ret;
-
- dbp = db185p->dbp;
-
- memset(&key, 0, sizeof(key));
- key.data = key185->data;
- key.size = key185->size;
- memset(&data, 0, sizeof(data));
- data.data = data185->data;
- data.size = data185->size;
-
- if (flags)
- goto einval;
-
- switch (ret = dbp->get(dbp, NULL, &key, &data, 0)) {
- case 0:
- data185->data = data.data;
- data185->size = data.size;
- return (0);
- case DB_NOTFOUND:
- return (1);
- }
-
- if (0) {
-einval: ret = EINVAL;
- }
- __os_set_errno(ret);
- return (-1);
-}
-
-static int
-db185_put(db185p, key185, data185, flags)
- const DB185 *db185p;
- DBT185 *key185;
- const DBT185 *data185;
- u_int flags;
-{
- DB *dbp;
- DBC *dbcp_put;
- DBT key, data;
- int ret, t_ret;
-
- dbp = db185p->dbp;
-
- memset(&key, 0, sizeof(key));
- key.data = key185->data;
- key.size = key185->size;
- memset(&data, 0, sizeof(data));
- data.data = data185->data;
- data.size = data185->size;
-
- switch (flags) {
- case 0:
- ret = dbp->put(dbp, NULL, &key, &data, 0);
- break;
- case R_CURSOR:
- ret = db185p->dbc->c_put(db185p->dbc, &key, &data, DB_CURRENT);
- break;
- case R_IAFTER:
- case R_IBEFORE:
- if (dbp->type != DB_RECNO)
- goto einval;
-
- if ((ret = dbp->cursor(dbp, NULL, &dbcp_put, 0)) != 0)
- break;
- if ((ret =
- dbcp_put->c_get(dbcp_put, &key, &data, DB_SET)) == 0) {
- memset(&data, 0, sizeof(data));
- data.data = data185->data;
- data.size = data185->size;
- ret = dbcp_put->c_put(dbcp_put, &key, &data,
- flags == R_IAFTER ? DB_AFTER : DB_BEFORE);
- }
- if ((t_ret = dbcp_put->c_close(dbcp_put)) != 0 && ret == 0)
- ret = t_ret;
- break;
- case R_NOOVERWRITE:
- ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE);
- break;
- case R_SETCURSOR:
- if (dbp->type != DB_BTREE && dbp->type != DB_RECNO)
- goto einval;
-
- if ((ret = dbp->put(dbp, NULL, &key, &data, 0)) != 0)
- break;
- ret =
- db185p->dbc->c_get(db185p->dbc, &key, &data, DB_SET_RANGE);
- break;
- default:
- goto einval;
- }
-
- switch (ret) {
- case 0:
- key185->data = key.data;
- key185->size = key.size;
- return (0);
- case DB_KEYEXIST:
- return (1);
- }
-
- if (0) {
-einval: ret = EINVAL;
- }
- __os_set_errno(ret);
- return (-1);
-}
-
-static int
-db185_seq(db185p, key185, data185, flags)
- const DB185 *db185p;
- DBT185 *key185, *data185;
- u_int flags;
-{
- DB *dbp;
- DBT key, data;
- int ret;
-
- dbp = db185p->dbp;
-
- memset(&key, 0, sizeof(key));
- key.data = key185->data;
- key.size = key185->size;
- memset(&data, 0, sizeof(data));
- data.data = data185->data;
- data.size = data185->size;
-
- switch (flags) {
- case R_CURSOR:
- flags = DB_SET_RANGE;
- break;
- case R_FIRST:
- flags = DB_FIRST;
- break;
- case R_LAST:
- if (dbp->type != DB_BTREE && dbp->type != DB_RECNO)
- goto einval;
- flags = DB_LAST;
- break;
- case R_NEXT:
- flags = DB_NEXT;
- break;
- case R_PREV:
- if (dbp->type != DB_BTREE && dbp->type != DB_RECNO)
- goto einval;
- flags = DB_PREV;
- break;
- default:
- goto einval;
- }
- switch (ret = db185p->dbc->c_get(db185p->dbc, &key, &data, flags)) {
- case 0:
- key185->data = key.data;
- key185->size = key.size;
- data185->data = data.data;
- data185->size = data.size;
- return (0);
- case DB_NOTFOUND:
- return (1);
- }
-
- if (0) {
-einval: ret = EINVAL;
- }
- __os_set_errno(ret);
- return (-1);
-}
-
-static int
-db185_sync(db185p, flags)
- const DB185 *db185p;
- u_int flags;
-{
- DB *dbp;
- int ret;
-
- dbp = db185p->dbp;
-
- switch (flags) {
- case 0:
- break;
- case R_RECNOSYNC:
- /*
- * !!!
- * We can't support the R_RECNOSYNC flag.
- */
-#define RSMSG \
- "Berkeley DB: DB 1.85's R_RECNOSYNC sync flag is not supported.\n"
- dbp->errx(dbp, "%s", RSMSG);
- /* FALLTHROUGH */
- default:
- goto einval;
- }
-
- if ((ret = dbp->sync(dbp, 0)) == 0)
- return (0);
-
- if (0) {
-einval: ret = EINVAL;
- }
- __os_set_errno(ret);
- return (-1);
-}
-
-/*
- * db185_compare --
- * Cutout routine to call the user's Btree comparison function.
- */
-static int
-db185_compare(dbp, a, b)
- DB *dbp;
- const DBT *a, *b;
-{
- DBT185 a185, b185;
-
- a185.data = a->data;
- a185.size = a->size;
- b185.data = b->data;
- b185.size = b->size;
-
- return (((DB185 *)dbp->api_internal)->compare(&a185, &b185));
-}
-
-/*
- * db185_prefix --
- * Cutout routine to call the user's Btree prefix function.
- */
-static size_t
-db185_prefix(dbp, a, b)
- DB *dbp;
- const DBT *a, *b;
-{
- DBT185 a185, b185;
-
- a185.data = a->data;
- a185.size = a->size;
- b185.data = b->data;
- b185.size = b->size;
-
- return (((DB185 *)dbp->api_internal)->prefix(&a185, &b185));
-}
-
-/*
- * db185_hash --
- * Cutout routine to call the user's hash function.
- */
-static u_int32_t
-db185_hash(dbp, key, len)
- DB *dbp;
- const void *key;
- u_int32_t len;
-{
- return (((DB185 *)dbp->api_internal)->hash(key, (size_t)len));
-}
diff --git a/storage/bdb/db185/db185_int.in b/storage/bdb/db185/db185_int.in
deleted file mode 100644
index eba4fdb002d..00000000000
--- a/storage/bdb/db185/db185_int.in
+++ /dev/null
@@ -1,129 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1997-2005
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995, 1996
- * Keith Bostic. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: db185_int.in,v 12.2 2005/10/06 14:36:52 bostic Exp $
- */
-
-#ifndef _DB185_INT_H_
-#define _DB185_INT_H_
-
-/* Routine flags. */
-#define R_CURSOR 1 /* del, put, seq */
-#define __R_UNUSED 2 /* UNUSED */
-#define R_FIRST 3 /* seq */
-#define R_IAFTER 4 /* put (RECNO) */
-#define R_IBEFORE 5 /* put (RECNO) */
-#define R_LAST 6 /* seq (BTREE, RECNO) */
-#define R_NEXT 7 /* seq */
-#define R_NOOVERWRITE 8 /* put */
-#define R_PREV 9 /* seq (BTREE, RECNO) */
-#define R_SETCURSOR 10 /* put (RECNO) */
-#define R_RECNOSYNC 11 /* sync (RECNO) */
-
-typedef struct {
- void *data; /* data */
- size_t size; /* data length */
-} DBT185;
-
-/* Access method description structure. */
-typedef struct __db185 {
- DBTYPE type; /* Underlying db type. */
- int (*close) __P((struct __db185 *));
- int (*del) __P((const struct __db185 *, const DBT185 *, u_int));
- int (*get)
- __P((const struct __db185 *, const DBT185 *, DBT185 *, u_int));
- int (*put)
- __P((const struct __db185 *, DBT185 *, const DBT185 *, u_int));
- int (*seq)
- __P((const struct __db185 *, DBT185 *, DBT185 *, u_int));
- int (*sync) __P((const struct __db185 *, u_int));
- DB *dbp; /* DB structure. Was void *internal. */
- int (*fd) __P((const struct __db185 *));
-
- /*
- * !!!
- * The following elements added to the end of the DB 1.85 DB
- * structure.
- */
- DBC *dbc; /* DB cursor. */
- /* Various callback functions. */
- int (*compare) __P((const DBT185 *, const DBT185 *));
- size_t (*prefix) __P((const DBT185 *, const DBT185 *));
- u_int32_t (*hash) __P((const void *, size_t));
-} DB185;
-
-/* Structure used to pass parameters to the btree routines. */
-typedef struct {
-#define R_DUP 0x01 /* duplicate keys */
- u_int32_t flags;
- u_int32_t cachesize; /* bytes to cache */
- u_int32_t maxkeypage; /* maximum keys per page */
- u_int32_t minkeypage; /* minimum keys per page */
- u_int32_t psize; /* page size */
- int (*compare) /* comparison function */
- __P((const DBT185 *, const DBT185 *));
- size_t (*prefix) /* prefix function */
- __P((const DBT185 *, const DBT185 *));
- int lorder; /* byte order */
-} BTREEINFO;
-
-/* Structure used to pass parameters to the hashing routines. */
-typedef struct {
- u_int32_t bsize; /* bucket size */
- u_int32_t ffactor; /* fill factor */
- u_int32_t nelem; /* number of elements */
- u_int32_t cachesize; /* bytes to cache */
- u_int32_t /* hash function */
- (*hash) __P((const void *, size_t));
- int lorder; /* byte order */
-} HASHINFO;
-
-/* Structure used to pass parameters to the record routines. */
-typedef struct {
-#define R_FIXEDLEN 0x01 /* fixed-length records */
-#define R_NOKEY 0x02 /* key not required */
-#define R_SNAPSHOT 0x04 /* snapshot the input */
- u_int32_t flags;
- u_int32_t cachesize; /* bytes to cache */
- u_int32_t psize; /* page size */
- int lorder; /* byte order */
- size_t reclen; /* record length (fixed-length records) */
- u_char bval; /* delimiting byte (variable-length records */
- char *bfname; /* btree file name */
-} RECNOINFO;
-#endif /* !_DB185_INT_H_ */
diff --git a/storage/bdb/db_archive/db_archive.c b/storage/bdb/db_archive/db_archive.c
deleted file mode 100644
index d00fc1bf9ea..00000000000
--- a/storage/bdb/db_archive/db_archive.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_archive.c,v 12.4 2005/09/09 12:38:30 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef lint
-static const char copyright[] =
- "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#include
-#include
-#include
-#include
-#endif
-
-#include "db_int.h"
-
-int main __P((int, char *[]));
-int usage __P((void));
-int version_check __P((void));
-
-const char *progname;
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- DB_ENV *dbenv;
- u_int32_t flags;
- int ch, exitval, ret, verbose;
- char **file, *home, **list, *passwd;
-
- if ((progname = strrchr(argv[0], '/')) == NULL)
- progname = argv[0];
- else
- ++progname;
-
- if ((ret = version_check()) != 0)
- return (ret);
-
- dbenv = NULL;
- flags = 0;
- exitval = verbose = 0;
- home = passwd = NULL;
- file = list = NULL;
- while ((ch = getopt(argc, argv, "adh:lP:sVv")) != EOF)
- switch (ch) {
- case 'a':
- LF_SET(DB_ARCH_ABS);
- break;
- case 'd':
- LF_SET(DB_ARCH_REMOVE);
- break;
- case 'h':
- home = optarg;
- break;
- case 'l':
- LF_SET(DB_ARCH_LOG);
- break;
- case 'P':
- passwd = strdup(optarg);
- memset(optarg, 0, strlen(optarg));
- if (passwd == NULL) {
- fprintf(stderr, "%s: strdup: %s\n",
- progname, strerror(errno));
- return (EXIT_FAILURE);
- }
- break;
- case 's':
- LF_SET(DB_ARCH_DATA);
- break;
- case 'V':
- printf("%s\n", db_version(NULL, NULL, NULL));
- return (EXIT_SUCCESS);
- case 'v':
- verbose = 1;
- break;
- case '?':
- default:
- return (usage());
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 0)
- return (usage());
-
- /* Handle possible interruptions. */
- __db_util_siginit();
-
- /*
- * Create an environment object and initialize it for error
- * reporting.
- */
- if ((ret = db_env_create(&dbenv, 0)) != 0) {
- fprintf(stderr,
- "%s: db_env_create: %s\n", progname, db_strerror(ret));
- goto shutdown;
- }
-
- dbenv->set_errfile(dbenv, stderr);
- dbenv->set_errpfx(dbenv, progname);
-
- if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv,
- passwd, DB_ENCRYPT_AES)) != 0) {
- dbenv->err(dbenv, ret, "set_passwd");
- goto shutdown;
- }
- /*
- * If attaching to a pre-existing environment fails, create a
- * private one and try again.
- */
- if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0 &&
- (ret == DB_VERSION_MISMATCH ||
- (ret = dbenv->open(dbenv, home, DB_CREATE |
- DB_INIT_LOG | DB_PRIVATE | DB_USE_ENVIRON, 0)) != 0)) {
- dbenv->err(dbenv, ret, "DB_ENV->open");
- goto shutdown;
- }
-
- /* Get the list of names. */
- if ((ret = dbenv->log_archive(dbenv, &list, flags)) != 0) {
- dbenv->err(dbenv, ret, "DB_ENV->log_archive");
- goto shutdown;
- }
-
- /* Print the list of names. */
- if (list != NULL) {
- for (file = list; *file != NULL; ++file)
- printf("%s\n", *file);
- free(list);
- }
-
- if (0) {
-shutdown: exitval = 1;
- }
- if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) {
- exitval = 1;
- fprintf(stderr,
- "%s: dbenv->close: %s\n", progname, db_strerror(ret));
- }
-
- if (passwd != NULL)
- free(passwd);
-
- /* Resend any caught signal. */
- __db_util_sigresend();
-
- return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
-}
-
-int
-usage()
-{
- (void)fprintf(stderr,
- "usage: %s [-adlsVv] [-h home] [-P password]\n", progname);
- return (EXIT_FAILURE);
-}
-
-int
-version_check()
-{
- int v_major, v_minor, v_patch;
-
- /* Make sure we're loaded with the right version of the DB library. */
- (void)db_version(&v_major, &v_minor, &v_patch);
- if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
- fprintf(stderr,
- "%s: version %d.%d doesn't match library version %d.%d\n",
- progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
- v_major, v_minor);
- return (EXIT_FAILURE);
- }
- return (0);
-}
diff --git a/storage/bdb/db_checkpoint/db_checkpoint.c b/storage/bdb/db_checkpoint/db_checkpoint.c
deleted file mode 100644
index c1ee7b50596..00000000000
--- a/storage/bdb/db_checkpoint/db_checkpoint.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_checkpoint.c,v 12.6 2005/09/09 12:38:30 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef lint
-static const char copyright[] =
- "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#if TIME_WITH_SYS_TIME
-#include
-#include
-#else
-#if HAVE_SYS_TIME_H
-#include
-#else
-#include
-#endif
-#endif
-
-#include
-#include
-#include
-#include
-#endif
-
-#include "db_int.h"
-
-int main __P((int, char *[]));
-int usage __P((void));
-int version_check __P((void));
-
-const char *progname;
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- DB_ENV *dbenv;
- time_t now;
- long argval;
- u_int32_t flags, kbytes, minutes, seconds;
- int ch, exitval, once, ret, verbose;
- char *home, *logfile, *passwd;
-
- if ((progname = strrchr(argv[0], '/')) == NULL)
- progname = argv[0];
- else
- ++progname;
-
- if ((ret = version_check()) != 0)
- return (ret);
-
- /*
- * !!!
- * Don't allow a fully unsigned 32-bit number, some compilers get
- * upset and require it to be specified in hexadecimal and so on.
- */
-#define MAX_UINT32_T 2147483647
-
- dbenv = NULL;
- kbytes = minutes = 0;
- exitval = once = verbose = 0;
- flags = 0;
- home = logfile = passwd = NULL;
- while ((ch = getopt(argc, argv, "1h:k:L:P:p:Vv")) != EOF)
- switch (ch) {
- case '1':
- once = 1;
- flags = DB_FORCE;
- break;
- case 'h':
- home = optarg;
- break;
- case 'k':
- if (__db_getlong(NULL, progname,
- optarg, 1, (long)MAX_UINT32_T, &argval))
- return (EXIT_FAILURE);
- kbytes = (u_int32_t)argval;
- break;
- case 'L':
- logfile = optarg;
- break;
- case 'P':
- passwd = strdup(optarg);
- memset(optarg, 0, strlen(optarg));
- if (passwd == NULL) {
- fprintf(stderr, "%s: strdup: %s\n",
- progname, strerror(errno));
- return (EXIT_FAILURE);
- }
- break;
- case 'p':
- if (__db_getlong(NULL, progname,
- optarg, 1, (long)MAX_UINT32_T, &argval))
- return (EXIT_FAILURE);
- minutes = (u_int32_t)argval;
- break;
- case 'V':
- printf("%s\n", db_version(NULL, NULL, NULL));
- return (EXIT_SUCCESS);
- case 'v':
- verbose = 1;
- break;
- case '?':
- default:
- return (usage());
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 0)
- return (usage());
-
- if (once == 0 && kbytes == 0 && minutes == 0) {
- (void)fprintf(stderr,
- "%s: at least one of -1, -k and -p must be specified\n",
- progname);
- return (EXIT_FAILURE);
- }
-
- /* Handle possible interruptions. */
- __db_util_siginit();
-
- /* Log our process ID. */
- if (logfile != NULL && __db_util_logset(progname, logfile))
- goto shutdown;
-
- /*
- * Create an environment object and initialize it for error
- * reporting.
- */
- if ((ret = db_env_create(&dbenv, 0)) != 0) {
- fprintf(stderr,
- "%s: db_env_create: %s\n", progname, db_strerror(ret));
- goto shutdown;
- }
-
- dbenv->set_errfile(dbenv, stderr);
- dbenv->set_errpfx(dbenv, progname);
-
- if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv,
- passwd, DB_ENCRYPT_AES)) != 0) {
- dbenv->err(dbenv, ret, "set_passwd");
- goto shutdown;
- }
- /* Initialize the environment. */
- if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0) {
- dbenv->err(dbenv, ret, "open");
- goto shutdown;
- }
-
- /*
- * If we have only a time delay, then we'll sleep the right amount
- * to wake up when a checkpoint is necessary. If we have a "kbytes"
- * field set, then we'll check every 30 seconds.
- */
- seconds = kbytes != 0 ? 30 : minutes * 60;
- while (!__db_util_interrupted()) {
- if (verbose) {
- (void)time(&now);
- dbenv->errx(dbenv, "checkpoint begin: %s", ctime(&now));
- }
-
- if ((ret = dbenv->txn_checkpoint(dbenv,
- kbytes, minutes, flags)) != 0) {
- dbenv->err(dbenv, ret, "txn_checkpoint");
- goto shutdown;
- }
-
- if (verbose) {
- (void)time(&now);
- dbenv->errx(dbenv,
- "checkpoint complete: %s", ctime(&now));
- }
-
- if (once)
- break;
-
- __os_sleep(dbenv, seconds, 0);
- }
-
- if (0) {
-shutdown: exitval = 1;
- }
-
- /* Clean up the logfile. */
- if (logfile != NULL)
- (void)remove(logfile);
-
- /* Clean up the environment. */
- if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) {
- exitval = 1;
- fprintf(stderr,
- "%s: dbenv->close: %s\n", progname, db_strerror(ret));
- }
-
- if (passwd != NULL)
- free(passwd);
-
- /* Resend any caught signal. */
- __db_util_sigresend();
-
- return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
-}
-
-int
-usage()
-{
- (void)fprintf(stderr, "usage: %s [-1Vv]\n\t%s\n", progname,
- "[-h home] [-k kbytes] [-L file] [-P password] [-p min]");
- return (EXIT_FAILURE);
-}
-
-int
-version_check()
-{
- int v_major, v_minor, v_patch;
-
- /* Make sure we're loaded with the right version of the DB library. */
- (void)db_version(&v_major, &v_minor, &v_patch);
- if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
- fprintf(stderr,
- "%s: version %d.%d doesn't match library version %d.%d\n",
- progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
- v_major, v_minor);
- return (EXIT_FAILURE);
- }
- return (0);
-}
diff --git a/storage/bdb/db_deadlock/db_deadlock.c b/storage/bdb/db_deadlock/db_deadlock.c
deleted file mode 100644
index 67078a6937a..00000000000
--- a/storage/bdb/db_deadlock/db_deadlock.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996-2005
- * Sleepycat Software. All rights reserved.
- *
- * $Id: db_deadlock.c,v 12.4 2005/10/03 16:00:16 bostic Exp $
- */
-
-#include "db_config.h"
-
-#ifndef lint
-static const char copyright[] =
- "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n";
-#endif
-
-#ifndef NO_SYSTEM_INCLUDES
-#include
-
-#if TIME_WITH_SYS_TIME
-#include
-#include
-#else
-#if HAVE_SYS_TIME_H
-#include
-#else
-#include
-#endif
-#endif
-
-#include
-#include
-#include
-#include
-#include