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:
parent
cc64f774b4
commit
b137545c44
11 changed files with 134 additions and 129 deletions
|
@ -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 -
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 -
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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, "
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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,29 +1091,11 @@ 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
|
||||||
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue