chiark / gitweb /
Load page.
authorDan Sheppard <dan.sheppard.circle@gmail.com>
Wed, 23 Apr 2025 18:18:24 +0000 (19:18 +0100)
committerDan Sheppard <dan.sheppard.circle@gmail.com>
Wed, 23 Apr 2025 18:18:24 +0000 (19:18 +0100)
Makefile
src/coquet.c
src/coquet.h
src/page.c
src/page.h
src/unix.c

index 737216c1acfe9167c415686e0121a091d1523019..6a85b95a6337c6af2b22ebbca237f26ff4038119 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -57,6 +57,7 @@ clean:
        -rm -f $(OBJDIR)/*
        -rm -f $(TESTOBJDIR)/*
        -rm -f $(BINDIR)/*
+       -rm -f tmp/*
 
 -include $(MAINDEPS)
 -include $(TESTDEPS)
index 6e9168248bafbc2cd728b078961daf01c92d2b4c..47b382f322fbb613474d61f8db6ee13d1c41f012 100644 (file)
@@ -166,11 +166,9 @@ static int find_last_main_block(coquet_t *cq, struct cq_filemeta *fm) {
     return COQUET_RET_OK;
 }
 
-static int filemeta_setup_write(coquet_t *cq, struct cq_filemeta *fm) {
+static int filemeta_setup_common(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) {
@@ -183,15 +181,48 @@ static int filemeta_setup_write(coquet_t *cq, struct cq_filemeta *fm) {
         return r;
     }
 
+    return COQUET_RET_OK;
+}
+
+static int filemeta_setup_write(coquet_t *cq, struct cq_filemeta *fm) {
+    int r;
+
+    fm->flags = 0;
+
+    r = filemeta_setup_common(cq,fm);
+    if(r != COQUET_RET_OK) {
+        return r;
+    }
+
     fm->flags |= COQUET_FM_FLAG_WRITE;
     return COQUET_RET_OK;
 }
 
+static int filemeta_setup_read(coquet_t *cq, struct cq_filemeta *fm) {
+    int r;
+
+    fm->flags = 0;
+
+    r = filemeta_setup_common(cq,fm);
+    if(r != COQUET_RET_OK) {
+        return r;
+    }
+
+    fm->flags |= COQUET_FM_FLAG_READ;
+    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));
 }
 
+bool cq_reading(coquet_t *cq, int which_file) {
+    return ((cq->flags & COQUET_CQ_FILE_VALID(which_file)) &&
+            (cq->filemeta[which_file].flags & 
+                (COQUET_FM_FLAG_WRITE|COQUET_FM_FLAG_READ)));
+}
+
 int coquet_write_start(coquet_t *cq, int which_file, bool wait) {
     int r;
 
@@ -237,3 +268,31 @@ int coquet_write_end(coquet_t *cq, int which_file) {
 
     return COQUET_RET_OK;
 }
+
+int coquet_read_start(coquet_t *cq, int which_file, bool wait) {
+    int r;
+
+    if(cq_reading(cq,which_file)) {
+        return COQUET_RET_TRSMERROR;
+    }
+
+    /* setup */
+    r = filemeta_setup_read(cq,&(cq->filemeta[which_file]));
+    if(r != COQUET_RET_OK) {
+        return r;
+    }
+    cq->flags |= COQUET_CQ_FILE_VALID(which_file);
+
+    return COQUET_RET_OK;
+}
+
+int coquet_read_end(coquet_t *cq, int which_file) {
+    if(!cq_reading(cq,which_file) || cq_writing(cq,which_file)) {
+        return COQUET_RET_TRSMERROR;
+    }
+
+    /* mark stale */
+    cq->flags &=~ COQUET_CQ_FILE_VALID(which_file);
+
+    return COQUET_RET_OK;
+}
index 38b59aee26e7e66c35822fcb3e05ec5c5ad4b1fb..9bb7f8223a11b00da472fd52a7b58744c97c5b9b 100644 (file)
@@ -12,6 +12,7 @@
 #define COQUET_CQ_FILE_VALID(file) (COQUET_CQ_FLAG_MAINVALID<<(file))
 
 #define COQUET_FM_FLAG_WRITE 0x01
+#define COQUET_FM_FLAG_READ  0x02
 
 struct cq_filemeta {
     int which_file;
@@ -43,14 +44,19 @@ int coquet_finish(coquet_t *cq);
  */
 char * coquet_error_string(coquet_t *cq, int error);
 
-/* Prepare for a write transaction: locking, and general setup.
+/* Prepare/finish 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 */
+/* Prepare/finish read transaction: locking, and general setup.
+ */
+int coquet_read_start(coquet_t *cq, int which_file, bool wait);
+int coquet_read_end(coquet_t *cq, int which_file);
+
+
+/* test if we can read/write */
+bool cq_reading(coquet_t *cq, int which_file);
 bool cq_writing(coquet_t *cq, int which_file);
 
 #endif
index fcfb46f714dbb16a89e79e6f8f60810a0ba6440d..33f4fdef02e11b19ffddc3783262071036415b8d 100644 (file)
@@ -1,3 +1,4 @@
+#include <stdlib.h>
 #include "page.h"
 
 off_t cq_offset_main_page(coquet_t *cq, int which_file, u_int64_t pgid) {
@@ -12,13 +13,39 @@ off_t cq_offset_main_page(coquet_t *cq, int which_file, u_int64_t pgid) {
     return header + (pgid-1) * (1<<fm->super.current.block_size);
 }
 
-int cq_load_page(coquet_t *cq, int which_file, uint64_t pgid, uint64_t **buffer, int *len) {
+int cq_load_page(coquet_t *cq, int which_file, uint64_t pgid, uint8_t **buffer, uint64_t *len) {
+    int r;
+    off_t offset;
+    struct cq_filemeta *fm;
+
     /* TODO nursery */
 
+    fm = &(cq->filemeta[which_file]);
+
+    /* check we're open for reading */
+    if(!cq_reading(cq,which_file)) {
+        return COQUET_RET_TRSMERROR;
+    }
+
+    /* create buffer */
+    *len = 1<<fm->super.current.block_size;
+    *buffer = malloc(*len);
+    if(*buffer == NULL) {
+        return COQUET_RET_HEAPERR;
+    }
+
+    /* read from main (always, for now) */
+    offset = cq_offset_main_page(cq,which_file,pgid);
+
+    /* read */
+    r = (cq->vfs_funcs.read)(cq->vfs_data,which_file,*buffer,offset,*len);
+    if(r != COQUET_RET_OK)
+        return r;
+
     return COQUET_RET_OK;
 }
 
-int cq_save_page(coquet_t *cq, int which_file, uint64_t *pgid, uint8_t *buffer, int len) {
+int cq_save_page(coquet_t *cq, int which_file, uint64_t *pgid, uint8_t *buffer, uint64_t len) {
     int r;
     off_t offset;
     struct cq_filemeta *fm;
@@ -60,10 +87,11 @@ int cq_save_page(coquet_t *cq, int which_file, uint64_t *pgid, uint8_t *buffer,
 
 void test_page() {
     uint64_t pgid,pgid2;
-    uint8_t buffer[4096],buffer2[4096];
+    uint8_t buffer[4096],buffer2[4096],*buffer3;
     coquet_t cq;
     struct cq_super super;
     int r;
+    uint64_t len;
 
     /* write two pages, one of all 0xC3, and one of all 0x3C */
     /* TODO, when we have proper end detection, this needs to become a
@@ -125,6 +153,8 @@ void test_page() {
      * 0x00802000 - 0x00802FFF pgid = 1 value = 0xC3
      * 0x00803000 - 0x00803FFF pgid = 2 value = 0x3C
      */
+
+    /* check directly */
     r = (cq.vfs_funcs.read)(cq.vfs_data,COQUET_FILE_MAIN,buffer2,0x00802000,4096);
     test_bail(&cq,r);
     memset(buffer,0xC3,4096);
@@ -135,6 +165,28 @@ void test_page() {
     memset(buffer,0x3C,4096);
     test_assert(!memcmp(buffer,buffer2,4096),"pgid2 data");
 
+    /* check with "proper" reads */
+
+    r = coquet_read_start(&cq,COQUET_FILE_MAIN,1);
+    test_bail(&cq,r);
+
+    r = cq_load_page(&cq,COQUET_FILE_MAIN,1,&buffer3,&len);
+    test_bail(&cq,r);
+    memset(buffer,0xC3,4096);
+    test_eq_int(len,4096,"len");
+    test_assert(!memcmp(buffer,buffer3,4096),"pgid1 data (b)");
+    free(buffer3);
+
+    r = cq_load_page(&cq,COQUET_FILE_MAIN,2,&buffer3,&len);
+    test_bail(&cq,r);
+    memset(buffer,0x3C,4096);
+    test_eq_int(len,4096,"len");
+    test_assert(!memcmp(buffer,buffer3,4096),"pgid2 data (b)");
+    free(buffer3);
+
+    r = coquet_read_end(&cq,COQUET_FILE_MAIN);
+    test_bail(&cq,r);
+
     r = coquet_finish(&cq);
     test_bail(&cq,r);
 }
index 6b2bcf308f607bab65b3a3560e8d58b565d72957..a3a0348d4d166fa594b8af2d814ae6a30607c5dc 100644 (file)
@@ -10,8 +10,8 @@ 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);
+int cq_load_page(coquet_t *cq, int which_file, uint64_t pgid, uint8_t **buffer, uint64_t *len);
+int cq_save_page(coquet_t *cq, int which_file, uint64_t *pgid, uint8_t *buffer, uint64_t len);
 
 #ifdef COQUET_TEST
 void test_page();
index 33bada0a5db98db3435e34c2099c0feee2a77a00..e7497ffa281fe2df8b538bf6bcd62c63be46d19a 100644 (file)
@@ -387,7 +387,7 @@ static int unix_delete(void *vfs_data, int which_file) {
 
     r = unlink(path);
     free(path);
-    if(r == -1) {
+    if(r == -1 && errno!=ENOENT) {
         set_error(pd,"delete failed",1);
         return COQUET_RET_VFSERR;
     }