From: Eric Sandeen <sandeen@redhat.com>
To: ext4 development <linux-ext4@vger.kernel.org>
Subject: [PATCH] libext2fs: try to get physical sector size first in ext2fs_get_device_sectsize()
Date: Mon, 08 Feb 2010 16:31:19 -0600 [thread overview]
Message-ID: <4B7090B7.4060708@redhat.com> (raw)
Some devices, notably 4k sector drives, may have a 512 logical
sector size, mapped onto a 4k physical sector size.
When mke2fs is ratcheting down the blocksize for small filesystems,
or when a blocksize is specified on the commandline, we should not
willingly go below the physical sector size of the device.
When a blocksize is specified, we -must- not go below
the logical sector size of the device.
Add a new library function, ext2fs_get_device_phys_sectsize()
to get the physical sector size if possible, and adjust the
logic in mke2fs to enforce the above rules.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 213a819..9c06048 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1086,6 +1086,7 @@ extern errcode_t ext2fs_get_device_size2(const char *file, int blocksize,
/* getsectsize.c */
errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize);
+errcode_t ext2fs_get_device_phys_sectsize(const char *file, int *sectsize);
/* i_block.c */
errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode,
diff --git a/lib/ext2fs/getsectsize.c b/lib/ext2fs/getsectsize.c
index ae9139d..0c7fa82 100644
--- a/lib/ext2fs/getsectsize.c
+++ b/lib/ext2fs/getsectsize.c
@@ -26,15 +26,20 @@
#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)
{
@@ -58,3 +63,29 @@ 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;
+}
diff --git a/lib/ext2fs/tst_getsectsize.c b/lib/ext2fs/tst_getsectsize.c
index cb1b8c6..31599d2 100644
--- a/lib/ext2fs/tst_getsectsize.c
+++ b/lib/ext2fs/tst_getsectsize.c
@@ -27,7 +27,7 @@
int main(int argc, char **argv)
{
- int sectsize;
+ int lsectsize, psectsize;
int retval;
if (argc < 2) {
@@ -35,13 +35,19 @@ int main(int argc, char **argv)
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);
}
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 94b4c81..1a1307b 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -1068,7 +1068,7 @@ static void PRS(int argc, char *argv[])
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;
@@ -1586,16 +1586,25 @@ got_size:
((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);
@@ -1606,14 +1615,25 @@ got_size:
(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;
ext2fs_blocks_count_set(&fs_param,
ext2fs_blocks_count(&fs_param) /
(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) {
next reply other threads:[~2010-02-08 22:31 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-08 22:31 Eric Sandeen [this message]
2010-02-08 22:33 ` [PATCH V2] mke2fs: account for physical as well as logical sector size Eric Sandeen
2010-02-09 22:21 ` tytso
2010-02-09 22:23 ` Eric Sandeen
2010-05-17 21:44 ` Eric Sandeen
2010-05-18 2:35 ` tytso
2010-05-18 3:12 ` Eric Sandeen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4B7090B7.4060708@redhat.com \
--to=sandeen@redhat.com \
--cc=linux-ext4@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.