diff options
-rw-r--r-- | lib/e2p/ChangeLog | 6 | ||||
-rw-r--r-- | lib/e2p/Makefile.in | 4 | ||||
-rw-r--r-- | lib/e2p/e2p.h | 2 | ||||
-rw-r--r-- | lib/e2p/percent.c | 62 | ||||
-rw-r--r-- | misc/ChangeLog | 4 | ||||
-rw-r--r-- | misc/mke2fs.c | 4 | ||||
-rw-r--r-- | misc/tune2fs.c | 3 | ||||
-rw-r--r-- | resize/ChangeLog | 4 | ||||
-rw-r--r-- | resize/online.c | 3 | ||||
-rw-r--r-- | resize/resize2fs.c | 4 |
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 |