Changeset View
Changeset View
Standalone View
Standalone View
head/sbin/fsck_msdosfs/dir.c
Show First 20 Lines • Show All 382 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Check an in-memory file entry | * Check an in-memory file entry | ||||
*/ | */ | ||||
static int | static int | ||||
checksize(struct fat_descriptor *fat, u_char *p, struct dosDirEntry *dir) | checksize(struct fat_descriptor *fat, u_char *p, struct dosDirEntry *dir) | ||||
{ | { | ||||
int ret = FSOK; | int ret = FSOK; | ||||
size_t physicalSize; | size_t chainsize; | ||||
u_int64_t physicalSize; | |||||
struct bootblock *boot; | struct bootblock *boot; | ||||
boot = fat_get_boot(fat); | boot = fat_get_boot(fat); | ||||
/* | /* | ||||
* Check size on ordinary files | * Check size on ordinary files | ||||
*/ | */ | ||||
if (dir->head == CLUST_FREE) { | if (dir->head == CLUST_FREE) { | ||||
physicalSize = 0; | physicalSize = 0; | ||||
} else { | } else { | ||||
if (!fat_is_valid_cl(fat, dir->head)) | if (!fat_is_valid_cl(fat, dir->head)) | ||||
return FSERROR; | return FSERROR; | ||||
ret = checkchain(fat, dir->head, &physicalSize); | ret = checkchain(fat, dir->head, &chainsize); | ||||
/* | /* | ||||
* Upon return, physicalSize would hold the chain length | * Upon return, chainsize would hold the chain length | ||||
* that checkchain() was able to validate, but if the user | * that checkchain() was able to validate, but if the user | ||||
* refused the proposed repair, it would be unsafe to | * refused the proposed repair, it would be unsafe to | ||||
* proceed with directory entry fix, so bail out in that | * proceed with directory entry fix, so bail out in that | ||||
* case. | * case. | ||||
*/ | */ | ||||
if (ret == FSERROR) { | if (ret == FSERROR) { | ||||
return (FSERROR); | return (FSERROR); | ||||
} | } | ||||
physicalSize *= boot->ClusterSize; | /* | ||||
* The maximum file size on FAT32 is 4GiB - 1, which | |||||
* will occupy a cluster chain of exactly 4GiB in | |||||
* size. On 32-bit platforms, since size_t is 32-bit, | |||||
* it would wrap back to 0. | |||||
*/ | |||||
physicalSize = (u_int64_t)chainsize * boot->ClusterSize; | |||||
} | } | ||||
if (physicalSize < dir->size) { | if (physicalSize < dir->size) { | ||||
pwarn("size of %s is %u, should at most be %zu\n", | pwarn("size of %s is %u, should at most be %zu\n", | ||||
fullpath(dir), dir->size, physicalSize); | fullpath(dir), dir->size, physicalSize); | ||||
if (ask(1, "Truncate")) { | if (ask(1, "Truncate")) { | ||||
dir->size = physicalSize; | dir->size = physicalSize; | ||||
p[28] = (u_char)physicalSize; | p[28] = (u_char)physicalSize; | ||||
p[29] = (u_char)(physicalSize >> 8); | p[29] = (u_char)(physicalSize >> 8); | ||||
▲ Show 20 Lines • Show All 738 Lines • Show Last 20 Lines |