chiark / gitweb /
Make superblock whole block. main
authorDan Sheppard <dan.sheppard.circle@gmail.com>
Mon, 12 May 2025 11:14:40 +0000 (12:14 +0100)
committerDan Sheppard <dan.sheppard.circle@gmail.com>
Mon, 12 May 2025 11:14:40 +0000 (12:14 +0100)
(Should help avoid curruption).

doc/TODO
src/superblock.c
src/superblock.h
testdata/sb1.coquet

index d7ba699e81924b30ae8dfabc8b48d649a79109c5..f3f494bbd3e82163588edd1ac92dbeeffc622c83 100644 (file)
--- a/doc/TODO
+++ b/doc/TODO
@@ -4,5 +4,5 @@
 * lock timeout
 * superblock corrupt jamming
 * switch to SHA256 (good h/w support for speed)
-* shift superblock somewhere safer
+* separate superblocks
 * optional suffix work
\ No newline at end of file
index bdce9de9f98f7b5f848c500fe88cb4aee6ce4e9b..63e5d65ef273c7d0dbf39b14e120d1f406cf532b 100644 (file)
@@ -5,10 +5,11 @@
 #include "util.h"
 #include "sha2.h"
 #include "superblock.h"
+#include "page.h"
 
 #define HASH_LEN    32
 
-/* cq_config: length = 2048
+/* cq_config: length = 4096
  *
  *                       offset    length
  * +-------------------+
  * | sb_serial         |   80         8
  * | description       |   88       128
  * +-------------------+
- * | unused            |  216       808
+ * | unused            |  216      1832
  * +-------------------+
- * | current           | 1024       512
+ * | current           | 2048      1024
  * +-------------------+
- * | desired           | 1536       512
+ * | desired           | 3072      1024
  * +-------------------+
  *
- * cq_super_config: length = 512
+ * cq_super_config: length = 1024
  *
  *                       offset    length
  * +-------------------+
  * | block_size        |   0           1
  * | nursery_size      |   1           1
  * +-------------------+
- * | unused            |   2         510
+ * | unused            |   2        1022
  * +-------------------+
  */
 
@@ -74,15 +75,15 @@ static int extract_half(uint8_t *data, struct cq_super *super) {
     memcpy(super->desc,data+88,DESC_LEN);
     super->sb_serial = be_decode(data+80,8);
     
-    extract_config(data+1024,&(super->current));
-    extract_config(data+1536,&(super->desired));
+    extract_config(data+2048,&(super->current));
+    extract_config(data+3072,&(super->desired));
 
     /* verify */
     memcpy(hash,data+48,HASH_LEN);
     memset(data+48,0,HASH_LEN);
     sha2_init_hmac(&sha2, SHA2_VARIETY_512_256,
         super->global_iv, GLOBAL_IV_LEN);
-    sha2_more(&sha2,data,HALF_BYTES);
+    sha2_more(&sha2,data,SUPER_BYTES);
     sha2_finish(&sha2,cmp,HASH_LEN);
     if(memcmp(hash,cmp,HASH_LEN)) {
         return 0;
@@ -103,18 +104,27 @@ static int super_init(coquet_t *cq, struct cq_super *super) {
     return COQUET_RET_OK;
 }
 
+static off_t super_offset(int use_b) {
+    return use_b?SUPER_BYTES:0;
+}
+
 /* TODO super due to split, anticipating */
 static int super_load_half(coquet_t *cq, int which_file, 
                            struct cq_super *super, int *ok, int use_b) {
     uint8_t super_bytes[SUPER_BYTES];
     int r;
+    uint64_t offset;
+
+    /* offset in file */
+    offset = super_offset(use_b);
 
+    /* read */
     r = (cq->vfs_funcs.read)
-            (cq->vfs_data,which_file,super_bytes,0,SUPER_BYTES);
+            (cq->vfs_data,which_file,super_bytes,offset,SUPER_BYTES);
     if(r != COQUET_RET_OK) {
         return r;
     }
-    *ok = !!extract_half(super_bytes+(use_b?HALF_BYTES:0),super);
+    *ok = !!extract_half(super_bytes,super);
     return COQUET_RET_OK;
 }
 
@@ -182,32 +192,32 @@ static void intract(uint8_t *data, struct cq_super *super, uint64_t serial) {
     struct sha2_ctx_t sha2;
     
     /* intract */
-    memset(data,0,HALF_BYTES);
+    memset(data,0,SUPER_BYTES);
     be_encode(data,COQUET_MAGIC,8);
     be_encode(data+8,COQUET_VERSION,8);
     memcpy(data+16,super->global_iv,GLOBAL_IV_LEN);
     be_encode(data+80,serial,8);
     memcpy(data+88,super->desc,DESC_LEN);
     
-    intract_config(data+1024,&(super->current));
-    intract_config(data+1536,&(super->desired));
+    intract_config(data+2048,&(super->current));
+    intract_config(data+3072,&(super->desired));
 
     /* set hash */
     sha2_init_hmac(&sha2, SHA2_VARIETY_512_256,
             super->global_iv, GLOBAL_IV_LEN);
-    sha2_more(&sha2,data,HALF_BYTES);
+    sha2_more(&sha2,data,SUPER_BYTES);
     sha2_finish(&sha2,data+48,HASH_LEN);
 }
 
 static int super_write(coquet_t *cq, struct cq_super *super,
-                       bool use_b, uint64_t serial) {
-    uint8_t half[HALF_BYTES];
+                       int which_file, bool use_b, uint64_t serial) {
+    uint8_t half[SUPER_BYTES];
     int r;
+    off_t offset;
 
+    offset = super_offset(use_b);
     intract(half,super,serial);
-    r = (cq->vfs_funcs.write)
-            (cq->vfs_data,COQUET_FILE_MAIN,half,
-            use_b?HALF_BYTES:0,HALF_BYTES);
+    r = (cq->vfs_funcs.write)(cq->vfs_data,which_file,half,offset,SUPER_BYTES);
 
     return r;
 }
@@ -249,10 +259,10 @@ int cq_super_save(coquet_t *cq, int which_file, struct cq_super *super, bool wai
 
     /* save */
     if(ret == COQUET_RET_OK) {
-        ret = super_write(cq,super,use_b,old.sb_serial+1);
+        ret = super_write(cq,super,which_file,use_b,old.sb_serial+1);
     } else if(ret == COQUET_RET_CORRUPT) {
         // XXX log TODO check this arm for correctness
-        ret = super_write(cq,super,0,1);
+        ret = super_write(cq,super,which_file,0,1);
     }
 
     /* sync */
@@ -347,12 +357,12 @@ void test_superblock_main() {
     test_bail(&cq,r);
 
     test_assert(super.version == COQUET_VERSION,"version");
-    test_assert(super.sb_serial == 2,"serial");
-    test_assert(super.from_b == 1,"from_b");
-    test_assert(super.current.block_size == 12,"cbsize");
-    test_assert(super.desired.block_size == 12,"dbsize");
-    test_assert(super.current.nursery_size == 10,"cnurs");
-    test_assert(super.desired.nursery_size == 11,"dnurs");
+    test_eq_int(super.sb_serial,2,"serial");
+    test_eq_int(super.from_b,1,"from_b");
+    test_eq_int(super.current.block_size,12,"cbsize");
+    test_eq_int(super.desired.block_size,12,"dbsize");
+    test_eq_int(super.current.nursery_size,10,"cnurs");
+    test_eq_int(super.desired.nursery_size,11,"dnurs");
     
     desc = cq_super_get_desc(&super);
     test_assert(!strcmp(desc,"test file"),"desc");
@@ -456,18 +466,18 @@ void test_superblock_corruption() {
     make_superblock(&cq,0,-1,12);
 
     /* Corrupting A should lead us to default, ie n.s. = 10 */
-    for(i=0;i<2048;i++) {
+    for(i=0;i<4096;i++) {
         make_superblock(&cq,0,i,10);
     }
 
     /* Corrupting A should keep B, ie n.s. = 11 */
-    for(i=0;i<2048;i++) {
+    for(i=0;i<4096;i++) {
         make_superblock(&cq,1,i,11);
     }
 
     /* Corrupting B should give A, ie n.s. = 12 */
-    for(i=0;i<2048;i++) {
-        make_superblock(&cq,1,2048+i,12);
+    for(i=0;i<4096;i++) {
+        make_superblock(&cq,1,4096+i,12);
     }
 
     testvfs_virtual(cq.vfs_data,0);
index 9a2155c5a176d87d2d7699841d92ac6bdfb4f4ac..e3516f630a92a052151e427d934eafb40042b031 100644 (file)
@@ -3,8 +3,7 @@
 
 #include "constants.h"
 
-#define HALF_BYTES  2048
-#define SUPER_BYTES (HALF_BYTES*2)
+#define SUPER_BYTES 4096
 #define GLOBAL_IV_LEN 32
 #define DESC_LEN 128
 #define NUM_LOCKS 32
index 1e7308d871cfead714d7f30e9a4a31739eaa066e..ca34fd384d6718cf286f37e265d605361e81b693 100644 (file)
Binary files a/testdata/sb1.coquet and b/testdata/sb1.coquet differ