Add filesystem consistency check.
authorbatt <batt@38d2e660-2303-0410-9eaa-f027e97ec537>
Thu, 25 Sep 2008 17:35:06 +0000 (17:35 +0000)
committerbatt <batt@38d2e660-2303-0410-9eaa-f027e97ec537>
Thu, 25 Sep 2008 17:35:06 +0000 (17:35 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@1849 38d2e660-2303-0410-9eaa-f027e97ec537

bertos/fs/battfs.c
bertos/fs/battfs.h
bertos/fs/battfs_test.c

index f43a9ce9a91bb5e35b6eab0b3fdfed3a118fb3e8..fd07efac5add4157b36f13480f6564eae53a7e9d 100644 (file)
@@ -508,9 +508,62 @@ bool battfs_init(struct BattFsSuper *disk)
        return true;
 }
 
-bool batts_fsck(struct BattFsSuper *disk)
+/**
+ * Check the filesystem.
+ * \return true if ok, false on errors.
+ */
+bool battfs_fsck(struct BattFsSuper *disk)
 {
+       #define FSCHECK(cond) do { if(!(cond)) { LOG_ERR("\"" #cond "\"\n"); goto fsck_err; } } while (0)
+
+       FSCHECK(disk->free_page_start <= disk->page_count);
+       FSCHECK(disk->data_size < disk->page_size);
+       FSCHECK(disk->free_bytes <= disk->disk_size);
+
+       disk_size_t free_bytes = 0;
+       BattFsPageHeader hdr, prev_hdr;
+       inode_t files = 0;
+       pgcnt_t page_used = 0;
+
+       bool start = true;
 
+       for (pgcnt_t page = 0; page < disk->page_count; page++)
+       {
+               FSCHECK(readHdr(disk, disk->page_array[page], &hdr));
+               free_bytes += disk->data_size;
+
+               if (page < disk->free_page_start)
+               {
+                       FSCHECK(computeFcs(&hdr) == hdr.fcs);
+                       page_used++;
+                       free_bytes -= hdr.fill;
+                       if (hdr.inode != prev_hdr.inode || start)
+                       {
+                               if (LIKELY(!start))
+                                       FSCHECK(hdr.inode > prev_hdr.inode);
+                               else
+                                       start = false;
+
+                               FSCHECK(hdr.pgoff == 0);
+                               files++;
+                       }
+                       else
+                       {
+                               FSCHECK(hdr.fill != 0);
+                               FSCHECK(prev_hdr.fill == disk->data_size);
+                               FSCHECK(hdr.pgoff == prev_hdr.pgoff + 1);
+                       }
+                       prev_hdr = hdr;
+               }
+       }
+
+       FSCHECK(page_used == disk->free_page_start);
+       FSCHECK(free_bytes == disk->free_bytes);
+       FSCHECK(files < BATTFS_MAX_FILES);
+       return true;
+
+       fsck_err:
+               return false;
 }
 
 /**
index 29cdde48a4eb202d83baf8c21a43ef75b5ba5450..20f38e07458d413fd29fc75e55b095f5666b6c29 100644 (file)
@@ -263,6 +263,7 @@ INLINE BattFs * BATTFS_CAST(KFile *fd)
 }
 
 bool battfs_init(struct BattFsSuper *d);
+bool battfs_fsck(struct BattFsSuper *disk);
 bool battfs_close(struct BattFsSuper *disk);
 
 bool battfs_fileExists(BattFsSuper *disk, inode_t inode);
index 359b1e2a81798be9a9a6ee7a156373fea9465d58..927048b224f097a35c80fd84ac9bf418895eb83b 100644 (file)
@@ -152,6 +152,7 @@ static void testCheck(BattFsSuper *disk, pgcnt_t *reference)
                        exit(2);
                }
        }
+       ASSERT(battfs_fsck(disk));
        battfs_close(disk);
 }
 
@@ -182,7 +183,7 @@ static void disk1File(BattFsSuper *disk)
 
        for (int i = 0; i < PAGE_COUNT; i++)
        {
-               battfs_writeTestBlock(disk, i, 0, 0, 0, i);
+               battfs_writeTestBlock(disk, i, 0, 0, disk->data_size, i);
                ref[i] = i;
        }
        fclose(fp);
@@ -202,7 +203,7 @@ static void diskHalfFile(BattFsSuper *disk)
 
        for (int i = 0; i < PAGE_COUNT / 2; i++)
        {
-               battfs_writeTestBlock(disk, i, 0, 0, 0, i);
+               battfs_writeTestBlock(disk, i, 0, 0, disk->data_size, i);
                ref[i] = i;
        }
        fseek(fp, FILE_SIZE / 2, SEEK_SET);
@@ -229,9 +230,9 @@ static void oldSeq1(BattFsSuper *disk)
 
        fp = fopen(test_filename, "w+");
        // page, inode, seq, fill, pgoff
-       battfs_writeTestBlock(disk, 0, 0, 0, 0, 0);
-       battfs_writeTestBlock(disk, 1, 0, 0, 0, 1);
-       battfs_writeTestBlock(disk, 2, 0, 1, 0, 1);
+       battfs_writeTestBlock(disk, 0, 0, 0, disk->data_size, 0);
+       battfs_writeTestBlock(disk, 1, 0, 0, disk->data_size, 1);
+       battfs_writeTestBlock(disk, 2, 0, 1, disk->data_size, 1);
        disk->erase(disk, 3);
 
 
@@ -253,9 +254,9 @@ static void oldSeq2(BattFsSuper *disk)
 
        fp = fopen(test_filename, "w+");
        // page, inode, seq, fill, pgoff
-       battfs_writeTestBlock(disk, 0, 0, 0, 0, 0);
-       battfs_writeTestBlock(disk, 1, 0, 1, 0, 1);
-       battfs_writeTestBlock(disk, 2, 0, 0, 0, 1);
+       battfs_writeTestBlock(disk, 0, 0, 0, disk->data_size, 0);
+       battfs_writeTestBlock(disk, 1, 0, 1, disk->data_size, 1);
+       battfs_writeTestBlock(disk, 2, 0, 0, disk->data_size, 1);
        disk->erase(disk, 3);
 
        fclose(fp);
@@ -278,9 +279,9 @@ static void oldSeq3(BattFsSuper *disk)
 
        // page, inode, seq, fill, pgoff
        disk->erase(disk, 0);
-       battfs_writeTestBlock(disk, 1, 0, 0, 0, 0);
-       battfs_writeTestBlock(disk, 2, 0, 1, 0, 1);
-       battfs_writeTestBlock(disk, 3, 0, 0, 0, 1);
+       battfs_writeTestBlock(disk, 1, 0, 0, disk->data_size, 0);
+       battfs_writeTestBlock(disk, 2, 0, 1, disk->data_size, 1);
+       battfs_writeTestBlock(disk, 3, 0, 0, disk->data_size, 1);
 
 
        fclose(fp);
@@ -303,13 +304,13 @@ static void oldSeq2File(BattFsSuper *disk)
 
        // page, inode, seq, fill, pgoff
        disk->erase(disk, 0);
-       battfs_writeTestBlock(disk, 1, 0, 0, 0, 0);
-       battfs_writeTestBlock(disk, 2, 0, 3, 0, 1);
-       battfs_writeTestBlock(disk, 3, 0, 0, 0, 1);
+       battfs_writeTestBlock(disk, 1, 0, 0, disk->data_size, 0);
+       battfs_writeTestBlock(disk, 2, 0, 3, disk->data_size, 1);
+       battfs_writeTestBlock(disk, 3, 0, 0, disk->data_size, 1);
        disk->erase(disk, 4);
-       battfs_writeTestBlock(disk, 5, 4, 0, 0, 0);
-       battfs_writeTestBlock(disk, 6, 4, 1, 0, 1);
-       battfs_writeTestBlock(disk, 7, 4, 0, 0, 1);
+       battfs_writeTestBlock(disk, 5, 4, 0, disk->data_size, 0);
+       battfs_writeTestBlock(disk, 6, 4, 1, disk->data_size, 1);
+       battfs_writeTestBlock(disk, 7, 4, 0, disk->data_size, 1);
 
 
        fclose(fp);
@@ -387,6 +388,7 @@ static void openFile(BattFsSuper *disk)
        ASSERT(kfile_close(&fd1.fd) == 0);
        ASSERT(kfile_close(&fd2.fd) == 0);
        ASSERT(LIST_EMPTY(&disk->file_opened_list));
+       ASSERT(battfs_fsck(disk));
        ASSERT(battfs_close(disk));
 
        TRACEMSG("10: passed\n");
@@ -425,6 +427,7 @@ static void readFile(BattFsSuper *disk)
                ASSERT(buf[i] == 0xff);
 
        ASSERT(kfile_close(&fd1.fd) == 0);
+       ASSERT(battfs_fsck(disk));
        ASSERT(battfs_close(disk));
 
        TRACEMSG("11: passed\n");
@@ -484,6 +487,7 @@ static void readAcross(BattFsSuper *disk)
        ASSERT(fd1.fd.seek_pos = (kfile_off_t)fd1.fd.size);
 
        ASSERT(kfile_close(&fd1.fd) == 0);
+       ASSERT(battfs_fsck(disk));
        ASSERT(battfs_close(disk));
 
        TRACEMSG("12: passed\n");
@@ -531,6 +535,7 @@ static void writeFile(BattFsSuper *disk)
                ASSERT(buf[i] == i);
 
        ASSERT(kfile_close(&fd1.fd) == 0);
+       ASSERT(battfs_fsck(disk));
        ASSERT(battfs_close(disk));
 
        TRACEMSG("13: passed\n");
@@ -601,6 +606,7 @@ static void writeAcross(BattFsSuper *disk)
        ASSERT(fd1.fd.seek_pos == (kfile_off_t)sizeof(buf) * 3);
 
        ASSERT(kfile_close(&fd1.fd) == 0);
+       ASSERT(battfs_fsck(disk));
        ASSERT(battfs_close(disk));
 
        TRACEMSG("14: passed\n");
@@ -628,6 +634,7 @@ static void createFile(BattFsSuper *disk)
        ASSERT(fd1.fd.seek_pos == FILE_SIZE / 2);
        ASSERT(fd1.fd.size == FILE_SIZE / 2);
        ASSERT(kfile_close(&fd1.fd) == 0);
+       ASSERT(battfs_fsck(disk));
        ASSERT(battfs_close(disk));
 
        ASSERT(battfs_init(disk));
@@ -644,6 +651,7 @@ static void createFile(BattFsSuper *disk)
 
        ASSERT(fd1.fd.seek_pos == FILE_SIZE / 2);
        ASSERT(kfile_close(&fd1.fd) == 0);
+       ASSERT(battfs_fsck(disk));
        ASSERT(battfs_close(disk));
 
 
@@ -687,6 +695,7 @@ static void multipleWrite(BattFsSuper *disk)
                ASSERT(disk->free_bytes == disk->disk_size - sizeof(buf));
        }
        ASSERT(kfile_close(&fd1.fd) == 0);
+       ASSERT(battfs_fsck(disk));
        ASSERT(battfs_close(disk));
 
        ASSERT(battfs_init(disk));
@@ -698,6 +707,7 @@ static void multipleWrite(BattFsSuper *disk)
        for (unsigned i = 0; i < sizeof(buf); i++)
                        ASSERT(buf[i] == ((j-1+i) & 0xff));
        ASSERT(kfile_close(&fd1.fd) == 0);
+       ASSERT(battfs_fsck(disk));
        ASSERT(battfs_close(disk));
 
 
@@ -743,6 +753,7 @@ static void increaseFile(BattFsSuper *disk)
 
        ASSERT(kfile_close(&fd1.fd) == 0);
        ASSERT(kfile_close(&fd2.fd) == 0);
+       ASSERT(battfs_fsck(disk));
        ASSERT(battfs_close(disk));
 
        TRACEMSG("17: passed\n");
@@ -780,6 +791,7 @@ static void readEOF(BattFsSuper *disk)
        ASSERT(kfile_read(&fd1.fd, buf, sizeof(buf)) == 0);
 
        ASSERT(kfile_close(&fd1.fd) == 0);
+       ASSERT(battfs_fsck(disk));
        ASSERT(battfs_close(disk));
 
        TRACEMSG("18: passed\n");
@@ -858,6 +870,7 @@ static void writeEOF(BattFsSuper *disk)
                ASSERT(buf[i] == (i & 0xff));
 
        ASSERT(kfile_close(&fd1.fd) == 0);
+       ASSERT(battfs_fsck(disk));
        ASSERT(battfs_close(disk));
 
        TRACEMSG("19: passed\n");