aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHyunchul Lee <hyc.lee@gmail.com>2021-05-03 15:25:51 +0900
committerHyunchul Lee <hyc.lee@gmail.com>2022-08-26 05:57:05 +0900
commit05bc35b1c7d9e12776211f03fecb4ffdd362d8c5 (patch)
treeb1a4f2577741030e419c0c0e83ac2de847a60ed3
parent4e29696e73c16a4572ca22a4a43185c5e838523a (diff)
downloadexfatprogs-05bc35b1c7d9e12776211f03fecb4ffdd362d8c5.tar.gz
fsck: handle bad clusters properly in check_clus_chain()
Truncate a NotFat file if a next cluster is BAD, And even if a next cluster is out of range, allocate the cluster to a file Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com>
-rw-r--r--fsck/fsck.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/fsck/fsck.c b/fsck/fsck.c
index e3b603b..7c469af 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -480,19 +480,31 @@ static int check_clus_chain(struct exfat *exfat, struct exfat_inode *node)
/* This cluster is allocated or not */
if (get_next_clus(exfat, node, clus, &next))
goto truncate_file;
- if (!node->is_contiguous) {
- if (!heap_clus(exfat, next) &&
- next != EXFAT_EOF_CLUSTER) {
+ if (next == EXFAT_BAD_CLUSTER) {
+ if (repair_file_ask(&exfat->de_iter, node,
+ ER_FILE_INVALID_CLUS,
+ "BAD cluster. truncate to %"
+ PRIu64 " bytes",
+ count * exfat->clus_size))
+ goto truncate_file;
+ else
+ return -EINVAL;
+ } else if (!node->is_contiguous) {
+ if (next != EXFAT_EOF_CLUSTER &&
+ !heap_clus(exfat, next)) {
if (repair_file_ask(&exfat->de_iter, node,
ER_FILE_INVALID_CLUS,
- "broken cluster chain. "
- "truncate to %"
+ "broken cluster chain. truncate to %"
PRIu64 " bytes",
- count * exfat->clus_size))
+ (count + 1) * exfat->clus_size)) {
+ count++;
+ prev = clus;
+ EXFAT_BITMAP_SET(exfat->alloc_bitmap,
+ clus - EXFAT_FIRST_CLUSTER);
goto truncate_file;
-
- else
+ } else {
return -EINVAL;
+ }
}
}