static int kaio_kernel_submit(struct file *file, struct bio *bio, struct ploop_request * preq, iblock_t iblk, unsigned long rw) { struct kiocb *iocb; unsigned short op; struct iov_iter iter; struct bio_vec *bvec; size_t nr_segs; loff_t pos = (loff_t) bio->bi_sector; pos = ((loff_t)iblk << preq->plo->cluster_log) | (pos & ((1<<preq->plo->cluster_log) - 1)); pos <<= 9; iocb = aio_kernel_alloc(GFP_NOIO); if (!iocb) return -ENOMEM; if (rw & (1<<BIO_RW)) op = IOCB_CMD_WRITE_ITER; else op = IOCB_CMD_READ_ITER; bvec = bio_iovec_idx(bio, bio->bi_idx); nr_segs = bio_segments(bio); iov_iter_init_bvec(&iter, bvec, nr_segs, bvec_length(bvec, nr_segs), 0); aio_kernel_init_iter(iocb, file, op, &iter, pos); aio_kernel_init_callback(iocb, kaio_rw_aio_complete, (u64)preq); return aio_kernel_submit(iocb); }
static int tbio_transfer(struct request *req, struct tbio_device *dev) { unsigned int i = 0, offset = 0; char *buf; unsigned long flags; size_t size; struct bio_vec *bv; struct req_iterator iter; size = blk_rq_cur_bytes(req); prk_info("bio req of size %zu:", size); offset = blk_rq_pos(req) * 512; rq_for_each_segment(bv, req, iter) { size = bv->bv_len; prk_info("%s bio(%u), segs(%u) sect(%u) pos(%lu) off(%u)", (bio_data_dir(iter.bio) == READ) ? "READ" : "WRITE", i, bio_segments(iter.bio), bio_sectors(iter.bio), iter.bio->bi_sector, offset); if (get_capacity(req->rq_disk) * 512 < offset) { prk_info("Error, small capacity %zu, offset %u", get_capacity(req->rq_disk) * 512, offset); continue; } buf = bvec_kmap_irq(bv, &flags); if (bio_data_dir(iter.bio) == WRITE) memcpy(dev->data + offset, buf, size); else memcpy(buf, dev->data + offset, size); offset += size; flush_kernel_dcache_page(bv->bv_page); bvec_kunmap_irq(buf, &flags); ++i; }
void blk_recount_segments(struct request_queue *q, struct bio *bio) { unsigned short seg_cnt; /* estimate segment number by bi_vcnt for non-cloned bio */ if (bio_flagged(bio, BIO_CLONED)) seg_cnt = bio_segments(bio); else seg_cnt = bio->bi_vcnt; if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags) && (seg_cnt < queue_max_segments(q))) bio->bi_phys_segments = seg_cnt; else { struct bio *nxt = bio->bi_next; bio->bi_next = NULL; bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, false); bio->bi_next = nxt; } bio->bi_flags |= (1 << BIO_SEG_VALID); }
void test(int bio){ bio = bio_alloc_bioset ( gfp_mask , bio_segments ( bio_src ) , bs ) ;}