2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 1996, 1997
5 * Sleepycat Software. All rights reserved.
8 * Copyright (c) 1995, 1996
9 * Margo Seltzer. All rights reserved.
12 * Copyright (c) 1995, 1996
13 * The President and Fellows of Harvard University. All rights reserved.
15 * This code is derived from software contributed to Berkeley by
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 * must display the following acknowledgement:
28 * This product includes software developed by the University of
29 * California, Berkeley and its contributors.
30 * 4. Neither the name of the University nor the names of its contributors
31 * may be used to endorse or promote products derived from this software
32 * without specific prior written permission.
34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 static const char sccsid[] = "@(#)hash_rec.c 10.13 (Sleepycat) 9/15/97";
53 #ifndef NO_SYSTEM_INCLUDES
54 #include <sys/types.h>
67 #include "db_dispatch.h"
68 #include "common_ext.h"
71 * __ham_insdel_recover --
73 * PUBLIC: int __ham_insdel_recover
74 * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
77 __ham_insdel_recover(logp, dbtp, lsnp, redo, info)
84 __ham_insdel_args *argp;
90 int cmp_n, cmp_p, getmeta, ret;
93 hashp = NULL; /* XXX: shut the compiler up. */
94 REC_PRINT(__ham_insdel_print);
95 REC_INTRO(__ham_insdel_read);
97 ret = memp_fget(mpf, &argp->pgno, 0, &pagep);
101 * We are undoing and the page doesn't exist. That
102 * is equivalent to having a pagelsn of 0, so we
103 * would not have to undo anything. In this case,
104 * don't bother creating a page.
106 *lsnp = argp->prev_lsn;
109 } else if ((ret = memp_fget(mpf, &argp->pgno,
110 DB_MPOOL_CREATE, &pagep)) != 0)
114 hashp = (HTAB *)file_dbp->internal;
115 GET_META(file_dbp, hashp);
118 cmp_n = log_compare(lsnp, &LSN(pagep));
119 cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
121 * Two possible things going on:
122 * redo a delete/undo a put: delete the item from the page.
123 * redo a put/undo a delete: add the item to the page.
124 * If we are undoing a delete, then the information logged is the
125 * entire entry off the page, not just the data of a dbt. In
126 * this case, we want to copy it back onto the page verbatim.
127 * We do this by calling __putitem with the type H_OFFPAGE instead
130 op = OPCODE_OF(argp->opcode);
132 if ((op == DELPAIR && cmp_n == 0 && !redo) ||
133 (op == PUTPAIR && cmp_p == 0 && redo)) {
134 /* Need to redo a PUT or undo a delete. */
135 __ham_putitem(pagep, &argp->key,
136 !redo || PAIR_ISKEYBIG(argp->opcode) ?
137 H_OFFPAGE : H_KEYDATA);
138 __ham_putitem(pagep, &argp->data,
139 !redo || PAIR_ISDATABIG(argp->opcode) ?
140 H_OFFPAGE : H_KEYDATA);
142 LSN(pagep) = redo ? *lsnp : argp->pagelsn;
143 if ((ret = __ham_put_page(file_dbp, pagep, 1)) != 0)
146 } else if ((op == DELPAIR && cmp_p == 0 && redo)
147 || (op == PUTPAIR && cmp_n == 0 && !redo)) {
148 /* Need to undo a put or redo a delete. */
149 __ham_dpair(file_dbp, pagep, argp->ndx);
150 LSN(pagep) = redo ? *lsnp : argp->pagelsn;
151 if ((ret = __ham_put_page(file_dbp, (PAGE *)pagep, 1)) != 0)
154 if ((ret = __ham_put_page(file_dbp, (PAGE *)pagep, 0)) != 0)
157 /* Return the previous LSN. */
158 *lsnp = argp->prev_lsn;
161 RELEASE_META(file_dbp, hashp);
166 * __ham_newpage_recover --
167 * This log message is used when we add/remove overflow pages. This
168 * message takes care of the pointer chains, not the data on the pages.
170 * PUBLIC: int __ham_newpage_recover
171 * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
174 __ham_newpage_recover(logp, dbtp, lsnp, redo, info)
181 __ham_newpage_args *argp;
186 int cmp_n, cmp_p, change, getmeta, ret;
189 hashp = NULL; /* XXX: shut the compiler up. */
190 REC_PRINT(__ham_newpage_print);
191 REC_INTRO(__ham_newpage_read);
193 ret = memp_fget(mpf, &argp->new_pgno, 0, &pagep);
197 * We are undoing and the page doesn't exist. That
198 * is equivalent to having a pagelsn of 0, so we
199 * would not have to undo anything. In this case,
200 * don't bother creating a page.
204 } else if ((ret = memp_fget(mpf, &argp->new_pgno,
205 DB_MPOOL_CREATE, &pagep)) != 0)
208 hashp = (HTAB *)file_dbp->internal;
209 GET_META(file_dbp, hashp);
213 * There are potentially three pages we need to check: the one
214 * that we created/deleted, the one before it and the one after
218 cmp_n = log_compare(lsnp, &LSN(pagep));
219 cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
222 if ((cmp_p == 0 && redo && argp->opcode == PUTOVFL) ||
223 (cmp_n == 0 && !redo && argp->opcode == DELOVFL)) {
224 /* Redo a create new page or undo a delete new page. */
225 P_INIT(pagep, file_dbp->pgsize, argp->new_pgno,
226 argp->prev_pgno, argp->next_pgno, 0, P_HASH);
228 } else if ((cmp_p == 0 && redo && argp->opcode == DELOVFL) ||
229 (cmp_n == 0 && !redo && argp->opcode == PUTOVFL)) {
231 * Redo a delete or undo a create new page. All we
232 * really need to do is change the LSN.
238 if ((ret = __ham_put_page(file_dbp, (PAGE *)pagep, 0)) != 0)
241 LSN(pagep) = redo ? *lsnp : argp->pagelsn;
242 if ((ret = __ham_put_page(file_dbp, (PAGE *)pagep, 1)) != 0)
246 /* Now do the prev page. */
247 ppage: if (argp->prev_pgno != PGNO_INVALID) {
248 ret = memp_fget(mpf, &argp->prev_pgno, 0, &pagep);
253 * We are undoing and the page doesn't exist.
254 * That is equivalent to having a pagelsn of 0,
255 * so we would not have to undo anything. In
256 * this case, don't bother creating a page.
261 memp_fget(mpf, &argp->prev_pgno,
262 DB_MPOOL_CREATE, &pagep)) != 0)
265 cmp_n = log_compare(lsnp, &LSN(pagep));
266 cmp_p = log_compare(&LSN(pagep), &argp->prevlsn);
269 if ((cmp_p == 0 && redo && argp->opcode == PUTOVFL) ||
270 (cmp_n == 0 && !redo && argp->opcode == DELOVFL)) {
271 /* Redo a create new page or undo a delete new page. */
272 pagep->next_pgno = argp->new_pgno;
274 } else if ((cmp_p == 0 && redo && argp->opcode == DELOVFL) ||
275 (cmp_n == 0 && !redo && argp->opcode == PUTOVFL)) {
276 /* Redo a delete or undo a create new page. */
277 pagep->next_pgno = argp->next_pgno;
282 if ((ret = __ham_put_page(file_dbp, (PAGE *)pagep, 0)) != 0)
285 LSN(pagep) = redo ? *lsnp : argp->prevlsn;
286 if ((ret = __ham_put_page(file_dbp, (PAGE *)pagep, 1)) != 0)
291 /* Now time to do the next page */
292 npage: if (argp->next_pgno != PGNO_INVALID) {
293 ret = memp_fget(mpf, &argp->next_pgno, 0, &pagep);
298 * We are undoing and the page doesn't exist.
299 * That is equivalent to having a pagelsn of 0,
300 * so we would not have to undo anything. In
301 * this case, don't bother creating a page.
303 *lsnp = argp->prev_lsn;
307 memp_fget(mpf, &argp->next_pgno,
308 DB_MPOOL_CREATE, &pagep)) != 0)
311 cmp_n = log_compare(lsnp, &LSN(pagep));
312 cmp_p = log_compare(&LSN(pagep), &argp->nextlsn);
315 if ((cmp_p == 0 && redo && argp->opcode == PUTOVFL) ||
316 (cmp_n == 0 && !redo && argp->opcode == DELOVFL)) {
317 /* Redo a create new page or undo a delete new page. */
318 pagep->prev_pgno = argp->new_pgno;
320 } else if ((cmp_p == 0 && redo && argp->opcode == DELOVFL) ||
321 (cmp_n == 0 && !redo && argp->opcode == PUTOVFL)) {
322 /* Redo a delete or undo a create new page. */
323 pagep->prev_pgno = argp->prev_pgno;
329 __ham_put_page(file_dbp, (PAGE *)pagep, 0)) != 0)
332 LSN(pagep) = redo ? *lsnp : argp->nextlsn;
334 __ham_put_page(file_dbp, (PAGE *)pagep, 1)) != 0)
338 *lsnp = argp->prev_lsn;
341 RELEASE_META(file_dbp, hashp);
347 * __ham_replace_recover --
348 * This log message refers to partial puts that are local to a single
349 * page. You can think of them as special cases of the more general
350 * insdel log message.
352 * PUBLIC: int __ham_replace_recover
353 * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
356 __ham_replace_recover(logp, dbtp, lsnp, redo, info)
363 __ham_replace_args *argp;
370 int change, cmp_n, cmp_p, getmeta, ret;
374 hashp = NULL; /* XXX: shut the compiler up. */
375 REC_PRINT(__ham_replace_print);
376 REC_INTRO(__ham_replace_read);
378 ret = memp_fget(mpf, &argp->pgno, 0, &pagep);
382 * We are undoing and the page doesn't exist. That
383 * is equivalent to having a pagelsn of 0, so we
384 * would not have to undo anything. In this case,
385 * don't bother creating a page.
387 *lsnp = argp->prev_lsn;
390 } else if ((ret = memp_fget(mpf, &argp->pgno,
391 DB_MPOOL_CREATE, &pagep)) != 0)
394 hashp = (HTAB *)file_dbp->internal;
395 GET_META(file_dbp, hashp);
398 cmp_n = log_compare(lsnp, &LSN(pagep));
399 cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
401 if (cmp_p == 0 && redo) {
403 /* Reapply the change as specified. */
404 dbt.data = argp->newitem.data;
405 dbt.size = argp->newitem.size;
406 grow = argp->newitem.size - argp->olditem.size;
408 } else if (cmp_n == 0 && !redo) {
410 /* Undo the already applied change. */
411 dbt.data = argp->olditem.data;
412 dbt.size = argp->olditem.size;
413 grow = argp->olditem.size - argp->newitem.size;
414 LSN(pagep) = argp->pagelsn;
421 __ham_onpage_replace(pagep,
422 file_dbp->pgsize, argp->ndx, argp->off, grow, &dbt);
424 hk = P_ENTRY(pagep, argp->ndx);
426 HPAGE_PTYPE(hk) = H_DUPLICATE;
428 HPAGE_PTYPE(hk) = H_KEYDATA;
432 if ((ret = __ham_put_page(file_dbp, pagep, change)) != 0)
435 *lsnp = argp->prev_lsn;
438 RELEASE_META(file_dbp, hashp);
443 * __ham_newpgno_recover --
444 * This log message is used when allocating or deleting an overflow
445 * page. It takes care of modifying the meta data.
447 * PUBLIC: int __ham_newpgno_recover
448 * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
451 __ham_newpgno_recover(logp, dbtp, lsnp, redo, info)
458 __ham_newpgno_args *argp;
463 int change, cmp_n, cmp_p, getmeta, ret;
466 hashp = NULL; /* XXX: shut the compiler up. */
467 REC_PRINT(__ham_newpgno_print);
468 REC_INTRO(__ham_newpgno_read);
470 hashp = (HTAB *)file_dbp->internal;
471 GET_META(file_dbp, hashp);
475 * There are two phases to the recovery here. First we need
476 * to update the meta data; then we need to update the page.
477 * We'll do the meta-data first.
479 cmp_n = log_compare(lsnp, &hashp->hdr->lsn);
480 cmp_p = log_compare(&hashp->hdr->lsn, &argp->metalsn);
483 if ((cmp_p == 0 && redo && argp->opcode == ALLOCPGNO) ||
484 (cmp_n == 0 && !redo && argp->opcode == DELPGNO)) {
485 /* Need to redo an allocation or undo a deletion. */
486 hashp->hdr->last_freed = argp->free_pgno;
487 if (redo && argp->old_pgno != 0) /* Must be ALLOCPGNO */
488 hashp->hdr->spares[hashp->hdr->ovfl_point]++;
490 } else if (cmp_p == 0 && redo && argp->opcode == DELPGNO) {
491 /* Need to redo a deletion */
492 hashp->hdr->last_freed = argp->pgno;
494 } else if (cmp_n == 0 && !redo && argp->opcode == ALLOCPGNO) {
495 /* undo an allocation. */
496 if (argp->old_pgno == 0)
497 hashp->hdr->last_freed = argp->pgno;
499 hashp->hdr->spares[hashp->hdr->ovfl_point]--;
500 hashp->hdr->last_freed = 0;
505 hashp->hdr->lsn = redo ? *lsnp : argp->metalsn;
506 F_SET(file_dbp, DB_HS_DIRTYMETA);
510 /* Now check the newly allocated/freed page. */
511 ret = memp_fget(mpf, &argp->pgno, 0, &pagep);
516 * We are undoing and the page doesn't exist. That
517 * is equivalent to having a pagelsn of 0, so we
518 * would not have to undo anything. In this case,
519 * don't bother creating a page.
521 *lsnp = argp->prev_lsn;
524 } else if ((ret = memp_fget(mpf, &argp->pgno,
525 DB_MPOOL_CREATE, &pagep)) != 0)
528 cmp_n = log_compare(lsnp, &LSN(pagep));
529 cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
532 if (cmp_p == 0 && redo && argp->opcode == ALLOCPGNO) {
533 /* Need to redo an allocation. */
534 P_INIT(pagep, file_dbp->pgsize, argp->pgno, PGNO_INVALID,
535 PGNO_INVALID, 0, argp->new_type);
537 } else if (cmp_n == 0 && !redo && argp->opcode == DELPGNO) {
538 /* Undoing a delete. */
539 P_INIT(pagep, file_dbp->pgsize, argp->pgno, PGNO_INVALID,
540 argp->old_pgno, 0, argp->old_type);
542 } else if ((cmp_p == 0 && redo && argp->opcode == DELPGNO) ||
543 (cmp_n == 0 && !redo && argp->opcode == ALLOCPGNO)) {
544 /* Need to redo a deletion or undo an allocation. */
545 NEXT_PGNO(pagep) = argp->free_pgno;
546 TYPE(pagep) = P_INVALID;
550 LSN(pagep) = redo ? *lsnp : argp->pagelsn;
552 if ((ret = __ham_put_page(file_dbp, pagep, change)) != 0)
555 *lsnp = argp->prev_lsn;
558 RELEASE_META(file_dbp, hashp);
564 * __ham_splitmeta_recover --
565 * This is the meta-data part of the split. Records the new and old
566 * bucket numbers and the new/old mask information.
568 * PUBLIC: int __ham_splitmeta_recover
569 * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
572 __ham_splitmeta_recover(logp, dbtp, lsnp, redo, info)
579 __ham_splitmeta_args *argp;
583 int change, cmp_n, cmp_p, getmeta, ret;
587 hashp = NULL; /* XXX: shut the compiler up. */
588 REC_PRINT(__ham_splitmeta_print);
589 REC_INTRO(__ham_splitmeta_read);
591 hashp = (HTAB *)file_dbp->internal;
592 GET_META(file_dbp, hashp);
596 * There are two phases to the recovery here. First we need
597 * to update the meta data; then we need to update the page.
598 * We'll do the meta-data first.
600 cmp_n = log_compare(lsnp, &hashp->hdr->lsn);
601 cmp_p = log_compare(&hashp->hdr->lsn, &argp->metalsn);
604 if (cmp_p == 0 && redo) {
605 /* Need to redo the split information. */
606 hashp->hdr->max_bucket = argp->bucket + 1;
607 pow = __db_log2(hashp->hdr->max_bucket + 1);
608 if (pow > hashp->hdr->ovfl_point) {
609 hashp->hdr->spares[pow] =
610 hashp->hdr->spares[hashp->hdr->ovfl_point];
611 hashp->hdr->ovfl_point = pow;
613 if (hashp->hdr->max_bucket > hashp->hdr->high_mask) {
614 hashp->hdr->low_mask = hashp->hdr->high_mask;
615 hashp->hdr->high_mask =
616 hashp->hdr->max_bucket | hashp->hdr->low_mask;
619 } else if (cmp_n == 0 && !redo) {
620 /* Need to undo the split information. */
621 hashp->hdr->max_bucket = argp->bucket;
622 hashp->hdr->ovfl_point = argp->ovflpoint;
623 hashp->hdr->spares[hashp->hdr->ovfl_point] = argp->spares;
624 pow = 1 << __db_log2(hashp->hdr->max_bucket + 1);
625 hashp->hdr->high_mask = pow - 1;
626 hashp->hdr->low_mask = (pow >> 1) - 1;
630 hashp->hdr->lsn = redo ? *lsnp : argp->metalsn;
631 F_SET(file_dbp, DB_HS_DIRTYMETA);
633 *lsnp = argp->prev_lsn;
636 RELEASE_META(file_dbp, hashp);
641 * __ham_splitdata_recover --
643 * PUBLIC: int __ham_splitdata_recover
644 * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
647 __ham_splitdata_recover(logp, dbtp, lsnp, redo, info)
654 __ham_splitdata_args *argp;
659 int change, cmp_n, cmp_p, getmeta, ret;
662 hashp = NULL; /* XXX: shut the compiler up. */
663 REC_PRINT(__ham_splitdata_print);
664 REC_INTRO(__ham_splitdata_read);
666 ret = memp_fget(mpf, &argp->pgno, 0, &pagep);
670 * We are undoing and the page doesn't exist. That
671 * is equivalent to having a pagelsn of 0, so we
672 * would not have to undo anything. In this case,
673 * don't bother creating a page.
675 *lsnp = argp->prev_lsn;
678 } else if ((ret = memp_fget(mpf, &argp->pgno,
679 DB_MPOOL_CREATE, &pagep)) != 0)
682 hashp = (HTAB *)file_dbp->internal;
683 GET_META(file_dbp, hashp);
686 cmp_n = log_compare(lsnp, &LSN(pagep));
687 cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);
690 * There are two types of log messages here, one for the old page
691 * and one for the new pages created. The original image in the
692 * SPLITOLD record is used for undo. The image in the SPLITNEW
693 * is used for redo. We should never have a case where there is
694 * a redo operation and the SPLITOLD record is on disk, but not
695 * the SPLITNEW record. Therefore, we only have work to do when
696 * redo NEW messages and undo OLD messages, but we have to update
697 * LSNs in both cases.
700 if (cmp_p == 0 && redo) {
701 if (argp->opcode == SPLITNEW)
702 /* Need to redo the split described. */
703 memcpy(pagep, argp->pageimage.data,
704 argp->pageimage.size);
707 } else if (cmp_n == 0 && !redo) {
708 if (argp->opcode == SPLITOLD) {
709 /* Put back the old image. */
710 memcpy(pagep, argp->pageimage.data,
711 argp->pageimage.size);
713 P_INIT(pagep, file_dbp->pgsize, argp->pgno,
714 PGNO_INVALID, PGNO_INVALID, 0, P_HASH);
715 LSN(pagep) = argp->pagelsn;
718 if ((ret = __ham_put_page(file_dbp, pagep, change)) != 0)
721 *lsnp = argp->prev_lsn;
724 RELEASE_META(file_dbp, hashp);
729 * __ham_ovfl_recover --
730 * This message is generated when we initialize a set of overflow pages.
732 * PUBLIC: int __ham_ovfl_recover
733 * PUBLIC: __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
736 __ham_ovfl_recover(logp, dbtp, lsnp, redo, info)
743 __ham_ovfl_args *argp;
748 db_pgno_t max_pgno, pgno;
749 int cmp_n, cmp_p, getmeta, ret;
752 hashp = NULL; /* XXX: shut the compiler up. */
753 REC_PRINT(__ham_ovfl_print);
754 REC_INTRO(__ham_ovfl_read);
756 hashp = (HTAB *)file_dbp->internal;
757 GET_META(file_dbp, hashp);
761 cmp_n = log_compare(lsnp, &hashp->hdr->lsn);
762 cmp_p = log_compare(&hashp->hdr->lsn, &argp->metalsn);
764 if (cmp_p == 0 && redo) {
765 /* Redo the allocation. */
766 hashp->hdr->last_freed = argp->start_pgno;
767 hashp->hdr->spares[argp->npages - 1] += argp->npages;
768 hashp->hdr->lsn = *lsnp;
769 F_SET(file_dbp, DB_HS_DIRTYMETA);
770 } else if (cmp_n == 0 && !redo) {
771 hashp->hdr->last_freed = argp->free_pgno;
772 hashp->hdr->spares[argp->npages - 1] -= argp->npages;
773 hashp->hdr->lsn = argp->metalsn;
774 F_SET(file_dbp, DB_HS_DIRTYMETA);
777 max_pgno = argp->start_pgno + argp->npages - 1;
779 for (pgno = argp->start_pgno; pgno <= max_pgno; pgno++) {
780 ret = memp_fget(mpf, &pgno, 0, &pagep);
782 if (redo && (ret = memp_fget(mpf, &pgno,
783 DB_MPOOL_CREATE, &pagep)) != 0)
786 (void)__ham_put_page(file_dbp, pagep, 0);
790 if (redo && log_compare((const DB_LSN *)lsnp,
791 (const DB_LSN *)&LSN(pagep)) > 0) {
792 P_INIT(pagep, file_dbp->pgsize, pgno, PGNO_INVALID,
793 pgno == max_pgno ? argp->free_pgno : pgno + 1,
796 ret = __ham_put_page(file_dbp, pagep, 1);
798 ZERO_LSN(pagep->lsn);
799 ret = __ham_put_page(file_dbp, pagep, 1);
801 ret = __ham_put_page(file_dbp, pagep, 0);
806 *lsnp = argp->prev_lsn;
808 RELEASE_META(file_dbp, hashp);