Update.
[glibc.git] / db2 / log / log_register.c
bloba6fc4c1b3b52ba5bb14919cf292c1b9f50670eb1
1 /*-
2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 1996, 1997, 1998
5 * Sleepycat Software. All rights reserved.
6 */
7 #include "config.h"
9 #ifndef lint
10 static const char sccsid[] = "@(#)log_register.c 10.18 (Sleepycat) 5/3/98";
11 #endif /* not lint */
13 #ifndef NO_SYSTEM_INCLUDES
14 #include <sys/types.h>
16 #include <errno.h>
17 #include <string.h>
18 #endif
20 #include "db_int.h"
21 #include "shqueue.h"
22 #include "log.h"
23 #include "common_ext.h"
26 * log_register --
27 * Register a file name.
29 int
30 log_register(dblp, dbp, name, type, idp)
31 DB_LOG *dblp;
32 DB *dbp;
33 const char *name;
34 DBTYPE type;
35 u_int32_t *idp;
37 DBT fid_dbt, r_name;
38 DB_LSN r_unused;
39 FNAME *fnp;
40 size_t len;
41 u_int32_t fid;
42 int inserted, ret;
43 char *fullname;
44 void *namep;
46 fid = 0;
47 inserted = 0;
48 fullname = NULL;
49 fnp = namep = NULL;
51 /* Check the arguments. */
52 if (type != DB_BTREE && type != DB_HASH && type != DB_RECNO) {
53 __db_err(dblp->dbenv, "log_register: unknown DB file type");
54 return (EINVAL);
57 /* Get the log file id. */
58 if ((ret = __db_appname(dblp->dbenv,
59 DB_APP_DATA, NULL, name, 0, NULL, &fullname)) != 0)
60 return (ret);
62 LOCK_LOGREGION(dblp);
65 * See if we've already got this file in the log, finding the
66 * next-to-lowest file id currently in use as we do it.
68 for (fid = 1, fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
69 fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
70 if (fid <= fnp->id)
71 fid = fnp->id + 1;
72 if (!memcmp(dbp->lock.fileid, fnp->ufid, DB_FILE_ID_LEN)) {
73 ++fnp->ref;
74 fid = fnp->id;
75 goto found;
79 /* Allocate a new file name structure. */
80 if ((ret = __db_shalloc(dblp->addr, sizeof(FNAME), 0, &fnp)) != 0)
81 goto err;
82 fnp->ref = 1;
83 fnp->id = fid;
84 fnp->s_type = type;
85 memcpy(fnp->ufid, dbp->lock.fileid, DB_FILE_ID_LEN);
87 len = strlen(name) + 1;
88 if ((ret = __db_shalloc(dblp->addr, len, 0, &namep)) != 0)
89 goto err;
90 fnp->name_off = R_OFFSET(dblp, namep);
91 memcpy(namep, name, len);
93 SH_TAILQ_INSERT_HEAD(&dblp->lp->fq, fnp, q, __fname);
94 inserted = 1;
96 found: /* Log the registry. */
97 if (!F_ISSET(dblp, DB_AM_RECOVER)) {
98 r_name.data = (void *)name; /* XXX: Yuck! */
99 r_name.size = strlen(name) + 1;
100 memset(&fid_dbt, 0, sizeof(fid_dbt));
101 fid_dbt.data = dbp->lock.fileid;
102 fid_dbt.size = DB_FILE_ID_LEN;
103 if ((ret = __log_register_log(dblp, NULL, &r_unused,
104 0, LOG_OPEN, &r_name, &fid_dbt, fid, type)) != 0)
105 goto err;
106 if ((ret = __log_add_logid(dblp, dbp, fid)) != 0)
107 goto err;
110 if (0) {
111 err: /*
112 * XXX
113 * We should grow the region.
115 if (inserted)
116 SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname);
117 if (namep != NULL)
118 __db_shalloc_free(dblp->addr, namep);
119 if (fnp != NULL)
120 __db_shalloc_free(dblp->addr, fnp);
123 UNLOCK_LOGREGION(dblp);
125 if (fullname != NULL)
126 FREES(fullname);
128 if (idp != NULL)
129 *idp = fid;
130 return (ret);
134 * log_unregister --
135 * Discard a registered file name.
138 log_unregister(dblp, fid)
139 DB_LOG *dblp;
140 u_int32_t fid;
142 DBT fid_dbt, r_name;
143 DB_LSN r_unused;
144 FNAME *fnp;
145 int ret;
147 ret = 0;
148 LOCK_LOGREGION(dblp);
150 /* Find the entry in the log. */
151 for (fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
152 fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname))
153 if (fid == fnp->id)
154 break;
155 if (fnp == NULL) {
156 __db_err(dblp->dbenv, "log_unregister: non-existent file id");
157 ret = EINVAL;
158 goto ret1;
161 /* Unlog the registry. */
162 if (!F_ISSET(dblp, DB_AM_RECOVER)) {
163 memset(&r_name, 0, sizeof(r_name));
164 r_name.data = R_ADDR(dblp, fnp->name_off);
165 r_name.size = strlen(r_name.data) + 1;
166 memset(&fid_dbt, 0, sizeof(fid_dbt));
167 fid_dbt.data = fnp->ufid;
168 fid_dbt.size = DB_FILE_ID_LEN;
169 if ((ret = __log_register_log(dblp, NULL, &r_unused,
170 0, LOG_CLOSE, &r_name, &fid_dbt, fid, fnp->s_type)) != 0)
171 goto ret1;
175 * If more than 1 reference, just decrement the reference and return.
176 * Otherwise, free the unique file information, name and structure.
178 if (fnp->ref > 1)
179 --fnp->ref;
180 else {
181 __db_shalloc_free(dblp->addr, R_ADDR(dblp, fnp->name_off));
182 SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname);
183 __db_shalloc_free(dblp->addr, fnp);
187 * Remove from the process local table. If this operation is taking
188 * place during recovery, then the logid was never added to the table,
189 * so do not remove it.
191 if (!F_ISSET(dblp, DB_AM_RECOVER))
192 __log_rem_logid(dblp, fid);
194 ret1: UNLOCK_LOGREGION(dblp);
195 return (ret);