system/core
リビジョン | 0959dea7d5bbb0071d5079882f8842787dd41a9d (tree) |
---|---|
日時 | 2019-03-05 14:42:50 |
作者 | Irina Patru <irina.patru@inte...> |
コミッター | Chih-Wei Huang |
UPSTREAM_PENDING newfs_msdos: Handle alignment failure
When trying to create a new FAT32 file system using alignment, the resulted
MBR structure is corrupted, because the total sectors reported does not
correspond to the actual available sectors. This is due to the reserved
sectors field which is updated during the alignment.
When fsck_msdos will try to check this file system, it will fail because it
cannot match the reported sectors with the actual available sectors.
Due to the failed check, the file system cannot be mounted by vold.
I/fsck_msdos( 2180): FAT size too small, 242822 entries won't fit into 1897 sectors
I/fsck_msdos( 2180): fsck_msdos terminated by exit(8)
E/Vold ( 2180): Filesystem check failed (unknown exit code 8)
E/Vold ( 2180): /dev/block/vold/179:49 failed FS checks (I/O error)
D/Vold ( 2180): Volume sdcard1 state changing 3 (Checking) -> 1 (Idle-Unmounted)
In order to fix this issue, we will save the initial bpb structure and restore
it if the alignment fails.
Change-Id: I58d5078551c689b28c9070585bb330c45bab9c62
Signed-off-by: Irina Patru <irina.patru@intel.com>
Reviewed-on: https://android.intel.com/256992
Reviewed-by: Dolca, Robert <robert.dolca@intel.com>
Reviewed-by: cactus <cactus@intel.com>
Reviewed-by: Popa, Valentin <valentin.popa@intel.com>
@@ -249,7 +249,7 @@ int newfs_msdos_main(int argc, char *argv[]) | ||
249 | 249 | char buf[MAXPATHLEN]; |
250 | 250 | struct stat sb; |
251 | 251 | struct timeval tv; |
252 | - struct bpb bpb; | |
252 | + struct bpb bpb, tempbpb; | |
253 | 253 | struct tm *tm; |
254 | 254 | struct bs *bs; |
255 | 255 | struct bsbpb *bsbpb; |
@@ -553,6 +553,7 @@ int newfs_msdos_main(int argc, char *argv[]) | ||
553 | 553 | set_spf = !bpb.bspf; |
554 | 554 | set_spc = !bpb.spc; |
555 | 555 | tempx = x; |
556 | + memset(&tempbpb, 0, sizeof(bpb)); | |
556 | 557 | /* |
557 | 558 | * Attempt to align if opt_A is set. This is done by increasing the number |
558 | 559 | * of reserved blocks. This can cause other factors to change, which can in |
@@ -600,10 +601,14 @@ int newfs_msdos_main(int argc, char *argv[]) | ||
600 | 601 | alignment = (bpb.res + bpb.bspf * bpb.nft) % bpb.spc; |
601 | 602 | extra_res += bpb.spc - alignment; |
602 | 603 | } |
603 | - attempts++; | |
604 | + if (++attempts == 1) | |
605 | + memcpy(&tempbpb, &bpb, sizeof(bpb)); | |
604 | 606 | } while(opt_A && alignment != 0 && attempts < 2); |
605 | - if (alignment != 0) | |
607 | + if (alignment != 0) { | |
606 | 608 | warnx("warning: Alignment failed."); |
609 | + /* return to data from first iteration */ | |
610 | + memcpy(&bpb, &tempbpb, sizeof(bpb)); | |
611 | + } | |
607 | 612 | |
608 | 613 | cls = (bpb.bsec - x1) / bpb.spc; |
609 | 614 | x = (u_int64_t)bpb.bspf * bpb.bps * NPB / (fat / BPN) - RESFTE; |