1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * Copyright (C) 2020 Hyunchul Lee <hyc.lee@gmail.com>
8 #include "exfat_ondisk.h"
13 struct exfat_repair_problem {
14 er_problem_code_t prcode;
15 const char *description;
16 bool (*fix_problem)(struct exfat *exfat,
17 union exfat_repair_context *rctx);
20 static bool fix_bs_checksum(struct exfat *exfat,
21 union exfat_repair_context *rctx)
26 size = EXFAT_SECTOR_SIZE(exfat->bs);
27 for (i = 0; i < size/sizeof(__le32); i++) {
28 ((__le32 *)rctx->bs_checksum.checksum_sect)[i] =
29 rctx->bs_checksum.checksum;
32 if (exfat_write(exfat->blk_dev->dev_fd,
33 rctx->bs_checksum.checksum_sect,
34 size, size * 11) != size) {
35 exfat_err("failed to write checksum sector\n");
42 static struct exfat_repair_problem problems[] = {
44 "the checksum of boot sector is not correct",
48 static struct exfat_repair_problem *find_problem(er_problem_code_t prcode)
52 for (i = 0; i < sizeof(problems)/sizeof(problems[0]); i++) {
53 if (problems[i].prcode == prcode) {
60 static bool ask_repair(struct exfat *exfat, struct exfat_repair_problem *pr)
64 switch (exfat->options & FSCK_OPTS_REPAIR) {
65 case FSCK_OPTS_REPAIR_ASK:
67 printf("%s: Fix (y/N)?", pr->description);
70 if (fgets(answer, sizeof(answer), stdin)) {
71 if (strcasecmp(answer, "Y\n") == 0)
73 else if (strcasecmp(answer, "\n") == 0 ||
74 strcasecmp(answer, "N\n") == 0)
79 case FSCK_OPTS_REPAIR_YES:
81 case FSCK_OPTS_REPAIR_NO:
89 bool exfat_repair(struct exfat *exfat, er_problem_code_t prcode,
90 union exfat_repair_context *rctx)
92 struct exfat_repair_problem *pr = NULL;
95 need_repair = ask_repair(exfat, pr);
99 pr = find_problem(prcode);
101 exfat_err("unknown problem code. %#x\n", prcode);
105 return pr->fix_problem(exfat, rctx);