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); }
double bvec_ber (bvec v1, bvec v2) { int lmin, lmax, d = 0; idx_t i; if (bvec_length (v1) > bvec_length (v2)) { lmin = bvec_length (v2); lmax = bvec_length (v1); } else { lmin = bvec_length (v1); lmax = bvec_length (v2); } for (i = 0; i < lmin; i++) if (v1[i] != v2[i]) d++; return (d + lmax - bvec_length (v2)) / (double) bvec_length (v1); }
/* * Pack as many bios from the list pointed by '*bio_pp' to kreq as possible, * but no more than 'size' bytes. Returns 'copy' equal to # bytes copied. * * <*bio_pp, *idx_p> plays the role of iterator to walk through bio list. * NB: the iterator is valid only while 'size' > 'copy' * * NB: at enter, '*nr_segs' depicts capacity of kreq; * at return, it depicts actual payload */ static size_t kaio_kreq_pack(struct kaio_req *kreq, int *nr_segs, struct bio **bio_pp, int *idx_p, size_t size) { int kreq_nr_max = *nr_segs; struct bio *b = *bio_pp; int idx = *idx_p; struct bio_vec *src_bv = b->bi_io_vec + idx; struct bio_vec *dst_bv = kreq->bvecs; size_t copy = 0; BUG_ON(b->bi_idx); while (1) { int nr = min_t(int, kreq_nr_max, b->bi_vcnt - idx); BUG_ON(!nr); memcpy(dst_bv, src_bv, nr * sizeof(struct bio_vec)); copy += bvec_length(dst_bv, nr); if (copy >= size) { *nr_segs = dst_bv - kreq->bvecs + nr; return size; } dst_bv += nr; src_bv += nr; idx += nr; if (b->bi_vcnt == idx) { b = b->bi_next; BUG_ON(!b); src_bv = b->bi_io_vec; idx = 0; } kreq_nr_max -= nr; if (kreq_nr_max == 0) break; } *bio_pp = b; *idx_p = idx; return copy; }
int bvec_distance_hamming (bvec v1, bvec v2) { int lmin, lmax, d = 0; idx_t i; if (bvec_length (v1) > bvec_length (v2)) { lmin = bvec_length (v2); lmax = bvec_length (v1); } else { lmin = bvec_length (v1); lmax = bvec_length (v2); } for (i = 0; i < lmin; i++) if (v1[i] != v2[i]) d++; return d + lmax - lmin; }