summaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2006-08-30 01:57:00 -0400
committerTheodore Ts'o <tytso@mit.edu>2006-08-30 01:57:00 -0400
commit69022e029f3273b3b860bf701219cd3fe615f76b (patch)
tree81ecd1b770fe3a4d8e0c325ce78bc6f0c17c927b /misc
parenta3e025c7493b58ec88b775f26a41e4205a6a2c9f (diff)
downloade2fsprogs-69022e029f3273b3b860bf701219cd3fe615f76b.tar.gz
Fix potential 2**32-1 overflow problems by ext2fs_div_ceil()
Add a new function, ext2fs_div_ceil(), which correctly calculates a division of two unsigned integer where the result is always rounded up the next largest integer. This is used everywhere where we might have previously caused an overflow when the number of blocks or inodes is too close to 2**32-1. Based on patches from Eric Sandeen, but generalized to use this new function Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Signed-off-by: Eric Sandeen <esandeen@redhat.com>
Diffstat (limited to 'misc')
-rw-r--r--misc/ChangeLog9
-rw-r--r--misc/filefrag.c9
-rw-r--r--misc/mke2fs.c8
3 files changed, 21 insertions, 5 deletions
diff --git a/misc/ChangeLog b/misc/ChangeLog
index 86254330..0cecaa43 100644
--- a/misc/ChangeLog
+++ b/misc/ChangeLog
@@ -1,3 +1,12 @@
+2006-08-30 Theodore Tso <tytso@mit.edu>
+
+ * mke2fs.c (parse_extended_opts): Use ext2fs_div_ceil() instead of
+ a using an open-coded expression which was subject to
+ overflows.
+
+ * filefrag.c (div_ceil, frag_report): Fix potential overflow for
+ really big filesystems.
+
2006-08-06 Theodore Tso <tytso@mit.edu>
* findsuper.c (main): Improve findsuper program by printing the
diff --git a/misc/filefrag.c b/misc/filefrag.c
index 0719d4ce..df900602 100644
--- a/misc/filefrag.c
+++ b/misc/filefrag.c
@@ -47,6 +47,13 @@ int verbose = 0;
#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
#define EXT3_IOC_GETFLAGS _IOR('f', 1, long)
+static unsigned int div_ceil(unsigned int a, unsigned int b)
+{
+ if (!a)
+ return 0;
+ return ((a - 1) / b) + 1;
+}
+
static unsigned long get_bmap(int fd, unsigned long block)
{
int ret;
@@ -105,7 +112,7 @@ static void frag_report(const char *filename)
if (verbose) {
printf("Filesystem type is: %x\n", fsinfo.f_type);
}
- cylgroups = (fsinfo.f_blocks + fsinfo.f_bsize*8-1) / fsinfo.f_bsize*8;
+ cylgroups = div_ceil(fsinfo.f_blocks, fsinfo.f_bsize*8);
if (verbose) {
printf("Filesystem cylinder groups is approximately %ld\n",
cylgroups);
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 677c5140..a581ef09 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -820,12 +820,12 @@ static void parse_extended_opts(struct ext2_super_block *param,
if (!bpg)
bpg = blocksize * 8;
gdpb = blocksize / sizeof(struct ext2_group_desc);
- group_desc_count = (param->s_blocks_count +
- bpg - 1) / bpg;
+ group_desc_count =
+ ext2fs_div_ceil(param->s_blocks_count, bpg);
desc_blocks = (group_desc_count +
gdpb - 1) / gdpb;
- rsv_groups = (resize + bpg - 1) / bpg;
- rsv_gdb = (rsv_groups + gdpb - 1) / gdpb -
+ rsv_groups = ext2fs_div_ceil(resize, bpg);
+ rsv_gdb = ext2fs_div_ceil(rsv_groups, gdpb) -
desc_blocks;
if (rsv_gdb > (int) EXT2_ADDR_PER_BLOCK(param))
rsv_gdb = EXT2_ADDR_PER_BLOCK(param);