fs/btrfs/space-info.c

Source file repositories/reference/linux-study-clean/fs/btrfs/space-info.c

File Facts

System
Linux kernel
Corpus path
fs/btrfs/space-info.c
Extension
.c
Size
73832 bytes
Lines
2268
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 reserve_ticket {
	u64 bytes;
	int error;
	bool steal;
	struct list_head list;
	wait_queue_head_t wait;
	spinlock_t lock;
};

/*
 * after adding space to the filesystem, we need to clear the full flags
 * on all the space infos.
 */
void btrfs_clear_space_info_full(struct btrfs_fs_info *info)
{
	struct list_head *head = &info->space_info;
	struct btrfs_space_info *found;

	list_for_each_entry(found, head, list)
		found->full = false;
}

/*
 * Block groups with more than this value (percents) of unusable space will be
 * scheduled for background reclaim.
 */
#define BTRFS_DEFAULT_ZONED_RECLAIM_THRESH			(75)

#define BTRFS_UNALLOC_BLOCK_GROUP_TARGET			(10ULL)

#define BTRFS_ZONED_SYNC_RECLAIM_BATCH				(5)

/*
 * Calculate chunk size depending on volume type (regular or zoned).
 */
static u64 calc_chunk_size(const struct btrfs_fs_info *fs_info, u64 flags)
{
	if (btrfs_is_zoned(fs_info))
		return fs_info->zone_size;

	ASSERT(flags & BTRFS_BLOCK_GROUP_TYPE_MASK, "flags=%llu", flags);

	if (flags & BTRFS_BLOCK_GROUP_DATA)
		return BTRFS_MAX_DATA_CHUNK_SIZE;
	else if (flags & (BTRFS_BLOCK_GROUP_SYSTEM | BTRFS_BLOCK_GROUP_METADATA_REMAP))
		return SZ_32M;

	/* Handle BTRFS_BLOCK_GROUP_METADATA */
	if (fs_info->fs_devices->total_rw_bytes > 50ULL * SZ_1G)
		return SZ_1G;

	return SZ_256M;
}

/*
 * Update default chunk size.
 */
void btrfs_update_space_info_chunk_size(struct btrfs_space_info *space_info,
					u64 chunk_size)
{
	WRITE_ONCE(space_info->chunk_size, chunk_size);
}

static void init_space_info(struct btrfs_fs_info *info,
			    struct btrfs_space_info *space_info, u64 flags)
{
	space_info->fs_info = info;
	for (int i = 0; i < BTRFS_NR_RAID_TYPES; i++)
		INIT_LIST_HEAD(&space_info->block_groups[i]);
	init_rwsem(&space_info->groups_sem);
	spin_lock_init(&space_info->lock);
	space_info->flags = flags & BTRFS_BLOCK_GROUP_TYPE_MASK;
	space_info->force_alloc = CHUNK_ALLOC_NO_FORCE;
	INIT_LIST_HEAD(&space_info->ro_bgs);
	INIT_LIST_HEAD(&space_info->tickets);
	INIT_LIST_HEAD(&space_info->priority_tickets);
	space_info->clamp = 1;
	btrfs_update_space_info_chunk_size(space_info, calc_chunk_size(info, flags));
	space_info->subgroup_id = BTRFS_SUB_GROUP_PRIMARY;

	if (btrfs_is_zoned(info))
		space_info->bg_reclaim_threshold = BTRFS_DEFAULT_ZONED_RECLAIM_THRESH;
}

static int create_space_info_sub_group(struct btrfs_space_info *parent, u64 flags,
				       enum btrfs_space_info_sub_group id, int index)
{
	struct btrfs_fs_info *fs_info = parent->fs_info;
	struct btrfs_space_info *sub_group;
	int ret;

Annotation

Implementation Notes