Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
/*
 * 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;
}
Пример #4
0
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;
}