1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1999-2009 Oracle.  All rights reserved.
5 *
6 * $Id$
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12#include "dbinc/db_page.h"
13#include "dbinc/hash.h"
14#include "dbinc/lock.h"
15#include "dbinc/mp.h"
16
17/*
18 * Acquire the meta-data page.
19 *
20 * PUBLIC: int __ham_get_meta __P((DBC *));
21 */
22int
23__ham_get_meta(dbc)
24	DBC *dbc;
25{
26	DB *dbp;
27	DB_MPOOLFILE *mpf;
28	HASH *hashp;
29	HASH_CURSOR *hcp;
30	int ret;
31
32	dbp = dbc->dbp;
33	mpf = dbp->mpf;
34	hashp = dbp->h_internal;
35	hcp = (HASH_CURSOR *)dbc->internal;
36
37	if ((ret = __db_lget(dbc, 0,
38	     hashp->meta_pgno, DB_LOCK_READ, 0, &hcp->hlock)) != 0)
39		return (ret);
40
41	if ((ret = __memp_fget(mpf, &hashp->meta_pgno,
42	    dbc->thread_info, dbc->txn, DB_MPOOL_CREATE, &hcp->hdr)) != 0)
43		(void)__LPUT(dbc, hcp->hlock);
44
45	return (ret);
46}
47
48/*
49 * Release the meta-data page.
50 *
51 * PUBLIC: int __ham_release_meta __P((DBC *));
52 */
53int
54__ham_release_meta(dbc)
55	DBC *dbc;
56{
57	DB_MPOOLFILE *mpf;
58	HASH_CURSOR *hcp;
59	int ret;
60
61	mpf = dbc->dbp->mpf;
62	hcp = (HASH_CURSOR *)dbc->internal;
63
64	if (hcp->hdr != NULL) {
65		if ((ret = __memp_fput(mpf,
66		    dbc->thread_info, hcp->hdr, dbc->priority)) != 0)
67			return (ret);
68		hcp->hdr = NULL;
69	}
70
71	return (__TLPUT(dbc, hcp->hlock));
72}
73
74/*
75 * Mark the meta-data page dirty.
76 *
77 * PUBLIC: int __ham_dirty_meta __P((DBC *, u_int32_t));
78 */
79int
80__ham_dirty_meta(dbc, flags)
81	DBC *dbc;
82	u_int32_t flags;
83{
84	DB_MPOOLFILE *mpf;
85	HASH *hashp;
86	HASH_CURSOR *hcp;
87	int ret;
88
89	if (F_ISSET(dbc, DBC_OPD))
90		dbc = dbc->internal->pdbc;
91	hashp = dbc->dbp->h_internal;
92	hcp = (HASH_CURSOR *)dbc->internal;
93	if (hcp->hlock.mode == DB_LOCK_WRITE)
94		return (0);
95
96	mpf = dbc->dbp->mpf;
97
98	if ((ret = __db_lget(dbc, LCK_COUPLE, hashp->meta_pgno,
99	     DB_LOCK_WRITE, DB_LOCK_NOWAIT, &hcp->hlock)) != 0) {
100		if (ret != DB_LOCK_NOTGRANTED && ret != DB_LOCK_DEADLOCK)
101			return (ret);
102		if ((ret = __memp_fput(mpf,
103		    dbc->thread_info, hcp->hdr, dbc->priority)) != 0)
104			return (ret);
105		hcp->hdr = NULL;
106		if ((ret = __db_lget(dbc, LCK_COUPLE, hashp->meta_pgno,
107		     DB_LOCK_WRITE, 0, &hcp->hlock)) != 0)
108			return (ret);
109		ret = __memp_fget(mpf, &hashp->meta_pgno,
110		    dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &hcp->hdr);
111		return (ret);
112	}
113
114	return (__memp_dirty(mpf,
115	    &hcp->hdr, dbc->thread_info, dbc->txn, dbc->priority, flags));
116}
117
118/*
119 * Return the meta data page if it is saved in the cursor.
120 *
121 * PUBLIC: int __ham_return_meta __P((DBC *, u_int32_t, DBMETA **));
122 */
123 int
124 __ham_return_meta(dbc, flags, metap)
125	DBC *dbc;
126	u_int32_t flags;
127	DBMETA **metap;
128{
129	HASH_CURSOR *hcp;
130	int ret;
131
132	*metap = NULL;
133	if (F_ISSET(dbc, DBC_OPD))
134		dbc = dbc->internal->pdbc;
135
136	hcp = (HASH_CURSOR *)dbc->internal;
137	if (hcp->hdr == NULL || PGNO(hcp->hdr) != PGNO_BASE_MD)
138		return (0);
139
140	if (LF_ISSET(DB_MPOOL_DIRTY) &&
141	    (ret = __ham_dirty_meta(dbc, flags)) != 0)
142		return (ret);
143
144	*metap = (DBMETA *)hcp->hdr;
145	return (0);
146}
147
148