#include <linux/fd.h>
#endif
-#if defined(__linux__) && defined(_IO) && !defined(BLKSSZGET)
+#if defined(__linux__) && defined(_IO)
+#if !defined(BLKSSZGET)
#define BLKSSZGET _IO(0x12,104)/* get block device sector size */
#endif
+#if !defined(BLKPBSZGET)
+#define BLKPBSZGET _IO(0x12,123)/* get block physical sector size */
+#endif
+#endif
#include "ext2_fs.h"
#include "ext2fs.h"
/*
- * Returns the number of blocks in a partition
+ * Returns the logical sector size of a device
*/
errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize)
{
close(fd);
return 0;
}
+
+/*
+ * Returns the physical sector size of a device
+ */
+errcode_t ext2fs_get_device_phys_sectsize(const char *file, int *sectsize)
+{
+ int fd;
+
+#ifdef HAVE_OPEN64
+ fd = open64(file, O_RDONLY);
+#else
+ fd = open(file, O_RDONLY);
+#endif
+ if (fd < 0)
+ return errno;
+
+#ifdef BLKPBSZGET
+ if (ioctl(fd, BLKPBSZGET, sectsize) >= 0) {
+ close(fd);
+ return 0;
+ }
+#endif
+ *sectsize = 0;
+ close(fd);
+ return 0;
+}
int main(int argc, char **argv)
{
- int sectsize;
+ int lsectsize, psectsize;
int retval;
if (argc < 2) {
exit(1);
}
- retval = ext2fs_get_device_sectsize(argv[1], §size);
+ retval = ext2fs_get_device_sectsize(argv[1], &lsectsize);
if (retval) {
com_err(argv[0], retval,
"while calling ext2fs_get_device_sectsize");
exit(1);
}
- printf("Device %s has a hardware sector size of %d.\n",
- argv[1], sectsize);
+ retval = ext2fs_get_device_phys_sectsize(argv[1], &psectsize);
+ if (retval) {
+ com_err(argv[0], retval,
+ "while calling ext2fs_get_device_phys_sectsize");
+ exit(1);
+ }
+ printf("Device %s has logical/physical sector size of %d/%d.\n",
+ argv[1], lsectsize, psectsize);
exit(0);
}
int inode_size = 0;
unsigned long flex_bg_size = 0;
double reserved_ratio = 5.0;
- int sector_size = 0;
+ int lsector_size = 0, psector_size = 0;
int show_version_only = 0;
unsigned long long num_inodes = 0; /* unsigned long long to catch too-large input */
errcode_t retval;
((tmp = getenv("MKE2FS_FIRST_META_BG"))))
fs_param.s_first_meta_bg = atoi(tmp);
- /* Get the hardware sector size, if available */
- retval = ext2fs_get_device_sectsize(device_name, §or_size);
+ /* Get the hardware sector sizes, if available */
+ retval = ext2fs_get_device_sectsize(device_name, &lsector_size);
if (retval) {
com_err(program_name, retval,
_("while trying to determine hardware sector size"));
exit(1);
}
+ retval = ext2fs_get_device_phys_sectsize(device_name, &psector_size);
+ if (retval) {
+ com_err(program_name, retval,
+ _("while trying to determine physical sector size"));
+ exit(1);
+ }
+ /* Older kernels may not have physical/logical distinction */
+ if (!psector_size)
+ psector_size = lsector_size;
if ((tmp = getenv("MKE2FS_DEVICE_SECTSIZE")) != NULL)
- sector_size = atoi(tmp);
+ psector_size = atoi(tmp);
if (blocksize <= 0) {
use_bsize = get_int_from_profile(fs_types, "blocksize", 4096);
(use_bsize > 4096))
use_bsize = 4096;
}
- if (sector_size && use_bsize < sector_size)
- use_bsize = sector_size;
+ if (psector_size && use_bsize < psector_size)
+ use_bsize = psector_size;
if ((blocksize < 0) && (use_bsize < (-blocksize)))
use_bsize = -blocksize;
blocksize = use_bsize;
fs_param.s_blocks_count /= blocksize / 1024;
+ } else {
+ if (blocksize < lsector_size || /* Impossible */
+ (!force && (blocksize < psector_size))) { /* Suboptimal */
+ com_err(program_name, EINVAL,
+ _("while setting blocksize; too small "
+ "for device\n"));
+ exit(1);
+ } else if (blocksize < psector_size) {
+ fprintf(stderr, _("Warning: specified blocksize %d is "
+ "less than device physical sectorsize %d, "
+ "forced to continue\n"), blocksize,
+ psector_size);
+ }
}
if (inode_ratio == 0) {