]> sourceware.org Git - glibc.git/blob - db2/log/log_register.c
Update.
[glibc.git] / db2 / log / log_register.c
1 /*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1996, 1997
5 * Sleepycat Software. All rights reserved.
6 */
7 #include "config.h"
8
9 #ifndef lint
10 static const char sccsid[] = "@(#)log_register.c 10.12 (Sleepycat) 9/29/97";
11 #endif /* not lint */
12
13 #ifndef NO_SYSTEM_INCLUDES
14 #include <sys/types.h>
15
16 #include <errno.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #endif
20
21 #include "db_int.h"
22 #include "shqueue.h"
23 #include "log.h"
24 #include "common_ext.h"
25
26 /*
27 * log_register --
28 * Register a file name.
29 */
30 int
31 log_register(dblp, dbp, name, type, idp)
32 DB_LOG *dblp;
33 DB *dbp;
34 const char *name;
35 DBTYPE type;
36 u_int32_t *idp;
37 {
38 DBT r_name;
39 DBT fid_dbt;
40 DB_LSN r_unused;
41 FNAME *fnp;
42 size_t len;
43 u_int32_t fid;
44 int inserted, ret;
45 char *fullname;
46 void *fidp, *namep;
47
48 fid = 0;
49 inserted = 0;
50 fullname = NULL;
51 fnp = fidp = namep = NULL;
52
53 /* Check the arguments. */
54 if (type != DB_BTREE && type != DB_HASH && type != DB_RECNO) {
55 __db_err(dblp->dbenv, "log_register: unknown DB file type");
56 return (EINVAL);
57 }
58
59 /* Get the log file id. */
60 if ((ret = __db_appname(dblp->dbenv,
61 DB_APP_DATA, NULL, name, NULL, &fullname)) != 0)
62 return (ret);
63
64 LOCK_LOGREGION(dblp);
65
66 /*
67 * See if we've already got this file in the log, finding the
68 * next-to-lowest file id currently in use as we do it.
69 */
70 for (fid = 1, fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
71 fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) {
72 if (fid <= fnp->id)
73 fid = fnp->id + 1;
74 if (!memcmp(dbp->lock.fileid,
75 R_ADDR(dblp, fnp->fileid_off), DB_FILE_ID_LEN)) {
76 ++fnp->ref;
77 fid = fnp->id;
78 if (!F_ISSET(dblp, DB_AM_RECOVER) &&
79 (ret = __log_add_logid(dblp, dbp, fid) != 0))
80 goto err;
81 goto ret1;
82 }
83 }
84
85 /* Allocate a new file name structure. */
86 if ((ret = __db_shalloc(dblp->addr, sizeof(FNAME), 0, &fnp)) != 0)
87 goto err;
88 fnp->ref = 1;
89 fnp->id = fid;
90 fnp->s_type = type;
91
92 if ((ret = __db_shalloc(dblp->addr, DB_FILE_ID_LEN, 0, &fidp)) != 0)
93 goto err;
94 /*
95 * XXX Now that uids are fixed size, we can put them in the fnp
96 * structure.
97 */
98 fnp->fileid_off = R_OFFSET(dblp, fidp);
99 memcpy(fidp, dbp->lock.fileid, DB_FILE_ID_LEN);
100
101 len = strlen(name) + 1;
102 if ((ret = __db_shalloc(dblp->addr, len, 0, &namep)) != 0)
103 goto err;
104 fnp->name_off = R_OFFSET(dblp, namep);
105 memcpy(namep, name, len);
106
107 SH_TAILQ_INSERT_HEAD(&dblp->lp->fq, fnp, q, __fname);
108 inserted = 1;
109
110 /* Log the registry. */
111 if (!F_ISSET(dblp, DB_AM_RECOVER)) {
112 r_name.data = (void *)name; /* XXX: Yuck! */
113 r_name.size = strlen(name) + 1;
114 memset(&fid_dbt, 0, sizeof(fid_dbt));
115 fid_dbt.data = dbp->lock.fileid;
116 fid_dbt.size = DB_FILE_ID_LEN;
117 if ((ret = __log_register_log(dblp, NULL, &r_unused,
118 0, &r_name, &fid_dbt, fid, type)) != 0)
119 goto err;
120 if ((ret = __log_add_logid(dblp, dbp, fid)) != 0)
121 goto err;
122 }
123
124 if (0) {
125 err: /*
126 * XXX
127 * We should grow the region.
128 */
129 if (inserted)
130 SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname);
131 if (namep != NULL)
132 __db_shalloc_free(dblp->addr, namep);
133 if (fidp != NULL)
134 __db_shalloc_free(dblp->addr, fidp);
135 if (fnp != NULL)
136 __db_shalloc_free(dblp->addr, fnp);
137 }
138
139 ret1: UNLOCK_LOGREGION(dblp);
140
141 if (fullname != NULL)
142 FREES(fullname);
143
144 if (idp != NULL)
145 *idp = fid;
146 return (ret);
147 }
148
149 /*
150 * log_unregister --
151 * Discard a registered file name.
152 */
153 int
154 log_unregister(dblp, fid)
155 DB_LOG *dblp;
156 u_int32_t fid;
157 {
158 DB_LSN r_unused;
159 FNAME *fnp;
160 int ret;
161
162 ret = 0;
163 LOCK_LOGREGION(dblp);
164
165 /* Unlog the registry. */
166 if (!F_ISSET(dblp, DB_AM_RECOVER) &&
167 (ret = __log_unregister_log(dblp, NULL, &r_unused, 0, fid)) != 0)
168 return (ret);
169
170 /* Find the entry in the log. */
171 for (fnp = SH_TAILQ_FIRST(&dblp->lp->fq, __fname);
172 fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname))
173 if (fid == fnp->id)
174 break;
175 if (fnp == NULL) {
176 __db_err(dblp->dbenv, "log_unregister: non-existent file id");
177 ret = EINVAL;
178 goto ret1;
179 }
180
181 /* If more than 1 reference, decrement the reference and return. */
182 if (fnp->ref > 1) {
183 --fnp->ref;
184 goto ret1;
185 }
186
187 /* Free the unique file information, name and structure. */
188 __db_shalloc_free(dblp->addr, R_ADDR(dblp, fnp->fileid_off));
189 __db_shalloc_free(dblp->addr, R_ADDR(dblp, fnp->name_off));
190 SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname);
191 __db_shalloc_free(dblp->addr, fnp);
192
193 /*
194 * Remove from the process local table. If this operation is taking
195 * place during recovery, then the logid was never added to the table,
196 * so do not remove it.
197 */
198 if (!F_ISSET(dblp, DB_AM_RECOVER))
199 __log_rem_logid(dblp, fid);
200
201 ret1: UNLOCK_LOGREGION(dblp);
202
203 return (ret);
204 }
This page took 0.046549 seconds and 5 git commands to generate.