bool Fat::isFat32(int dosfs) { struct bootblock boot; if (!readboot(dosfs, &boot)) { return boot.flags & FAT32; } else { SLOGI("Not valid BPB. return NOT FAT32."); return false; } }
static int writelabel(void) { int i, fd, serrno; struct gctl_req *grq; char const *errstr; struct disklabel *lp = &lab; if (disable_write) { warnx("write to disk label suppressed - label was as follows:"); display(stdout, NULL); return (0); } lp->d_magic = DISKMAGIC; lp->d_magic2 = DISKMAGIC; lp->d_checksum = 0; lp->d_checksum = dkcksum(lp); if (installboot) readboot(); for (i = 0; i < lab.d_npartitions; i++) if (lab.d_partitions[i].p_size) lab.d_partitions[i].p_offset += lba_offset; bsd_disklabel_le_enc(bootarea + labeloffset + labelsoffset * lab.d_secsize, lp); fd = open(specname, O_RDWR); if (fd < 0) { if (is_file) { warn("cannot open file %s for writing label", specname); return(1); } else serrno = errno; if (geom_class_available("PART") != 0) { /* * Since we weren't able open provider for * writing, then recommend user to use gpart(8). */ warnc(serrno, "cannot open provider %s for writing label", specname); warnx("Try to use gpart(8)."); return (1); } /* Give up if GEOM_BSD is not available. */ if (geom_class_available("BSD") == 0) { warnc(serrno, "%s", specname); return (1); } grq = gctl_get_handle(); gctl_ro_param(grq, "verb", -1, "write label"); gctl_ro_param(grq, "class", -1, "BSD"); gctl_ro_param(grq, "geom", -1, pname); gctl_ro_param(grq, "label", 148+16*8, bootarea + labeloffset + labelsoffset * lab.d_secsize); errstr = gctl_issue(grq); if (errstr != NULL) { warnx("%s", errstr); gctl_free(grq); return(1); } gctl_free(grq); if (installboot) { grq = gctl_get_handle(); gctl_ro_param(grq, "verb", -1, "write bootcode"); gctl_ro_param(grq, "class", -1, "BSD"); gctl_ro_param(grq, "geom", -1, pname); gctl_ro_param(grq, "bootcode", BBSIZE, bootarea); errstr = gctl_issue(grq); if (errstr != NULL) { warnx("%s", errstr); gctl_free(grq); return (1); } gctl_free(grq); } } else { if (write(fd, bootarea, bbsize) != bbsize) { warn("write %s", specname); close (fd); return (1); } close (fd); } return (0); }
int checkfilesys(const char *fname) { int dosfs; struct bootblock boot; struct fatEntry *fat = NULL; int finish_dosdirsection=0; u_int i; int mod = 0; int ret = 8; rdonly = alwaysno; if (!preen) printf("** %s", fname); dosfs = open(fname, rdonly ? O_RDONLY : O_RDWR, 0); if (dosfs < 0 && !rdonly) { dosfs = open(fname, O_RDONLY, 0); if (dosfs >= 0) pwarn(" (NO WRITE)\n"); else if (!preen) printf("\n"); rdonly = 1; } else if (!preen) printf("\n"); if (dosfs < 0) { perror("Can't open"); return 8; } if (readboot(dosfs, &boot) != FSOK) { close(dosfs); printf("\n"); return 8; } if (skipclean && preen && checkdirty(dosfs, &boot)) { printf("%s: ", fname); printf("FILESYSTEM CLEAN; SKIPPING CHECKS\n"); ret = 0; goto out; } if (!preen) { if (boot.ValidFat < 0) printf("** Phase 1 - Read and Compare FATs\n"); else printf("** Phase 1 - Read FAT\n"); } mod |= readfat(dosfs, &boot, boot.ValidFat >= 0 ? boot.ValidFat : 0, &fat); if (mod & FSFATAL) { close(dosfs); return 8; } if (boot.ValidFat < 0) for (i = 1; i < boot.bpbFATs; i++) { struct fatEntry *currentFat; mod |= readfat(dosfs, &boot, i, ¤tFat); if (mod & FSFATAL) goto out; mod |= comparefat(&boot, fat, currentFat, i); free(currentFat); if (mod & FSFATAL) goto out; } if (!preen) printf("** Phase 2 - Check Cluster Chains\n"); mod |= checkfat(&boot, fat); if (mod & FSFATAL) goto out; /* delay writing FATs */ if (!preen) printf("** Phase 3 - Checking Directories\n"); mod |= resetDosDirSection(&boot, fat); finish_dosdirsection = 1; if (mod & FSFATAL) goto out; /* delay writing FATs */ mod |= handleDirTree(dosfs, &boot, fat); if (mod & FSFATAL) goto out; if (!preen) printf("** Phase 4 - Checking for Lost Files\n"); mod |= checklost(dosfs, &boot, fat); if (mod & FSFATAL) goto out; /* now write the FATs */ if (mod & FSFATMOD) { if (ask(1, "Update FATs")) { mod |= writefat(dosfs, &boot, fat, mod & FSFIXFAT); if (mod & FSFATAL) goto out; } else mod |= FSERROR; } if (boot.NumBad) pwarn("%d files, %d free (%d clusters), %d bad (%d clusters)\n", boot.NumFiles, boot.NumFree * boot.ClusterSize / 1024, boot.NumFree, boot.NumBad * boot.ClusterSize / 1024, boot.NumBad); else pwarn("%d files, %d free (%d clusters)\n", boot.NumFiles, boot.NumFree * boot.ClusterSize / 1024, boot.NumFree); if (mod && (mod & FSERROR) == 0) { if (mod & FSDIRTY) { if (ask(1, "MARK FILE SYSTEM CLEAN") == 0) mod &= ~FSDIRTY; if (mod & FSDIRTY) { pwarn("MARKING FILE SYSTEM CLEAN\n"); mod |= writefat(dosfs, &boot, fat, 1); } else { pwarn("\n***** FILE SYSTEM IS LEFT MARKED AS DIRTY *****\n"); mod |= FSERROR; /* file system not clean */ } } } if (mod & (FSFATAL | FSERROR)) goto out; ret = 0; out: if (finish_dosdirsection) finishDosDirSection(); free(fat); close(dosfs); if (mod & (FSFATMOD|FSDIRMOD)) pwarn("\n***** FILE SYSTEM WAS MODIFIED *****\n"); return ret; }
int checkfilesys(const char *fname) { int dosfs; struct bootblock boot; struct fatEntry *fat = NULL; int i; int mod = 0; int quiet = 0; int skip_fat_compare = 0; rdonly = alwaysno; if (!quiet) printf("** %s", fname); dosfs = open(fname, rdonly ? O_RDONLY : O_RDWR, 0); if (dosfs < 0 && !rdonly) { xlog_printf(ANDROID_LOG_INFO, FSCK_XLOG_TAG, "dosfs < 0 && !rdonly"); dosfs = open(fname, O_RDONLY, 0); if (dosfs >= 0) pwarn(" (NO WRITE)\n"); else if (!quiet) printf("\n"); rdonly = 1; } else if (!quiet) printf("\n"); if (dosfs < 0) { perror("Can't open"); printf("%s() : Cannot open %s\n", __func__, fname) ; return 8; } if (readboot(dosfs, &boot) == FSFATAL) { close(dosfs); printf("\n"); return 8; } if (skipclean && preen && checkdirty(dosfs, &boot)) { printf("%s: ", fname); printf("FILESYSTEM CLEAN; SKIPPING CHECKS\n"); close(dosfs); return 0; } if (((boot.FATsecs * boot.BytesPerSec) / 1024) > FAT_COMPARE_MAX_KB) { xlog_printf(ANDROID_LOG_INFO, FSCK_XLOG_TAG, " - ((boot.FATsecs * boot.BytesPerSec) / 1024) = %d > FAT_COMPARE_MAX_KB(%d)", ((boot.FATsecs * boot.BytesPerSec) / 1024), FAT_COMPARE_MAX_KB ); xlog_printf(ANDROID_LOG_INFO, FSCK_XLOG_TAG, " - Skip FAT compare!") ; skip_fat_compare = 1; } start_count(&fsck_p1_time) ; if (!quiet) { if (skip_fat_compare) printf("** Phase 1 - Read FAT (compare skipped)\n"); else if (boot.ValidFat < 0) printf("** Phase 1 - Read and Compare FATs\n"); else printf("** Phase 1 - Read FAT\n"); } mod |= readfat(dosfs, &boot, boot.ValidFat >= 0 ? boot.ValidFat : 0, &fat); if (mod & FSERROR) { printf("FSERROR after readfat()\n"); } if (mod & FSFATAL) { printf("\nFatal error during readfat()\n"); close(dosfs); return 8; } if (!skip_fat_compare && boot.ValidFat < 0) for (i = 1; i < (int)boot.FATs; i++) { struct fatEntry *currentFat; mod |= readfat(dosfs, &boot, i, ¤tFat); if (mod & FSFATAL) { printf("Fatal error during readfat() for comparison\n"); free(fat); (void)close(dosfs); return 8; } mod |= comparefat(&boot, fat, currentFat, i); free(currentFat); if (mod & FSFATAL) { printf("Fatal error during FAT comparison\n"); free(fat); (void)close(dosfs); return 8; } } end_count("Phase#1", &fsck_p1_time) ; start_count(&fsck_p2_time) ; if (!quiet) printf("** Phase 2 - Check Cluster Chains\n"); mod |= checkfat(&boot, fat); if (mod & FSERROR) { printf("FSERROR after checkfat()\n"); } if (mod & FSFATAL) { printf("Fatal error during FAT check\n"); free(fat); (void)close(dosfs); return 8; } end_count("Phase#2", &fsck_p2_time) ; /* delay writing FATs */ start_count(&fsck_p3_time) ; if (!quiet) printf("** Phase 3 - Checking Directories\n"); mod |= resetDosDirSection(&boot, fat); if (mod & FSERROR) { printf("FSERROR after resetDosDirSection()\n"); } if (mod & FSFATAL) { printf("Fatal error during resetDosDirSection()\n"); free(fat); close(dosfs); return 8; } /* delay writing FATs */ mod |= handleDirTree(dosfs, &boot, fat); if (mod & FSERROR) { printf("FSERROR after handleDirTree()\n"); /* try to recovery again */ mod &= ~FSERROR; mod |= handleDirTree(dosfs, &boot, fat); } if (mod & FSFATAL) { printf("Fatal error during handleDirTree()\n"); finishDosDirSection(); free(fat); close(dosfs); return 8; } end_count("Phase#3", &fsck_p3_time) ; start_count(&fsck_p4_time) ; if (!quiet) printf("** Phase 4 - Checking for Lost Files\n"); mod |= checklost(dosfs, &boot, fat); if (mod & FSERROR) { printf("FSERROR after checklost()\n"); } if (mod & FSFATAL) { printf("Fatal error during checklost()\n"); finishDosDirSection(); free(fat); (void)close(dosfs); return 8; } end_count("Phase#4", &fsck_p4_time) ; /* now write the FATs */ if (mod & FSFATMOD) { if (ask(1, "Update FATs")) { mod |= writefat(dosfs, &boot, fat, mod & FSFIXFAT); if (mod & FSFATAL) { printf("Fatal error during writefat()\n"); finishDosDirSection(); free(fat); (void)close(dosfs); return 8; } } else mod |= FSERROR; } if (boot.NumBad) pwarn("%d files, %d free (%d clusters), %d bad (%d clusters)\n", boot.NumFiles, boot.NumFree * boot.ClusterSize / 1024, boot.NumFree, boot.NumBad * boot.ClusterSize / 1024, boot.NumBad); else pwarn("%d files, %d free (%d clusters)\n", boot.NumFiles, boot.NumFree * boot.ClusterSize / 1024, boot.NumFree); if (mod && (mod & FSERROR) == 0) { if (mod & FSDIRTY) { if (ask(1, "MARK FILE SYSTEM CLEAN") == 0) mod &= ~FSDIRTY; if (mod & FSDIRTY) { pwarn("MARKING FILE SYSTEM CLEAN\n"); mod |= writefat(dosfs, &boot, fat, 1); } else { pwarn("\n***** FILE SYSTEM IS LEFT MARKED AS DIRTY *****\n"); mod |= FSERROR; /* file system not clean */ } } } finishDosDirSection(); free(fat); (void)close(dosfs); if (mod & FSFATAL) { pwarn("\n***** FSFATAL *****\n"); return 8; } if (mod & FSERROR) { pwarn("\n***** FSERROR *****\n"); return 8; } if (mod) { pwarn("\n***** FILE SYSTEM WAS MODIFIED *****\n"); return 4; } return 0; }
int Fat::check(const char *fsPath) { bool rw = true; if (access(FSCK_MSDOS_PATH, X_OK)) { SLOGW("Skipping fs checks\n"); return 0; } #ifdef FSCK_MSDOS_MTK SLOGI("-- MTK_FSCK_MSDOS_MTK enabled--"); int fsck_enhanced = 0 ; // 0 : original ver(fsck_msdos), 1 : enhanced ver(fsck_msdos_mtk) if (access(FSCK_MSDOS_MTK_PATH, X_OK)) { SLOGW("Because %s does not exist, we just use fsck_msdos (original ver.)", FSCK_MSDOS_MTK_PATH) ; fsck_enhanced = 0 ; } else { SLOGI("vold:fat:check fs = %s\n", fsPath) ; int fd = open(fsPath, O_RDONLY); if(fd < 0) { SLOGW("Because cannot read dev, we just use fsck_msdos (original ver.)") ; fsck_enhanced = 0 ; } else { struct bootblock boot ; if(readboot(fd, &boot) == 0) { if(boot.ClustMask == 0xfff) { SLOGW("Because fsck_msdos_mtk only supports FAT32, but this is FAT12!") ; SLOGW("We still use fsck_msdos for FAT12!") ; fsck_enhanced = 0 ; } else if(boot.ClustMask == 0xffff) { SLOGW("Because fsck_msdos_mtk only supports FAT32, but this is FAT16!") ; SLOGW("We still use fsck_msdos for FAT16!") ; fsck_enhanced = 0 ; } else { SLOGW("We always use fsck_msdos_mtk for FAT32 now!") ; fsck_enhanced = 1 ; } /*if(boot.NumClusters * 16 > 8*1024*1024) { SLOGI("It may need %d bytes ! It is too much ! Try enhanced fsck -- fsck_msdos_mtk !", boot.NumClusters * 16) ; fsck_enhanced = 1 ; } else SLOGW("Use fsck_msdos (original ver.)") ; */ } close(fd) ; } } #endif int pass = 1; int rc = 0; do { const char *args[5]; #ifdef FSCK_MSDOS_MTK if(fsck_enhanced) args[0] = FSCK_MSDOS_MTK_PATH; else #endif args[0] = FSCK_MSDOS_PATH; args[1] = "-p"; args[2] = "-f"; args[3] = fsPath; args[4] = NULL; rc = logwrap(4, args, 1); switch(rc) { case 0: SLOGI("Filesystem check completed OK"); return 0; case 2: SLOGE("Filesystem check failed (not a FAT filesystem)"); errno = ENODATA; return -1; case 4: if (pass++ <= 3) { SLOGW("Filesystem modified - rechecking (pass %d)", pass); continue; } SLOGE("Failing check after too many rechecks"); errno = EIO; return -1; default: SLOGE("Filesystem check failed (unknown exit code %d)", rc); errno = EIO; return -1; } } while (1); return 0; }
bool Fat::checkFatMeta( int dosfs) { struct bootblock boot; return (readboot(dosfs, &boot) == 0); }
int checkfilesys(const char *fname) { int dosfs; struct bootblock boot; struct fatEntry *fat = NULL; int i; int mod = 0; rdonly = alwaysno; if (!preen) printf("** %s", fname); dosfs = open(fname, rdonly ? O_RDONLY : O_RDWR, 0); if (dosfs < 0 && !rdonly) { dosfs = open(fname, O_RDONLY, 0); if (dosfs >= 0) pwarn(" (NO WRITE)\n"); else if (!preen) printf("\n"); rdonly = 1; } else if (!preen) printf("\n"); if (dosfs < 0) { xperror("Can't open"); return (8); } if (readboot(dosfs, &boot) != FSOK) { (void)close(dosfs); return (8); } if (!preen) { if (boot.ValidFat < 0) printf("** Phase 1 - Read and Compare FATs\n"); else printf("** Phase 1 - Read FAT\n"); } mod |= readfat(dosfs, &boot, boot.ValidFat >= 0 ? boot.ValidFat : 0, &fat); if (mod & FSFATAL) { (void)close(dosfs); return 8; } if (boot.ValidFat < 0) for (i = 1; i < boot.FATs; i++) { struct fatEntry *currentFat; mod |= readfat(dosfs, &boot, i, ¤tFat); if (mod & FSFATAL) { free(fat); (void)close(dosfs); return 8; } mod |= comparefat(&boot, fat, currentFat, i); free(currentFat); if (mod & FSFATAL) { free(fat); (void)close(dosfs); return (8); } } if (!preen) printf("** Phase 2 - Check Cluster Chains\n"); mod |= checkfat(&boot, fat); if (mod & FSFATAL) { free(fat); (void)close(dosfs); return (8); } if (mod & FSFATMOD) mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ if (mod & FSFATAL) { free(fat); (void)close(dosfs); return (8); } if (!preen) printf("** Phase 3 - Check Directories\n"); mod |= resetDosDirSection(&boot, fat); if (mod & FSFATAL) { free(fat); close(dosfs); return 8; } if (mod & FSFATMOD) mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ if (mod & FSFATAL) { finishDosDirSection(); free(fat); (void)close(dosfs); return (8); } mod |= handleDirTree(dosfs, &boot, fat); if (mod & FSFATAL) { finishDosDirSection(); free(fat); (void)close(dosfs); return (8); } if (!preen) printf("** Phase 4 - Check for Lost Files\n"); mod |= checklost(dosfs, &boot, fat); if (mod & FSFATAL) { finishDosDirSection(); free(fat); (void)close(dosfs); return 8; } if (mod & FSFATMOD) mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ finishDosDirSection(); free(fat); (void)close(dosfs); if (mod & FSFATAL) return 8; if (boot.NumBad) pwarn("%d files, %d free (%d clusters), %d bad (%d clusters)\n", boot.NumFiles, boot.NumFree * boot.ClusterSize / 1024, boot.NumFree, boot.NumBad * boot.ClusterSize / 1024, boot.NumBad); else pwarn("%d files, %d free (%d clusters)\n", boot.NumFiles, boot.NumFree * boot.ClusterSize / 1024, boot.NumFree); if (mod & (FSFATAL | FSERROR)) return (8); if (mod) { pwarn("\n***** FILE SYSTEM WAS MODIFIED *****\n"); return (4); } return (0); }