git: 8a702ccda30d - stable/14 - MFC: fsck_msdosfs: fix status accounting for lost cluster chains
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 10 Sep 2026 02:32:13 UTC
The branch stable/14 has been updated by delphij:
URL: https://cgit.FreeBSD.org/src/commit/?id=8a702ccda30da602007db38f1ebf91e92d72fe52
commit 8a702ccda30da602007db38f1ebf91e92d72fe52
Author: Jie Li <sheng9qing@gmail.com>
AuthorDate: 2026-09-02 06:15:05 +0000
Commit: Xin LI <delphij@FreeBSD.org>
CommitDate: 2026-09-10 02:31:07 +0000
MFC: fsck_msdosfs: fix status accounting for lost cluster chains
(cherry picked from commit 6cf0d6c3b5777e053074200ff99dc4b750e62b96)
---
sbin/fsck_msdosfs/fat.c | 41 ++++++++++++++++++++++++++++++++---------
1 file changed, 32 insertions(+), 9 deletions(-)
diff --git a/sbin/fsck_msdosfs/fat.c b/sbin/fsck_msdosfs/fat.c
index bd8171043cc1..7d0ad9a595cf 100644
--- a/sbin/fsck_msdosfs/fat.c
+++ b/sbin/fsck_msdosfs/fat.c
@@ -1284,18 +1284,41 @@ checklost(struct fat_descriptor *fat)
}
if (fat_is_cl_head(fat, head)) {
ret = checkchain(fat, head, &chainlength);
- if (ret != FSERROR && chainlength > 0) {
- pwarn("Lost cluster chain at cluster %u\n"
- "%zd Cluster(s) lost\n",
- head, chainlength);
- mod |= ret = reconnect(fat, head,
- chainlength);
+ /*
+ * Record whether checkchain() has repaired the
+ * chain (FSFATMOD) or died trying (FSFATAL) before
+ * reconnect() overwrites ret, otherwise the repair
+ * is never written back.
+ */
+ if (ret != FSERROR) {
+ mod |= ret;
+ if (!(mod & FSFATAL) && chainlength > 0) {
+ pwarn(
+ "Lost cluster chain at cluster %u\n"
+ "%zd Cluster(s) lost\n",
+ head, chainlength);
+ ret = reconnect(fat, head, chainlength);
+ if (ret != FSERROR)
+ mod |= ret;
+ }
}
if (mod & FSFATAL)
break;
- if (ret == FSERROR && ask(0, "Clear")) {
- clearchain(fat, head);
- mod |= FSFATMOD;
+ /*
+ * If reconnect() failed (or checkchain() truncation
+ * was declined), defer folding FSERROR into mod until
+ * the Clear fallback is known: if the lost chain is
+ * cleared, the error has been resolved and must not
+ * report an exit code 8; otherwise record FSERROR as
+ * an unrecovered error.
+ */
+ if (ret == FSERROR) {
+ if (ask(0, "Clear")) {
+ clearchain(fat, head);
+ mod |= FSFATMOD;
+ } else {
+ mod |= FSERROR;
+ }
}
chains--;
}