static void _reopen(struct fixture *f) { struct io_engine *engine; bcache_destroy(f->cache); engine = create_async_io_engine(); T_ASSERT(engine); f->cache = bcache_create(T_BLOCK_SIZE / 512, NR_BLOCKS, engine); T_ASSERT(f->cache); }
static void *_fix_init(struct io_engine *engine) { uint8_t buffer[T_BLOCK_SIZE]; struct fixture *f = malloc(sizeof(*f)); unsigned b, i; struct statvfs fsdata; static int _runs_is_tmpfs = -1; if (_runs_is_tmpfs == -1) { // With testing in tmpfs directory O_DIRECT cannot be used // tmpfs has f_fsid == 0 (unsure if this is best guess) _runs_is_tmpfs = (statvfs(".", &fsdata) == 0 && !fsdata.f_fsid) ? 1 : 0; if (_runs_is_tmpfs) printf(" Running test in tmpfs, *NOT* using O_DIRECT\n"); } T_ASSERT(f); snprintf(f->fname, sizeof(f->fname), "unit-test-XXXXXX"); f->fd = mkstemp(f->fname); T_ASSERT(f->fd >= 0); for (b = 0; b < NR_BLOCKS; b++) { for (i = 0; i < sizeof(buffer); i++) buffer[i] = _pattern_at(INIT_PATTERN, byte(b, i)); T_ASSERT(write(f->fd, buffer, T_BLOCK_SIZE) > 0); } if (!_runs_is_tmpfs) { close(f->fd); // reopen with O_DIRECT f->fd = open(f->fname, O_RDWR | O_DIRECT); T_ASSERT(f->fd >= 0); } f->cache = bcache_create(T_BLOCK_SIZE / 512, NR_BLOCKS, engine); T_ASSERT(f->cache); return f; }
int ext2_mount(bdev_t *dev, fscookie *cookie) { int err; LTRACEF("dev %p\n", dev); ext2_t *ext2 = malloc(sizeof(ext2_t)); ext2->dev = dev; err = bio_read(dev, &ext2->sb, 1024, sizeof(struct ext2_super_block)); if (err < 0) goto err; endian_swap_superblock(&ext2->sb); /* see if the superblock is good */ if (ext2->sb.s_magic != EXT2_SUPER_MAGIC) { err = -1; return err; } /* calculate group count, rounded up */ ext2->s_group_count = (ext2->sb.s_blocks_count + ext2->sb.s_blocks_per_group - 1) / ext2->sb.s_blocks_per_group; /* print some info */ LTRACEF("rev level %d\n", ext2->sb.s_rev_level); LTRACEF("compat features 0x%x\n", ext2->sb.s_feature_compat); LTRACEF("incompat features 0x%x\n", ext2->sb.s_feature_incompat); LTRACEF("ro compat features 0x%x\n", ext2->sb.s_feature_ro_compat); LTRACEF("block size %d\n", EXT2_BLOCK_SIZE(ext2->sb)); LTRACEF("inode size %d\n", EXT2_INODE_SIZE(ext2->sb)); LTRACEF("block count %d\n", ext2->sb.s_blocks_count); LTRACEF("blocks per group %d\n", ext2->sb.s_blocks_per_group); LTRACEF("group count %d\n", ext2->s_group_count); LTRACEF("inodes per group %d\n", ext2->sb.s_inodes_per_group); /* we only support dynamic revs */ if (ext2->sb.s_rev_level > EXT2_DYNAMIC_REV) { err = -2; return err; } /* make sure it doesn't have any ro features we don't support */ if (ext2->sb.s_feature_ro_compat & ~(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) { err = -3; return err; } /* read in all the group descriptors */ ext2->gd = malloc(sizeof(struct ext2_group_desc) * ext2->s_group_count); err = bio_read(ext2->dev, (void *)ext2->gd, (EXT2_BLOCK_SIZE(ext2->sb) == 4096) ? 4096 : 2048, sizeof(struct ext2_group_desc) * ext2->s_group_count); if (err < 0) { err = -4; return err; } int i; for (i=0; i < ext2->s_group_count; i++) { endian_swap_group_desc(&ext2->gd[i]); LTRACEF("group %d:\n", i); LTRACEF("\tblock bitmap %d\n", ext2->gd[i].bg_block_bitmap); LTRACEF("\tinode bitmap %d\n", ext2->gd[i].bg_inode_bitmap); LTRACEF("\tinode table %d\n", ext2->gd[i].bg_inode_table); LTRACEF("\tfree blocks %d\n", ext2->gd[i].bg_free_blocks_count); LTRACEF("\tfree inodes %d\n", ext2->gd[i].bg_free_inodes_count); LTRACEF("\tused dirs %d\n", ext2->gd[i].bg_used_dirs_count); } /* initialize the block cache */ ext2->cache = bcache_create(ext2->dev, EXT2_BLOCK_SIZE(ext2->sb), 4); /* load the first inode */ err = ext2_load_inode(ext2, EXT2_ROOT_INO, &ext2->root_inode); if (err < 0) goto err; // TRACE("successfully mounted volume\n"); *cookie = ext2; return 0; err: LTRACEF("exiting with err code %d\n", err); free(ext2); return err; }