fs/btrfs/extent_io.c

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

File Facts

System
Linux kernel
Corpus path
fs/btrfs/extent_io.c
Extension
.c
Size
137942 bytes
Lines
4693
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 btrfs_bio_ctrl {
	struct btrfs_bio *bbio;
	/* Last byte contained in bbio + 1 . */
	loff_t next_file_offset;
	enum btrfs_compression_type compress_type;
	u32 len_to_oe_boundary;
	blk_opf_t opf;
	/*
	 * For data read bios, we attempt to optimize csum lookups if the extent
	 * generation is older than the current one. To make this possible, we
	 * need to track the maximum generation of an extent in a bio_ctrl to
	 * make the decision when submitting the bio.
	 *
	 * The pattern between do_readpage(), submit_one_bio() and
	 * submit_extent_folio() is quite subtle, so tracking this is tricky.
	 *
	 * As we process extent E, we might submit a bio with existing built up
	 * extents before adding E to a new bio, or we might just add E to the
	 * bio. As a result, E's generation could apply to the current bio or
	 * to the next one, so we need to be careful to update the bio_ctrl's
	 * generation with E's only when we are sure E is added to bio_ctrl->bbio
	 * in submit_extent_folio().
	 *
	 * See the comment in btrfs_lookup_bio_sums() for more detail on the
	 * need for this optimization.
	 */
	u64 generation;
	btrfs_bio_end_io_t end_io_func;
	struct writeback_control *wbc;

	/*
	 * The sectors of the page which are going to be submitted by
	 * extent_writepage_io().
	 * This is to avoid touching ranges covered by compression/inline.
	 */
	unsigned long submit_bitmap[BITS_TO_LONGS(BTRFS_MAX_BLOCKS_PER_FOLIO)];

	struct readahead_control *ractl;

	/*
	 * The start offset of the last used extent map by a read operation.
	 *
	 * This is for proper compressed read merge.
	 * U64_MAX means we are starting the read and have made no progress yet.
	 *
	 * The current btrfs_bio_is_contig() only uses disk_bytenr as
	 * the condition to check if the read can be merged with previous
	 * bio, which is not correct. E.g. two file extents pointing to the
	 * same extent but with different offset.
	 *
	 * So here we need to do extra checks to only merge reads that are
	 * covered by the same extent map.
	 * Just extent_map::start will be enough, as they are unique
	 * inside the same inode.
	 */
	u64 last_em_start;
};

/*
 * Helper to set the csum search commit root option for a bio_ctrl's bbio
 * before submitting the bio.
 *
 * Only for use by submit_one_bio().
 */
static void bio_set_csum_search_commit_root(struct btrfs_bio_ctrl *bio_ctrl)
{
	struct btrfs_bio *bbio = bio_ctrl->bbio;

	ASSERT(bbio);

	if (!(btrfs_op(&bbio->bio) == BTRFS_MAP_READ && is_data_inode(bbio->inode)))
		return;

	bio_ctrl->bbio->csum_search_commit_root =
		(bio_ctrl->generation &&
		 bio_ctrl->generation < btrfs_get_fs_generation(bbio->inode->root->fs_info));
}

static void submit_one_bio(struct btrfs_bio_ctrl *bio_ctrl)
{
	struct btrfs_bio *bbio = bio_ctrl->bbio;

	if (!bbio)
		return;

	/* Caller should ensure the bio has at least some range added */
	ASSERT(bbio->bio.bi_iter.bi_size);

	bio_set_csum_search_commit_root(bio_ctrl);

Annotation

Implementation Notes