Skip to content

Commit

Permalink
Fix potential EIO error (#51)
Browse files Browse the repository at this point in the history
If we use 'dd if=/dev/random of=test.img bs=1M count=32' rather
than 'if=/dev/zero' and mount it, it will cause an EIO error and
get stuck in a loop.

This commit addresses an issue where the 'ls' command would read random,
meaningless values from 'simplefs_file_ei_block' for uninitialized
blocks. This occurred because the blocks contained residual data,
leading to erroneous outputs.

Changes:
1. Clear the root extent block during the 'mkfs' process to prevent
   erroneous 'simplefs_file_ei_block' data.
2. Ensure that file data blocks are cleared immediately upon
   allocation to prevent erroneous 'simplefs_file' data.

Close #20 and #50
  • Loading branch information
HotMercury authored May 18, 2024
1 parent 5e11fa7 commit 855c339
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 13 deletions.
22 changes: 18 additions & 4 deletions bitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
3 changes: 1 addition & 2 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 5 additions & 5 deletions inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
17 changes: 15 additions & 2 deletions mkfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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():");
Expand Down

0 comments on commit 855c339

Please sign in to comment.