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); }
int cmd_write(struct super_block *sb, struct context *c) { int inode_nr; struct inode *in; int size; int ret = 0; char * filename = c->cmd[1]; char * content = c->cmd[2]; if (c->nargs != 3) { return -EINVAL; } inode_nr = testfs_dir_name_to_inode_nr(c->cur_dir, filename); if (inode_nr < 0) return inode_nr; in = testfs_get_inode(sb, inode_nr); if (testfs_inode_get_type(in) == I_DIR) { ret = -EISDIR; goto out; } size = strlen(content); testfs_tx_start(sb, TX_WRITE); ret = testfs_write_data(in, 0, content, size); if (ret >= 0) { testfs_truncate_data(in, size); } testfs_sync_inode(in); testfs_tx_commit(sb, TX_WRITE); out: testfs_put_inode(in); return ret; }
static int testfs_create_file_or_dir(struct super_block *sb, struct inode *dir, inode_type type, char *name) { int ret = 0; struct inode *in; int inode_nr; if (dir) { inode_nr = testfs_dir_name_to_inode_nr(dir, name); if (inode_nr >= 0) return -EEXIST; } testfs_tx_start(sb, TX_CREATE); /* first create inode */ ret = testfs_create_inode(sb, type, &in); if (ret < 0) { goto fail; } inode_nr = testfs_inode_get_nr(in); if (type == I_DIR) { /* create directory */ int p_inode_nr = dir ? testfs_inode_get_nr(dir) : inode_nr; ret = testfs_create_empty_dir(sb, p_inode_nr, in); if (ret < 0) goto out; } /* then add directory entry */ if (dir) { if ((ret = testfs_add_dirent(dir, name, inode_nr)) < 0) goto out; testfs_sync_inode(dir); } testfs_sync_inode(in); testfs_put_inode(in); testfs_tx_commit(sb, TX_CREATE); return 0; out: testfs_remove_inode(in); fail: testfs_tx_commit(sb, TX_CREATE); return ret; }
int cmd_rm(struct super_block *sb, struct context *c) { int inode_nr; struct inode *in; if (c->nargs != 2) { return -EINVAL; } testfs_tx_start(sb, TX_RM); inode_nr = testfs_remove_dirent(sb, c->cur_dir, c->cmd[1]); if (inode_nr < 0) { testfs_tx_commit(sb, TX_RM); return inode_nr; } in = testfs_get_inode(sb, inode_nr); testfs_remove_inode(in); testfs_sync_inode(c->cur_dir); testfs_tx_commit(sb, TX_RM); return 0; }