summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2013-06-06 17:40:37 +0200
committerTheodore Ts'o <tytso@mit.edu>2013-06-06 17:40:37 +0200
commitf4afb4f4e3e9af626ad695c87e4f9aaa780b29ec (patch)
tree4f675c6ecaa15df61e842e89dbcacd33d90974c2
parentext4: add sanity check to ext4_get_group_info() (diff)
downloadlinux-f4afb4f4e3e9af626ad695c87e4f9aaa780b29ec.tar.xz
linux-f4afb4f4e3e9af626ad695c87e4f9aaa780b29ec.zip
ext4: optimize test_root()
The test_root() function could potentially loop forever due to overflow issues. So rewrite test_root() to avoid this issue; as a bonus, it is 38% faster when benchmarked via a test loop: int main(int argc, char **argv) { int i; for (i = 0; i < 1 << 24; i++) { if (test_root(i, 7)) printf("%d\n", i); } } Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/ext4/balloc.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index d0f13eada0ed..58339393fa6e 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -682,11 +682,15 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb)
static inline int test_root(ext4_group_t a, int b)
{
- int num = b;
-
- while (a > num)
- num *= b;
- return num == a;
+ while (1) {
+ if (a < b)
+ return 0;
+ if (a == b)
+ return 1;
+ if ((a % b) != 0)
+ return 0;
+ a = a / b;
+ }
}
static int ext4_group_sparse(ext4_group_t group)