Commit 4d61db4f authored by Artem Bityutskiy's avatar Artem Bityutskiy

UBIFS: use nicer 64-bit math

Instead of using do_div(), use better primitives from
linux/math64.h.
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
parent af14a1ad
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include "ubifs.h" #include "ubifs.h"
#include <linux/writeback.h> #include <linux/writeback.h>
#include <asm/div64.h> #include <linux/math64.h>
/* /*
* When pessimistic budget calculations say that there is no enough space, * When pessimistic budget calculations say that there is no enough space,
...@@ -258,8 +258,8 @@ static int make_free_space(struct ubifs_info *c, struct retries_info *ri) ...@@ -258,8 +258,8 @@ static int make_free_space(struct ubifs_info *c, struct retries_info *ri)
*/ */
int ubifs_calc_min_idx_lebs(struct ubifs_info *c) int ubifs_calc_min_idx_lebs(struct ubifs_info *c)
{ {
int ret; int idx_lebs, eff_leb_size = c->leb_size - c->max_idx_node_sz;
uint64_t idx_size; long long idx_size;
idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx; idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx;
...@@ -271,18 +271,16 @@ int ubifs_calc_min_idx_lebs(struct ubifs_info *c) ...@@ -271,18 +271,16 @@ int ubifs_calc_min_idx_lebs(struct ubifs_info *c)
* pair, nor similarly the two variables for the new index size, so we * pair, nor similarly the two variables for the new index size, so we
* have to do this costly 64-bit division on fast-path. * have to do this costly 64-bit division on fast-path.
*/ */
if (do_div(idx_size, c->leb_size - c->max_idx_node_sz)) idx_size += eff_leb_size - 1;
ret = idx_size + 1; idx_lebs = div_u64(idx_size, eff_leb_size);
else
ret = idx_size;
/* /*
* The index head is not available for the in-the-gaps method, so add an * The index head is not available for the in-the-gaps method, so add an
* extra LEB to compensate. * extra LEB to compensate.
*/ */
ret += 1; idx_lebs += 1;
if (ret < MIN_INDEX_LEBS) if (idx_lebs < MIN_INDEX_LEBS)
ret = MIN_INDEX_LEBS; idx_lebs = MIN_INDEX_LEBS;
return ret; return idx_lebs;
} }
/** /**
...@@ -718,7 +716,7 @@ void ubifs_release_dirty_inode_budget(struct ubifs_info *c, ...@@ -718,7 +716,7 @@ void ubifs_release_dirty_inode_budget(struct ubifs_info *c,
* Note, the calculation is pessimistic, which means that most of the time * Note, the calculation is pessimistic, which means that most of the time
* UBIFS reports less space than it actually has. * UBIFS reports less space than it actually has.
*/ */
long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free) long long ubifs_reported_space(const struct ubifs_info *c, long long free)
{ {
int divisor, factor, f; int divisor, factor, f;
...@@ -740,8 +738,7 @@ long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free) ...@@ -740,8 +738,7 @@ long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free)
divisor = UBIFS_MAX_DATA_NODE_SZ; divisor = UBIFS_MAX_DATA_NODE_SZ;
divisor += (c->max_idx_node_sz * 3) / (f - 1); divisor += (c->max_idx_node_sz * 3) / (f - 1);
free *= factor; free *= factor;
do_div(free, divisor); return div_u64(free, divisor);
return free;
} }
/** /**
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/math64.h>
#ifdef CONFIG_UBIFS_FS_DEBUG #ifdef CONFIG_UBIFS_FS_DEBUG
......
...@@ -43,8 +43,9 @@ ...@@ -43,8 +43,9 @@
* mounted. * mounted.
*/ */
#include <linux/crc16.h>
#include "ubifs.h" #include "ubifs.h"
#include <linux/crc16.h>
#include <linux/math64.h>
/** /**
* do_calc_lpt_geom - calculate sizes for the LPT area. * do_calc_lpt_geom - calculate sizes for the LPT area.
...@@ -135,15 +136,13 @@ static void do_calc_lpt_geom(struct ubifs_info *c) ...@@ -135,15 +136,13 @@ static void do_calc_lpt_geom(struct ubifs_info *c)
int ubifs_calc_lpt_geom(struct ubifs_info *c) int ubifs_calc_lpt_geom(struct ubifs_info *c)
{ {
int lebs_needed; int lebs_needed;
uint64_t sz; long long sz;
do_calc_lpt_geom(c); do_calc_lpt_geom(c);
/* Verify that lpt_lebs is big enough */ /* Verify that lpt_lebs is big enough */
sz = c->lpt_sz * 2; /* Must have at least 2 times the size */ sz = c->lpt_sz * 2; /* Must have at least 2 times the size */
sz += c->leb_size - 1; lebs_needed = div_u64(sz + c->leb_size - 1, c->leb_size);
do_div(sz, c->leb_size);
lebs_needed = sz;
if (lebs_needed > c->lpt_lebs) { if (lebs_needed > c->lpt_lebs) {
ubifs_err("too few LPT LEBs"); ubifs_err("too few LPT LEBs");
return -EINVAL; return -EINVAL;
...@@ -175,7 +174,7 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, ...@@ -175,7 +174,7 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs,
int *big_lpt) int *big_lpt)
{ {
int i, lebs_needed; int i, lebs_needed;
uint64_t sz; long long sz;
/* Start by assuming the minimum number of LPT LEBs */ /* Start by assuming the minimum number of LPT LEBs */
c->lpt_lebs = UBIFS_MIN_LPT_LEBS; c->lpt_lebs = UBIFS_MIN_LPT_LEBS;
...@@ -202,9 +201,7 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, ...@@ -202,9 +201,7 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs,
/* Now check there are enough LPT LEBs */ /* Now check there are enough LPT LEBs */
for (i = 0; i < 64 ; i++) { for (i = 0; i < 64 ; i++) {
sz = c->lpt_sz * 4; /* Allow 4 times the size */ sz = c->lpt_sz * 4; /* Allow 4 times the size */
sz += c->leb_size - 1; lebs_needed = div_u64(sz + c->leb_size - 1, c->leb_size);
do_div(sz, c->leb_size);
lebs_needed = sz;
if (lebs_needed > c->lpt_lebs) { if (lebs_needed > c->lpt_lebs) {
/* Not enough LPT LEBs so try again with more */ /* Not enough LPT LEBs so try again with more */
c->lpt_lebs = lebs_needed; c->lpt_lebs = lebs_needed;
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "ubifs.h" #include "ubifs.h"
#include <linux/random.h> #include <linux/random.h>
#include <linux/math64.h>
/* /*
* Default journal size in logical eraseblocks as a percent of total * Default journal size in logical eraseblocks as a percent of total
...@@ -80,7 +81,7 @@ static int create_default_filesystem(struct ubifs_info *c) ...@@ -80,7 +81,7 @@ static int create_default_filesystem(struct ubifs_info *c)
int err, tmp, jnl_lebs, log_lebs, max_buds, main_lebs, main_first; int err, tmp, jnl_lebs, log_lebs, max_buds, main_lebs, main_first;
int lpt_lebs, lpt_first, orph_lebs, big_lpt, ino_waste, sup_flags = 0; int lpt_lebs, lpt_first, orph_lebs, big_lpt, ino_waste, sup_flags = 0;
int min_leb_cnt = UBIFS_MIN_LEB_CNT; int min_leb_cnt = UBIFS_MIN_LEB_CNT;
uint64_t tmp64, main_bytes; long long tmp64, main_bytes;
__le64 tmp_le64; __le64 tmp_le64;
/* Some functions called from here depend on the @c->key_len filed */ /* Some functions called from here depend on the @c->key_len filed */
...@@ -160,7 +161,7 @@ static int create_default_filesystem(struct ubifs_info *c) ...@@ -160,7 +161,7 @@ static int create_default_filesystem(struct ubifs_info *c)
if (!sup) if (!sup)
return -ENOMEM; return -ENOMEM;
tmp64 = (uint64_t)max_buds * c->leb_size; tmp64 = (long long)max_buds * c->leb_size;
if (big_lpt) if (big_lpt)
sup_flags |= UBIFS_FLG_BIGLPT; sup_flags |= UBIFS_FLG_BIGLPT;
...@@ -187,9 +188,8 @@ static int create_default_filesystem(struct ubifs_info *c) ...@@ -187,9 +188,8 @@ static int create_default_filesystem(struct ubifs_info *c)
generate_random_uuid(sup->uuid); generate_random_uuid(sup->uuid);
main_bytes = (uint64_t)main_lebs * c->leb_size; main_bytes = (long long)main_lebs * c->leb_size;
tmp64 = main_bytes * DEFAULT_RP_PERCENT; tmp64 = div_u64(main_bytes * DEFAULT_RP_PERCENT, 100);
do_div(tmp64, 100);
if (tmp64 > DEFAULT_MAX_RP_SIZE) if (tmp64 > DEFAULT_MAX_RP_SIZE)
tmp64 = DEFAULT_MAX_RP_SIZE; tmp64 = DEFAULT_MAX_RP_SIZE;
sup->rp_size = cpu_to_le64(tmp64); sup->rp_size = cpu_to_le64(tmp64);
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/math64.h>
#include "ubifs.h" #include "ubifs.h"
/* /*
...@@ -612,7 +613,7 @@ static int bud_wbuf_callback(struct ubifs_info *c, int lnum, int free, int pad) ...@@ -612,7 +613,7 @@ static int bud_wbuf_callback(struct ubifs_info *c, int lnum, int free, int pad)
static int init_constants_late(struct ubifs_info *c) static int init_constants_late(struct ubifs_info *c)
{ {
int tmp, err; int tmp, err;
uint64_t tmp64; long long tmp64;
c->main_bytes = (long long)c->main_lebs * c->leb_size; c->main_bytes = (long long)c->main_lebs * c->leb_size;
c->max_znode_sz = sizeof(struct ubifs_znode) + c->max_znode_sz = sizeof(struct ubifs_znode) +
...@@ -639,9 +640,8 @@ static int init_constants_late(struct ubifs_info *c) ...@@ -639,9 +640,8 @@ static int init_constants_late(struct ubifs_info *c)
* Make sure that the log is large enough to fit reference nodes for * Make sure that the log is large enough to fit reference nodes for
* all buds plus one reserved LEB. * all buds plus one reserved LEB.
*/ */
tmp64 = c->max_bud_bytes; tmp64 = c->max_bud_bytes + c->leb_size - 1;
tmp = do_div(tmp64, c->leb_size); c->max_bud_cnt = div_u64(tmp64, c->leb_size);
c->max_bud_cnt = tmp64 + !!tmp;
tmp = (c->ref_node_alsz * c->max_bud_cnt + c->leb_size - 1); tmp = (c->ref_node_alsz * c->max_bud_cnt + c->leb_size - 1);
tmp /= c->leb_size; tmp /= c->leb_size;
tmp += 1; tmp += 1;
...@@ -677,7 +677,7 @@ static int init_constants_late(struct ubifs_info *c) ...@@ -677,7 +677,7 @@ static int init_constants_late(struct ubifs_info *c)
* Consequently, if the journal is too small, UBIFS will treat it as * Consequently, if the journal is too small, UBIFS will treat it as
* always full. * always full.
*/ */
tmp64 = (uint64_t)(c->jhead_cnt + 1) * c->leb_size + 1; tmp64 = (long long)(c->jhead_cnt + 1) * c->leb_size + 1;
if (c->bg_bud_bytes < tmp64) if (c->bg_bud_bytes < tmp64)
c->bg_bud_bytes = tmp64; c->bg_bud_bytes = tmp64;
if (c->max_bud_bytes < tmp64 + c->leb_size) if (c->max_bud_bytes < tmp64 + c->leb_size)
...@@ -699,7 +699,7 @@ static int init_constants_late(struct ubifs_info *c) ...@@ -699,7 +699,7 @@ static int init_constants_late(struct ubifs_info *c)
* head is available. * head is available.
*/ */
tmp64 = c->main_lebs - 1 - 1 - MIN_INDEX_LEBS - c->jhead_cnt + 1; tmp64 = c->main_lebs - 1 - 1 - MIN_INDEX_LEBS - c->jhead_cnt + 1;
tmp64 *= (uint64_t)c->leb_size - c->leb_overhead; tmp64 *= (long long)c->leb_size - c->leb_overhead;
tmp64 = ubifs_reported_space(c, tmp64); tmp64 = ubifs_reported_space(c, tmp64);
c->block_cnt = tmp64 >> UBIFS_BLOCK_SHIFT; c->block_cnt = tmp64 >> UBIFS_BLOCK_SHIFT;
......
...@@ -1498,7 +1498,7 @@ void ubifs_cancel_ino_op(struct ubifs_info *c, struct inode *inode, ...@@ -1498,7 +1498,7 @@ void ubifs_cancel_ino_op(struct ubifs_info *c, struct inode *inode,
long long ubifs_get_free_space(struct ubifs_info *c); long long ubifs_get_free_space(struct ubifs_info *c);
int ubifs_calc_min_idx_lebs(struct ubifs_info *c); int ubifs_calc_min_idx_lebs(struct ubifs_info *c);
void ubifs_convert_page_budget(struct ubifs_info *c); void ubifs_convert_page_budget(struct ubifs_info *c);
long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free); long long ubifs_reported_space(const struct ubifs_info *c, long long free);
long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs); long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs);
/* find.c */ /* find.c */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment