void testfs_close_super_block(struct super_block *sb) { testfs_tx_start(sb, TX_UMOUNT); // write sb->sb of type dsuper_block to disk at offset 0. testfs_write_super_block(sb); // assume there are no entries in the inode hash table. // delete the 256 hash size inode hash table inode_hash_destroy(); if (sb->inode_freemap) { // write inode map to disk. write_blocks(sb, bitmap_getdata(sb->inode_freemap), sb->sb.inode_freemap_start, INODE_FREEMAP_SIZE); // free in memory bitmap file. bitmap_destroy(sb->inode_freemap); sb->inode_freemap = NULL; } if (sb->block_freemap) { // write inode freemap to disk write_blocks(sb, bitmap_getdata(sb->block_freemap), sb->sb.block_freemap_start, BLOCK_FREEMAP_SIZE); // destroy inode freemap bitmap_destroy(sb->block_freemap); sb->block_freemap = NULL; } testfs_tx_commit(sb, TX_UMOUNT); fflush(sb->dev); fclose(sb->dev); sb->dev = NULL; // free in memory data structure sb superblock free(sb); }
void testfs_put_inode_freemap(struct super_block *sb, int inode_nr) { assert(sb->inode_freemap); bitmap_unmark(sb->inode_freemap, inode_nr); testfs_write_inode_freemap(sb, inode_nr); assert(sb->sb.used_inode_count > 0); sb->sb.used_inode_count--; testfs_write_super_block(sb); }
/* free a block. * returns negative value on error. */ int testfs_free_block(struct super_block *sb, int block_nr) { zero_blocks(sb, block_nr, 1); block_nr -= sb->sb.data_blocks_start; //printf("block nr: %d\n",block_nr ); assert(block_nr >= 0); testfs_put_block_freemap(sb, block_nr); assert(sb->sb.used_block_count > 0); sb->sb.used_block_count--; testfs_write_super_block(sb); return 0; }
int testfs_alloc_block(struct super_block *sb) { int phy_block_nr; /* file system size is limited to max_fs_blocks */ if (sb->sb.used_block_count >= sb->sb.max_fs_blocks) return -ENOSPC; phy_block_nr = testfs_get_block_freemap(sb); if (phy_block_nr < 0) return phy_block_nr; sb->sb.used_block_count++; testfs_write_super_block(sb); return sb->sb.data_blocks_start + phy_block_nr; }
int testfs_get_inode_freemap(struct super_block *sb) { u_int32_t index; int ret; assert(sb->inode_freemap); ret = bitmap_alloc(sb->inode_freemap, &index); if (ret < 0) return ret; testfs_write_inode_freemap(sb, index); sb->sb.used_inode_count++; testfs_write_super_block(sb); return index; }
void testfs_close_super_block(struct super_block *sb) { testfs_write_super_block(sb); inode_hash_destroy(); if (sb->inode_freemap) { write_blocks(sb, bitmap_getdata(sb->inode_freemap), sb->sb.inode_freemap_start, INODE_FREEMAP_SIZE); bitmap_destroy(sb->inode_freemap); sb->inode_freemap = NULL; } if (sb->block_freemap) { write_blocks(sb, bitmap_getdata(sb->block_freemap), sb->sb.block_freemap_start, BLOCK_FREEMAP_SIZE); bitmap_destroy(sb->block_freemap); sb->block_freemap = NULL; } fflush(sb->dev); fclose(sb->dev); sb->dev = NULL; free(sb); }
struct super_block * testfs_make_super_block(char *file) { struct super_block *sb = calloc(1, sizeof(struct super_block)); if (!sb) { EXIT("malloc"); } if ((sb->dev = fopen(file, "w")) == NULL) { EXIT(file); } sb->sb.inode_freemap_start = SUPER_BLOCK_SIZE; sb->sb.block_freemap_start = sb->sb.inode_freemap_start + INODE_FREEMAP_SIZE; sb->sb.csum_table_start = sb->sb.block_freemap_start + BLOCK_FREEMAP_SIZE; sb->sb.inode_blocks_start = sb->sb.csum_table_start + CSUM_TABLE_SIZE; sb->sb.data_blocks_start = sb->sb.inode_blocks_start + NR_INODE_BLOCKS; sb->sb.modification_time = 0; testfs_write_super_block(sb); inode_hash_init(); return sb; }
struct super_block * testfs_make_super_block(const char *dev, u64 max_fs_blocks) { struct super_block *sb = calloc(1, sizeof(struct super_block)); if (!sb) { EXIT("malloc"); } if ((sb->dev = fopen(dev, "w")) == NULL) { EXIT(dev); } sb->sb.inode_freemap_start = SUPER_BLOCK_SIZE; sb->sb.block_freemap_start = sb->sb.inode_freemap_start + INODE_FREEMAP_SIZE; sb->sb.inode_blocks_start = sb->sb.block_freemap_start + BLOCK_FREEMAP_SIZE; sb->sb.data_blocks_start = sb->sb.inode_blocks_start + NR_INODE_BLOCKS; sb->sb.used_inode_count = 0; sb->sb.used_block_count = 0; sb->sb.max_fs_blocks = max_fs_blocks; testfs_write_super_block(sb); inode_hash_init(); return sb; }