From 1950a3ed38c9be32ec9f7a08042997325aca957a Mon Sep 17 00:00:00 2001 From: relan Date: Sat, 11 Mar 2017 09:52:30 +0300 Subject: [PATCH] Repairing: implement invalid VBR checksum fix. --- libexfat/exfat.h | 2 ++ libexfat/mount.c | 3 ++- libexfat/repair.c | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/libexfat/exfat.h b/libexfat/exfat.h index ff68465..d9bbbba 100644 --- a/libexfat/exfat.h +++ b/libexfat/exfat.h @@ -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 */ diff --git a/libexfat/mount.c b/libexfat/mount.c index eedb07c..4284aee 100644 --- a/libexfat/mount.c +++ b/libexfat/mount.c @@ -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; } diff --git a/libexfat/repair.c b/libexfat/repair.c index 10ec865..a7222cd 100644 --- a/libexfat/repair.c +++ b/libexfat/repair.c @@ -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; +} -- 2.11.0