static void check_fs(char *blk_dev, char *type, char *target) { pid_t pid; int status; int ret; long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID; char *tmpmnt_opts = "nomblk_io_submit,errors=remount-ro"; /* Check for the types of filesystems we know how to check */ if (!strcmp(type, "ext2") || !strcmp(type, "ext3") || !strcmp(type, "ext4")) { /* * First try to mount and unmount the filesystem. We do this because * the kernel is more efficient than e2fsck in running the journal and * processing orphaned inodes, and on at least one device with a * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes * to do what the kernel does in about a second. * * After mounting and unmounting the filesystem, run e2fsck, and if an * error is recorded in the filesystem superblock, e2fsck will do a full * check. Otherwise, it does nothing. If the kernel cannot mount the * filesytsem due to an error, e2fsck is still run to do a full check * fix the filesystem. */ ret = mount(blk_dev, target, type, tmpmnt_flags, tmpmnt_opts); if (! ret) { umount(target); } else { setup_ext4(blk_dev); } INFO("Running %s on %s\n", E2FSCK_BIN, blk_dev); pid = fork(); if (pid > 0) { /* Parent, wait for the child to return */ waitpid(pid, &status, 0); } else if (pid == 0) { /* child, run checker */ execlp(E2FSCK_BIN, E2FSCK_BIN, "-y", blk_dev, (char *)NULL); /* Only gets here on error */ ERROR("Cannot run fs_mgr binary %s\n", E2FSCK_BIN); } else { /* No need to check for error in fork, we can't really handle it now */ ERROR("Fork failed trying to run %s\n", E2FSCK_BIN); } } return; }
static void check_fs(char *blk_device, char *fs_type, char *target, bool force_format, char *key_loc, bool is_crypttable) { int status; int ret; long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID; char *tmpmnt_opts = "nomblk_io_submit,errors=remount-ro"; char *e2fsck_argv[] = { E2FSCK_BIN, "-y", blk_device }; //reserve 1M for crypted partintion key off64_t key_loc_reserve=1048576; //partintion key is saved in 32768 before SEEK_END off64_t key_loc_pos_to_end=-32768; /* Check for the types of filesystems we know how to check */ if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) { /* * First try to mount and unmount the filesystem. We do this because * the kernel is more efficient than e2fsck in running the journal and * processing orphaned inodes, and on at least one device with a * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes * to do what the kernel does in about a second. * * After mounting and unmounting the filesystem, run e2fsck, and if an * error is recorded in the filesystem superblock, e2fsck will do a full * check. Otherwise, it does nothing. If the kernel cannot mount the * filesytsem due to an error, e2fsck is still run to do a full check * fix the filesystem. */ ret = mount(blk_device, target, fs_type, tmpmnt_flags, tmpmnt_opts); if (! ret) { umount(target); }else{ if (key_loc!=NULL && is_crypttable && !partition_wiped(blk_device)) { bool is_crypted=true; char magicBuf[4]= {0}; int databk=open(key_loc, O_RDONLY); if (databk<0) is_crypted=false; if (is_crypted && lseek64(databk,key_loc_pos_to_end,SEEK_END)<0) is_crypted=false; if (is_crypted && read(databk,magicBuf,4)<4) is_crypted=false; close(databk); if (is_crypted && magicBuf[0]==0xC4 && magicBuf[1]==0xB1 && magicBuf[2]==0xB5 && magicBuf[3]==0xD0) { // is cryptted INFO("%s is crypted\n", blk_device); goto out; } else setup_ext4(blk_device,0); } else if (key_loc!=NULL && !strcmp(key_loc,blk_device)) { setup_ext4(blk_device,key_loc_reserve); } else if (force_format) { setup_ext4(blk_device,0); } } INFO("Running %s on %s\n", E2FSCK_BIN, blk_device); ret = android_fork_execvp_ext(ARRAY_SIZE(e2fsck_argv), e2fsck_argv, &status, true, LOG_KLOG | LOG_FILE, true, FSCK_LOG_FILE); if (ret < 0) { /* No need to check for error in fork, we can't really handle it now */ ERROR("Failed trying to run %s\n", E2FSCK_BIN); } } out: return; }