static void test02(struct sb *sb, block_t blocks) { /* Allocate specific range */ block_t start = 121; unsigned count = 10; for (int i = 0; i < count + 2; i++) { struct block_segment seg; int err = balloc_from_range(sb, start, count, 1, 0, &seg, 1); if (i < count) test_assert(!err && seg.block == start + i); else test_assert(err == -ENOSPC); } /* Check bitmap */ test_assert(bitmap_all_set(sb, start, count)); test_assert(bitmap_all_clear(sb, 0, start)); loff_t cnt = ((blocks << sb->blockbits) << 3) - (start + count); test_assert(bitmap_all_clear(sb, start + count, cnt)); for (int i = 0; i < count; i++) { int err = bfree(sb, start + i, 1); if (i < count) test_assert(!err); else test_assert(err); } test_assert(bitmap_all_clear(sb, 0, (blocks << sb->blockbits) << 3)); clean_main(sb); }
/* Test balloc for partial allocation */ static void test08(struct sb *sb, block_t blocks) { struct block_segment seg; /* Alloc blocks whole blocks */ test_assert(balloc(sb, sb->volblocks, &seg, 1) == 0); test_assert(seg.block == 0); test_assert(seg.count == sb->volblocks); test_assert(bitmap_all_set(sb, seg.block, seg.count)); /* Free some blocks */ test_assert(bfree(sb, 10, 20) == 0); test_assert(bitmap_all_clear(sb, 10, 20)); test_assert(bfree(sb, 100, 40) == 0); test_assert(bitmap_all_clear(sb, 100, 40)); /* Allocate partial blocks */ test_assert(balloc_partial(sb, 50, &seg, 1) == 0); test_assert(seg.block == 100); test_assert(seg.count == 40); test_assert(bitmap_all_set(sb, 100, 40)); /* Allocate partial blocks */ test_assert(balloc_partial(sb, 50, &seg, 1) == 0); test_assert(seg.block == 10); test_assert(seg.count == 20); test_assert(bitmap_all_set(sb, 10, 20)); clean_main(sb); }
/* Tests bits set/clear/test functions */ static void test01(struct sb *sb, block_t blocks) { tux3_msg(sb, "---- test bitops ----"); unsigned char bits[16]; memset(bits, 0, sizeof(bits)); /* set some bits */ set_bits(bits, 6, 20); set_bits(bits, 49, 16); set_bits(bits, 0x51, 2); /* test set bits */ test_assert(all_set(bits, 6, 20)); test_assert(all_set(bits, 49, 16)); test_assert(all_set(bits, 0x51, 2)); /* test clear bits */ test_assert(all_clear(bits, 6, 20) == 0); test_assert(all_clear(bits, 49, 16) == 0); test_assert(all_clear(bits, 0x51, 2) == 0); /* should return false */ test_assert(all_set(bits, 5, 20) == 0); test_assert(all_set(bits, 49, 17) == 0); test_assert(all_set(bits, 0x51, 3) == 0); test_assert(all_clear(bits, 5, 20) == 0); test_assert(all_clear(bits, 49, 17) == 0); test_assert(all_clear(bits, 0x51, 3) == 0); /* all zero now */ clear_bits(bits, 6, 20); clear_bits(bits, 49, 16); clear_bits(bits, 0x51, 2); test_assert(all_clear(bits, 0, 8 * sizeof(bits))); test_assert(all_clear(bits, 6, 20)); test_assert(all_clear(bits, 49, 16)); test_assert(all_clear(bits, 0x51, 2)); test_assert(all_set(bits, 6, 20) == 0); test_assert(all_set(bits, 49, 16) == 0); test_assert(all_set(bits, 0x51, 2) == 0); /* Corner case */ #if 1 unsigned char *bitmap = malloc(8); /* bitmap must be array of ulong */ #else unsigned char *bitmap = malloc(7); #endif set_bits(bitmap, 0, 7 * 8); test_assert(all_set(bitmap, 0, 7 * 8)); test_assert(all_clear(bitmap, 0, 7 * 8) == 0); clear_bits(bitmap, 0, 7 * 8); test_assert(all_clear(bitmap, 0, 7 * 8)); test_assert(all_set(bitmap, 0, 7 * 8) == 0); free(bitmap); clean_main(sb); }
/* Test balloc and bfree on multiple blocks */ static void test07(struct sb *sb, block_t blocks) { for (int i = 0; i < 3; i++) { struct block_segment seg; /* Alloc blocks on multiple bitmap data pages */ test_assert(balloc(sb, sb->volblocks, &seg, 1) == 0); test_assert(seg.block == 0); test_assert(seg.count == sb->volblocks); test_assert(bitmap_all_set(sb, seg.block, seg.count)); /* Free blocks on multiple bitmap data pages */ test_assert(bfree(sb, seg.block, seg.count) == 0); test_assert(bitmap_all_clear(sb, seg.block, seg.count)); } clean_main(sb); }
static void test03(struct sb *sb, block_t blocks) { struct block_segment seg; /* nextblock point last bit, but can't allocate 2 bits. So, * this should wrap around to zero */ sb->nextblock = sb->volblocks - 1; test_assert(balloc(sb, 2, &seg, 1) == 0); test_assert(seg.block == 0); test_assert(seg.count == 2); test_assert(bitmap_all_set(sb, seg.block, seg.count)); test_assert(bitmap_all_clear(sb, seg.count, sb->volblocks - seg.count)); test_assert(bfree(sb, seg.block, seg.count) == 0); test_assert(bitmap_all_clear(sb, 0, sb->volblocks)); clean_main(sb); }
static void test04(struct sb *sb, block_t blocks) { block_t start; /* nextblock point last bit, this should wrap around to zero */ start = sb->nextblock = sb->volblocks - 1; for (int i = 0; i < 2; i++) { struct block_segment seg; test_assert(balloc(sb, 1, &seg, 1) == 0); test_assert(seg.block == (start + i) % sb->volblocks); test_assert(seg.count == 1); } test_assert(bitmap_all_set(sb, 0, 1)); test_assert(bitmap_all_clear(sb, 1, start - 1)); test_assert(bitmap_all_set(sb, start, 1)); test_assert(bfree(sb, start, 1) == 0); test_assert(bfree(sb, 0, 1) == 0); test_assert(bitmap_all_clear(sb, 0, sb->volblocks)); clean_main(sb); }
/* Fill whole bitmap and free */ static void test06(struct sb *sb, block_t blocks) { #define ALLOC_UNIT 8 block_t total = blocks << (sb->blockbits + 3); struct block_segment *seg; int err, nr = total / ALLOC_UNIT; seg = malloc(nr * sizeof(*seg)); assert(seg); for (int i = 0; i < nr; i++) { err = balloc_from_range(sb, 0, total, ALLOC_UNIT, 0, &seg[i], 1); test_assert(!err); test_assert(seg[i].count == ALLOC_UNIT); } for (int i = 0; i < nr; i++) test_assert(bfree(sb, seg[i].block, seg[i].count) == 0); free(seg); clean_main(sb); }
static void test05(struct sb *sb, block_t blocks) { block_t bits = 1 << (3 + sb->blockbits); for (int i = 0; i < 2; i++) { struct block_segment seg; /* Alloc blocks on a bitmap page */ test_assert(balloc(sb, bits, &seg, 1) == 0); test_assert(seg.block == i * bits); test_assert(seg.count == bits); test_assert(bitmap_all_set(sb, i * bits, bits)); } test_assert(bitmap_all_set(sb, 0, 2 * bits)); for (int i = 0; i < 2; i++) { /* Free blocks on a bitmap page */ test_assert(bfree(sb, i * bits, bits) == 0); test_assert(bitmap_all_clear(sb, i * bits, bits)); } test_assert(bitmap_all_clear(sb, 0, 2 * bits)); clean_main(sb); }
/* Test basic operations */ static void test01(struct sb *sb, struct inode *inode) { /* * FIXME: map_region() are not supporting to read segments on * multiple leaves at once. */ #define CAN_HANDLE_A_LEAF 1 /* Create by ascending order */ if (test_start("test01.1")) { struct block_segment seg; int err, segs; /* Set fake backend mark to modify backend objects. */ tux3_start_backend(sb); for (int i = 0, j = 0; i < 30; i++, j++) { segs = d_map_region(inode, 2*i, 1, &seg, 1, MAP_WRITE); test_assert(segs == 1); } #ifdef CAN_HANDLE_A_LEAF for (int i = 0; i < 30; i++) { segs = check_map_region(inode, 2*i, 1, &seg, 1); test_assert(segs == 1); } #else segs = check_map_region(inode, 0, 30*2, seg, ARRAY_SIZE(seg)); test_assert(segs == 30*2); #endif /* btree_chop and dleaf_chop test */ int index = 31*2; while (index--) { err = btree_chop(&tux_inode(inode)->btree, index, TUXKEY_LIMIT); test_assert(!err); #ifdef CAN_HANDLE_A_LEAF for (int i = 0; i < 30; i++) { if (index <= i*2) break; segs = check_map_region(inode, 2*i, 1, &seg, 1); test_assert(segs == 1); } #else segs = check_map_region(inode, 0, 30*2, seg, ARRAY_SIZE(seg)); test_assert(segs == i*2); #endif } /* Check if truncated all */ segs = map_region(inode, 0, INT_MAX, &seg, 1, MAP_READ); test_assert(segs == 1); test_assert(seg.count == INT_MAX); test_assert(seg.state == BLOCK_SEG_HOLE); tux3_end_backend(); test_assert(force_delta(sb) == 0); clean_main(sb, inode); } test_end(); /* Create by descending order */ if (test_start("test01.2")) { struct block_segment seg; int err, segs; /* Set fake backend mark to modify backend objects. */ tux3_start_backend(sb); for (int i = 30; i >= 0; i--) { segs = d_map_region(inode, 2*i, 1, &seg, 1, MAP_WRITE); test_assert(segs == 1); } #ifdef CAN_HANDLE_A_LEAF for (int i = 30; i >= 0; i--) { segs = check_map_region(inode, 2*i, 1, &seg, 1); test_assert(segs == 1); } #else segs = check_map_region(inode, 0, 30*2, seg, ARRAY_SIZE(seg)); test_assert(segs == i*2); #endif err = btree_chop(&tux_inode(inode)->btree, 0, TUXKEY_LIMIT); test_assert(!err); /* Check if truncated all */ segs = map_region(inode, 0, INT_MAX, &seg, 1, MAP_READ); test_assert(segs == 1); test_assert(seg.count == INT_MAX); test_assert(seg.state == BLOCK_SEG_HOLE); tux3_end_backend(); test_assert(force_delta(sb) == 0); clean_main(sb, inode); } test_end(); test_assert(force_delta(sb) == 0); clean_main(sb, inode); }
int main(int argc, char *argv[]) { #define BITMAP_BLOCKS 10 struct dev *dev = &(struct dev){ .bits = 3 }; /* This expect buffer is never reclaimed */ init_buffers(dev, 1 << 20, 1); block_t volblocks = BITMAP_BLOCKS << (dev->bits + 3); struct sb *sb = rapid_sb(dev); sb->super = INIT_DISKSB(dev->bits, volblocks); setup_sb(sb, &sb->super); test_init(argv[0]); struct inode *bitmap = rapid_open_inode(sb, NULL, 0); sb->bitmap = bitmap; /* Setup buffers for bitmap */ for (int block = 0; block < BITMAP_BLOCKS; block++) { struct buffer_head *buffer = blockget(bitmap->map, block); memset(bufdata(buffer), 0, sb->blocksize); set_buffer_clean(buffer); blockput(buffer); } /* Set fake backend mark to modify backend objects. */ tux3_start_backend(sb); if (test_start("test01")) test01(sb, BITMAP_BLOCKS); test_end(); if (test_start("test02")) test02(sb, BITMAP_BLOCKS); test_end(); if (test_start("test03")) test03(sb, BITMAP_BLOCKS); test_end(); if (test_start("test04")) test04(sb, BITMAP_BLOCKS); test_end(); if (test_start("test05")) test05(sb, BITMAP_BLOCKS); test_end(); if (test_start("test06")) test06(sb, BITMAP_BLOCKS); test_end(); if (test_start("test07")) test07(sb, BITMAP_BLOCKS); test_end(); if (test_start("test08")) test08(sb, BITMAP_BLOCKS); test_end(); tux3_end_backend(); clean_main(sb); return test_failures(); }