OSDN Git Service

Repairing: implement invalid VBR checksum fix.
authorrelan <relan@users.noreply.github.com>
Sat, 11 Mar 2017 06:52:30 +0000 (09:52 +0300)
committerrelan <relan@users.noreply.github.com>
Sat, 15 Sep 2018 04:52:46 +0000 (07:52 +0300)
libexfat/exfat.h
libexfat/mount.c
libexfat/repair.c

index ff68465..d9bbbba 100644 (file)
@@ -234,5 +234,7 @@ void exfat_unix2exfat(time_t unix_time, le16_t* date, le16_t* time,
 void exfat_tzset(void);
 
 bool exfat_ask_to_fix(const struct exfat* ef);
+bool exfat_fix_invalid_vbr_checksum(const struct exfat* ef, void* sector,
+               uint32_t vbr_checksum);
 
 #endif /* ifndef EXFAT_H_INCLUDED */
index eedb07c..4284aee 100644 (file)
@@ -150,7 +150,8 @@ static bool verify_vbr_checksum(const struct exfat* ef, void* sector)
                {
                        exfat_error("invalid VBR checksum 0x%x (expected 0x%x)",
                                        le32_to_cpu(((const le32_t*) sector)[i]), vbr_checksum);
-                       return false;
+                       if (!EXFAT_REPAIR(invalid_vbr_checksum, ef, sector, vbr_checksum))
+                               return false;
                }
        return true;
 }
index 10ec865..a7222cd 100644 (file)
@@ -59,3 +59,20 @@ bool exfat_ask_to_fix(const struct exfat* ef)
        }
        exfat_bug("invalid repair option value: %d", ef->repair);
 }
+
+bool exfat_fix_invalid_vbr_checksum(const struct exfat* ef, void* sector,
+               uint32_t vbr_checksum)
+{
+       size_t i;
+       off_t sector_size = SECTOR_SIZE(*ef->sb);
+
+       for (i = 0; i < sector_size / sizeof(vbr_checksum); i++)
+               ((le32_t*) sector)[i] = cpu_to_le32(vbr_checksum);
+       if (exfat_pwrite(ef->dev, sector, sector_size, 11 * sector_size) < 0)
+       {
+               exfat_error("failed to write correct VBR checksum");
+               return false;
+       }
+       exfat_errors_fixed++;
+       return true;
+}