Add error flag to cbd_params, set it on write error
This commit is contained in:
parent
97eb421b58
commit
66eeec39f5
|
@ -91,7 +91,8 @@ compress_read_header(struct compress* c)
|
||||||
pblkbuf = page_address(pblkpage);
|
pblkbuf = page_address(pblkpage);
|
||||||
iopagev[0] = pblkpage;
|
iopagev[0] = pblkpage;
|
||||||
|
|
||||||
ret = pblk_read_wait(c->dev->bdev, 0, 1, iopagev);
|
header.params.priv = c->dev->bdev;
|
||||||
|
ret = pblk_read_wait(&header.params, 0, 1, iopagev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_ERR "%s: failed to read header\n", __func__);
|
printk(KERN_ERR "%s: failed to read header\n", __func__);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -186,7 +187,7 @@ compress_write_header(struct compress* c)
|
||||||
memcpy(&header.stats, &c->stats, sizeof(header.stats));
|
memcpy(&header.stats, &c->stats, sizeof(header.stats));
|
||||||
cbd_header_put(pblkbuf, &header);
|
cbd_header_put(pblkbuf, &header);
|
||||||
iopagev[0] = pblkpage;
|
iopagev[0] = pblkpage;
|
||||||
ret = pblk_write_wait(c->params.priv, 0, 1, iopagev);
|
ret = pblk_write_wait(&c->params, 0, 1, iopagev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_ERR "%s: failed to write header\n", __func__);
|
printk(KERN_ERR "%s: failed to write header\n", __func__);
|
||||||
}
|
}
|
||||||
|
@ -475,6 +476,12 @@ compress_map(struct dm_target *ti, struct bio *bio)
|
||||||
struct compress *c = ti->private;
|
struct compress *c = ti->private;
|
||||||
struct compress_io *cio;
|
struct compress_io *cio;
|
||||||
|
|
||||||
|
if (c->params.flags & CBD_FLAG_ERROR) {
|
||||||
|
bio->bi_status = BLK_STS_IOERR;
|
||||||
|
bio_endio(bio);
|
||||||
|
return DM_MAPIO_SUBMITTED; /* XXXX: DM_MAPIO_KILL? */
|
||||||
|
}
|
||||||
|
|
||||||
/* from dm-crypt.c */
|
/* from dm-crypt.c */
|
||||||
if (unlikely(bio->bi_opf & REQ_PREFLUSH || bio_op(bio) == REQ_OP_DISCARD)) {
|
if (unlikely(bio->bi_opf & REQ_PREFLUSH || bio_op(bio) == REQ_OP_DISCARD)) {
|
||||||
bio_set_dev(bio, c->dev->bdev);
|
bio_set_dev(bio, c->dev->bdev);
|
||||||
|
|
|
@ -91,7 +91,7 @@ lbatpage_flush(struct lbatpage* lp)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
iopagev[0] = lp->page;
|
iopagev[0] = lp->page;
|
||||||
pblk_write(lp->params->priv, lp->pblk, 1, iopagev);
|
pblk_write(lp->params, lp->pblk, 1, iopagev);
|
||||||
mutex_unlock(&lp->lock);
|
mutex_unlock(&lp->lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -110,7 +110,7 @@ lbatpage_read(struct lbatpage* lp)
|
||||||
struct page* pagev[1];
|
struct page* pagev[1];
|
||||||
|
|
||||||
pagev[0] = lp->page;
|
pagev[0] = lp->page;
|
||||||
ret = pblk_read_wait(lp->params->priv, lp->pblk, 1, pagev);
|
ret = pblk_read_wait(lp->params, lp->pblk, 1, pagev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -354,7 +354,7 @@ lbd_flush(struct lbd* lbd, struct cbd_stats* stats)
|
||||||
pblk = lbatview_elem_pblk(lbd->lv, lbd->lblk, n);
|
pblk = lbatview_elem_pblk(lbd->lv, lbd->lblk, n);
|
||||||
BUG_ON(pblk == PBLK_NONE);
|
BUG_ON(pblk == PBLK_NONE);
|
||||||
iopagev[0] = lbd->pagev[n];
|
iopagev[0] = lbd->pagev[n];
|
||||||
pblk_write(lbd->params->priv, pblk, 1, iopagev);
|
pblk_write(lbd->params, pblk, 1, iopagev);
|
||||||
}
|
}
|
||||||
while (n < lblk_per_pblk(lbd->params)) {
|
while (n < lblk_per_pblk(lbd->params)) {
|
||||||
unlock_page(lbd->pagev[n]);
|
unlock_page(lbd->pagev[n]);
|
||||||
|
@ -407,7 +407,7 @@ lbd_read(struct lbd* lbd)
|
||||||
}
|
}
|
||||||
iopagev[0] = lbd->pagev[n];
|
iopagev[0] = lbd->pagev[n];
|
||||||
/* XXX: Issue non-blocking reads? */
|
/* XXX: Issue non-blocking reads? */
|
||||||
ret = pblk_read_wait(lbd->params->priv, pblk, 1, iopagev);
|
ret = pblk_read_wait(lbd->params, pblk, 1, iopagev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ pbat_flush(struct pbat* pbat)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
pblk = pbat_off(pbat->params, pbat->zone);
|
pblk = pbat_off(pbat->params, pbat->zone);
|
||||||
pblk_write(pbat->params->priv, pblk, nr_pages, pbat->pagev);
|
pblk_write(pbat->params, pblk, nr_pages, pbat->pagev);
|
||||||
mutex_unlock(&pbat->lock);
|
mutex_unlock(&pbat->lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -138,7 +138,7 @@ pbat_read(struct pbat* pbat)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
pblk = pbat_off(pbat->params, pbat->zone);
|
pblk = pbat_off(pbat->params, pbat->zone);
|
||||||
ret = pblk_read_wait(pbat->params->priv, pblk, nr_pages, pbat->pagev);
|
ret = pblk_read_wait(pbat->params, pblk, nr_pages, pbat->pagev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,13 +123,13 @@ pblk_io_prepare(struct block_device* bdev, unsigned int op,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pblk_read_wait(struct block_device* bdev,
|
pblk_read_wait(struct cbd_params* params,
|
||||||
u64 pblk, u32 count, struct page** pagev)
|
u64 pblk, u32 count, struct page** pagev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct bio* bio;
|
struct bio* bio;
|
||||||
|
|
||||||
bio = pblk_io_prepare(bdev, REQ_OP_READ, pblk, count, pagev);
|
bio = pblk_io_prepare(params->priv, REQ_OP_READ, pblk, count, pagev);
|
||||||
if (!bio) {
|
if (!bio) {
|
||||||
printk(KERN_ERR "%s: out of memory\n", __func__);
|
printk(KERN_ERR "%s: out of memory\n", __func__);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -144,13 +144,13 @@ pblk_read_wait(struct block_device* bdev,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pblk_write_wait(struct block_device* bdev,
|
pblk_write_wait(struct cbd_params* params,
|
||||||
u64 pblk, u32 count, struct page** pagev)
|
u64 pblk, u32 count, struct page** pagev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct bio* bio;
|
struct bio* bio;
|
||||||
|
|
||||||
bio = pblk_io_prepare(bdev, REQ_OP_WRITE, pblk, count, pagev);
|
bio = pblk_io_prepare(params->priv, REQ_OP_WRITE, pblk, count, pagev);
|
||||||
if (!bio) {
|
if (!bio) {
|
||||||
printk(KERN_ERR "%s: out of memory\n", __func__);
|
printk(KERN_ERR "%s: out of memory\n", __func__);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -158,6 +158,7 @@ pblk_write_wait(struct block_device* bdev,
|
||||||
ret = submit_bio_wait(bio);
|
ret = submit_bio_wait(bio);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_ERR "%s: submit_bio_wait failed: %d\n", __func__, ret);
|
printk(KERN_ERR "%s: submit_bio_wait failed: %d\n", __func__, ret);
|
||||||
|
params->flags |= CBD_FLAG_ERROR;
|
||||||
}
|
}
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
|
|
||||||
|
@ -167,11 +168,13 @@ pblk_write_wait(struct block_device* bdev,
|
||||||
void
|
void
|
||||||
pblk_write_endio(struct bio* bio)
|
pblk_write_endio(struct bio* bio)
|
||||||
{
|
{
|
||||||
|
struct cbd_params* params = bio->bi_private;
|
||||||
u32 n;
|
u32 n;
|
||||||
struct page* page;
|
struct page* page;
|
||||||
|
|
||||||
BUG_ON(!bio);
|
BUG_ON(!bio);
|
||||||
if (bio->bi_status != BLK_STS_OK) {
|
if (bio->bi_status != BLK_STS_OK) {
|
||||||
|
params->flags |= CBD_FLAG_ERROR;
|
||||||
for (n = 0; n < bio->bi_max_vecs; ++n) {
|
for (n = 0; n < bio->bi_max_vecs; ++n) {
|
||||||
page = bio->bi_io_vec[n].bv_page;
|
page = bio->bi_io_vec[n].bv_page;
|
||||||
SetPageError(page);
|
SetPageError(page);
|
||||||
|
@ -186,15 +189,16 @@ pblk_write_endio(struct bio* bio)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pblk_write(struct block_device* bdev,
|
pblk_write(struct cbd_params* params,
|
||||||
u64 pblk, u32 count, struct page** pagev)
|
u64 pblk, u32 count, struct page** pagev)
|
||||||
{
|
{
|
||||||
struct bio* bio;
|
struct bio* bio;
|
||||||
u32 n;
|
u32 n;
|
||||||
|
|
||||||
bio = pblk_io_prepare(bdev, REQ_OP_WRITE, pblk, count, pagev);
|
bio = pblk_io_prepare(params->priv, REQ_OP_WRITE, pblk, count, pagev);
|
||||||
if (!bio) {
|
if (!bio) {
|
||||||
printk(KERN_ERR "%s: out of memory\n", __func__);
|
printk(KERN_ERR "%s: out of memory\n", __func__);
|
||||||
|
params->flags |= CBD_FLAG_ERROR;
|
||||||
for (n = 0; n < count; ++n) {
|
for (n = 0; n < count; ++n) {
|
||||||
SetPageError(pagev[n]);
|
SetPageError(pagev[n]);
|
||||||
unlock_page(pagev[n]);
|
unlock_page(pagev[n]);
|
||||||
|
@ -202,6 +206,7 @@ pblk_write(struct block_device* bdev,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bio->bi_end_io = pblk_write_endio;
|
bio->bi_end_io = pblk_write_endio;
|
||||||
|
bio->bi_private = params;
|
||||||
|
|
||||||
submit_bio(bio);
|
submit_bio(bio);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ static const u16 CBD_VERSION_MAJOR = 1;
|
||||||
static const u16 CBD_VERSION_MINOR = 1;
|
static const u16 CBD_VERSION_MINOR = 1;
|
||||||
|
|
||||||
#define CBD_FLAG_DIRTY 0x01
|
#define CBD_FLAG_DIRTY 0x01
|
||||||
|
#define CBD_FLAG_ERROR 0x02
|
||||||
|
|
||||||
enum cbd_alg {
|
enum cbd_alg {
|
||||||
CBD_ALG_NONE,
|
CBD_ALG_NONE,
|
||||||
|
@ -523,11 +524,11 @@ bool cbd_alloc_pagev(struct page** pagev, size_t len);
|
||||||
void cbd_free_pagev(struct page** pagev, size_t len);
|
void cbd_free_pagev(struct page** pagev, size_t len);
|
||||||
|
|
||||||
/* Core low-level I/O */
|
/* Core low-level I/O */
|
||||||
int pblk_read_wait(struct block_device* bdev,
|
int pblk_read_wait(struct cbd_params* params,
|
||||||
u64 pblk, u32 count, struct page** pagev);
|
u64 pblk, u32 count, struct page** pagev);
|
||||||
int pblk_write_wait(struct block_device* bdev,
|
int pblk_write_wait(struct cbd_params* params,
|
||||||
u64 pblk, u32 count, struct page** pagev);
|
u64 pblk, u32 count, struct page** pagev);
|
||||||
void pblk_write(struct block_device* bdev,
|
void pblk_write(struct cbd_params* params,
|
||||||
u64 pblk, u32 count, struct page** pagev);
|
u64 pblk, u32 count, struct page** pagev);
|
||||||
|
|
||||||
struct pbat;
|
struct pbat;
|
||||||
|
|
Loading…
Reference in New Issue