[parted-devel] [PATCH] mkpartfs ext2 2 10 would erroneously report "file system too small"
Jim Meyering
jim at meyering.net
Fri May 18 13:56:02 UTC 2007
mkpartfs ext2 2 10 would erroneously report "file system too small"
for some small (single-group) partitions. It would also fail to
report "file system too small" in some cases, and instead continue
on to into inode-allocation code where it'd report "File system full!"
* libparted/fs/ext2/ext2_mkfs.c (compute_block_counts): New function,
factored out of...
(ext2_mkfs): ...here. Call compute_block_counts rather than
open-coded it. When decrementing numblocks, call compute_block_counts
again, to recompute all of the derived values.
Require at least 14 free blocks in a 16-inode-per-group partition.
* tests/t1500-small-ext2.sh: New file. Test for the above.
* tests/Makefile.am (TESTS): Add t1500-small-ext2.sh.
Signed-off-by: Jim Meyering <jim at meyering.net>
---
libparted/fs/ext2/ext2_mkfs.c | 81 ++++++++++++++++++++++++++++-------------
tests/Makefile.am | 1 +
tests/t1500-small-ext2.sh | 63 ++++++++++++++++++++++++++++++++
3 files changed, 120 insertions(+), 25 deletions(-)
create mode 100755 tests/t1500-small-ext2.sh
diff --git a/libparted/fs/ext2/ext2_mkfs.c b/libparted/fs/ext2/ext2_mkfs.c
index 86175a8..8f74a45 100644
--- a/libparted/fs/ext2/ext2_mkfs.c
+++ b/libparted/fs/ext2/ext2_mkfs.c
@@ -480,6 +480,32 @@ static int ext2_mkfs_init_sb (struct ext2_super_block *sb, blk_t numblocks,
return 1;
}
+/* Given these five inputs, compute the three outputs. */
+static void
+compute_block_counts (blk_t numblocks, int numgroups, int log_block_size,
+ int sparse_sb, blk_t blocks_per_group,
+ int *last_group_blocks,
+ int *last_group_admin,
+ int *inodes_per_group)
+{
+ int first_block = (log_block_size == 10) ? 1 : 0;
+ size_t block_size = 1 << log_block_size;
+
+ *last_group_blocks = ((numblocks - first_block) % blocks_per_group);
+ if (!*last_group_blocks)
+ *last_group_blocks = blocks_per_group;
+ *inodes_per_group = ped_round_up_to (numblocks / numgroups / 2,
+ (block_size
+ / sizeof(struct ext2_inode)));
+ *last_group_admin = (2 + *inodes_per_group * sizeof(struct ext2_inode)
+ / block_size);
+ if (is_group_sparse(sparse_sb, numgroups - 1)) {
+ *last_group_admin +=
+ (ped_div_round_up (numgroups * sizeof(struct ext2_group_desc),
+ block_size));
+ }
+}
+
struct ext2_fs *ext2_mkfs(struct ext2_dev_handle *handle,
blk_t numblocks,
int log_block_size,
@@ -494,8 +520,6 @@ struct ext2_fs *ext2_mkfs(struct ext2_dev_handle *handle,
struct ext2_group_desc *gd;
int numgroups;
int first_block;
- int non_sparse_admin;
- int sparse_admin;
int last_group_blocks;
int last_group_admin;
@@ -518,6 +542,7 @@ struct ext2_fs *ext2_mkfs(struct ext2_dev_handle *handle,
if (numblocks == 0)
numblocks = handle->ops->get_size(handle->cookie);
+ PED_ASSERT(numblocks != 0, return NULL);
if (blocks_per_group == (unsigned int) 0)
blocks_per_group = 8 << log_block_size;
@@ -527,11 +552,6 @@ struct ext2_fs *ext2_mkfs(struct ext2_dev_handle *handle,
numgroups = ped_div_round_up (numblocks
- first_block, blocks_per_group);
- if (inodes_per_group == 0)
- inodes_per_group = ped_round_up_to (
- numblocks / numgroups / 2,
- (1 << log_block_size) / sizeof(struct ext2_inode));
-
if (sparse_sb == -1)
sparse_sb = 1;
@@ -539,25 +559,36 @@ struct ext2_fs *ext2_mkfs(struct ext2_dev_handle *handle,
if (reserved_block_percentage == -1)
reserved_block_percentage = 5;
- last_group_blocks = (numblocks - first_block) % blocks_per_group;
- if (!last_group_blocks) last_group_blocks = blocks_per_group;
- non_sparse_admin = 2
- + inodes_per_group * sizeof(struct ext2_inode)
- / (1 << log_block_size);
- sparse_admin = non_sparse_admin
- + ped_div_round_up (numgroups
- * sizeof(struct ext2_group_desc),
- 1 << log_block_size);
- last_group_admin = is_group_sparse(sparse_sb, numgroups - 1)
- ? sparse_admin : non_sparse_admin;
- if (last_group_admin >= last_group_blocks) {
- numgroups--;
+ compute_block_counts (numblocks, numgroups, log_block_size, sparse_sb,
+ blocks_per_group, &last_group_blocks,
+ &last_group_admin, &inodes_per_group);
+
+ int fs_too_small = 0;
+ if (last_group_admin >= last_group_blocks)
+ {
+ numgroups--;
+ if (numgroups == 0)
+ fs_too_small = 1;
+ else if (numgroups == 1)
+ {
numblocks -= last_group_blocks;
- }
- if (!numgroups
- || (numgroups == 1
- && (last_group_blocks - last_group_admin < 8
- || inodes_per_group < 16))) {
+ compute_block_counts (numblocks, numgroups, log_block_size,
+ sparse_sb, blocks_per_group,
+ &last_group_blocks, &last_group_admin,
+ &inodes_per_group);
+ }
+ }
+
+ if (numgroups == 1
+ && (last_group_blocks - last_group_admin < 8
+ || inodes_per_group < 16
+ /* This final term ensures that we detect
+ mkpartfs primary ext2 10KB 27650B as invalid. */
+ || (inodes_per_group == 16
+ && last_group_blocks - last_group_admin < 14)))
+ fs_too_small = 1;
+
+ if (fs_too_small) {
ped_exception_throw (
PED_EXCEPTION_ERROR,
PED_EXCEPTION_CANCEL,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index df18eb4..55e44e2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -2,6 +2,7 @@ TESTS = \
t0000-basic.sh \
t1000-mkpartfs.sh \
t1100-busy-label.sh \
+ t1500-small-ext2.sh \
t2000-mkfs.sh
TESTS_ENVIRONMENT = \
diff --git a/tests/t1500-small-ext2.sh b/tests/t1500-small-ext2.sh
new file mode 100755
index 0000000..887a5f5
--- /dev/null
+++ b/tests/t1500-small-ext2.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+# Copyright (C) 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+test_description='Create very small ext2 file systems.'
+
+. ./init.sh
+
+dev=loop-file
+test_expect_success \
+ 'setup' '
+ dd if=/dev/zero of=$dev bs=10M count=1 2> /dev/null &&
+ parted -s $dev mklabel msdos'
+
+test_expect_failure \
+ 'try to create an ext2 partition that is one byte too small' '
+ parted -s $dev mkpartfs primary ext2 10KB 29695B > out 2>&1'
+
+test_expect_success \
+ 'check for expected diagnostic' '
+ echo Error: File system too small for ext2. > exp &&
+ $compare out exp'
+
+test_expect_success \
+ 'create the smallest ext2 partition' '
+ parted -s $dev mkpartfs primary ext2 10KB 29696B > out 2>&1
+ $compare out /dev/null'
+
+# Restore $dev to initial state by writing 1KB of zeroes at the beginning.
+# Then relabel.
+test_expect_success \
+ 'setup' '
+ dd if=/dev/zero of=$dev bs=1K count=1 conv=notrunc 2> /dev/null &&
+ parted -s $dev mklabel msdos'
+
+test_expect_success \
+ 'create another ext2 file system (this would fail for parted-1.8.7)' '
+ parted -s $dev mkpartfs primary ext2 2 10 > out 2>&1'
+test_expect_success 'expect no output' '$compare out /dev/null'
+
+test_expect_success \
+ 'create a smaller one; this would succeed for parted-1.8.7' '
+ dd if=/dev/zero of=$dev bs=1K count=1 conv=notrunc 2> /dev/null &&
+ parted -s $dev mklabel msdos &&
+ parted -s $dev mkpartfs primary ext2 2 9 > out 2>&1'
+test_expect_success 'expect no output' '$compare out /dev/null'
+
+test_done
--
1.5.2.rc3.50.gfdcb7
More information about the parted-devel
mailing list