diff --git a/bitmap.h b/bitmap.h index f7fa938..ba08931 100644 --- a/bitmap.h +++ b/bitmap.h @@ -40,14 +40,28 @@ static inline uint32_t get_free_inode(struct simplefs_sb_info *sbi) } /* Return 'len' unused block(s) number and mark it used. + * Clean the block content. * Return 0 if no enough free block(s) were found. */ -static inline uint32_t get_free_blocks(struct simplefs_sb_info *sbi, - uint32_t len) +static inline uint32_t get_free_blocks(struct super_block *sb, uint32_t len) { + struct simplefs_sb_info *sbi = SIMPLEFS_SB(sb); uint32_t ret = get_first_free_bits(sbi->bfree_bitmap, sbi->nr_blocks, len); - if (ret) - sbi->nr_free_blocks -= len; + if (!ret) /* No enough free blocks */ + return 0; + + sbi->nr_free_blocks -= len; + for (uint32_t i = 0; i < len; i++) { + struct buffer_head *bh = sb_bread(sb, ret + i); + if (!bh) { + pr_err("get_free_blocks: sb_bread failed for block %d\n", ret + i); + sbi->nr_free_blocks += len; + return -EIO; + } + memset(bh->b_data, 0, SIMPLEFS_BLOCK_SIZE); + mark_buffer_dirty(bh); + brelse(bh); + } return ret; } diff --git a/file.c b/file.c index 67a8e82..a26a12e 100644 --- a/file.c +++ b/file.c @@ -20,7 +20,6 @@ static int simplefs_file_get_block(struct inode *inode, int create) { struct super_block *sb = inode->i_sb; - struct simplefs_sb_info *sbi = SIMPLEFS_SB(sb); struct simplefs_inode_info *ci = SIMPLEFS_INODE(inode); struct simplefs_file_ei_block *index; struct buffer_head *bh_index; @@ -52,7 +51,7 @@ static int simplefs_file_get_block(struct inode *inode, ret = 0; goto brelse_index; } - bno = get_free_blocks(sbi, 8); + bno = get_free_blocks(sb, 8); if (!bno) { ret = -ENOSPC; goto brelse_index; diff --git a/inode.c b/inode.c index 5750016..ef60889 100644 --- a/inode.c +++ b/inode.c @@ -248,7 +248,7 @@ static struct inode *simplefs_new_inode(struct inode *dir, mode_t mode) ci = SIMPLEFS_INODE(inode); /* Get a free block for this new inode's index */ - bno = get_free_blocks(sbi, 1); + bno = get_free_blocks(sb, 1); if (!bno) { ret = -ENOSPC; goto put_inode; @@ -381,7 +381,7 @@ static int simplefs_create(struct inode *dir, fi = eblock->nr_files % SIMPLEFS_FILES_PER_BLOCK; if (!eblock->extents[ei].ee_start) { - bno = get_free_blocks(SIMPLEFS_SB(sb), 8); + bno = get_free_blocks(sb, 8); if (!bno) { ret = -ENOSPC; goto iput; @@ -753,7 +753,7 @@ static int simplefs_rename(struct inode *old_dir, /* insert in new parent directory */ /* Get new freeblocks for extent if needed*/ if (new_pos < 0) { - bno = get_free_blocks(SIMPLEFS_SB(sb), 8); + bno = get_free_blocks(sb, 8); if (!bno) { ret = -ENOSPC; goto release_new; @@ -909,7 +909,7 @@ static int simplefs_link(struct dentry *old_dentry, fi = eblock->nr_files % SIMPLEFS_FILES_PER_BLOCK; if (eblock->extents[ei].ee_start == 0) { - bno = get_free_blocks(SIMPLEFS_SB(sb), 8); + bno = get_free_blocks(sb, 8); if (!bno) { ret = -ENOSPC; goto end; @@ -1002,7 +1002,7 @@ static int simplefs_symlink(struct inode *dir, fi = eblock->nr_files % SIMPLEFS_FILES_PER_BLOCK; if (eblock->extents[ei].ee_start == 0) { - bno = get_free_blocks(SIMPLEFS_SB(sb), 8); + bno = get_free_blocks(sb, 8); if (!bno) { ret = -ENOSPC; goto end; diff --git a/mkfs.c b/mkfs.c index f0af711..01a6e0b 100644 --- a/mkfs.c +++ b/mkfs.c @@ -235,7 +235,20 @@ static int write_bfree_blocks(int fd, struct superblock *sb) static int write_data_blocks(int fd, struct superblock *sb) { - /* FIXME: unimplemented */ + char *buffer = calloc(1, SIMPLEFS_BLOCK_SIZE); + if (!buffer) { + perror("Failed to allocate memory"); + return -1; + } + + ssize_t ret = write(fd, buffer, SIMPLEFS_BLOCK_SIZE); + if (ret != SIMPLEFS_BLOCK_SIZE) { + perror("Failed to write data block"); + free(buffer); + return -1; + } + + free(buffer); return 0; } @@ -315,7 +328,7 @@ int main(int argc, char **argv) goto free_sb; } - /* Write data blocks */ + /* clear a root index block */ ret = write_data_blocks(fd, sb); if (ret) { perror("write_data_blocks():");