summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dir.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/dir.c b/dir.c
index 0b26fd4..681859b 100644
--- a/dir.c
+++ b/dir.c
@@ -427,7 +427,8 @@ checksize(struct bootblock *boot, u_char *p,
*/
struct cluster_chain_descriptor *fat,tofind;
struct fatcache *cache;
- int32_t physicalSize;
+ u_int64_t physicalSize;
+ const u_int64_t max_physical_size = 0x100000000;
if (dir->head == CLUST_FREE)
physicalSize = 0;
@@ -440,12 +441,29 @@ checksize(struct bootblock *boot, u_char *p,
pwarn("Can't find the cluster chain with head(%u) \n",dir->head);
return FSERROR;
}
- physicalSize = fat->length * boot->ClusterSize;
+ physicalSize = ((u_int64_t)fat->length) * ((u_int64_t)boot->ClusterSize);
}
- if (physicalSize < dir->size) {
+ /*
+ *The file size means how much useful data the file contains
+ *FAT use 4 bytes to describe the file size, so the max file size is (4GBytes - 1).
+ *The physical size means how much space the file use in disk. The max physical
+ *size is 4GBytes.
+ *
+ *For example, we create a new file in WINDOWS,which size is 100Bytes, but i
+ *use 4KB in disk. Here 100B is file size ,and 4KB is physical size.
+ *
+ *Physical size = (file size + boot->ClusterSize - 1) & (boot->ClusterSize - 1)
+ */
+ if (physicalSize > max_physical_size) {
+ fsck_err("file %s physical size exceed 4 GBytes. %llu\n",
+ fullpath(dir), physicalSize);
+ return FSERROR;
+ }
+
+ if (physicalSize < (u_int64_t)dir->size) {
pwarn("size of %s is %u, should at most be %u\n",
fullpath(dir), dir->size, physicalSize);
- fsck_debug("physicalSize:%d ,dir->size = %d ,dir->head:0x%x\n",physicalSize,dir->size,dir->head);
+ fsck_debug("physicalSize:%llu ,dir->size = %d ,dir->head:0x%x\n",physicalSize,dir->size,dir->head);
if (ask(1, "Truncate")) {
dir->size = physicalSize;
p[28] = (u_char)physicalSize;
@@ -455,10 +473,10 @@ checksize(struct bootblock *boot, u_char *p,
return FSDIRMOD;
} else
return FSERROR;
- } else if (physicalSize - dir->size >= boot->ClusterSize) {
+ } else if (physicalSize - (u_int64_t)dir->size >= (u_int64_t)boot->ClusterSize) {
pwarn("%s has too many clusters allocated\n",
fullpath(dir));
- fsck_debug("physicalSize:%d ,dir->size = %d ,dir->head:0x%x\n",physicalSize,dir->size,dir->head);
+ fsck_debug("physicalSize:%llu ,dir->size = %d ,dir->head:0x%x\n",physicalSize,dir->size,dir->head);
if (ask(1, "Drop superfluous clusters")) {
cl_t cl;
u_int32_t sz = 0;
@@ -470,12 +488,9 @@ checksize(struct bootblock *boot, u_char *p,
if(cl == CLUST_EOF)
break;
}
- //cache = Find_nextclus(fat,cl,&cl);
if(!cache && !cl)
return FSERROR;
- //TODO: i don't no why exec clearchain here.when cl != fat.head,clear do nothing
- //clearchain(boot, fat,cl);
- //if trunc it ,when next fsck ,the rest will locate in LOST.DIR
+
Trunc(boot,fat,cl);
fsck_debug("after truncate ,fat->length = %d \n",fat->length);
return FSFATMOD;