X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fbucket.c;h=abe97672246d1ac84da46b790f872744d9a5ea5f;hb=bf1a6d75a8dbd2999321a3d6e1a7be91adb804ea;hp=cac9419f382799f017d944b872e5727853ab4353;hpb=995458e48d482bd5fa349882fba5cb4d6350076d;p=libucw.git diff --git a/lib/bucket.c b/lib/bucket.c index cac9419f..abe97672 100644 --- a/lib/bucket.c +++ b/lib/bucket.c @@ -8,6 +8,7 @@ #include "lib/bucket.h" #include "lib/fastbuf.h" #include "lib/lfs.h" +#include "lib/conf.h" #include #include @@ -19,32 +20,69 @@ static unsigned int obuck_remains, obuck_check_pad; static struct fastbuf *obuck_fb; static struct obuck_header obuck_hdr; static sh_off_t bucket_start; -byte *obuck_name = "db/objects"; /* FIXME */ + +/*** Configuration ***/ + +byte *obuck_name = "not/configured"; +static int obuck_io_buflen = 65536; + +static struct cfitem obuck_config[] = { + { "Buckets", CT_SECTION, NULL }, + { "BucketFile", CT_STRING, &obuck_name }, + { "BufSize", CT_INT, &obuck_io_buflen }, + { NULL, CT_STOP, NULL } +}; + +static void CONSTRUCTOR obuck_init_config(void) +{ + cf_register(obuck_config); +} /*** Internal operations ***/ static void obuck_broken(char *msg) { - die("Object pool corrupted: %s (pos=%Lx)", msg, (long long) bucket_start); /* FIXME */ + die("Object pool corrupted: %s (pos=%Lx)", msg, (long long) bucket_start); +} + +/* + * Unfortunately we cannot use flock() here since it happily permits + * locking a shared fd (e.g., after fork()) multiple times. The fcntl + * locks are very ugly and they don't support 64-bit offsets, but we + * can work around the problem by always locking the first header + * in the file. + */ + +static inline void +obuck_do_lock(int type) +{ + struct flock fl; + + fl.l_type = type; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = sizeof(struct obuck_header); + if (fcntl(obuck_fd, F_SETLKW, &fl) < 0) + die("fcntl lock: %m"); } static inline void obuck_lock_read(void) { - flock(obuck_fd, LOCK_SH); + obuck_do_lock(F_RDLCK); } static inline void obuck_lock_write(void) { - flock(obuck_fd, LOCK_EX); + obuck_do_lock(F_WRLCK); } static inline void obuck_unlock(void) { - flock(obuck_fd, LOCK_UN); + obuck_do_lock(F_UNLCK); } /*** FastIO emulation ***/ @@ -111,15 +149,16 @@ void obuck_init(int writeable) { struct fastbuf *b; - int buflen = 65536; sh_off_t size; - obuck_fd = open(obuck_name, (writeable ? O_RDWR | O_CREAT : O_RDONLY), 0666); - obuck_fb = b = xmalloc_zero(sizeof(struct fastbuf) + buflen + OBUCK_ALIGN + 4); - b->buflen = buflen; + obuck_fd = sh_open(obuck_name, (writeable ? O_RDWR | O_CREAT : O_RDONLY), 0666); + if (obuck_fd < 0) + die("Unable to open bucket file %s: %m", obuck_name); + obuck_fb = b = xmalloc_zero(sizeof(struct fastbuf) + obuck_io_buflen + OBUCK_ALIGN + 4); + b->buflen = obuck_io_buflen; b->buffer = (char *)(b+1); b->bptr = b->bstop = b->buffer; - b->bufend = b->buffer + buflen; + b->bufend = b->buffer + obuck_io_buflen; b->name = "bucket"; b->fd = obuck_fd; b->refill = obuck_fb_refill; @@ -145,7 +184,7 @@ obuck_cleanup(void) bclose(obuck_fb); } -void /* FIXME: Call somewhere :) */ +void obuck_sync(void) { bflush(obuck_fb); @@ -280,17 +319,23 @@ obuck_delete(oid_t oid) #ifdef TEST -#define COUNT 100 +#define COUNT 5000 #define MAXLEN 10000 #define KILLPERC 13 #define LEN(i) ((259309*(i))%MAXLEN) -int main(void) +int main(int argc, char **argv) { int ids[COUNT]; unsigned int i, j, cnt; struct obuck_header h; struct fastbuf *b; + + log_init(NULL); + if (cf_getopt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) >= 0 || + optind < argc) + die("This program has no command-line arguments."); + unlink(obuck_name); obuck_init(1); for(j=0; j