From: Richard Jones Date: Thu, 3 Jun 2010 13:03:08 +0000 (+0100) Subject: mkfs-b: Map block size to cluster size for VFAT and NTFS partitions (RHBZ#599464). X-Git-Tag: 1.3.19~6 X-Git-Url: http://git.annexia.org/?a=commitdiff_plain;h=4d5c22800214008b229e937dada2299de8353d9e;p=libguestfs.git mkfs-b: Map block size to cluster size for VFAT and NTFS partitions (RHBZ#599464). This also adds a regression test for VFAT and (conditionally) NTFS filesystems. --- diff --git a/daemon/mkfs.c b/daemon/mkfs.c index 2c3a3cd..ad3014c 100644 --- a/daemon/mkfs.c +++ b/daemon/mkfs.c @@ -102,17 +102,46 @@ int do_mkfs_b (const char *fstype, int blocksize, const char *device) { const char *extra[2]; - char blocksize_s[32]; + char n[32]; if (blocksize <= 0 || !is_power_of_2 (blocksize)) { reply_with_error ("block size must be > 0 and a power of 2"); return -1; } - snprintf (blocksize_s, sizeof blocksize_s, "%d", blocksize); - - extra[0] = "-b"; - extra[1] = blocksize_s; + if (STREQ (fstype, "vfat") || + STREQ (fstype, "msdos")) { + /* For VFAT map the blocksize into a cluster size. However we + * have to determine the block device sector size in order to do + * this. + */ + int sectorsize = do_blockdev_getss (device); + if (sectorsize == -1) + return -1; + + int sectors_per_cluster = blocksize / sectorsize; + if (sectors_per_cluster < 1 || sectors_per_cluster > 128) { + reply_with_error ("unsupported cluster size for %s filesystem (requested cluster size = %d, sector size = %d, trying sectors per cluster = %d)", + fstype, blocksize, sectorsize, sectors_per_cluster); + return -1; + } + + snprintf (n, sizeof n, "%d", sectors_per_cluster); + extra[0] = "-s"; + extra[1] = n; + } + else if (STREQ (fstype, "ntfs")) { + /* For NTFS map the blocksize into a cluster size. */ + snprintf (n, sizeof n, "%d", blocksize); + extra[0] = "-c"; + extra[1] = n; + } + else { + /* For all other filesystem types, try the -b option. */ + snprintf (n, sizeof n, "%d", blocksize); + extra[0] = "-b"; + extra[1] = n; + } return mkfs (fstype, device, extra, 2); } diff --git a/src/generator.ml b/src/generator.ml index 4d74cb0..ec6123a 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -3732,13 +3732,28 @@ and C"); ["mkfs_b"; "ext2"; "4096"; "/dev/sda1"]; ["mount_options"; ""; "/dev/sda1"; "/"]; ["write"; "/new"; "new file contents"]; - ["cat"; "/new"]], "new file contents")], + ["cat"; "/new"]], "new file contents"); + InitEmpty, Always, TestRun ( + [["part_disk"; "/dev/sda"; "mbr"]; + ["mkfs_b"; "vfat"; "32768"; "/dev/sda1"]]); + InitEmpty, Always, TestLastFail ( + [["part_disk"; "/dev/sda"; "mbr"]; + ["mkfs_b"; "vfat"; "32769"; "/dev/sda1"]]); + InitEmpty, Always, TestLastFail ( + [["part_disk"; "/dev/sda"; "mbr"]; + ["mkfs_b"; "vfat"; "33280"; "/dev/sda1"]]); + InitEmpty, IfAvailable "ntfsprogs", TestRun ( + [["part_disk"; "/dev/sda"; "mbr"]; + ["mkfs_b"; "ntfs"; "32768"; "/dev/sda1"]])], "make a filesystem with block size", "\ This call is similar to C, but it allows you to control the block size of the resulting filesystem. Supported block sizes depend on the filesystem type, but typically they -are C<1024>, C<2048> or C<4096> only."); +are C<1024>, C<2048> or C<4096> only. + +For VFAT and NTFS the C parameter is treated as +the requested cluster size."); ("mke2journal", (RErr, [Int "blocksize"; Device "device"]), 188, [], [InitEmpty, Always, TestOutput (