fs/ubifs/budget.c

Source file repositories/reference/linux-study-clean/fs/ubifs/budget.c

File Facts

System
Linux kernel
Corpus path
fs/ubifs/budget.c
Extension
.c
Size
23727 bytes
Lines
715
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!retried) {
			retried = 1;
			dbg_budg("-ENOSPC, but anyway try once again");
			goto again;
		}
		dbg_budg("FS is full, -ENOSPC");
		c->bi.nospace = 1;
		if (can_use_rp(c) || c->rp_size == 0)
			c->bi.nospace_rp = 1;
		smp_wmb();
	} else
		ubifs_err(c, "cannot budget space, error %d", err);
	return err;
}

/**
 * ubifs_release_budget - release budgeted free space.
 * @c: UBIFS file-system description object
 * @req: budget request
 *
 * This function releases the space budgeted by 'ubifs_budget_space()'. Note,
 * 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
 * from @c->bi.idx_growth to @c->bi.uncommitted_idx. The latter will be zeroed
 * by the commit operation.
 */
void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req)
{
	ubifs_assert(c, req->new_page <= 1);
	ubifs_assert(c, req->dirtied_page <= 1);
	ubifs_assert(c, req->new_dent <= 1);
	ubifs_assert(c, req->mod_dent <= 1);
	ubifs_assert(c, req->new_ino <= 1);
	ubifs_assert(c, req->new_ino_d <= UBIFS_MAX_INO_DATA);
	ubifs_assert(c, req->dirtied_ino <= 4);
	ubifs_assert(c, req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4);
	ubifs_assert(c, !(req->new_ino_d & 7));
	ubifs_assert(c, !(req->dirtied_ino_d & 7));
	if (!req->recalculate) {
		ubifs_assert(c, req->idx_growth >= 0);
		ubifs_assert(c, req->data_growth >= 0);
		ubifs_assert(c, req->dd_growth >= 0);
	}

	if (req->recalculate) {
		req->data_growth = calc_data_growth(c, req);
		req->dd_growth = calc_dd_growth(c, req);
		req->idx_growth = calc_idx_growth(c, req);
	}

	if (!req->data_growth && !req->dd_growth)
		return;

	c->bi.nospace = c->bi.nospace_rp = 0;
	smp_wmb();

	spin_lock(&c->space_lock);
	c->bi.idx_growth -= req->idx_growth;
	c->bi.uncommitted_idx += req->idx_growth;
	c->bi.data_growth -= req->data_growth;
	c->bi.dd_growth -= req->dd_growth;
	c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c);

	ubifs_assert(c, c->bi.idx_growth >= 0);
	ubifs_assert(c, c->bi.data_growth >= 0);
	ubifs_assert(c, c->bi.dd_growth >= 0);
	ubifs_assert(c, c->bi.min_idx_lebs < c->main_lebs);
	ubifs_assert(c, !(c->bi.idx_growth & 7));
	ubifs_assert(c, !(c->bi.data_growth & 7));
	ubifs_assert(c, !(c->bi.dd_growth & 7));
	spin_unlock(&c->space_lock);
}

/**
 * ubifs_convert_page_budget - convert budget of a new page.
 * @c: UBIFS file-system description object
 *
 * This function converts budget which was allocated for a new page of data to
 * the budget of changing an existing page of data. The latter is smaller than
 * the former, so this function only does simple re-calculation and does not
 * involve any write-back.
 */
void ubifs_convert_page_budget(struct ubifs_info *c)
{
	spin_lock(&c->space_lock);
	/* Release the index growth reservation */
	c->bi.idx_growth -= c->max_idx_node_sz << UBIFS_BLOCKS_PER_PAGE_SHIFT;
	/* Release the data growth reservation */
	c->bi.data_growth -= c->bi.page_budget;
	/* Increase the dirty data growth reservation instead */

Annotation

Implementation Notes