diff options
author | Hyunchul Lee <hyc.lee@gmail.com> | 2021-05-03 15:25:51 +0900 |
---|---|---|
committer | Hyunchul Lee <hyc.lee@gmail.com> | 2022-08-26 05:57:05 +0900 |
commit | 05bc35b1c7d9e12776211f03fecb4ffdd362d8c5 (patch) | |
tree | b1a4f2577741030e419c0c0e83ac2de847a60ed3 | |
parent | 4e29696e73c16a4572ca22a4a43185c5e838523a (diff) | |
download | exfatprogs-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.c | 28 |
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; + } } } |