static int crypt_convert_block(struct crypt_config *cc, struct convert_context *ctx, struct ablkcipher_request *req) { struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in); struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out); struct dm_crypt_request *dmreq; u8 *iv; int r; dmreq = dmreq_of_req(cc, req); iv = iv_of_dmreq(cc, dmreq); dmreq->iv_sector = ctx->cc_sector; dmreq->ctx = ctx; sg_init_table(&dmreq->sg_in, 1); sg_set_page(&dmreq->sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT, bv_in->bv_offset + ctx->offset_in); sg_init_table(&dmreq->sg_out, 1); sg_set_page(&dmreq->sg_out, bv_out->bv_page, 1 << SECTOR_SHIFT, bv_out->bv_offset + ctx->offset_out); ctx->offset_in += 1 << SECTOR_SHIFT; if (ctx->offset_in >= bv_in->bv_len) { ctx->offset_in = 0; ctx->idx_in++; } ctx->offset_out += 1 << SECTOR_SHIFT; if (ctx->offset_out >= bv_out->bv_len) { ctx->offset_out = 0; ctx->idx_out++; } if (cc->iv_gen_ops) { r = cc->iv_gen_ops->generator(cc, iv, dmreq); if (r < 0) return r; } ablkcipher_request_set_crypt(req, &dmreq->sg_in, &dmreq->sg_out, 1 << SECTOR_SHIFT, iv); if (bio_data_dir(ctx->bio_in) == WRITE) r = crypto_ablkcipher_encrypt(req); else r = crypto_ablkcipher_decrypt(req); if (!r && cc->iv_gen_ops && cc->iv_gen_ops->post) r = cc->iv_gen_ops->post(cc, iv, dmreq); return r; }
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); }
int sba_print_bio(struct bio *sba_bio) { int i; struct bio_vec *bvl; if ((bio_data_dir(sba_bio) == READ) || (bio_data_dir(sba_bio) == READA) || (bio_data_dir(sba_bio) == READ_SYNC)) { sba_debug(1, "READ block %ld size = %d sectors\n", SBA_SECTOR_TO_BLOCK(sba_bio->bi_sector), bio_sectors(sba_bio)); //access each page of data bio_for_each_segment(bvl, sba_bio, i) { sba_debug(0, "READ: Page vir addrs %0x\n", (int)(bio_iovec_idx(sba_bio, i)->bv_page)); }
static int drct_set_sg_entry(spd_dev_t *dev, int n, struct bio *bio, u32 count) { spd_scatterlist_t *sg = dev->sg; spd_bdev_t *bdev = dev->bdev; struct bio_vec *bvec = bio_iovec_idx(bio, bdev->rmw_bio_idx); u32 bus_addr = 0; u32 size = 0; int i = bdev->rmw_bio_idx; PINFO("idx=%d n=%d count=%lx", bdev->rmw_bio_idx, n, (unsigned long)count); while(count > 0){ bvec = bio_iovec_idx(bio, i); #if defined(CONFIG_P2FAT_FS) if(bio_drct(bio)){ /* Cannot touch bvec->bv_page(=NULL)!! * bvec->bv_private(append new) = bus address!? * bvec->bv_len = data size * maybe offset == 0 */ bus_addr = bvec->bv_private + bdev->rmw_bvec_offset; size = bvec->bv_len - bdev->rmw_bvec_offset; PRINT_BVEC(i, bus_addr, size, bdev->rmw_bvec_offset, n, 1); if(size > count){ PINFO("size=%lx count=%lx", (unsigned long)size, (unsigned long)count); n = set_sg_entry(sg, n, bus_addr, count); bdev->rmw_bvec_offset += count; bdev->rmw_bio_idx = i; break; } n = set_sg_entry(sg, n, bus_addr, size); #else /* ! CONFIG_P2FAT_FS */ if (0) { ; #endif /* CONFIG_P2FAT_FS */ } else { /* Use bvec->bv_page (nomal style) */ unsigned long flags = 0; char *buffer = bvec_kmap_irq(bvec, &flags); bus_addr = virt_to_bus((void *)buffer) + bdev->rmw_bvec_offset; size = bvec->bv_len - bdev->rmw_bvec_offset; PRINT_BVEC(i, bus_addr, size, bdev->rmw_bvec_offset, n, 0); if(size > count){ PINFO("size=%lx count=%lx", (unsigned long)size, (unsigned long)count); n = set_sg_entry(sg, n, bus_addr, count); bdev->rmw_bvec_offset += count; bdev->rmw_bio_idx = i; bvec_kunmap_irq(buffer, &flags); break; } n = set_sg_entry(sg, n, bus_addr, size); bvec_kunmap_irq(buffer, &flags); } if(n < 0){ return n; } i++; count -= size; bdev->rmw_bvec_offset = 0; bdev->rmw_bio_idx = i; } return n; }