From f3a6320642df9a8b0c20081f4fff17e7210105a6 Mon Sep 17 00:00:00 2001 From: Dan Sheppard Date: Wed, 23 Apr 2025 17:28:28 +0100 Subject: [PATCH] Start of main section file save/load. --- .vscode/settings.json | 3 +- Makefile | 2 +- src/constants.h | 18 +++--- src/coquet.c | 118 +++++++++++++++++++++++++++++++++-- src/coquet.h | 30 ++++++++- src/main.c | 4 +- src/page.c | 142 ++++++++++++++++++++++++++++++++++++++++++ src/page.h | 20 ++++++ src/superblock.c | 37 ++++++----- src/superblock.h | 4 +- src/test.c | 2 + src/testvfs.c | 4 +- src/unix.c | 19 +++--- src/vfs.h | 2 +- 14 files changed, 353 insertions(+), 52 deletions(-) create mode 100644 src/page.c create mode 100644 src/page.h diff --git a/.vscode/settings.json b/.vscode/settings.json index b05135a..73c8923 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,7 +9,8 @@ ], "files.associations": { "coquet.h": "c", - "superblock.h": "c" + "superblock.h": "c", + "page.h": "c" }, "C_Cpp.dimInactiveRegions": false } \ No newline at end of file diff --git a/Makefile b/Makefile index 63f8bb7..737216c 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ BINDIR := bin OBJDIR := obj/main TESTOBJDIR := obj/test -SRCFILES := unix.c util.c coquet.c superblock.c sha2.c testvfs.c +SRCFILES := unix.c util.c coquet.c superblock.c sha2.c testvfs.c page.c SRC := $(addprefix $(SRCDIR)/,$(SRCFILES)) diff --git a/src/constants.h b/src/constants.h index 55e4e7d..3b8e13e 100644 --- a/src/constants.h +++ b/src/constants.h @@ -13,14 +13,16 @@ #define COQUET_FILE_NUM 3 /* remember to update messages */ -#define COQUET_RET_OK 0 -#define COQUET_RET_VFSERR 1 -#define COQUET_RET_HEAPERR 2 -#define COQUET_RET_LOCKED 3 -#define COQUET_RET_CORRUPT 4 -#define COQUET_RET_EXISTS 5 -#define COQUET_UNUSED_ERROR 6 -#define COQUET_LAST_ERROR 6 +#define COQUET_RET_OK 0 +#define COQUET_RET_VFSERR 1 +#define COQUET_RET_HEAPERR 2 +#define COQUET_RET_LOCKED 3 +#define COQUET_RET_CORRUPT 4 +#define COQUET_RET_EXISTS 5 +#define COQUET_RET_TRSMERROR 6 +#define COQUET_RET_BADARGS 7 +#define COQUET_UNUSED_ERROR 8 +#define COQUET_LAST_ERROR 8 #define COQUET_CMODE_OPEN 0 #define COQUET_CMODE_CREATE 1 diff --git a/src/coquet.c b/src/coquet.c index aa3e3c5..6e91682 100644 --- a/src/coquet.c +++ b/src/coquet.c @@ -5,6 +5,7 @@ #include "coquet.h" #include "util.h" #include "vfs.h" +#include "page.h" /* VFS null is used as a placeholder prior to initialisation, so that * subsequent tidies can be clean. @@ -48,12 +49,16 @@ static int testvfs_wrap(coquet_t *cq) { } #endif +static void choose_vfs(coquet_t *cq) { + cq->vfs_funcs = vfs_unix; + cq->vfs_data = unix_make(); +} + /* Allocate and initialise vfs layer. */ static int init_vfs(coquet_t *cq, char *basename) { int r; - cq->vfs_funcs = vfs_unix; - cq->vfs_data = unix_make(); + choose_vfs(cq); if(cq->vfs_data == NULL) { cq->vfs_funcs = vfs_null; return COQUET_RET_HEAPERR; @@ -81,9 +86,14 @@ static int init_vfs(coquet_t *cq, char *basename) { * content. */ int coquet_init(coquet_t *cq, char * basename) { - int r; + int i,r; r = init_vfs(cq,basename); + cq->flags = 0; + for(i=0;ifilemeta[i].which_file = i; + } + if(r != COQUET_RET_OK) { return r; } @@ -110,8 +120,9 @@ char * error_strings[COQUET_UNUSED_ERROR+1] = { /* COQUET_RET_LOCKED */ "Locked", /* COQUET_RET_CORRUPT */ "File corrupt", /* COQUET_RET_EXISTS */ "File already exists", + /* COQUET_RET_TRSMERROR */"Transaction state machine error", + /* COQUET_RET_BADARGS */ "Internal error: bad arguments", /* COQUET_UNUSED_ERROR */ "No such error code", - }; /* Return error string for most recent error. Returned string is owned by @@ -127,3 +138,102 @@ char * coquet_error_string(coquet_t *cq, int error) { return strdup(error_strings[error]); } } + +/* find last block */ +/* TODO: this is not correct, but we can't do it correclty yet! */ +static int find_last_main_block(coquet_t *cq, struct cq_filemeta *fm) { + int r; + off_t offset; + int64_t main_size; + + r = (cq->vfs_funcs.size)(cq->vfs_data,fm->which_file,&offset); + if(r != COQUET_RET_OK) { + return r; + } + + /* subtract header */ + main_size = offset - cq_offset_main_page(cq,fm->which_file,1); + if(main_size < 0) + main_size = 0; + + /* reduce to pages */ + main_size = main_size / (1<<(fm->super.current.block_size)); + + /* TODO: check validity, etc */ + + fm->last_main_block = main_size; + + return COQUET_RET_OK; +} + +static int filemeta_setup_write(coquet_t *cq, struct cq_filemeta *fm) { + int r; + + fm->flags = 0; + + /* load superblock */ + r = cq_super_load(cq,fm->which_file,&(fm->super),1); // TODO "create mode" + if(r != COQUET_RET_OK) { + return r; + } + + /* find last block */ + r = find_last_main_block(cq,fm); + if(r != COQUET_RET_OK) { + return r; + } + + fm->flags |= COQUET_FM_FLAG_WRITE; + return COQUET_RET_OK; +} + +bool cq_writing(coquet_t *cq, int which_file) { + return ((cq->flags & COQUET_CQ_FILE_VALID(which_file)) && + (cq->filemeta[which_file].flags & COQUET_FM_FLAG_WRITE)); +} + +int coquet_write_start(coquet_t *cq, int which_file, bool wait) { + int r; + + if(cq_writing(cq,which_file)) { + return COQUET_RET_TRSMERROR; + } + + /* lock */ + r = (cq->vfs_funcs.lock)(cq->vfs_data, which_file, + COQUET_LOCK_WRITE,COQUET_LMODE_EXCL,wait); + if(r != COQUET_RET_OK) { + return r; + } + + /* setup */ + r = filemeta_setup_write(cq,&(cq->filemeta[which_file])); + if(r != COQUET_RET_OK) { + (cq->vfs_funcs.lock)(cq->vfs_data, which_file, + COQUET_LOCK_WRITE,COQUET_LMODE_UN,wait); + return r; + } + cq->flags |= COQUET_CQ_FILE_VALID(which_file); + + return COQUET_RET_OK; +} + +int coquet_write_end(coquet_t *cq, int which_file) { + int r; + + if(!cq_writing(cq,which_file)) { + return COQUET_RET_TRSMERROR; + } + + /* unlock */ + r = (cq->vfs_funcs.lock)(cq->vfs_data, which_file, + COQUET_LOCK_WRITE,COQUET_LMODE_UN,1); + if(r != COQUET_RET_OK) { + return r; + } + + /* mark stale */ + cq->flags &=~ COQUET_CQ_FILE_VALID(which_file); + + return COQUET_RET_OK; +} diff --git a/src/coquet.h b/src/coquet.h index 4cd6547..38b59ae 100644 --- a/src/coquet.h +++ b/src/coquet.h @@ -5,14 +5,28 @@ #include "superblock.h" #include "vfs.h" +#define COQUET_CQ_FLAG_MAINVALID 0x00000001 +#define COQUET_CQ_FLAG_OLDVALID 0x00000002 +#define COQUET_CQ_FLAG_TMPVALID 0x00000004 + +#define COQUET_CQ_FILE_VALID(file) (COQUET_CQ_FLAG_MAINVALID<<(file)) + +#define COQUET_FM_FLAG_WRITE 0x01 + +struct cq_filemeta { + int which_file; + struct cq_super super; + uint8_t flags; + uint64_t last_main_block; +}; + typedef struct coquet { - /* superblock stuff */ - uint64_t global_iv[GLOBAL_IV_LEN]; + uint32_t flags; + struct cq_filemeta filemeta[COQUET_FILE_NUM]; /* VFS */ vfs_t vfs_funcs; void *vfs_data; - } coquet_t; /* Initialise whole library. Returns NULL on malloc failure. cq must @@ -29,4 +43,14 @@ int coquet_finish(coquet_t *cq); */ char * coquet_error_string(coquet_t *cq, int error); +/* Prepare for a write transaction: locking, and general setup. + */ +int coquet_write_start(coquet_t *cq, int which_file, bool wait); + +/* Write has fnished, tear down. */ +int coquet_write_end(coquet_t *cq, int which_file); + +/* test if we're open for writing */ +bool cq_writing(coquet_t *cq, int which_file); + #endif diff --git a/src/main.c b/src/main.c index c7436e6..48acc2d 100644 --- a/src/main.c +++ b/src/main.c @@ -30,9 +30,9 @@ int main() { bail(&cq,r); r = (cq.vfs_funcs.open)(cq.vfs_data,COQUET_FILE_MAIN,COQUET_CMODE_EITHER); bail(&cq,r); - r = cq_super_load(&cq,&super,1); + r = cq_super_load(&cq,COQUET_FILE_MAIN,&super,1); bail(&cq,r); - cq_super_save(&cq,&super,1); + cq_super_save(&cq,COQUET_FILE_MAIN,&super,1); r = (cq.vfs_funcs.close)(cq.vfs_data,COQUET_FILE_MAIN); bail(&cq,r); r = coquet_finish(&cq); diff --git a/src/page.c b/src/page.c new file mode 100644 index 0000000..fcfb46f --- /dev/null +++ b/src/page.c @@ -0,0 +1,142 @@ +#include "page.h" + +off_t cq_offset_main_page(coquet_t *cq, int which_file, u_int64_t pgid) { + struct cq_filemeta *fm; + off_t header; + off_t nursery; + + fm = &(cq->filemeta[which_file]); + nursery = (2<<(fm->super.current.nursery_size + fm->super.current.block_size)); + header = 2*SUPER_BYTES + nursery; + + return header + (pgid-1) * (1<super.current.block_size); +} + +int cq_load_page(coquet_t *cq, int which_file, uint64_t pgid, uint64_t **buffer, int *len) { + /* TODO nursery */ + + return COQUET_RET_OK; +} + +int cq_save_page(coquet_t *cq, int which_file, uint64_t *pgid, uint8_t *buffer, int len) { + int r; + off_t offset; + struct cq_filemeta *fm; + + /* TODO nursery */ + + fm = &(cq->filemeta[which_file]); + + /* check we're open for writing */ + if(!cq_writing(cq,which_file)) { + return COQUET_RET_TRSMERROR; + } + + /* check we've got the right amount of data */ + if(len != 1 << fm->super.current.block_size) { + return COQUET_RET_BADARGS; + } + + /* write to the end of main (always, for now) */ + offset = cq_offset_main_page(cq,which_file,fm->last_main_block+1); + + /* write */ + r = (cq->vfs_funcs.write)(cq->vfs_data,which_file,buffer,offset,len); + if(r != COQUET_RET_OK) + return r; + + /* update metadata */ + fm->last_main_block += 1; + *pgid = fm->last_main_block; + + return COQUET_RET_OK; +} + +#ifdef COQUET_TEST + +#include +#include +#include "test.h" + +void test_page() { + uint64_t pgid,pgid2; + uint8_t buffer[4096],buffer2[4096]; + coquet_t cq; + struct cq_super super; + int r; + + /* write two pages, one of all 0xC3, and one of all 0x3C */ + /* TODO, when we have proper end detection, this needs to become a + * plausible root page. + */ + memset(buffer,0xC3,4096); + + r = coquet_init(&cq,"tmp/pagetest"); + test_bail(&cq,r); + + r = (cq.vfs_funcs.delete(cq.vfs_data,COQUET_FILE_MAIN)); + test_bail(&cq,r); + + /* first page */ + r = (cq.vfs_funcs.open)(cq.vfs_data,COQUET_FILE_MAIN,COQUET_CMODE_CREATE); + test_bail(&cq,r); + + cq_super_load(&cq,COQUET_FILE_MAIN,&super,1); + cq_super_save(&cq,COQUET_FILE_MAIN,&super,1); + + r = coquet_write_start(&cq,COQUET_FILE_MAIN,1); + test_bail(&cq,r); + + r = cq_save_page(&cq,COQUET_FILE_MAIN,&pgid,buffer,4096); + test_bail(&cq,r); + + /* close and reopen to make it work it all out again */ + r = coquet_write_end(&cq,COQUET_FILE_MAIN); + test_bail(&cq,r); + + r = (cq.vfs_funcs.close)(cq.vfs_data,COQUET_FILE_MAIN); + test_bail(&cq,r); + + r = (cq.vfs_funcs.open)(cq.vfs_data,COQUET_FILE_MAIN,COQUET_CMODE_OPEN); + test_bail(&cq,r); + + r = coquet_write_start(&cq,COQUET_FILE_MAIN,1); + test_bail(&cq,r); + + /* second page */ + memset(buffer,0x3C,4096); + + r = cq_save_page(&cq,COQUET_FILE_MAIN,&pgid2,buffer,4096); + test_bail(&cq,r); + + test_eq_int(pgid,1,"pgid1"); + test_eq_int(pgid2,2,"pgid2"); + + r = coquet_write_end(&cq,COQUET_FILE_MAIN); + test_bail(&cq,r); + + /* nursery is (2 sets of 2^12 lots of 10-bit blocks = 2 * 2^22 bytes) + * + * File should look like this + * 0x00000000 - 0x00000FFF superblock + * 0x00001000 - 0x00002FFF lock region + * 0x00002000 - 0x00401FFF nursery A + * 0x00402000 - 0x00801FFF nursery B + * 0x00802000 - 0x00802FFF pgid = 1 value = 0xC3 + * 0x00803000 - 0x00803FFF pgid = 2 value = 0x3C + */ + r = (cq.vfs_funcs.read)(cq.vfs_data,COQUET_FILE_MAIN,buffer2,0x00802000,4096); + test_bail(&cq,r); + memset(buffer,0xC3,4096); + test_assert(!memcmp(buffer,buffer2,4096),"pgid1 data"); + + r = (cq.vfs_funcs.read)(cq.vfs_data,COQUET_FILE_MAIN,buffer2,0x00803000,4096); + test_bail(&cq,r); + memset(buffer,0x3C,4096); + test_assert(!memcmp(buffer,buffer2,4096),"pgid2 data"); + + r = coquet_finish(&cq); + test_bail(&cq,r); +} + +#endif diff --git a/src/page.h b/src/page.h new file mode 100644 index 0000000..6b2bcf3 --- /dev/null +++ b/src/page.h @@ -0,0 +1,20 @@ +#ifndef COQUET_PAGE_H +#define COQUET_PAGE_H + +#include +#include "coquet.h" + +/* byte offset of given main page. Note pgids are 1-based */ +off_t cq_offset_main_page(coquet_t *cq, int which_file, u_int64_t pgid); + +/* Load/Save page with given pgid. Translation to nursery addresses (if + * needed) occurs immediately INSIDE these functions. + */ +int cq_load_page(coquet_t *cq, int which_file, uint64_t pgid, uint64_t **buffer, int *len); +int cq_save_page(coquet_t *cq, int which_file, uint64_t *pgid, uint8_t *buffer, int len); + +#ifdef COQUET_TEST +void test_page(); +#endif + +#endif diff --git a/src/superblock.c b/src/superblock.c index 99c3e4e..2cd96fc 100644 --- a/src/superblock.c +++ b/src/superblock.c @@ -108,14 +108,14 @@ static int super_init(coquet_t *cq, struct cq_super *super) { * reducing the HMAC to a simple hash in terms of guarantees. Requires the * main file to be open. */ -int cq_super_load(coquet_t *cq, struct cq_super *super, bool create) { +int cq_super_load(coquet_t *cq, int which_file, struct cq_super *super, bool create) { uint8_t super_bytes[SUPER_BYTES]; struct cq_super super_a, super_b; int r,r2; bool use_b; r = (cq->vfs_funcs.read) - (cq->vfs_data,COQUET_FILE_MAIN,super_bytes,0,SUPER_BYTES); + (cq->vfs_data,which_file,super_bytes,0,SUPER_BYTES); if(r != COQUET_RET_OK) { return r; } @@ -149,9 +149,9 @@ int cq_super_load(coquet_t *cq, struct cq_super *super, bool create) { return COQUET_RET_OK; } -static int lock_super(coquet_t *cq, int mode, bool wait) { +static int lock_super(coquet_t *cq, int which_file, int mode, bool wait) { return (cq->vfs_funcs.lock) - (cq->vfs_data,COQUET_LOCK_SUPERBLOCK,mode,wait); + (cq->vfs_data,which_file,COQUET_LOCK_SUPERBLOCK,mode,wait); } static void intract_config(uint8_t *data, @@ -194,18 +194,18 @@ static int super_write(coquet_t *cq, struct cq_super *super, return r; } -int cq_super_save(coquet_t *cq, struct cq_super *super, bool wait) { +int cq_super_save(coquet_t *cq, int which_file, struct cq_super *super, bool wait) { int r, ret; struct cq_super old; /* lock */ - r = lock_super(cq,COQUET_LMODE_EXCL,wait); + r = lock_super(cq,which_file,COQUET_LMODE_EXCL,wait); if(r != COQUET_RET_OK) { return r; } /* load */ - ret = cq_super_load(cq,&old,0); + ret = cq_super_load(cq,which_file,&old,0); if(ret == COQUET_RET_OK) { ret = super_write(cq,super,!old.from_b,old.sb_serial+1); } else if(ret == COQUET_RET_CORRUPT) { @@ -218,7 +218,7 @@ int cq_super_save(coquet_t *cq, struct cq_super *super, bool wait) { ret = (cq->vfs_funcs.sync)(cq->vfs_data,COQUET_FILE_MAIN,1); /* unlock */ - r = lock_super(cq,COQUET_LMODE_UN,wait); + r = lock_super(cq,which_file,COQUET_LMODE_UN,wait); if(r != COQUET_RET_OK) { return r; } @@ -278,15 +278,15 @@ void test_superblock_main() { test_open(&cq); - r = cq_super_load(&cq,&super,1); + r = cq_super_load(&cq,COQUET_FILE_MAIN,&super,1); test_bail(&cq,r); - cq_super_save(&cq,&super,1); + cq_super_save(&cq,COQUET_FILE_MAIN,&super,1); test_bail(&cq,r); super.desired.nursery_size = 11; /* change something for B */ cq_super_set_desc(&super,"test file"); - cq_super_save(&cq,&super,1); + cq_super_save(&cq,COQUET_FILE_MAIN,&super,1); test_bail(&cq,r); test_close(&cq); @@ -296,7 +296,7 @@ void test_superblock_main() { /* reopen to check the marshalling */ test_open(&cq); - r = cq_super_load(&cq,&super,1); + r = cq_super_load(&cq,COQUET_FILE_MAIN,&super,1); test_bail(&cq,r); test_assert(super.version == COQUET_VERSION,"version"); @@ -338,12 +338,12 @@ void test_superblock_main() { /* check updated in file successfully */ test_open(&cq); - cq_super_save(&cq,&super,1); + cq_super_save(&cq,COQUET_FILE_MAIN,&super,1); test_close(&cq); test_open(&cq); - r = cq_super_load(&cq,&super,1); + r = cq_super_load(&cq,COQUET_FILE_MAIN,&super,1); test_bail(&cq,r); desc = cq_super_get_desc(&super); @@ -370,12 +370,12 @@ static void make_superblock(coquet_t *cq, bool also_b, test_bail(cq,r); test_open(cq); - r = cq_super_load(cq,&super,1); + r = cq_super_load(cq,COQUET_FILE_MAIN,&super,1); super.current.nursery_size = 12; - cq_super_save(cq,&super,1); + cq_super_save(cq,COQUET_FILE_MAIN,&super,1); if(also_b) { super.current.nursery_size = 11; - cq_super_save(cq,&super,1); + cq_super_save(cq,COQUET_FILE_MAIN,&super,1); } if(corrupt>-1) { r = (cq->vfs_funcs.read)(cq->vfs_data,COQUET_FILE_MAIN,&d,corrupt,1); @@ -388,7 +388,7 @@ static void make_superblock(coquet_t *cq, bool also_b, /* check */ test_open(cq); - r = cq_super_load(cq,&super,1); + r = cq_super_load(cq,COQUET_FILE_MAIN,&super,1); test_bail(cq,r); test_eq_int(super.current.nursery_size,check,"c1"); test_close(cq); @@ -438,7 +438,6 @@ void test_superblock() { creation a/b choice -magic */ diff --git a/src/superblock.h b/src/superblock.h index abb9a5d..82ff11a 100644 --- a/src/superblock.h +++ b/src/superblock.h @@ -33,8 +33,8 @@ struct cq_super { #include "coquet.h" -int cq_super_save(coquet_t *cq, struct cq_super *super, bool wait); -int cq_super_load(coquet_t *cq, struct cq_super *super, bool create); +int cq_super_save(coquet_t *cq, int which_file, struct cq_super *super, bool wait); +int cq_super_load(coquet_t *cq, int which_file, struct cq_super *super, bool create); void cq_super_set_desc(struct cq_super *super, char *desc); char * cq_super_get_desc(struct cq_super *super); diff --git a/src/test.c b/src/test.c index 2aacc4b..64bf6f4 100644 --- a/src/test.c +++ b/src/test.c @@ -5,6 +5,7 @@ #include #include "sha2.h" #include "superblock.h" +#include "page.h" #include "test.h" void test_assert(int is_true, char *msg) { @@ -108,5 +109,6 @@ int main() { printf("testing\n"); test_sha2(); test_superblock(); + test_page(); return 0; } diff --git a/src/testvfs.c b/src/testvfs.c index 608fbc0..552536e 100644 --- a/src/testvfs.c +++ b/src/testvfs.c @@ -125,13 +125,13 @@ static int test_read(void * vfs_data, int which_file, uint8_t * data, which_file, data, offset, length); } -static int test_lock(void * vfs_data, int which_lock, int lock_mode, +static int test_lock(void * vfs_data, int which_file, int which_lock, int lock_mode, bool wait) { struct test_data * td = (struct test_data *)vfs_data; if(td->virtual) return COQUET_RET_OK; - return (td->vfs_funcs.lock)(td->vfs_data, + return (td->vfs_funcs.lock)(td->vfs_data, which_file, which_lock, lock_mode, wait); } diff --git a/src/unix.c b/src/unix.c index a41972c..33bada0 100644 --- a/src/unix.c +++ b/src/unix.c @@ -293,7 +293,7 @@ static int unix_read(void * vfs_data, int which_file, uint8_t * data, } /* main_fd must be open */ -static int min_size(struct unix_data *pd, off_t offset) { +static int min_size(struct unix_data *pd, int fd, off_t offset) { int r; off_t r_off; char buf[1] = {0}; @@ -302,13 +302,13 @@ static int min_size(struct unix_data *pd, off_t offset) { return COQUET_RET_OK; } - r_off = lseek(pd->main_fd,offset,SEEK_SET); + r_off = lseek(fd,offset,SEEK_SET); if(r_off == -1) { set_error(pd,"seek failed",1); return COQUET_RET_VFSERR; } - r = write(pd->main_fd,buf,1); + r = write(fd,buf,1); if(r == -1) { set_error(pd,"write failed",1); return COQUET_RET_VFSERR; @@ -317,20 +317,21 @@ static int min_size(struct unix_data *pd, off_t offset) { return COQUET_RET_OK; } -#define LOCK_BLOCK 128 -static int unix_lock(void * vfs_data, int which_lock, int lock_mode, +#define LOCK_BLOCK (SUPER_BYTES/NUM_LOCKS) +static int unix_lock(void * vfs_data, int which_file, int which_lock, int lock_mode, bool wait) { struct unix_data * pd = (struct unix_data *)vfs_data; - int r, op; + int r, op, *fd; struct flock flk; - if(pd->main_fd==-1) { + fd = file_fd(pd,which_file); + if(*fd==-1) { set_error(pd,"main file closed during locking",0); return COQUET_RET_VFSERR; } /* Lock region needs to exist. We can append zeroes.*/ - r = min_size(pd,SUPER_BYTES+LOCK_BLOCK*NUM_LOCKS); + r = min_size(pd,*fd,SUPER_BYTES+LOCK_BLOCK*NUM_LOCKS); if(r != COQUET_RET_OK) { return r; } @@ -359,7 +360,7 @@ static int unix_lock(void * vfs_data, int which_lock, int lock_mode, op = F_OFD_SETLK; } - r = fcntl(pd->main_fd,op,&flk); + r = fcntl(*fd,op,&flk); if(r == -1) { set_error(pd,"flock failed",1); return COQUET_RET_VFSERR; diff --git a/src/vfs.h b/src/vfs.h index c974426..d8f949c 100644 --- a/src/vfs.h +++ b/src/vfs.h @@ -30,7 +30,7 @@ typedef struct vfs { * purpose. COQUET_FILE_MAIN will be open when called. If wait is true, * function will wait, otherwise return COQUET_RET_LOCKED */ - int (*lock)(void * vfs_data, int which_lock, int lock_mode, + int (*lock)(void * vfs_data, int which_file, int which_lock, int lock_mode, bool wait); /* Open the given file. which_file is drawn from COQUET_FILE_*. -- 2.30.2