Project

General

Profile

Submit #2775 » unittest.c

tkusumi, 01/21/2015 06:44 AM

 
#include <stdio.h>
#include <assert.h>
#include <vfs/hammer/hammer_disk.h>

/*
* mimic freemap initialization loop of
* ondisk.c:initialize_freemap
*/
static void assert_freemap_init_loop(int vol_no, hammer_off_t base,
hammer_off_t end, int debug) {
hammer_off_t layer1_base;
hammer_off_t layer1_offset = 0xDEADBEEF;
hammer_off_t phys_offset;
hammer_off_t vol_free_end;
hammer_off_t aligned_vol_free_end;
hammer_off_t tmp;
int count = 0;

layer1_base = HAMMER_ENCODE_RAW_BUFFER(0, base);

vol_free_end = HAMMER_ENCODE_RAW_BUFFER(vol_no, end
& ~HAMMER_LARGEBLOCK_MASK64);
aligned_vol_free_end = (vol_free_end + HAMMER_BLOCKMAP_LAYER2_MASK)
& ~HAMMER_BLOCKMAP_LAYER2_MASK;

if (debug) {
printf("\n");
printf("layer1_base = 0x%0lX\n", layer1_base);
printf("vol_free_end = 0x%0lX\n", vol_free_end);
printf("aligned_vol_free_end = 0x%0lX\n", aligned_vol_free_end);
}

for (phys_offset = HAMMER_ENCODE_RAW_BUFFER(vol_no, 0);
phys_offset < aligned_vol_free_end;
phys_offset += HAMMER_LARGEBLOCK_SIZE) {

if ((phys_offset % HAMMER_BLOCKMAP_LAYER2) == 0) {
/* Get layer1 when moving on to the next layer 1 */
layer1_offset = layer1_base +
HAMMER_BLOCKMAP_LAYER1_OFFSET(phys_offset);
if (debug)
printf("get layer1 = 0x%0lX\n", layer1_offset);
count++;
} else {
/* We can reuse layer 1 till it hits the next one */
tmp = layer1_base +
HAMMER_BLOCKMAP_LAYER1_OFFSET(phys_offset);
/* Make sure it's same as the one we already have */
assert(layer1_offset == tmp);
/* Make sure we don't come here on the first time */
assert(layer1_offset != 0xDEADBEEF);
}
}

/*
* layer1/layer2 direct map:
* zzzzvvvvvvvvoooo oooooooooooooooo oooooooooooooooo oooooooooooooooo
* ----111111111111 1111112222222222 222222222ooooooo oooooooooooooooo
* ^^^^ ^^^^^^
* We read layer 1 for ^^^^^^^^^^ times + 1 per volume.
* e.g. Maximum will be 2^10 = 1024 times per volume
* e.g. Minimum will be 1 time per volume
* e.g. If the volume size is < 4TB it reads layer 1 only
* once per volume.
*/
vol_free_end &= 0x000FFFFFFFFFFFFF;
vol_free_end >>= 42;
assert(count == vol_free_end + 1);
}

int main(int argc, char **argv) {
int i, debug = 0;
hammer_off_t base, end;

if (argc > 1)
debug = 1;

/* HAMMER_BLOCKMAP_LAYER1_OFFSET() gets +sizeof(layer1) every 4TB */
assert((HAMMER_BLOCKMAP_LAYER2 >> 42) == 1);

assert(HAMMER_BLOCKMAP_LAYER1_OFFSET(0) == 0);
assert(HAMMER_BLOCKMAP_LAYER1_OFFSET(HAMMER_BLOCKMAP_LAYER2 - 1)
== 0);

assert(HAMMER_BLOCKMAP_LAYER1_OFFSET(HAMMER_BLOCKMAP_LAYER2)
== sizeof(struct hammer_blockmap_layer1));
assert(HAMMER_BLOCKMAP_LAYER1_OFFSET(HAMMER_BLOCKMAP_LAYER2 + 1)
== sizeof(struct hammer_blockmap_layer1));
assert(HAMMER_BLOCKMAP_LAYER1_OFFSET(HAMMER_BLOCKMAP_LAYER2 * 2 - 1)
== sizeof(struct hammer_blockmap_layer1));

assert(HAMMER_BLOCKMAP_LAYER1_OFFSET(HAMMER_BLOCKMAP_LAYER2 * 2)
== sizeof(struct hammer_blockmap_layer1) * 2);
assert(HAMMER_BLOCKMAP_LAYER1_OFFSET(HAMMER_BLOCKMAP_LAYER2 * 2 + 1)
== sizeof(struct hammer_blockmap_layer1) * 2);
assert(HAMMER_BLOCKMAP_LAYER1_OFFSET(HAMMER_BLOCKMAP_LAYER2 * 3 - 1)
== sizeof(struct hammer_blockmap_layer1) * 2);

base = 0x0; /* use 0 for freemap zone offset */
end = 0xFFFFFFFFFFFFFFFF; /* just pass maximum possible */

/* Freemap init assertions are based on above behavior */
for (i = 0; i < 256; i++) {
assert_freemap_init_loop(i, base, end, debug);
printf(".");
fflush(stdout);
}

printf("\n");
printf("success\n");
return 0;
}
(2-2/2)