aboutsummaryrefslogtreecommitdiff
path: root/util-linux/mkfs_vfat.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-28 12:17:20 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-28 12:17:20 +0000
commit781b672b372ade5c1903adbdc4de8dcb16a29a37 (patch)
tree5c8a1ee82fbd33e2eb99ca431f2c6a0d1bf3efde /util-linux/mkfs_vfat.c
parent70a2c8d5316a74d0d716495170a075df486b2cd9 (diff)
downloadbusybox-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.c21
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, &param); 331 int not_floppy = ioctl(dev, FDGETPRM, &param);
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",