block/blk-map.c

Source file repositories/reference/linux-study-clean/block/blk-map.c

File Facts

System
Linux kernel
Corpus path
block/blk-map.c
Extension
.c
Size
15436 bytes
Lines
678
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

struct bio_map_data {
	bool is_our_pages : 1;
	bool is_null_mapped : 1;
	struct iov_iter iter;
	struct iovec iov[];
};

static struct bio_map_data *bio_alloc_map_data(struct iov_iter *data,
					       gfp_t gfp_mask)
{
	struct bio_map_data *bmd;

	if (data->nr_segs > UIO_MAXIOV)
		return NULL;

	bmd = kmalloc_flex(*bmd, iov, data->nr_segs, gfp_mask);
	if (!bmd)
		return NULL;
	bmd->iter = *data;
	if (iter_is_iovec(data)) {
		memcpy(bmd->iov, iter_iov(data), sizeof(struct iovec) * data->nr_segs);
		bmd->iter.__iov = bmd->iov;
	}
	return bmd;
}

static inline void blk_mq_map_bio_put(struct bio *bio)
{
	bio_put(bio);
}

static struct bio *blk_rq_map_bio_alloc(struct request *rq,
		unsigned int nr_vecs, gfp_t gfp_mask)
{
	struct block_device *bdev = rq->q->disk ? rq->q->disk->part0 : NULL;
	struct bio *bio;

	bio = bio_alloc_bioset(bdev, nr_vecs, rq->cmd_flags, gfp_mask,
				&fs_bio_set);
	if (!bio)
		return NULL;

	return bio;
}

/**
 * bio_copy_from_iter - copy all pages from iov_iter to bio
 * @bio: The &struct bio which describes the I/O as destination
 * @iter: iov_iter as source
 *
 * Copy all pages from iov_iter to bio.
 * Returns 0 on success, or error on failure.
 */
static int bio_copy_from_iter(struct bio *bio, struct iov_iter *iter)
{
	struct bio_vec *bvec;
	struct bvec_iter_all iter_all;

	bio_for_each_segment_all(bvec, bio, iter_all) {
		ssize_t ret;

		ret = copy_page_from_iter(bvec->bv_page,
					  bvec->bv_offset,
					  bvec->bv_len,
					  iter);

		if (!iov_iter_count(iter))
			break;

		if (ret < bvec->bv_len)
			return -EFAULT;
	}

	return 0;
}

/**
 * bio_copy_to_iter - copy all pages from bio to iov_iter
 * @bio: The &struct bio which describes the I/O as source
 * @iter: iov_iter as destination
 *
 * Copy all pages from bio to iov_iter.
 * Returns 0 on success, or error on failure.
 */
static int bio_copy_to_iter(struct bio *bio, struct iov_iter iter)
{
	struct bio_vec *bvec;
	struct bvec_iter_all iter_all;

	bio_for_each_segment_all(bvec, bio, iter_all) {

Annotation

Implementation Notes