From a84c775d11326b6598bd9ab6b33d40719b1649d3 Mon Sep 17 00:00:00 2001 From: "Tse-Chia.Chang" Date: Thu, 20 Jun 2024 13:08:34 +0800 Subject: [PATCH] Fix missing data synchronization The get_free_blocks function in simplefs has an issue where data written to the disk is not being properly synchronized. Testing: The test flow is as follow. After step 4 the content of test.txt is empty. 1. mount simplefs 2. vim test.txt 3. umount 4. mount Changes: Add sync_dirty_buffer to ensure proper disk synchronization. Add automated tests for checking the data consistency. --- bitmap.h | 4 +++- script/test.sh | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/bitmap.h b/bitmap.h index ba08931..e0368f3 100644 --- a/bitmap.h +++ b/bitmap.h @@ -47,11 +47,12 @@ 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); + uint32_t i; if (!ret) /* No enough free blocks */ return 0; sbi->nr_free_blocks -= len; - for (uint32_t i = 0; i < len; i++) { + for (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); @@ -60,6 +61,7 @@ static inline uint32_t get_free_blocks(struct super_block *sb, uint32_t len) } memset(bh->b_data, 0, SIMPLEFS_BLOCK_SIZE); mark_buffer_dirty(bh); + sync_dirty_buffer(bh); /* write the buffer to disk */ brelse(bh); } return ret; diff --git a/script/test.sh b/script/test.sh index b2b974d..ab8bbe8 100755 --- a/script/test.sh +++ b/script/test.sh @@ -10,6 +10,7 @@ F_MOD="-rw-r--r--" S_MOD="lrwxrwxrwx" MAXFILESIZE=11173888 # SIMPLEFS_MAX_EXTENTS * SIMPLEFS_MAX_BLOCKS_PER_EXTENT * SIMPLEFS_BLOCK_SIZE MAXFILES=40920 # max files per dir +MOUNT_TEST=100 test_op() { local op=$1 @@ -61,6 +62,42 @@ done filecnts=$(ls | wc -w) test $filecnts -eq $MAXFILES || echo "Failed, it should be $MAXFILES files" find . -name '[0-9]*.txt' | xargs -n 2000 sudo rm +sync + +# create 100 files with filenames inside +for ((i=1; i<=$MOUNT_TEST; i++)) +do + echo file_$i | sudo tee file_$i.txt >/dev/null && echo "file_$i.txt created." +done +sync + +# unmount and remount the filesystem +echo "Unmounting filesystem..." +popd >/dev/null || { echo "popd failed"; exit 1; } +sudo umount test || { echo "umount failed"; exit 1; } +sleep 1 +echo "Remounting filesystem..." +sudo mount -t simplefs -o loop $IMAGE test || { echo "mount failed"; exit 1; } +echo "Remount succeeds." +pushd test >/dev/null || { echo "pushd failed"; exit 1; } + +# check if files exist and content is correct after remounting +for ((i=1; i<=$MOUNT_TEST; i++)) +do + if [[ -f "file_$i.txt" ]]; then + content=$(cat "file_$i.txt" | tr -d '\000') + if [[ "$content" == "file_$i" ]]; then + echo "Success: file_$i.txt content is correct." + else + echo "Failed: file_$i.txt content is incorrect." + exit 1 + fi + else + echo "Failed: file_$i.txt does not exist." + exit 1 + fi +done +find . -name 'file_[0-9]*.txt' | xargs sudo rm || { echo "Failed to delete files"; exit 1; } # hard link test_op 'ln file hdlink' @@ -96,4 +133,4 @@ check_exist $S_MOD 1 symlink sleep 1 popd >/dev/null sudo umount test -sudo rmmod simplefs +sudo rmmod simplefs \ No newline at end of file