#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
* +-------------------+
*/
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;
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;
}
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;
}
/* 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 */
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");
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);