+ return ret;
+}
+
+static int restore_boot_region(struct exfat_blk_dev *bd)
+{
+ int i;
+ char *sector;
+
+ sector = malloc(bd->sector_size);
+ if (!sector)
+ return -ENOMEM;
+
+ for (i = 0; i < 12; i++) {
+ if (exfat_read(bd->dev_fd, sector, bd->sector_size,
+ BACKUP_BOOT_SEC_IDX * bd->sector_size +
+ i * bd->sector_size) !=
+ (ssize_t)bd->sector_size)
+ return -EIO;
+ if (i == 0)
+ ((struct pbr *)sector)->bsx.perc_in_use = 0xff;
+
+ if (exfat_write(bd->dev_fd, sector, bd->sector_size,
+ BOOT_SEC_IDX * bd->sector_size +
+ i * bd->sector_size) !=
+ (ssize_t)bd->sector_size)
+ return -EIO;
+ }
+ if (fsync(bd->dev_fd))
+ return -EIO;
+ free(sector);
+ return 0;
+}
+
+static int exfat_boot_region_check(struct exfat *exfat, struct pbr **bs)
+{
+ int ret;
+
+ ret = read_boot_region(exfat->blk_dev, bs, BOOT_SEC_IDX);
+ if (ret == -EINVAL && exfat_repair_ask(exfat, ER_BS_BOOT_REGION,
+ "boot region is corrupted. try to restore the region from backup"
+ )) {
+ ret = read_boot_region(exfat->blk_dev, bs, BACKUP_BOOT_SEC_IDX);
+ if (ret < 0) {
+ exfat_err("backup boot region is also corrupted\n");
+ return ret;
+ }
+ ret = restore_boot_region(exfat->blk_dev);
+ if (ret < 0) {
+ exfat_err("failed to restore boot region from backup\n");
+ free(*bs);
+ *bs = NULL;
+ return ret;
+ }
+ }
+ return ret;