Skip to content

Commit 855c339

Browse files
authored
Fix potential EIO error (#51)
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
1 parent 5e11fa7 commit 855c339

File tree

4 files changed

+39
-13
lines changed

4 files changed

+39
-13
lines changed

bitmap.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,28 @@ static inline uint32_t get_free_inode(struct simplefs_sb_info *sbi)
4040
}
4141

4242
/* Return 'len' unused block(s) number and mark it used.
43+
* Clean the block content.
4344
* Return 0 if no enough free block(s) were found.
4445
*/
45-
static inline uint32_t get_free_blocks(struct simplefs_sb_info *sbi,
46-
uint32_t len)
46+
static inline uint32_t get_free_blocks(struct super_block *sb, uint32_t len)
4747
{
48+
struct simplefs_sb_info *sbi = SIMPLEFS_SB(sb);
4849
uint32_t ret = get_first_free_bits(sbi->bfree_bitmap, sbi->nr_blocks, len);
49-
if (ret)
50-
sbi->nr_free_blocks -= len;
50+
if (!ret) /* No enough free blocks */
51+
return 0;
52+
53+
sbi->nr_free_blocks -= len;
54+
for (uint32_t i = 0; i < len; i++) {
55+
struct buffer_head *bh = sb_bread(sb, ret + i);
56+
if (!bh) {
57+
pr_err("get_free_blocks: sb_bread failed for block %d\n", ret + i);
58+
sbi->nr_free_blocks += len;
59+
return -EIO;
60+
}
61+
memset(bh->b_data, 0, SIMPLEFS_BLOCK_SIZE);
62+
mark_buffer_dirty(bh);
63+
brelse(bh);
64+
}
5165
return ret;
5266
}
5367

file.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ static int simplefs_file_get_block(struct inode *inode,
2020
int create)
2121
{
2222
struct super_block *sb = inode->i_sb;
23-
struct simplefs_sb_info *sbi = SIMPLEFS_SB(sb);
2423
struct simplefs_inode_info *ci = SIMPLEFS_INODE(inode);
2524
struct simplefs_file_ei_block *index;
2625
struct buffer_head *bh_index;
@@ -52,7 +51,7 @@ static int simplefs_file_get_block(struct inode *inode,
5251
ret = 0;
5352
goto brelse_index;
5453
}
55-
bno = get_free_blocks(sbi, 8);
54+
bno = get_free_blocks(sb, 8);
5655
if (!bno) {
5756
ret = -ENOSPC;
5857
goto brelse_index;

inode.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ static struct inode *simplefs_new_inode(struct inode *dir, mode_t mode)
248248
ci = SIMPLEFS_INODE(inode);
249249

250250
/* Get a free block for this new inode's index */
251-
bno = get_free_blocks(sbi, 1);
251+
bno = get_free_blocks(sb, 1);
252252
if (!bno) {
253253
ret = -ENOSPC;
254254
goto put_inode;
@@ -381,7 +381,7 @@ static int simplefs_create(struct inode *dir,
381381
fi = eblock->nr_files % SIMPLEFS_FILES_PER_BLOCK;
382382

383383
if (!eblock->extents[ei].ee_start) {
384-
bno = get_free_blocks(SIMPLEFS_SB(sb), 8);
384+
bno = get_free_blocks(sb, 8);
385385
if (!bno) {
386386
ret = -ENOSPC;
387387
goto iput;
@@ -753,7 +753,7 @@ static int simplefs_rename(struct inode *old_dir,
753753
/* insert in new parent directory */
754754
/* Get new freeblocks for extent if needed*/
755755
if (new_pos < 0) {
756-
bno = get_free_blocks(SIMPLEFS_SB(sb), 8);
756+
bno = get_free_blocks(sb, 8);
757757
if (!bno) {
758758
ret = -ENOSPC;
759759
goto release_new;
@@ -909,7 +909,7 @@ static int simplefs_link(struct dentry *old_dentry,
909909
fi = eblock->nr_files % SIMPLEFS_FILES_PER_BLOCK;
910910

911911
if (eblock->extents[ei].ee_start == 0) {
912-
bno = get_free_blocks(SIMPLEFS_SB(sb), 8);
912+
bno = get_free_blocks(sb, 8);
913913
if (!bno) {
914914
ret = -ENOSPC;
915915
goto end;
@@ -1002,7 +1002,7 @@ static int simplefs_symlink(struct inode *dir,
10021002
fi = eblock->nr_files % SIMPLEFS_FILES_PER_BLOCK;
10031003

10041004
if (eblock->extents[ei].ee_start == 0) {
1005-
bno = get_free_blocks(SIMPLEFS_SB(sb), 8);
1005+
bno = get_free_blocks(sb, 8);
10061006
if (!bno) {
10071007
ret = -ENOSPC;
10081008
goto end;

mkfs.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,20 @@ static int write_bfree_blocks(int fd, struct superblock *sb)
235235

236236
static int write_data_blocks(int fd, struct superblock *sb)
237237
{
238-
/* FIXME: unimplemented */
238+
char *buffer = calloc(1, SIMPLEFS_BLOCK_SIZE);
239+
if (!buffer) {
240+
perror("Failed to allocate memory");
241+
return -1;
242+
}
243+
244+
ssize_t ret = write(fd, buffer, SIMPLEFS_BLOCK_SIZE);
245+
if (ret != SIMPLEFS_BLOCK_SIZE) {
246+
perror("Failed to write data block");
247+
free(buffer);
248+
return -1;
249+
}
250+
251+
free(buffer);
239252
return 0;
240253
}
241254

@@ -315,7 +328,7 @@ int main(int argc, char **argv)
315328
goto free_sb;
316329
}
317330

318-
/* Write data blocks */
331+
/* clear a root index block */
319332
ret = write_data_blocks(fd, sb);
320333
if (ret) {
321334
perror("write_data_blocks():");

0 commit comments

Comments
 (0)