fs/ext4/extents_status.c

Source file repositories/reference/linux-study-clean/fs/ext4/extents_status.c

File Facts

System
Linux kernel
Corpus path
fs/ext4/extents_status.c
Extension
.c
Size
68570 bytes
Lines
2393
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

struct rsvd_count {
	int ndelayed;
	bool first_do_lblk_found;
	ext4_lblk_t first_do_lblk;
	ext4_lblk_t last_do_lblk;
	struct extent_status *left_es;
	bool partial;
	ext4_lblk_t lclu;
};

/*
 * init_rsvd - initialize reserved count data before removing block range
 *	       in file from extent status tree
 *
 * @inode - file containing range
 * @lblk - first block in range
 * @es - pointer to first extent in range
 * @rc - pointer to reserved count data
 *
 * Assumes es is not NULL
 */
static void init_rsvd(struct inode *inode, ext4_lblk_t lblk,
		      struct extent_status *es, struct rsvd_count *rc)
{
	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
	struct rb_node *node;

	rc->ndelayed = 0;

	/*
	 * for bigalloc, note the first delayed block in the range has not
	 * been found, record the extent containing the block to the left of
	 * the region to be removed, if any, and note that there's no partial
	 * cluster to track
	 */
	if (sbi->s_cluster_ratio > 1) {
		rc->first_do_lblk_found = false;
		if (lblk > es->es_lblk) {
			rc->left_es = es;
		} else {
			node = rb_prev(&es->rb_node);
			rc->left_es = node ? rb_entry(node,
						      struct extent_status,
						      rb_node) : NULL;
		}
		rc->partial = false;
	}
}

/*
 * count_rsvd - count the clusters containing delayed blocks in a range
 *	        within an extent and add to the running tally in rsvd_count
 *
 * @inode - file containing extent
 * @lblk - first block in range
 * @len - length of range in blocks
 * @es - pointer to extent containing clusters to be counted
 * @rc - pointer to reserved count data
 *
 * Tracks partial clusters found at the beginning and end of extents so
 * they aren't overcounted when they span adjacent extents
 */
static void count_rsvd(struct inode *inode, ext4_lblk_t lblk, long len,
		       struct extent_status *es, struct rsvd_count *rc)
{
	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
	ext4_lblk_t i, end, nclu;

	if (!ext4_es_is_delayed(es))
		return;

	WARN_ON(len <= 0);

	if (sbi->s_cluster_ratio == 1) {
		rc->ndelayed += (int) len;
		return;
	}

	/* bigalloc */

	i = (lblk < es->es_lblk) ? es->es_lblk : lblk;
	end = lblk + (ext4_lblk_t) len - 1;
	end = (end > ext4_es_end(es)) ? ext4_es_end(es) : end;

	/* record the first block of the first delayed extent seen */
	if (!rc->first_do_lblk_found) {
		rc->first_do_lblk = i;
		rc->first_do_lblk_found = true;
	}

Annotation

Implementation Notes