UBIFS: introduce a separate structure for budgeting info

This patch separates out all the budgeting-related information
from 'struct ubifs_info' to 'struct ubifs_budg_info'. This way the
code looks a bit cleaner. However, the main driver for this is
that we want to save budgeting information and print it later,
so a separate data structure for this is helpful.

This patch is a preparation for the further debugging output
improvements.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This commit is contained in:
Artem Bityutskiy 2011-03-29 18:04:05 +03:00
parent cc64f774b4
commit b137545c44
11 changed files with 134 additions and 129 deletions

View file

@ -106,7 +106,7 @@ static long long get_liability(struct ubifs_info *c)
long long liab; long long liab;
spin_lock(&c->space_lock); spin_lock(&c->space_lock);
liab = c->budg_idx_growth + c->budg_data_growth + c->budg_dd_growth; liab = c->bi.idx_growth + c->bi.data_growth + c->bi.dd_growth;
spin_unlock(&c->space_lock); spin_unlock(&c->space_lock);
return liab; return liab;
} }
@ -180,7 +180,7 @@ int ubifs_calc_min_idx_lebs(struct ubifs_info *c)
int idx_lebs; int idx_lebs;
long long idx_size; long long idx_size;
idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx; idx_size = c->bi.old_idx_sz + c->bi.idx_growth + c->bi.uncommitted_idx;
/* And make sure we have thrice the index size of space reserved */ /* And make sure we have thrice the index size of space reserved */
idx_size += idx_size << 1; idx_size += idx_size << 1;
/* /*
@ -292,13 +292,13 @@ static int can_use_rp(struct ubifs_info *c)
* budgeted index space to the size of the current index, multiplies this by 3, * budgeted index space to the size of the current index, multiplies this by 3,
* and makes sure this does not exceed the amount of free LEBs. * and makes sure this does not exceed the amount of free LEBs.
* *
* Notes about @c->min_idx_lebs and @c->lst.idx_lebs variables: * Notes about @c->bi.min_idx_lebs and @c->lst.idx_lebs variables:
* o @c->lst.idx_lebs is the number of LEBs the index currently uses. It might * o @c->lst.idx_lebs is the number of LEBs the index currently uses. It might
* be large, because UBIFS does not do any index consolidation as long as * be large, because UBIFS does not do any index consolidation as long as
* there is free space. IOW, the index may take a lot of LEBs, but the LEBs * there is free space. IOW, the index may take a lot of LEBs, but the LEBs
* will contain a lot of dirt. * will contain a lot of dirt.
* o @c->min_idx_lebs is the number of LEBS the index presumably takes. IOW, * o @c->bi.min_idx_lebs is the number of LEBS the index presumably takes. IOW,
* the index may be consolidated to take up to @c->min_idx_lebs LEBs. * the index may be consolidated to take up to @c->bi.min_idx_lebs LEBs.
* *
* This function returns zero in case of success, and %-ENOSPC in case of * This function returns zero in case of success, and %-ENOSPC in case of
* failure. * failure.
@ -343,13 +343,13 @@ static int do_budget_space(struct ubifs_info *c)
c->lst.taken_empty_lebs; c->lst.taken_empty_lebs;
if (unlikely(rsvd_idx_lebs > lebs)) { if (unlikely(rsvd_idx_lebs > lebs)) {
dbg_budg("out of indexing space: min_idx_lebs %d (old %d), " dbg_budg("out of indexing space: min_idx_lebs %d (old %d), "
"rsvd_idx_lebs %d", min_idx_lebs, c->min_idx_lebs, "rsvd_idx_lebs %d", min_idx_lebs, c->bi.min_idx_lebs,
rsvd_idx_lebs); rsvd_idx_lebs);
return -ENOSPC; return -ENOSPC;
} }
available = ubifs_calc_available(c, min_idx_lebs); available = ubifs_calc_available(c, min_idx_lebs);
outstanding = c->budg_data_growth + c->budg_dd_growth; outstanding = c->bi.data_growth + c->bi.dd_growth;
if (unlikely(available < outstanding)) { if (unlikely(available < outstanding)) {
dbg_budg("out of data space: available %lld, outstanding %lld", dbg_budg("out of data space: available %lld, outstanding %lld",
@ -360,7 +360,7 @@ static int do_budget_space(struct ubifs_info *c)
if (available - outstanding <= c->rp_size && !can_use_rp(c)) if (available - outstanding <= c->rp_size && !can_use_rp(c))
return -ENOSPC; return -ENOSPC;
c->min_idx_lebs = min_idx_lebs; c->bi.min_idx_lebs = min_idx_lebs;
return 0; return 0;
} }
@ -393,11 +393,11 @@ static int calc_data_growth(const struct ubifs_info *c,
{ {
int data_growth; int data_growth;
data_growth = req->new_ino ? c->inode_budget : 0; data_growth = req->new_ino ? c->bi.inode_budget : 0;
if (req->new_page) if (req->new_page)
data_growth += c->page_budget; data_growth += c->bi.page_budget;
if (req->new_dent) if (req->new_dent)
data_growth += c->dent_budget; data_growth += c->bi.dent_budget;
data_growth += req->new_ino_d; data_growth += req->new_ino_d;
return data_growth; return data_growth;
} }
@ -413,12 +413,12 @@ static int calc_dd_growth(const struct ubifs_info *c,
{ {
int dd_growth; int dd_growth;
dd_growth = req->dirtied_page ? c->page_budget : 0; dd_growth = req->dirtied_page ? c->bi.page_budget : 0;
if (req->dirtied_ino) if (req->dirtied_ino)
dd_growth += c->inode_budget << (req->dirtied_ino - 1); dd_growth += c->bi.inode_budget << (req->dirtied_ino - 1);
if (req->mod_dent) if (req->mod_dent)
dd_growth += c->dent_budget; dd_growth += c->bi.dent_budget;
dd_growth += req->dirtied_ino_d; dd_growth += req->dirtied_ino_d;
return dd_growth; return dd_growth;
} }
@ -460,19 +460,19 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req)
again: again:
spin_lock(&c->space_lock); spin_lock(&c->space_lock);
ubifs_assert(c->budg_idx_growth >= 0); ubifs_assert(c->bi.idx_growth >= 0);
ubifs_assert(c->budg_data_growth >= 0); ubifs_assert(c->bi.data_growth >= 0);
ubifs_assert(c->budg_dd_growth >= 0); ubifs_assert(c->bi.dd_growth >= 0);
if (unlikely(c->nospace) && (c->nospace_rp || !can_use_rp(c))) { if (unlikely(c->bi.nospace) && (c->bi.nospace_rp || !can_use_rp(c))) {
dbg_budg("no space"); dbg_budg("no space");
spin_unlock(&c->space_lock); spin_unlock(&c->space_lock);
return -ENOSPC; return -ENOSPC;
} }
c->budg_idx_growth += idx_growth; c->bi.idx_growth += idx_growth;
c->budg_data_growth += data_growth; c->bi.data_growth += data_growth;
c->budg_dd_growth += dd_growth; c->bi.dd_growth += dd_growth;
err = do_budget_space(c); err = do_budget_space(c);
if (likely(!err)) { if (likely(!err)) {
@ -484,9 +484,9 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req)
} }
/* Restore the old values */ /* Restore the old values */
c->budg_idx_growth -= idx_growth; c->bi.idx_growth -= idx_growth;
c->budg_data_growth -= data_growth; c->bi.data_growth -= data_growth;
c->budg_dd_growth -= dd_growth; c->bi.dd_growth -= dd_growth;
spin_unlock(&c->space_lock); spin_unlock(&c->space_lock);
if (req->fast) { if (req->fast) {
@ -506,9 +506,9 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req)
goto again; goto again;
} }
dbg_budg("FS is full, -ENOSPC"); dbg_budg("FS is full, -ENOSPC");
c->nospace = 1; c->bi.nospace = 1;
if (can_use_rp(c) || c->rp_size == 0) if (can_use_rp(c) || c->rp_size == 0)
c->nospace_rp = 1; c->bi.nospace_rp = 1;
smp_wmb(); smp_wmb();
} else } else
ubifs_err("cannot budget space, error %d", err); ubifs_err("cannot budget space, error %d", err);
@ -523,8 +523,8 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req)
* This function releases the space budgeted by 'ubifs_budget_space()'. Note, * This function releases the space budgeted by 'ubifs_budget_space()'. Note,
* since the index changes (which were budgeted for in @req->idx_growth) will * since the index changes (which were budgeted for in @req->idx_growth) will
* only be written to the media on commit, this function moves the index budget * only be written to the media on commit, this function moves the index budget
* from @c->budg_idx_growth to @c->budg_uncommitted_idx. The latter will be * from @c->bi.idx_growth to @c->bi.uncommitted_idx. The latter will be zeroed
* zeroed by the commit operation. * by the commit operation.
*/ */
void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req) void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req)
{ {
@ -553,23 +553,23 @@ void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req)
if (!req->data_growth && !req->dd_growth) if (!req->data_growth && !req->dd_growth)
return; return;
c->nospace = c->nospace_rp = 0; c->bi.nospace = c->bi.nospace_rp = 0;
smp_wmb(); smp_wmb();
spin_lock(&c->space_lock); spin_lock(&c->space_lock);
c->budg_idx_growth -= req->idx_growth; c->bi.idx_growth -= req->idx_growth;
c->budg_uncommitted_idx += req->idx_growth; c->bi.uncommitted_idx += req->idx_growth;
c->budg_data_growth -= req->data_growth; c->bi.data_growth -= req->data_growth;
c->budg_dd_growth -= req->dd_growth; c->bi.dd_growth -= req->dd_growth;
c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c);
ubifs_assert(c->budg_idx_growth >= 0); ubifs_assert(c->bi.idx_growth >= 0);
ubifs_assert(c->budg_data_growth >= 0); ubifs_assert(c->bi.data_growth >= 0);
ubifs_assert(c->budg_dd_growth >= 0); ubifs_assert(c->bi.dd_growth >= 0);
ubifs_assert(c->min_idx_lebs < c->main_lebs); ubifs_assert(c->bi.min_idx_lebs < c->main_lebs);
ubifs_assert(!(c->budg_idx_growth & 7)); ubifs_assert(!(c->bi.idx_growth & 7));
ubifs_assert(!(c->budg_data_growth & 7)); ubifs_assert(!(c->bi.data_growth & 7));
ubifs_assert(!(c->budg_dd_growth & 7)); ubifs_assert(!(c->bi.dd_growth & 7));
spin_unlock(&c->space_lock); spin_unlock(&c->space_lock);
} }
@ -586,13 +586,13 @@ void ubifs_convert_page_budget(struct ubifs_info *c)
{ {
spin_lock(&c->space_lock); spin_lock(&c->space_lock);
/* Release the index growth reservation */ /* Release the index growth reservation */
c->budg_idx_growth -= c->max_idx_node_sz << UBIFS_BLOCKS_PER_PAGE_SHIFT; c->bi.idx_growth -= c->max_idx_node_sz << UBIFS_BLOCKS_PER_PAGE_SHIFT;
/* Release the data growth reservation */ /* Release the data growth reservation */
c->budg_data_growth -= c->page_budget; c->bi.data_growth -= c->bi.page_budget;
/* Increase the dirty data growth reservation instead */ /* Increase the dirty data growth reservation instead */
c->budg_dd_growth += c->page_budget; c->bi.dd_growth += c->bi.page_budget;
/* And re-calculate the indexing space reservation */ /* And re-calculate the indexing space reservation */
c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c);
spin_unlock(&c->space_lock); spin_unlock(&c->space_lock);
} }
@ -612,7 +612,7 @@ void ubifs_release_dirty_inode_budget(struct ubifs_info *c,
memset(&req, 0, sizeof(struct ubifs_budget_req)); memset(&req, 0, sizeof(struct ubifs_budget_req));
/* The "no space" flags will be cleared because dd_growth is > 0 */ /* The "no space" flags will be cleared because dd_growth is > 0 */
req.dd_growth = c->inode_budget + ALIGN(ui->data_len, 8); req.dd_growth = c->bi.inode_budget + ALIGN(ui->data_len, 8);
ubifs_release_budget(c, &req); ubifs_release_budget(c, &req);
} }
@ -682,9 +682,9 @@ long long ubifs_get_free_space_nolock(struct ubifs_info *c)
int rsvd_idx_lebs, lebs; int rsvd_idx_lebs, lebs;
long long available, outstanding, free; long long available, outstanding, free;
ubifs_assert(c->min_idx_lebs == ubifs_calc_min_idx_lebs(c)); ubifs_assert(c->bi.min_idx_lebs == ubifs_calc_min_idx_lebs(c));
outstanding = c->budg_data_growth + c->budg_dd_growth; outstanding = c->bi.data_growth + c->bi.dd_growth;
available = ubifs_calc_available(c, c->min_idx_lebs); available = ubifs_calc_available(c, c->bi.min_idx_lebs);
/* /*
* When reporting free space to user-space, UBIFS guarantees that it is * When reporting free space to user-space, UBIFS guarantees that it is
@ -697,8 +697,8 @@ long long ubifs_get_free_space_nolock(struct ubifs_info *c)
* Note, the calculations below are similar to what we have in * Note, the calculations below are similar to what we have in
* 'do_budget_space()', so refer there for comments. * 'do_budget_space()', so refer there for comments.
*/ */
if (c->min_idx_lebs > c->lst.idx_lebs) if (c->bi.min_idx_lebs > c->lst.idx_lebs)
rsvd_idx_lebs = c->min_idx_lebs - c->lst.idx_lebs; rsvd_idx_lebs = c->bi.min_idx_lebs - c->lst.idx_lebs;
else else
rsvd_idx_lebs = 0; rsvd_idx_lebs = 0;
lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt - lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -

View file

@ -182,7 +182,7 @@ static int do_commit(struct ubifs_info *c)
c->mst_node->root_len = cpu_to_le32(zroot.len); c->mst_node->root_len = cpu_to_le32(zroot.len);
c->mst_node->ihead_lnum = cpu_to_le32(c->ihead_lnum); c->mst_node->ihead_lnum = cpu_to_le32(c->ihead_lnum);
c->mst_node->ihead_offs = cpu_to_le32(c->ihead_offs); c->mst_node->ihead_offs = cpu_to_le32(c->ihead_offs);
c->mst_node->index_size = cpu_to_le64(c->old_idx_sz); c->mst_node->index_size = cpu_to_le64(c->bi.old_idx_sz);
c->mst_node->lpt_lnum = cpu_to_le32(c->lpt_lnum); c->mst_node->lpt_lnum = cpu_to_le32(c->lpt_lnum);
c->mst_node->lpt_offs = cpu_to_le32(c->lpt_offs); c->mst_node->lpt_offs = cpu_to_le32(c->lpt_offs);
c->mst_node->nhead_lnum = cpu_to_le32(c->nhead_lnum); c->mst_node->nhead_lnum = cpu_to_le32(c->nhead_lnum);

View file

@ -614,14 +614,14 @@ void dbg_dump_budg(struct ubifs_info *c)
spin_lock(&dbg_lock); spin_lock(&dbg_lock);
printk(KERN_DEBUG "(pid %d) Budgeting info: budg_data_growth %lld, " printk(KERN_DEBUG "(pid %d) Budgeting info: budg_data_growth %lld, "
"budg_dd_growth %lld, budg_idx_growth %lld\n", current->pid, "budg_dd_growth %lld, budg_idx_growth %lld\n", current->pid,
c->budg_data_growth, c->budg_dd_growth, c->budg_idx_growth); c->bi.data_growth, c->bi.dd_growth, c->bi.idx_growth);
printk(KERN_DEBUG "\tdata budget sum %lld, total budget sum %lld, " printk(KERN_DEBUG "\tdata budget sum %lld, total budget sum %lld, "
"freeable_cnt %d\n", c->budg_data_growth + c->budg_dd_growth, "freeable_cnt %d\n", c->bi.data_growth + c->bi.dd_growth,
c->budg_data_growth + c->budg_dd_growth + c->budg_idx_growth, c->bi.data_growth + c->bi.dd_growth + c->bi.idx_growth,
c->freeable_cnt); c->freeable_cnt);
printk(KERN_DEBUG "\tmin_idx_lebs %d, old_idx_sz %lld, " printk(KERN_DEBUG "\tmin_idx_lebs %d, old_idx_sz %lld, "
"calc_idx_sz %lld, idx_gc_cnt %d\n", c->min_idx_lebs, "calc_idx_sz %lld, idx_gc_cnt %d\n", c->bi.min_idx_lebs,
c->old_idx_sz, c->calc_idx_sz, c->idx_gc_cnt); c->bi.old_idx_sz, c->calc_idx_sz, c->idx_gc_cnt);
printk(KERN_DEBUG "\tdirty_pg_cnt %ld, dirty_zn_cnt %ld, " printk(KERN_DEBUG "\tdirty_pg_cnt %ld, dirty_zn_cnt %ld, "
"clean_zn_cnt %ld\n", atomic_long_read(&c->dirty_pg_cnt), "clean_zn_cnt %ld\n", atomic_long_read(&c->dirty_pg_cnt),
atomic_long_read(&c->dirty_zn_cnt), atomic_long_read(&c->dirty_zn_cnt),
@ -648,8 +648,8 @@ void dbg_dump_budg(struct ubifs_info *c)
printk(KERN_DEBUG "\tcommit state %d\n", c->cmt_state); printk(KERN_DEBUG "\tcommit state %d\n", c->cmt_state);
/* Print budgeting predictions */ /* Print budgeting predictions */
available = ubifs_calc_available(c, c->min_idx_lebs); available = ubifs_calc_available(c, c->bi.min_idx_lebs);
outstanding = c->budg_data_growth + c->budg_dd_growth; outstanding = c->bi.data_growth + c->bi.dd_growth;
free = ubifs_get_free_space_nolock(c); free = ubifs_get_free_space_nolock(c);
printk(KERN_DEBUG "Budgeting predictions:\n"); printk(KERN_DEBUG "Budgeting predictions:\n");
printk(KERN_DEBUG "\tavailable: %lld, outstanding %lld, free %lld\n", printk(KERN_DEBUG "\tavailable: %lld, outstanding %lld, free %lld\n",

View file

@ -603,7 +603,7 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
ubifs_release_budget(c, &req); ubifs_release_budget(c, &req);
else { else {
/* We've deleted something - clean the "no space" flags */ /* We've deleted something - clean the "no space" flags */
c->nospace = c->nospace_rp = 0; c->bi.nospace = c->bi.nospace_rp = 0;
smp_wmb(); smp_wmb();
} }
return 0; return 0;
@ -693,7 +693,7 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
ubifs_release_budget(c, &req); ubifs_release_budget(c, &req);
else { else {
/* We've deleted something - clean the "no space" flags */ /* We've deleted something - clean the "no space" flags */
c->nospace = c->nospace_rp = 0; c->bi.nospace = c->bi.nospace_rp = 0;
smp_wmb(); smp_wmb();
} }
return 0; return 0;

View file

@ -212,7 +212,7 @@ static void release_new_page_budget(struct ubifs_info *c)
*/ */
static void release_existing_page_budget(struct ubifs_info *c) static void release_existing_page_budget(struct ubifs_info *c)
{ {
struct ubifs_budget_req req = { .dd_growth = c->page_budget}; struct ubifs_budget_req req = { .dd_growth = c->bi.page_budget};
ubifs_release_budget(c, &req); ubifs_release_budget(c, &req);
} }
@ -1189,7 +1189,7 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
if (budgeted) if (budgeted)
ubifs_release_budget(c, &req); ubifs_release_budget(c, &req);
else { else {
c->nospace = c->nospace_rp = 0; c->bi.nospace = c->bi.nospace_rp = 0;
smp_wmb(); smp_wmb();
} }
return err; return err;

View file

@ -252,8 +252,8 @@ int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
* But if the index takes fewer LEBs than it is reserved for it, * But if the index takes fewer LEBs than it is reserved for it,
* this function must avoid picking those reserved LEBs. * this function must avoid picking those reserved LEBs.
*/ */
if (c->min_idx_lebs >= c->lst.idx_lebs) { if (c->bi.min_idx_lebs >= c->lst.idx_lebs) {
rsvd_idx_lebs = c->min_idx_lebs - c->lst.idx_lebs; rsvd_idx_lebs = c->bi.min_idx_lebs - c->lst.idx_lebs;
exclude_index = 1; exclude_index = 1;
} }
spin_unlock(&c->space_lock); spin_unlock(&c->space_lock);
@ -276,7 +276,7 @@ int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
pick_free = 0; pick_free = 0;
} else { } else {
spin_lock(&c->space_lock); spin_lock(&c->space_lock);
exclude_index = (c->min_idx_lebs >= c->lst.idx_lebs); exclude_index = (c->bi.min_idx_lebs >= c->lst.idx_lebs);
spin_unlock(&c->space_lock); spin_unlock(&c->space_lock);
} }
@ -501,8 +501,8 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *offs,
/* Check if there are enough empty LEBs for commit */ /* Check if there are enough empty LEBs for commit */
spin_lock(&c->space_lock); spin_lock(&c->space_lock);
if (c->min_idx_lebs > c->lst.idx_lebs) if (c->bi.min_idx_lebs > c->lst.idx_lebs)
rsvd_idx_lebs = c->min_idx_lebs - c->lst.idx_lebs; rsvd_idx_lebs = c->bi.min_idx_lebs - c->lst.idx_lebs;
else else
rsvd_idx_lebs = 0; rsvd_idx_lebs = 0;
lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt - lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -

View file

@ -148,7 +148,7 @@ static int validate_master(const struct ubifs_info *c)
} }
main_sz = (long long)c->main_lebs * c->leb_size; main_sz = (long long)c->main_lebs * c->leb_size;
if (c->old_idx_sz & 7 || c->old_idx_sz >= main_sz) { if (c->bi.old_idx_sz & 7 || c->bi.old_idx_sz >= main_sz) {
err = 9; err = 9;
goto out; goto out;
} }
@ -218,7 +218,7 @@ static int validate_master(const struct ubifs_info *c)
} }
if (c->lst.total_dead + c->lst.total_dark + if (c->lst.total_dead + c->lst.total_dark +
c->lst.total_used + c->old_idx_sz > main_sz) { c->lst.total_used + c->bi.old_idx_sz > main_sz) {
err = 21; err = 21;
goto out; goto out;
} }
@ -286,7 +286,7 @@ int ubifs_read_master(struct ubifs_info *c)
c->gc_lnum = le32_to_cpu(c->mst_node->gc_lnum); c->gc_lnum = le32_to_cpu(c->mst_node->gc_lnum);
c->ihead_lnum = le32_to_cpu(c->mst_node->ihead_lnum); c->ihead_lnum = le32_to_cpu(c->mst_node->ihead_lnum);
c->ihead_offs = le32_to_cpu(c->mst_node->ihead_offs); c->ihead_offs = le32_to_cpu(c->mst_node->ihead_offs);
c->old_idx_sz = le64_to_cpu(c->mst_node->index_size); c->bi.old_idx_sz = le64_to_cpu(c->mst_node->index_size);
c->lpt_lnum = le32_to_cpu(c->mst_node->lpt_lnum); c->lpt_lnum = le32_to_cpu(c->mst_node->lpt_lnum);
c->lpt_offs = le32_to_cpu(c->mst_node->lpt_offs); c->lpt_offs = le32_to_cpu(c->mst_node->lpt_offs);
c->nhead_lnum = le32_to_cpu(c->mst_node->nhead_lnum); c->nhead_lnum = le32_to_cpu(c->mst_node->nhead_lnum);
@ -305,7 +305,7 @@ int ubifs_read_master(struct ubifs_info *c)
c->lst.total_dead = le64_to_cpu(c->mst_node->total_dead); c->lst.total_dead = le64_to_cpu(c->mst_node->total_dead);
c->lst.total_dark = le64_to_cpu(c->mst_node->total_dark); c->lst.total_dark = le64_to_cpu(c->mst_node->total_dark);
c->calc_idx_sz = c->old_idx_sz; c->calc_idx_sz = c->bi.old_idx_sz;
if (c->mst_node->flags & cpu_to_le32(UBIFS_MST_NO_ORPHS)) if (c->mst_node->flags & cpu_to_le32(UBIFS_MST_NO_ORPHS))
c->no_orphs = 1; c->no_orphs = 1;

View file

@ -1065,13 +1065,13 @@ int ubifs_replay_journal(struct ubifs_info *c)
goto out; goto out;
/* /*
* UBIFS budgeting calculations use @c->budg_uncommitted_idx variable * UBIFS budgeting calculations use @c->bi.uncommitted_idx variable
* to roughly estimate index growth. Things like @c->min_idx_lebs * to roughly estimate index growth. Things like @c->bi.min_idx_lebs
* depend on it. This means we have to initialize it to make sure * depend on it. This means we have to initialize it to make sure
* budgeting works properly. * budgeting works properly.
*/ */
c->budg_uncommitted_idx = atomic_long_read(&c->dirty_zn_cnt); c->bi.uncommitted_idx = atomic_long_read(&c->dirty_zn_cnt);
c->budg_uncommitted_idx *= c->max_idx_node_sz; c->bi.uncommitted_idx *= c->max_idx_node_sz;
ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery); ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery);
dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, " dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, "

View file

@ -375,7 +375,7 @@ static void ubifs_evict_inode(struct inode *inode)
ubifs_release_dirty_inode_budget(c, ui); ubifs_release_dirty_inode_budget(c, ui);
else { else {
/* We've deleted something - clean the "no space" flags */ /* We've deleted something - clean the "no space" flags */
c->nospace = c->nospace_rp = 0; c->bi.nospace = c->bi.nospace_rp = 0;
smp_wmb(); smp_wmb();
} }
done: done:
@ -694,11 +694,11 @@ static int init_constants_sb(struct ubifs_info *c)
* be compressed and direntries are of the maximum size. * be compressed and direntries are of the maximum size.
* *
* Note, data, which may be stored in inodes is budgeted separately, so * Note, data, which may be stored in inodes is budgeted separately, so
* it is not included into 'c->inode_budget'. * it is not included into 'c->bi.inode_budget'.
*/ */
c->page_budget = UBIFS_MAX_DATA_NODE_SZ * UBIFS_BLOCKS_PER_PAGE; c->bi.page_budget = UBIFS_MAX_DATA_NODE_SZ * UBIFS_BLOCKS_PER_PAGE;
c->inode_budget = UBIFS_INO_NODE_SZ; c->bi.inode_budget = UBIFS_INO_NODE_SZ;
c->dent_budget = UBIFS_MAX_DENT_NODE_SZ; c->bi.dent_budget = UBIFS_MAX_DENT_NODE_SZ;
/* /*
* When the amount of flash space used by buds becomes * When the amount of flash space used by buds becomes
@ -742,7 +742,7 @@ static void init_constants_master(struct ubifs_info *c)
{ {
long long tmp64; long long tmp64;
c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c);
c->report_rp_size = ubifs_reported_space(c, c->rp_size); c->report_rp_size = ubifs_reported_space(c, c->rp_size);
/* /*
@ -1304,7 +1304,7 @@ static int mount_ubifs(struct ubifs_info *c)
if (err) if (err)
goto out_lpt; goto out_lpt;
err = dbg_check_idx_size(c, c->old_idx_sz); err = dbg_check_idx_size(c, c->bi.old_idx_sz);
if (err) if (err)
goto out_lpt; goto out_lpt;
@ -1313,7 +1313,7 @@ static int mount_ubifs(struct ubifs_info *c)
goto out_journal; goto out_journal;
/* Calculate 'min_idx_lebs' after journal replay */ /* Calculate 'min_idx_lebs' after journal replay */
c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c);
err = ubifs_mount_orphans(c, c->need_recovery, c->ro_mount); err = ubifs_mount_orphans(c, c->need_recovery, c->ro_mount);
if (err) if (err)
@ -1442,7 +1442,8 @@ static int mount_ubifs(struct ubifs_info *c)
c->main_lebs, c->main_first, c->leb_cnt - 1); c->main_lebs, c->main_first, c->leb_cnt - 1);
dbg_msg("index LEBs: %d", c->lst.idx_lebs); dbg_msg("index LEBs: %d", c->lst.idx_lebs);
dbg_msg("total index bytes: %lld (%lld KiB, %lld MiB)", dbg_msg("total index bytes: %lld (%lld KiB, %lld MiB)",
c->old_idx_sz, c->old_idx_sz >> 10, c->old_idx_sz >> 20); c->bi.old_idx_sz, c->bi.old_idx_sz >> 10,
c->bi.old_idx_sz >> 20);
dbg_msg("key hash type: %d", c->key_hash_type); dbg_msg("key hash type: %d", c->key_hash_type);
dbg_msg("tree fanout: %d", c->fanout); dbg_msg("tree fanout: %d", c->fanout);
dbg_msg("reserved GC LEB: %d", c->gc_lnum); dbg_msg("reserved GC LEB: %d", c->gc_lnum);
@ -1766,10 +1767,9 @@ static void ubifs_put_super(struct super_block *sb)
* to write them back because of I/O errors. * to write them back because of I/O errors.
*/ */
if (!c->ro_error) { if (!c->ro_error) {
ubifs_assert(atomic_long_read(&c->dirty_pg_cnt) == 0); ubifs_assert(c->bi.idx_growth == 0);
ubifs_assert(c->budg_idx_growth == 0); ubifs_assert(c->bi.dd_growth == 0);
ubifs_assert(c->budg_dd_growth == 0); ubifs_assert(c->bi.data_growth == 0);
ubifs_assert(c->budg_data_growth == 0);
} }
/* /*

View file

@ -796,16 +796,16 @@ int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot)
spin_lock(&c->space_lock); spin_lock(&c->space_lock);
/* /*
* Although we have not finished committing yet, update size of the * Although we have not finished committing yet, update size of the
* committed index ('c->old_idx_sz') and zero out the index growth * committed index ('c->bi.old_idx_sz') and zero out the index growth
* budget. It is OK to do this now, because we've reserved all the * budget. It is OK to do this now, because we've reserved all the
* space which is needed to commit the index, and it is save for the * space which is needed to commit the index, and it is save for the
* budgeting subsystem to assume the index is already committed, * budgeting subsystem to assume the index is already committed,
* even though it is not. * even though it is not.
*/ */
ubifs_assert(c->min_idx_lebs == ubifs_calc_min_idx_lebs(c)); ubifs_assert(c->bi.min_idx_lebs == ubifs_calc_min_idx_lebs(c));
c->old_idx_sz = c->calc_idx_sz; c->bi.old_idx_sz = c->calc_idx_sz;
c->budg_uncommitted_idx = 0; c->bi.uncommitted_idx = 0;
c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c);
spin_unlock(&c->space_lock); spin_unlock(&c->space_lock);
mutex_unlock(&c->tnc_mutex); mutex_unlock(&c->tnc_mutex);

View file

@ -937,6 +937,40 @@ struct ubifs_mount_opts {
unsigned int compr_type:2; unsigned int compr_type:2;
}; };
/**
* struct ubifs_budg_info - UBIFS budgeting information.
* @idx_growth: amount of bytes budgeted for index growth
* @data_growth: amount of bytes budgeted for cached data
* @dd_growth: amount of bytes budgeted for cached data that will make
* other data dirty
* @uncommitted_idx: amount of bytes were budgeted for growth of the index, but
* which still have to be taken into account because the index
* has not been committed so far
* @old_idx_sz: size of index on flash
* @min_idx_lebs: minimum number of LEBs required for the index
* @nospace: non-zero if the file-system does not have flash space (used as
* optimization)
* @nospace_rp: the same as @nospace, but additionally means that even reserved
* pool is full
* @page_budget: budget for a page (constant, nenver changed after mount)
* @inode_budget: budget for an inode (constant, nenver changed after mount)
* @dent_budget: budget for a directory entry (constant, nenver changed after
* mount)
*/
struct ubifs_budg_info {
long long idx_growth;
long long data_growth;
long long dd_growth;
long long uncommitted_idx;
unsigned long long old_idx_sz;
int min_idx_lebs;
unsigned int nospace:1;
unsigned int nospace_rp:1;
int page_budget;
int inode_budget;
int dent_budget;
};
struct ubifs_debug_info; struct ubifs_debug_info;
/** /**
@ -1057,32 +1091,14 @@ struct ubifs_debug_info;
* @dirty_zn_cnt: number of dirty znodes * @dirty_zn_cnt: number of dirty znodes
* @clean_zn_cnt: number of clean znodes * @clean_zn_cnt: number of clean znodes
* *
* @budg_idx_growth: amount of bytes budgeted for index growth * @space_lock: protects @bi and @lst
* @budg_data_growth: amount of bytes budgeted for cached data * @lst: lprops statistics
* @budg_dd_growth: amount of bytes budgeted for cached data that will make * @bi: budgeting information
* other data dirty
* @budg_uncommitted_idx: amount of bytes were budgeted for growth of the index,
* but which still have to be taken into account because
* the index has not been committed so far
* @space_lock: protects @budg_idx_growth, @budg_data_growth, @budg_dd_growth,
* @budg_uncommited_idx, @min_idx_lebs, @old_idx_sz, @lst,
* @nospace, and @nospace_rp;
* @min_idx_lebs: minimum number of LEBs required for the index
* @old_idx_sz: size of index on flash
* @calc_idx_sz: temporary variable which is used to calculate new index size * @calc_idx_sz: temporary variable which is used to calculate new index size
* (contains accurate new index size at end of TNC commit start) * (contains accurate new index size at end of TNC commit start)
* @lst: lprops statistics
* @nospace: non-zero if the file-system does not have flash space (used as
* optimization)
* @nospace_rp: the same as @nospace, but additionally means that even reserved
* pool is full
*
* @page_budget: budget for a page
* @inode_budget: budget for an inode
* @dent_budget: budget for a directory entry
* *
* @ref_node_alsz: size of the LEB reference node aligned to the min. flash * @ref_node_alsz: size of the LEB reference node aligned to the min. flash
* I/O unit * I/O unit
* @mst_node_alsz: master node aligned size * @mst_node_alsz: master node aligned size
* @min_idx_node_sz: minimum indexing node aligned on 8-bytes boundary * @min_idx_node_sz: minimum indexing node aligned on 8-bytes boundary
* @max_idx_node_sz: maximum indexing node aligned on 8-bytes boundary * @max_idx_node_sz: maximum indexing node aligned on 8-bytes boundary
@ -1308,21 +1324,10 @@ struct ubifs_info {
atomic_long_t dirty_zn_cnt; atomic_long_t dirty_zn_cnt;
atomic_long_t clean_zn_cnt; atomic_long_t clean_zn_cnt;
long long budg_idx_growth;
long long budg_data_growth;
long long budg_dd_growth;
long long budg_uncommitted_idx;
spinlock_t space_lock; spinlock_t space_lock;
int min_idx_lebs;
unsigned long long old_idx_sz;
unsigned long long calc_idx_sz;
struct ubifs_lp_stats lst; struct ubifs_lp_stats lst;
unsigned int nospace:1; struct ubifs_budg_info bi;
unsigned int nospace_rp:1; unsigned long long calc_idx_sz;
int page_budget;
int inode_budget;
int dent_budget;
int ref_node_alsz; int ref_node_alsz;
int mst_node_alsz; int mst_node_alsz;