fs/btrfs/bio.c

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

File Facts

System
Linux kernel
Corpus path
fs/btrfs/bio.c
Extension
.c
Size
31947 bytes
Lines
1073
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_failed_bio {
	struct btrfs_bio *bbio;
	int num_copies;
	atomic_t repair_count;
};

/* Is this a data path I/O that needs storage layer checksum and repair? */
static inline bool is_data_bbio(const struct btrfs_bio *bbio)
{
	return bbio->inode && is_data_inode(bbio->inode);
}

static bool bbio_has_ordered_extent(const struct btrfs_bio *bbio)
{
	return is_data_bbio(bbio) && btrfs_op(&bbio->bio) == BTRFS_MAP_WRITE;
}

/*
 * Initialize a btrfs_bio structure.  This skips the embedded bio itself as it
 * is already initialized by the block layer.
 */
void btrfs_bio_init(struct btrfs_bio *bbio, struct btrfs_inode *inode, u64 file_offset,
		    btrfs_bio_end_io_t end_io, void *private)
{
	/* @inode parameter is mandatory. */
	ASSERT(inode);

	memset(bbio, 0, offsetof(struct btrfs_bio, bio));
	bbio->inode = inode;
	bbio->end_io = end_io;
	bbio->private = private;
	bbio->file_offset = file_offset;
	atomic_set(&bbio->pending_ios, 1);
	WRITE_ONCE(bbio->status, BLK_STS_OK);
}

/*
 * Allocate a btrfs_bio structure.  The btrfs_bio is the main I/O container for
 * btrfs, and is used for all I/O submitted through btrfs_submit_bbio().
 *
 * Just like the underlying bio_alloc_bioset it will not fail as it is backed by
 * a mempool.
 */
struct btrfs_bio *btrfs_bio_alloc(unsigned int nr_vecs, blk_opf_t opf,
				  struct btrfs_inode *inode, u64 file_offset,
				  btrfs_bio_end_io_t end_io, void *private)
{
	struct btrfs_bio *bbio;
	struct bio *bio;

	bio = bio_alloc_bioset(NULL, nr_vecs, opf, GFP_NOFS, &btrfs_bioset);
	bbio = btrfs_bio(bio);
	btrfs_bio_init(bbio, inode, file_offset, end_io, private);
	return bbio;
}

static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info,
					 struct btrfs_bio *orig_bbio,
					 u64 map_length)
{
	struct btrfs_bio *bbio;
	struct bio *bio;

	bio = bio_split(&orig_bbio->bio, map_length >> SECTOR_SHIFT, GFP_NOFS,
			&btrfs_clone_bioset);
	if (IS_ERR(bio))
		return ERR_CAST(bio);

	bbio = btrfs_bio(bio);
	btrfs_bio_init(bbio, orig_bbio->inode, orig_bbio->file_offset, NULL, orig_bbio);
	orig_bbio->file_offset += map_length;
	if (bbio_has_ordered_extent(bbio)) {
		refcount_inc(&orig_bbio->ordered->refs);
		bbio->ordered = orig_bbio->ordered;
		bbio->orig_logical = orig_bbio->orig_logical;
		orig_bbio->orig_logical += map_length;
	}

	bbio->csum_search_commit_root = orig_bbio->csum_search_commit_root;
	bbio->can_use_append = orig_bbio->can_use_append;
	bbio->is_scrub = orig_bbio->is_scrub;
	bbio->is_remap = orig_bbio->is_remap;
	bbio->async_csum = orig_bbio->async_csum;

	atomic_inc(&orig_bbio->pending_ios);
	return bbio;
}

void btrfs_bio_end_io(struct btrfs_bio *bbio, blk_status_t status)
{

Annotation

Implementation Notes