summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/e2p/ChangeLog6
-rw-r--r--lib/e2p/Makefile.in4
-rw-r--r--lib/e2p/e2p.h2
-rw-r--r--lib/e2p/percent.c62
-rw-r--r--misc/ChangeLog4
-rw-r--r--misc/mke2fs.c4
-rw-r--r--misc/tune2fs.c3
-rw-r--r--resize/ChangeLog4
-rw-r--r--resize/online.c3
-rw-r--r--resize/resize2fs.c4
10 files changed, 88 insertions, 8 deletions
diff --git a/lib/e2p/ChangeLog b/lib/e2p/ChangeLog
index 4dfaba73..48834010 100644
--- a/lib/e2p/ChangeLog
+++ b/lib/e2p/ChangeLog
@@ -1,3 +1,9 @@
+2006-08-30 Theodore Tso <tytso@mit.edu>
+
+ * percent.c (e2p_percent): Add a new function which accurate and
+ without risk of overflow calculates a percentage of a base
+ number.
+
2006-08-05 Theodore Tso <tytso@mit.edu>
* pf.c: Add support for EXT4_EXTENTS_FL flag.
diff --git a/lib/e2p/Makefile.in b/lib/e2p/Makefile.in
index 6dd3922e..494ecd25 100644
--- a/lib/e2p/Makefile.in
+++ b/lib/e2p/Makefile.in
@@ -19,7 +19,7 @@ all:: e2p.pc
OBJS= feature.o fgetflags.o fsetflags.o fgetversion.o fsetversion.o \
getflags.o getversion.o hashstr.o iod.o ls.o mntopts.o \
parse_num.o pe.o pf.o ps.o setflags.o setversion.o uuid.o \
- ostype.o
+ ostype.o percent.o
SRCS= $(srcdir)/feature.c $(srcdir)/fgetflags.c \
$(srcdir)/fsetflags.c $(srcdir)/fgetversion.c \
@@ -28,7 +28,7 @@ SRCS= $(srcdir)/feature.c $(srcdir)/fgetflags.c \
$(srcdir)/ls.c $(srcdir)/mntopts.c $(srcdir)/parse_num.c \
$(srcdir)/pe.c $(srcdir)/pf.c $(srcdir)/ps.c \
$(srcdir)/setflags.c $(srcdir)/setversion.c $(srcdir)/uuid.c \
- $(srcdir)/ostype.c
+ $(srcdir)/ostype.c $(srcdir)/percent.o
HFILES= e2p.h
LIBRARY= libe2p
diff --git a/lib/e2p/e2p.h b/lib/e2p/e2p.h
index d208b46a..5d9131fd 100644
--- a/lib/e2p/e2p.h
+++ b/lib/e2p/e2p.h
@@ -50,3 +50,5 @@ unsigned long parse_num_blocks(const char *arg, int log_block_size);
char *e2p_os2string(int os_type);
int e2p_string2os(char *str);
+
+unsigned int e2p_percent(int percent, unsigned int base);
diff --git a/lib/e2p/percent.c b/lib/e2p/percent.c
new file mode 100644
index 00000000..f4497b6f
--- /dev/null
+++ b/lib/e2p/percent.c
@@ -0,0 +1,62 @@
+/*
+ * percent.c - Take percentage of a number
+ *
+ * Copyright (C) 2006 Theodore Ts'o <tytso@mit.edu>
+ *
+ * This file can be redistributed under the terms of the GNU Library General
+ * Public License
+ */
+
+#include "e2p.h"
+
+#include <stdlib.h>
+
+/*
+ * We work really hard to calculate this accurately, while avoiding
+ * an overflow. "Is there a hyphen in anal-retentive?" :-)
+ */
+unsigned int e2p_percent(int percent, unsigned int base)
+{
+ unsigned int mask = ~((1 << (sizeof(unsigned int) - 1) * 8) - 1);
+
+ if (100 % percent == 0)
+ return base / (100 / percent);
+ if (mask & base)
+ return (base / 100) * percent;
+ return base * percent / 100;
+}
+
+#ifdef DEBUG
+#include <unistd.h>
+#include <stdio.h>
+
+main(int argc, char **argv)
+{
+ unsigned int base;
+ int percent;
+ char *p;
+ int log_block_size = 0;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s percent base\n", argv[0]);
+ exit(1);
+ }
+
+ percent = strtoul(argv[1], &p, 0);
+ if (p[0] && p[1]) {
+ fprintf(stderr, "Bad percent: %s\n", argv[1]);
+ exit(1);
+ }
+
+ base = strtoul(argv[2], &p, 0);
+ if (p[0] && p[1]) {
+ fprintf(stderr, "Bad base: %s\n", argv[2]);
+ exit(1);
+ }
+
+ printf("%d percent of %u is %u.\n", percent, base,
+ e2p_percent(percent, base));
+
+ exit(0);
+}
+#endif
diff --git a/misc/ChangeLog b/misc/ChangeLog
index 4db1c6d6..b6a9c51d 100644
--- a/misc/ChangeLog
+++ b/misc/ChangeLog
@@ -1,5 +1,9 @@
2006-08-30 Theodore Tso <tytso@mit.edu>
+ * tune2fs.c (main), mke2fs.c (PRS): Use e2p_percent to properly
+ calculate the number of reserved blocks without worrying
+ about overflow.
+
* Makefile.in (resize2fs): Remove unused (and bogus) resize2fs
rule, which shouldn't be in misc/Makefile.in
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index a581ef09..01ef546d 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -1447,8 +1447,8 @@ static void PRS(int argc, char *argv[])
/*
* Calculate number of blocks to reserve
*/
- fs_param.s_r_blocks_count = (fs_param.s_blocks_count * reserved_ratio)
- / 100;
+ fs_param.s_r_blocks_count = e2p_percent(reserved_ratio,
+ fs_param.s_blocks_count);
}
int main (int argc, char *argv[])
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index a0fcf37d..d5b9eb33 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -823,7 +823,8 @@ int main (int argc, char ** argv)
printf (_("Setting interval between checks to %lu seconds\n"), interval);
}
if (m_flag) {
- sb->s_r_blocks_count = sb->s_blocks_count * reserved_ratio /100;
+ sb->s_r_blocks_count = e2p_percent(reserved_ratio,
+ sb->s_blocks_count);
ext2fs_mark_super_dirty(fs);
printf (_("Setting reserved blocks percentage to %g%% (%u blocks)\n"),
reserved_ratio, sb->s_r_blocks_count);
diff --git a/resize/ChangeLog b/resize/ChangeLog
index dea9ba62..b1c0794b 100644
--- a/resize/ChangeLog
+++ b/resize/ChangeLog
@@ -1,5 +1,9 @@
2006-08-30 Theodore Tso <tytso@mit.edu>
+ * resize2fs.c (adjust_fs_info), online.c (online_resize_fs): Use
+ e2p_percent to properly calculate the number of reserved
+ blocks without worrying about overflow.
+
* resize2fs.c (ext2fs_calculate_summary_stats): Fix potential
overflow problems when the number of blocks is close to
2**31.
diff --git a/resize/online.c b/resize/online.c
index 45262b12..7701150d 100644
--- a/resize/online.c
+++ b/resize/online.c
@@ -107,7 +107,8 @@ errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
sb->s_first_data_block -
(i * sb->s_blocks_per_group);
}
- input.reserved_blocks = input.blocks_count * r_frac / 100;
+ input.reserved_blocks = e2p_percent(r_frac,
+ input.blocks_count);
#if 0
printf("new block bitmap is at 0x%04x\n", input.block_bitmap);
diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index 74b517b7..7d3bde90 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -245,8 +245,8 @@ retry:
*/
blk = old_fs->super->s_r_blocks_count * 100 /
old_fs->super->s_blocks_count;
- fs->super->s_r_blocks_count = ((fs->super->s_blocks_count * blk)
- / 100);
+ fs->super->s_r_blocks_count = e2p_percent(blk,
+ fs->super->s_blocks_count);
/*
* Adjust the bitmaps for size