IDZEBRA 2.2.8
bfile.c
Go to the documentation of this file.
1/* This file is part of the Zebra server.
2 Copyright (C) Index Data
3
4Zebra is free software; you can redistribute it and/or modify it under
5the terms of the GNU General Public License as published by the Free
6Software Foundation; either version 2, or (at your option) any later
7version.
8
9Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18*/
19
20#if HAVE_CONFIG_H
21#include <config.h>
22#endif
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <assert.h>
27#ifdef WIN32
28#include <io.h>
29#endif
30
31#if HAVE_UNISTD_H
32#include <unistd.h>
33#endif
34
35#include <yaz/xmalloc.h>
36#include <idzebra/util.h>
37#include <idzebra/bfile.h>
38#include "mfile.h"
39#include "cfile.h"
40
48
55
56BFiles bfs_create (const char *spec, const char *base)
57{
58 BFiles bfs = (BFiles) xmalloc(sizeof(*bfs));
59 bfs->commit_area = 0;
60 bfs->base = 0;
61 bfs->cache_fname = 0;
62 if (base)
63 bfs->base = xstrdup(base);
64 bfs->register_area = mf_init("register", spec, base, 0);
65 if (!bfs->register_area)
66 {
67 bfs_destroy(bfs);
68 return 0;
69 }
70 return bfs;
71}
72
74{
75 if (!bfs)
76 return;
77 xfree(bfs->cache_fname);
78 xfree(bfs->base);
81 xfree(bfs);
82}
83
84static FILE *open_cache(BFiles bfs, const char *flags)
85{
86 return fopen(bfs->cache_fname, flags);
87}
88
89static void unlink_cache(BFiles bfs)
90{
91 if (bfs->cache_fname)
92 unlink(bfs->cache_fname);
93}
94
95ZEBRA_RES bf_cache(BFiles bfs, const char *spec)
96{
97 if (spec)
98 {
99 yaz_log(YLOG_LOG, "enabling shadow spec=%s", spec);
100 if (!bfs->commit_area)
101 bfs->commit_area = mf_init("shadow", spec, bfs->base, 1);
102 if (bfs->commit_area)
103 {
104 bfs->cache_fname = xmalloc(strlen(bfs->commit_area->dirs->name)+
105 8);
106 strcpy(bfs->cache_fname, bfs->commit_area->dirs->name);
107 strcat(bfs->cache_fname, "/cache");
108 yaz_log(YLOG_LOG, "cache_fname = %s", bfs->cache_fname);
109 }
110 else
111 {
112 yaz_log(YLOG_WARN, "shadow could not be enabled");
113 return ZEBRA_FAIL;
114 }
115 }
116 else
117 bfs->commit_area = 0;
118 return ZEBRA_OK;
119}
120
122{
123 int ret = 0;
125 if (bf->cf)
126 {
127 if (cf_close(bf->cf))
128 ret = -1;
129 }
130 if (bf->mf)
131 {
132 if (mf_close(bf->mf))
133 ret = -1;
134 }
135 xfree(bf);
136 return ret;
137}
138
140{
141 if (bf_close2(bf))
142 {
143 zebra_exit("bf_close");
144 }
145}
146
147
148#define HEADER_SIZE 256
149
150BFile bf_open(BFiles bfs, const char *name, int block_size, int wflag)
151{
152 BFile bf = (BFile) xmalloc(sizeof(*bf));
153
154 bf->block_size = block_size;
155 bf->cf = 0;
156 bf->mf = 0;
158
159 if (bfs->commit_area)
160 {
161 int first_time;
162
163 bf->mf = mf_open(bfs->register_area, name, block_size, 0);
164 bf->cf = cf_open(bf->mf, bfs->commit_area, name, block_size,
165 wflag, &first_time);
166 if (!bf->cf)
167 {
168 yaz_log(YLOG_FATAL, "cf_open failed for %s", name);
169 bf_close(bf);
170 return 0;
171 }
172 if (first_time)
173 {
174 FILE *outf;
175
176 outf = open_cache(bfs, "ab");
177 if (!outf)
178 {
179 yaz_log(YLOG_FATAL|YLOG_ERRNO, "open %s", bfs->cache_fname);
180 bf_close(bf);
181 return 0;
182 }
183 fprintf(outf, "%s %d\n", name, block_size);
184 if (fclose(outf))
185 {
186 yaz_log(YLOG_FATAL|YLOG_ERRNO, "fclose %s", bfs->cache_fname);
187 bf_close(bf);
188 return 0;
189 }
190 }
191 }
192 else
193 {
194 bf->mf = mf_open(bfs->register_area, name, block_size, wflag);
195 }
196 if (!bf->mf)
197 {
198 yaz_log(YLOG_FATAL, "mf_open failed for %s", name);
199 bf_close(bf);
200 return 0;
201 }
202 return bf;
203}
204
205int bf_read(BFile bf, zint no, int offset, int nbytes, void *buf)
206{
207 int ret = bf_read2(bf, no, offset, nbytes, buf);
208
209 if (ret == -1)
210 {
211 zebra_exit("bf_read");
212 }
213 return ret;
214}
215
216int bf_read2(BFile bf, zint no, int offset, int nbytes, void *buf)
217{
218 int ret;
219
221 if (bf->cf)
222 {
223 if ((ret = cf_read(bf->cf, no, offset, nbytes, buf)) == 0)
224 ret = mf_read(bf->mf, no, offset, nbytes, buf);
225 }
226 else
227 ret = mf_read(bf->mf, no, offset, nbytes, buf);
229 return ret;
230}
231
232int bf_write(BFile bf, zint no, int offset, int nbytes, const void *buf)
233{
234 int ret = bf_write2(bf, no, offset, nbytes, buf);
235
236 if (ret == -1)
237 {
238 zebra_exit("bf_write");
239 }
240 return ret;
241}
242
243int bf_write2(BFile bf, zint no, int offset, int nbytes, const void *buf)
244{
245 int r;
247 if (bf->cf)
248 r = cf_write(bf->cf, no, offset, nbytes, buf);
249 else
250 r = mf_write(bf->mf, no, offset, nbytes, buf);
252 return r;
253}
254
256{
257 FILE *inf;
258
259 inf = open_cache(bfs, "rb");
260 if (inf)
261 {
262 fclose(inf);
263 return 1;
264 }
265 return 0;
266}
267
269{
270 if (!bfs)
271 return;
272 mf_reset(bfs->commit_area, 1);
273 mf_reset(bfs->register_area, 1);
274 unlink_cache(bfs);
275}
276
278{
279 FILE *inf;
280 int block_size;
281 char path[256];
282 MFile mf;
283 CFile cf;
284 int first_time;
285 int r = 0;
286
287 assert(bfs->commit_area);
288 if (!(inf = open_cache(bfs, "rb")))
289 {
290 yaz_log(YLOG_LOG, "No commit file");
291 return -1;
292 }
293 while (fscanf(inf, "%s %d", path, &block_size) == 2)
294 {
295 mf = mf_open(bfs->register_area, path, block_size, 1);
296 if (!mf)
297 {
298 r = -1;
299 break;
300 }
301 cf = cf_open(mf, bfs->commit_area, path, block_size, 0, &first_time);
302 if (!cf)
303 {
304 mf_close(mf);
305 r = -1;
306 break;
307 }
308
309 r = cf_commit(cf);
310
311 cf_close(cf);
312 mf_close(mf);
313
314 if (r)
315 break;
316 }
317 fclose(inf);
318 return r;
319}
320
321void bf_commitClean(BFiles bfs, const char *spec)
322{
323 int mustDisable = 0;
324
325 if (!bfs->commit_area)
326 {
327 bf_cache(bfs, spec);
328 mustDisable = 1;
329 }
330
331 mf_reset(bfs->commit_area, 1);
332
333 unlink_cache(bfs);
334 if (mustDisable)
335 bf_cache(bfs, 0);
336}
337
338int bfs_register_directory_stat(BFiles bfs, int no, const char **directory,
339 double *used_bytes, double *max_bytes)
340{
341 return mf_area_directory_stat(bfs->register_area, no, directory,
342 used_bytes, max_bytes);
343}
344
345
346int bfs_shadow_directory_stat(BFiles bfs, int no, const char **directory,
347 double *used_bytes, double *max_bytes)
348{
349 if (!bfs->commit_area)
350 return 0;
351 return mf_area_directory_stat(bfs->commit_area, no, directory,
352 used_bytes, max_bytes);
353}
354
355/* unimplemented functions not in use, but kept to ensure ABI */
356void bf_xclose(void) {}
357void bf_xopen(void) {}
358void bf_alloc(void) {}
359void bf_free(void) {}
360
361
362/*
363 * Local variables:
364 * c-basic-offset: 4
365 * c-file-style: "Stroustrup"
366 * indent-tabs-mode: nil
367 * End:
368 * vim: shiftwidth=4 tabstop=8 expandtab
369 */
370
int bf_write2(BFile bf, zint no, int offset, int nbytes, const void *buf)
writes block of bytes to file
Definition bfile.c:243
int bf_read(BFile bf, zint no, int offset, int nbytes, void *buf)
read from block file (may call exit)
Definition bfile.c:205
void bf_xopen(void)
Definition bfile.c:357
int bf_read2(BFile bf, zint no, int offset, int nbytes, void *buf)
read from block file
Definition bfile.c:216
ZEBRA_RES bf_cache(BFiles bfs, const char *spec)
enables or disables shadow for block files
Definition bfile.c:95
int bfs_register_directory_stat(BFiles bfs, int no, const char **directory, double *used_bytes, double *max_bytes)
Definition bfile.c:338
void bf_close(BFile bf)
closes a Block file (may call exit)
Definition bfile.c:139
BFile bf_open(BFiles bfs, const char *name, int block_size, int wflag)
opens and returns a Block file handle
Definition bfile.c:150
static FILE * open_cache(BFiles bfs, const char *flags)
Definition bfile.c:84
static void unlink_cache(BFiles bfs)
Definition bfile.c:89
void bf_alloc(void)
Definition bfile.c:358
int bf_write(BFile bf, zint no, int offset, int nbytes, const void *buf)
writes block of bytes to file (may call exit)
Definition bfile.c:232
void bf_reset(BFiles bfs)
Removes register and shadow completely.
Definition bfile.c:268
void bfs_destroy(BFiles bfs)
destroys a block files handle
Definition bfile.c:73
void bf_commitClean(BFiles bfs, const char *spec)
Cleans shadow files (remove them)
Definition bfile.c:321
int bf_close2(BFile bf)
closes a Block file
Definition bfile.c:121
void bf_xclose(void)
Definition bfile.c:356
int bfs_shadow_directory_stat(BFiles bfs, int no, const char **directory, double *used_bytes, double *max_bytes)
Definition bfile.c:346
BFiles bfs_create(const char *spec, const char *base)
creates a Block files collection
Definition bfile.c:56
int bf_commitExec(BFiles bfs)
Executes commit operation.
Definition bfile.c:277
int bf_commitExists(BFiles bfs)
Check if there is content in shadow area (to be committed).
Definition bfile.c:255
void bf_free(void)
Definition bfile.c:359
Zebra Block File Layer.
struct BFile_struct * BFile
A Block File.
Definition bfile.h:43
struct BFiles_struct * BFiles
A collection of BFile(s).
Definition bfile.h:38
CFile cf_open(MFile mf, MFile_area area, const char *fname, int block_size, int wflag, int *firstp)
Definition cfile.c:82
int cf_read(CFile cf, zint no, int offset, int nbytes, void *buf)
reads block from commit area
Definition cfile.c:542
int cf_write(CFile cf, zint no, int offset, int nbytes, const void *buf)
writes block to commit area
Definition cfile.c:579
int cf_close(CFile cf)
Definition cfile.c:616
int cf_commit(CFile cf) ZEBRA_GCC_ATTR((warn_unused_result))
Definition commit.c:257
int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf)
writes block to metafile
Definition mfile.c:486
int mf_area_directory_stat(MFile_area ma, int no, const char **directory, double *used_bytes, double *max_bytes)
metafile area statistics
Definition mfile.c:612
int mf_read(MFile mf, zint no, int offset, int nbytes, void *buf)
reads block from metafile
Definition mfile.c:453
void mf_reset(MFile_area ma, int unlink_flag)
reset all files in a metafile area (optionally delete them as well)
Definition mfile.c:326
void mf_destroy(MFile_area ma)
destroys metafile area handle
Definition mfile.c:309
MFile_area mf_init(const char *name, const char *spec, const char *base, int only_shadow_files)
creates a metafile area
Definition mfile.c:196
int mf_close(MFile mf)
closes metafile
Definition mfile.c:431
MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag)
opens metafile
Definition mfile.c:353
static FILE * outf
Definition readfile.c:38
static FILE * inf
Definition readfile.c:37
Zebra_lock_rdwr rdwr_lock
Definition bfile.c:44
int block_size
Definition bfile.c:46
MFile mf
Definition bfile.c:43
struct CFile_struct * cf
Definition bfile.c:45
char * cache_fname
Definition bfile.c:53
char * base
Definition bfile.c:52
MFile_area register_area
Definition bfile.c:51
MFile_area commit_area
Definition bfile.c:50
All in-memory information per CFile.
Definition cfile.h:69
mf_dir * dirs
Definition mfile.h:96
char name[FILENAME_MAX+1]
Definition mfile.h:57
long zint
Zebra integer.
Definition util.h:66
#define ZEBRA_FAIL
Definition util.h:81
void zebra_exit(const char *msg)
Definition exit.c:26
#define ZEBRA_OK
Definition util.h:82
short ZEBRA_RES
Common return type for Zebra API.
Definition util.h:80
int zebra_lock_rdwr_rlock(Zebra_lock_rdwr *p)
Definition zebra-lock.c:111
int zebra_lock_rdwr_wlock(Zebra_lock_rdwr *p)
Definition zebra-lock.c:123
int zebra_lock_rdwr_destroy(Zebra_lock_rdwr *p)
Definition zebra-lock.c:100
int zebra_lock_rdwr_wunlock(Zebra_lock_rdwr *p)
Definition zebra-lock.c:155
int zebra_lock_rdwr_runlock(Zebra_lock_rdwr *p)
Definition zebra-lock.c:135
int zebra_lock_rdwr_init(Zebra_lock_rdwr *p)
Definition zebra-lock.c:89