23 #include <sys/types.h>
40 #include <yaz/yaz-util.h>
41 #include <yaz/snprintf.h>
57 int i = 0, fact = 1, multi;
60 while (*ad ==
' ' || *ad ==
'\t')
64 if (!yaz_is_abspath(ad) && base)
66 strcpy(dirname, base);
72 if (*ad ==
':' && strchr(
"+-0123456789", ad[1]))
81 yaz_log(YLOG_WARN,
"Missing colon after path: %s", ad0);
86 yaz_log(YLOG_WARN,
"Empty path: %s", ad0);
89 while (*ad ==
' ' || *ad ==
'\t')
99 if (*ad < '0' || *ad >
'9')
101 yaz_log(YLOG_FATAL,
"Missing size after path: %s", ad0);
105 while (*ad >=
'0' && *ad <=
'9')
106 size = size*10 + (*ad++ -
'0');
109 case 'B':
case 'b': multi = 1;
break;
110 case 'K':
case 'k': multi = 1024;
break;
111 case 'M':
case 'm': multi = 1048576;
break;
112 case 'G':
case 'g': multi = 1073741824;
break;
114 yaz_log(YLOG_FATAL,
"Missing unit: %s", ad0);
117 yaz_log(YLOG_FATAL,
"Illegal unit: %c in %s", *ad, ad0);
123 strcpy(dir->name, dirname);
124 dir->max_bytes = dir->avail_bytes = fact * size * multi;
144 if ((c > 0 && pos <= mf->files[c-1].top) ||
145 (c < mf->no_files -1 && pos > mf->
files[c].
top))
153 assert(c < mf->no_files);
156 off = c ? (mf->
files[c-1].
top + 1) : 0;
164 if (!mf->
wr && errno == ENOENT && off == 0)
169 yaz_log(YLOG_WARN|YLOG_ERRNO,
"Failed to open %s", mf->
files[c].
path);
177 yaz_log(YLOG_WARN|YLOG_ERRNO,
"Failed to seek in %s", mf->
files[c].
path);
197 int only_shadow_files)
208 yaz_log(YLOG_DEBUG,
"mf_init(%s)", name);
209 strcpy(ma->
name, name);
214 yaz_log(YLOG_WARN,
"Failed to access description of '%s'", name);
219 for (dirp = ma->
dirs; dirp; dirp = dirp->
next)
221 if (!(dd = opendir(dirp->
name)))
223 yaz_log(YLOG_WARN|YLOG_ERRNO,
"Failed to open directory %s",
229 while ((dent = readdir(dd)))
231 int len = strlen(dent->d_name);
232 const char *cp = strrchr(dent->d_name,
'-');
233 if (strchr(
".-", *dent->d_name))
235 if (len < 5 || !cp || strcmp(dent->d_name + len - 3,
".mf"))
238 memcpy(metaname, dent->d_name, cp - dent->d_name);
239 metaname[ cp - dent->d_name] =
'\0';
242 if (only_shadow_files && cp[-2] !=
'-')
244 if (!only_shadow_files && cp[-2] ==
'-')
246 for (meta_f = ma->
mfiles; meta_f; meta_f = meta_f->
next)
249 if (!strcmp(meta_f->
name, metaname))
258 meta_f = (
meta_file *) xmalloc(
sizeof(*meta_f));
265 strcpy(meta_f->
name, metaname);
266 part_f = &meta_f->
files[0];
273 "%s/%s", dirp->
name, dent->d_name);
274 part_f->
path = xstrdup(tmpnam);
278 yaz_log(YLOG_FATAL|YLOG_ERRNO,
"Failed to access %s",
286 yaz_log(YLOG_FATAL|YLOG_ERRNO,
"Failed to seek in %s",
299 for (meta_f = ma->
mfiles; meta_f; meta_f = meta_f->
next)
301 yaz_log(YLOG_DEBUG,
"mf_init: %s consists of %d part(s)", meta_f->
name,
338 meta_f = meta_f->
next;
360 yaz_log(YLOG_DEBUG,
"mf_open(%s bs=%d, %s)", name, block_size,
361 wflag ?
"RW" :
"RDONLY");
363 for (mnew = ma->
mfiles; mnew; mnew = mnew->
next)
364 if (!strcmp(name, mnew->
name))
368 yaz_log(YLOG_WARN,
"metafile %s already open", name);
375 mnew = (
meta_file *) xmalloc(
sizeof(*mnew));
376 strcpy(mnew->
name, name);
390 yaz_log(YLOG_FATAL,
"Insufficient space for file %s", name);
403 for (i = 0; i < mnew->
no_files; i++)
418 for (i = 0; i < mnew->
no_files; i++)
435 yaz_log(YLOG_DEBUG,
"mf_close(%s)", mf->
name);
468 yaz_log(YLOG_FATAL,
"mf_read2 %s internal error", mf->
name);
472 toread = nbytes ? nbytes : mf->
blocksize;
475 yaz_log(YLOG_FATAL|YLOG_ERRNO,
"mf_read2: Read failed (%s)",
494 unsigned char dummych =
'\xff';
499 yaz_log(YLOG_FATAL,
"mf_write: %s error (1)", mf->
name);
516 yaz_log(YLOG_DEBUG,
"Capping off file %s at pos " ZINT_FORMAT,
522 yaz_log(YLOG_FATAL,
"mf_write: %s error (2)",
530 yaz_log(YLOG_ERRNO|YLOG_FATAL,
"mf_write: %s error (3)",
541 yaz_log(YLOG_DEBUG,
"Creating new file.");
546 yaz_log(YLOG_FATAL,
"mf_write: %s error (4) no more space",
554 yaz_log(YLOG_FATAL,
"Adjust the limits in your zebra.cfg");
576 yaz_log(YLOG_FATAL,
"mf_write: %s error (5)", mf->
name);
591 towrite = nbytes ? nbytes : mf->
blocksize;
594 yaz_log(YLOG_FATAL|YLOG_ERRNO,
"Write failed for file %s part %d",
613 double *used_bytes,
double *max_bytes)
617 for (i = 0; d && i<no; i++, d = d->
next)
622 *directory = d->
name;
static int cmp_part_file(const void *p1, const void *p2)
int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf)
writes block to metafile
int mf_area_directory_stat(MFile_area ma, int no, const char **directory, double *used_bytes, double *max_bytes)
metafile area statistics
static zint file_position(MFile mf, zint pos, int offset)
position within metafile (perform seek)
int mf_read(MFile mf, zint no, int offset, int nbytes, void *buf)
reads block from metafile
void mf_reset(MFile_area ma, int unlink_flag)
reset all files in a metafile area (optionally delete them as well)
void mf_destroy(MFile_area ma)
destroys metafile area handle
MFile_area mf_init(const char *name, const char *spec, const char *base, int only_shadow_files)
creates a metafile area
int mf_close(MFile mf)
closes metafile
MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag)
opens metafile
static int scan_areadef(MFile_area ma, const char *ad, const char *base)
#define MF_MIN_BLOCKS_CREAT
struct MFile_area_struct * MFile_area
struct meta_file * mfiles
char name[FILENAME_MAX+1]
char name[FILENAME_MAX+1]
int zebra_mutex_unlock(Zebra_mutex *p)
int zebra_mutex_init(Zebra_mutex *p)
int zebra_mutex_lock(Zebra_mutex *p)
int zebra_mutex_destroy(Zebra_mutex *p)