X-Git-Url: http://git.indexdata.com/?p=idzebra-moved-to-github.git;a=blobdiff_plain;f=bfile%2Fmfile.c;h=674687afb0ad8f2bede38ae3728b56a933ab4c54;hp=9d8a3fbed5036f9693c42c245757f51b6f535e98;hb=a5c8c78e8671af863fc61b2ad8b24f92f827f7b2;hpb=91c31916bd40829afa20cd4e104ffc764ea116bf diff --git a/bfile/mfile.c b/bfile/mfile.c index 9d8a3fb..674687a 100644 --- a/bfile/mfile.c +++ b/bfile/mfile.c @@ -1,8 +1,5 @@ -/* $Id: mfile.c,v 1.70 2006-11-08 22:08:27 adam Exp $ - Copyright (C) 1995-2006 - Index Data ApS - -This file is part of the Zebra server. +/* This file is part of the Zebra server. + Copyright (C) 1994-2011 Index Data Zebra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -20,6 +17,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#if HAVE_CONFIG_H +#include +#endif #include #include #ifdef WIN32 @@ -192,13 +192,8 @@ static int cmp_part_file(const void *p1, const void *p2) return 0; } -/** \brief creates a metafile area - \param name of area (does not show up on disk - purely for notation) - \param spec area specification (e.g. "/a:1G dir /b:2000M" - \param base base directory (NULL for no base) - \returns metafile area handle or NULL if error occurs -*/ -MFile_area mf_init(const char *name, const char *spec, const char *base) +MFile_area mf_init(const char *name, const char *spec, const char *base, + int only_shadow_files) { MFile_area ma = (MFile_area) xmalloc(sizeof(*ma)); mf_dir *dirp; @@ -216,6 +211,7 @@ MFile_area mf_init(const char *name, const char *spec, const char *base) if (scan_areadef(ma, spec, base) < 0) { yaz_log(YLOG_WARN, "Failed to access description of '%s'", name); + mf_destroy(ma); return 0; } /* look at each directory */ @@ -224,7 +220,8 @@ MFile_area mf_init(const char *name, const char *spec, const char *base) if (!(dd = opendir(dirp->name))) { yaz_log(YLOG_WARN|YLOG_ERRNO, "Failed to open directory %s", - dirp->name); + dirp->name); + mf_destroy(ma); return 0; } /* look at each file */ @@ -240,6 +237,11 @@ MFile_area mf_init(const char *name, const char *spec, const char *base) memcpy(metaname, dent->d_name, cp - dent->d_name); metaname[ cp - dent->d_name] = '\0'; + /* only files such as file-i-0.mf and file-i-b-0.mf, bug #739 */ + if (only_shadow_files && cp[-2] != '-') + continue; + if (!only_shadow_files && cp[-2] == '-') + continue; for (meta_f = ma->mfiles; meta_f; meta_f = meta_f->next) { /* known metafile */ @@ -273,17 +275,19 @@ MFile_area mf_init(const char *name, const char *spec, const char *base) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to access %s", dent->d_name); + closedir(dd); + mf_destroy(ma); return 0; } if ((part_f->bytes = mfile_seek(fd, 0, SEEK_END)) < 0) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to seek in %s", dent->d_name); + close(fd); + closedir(dd); + mf_destroy(ma); return 0; } -#ifndef WIN32 - fsync(fd); -#endif close(fd); if (dirp->max_bytes >= 0) dirp->avail_bytes -= part_f->bytes; @@ -300,9 +304,6 @@ MFile_area mf_init(const char *name, const char *spec, const char *base) return ma; } -/** \brief destroys metafile area handle - \param ma metafile area handle -*/ void mf_destroy(MFile_area ma) { mf_dir *dp; @@ -320,10 +321,6 @@ void mf_destroy(MFile_area ma) xfree(ma); } -/** \brief reset all files in a metafile area (optionally delete them as well) - \param ma metafile area - \param unlink_flag if unlink_flag=1 all files are removed from FS -*/ void mf_reset(MFile_area ma, int unlink_flag) { meta_file *meta_f; @@ -351,13 +348,6 @@ void mf_reset(MFile_area ma, int unlink_flag) ma->mfiles = 0; } -/** \brief opens metafile - \param ma metafile area handle - \param name pseudo filename (name*.mf) - \param block_size block size for this file - \param wflag write flag, 0=read, 1=write&read - \returns metafile handle, or NULL for error (could not be opened) - */ MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag) { meta_file *mnew; @@ -376,6 +366,7 @@ MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag) yaz_log(YLOG_WARN, "metafile %s already open", name); return 0; } + break; } if (!mnew) { @@ -394,7 +385,8 @@ MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag) mnew->min_bytes_creat; dp = dp->next); if (!dp) { - yaz_log(YLOG_FATAL, "Insufficient space for new mfile."); + yaz_log(YLOG_FATAL, "Insufficient space for file %s", name); + xfree(mnew); return 0; } mnew->files[0].dir = dp; @@ -434,10 +426,6 @@ MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag) return mnew; } -/** \brief closes metafile - \param mf metafile handle - \retval 0 OK -*/ int mf_close(MFile mf) { int i; @@ -449,7 +437,8 @@ int mf_close(MFile mf) if (mf->files[i].fd >= 0) { #ifndef WIN32 - fsync(mf->files[i].fd); + if (mf->wr) + fsync(mf->files[i].fd); #endif close(mf->files[i].fd); mf->files[i].fd = -1; @@ -459,16 +448,6 @@ int mf_close(MFile mf) return 0; } -/** \brief reads block from metafile - \param mf metafile handle - \param no block position - \param offset offset within block - \param nbytes no of bytes to read (0 for whole block) - \param buf content (filled with data if OK) - \retval 0 block partially read - \retval 1 block fully read - \retval -1 block could not be read due to error - */ int mf_read(MFile mf, zint no, int offset, int nbytes, void *buf) { zint rd; @@ -502,18 +481,9 @@ int mf_read(MFile mf, zint no, int offset, int nbytes, void *buf) return 1; } - -/** \brief writes block to metafile - \param mf metafile handle - \param no block position - \param offset offset within block - \param nbytes no of bytes to write (0 for whole block) - \param buf content to be written - \retval 0 block written - \retval -1 error (block not written) - */ int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) { + int ret = 0; zint ps; zint nblocks; int towrite; @@ -524,8 +494,9 @@ int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) zebra_mutex_lock(&mf->mutex); if ((ps = file_position(mf, no, offset)) < 0) { - yaz_log(YLOG_FATAL, "mf_write %s internal error (1)", mf->name); - return -1; + yaz_log(YLOG_FATAL, "mf_write: %s error (1)", mf->name); + ret = -1; + goto out; } /* file needs to grow */ while (ps >= mf->files[mf->cur_file].blocks) @@ -546,16 +517,18 @@ int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) (mf->cur_file ? mf->files[mf->cur_file-1].top : 0) + mf->files[mf->cur_file].blocks + nblocks - 1, 0)) < 0) { - yaz_log(YLOG_FATAL, "mf_write %s internal error (2)", + yaz_log(YLOG_FATAL, "mf_write: %s error (2)", mf->name); - return -1; + ret = -1; + goto out; } yaz_log(YLOG_DEBUG, "ps = " ZINT_FORMAT, ps); if (write(mf->files[mf->cur_file].fd, &dummych, 1) < 1) { - yaz_log(YLOG_ERRNO|YLOG_FATAL, "mf_write %s internal error (3)", + yaz_log(YLOG_ERRNO|YLOG_FATAL, "mf_write: %s error (3)", mf->name); - return -1; + ret = -1; + goto out; } mf->files[mf->cur_file].blocks += nblocks; mf->files[mf->cur_file].bytes += nblocks * mf->blocksize; @@ -568,12 +541,20 @@ int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) dp->avail_bytes < needed; dp = dp->next); if (!dp) { - yaz_log(YLOG_FATAL, "Cannot allocate more space for %s", - mf->name); - return -1; + yaz_log(YLOG_FATAL, "mf_write: %s error (4) no more space", + mf->name); + for (dp = mf->ma->dirs; dp ; dp = dp->next) { + yaz_log(YLOG_FATAL,"%s: max=" ZINT_FORMAT + " used=" ZINT_FORMAT " available=" ZINT_FORMAT, + dp->name, (zint)dp->max_bytes, + (zint)(dp->max_bytes - dp->avail_bytes), (zint)dp->avail_bytes ); + } + yaz_log(YLOG_FATAL,"Adjust the limits in your zebra.cfg"); + ret = -1; + goto out; } mf->files[mf->cur_file].top = (mf->cur_file ? - mf->files[mf->cur_file-1].top : -1) + + mf->files[mf->cur_file-1].top : -1) + mf->files[mf->cur_file].blocks; mf->files[++(mf->cur_file)].top = -1; mf->files[mf->cur_file].dir = dp; @@ -589,9 +570,9 @@ int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) /* open new file and position at beginning */ if ((ps = file_position(mf, no, offset)) < 0) { - yaz_log(YLOG_FATAL, "mf_write %s internal error (4)", - mf->name); - return -1; + yaz_log(YLOG_FATAL, "mf_write: %s error (5)", mf->name); + ret = -1; + goto out; } } else @@ -609,10 +590,11 @@ int mf_write(MFile mf, zint no, int offset, int nbytes, const void *buf) { yaz_log(YLOG_FATAL|YLOG_ERRNO, "Write failed for file %s part %d", mf->name, mf->cur_file); - return -1; + ret = -1; } + out: zebra_mutex_unlock(&mf->mutex); - return 0; + return ret; } /** \brief metafile area statistics @@ -650,6 +632,7 @@ int mf_area_directory_stat(MFile_area ma, int no, const char **directory, /* * Local variables: * c-basic-offset: 4 + * c-file-style: "Stroustrup" * indent-tabs-mode: nil * End: * vim: shiftwidth=4 tabstop=8 expandtab