diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-28 12:17:20 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-28 12:17:20 +0000 |
commit | 781b672b372ade5c1903adbdc4de8dcb16a29a37 (patch) | |
tree | 5c8a1ee82fbd33e2eb99ca431f2c6a0d1bf3efde /util-linux/mkfs_vfat.c | |
parent | 70a2c8d5316a74d0d716495170a075df486b2cd9 (diff) | |
download | busybox-w32-781b672b372ade5c1903adbdc4de8dcb16a29a37.tar.gz busybox-w32-781b672b372ade5c1903adbdc4de8dcb16a29a37.tar.bz2 busybox-w32-781b672b372ade5c1903adbdc4de8dcb16a29a37.zip |
mkfs.vfat: fix a problem with over-estimating FAT size
Diffstat (limited to 'util-linux/mkfs_vfat.c')
-rw-r--r-- | util-linux/mkfs_vfat.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/util-linux/mkfs_vfat.c b/util-linux/mkfs_vfat.c index 30996b267..705c75c20 100644 --- a/util-linux/mkfs_vfat.c +++ b/util-linux/mkfs_vfat.c | |||
@@ -327,6 +327,7 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv) | |||
327 | volume_size_bytes >= ((off_t)8)*1024*1024*1024 ? 16 : | 327 | volume_size_bytes >= ((off_t)8)*1024*1024*1024 ? 16 : |
328 | volume_size_bytes >= 260*1024*1024 ? 8 : 1; | 328 | volume_size_bytes >= 260*1024*1024 ? 8 : 1; |
329 | } else { | 329 | } else { |
330 | // floppy, loop, or regular file | ||
330 | int not_floppy = ioctl(dev, FDGETPRM, ¶m); | 331 | int not_floppy = ioctl(dev, FDGETPRM, ¶m); |
331 | if (not_floppy == 0) { | 332 | if (not_floppy == 0) { |
332 | // floppy disk | 333 | // floppy disk |
@@ -367,12 +368,14 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv) | |||
367 | // Calculate number of clusters, sectors/cluster, sectors/FAT | 368 | // Calculate number of clusters, sectors/cluster, sectors/FAT |
368 | // (an initial guess for sect_per_clust should already be set) | 369 | // (an initial guess for sect_per_clust should already be set) |
369 | // | 370 | // |
370 | if ((off_t)(volume_size_sect - reserved_sect) < 16) // arbitrary limit | 371 | // "mkdosfs -v -F 32 image5k 5" is the minimum: |
372 | // 2 sectors for FATs and 2 data sectors | ||
373 | if ((off_t)(volume_size_sect - reserved_sect) < 4) | ||
371 | bb_error_msg_and_die("the image is too small for FAT32"); | 374 | bb_error_msg_and_die("the image is too small for FAT32"); |
372 | sect_per_fat = 1; | 375 | sect_per_fat = 1; |
373 | while (1) { | 376 | while (1) { |
374 | while (1) { | 377 | while (1) { |
375 | unsigned spf; | 378 | int spf_adj; |
376 | off_t tcl = (volume_size_sect - reserved_sect - NUM_FATS * sect_per_fat) / sect_per_clust; | 379 | off_t tcl = (volume_size_sect - reserved_sect - NUM_FATS * sect_per_fat) / sect_per_clust; |
377 | // tcl may be > MAX_CLUST_32 here, but it may be | 380 | // tcl may be > MAX_CLUST_32 here, but it may be |
378 | // because sect_per_fat is underestimated, | 381 | // because sect_per_fat is underestimated, |
@@ -382,8 +385,13 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv) | |||
382 | if (tcl > 0x7fffffff) | 385 | if (tcl > 0x7fffffff) |
383 | goto next; | 386 | goto next; |
384 | total_clust = tcl; // fits in uint32_t | 387 | total_clust = tcl; // fits in uint32_t |
385 | spf = ((total_clust + 2) * 4 + bytes_per_sect - 1) / bytes_per_sect; | 388 | spf_adj = ((total_clust + 2) * 4 + bytes_per_sect - 1) / bytes_per_sect - sect_per_fat; |
386 | if (spf <= sect_per_fat) { | 389 | #if 0 |
390 | bb_error_msg("sect_per_clust:%u sect_per_fat:%u total_clust:%u", | ||
391 | sect_per_clust, sect_per_fat, (int)tcl); | ||
392 | bb_error_msg("adjust to sect_per_fat:%d", spf_adj); | ||
393 | #endif | ||
394 | if (spf_adj <= 0) { | ||
387 | // do not need to adjust sect_per_fat. | 395 | // do not need to adjust sect_per_fat. |
388 | // so, was total_clust too big after all? | 396 | // so, was total_clust too big after all? |
389 | if (total_clust <= MAX_CLUST_32) | 397 | if (total_clust <= MAX_CLUST_32) |
@@ -392,7 +400,8 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv) | |||
392 | goto next; | 400 | goto next; |
393 | } | 401 | } |
394 | // adjust sect_per_fat, go back and recalc total_clust | 402 | // adjust sect_per_fat, go back and recalc total_clust |
395 | sect_per_fat = spf; | 403 | // (note: just "sect_per_fat += spf_adj" isn't ok) |
404 | sect_per_fat += ((unsigned)spf_adj / 2) | 1; | ||
396 | } | 405 | } |
397 | next: | 406 | next: |
398 | if (sect_per_clust == 128) | 407 | if (sect_per_clust == 128) |
@@ -409,7 +418,7 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv) | |||
409 | fprintf(stderr, | 418 | fprintf(stderr, |
410 | "Device '%s':\n" | 419 | "Device '%s':\n" |
411 | "heads:%u, sectors/track:%u, bytes/sector:%u\n" | 420 | "heads:%u, sectors/track:%u, bytes/sector:%u\n" |
412 | "media descriptor:0x%02x\n" | 421 | "media descriptor:%02x\n" |
413 | "total sectors:%"OFF_FMT"u, clusters:%u, sectors/cluster:%u\n" | 422 | "total sectors:%"OFF_FMT"u, clusters:%u, sectors/cluster:%u\n" |
414 | "FATs:2, sectors/FAT:%u\n" | 423 | "FATs:2, sectors/FAT:%u\n" |
415 | "volumeID:%08x, label:'%s'\n", | 424 | "volumeID:%08x, label:'%s'\n", |