1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2000,2008 Oracle.  All rights reserved.
5 *
6 * $Id: db_setlsn.c,v 12.22 2008/01/08 20:58:10 bostic Exp $
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12#include "dbinc/db_page.h"
13#include "dbinc/db_am.h"
14#include "dbinc/mp.h"
15
16static int __env_lsn_reset __P((ENV *, DB_THREAD_INFO *, const char *, int));
17
18/*
19 * __env_lsn_reset_pp --
20 *	ENV->lsn_reset pre/post processing.
21 *
22 * PUBLIC: int __env_lsn_reset_pp __P((DB_ENV *, const char *, u_int32_t));
23 */
24int
25__env_lsn_reset_pp(dbenv, name, flags)
26	DB_ENV *dbenv;
27	const char *name;
28	u_int32_t flags;
29{
30	DB_THREAD_INFO *ip;
31	ENV *env;
32	int ret;
33
34	env = dbenv->env;
35
36	ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->lsn_reset");
37
38	/*
39	 * !!!
40	 * The actual argument checking is simple, do it inline, outside of
41	 * the replication block.
42	 */
43	if (flags != 0 && flags != DB_ENCRYPT)
44		return (__db_ferr(env, "DB_ENV->lsn_reset", 0));
45
46	ENV_ENTER(env, ip);
47	REPLICATION_WRAP(env,
48	    (__env_lsn_reset(env, ip, name, LF_ISSET(DB_ENCRYPT) ? 1 : 0)),
49	    1, ret);
50	ENV_LEAVE(env, ip);
51	return (ret);
52}
53
54/*
55 * __env_lsn_reset --
56 *	Reset the LSNs for every page in the file.
57 */
58static int
59__env_lsn_reset(env, ip, name, encrypted)
60	ENV *env;
61	DB_THREAD_INFO *ip;
62	const char *name;
63	int encrypted;
64{
65	DB *dbp;
66	DB_MPOOLFILE *mpf;
67	PAGE *pagep;
68	db_pgno_t pgno;
69	int t_ret, ret;
70
71	/* Create the DB object. */
72	if ((ret = __db_create_internal(&dbp, env, 0)) != 0)
73		return (ret);
74
75	/* If configured with a password, the databases are encrypted. */
76	if (encrypted && (ret = __db_set_flags(dbp, DB_ENCRYPT)) != 0)
77		goto err;
78
79	/*
80	 * Open the DB file.
81	 *
82	 * !!!
83	 * Note DB_RDWRMASTER flag, we need to open the master database file
84	 * for writing in this case.
85	 */
86	if ((ret = __db_open(dbp, ip, NULL,
87	    name, NULL, DB_UNKNOWN, DB_RDWRMASTER, 0, PGNO_BASE_MD)) != 0) {
88		__db_err(env, ret, "%s", name);
89		goto err;
90	}
91
92	/* Reset the LSN on every page of the database file. */
93	mpf = dbp->mpf;
94	for (pgno = 0;
95	    (ret = __memp_fget(mpf,
96	    &pgno, ip, NULL, DB_MPOOL_DIRTY, &pagep)) == 0;
97	    ++pgno) {
98		LSN_NOT_LOGGED(pagep->lsn);
99		if ((ret = __memp_fput(mpf,
100		    ip, pagep, DB_PRIORITY_UNCHANGED)) != 0)
101			goto err;
102	}
103
104	if (ret == DB_PAGE_NOTFOUND)
105		ret = 0;
106
107err:	if ((t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0)
108		ret = t_ret;
109	return (ret);
110}
111