Commit feb261e2 authored by Kent Overstreet's avatar Kent Overstreet

aoe: Convert to immutable biovecs

Now that we've got a mechanism for immutable biovecs -
bi_iter.bi_bvec_done - we need to convert drivers to use primitives that
respect it instead of using the bvec array directly.

The aoe code no longer has to manually iterate over partial bvecs, so
some struct members go away - other struct members are effectively
renamed:

buf->resid	-> buf->iter.bi_size
buf->sector	-> buf->iter.bi_sector

f->bcnt		-> f->iter.bi_size
f->lba		-> f->iter.bi_sector
Signed-off-by: default avatarKent Overstreet <kmo@daterainc.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: "Ed L. Cashin" <ecashin@coraid.com>
parent 003b5c57
...@@ -100,11 +100,8 @@ enum { ...@@ -100,11 +100,8 @@ enum {
struct buf { struct buf {
ulong nframesout; ulong nframesout;
ulong resid;
ulong bv_resid;
sector_t sector;
struct bio *bio; struct bio *bio;
struct bio_vec *bv; struct bvec_iter iter;
struct request *rq; struct request *rq;
}; };
...@@ -120,13 +117,10 @@ struct frame { ...@@ -120,13 +117,10 @@ struct frame {
ulong waited; ulong waited;
ulong waited_total; ulong waited_total;
struct aoetgt *t; /* parent target I belong to */ struct aoetgt *t; /* parent target I belong to */
sector_t lba;
struct sk_buff *skb; /* command skb freed on module exit */ struct sk_buff *skb; /* command skb freed on module exit */
struct sk_buff *r_skb; /* response skb for async processing */ struct sk_buff *r_skb; /* response skb for async processing */
struct buf *buf; struct buf *buf;
struct bio_vec *bv; struct bvec_iter iter;
ulong bcnt;
ulong bv_off;
char flags; char flags;
}; };
......
...@@ -196,8 +196,7 @@ aoe_freetframe(struct frame *f) ...@@ -196,8 +196,7 @@ aoe_freetframe(struct frame *f)
t = f->t; t = f->t;
f->buf = NULL; f->buf = NULL;
f->lba = 0; memset(&f->iter, 0, sizeof(f->iter));
f->bv = NULL;
f->r_skb = NULL; f->r_skb = NULL;
f->flags = 0; f->flags = 0;
list_add(&f->head, &t->ffree); list_add(&f->head, &t->ffree);
...@@ -295,21 +294,14 @@ newframe(struct aoedev *d) ...@@ -295,21 +294,14 @@ newframe(struct aoedev *d)
} }
static void static void
skb_fillup(struct sk_buff *skb, struct bio_vec *bv, ulong off, ulong cnt) skb_fillup(struct sk_buff *skb, struct bio *bio, struct bvec_iter iter)
{ {
int frag = 0; int frag = 0;
ulong fcnt; struct bio_vec bv;
loop:
fcnt = bv->bv_len - (off - bv->bv_offset); __bio_for_each_segment(bv, bio, iter, iter)
if (fcnt > cnt) skb_fill_page_desc(skb, frag++, bv.bv_page,
fcnt = cnt; bv.bv_offset, bv.bv_len);
skb_fill_page_desc(skb, frag++, bv->bv_page, off, fcnt);
cnt -= fcnt;
if (cnt <= 0)
return;
bv++;
off = bv->bv_offset;
goto loop;
} }
static void static void
...@@ -346,12 +338,10 @@ ata_rw_frameinit(struct frame *f) ...@@ -346,12 +338,10 @@ ata_rw_frameinit(struct frame *f)
t->nout++; t->nout++;
f->waited = 0; f->waited = 0;
f->waited_total = 0; f->waited_total = 0;
if (f->buf)
f->lba = f->buf->sector;
/* set up ata header */ /* set up ata header */
ah->scnt = f->bcnt >> 9; ah->scnt = f->iter.bi_size >> 9;
put_lba(ah, f->lba); put_lba(ah, f->iter.bi_sector);
if (t->d->flags & DEVFL_EXT) { if (t->d->flags & DEVFL_EXT) {
ah->aflags |= AOEAFL_EXT; ah->aflags |= AOEAFL_EXT;
} else { } else {
...@@ -360,11 +350,11 @@ ata_rw_frameinit(struct frame *f) ...@@ -360,11 +350,11 @@ ata_rw_frameinit(struct frame *f)
ah->lba3 |= 0xe0; /* LBA bit + obsolete 0xa0 */ ah->lba3 |= 0xe0; /* LBA bit + obsolete 0xa0 */
} }
if (f->buf && bio_data_dir(f->buf->bio) == WRITE) { if (f->buf && bio_data_dir(f->buf->bio) == WRITE) {
skb_fillup(skb, f->bv, f->bv_off, f->bcnt); skb_fillup(skb, f->buf->bio, f->iter);
ah->aflags |= AOEAFL_WRITE; ah->aflags |= AOEAFL_WRITE;
skb->len += f->bcnt; skb->len += f->iter.bi_size;
skb->data_len = f->bcnt; skb->data_len = f->iter.bi_size;
skb->truesize += f->bcnt; skb->truesize += f->iter.bi_size;
t->wpkts++; t->wpkts++;
} else { } else {
t->rpkts++; t->rpkts++;
...@@ -382,7 +372,6 @@ aoecmd_ata_rw(struct aoedev *d) ...@@ -382,7 +372,6 @@ aoecmd_ata_rw(struct aoedev *d)
struct buf *buf; struct buf *buf;
struct sk_buff *skb; struct sk_buff *skb;
struct sk_buff_head queue; struct sk_buff_head queue;
ulong bcnt, fbcnt;
buf = nextbuf(d); buf = nextbuf(d);
if (buf == NULL) if (buf == NULL)
...@@ -390,39 +379,22 @@ aoecmd_ata_rw(struct aoedev *d) ...@@ -390,39 +379,22 @@ aoecmd_ata_rw(struct aoedev *d)
f = newframe(d); f = newframe(d);
if (f == NULL) if (f == NULL)
return 0; return 0;
bcnt = d->maxbcnt;
if (bcnt == 0)
bcnt = DEFAULTBCNT;
if (bcnt > buf->resid)
bcnt = buf->resid;
fbcnt = bcnt;
f->bv = buf->bv;
f->bv_off = f->bv->bv_offset + (f->bv->bv_len - buf->bv_resid);
do {
if (fbcnt < buf->bv_resid) {
buf->bv_resid -= fbcnt;
buf->resid -= fbcnt;
break;
}
fbcnt -= buf->bv_resid;
buf->resid -= buf->bv_resid;
if (buf->resid == 0) {
d->ip.buf = NULL;
break;
}
buf->bv++;
buf->bv_resid = buf->bv->bv_len;
WARN_ON(buf->bv_resid == 0);
} while (fbcnt);
/* initialize the headers & frame */ /* initialize the headers & frame */
f->buf = buf; f->buf = buf;
f->bcnt = bcnt; f->iter = buf->iter;
ata_rw_frameinit(f); f->iter.bi_size = min_t(unsigned long,
d->maxbcnt ?: DEFAULTBCNT,
f->iter.bi_size);
bio_advance_iter(buf->bio, &buf->iter, f->iter.bi_size);
if (!buf->iter.bi_size)
d->ip.buf = NULL;
/* mark all tracking fields and load out */ /* mark all tracking fields and load out */
buf->nframesout += 1; buf->nframesout += 1;
buf->sector += bcnt >> 9;
ata_rw_frameinit(f);
skb = skb_clone(f->skb, GFP_ATOMIC); skb = skb_clone(f->skb, GFP_ATOMIC);
if (skb) { if (skb) {
...@@ -613,10 +585,7 @@ reassign_frame(struct frame *f) ...@@ -613,10 +585,7 @@ reassign_frame(struct frame *f)
skb = nf->skb; skb = nf->skb;
nf->skb = f->skb; nf->skb = f->skb;
nf->buf = f->buf; nf->buf = f->buf;
nf->bcnt = f->bcnt; nf->iter = f->iter;
nf->lba = f->lba;
nf->bv = f->bv;
nf->bv_off = f->bv_off;
nf->waited = 0; nf->waited = 0;
nf->waited_total = f->waited_total; nf->waited_total = f->waited_total;
nf->sent = f->sent; nf->sent = f->sent;
...@@ -648,19 +617,19 @@ probe(struct aoetgt *t) ...@@ -648,19 +617,19 @@ probe(struct aoetgt *t)
} }
f->flags |= FFL_PROBE; f->flags |= FFL_PROBE;
ifrotate(t); ifrotate(t);
f->bcnt = t->d->maxbcnt ? t->d->maxbcnt : DEFAULTBCNT; f->iter.bi_size = t->d->maxbcnt ? t->d->maxbcnt : DEFAULTBCNT;
ata_rw_frameinit(f); ata_rw_frameinit(f);
skb = f->skb; skb = f->skb;
for (frag = 0, n = f->bcnt; n > 0; ++frag, n -= m) { for (frag = 0, n = f->iter.bi_size; n > 0; ++frag, n -= m) {
if (n < PAGE_SIZE) if (n < PAGE_SIZE)
m = n; m = n;
else else
m = PAGE_SIZE; m = PAGE_SIZE;
skb_fill_page_desc(skb, frag, empty_page, 0, m); skb_fill_page_desc(skb, frag, empty_page, 0, m);
} }
skb->len += f->bcnt; skb->len += f->iter.bi_size;
skb->data_len = f->bcnt; skb->data_len = f->iter.bi_size;
skb->truesize += f->bcnt; skb->truesize += f->iter.bi_size;
skb = skb_clone(f->skb, GFP_ATOMIC); skb = skb_clone(f->skb, GFP_ATOMIC);
if (skb) { if (skb) {
...@@ -929,12 +898,8 @@ bufinit(struct buf *buf, struct request *rq, struct bio *bio) ...@@ -929,12 +898,8 @@ bufinit(struct buf *buf, struct request *rq, struct bio *bio)
memset(buf, 0, sizeof(*buf)); memset(buf, 0, sizeof(*buf));
buf->rq = rq; buf->rq = rq;
buf->bio = bio; buf->bio = bio;
buf->resid = bio->bi_iter.bi_size; buf->iter = bio->bi_iter;
buf->sector = bio->bi_iter.bi_sector;
bio_pageinc(bio); bio_pageinc(bio);
buf->bv = __bio_iovec(bio);
buf->bv_resid = buf->bv->bv_len;
WARN_ON(buf->bv_resid == 0);
} }
static struct buf * static struct buf *
...@@ -1119,24 +1084,18 @@ gettgt(struct aoedev *d, char *addr) ...@@ -1119,24 +1084,18 @@ gettgt(struct aoedev *d, char *addr)
} }
static void static void
bvcpy(struct bio_vec *bv, ulong off, struct sk_buff *skb, long cnt) bvcpy(struct sk_buff *skb, struct bio *bio, struct bvec_iter iter, long cnt)
{ {
ulong fcnt;
char *p;
int soff = 0; int soff = 0;
loop: struct bio_vec bv;
fcnt = bv->bv_len - (off - bv->bv_offset);
if (fcnt > cnt) iter.bi_size = cnt;
fcnt = cnt;
p = page_address(bv->bv_page) + off; __bio_for_each_segment(bv, bio, iter, iter) {
skb_copy_bits(skb, soff, p, fcnt); char *p = page_address(bv.bv_page) + bv.bv_offset;
soff += fcnt; skb_copy_bits(skb, soff, p, bv.bv_len);
cnt -= fcnt; soff += bv.bv_len;
if (cnt <= 0) }
return;
bv++;
off = bv->bv_offset;
goto loop;
} }
void void
...@@ -1229,7 +1188,15 @@ noskb: if (buf) ...@@ -1229,7 +1188,15 @@ noskb: if (buf)
clear_bit(BIO_UPTODATE, &buf->bio->bi_flags); clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
break; break;
} }
bvcpy(f->bv, f->bv_off, skb, n); if (n > f->iter.bi_size) {
pr_err_ratelimited("%s e%ld.%d. bytes=%ld need=%u\n",
"aoe: too-large data size in read from",
(long) d->aoemajor, d->aoeminor,
n, f->iter.bi_size);
clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
break;
}
bvcpy(skb, f->buf->bio, f->iter, n);
case ATA_CMD_PIO_WRITE: case ATA_CMD_PIO_WRITE:
case ATA_CMD_PIO_WRITE_EXT: case ATA_CMD_PIO_WRITE_EXT:
spin_lock_irq(&d->lock); spin_lock_irq(&d->lock);
...@@ -1272,7 +1239,7 @@ noskb: if (buf) ...@@ -1272,7 +1239,7 @@ noskb: if (buf)
aoe_freetframe(f); aoe_freetframe(f);
if (buf && --buf->nframesout == 0 && buf->resid == 0) if (buf && --buf->nframesout == 0 && buf->iter.bi_size == 0)
aoe_end_buf(d, buf); aoe_end_buf(d, buf);
spin_unlock_irq(&d->lock); spin_unlock_irq(&d->lock);
...@@ -1727,7 +1694,7 @@ aoe_failbuf(struct aoedev *d, struct buf *buf) ...@@ -1727,7 +1694,7 @@ aoe_failbuf(struct aoedev *d, struct buf *buf)
{ {
if (buf == NULL) if (buf == NULL)
return; return;
buf->resid = 0; buf->iter.bi_size = 0;
clear_bit(BIO_UPTODATE, &buf->bio->bi_flags); clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
if (buf->nframesout == 0) if (buf->nframesout == 0)
aoe_end_buf(d, buf); aoe_end_buf(d, buf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment