Browse Source

Checking boot sector for dirty bit.

Some OSos use reseved byte of boot sector to set state of the file
system. If first bit set, then filesystem is proably damaged - write
operation was not finished/cache not snycted/...

Signed-off-by: Oleksij Rempel <bug-track@fisher-privat.net>
Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch>
Oleksij Rempel 11 years ago
parent
commit
ce2f8dc349
2 changed files with 43 additions and 0 deletions
  1. 41 0
      src/boot.c
  2. 2 0
      src/dosfsck.h

+ 41 - 0
src/boot.c

@@ -291,6 +291,45 @@ static void read_fsinfo(DOS_FS * fs, struct boot_sector *b, int lss)
 	fs->free_clusters = CF_LE_L(i.free_clusters);
 }
 
+static char print_fat_dirty_state(void)
+{
+    printf("Dirty bit is set. Fs was not properly unmounted and"
+           " some data may be corrupt.\n");
+
+    if (interactive) {
+        printf("1) Remove dirty bit\n"
+               "2) No action\n");
+        return get_key("12", "?");
+    } else
+        printf(" Automaticaly removing dirty bit.\n");
+    return '1';
+}
+
+static void check_fat_state_bit (DOS_FS *fs, void *b)
+{
+    if (fs->fat_bits == 32) {
+        struct boot_sector *b32 = b;
+
+        if (b32->reserved3 & FAT_STATE_DIRTY) {
+            printf("0x41: ");
+            if (print_fat_dirty_state() == '1') {
+                b32->reserved3 &= ~FAT_STATE_DIRTY;
+                fs_write(0, sizeof(*b32), b32);
+            }
+        }
+    } else {
+        struct boot_sector_16 *b16 = b;
+
+        if (b16->reserved2 & FAT_STATE_DIRTY) {
+            printf("0x25: ");
+            if (print_fat_dirty_state() == '1') {
+                b16->reserved2 &= ~FAT_STATE_DIRTY;
+                fs_write(0, sizeof(*b16), b16);
+            }
+        }
+    }
+}
+
 void read_boot(DOS_FS * fs)
 {
     struct boot_sector b;
@@ -363,6 +402,7 @@ void read_boot(DOS_FS * fs)
 		   "  This may lead to problems on some systems.\n",
 		   fs->clusters, FAT16_THRESHOLD);
 
+	check_fat_state_bit(fs, &b);
 	fs->backupboot_start = CF_LE_W(b.backup_boot) * logical_sector_size;
 	check_backup_boot(fs, &b, logical_sector_size);
 
@@ -373,6 +413,7 @@ void read_boot(DOS_FS * fs)
 	fs->fat_bits = (fs->clusters >= FAT12_THRESHOLD) ? 16 : 12;
 	if (fs->clusters >= FAT16_THRESHOLD)
 	    die("Too many clusters (%lu) for FAT16 filesystem.", fs->clusters);
+	check_fat_state_bit(fs, &b);
     } else {
 	/* On Atari, things are more difficult: GEMDOS always uses 12bit FATs
 	 * on floppies, and always 16 bit on harddisks. */

+ 2 - 0
src/dosfsck.h

@@ -57,6 +57,8 @@
 
 #define VFAT_LN_ATTR (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
 
+#define FAT_STATE_DIRTY 0x01
+
 /* ++roman: Use own definition of boot sector structure -- the kernel headers'
  * name for it is msdos_boot_sector in 2.0 and fat_boot_sector in 2.1 ... */
 struct boot_sector {