summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2026-07-27 23:09:28 +0200
committerMikulas Patocka <mpatocka@redhat.com>2026-07-27 23:09:28 +0200
commit47a5e62f39875f371bded6e34ffb9cf15ccd813d (patch)
tree04288c01057a54214ebfe449f366f212b12d1053
parent62dc37a819a5a5de5cba989ad9e96ee214b9253e (diff)
downloadlinux-next-47a5e62f39875f371bded6e34ffb9cf15ccd813d.tar.gz
linux-next-47a5e62f39875f371bded6e34ffb9cf15ccd813d.zip
dm-io: report non-retryable errors separatedly
The error codes BLK_STS_NOTSUPP and BLK_STS_INVAL should not cause leg failure on dm-raid1. This patch changes the interface to dm-io, so that it reports two error bitmaps - error_bits and unsup_bits. The unsup_bit bitmap tracks BLK_STS_NOTSUPP or BLK_STS_INVAL errors, the error_bits bitmap tracks all the other errors. dm-raid1 is changed so that it won't fail a leg if it receives an error in the unsup_bits bitmap. This patch (with 62dc37a819a5) fixes misbehavior if the user uses unaligned bio vectors on dm-raid1. Fixes: 7eac33186957 ("iomap: simplify direct io validity check") Fixes: 5ff3f74e145a ("block: simplify direct io validity check") Cc: stable@vger.kernel.org Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
-rw-r--r--drivers/md/dm-bufio.c10
-rw-r--r--drivers/md/dm-integrity.c32
-rw-r--r--drivers/md/dm-io.c29
-rw-r--r--drivers/md/dm-kcopyd.c10
-rw-r--r--drivers/md/dm-log.c4
-rw-r--r--drivers/md/dm-raid1.c26
-rw-r--r--drivers/md/dm-snap-persistent.c4
-rw-r--r--drivers/md/dm-verity-target.c2
-rw-r--r--drivers/md/dm-writecache.c14
-rw-r--r--include/linux/dm-io.h6
10 files changed, 83 insertions, 54 deletions
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index a458b9fd2fcd..d58eed96a8ff 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -1287,11 +1287,11 @@ static void free_buffer(struct dm_buffer *b)
* dm-io completion routine. It just calls b->bio.bi_end_io, pretending
* that the request was handled directly with bio interface.
*/
-static void dmio_complete(unsigned long error, void *context)
+static void dmio_complete(unsigned long error, unsigned long unsup, void *context)
{
struct dm_buffer *b = context;
- b->end_io(b, unlikely(error != 0) ? BLK_STS_IOERR : 0);
+ b->end_io(b, unlikely(error != 0) ? BLK_STS_IOERR : unlikely(unsup != 0) ? BLK_STS_NOTSUPP : 0);
}
static void use_dmio(struct dm_buffer *b, enum req_op op, sector_t sector,
@@ -1319,7 +1319,7 @@ static void use_dmio(struct dm_buffer *b, enum req_op op, sector_t sector,
io_req.mem.ptr.vma = (char *)b->data + offset;
}
- r = dm_io(&io_req, 1, &region, NULL, ioprio);
+ r = dm_io(&io_req, 1, &region, NULL, NULL, ioprio);
if (unlikely(r))
b->end_io(b, errno_to_blk_status(r));
}
@@ -2220,7 +2220,7 @@ int dm_bufio_issue_flush(struct dm_bufio_client *c)
if (WARN_ON_ONCE(dm_bufio_in_request()))
return -EINVAL;
- return dm_io(&io_req, 1, &io_reg, NULL, IOPRIO_DEFAULT);
+ return dm_io(&io_req, 1, &io_reg, NULL, NULL, IOPRIO_DEFAULT);
}
EXPORT_SYMBOL_GPL(dm_bufio_issue_flush);
@@ -2246,7 +2246,7 @@ int dm_bufio_issue_discard(struct dm_bufio_client *c, sector_t block, sector_t c
if (WARN_ON_ONCE(dm_bufio_in_request()))
return -EINVAL; /* discards are optional */
- return dm_io(&io_req, 1, &io_reg, NULL, IOPRIO_DEFAULT);
+ return dm_io(&io_req, 1, &io_reg, NULL, NULL, IOPRIO_DEFAULT);
}
EXPORT_SYMBOL_GPL(dm_bufio_issue_discard);
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
index 5156079785dc..c19efee569d1 100644
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -562,7 +562,7 @@ static int sync_rw_sb(struct dm_integrity_c *ic, blk_opf_t opf)
}
}
- r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
+ r = dm_io(&io_req, 1, &io_loc, NULL, NULL, IOPRIO_DEFAULT);
if (unlikely(r))
return r;
@@ -1035,12 +1035,14 @@ static void encrypt_journal(struct dm_integrity_c *ic, bool encrypt, unsigned in
return crypt_journal(ic, encrypt, section, n_sections, comp);
}
-static void complete_journal_io(unsigned long error, void *context)
+static void complete_journal_io(unsigned long error, unsigned long unsup, void *context)
{
struct journal_completion *comp = context;
if (unlikely(error != 0))
dm_integrity_io_error(comp->ic, "writing journal", -EIO);
+ else if (unlikely(unsup != 0))
+ dm_integrity_io_error(comp->ic, "writing journal", -EOPNOTSUPP);
complete_journal_op(comp);
}
@@ -1055,7 +1057,7 @@ static void rw_journal_sectors(struct dm_integrity_c *ic, blk_opf_t opf,
if (unlikely(dm_integrity_failed(ic))) {
if (comp)
- complete_journal_io(-1UL, comp);
+ complete_journal_io(-1UL, -1UL, comp);
return;
}
@@ -1080,13 +1082,13 @@ static void rw_journal_sectors(struct dm_integrity_c *ic, blk_opf_t opf,
io_loc.sector = ic->start + SB_SECTORS + sector;
io_loc.count = n_sectors;
- r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
+ r = dm_io(&io_req, 1, &io_loc, NULL, NULL, IOPRIO_DEFAULT);
if (unlikely(r)) {
dm_integrity_io_error(ic, (opf & REQ_OP_MASK) == REQ_OP_READ ?
"reading journal" : "writing journal", r);
if (comp) {
WARN_ONCE(1, "asynchronous dm_io failed: %d", r);
- complete_journal_io(-1UL, comp);
+ complete_journal_io(-1UL, -1UL, comp);
}
}
}
@@ -1177,7 +1179,7 @@ static void copy_from_journal(struct dm_integrity_c *ic, unsigned int section, u
BUG_ON((target | n_sectors | offset) & (unsigned int)(ic->sectors_per_block - 1));
if (unlikely(dm_integrity_failed(ic))) {
- fn(-1UL, data);
+ fn(-1UL, -1UL, data);
return;
}
@@ -1197,10 +1199,10 @@ static void copy_from_journal(struct dm_integrity_c *ic, unsigned int section, u
io_loc.sector = target;
io_loc.count = n_sectors;
- r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
+ r = dm_io(&io_req, 1, &io_loc, NULL, NULL, IOPRIO_DEFAULT);
if (unlikely(r)) {
WARN_ONCE(1, "asynchronous dm_io failed: %d", r);
- fn(-1UL, data);
+ fn(-1UL, -1UL, data);
}
}
@@ -1493,12 +1495,14 @@ struct flush_request {
struct completion comp;
};
-static void flush_notify(unsigned long error, void *fr_)
+static void flush_notify(unsigned long error, unsigned long unsup, void *fr_)
{
struct flush_request *fr = fr_;
if (unlikely(error != 0))
dm_integrity_io_error(fr->ic, "flushing disk cache", -EIO);
+ else if (unlikely(unsup != 0))
+ dm_integrity_io_error(fr->ic, "flushing disk cache", -EOPNOTSUPP);
complete(&fr->comp);
}
@@ -1521,7 +1525,7 @@ static void dm_integrity_flush_buffers(struct dm_integrity_c *ic, bool flush_dat
fr.io_reg.count = 0;
fr.ic = ic;
init_completion(&fr.comp);
- r = dm_io(&fr.io_req, 1, &fr.io_reg, NULL, IOPRIO_DEFAULT);
+ r = dm_io(&fr.io_req, 1, &fr.io_reg, NULL, NULL, IOPRIO_DEFAULT);
BUG_ON(r);
}
@@ -1837,7 +1841,7 @@ static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checks
buffer_offset = (sector - io_loc.sector) << SECTOR_SHIFT;
io_loc.count = round_up(io_loc.count, alignment);
- r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
+ r = dm_io(&io_req, 1, &io_loc, NULL, NULL, IOPRIO_DEFAULT);
if (unlikely(r)) {
dio->bi_status = errno_to_blk_status(r);
goto free_ret;
@@ -2891,7 +2895,7 @@ release_flush_bios:
}
}
-static void complete_copy_from_journal(unsigned long error, void *context)
+static void complete_copy_from_journal(unsigned long error, unsigned long unsup, void *context)
{
struct journal_io *io = context;
struct journal_completion *comp = io->comp;
@@ -2901,6 +2905,8 @@ static void complete_copy_from_journal(unsigned long error, void *context)
mempool_free(io, &ic->journal_io_mempool);
if (unlikely(error != 0))
dm_integrity_io_error(ic, "copying from journal", -EIO);
+ else if (unlikely(unsup != 0))
+ dm_integrity_io_error(ic, "copying from journal", -EOPNOTSUPP);
complete_journal_op(comp);
}
@@ -3216,7 +3222,7 @@ next_chunk:
io_loc.sector = get_data_sector(ic, area, offset);
io_loc.count = n_sectors;
- r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
+ r = dm_io(&io_req, 1, &io_loc, NULL, NULL, IOPRIO_DEFAULT);
if (unlikely(r)) {
dm_integrity_io_error(ic, "reading data", r);
goto err;
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 28adfeb58f24..777b917be400 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -33,6 +33,7 @@ struct dm_io_client {
*/
struct io {
unsigned long error_bits;
+ unsigned long unsup_bits;
atomic_t count;
struct dm_io_client *client;
io_notify_fn callback;
@@ -119,6 +120,7 @@ static void retrieve_io_and_region_from_bio(struct bio *bio, struct io **io,
static void complete_io(struct io *io)
{
unsigned long error_bits = io->error_bits;
+ unsigned long unsup_bits = io->unsup_bits;
io_notify_fn fn = io->callback;
void *context = io->context;
@@ -127,13 +129,17 @@ static void complete_io(struct io *io)
io->vma_invalidate_size);
mempool_free(io, &io->client->pool);
- fn(error_bits, context);
+ fn(error_bits, unsup_bits, context);
}
static void dec_count(struct io *io, unsigned int region, blk_status_t error)
{
- if (error)
- set_bit(region, &io->error_bits);
+ if (unlikely(error)) {
+ if (error == BLK_STS_NOTSUPP || error == BLK_STS_INVAL)
+ set_bit(region, &io->unsup_bits);
+ else
+ set_bit(region, &io->error_bits);
+ }
if (atomic_dec_and_test(&io->count))
complete_io(io);
@@ -394,6 +400,7 @@ static void async_io(struct dm_io_client *client, unsigned int num_regions,
io = mempool_alloc(&client->pool, GFP_NOIO);
io->error_bits = 0;
+ io->unsup_bits = 0;
atomic_set(&io->count, 1); /* see dispatch_io() */
io->client = client;
io->callback = fn;
@@ -407,20 +414,23 @@ static void async_io(struct dm_io_client *client, unsigned int num_regions,
struct sync_io {
unsigned long error_bits;
+ unsigned long unsup_bits;
struct completion wait;
};
-static void sync_io_complete(unsigned long error, void *context)
+static void sync_io_complete(unsigned long error, unsigned long unsup, void *context)
{
struct sync_io *sio = context;
sio->error_bits = error;
+ sio->unsup_bits = unsup;
complete(&sio->wait);
}
static int sync_io(struct dm_io_client *client, unsigned int num_regions,
struct dm_io_region *where, blk_opf_t opf, struct dpages *dp,
- unsigned long *error_bits, unsigned short ioprio)
+ unsigned long *error_bits, unsigned long *unsup_bits,
+ unsigned short ioprio)
{
struct sync_io sio;
@@ -433,8 +443,10 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,
if (error_bits)
*error_bits = sio.error_bits;
+ if (unsup_bits)
+ *unsup_bits = sio.unsup_bits;
- return sio.error_bits ? -EIO : 0;
+ return sio.error_bits ? -EIO : sio.unsup_bits ? -EOPNOTSUPP : 0;
}
static int dp_init(struct dm_io_request *io_req, struct dpages *dp,
@@ -481,7 +493,7 @@ static int dp_init(struct dm_io_request *io_req, struct dpages *dp,
int dm_io(struct dm_io_request *io_req, unsigned int num_regions,
struct dm_io_region *where, unsigned long *sync_error_bits,
- unsigned short ioprio)
+ unsigned long *sync_unsup_bits, unsigned short ioprio)
{
int r;
struct dpages dp;
@@ -497,7 +509,8 @@ int dm_io(struct dm_io_request *io_req, unsigned int num_regions,
if (!io_req->notify.fn)
return sync_io(io_req->client, num_regions, where,
- io_req->bi_opf, &dp, sync_error_bits, ioprio);
+ io_req->bi_opf, &dp, sync_error_bits,
+ sync_unsup_bits, ioprio);
async_io(io_req->client, num_regions, where, io_req->bi_opf, &dp,
io_req->notify.fn, io_req->notify.context, ioprio);
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c
index 96c8b8ff61c2..5c9c24a3dcd9 100644
--- a/drivers/md/dm-kcopyd.c
+++ b/drivers/md/dm-kcopyd.c
@@ -517,16 +517,16 @@ static int run_complete_job(struct kcopyd_job *job)
return 0;
}
-static void complete_io(unsigned long error, void *context)
+static void complete_io(unsigned long error, unsigned long unsup, void *context)
{
struct kcopyd_job *job = context;
struct dm_kcopyd_client *kc = job->kc;
io_job_finish(kc->throttle);
- if (error) {
+ if (unlikely((error | unsup) != 0)) {
if (op_is_write(job->op))
- job->write_err |= error;
+ job->write_err |= error | unsup;
else
job->read_err = 1;
@@ -578,9 +578,9 @@ static int run_io_job(struct kcopyd_job *job)
io_job_start(job->kc->throttle);
if (job->op == REQ_OP_READ)
- r = dm_io(&io_req, 1, &job->source, NULL, IOPRIO_DEFAULT);
+ r = dm_io(&io_req, 1, &job->source, NULL, NULL, IOPRIO_DEFAULT);
else
- r = dm_io(&io_req, job->num_dests, job->dests, NULL, IOPRIO_DEFAULT);
+ r = dm_io(&io_req, job->num_dests, job->dests, NULL, NULL, IOPRIO_DEFAULT);
return r;
}
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 2ddeb4250c59..4c114fc5ef83 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -300,7 +300,7 @@ static int rw_header(struct log_c *lc, enum req_op op)
{
lc->io_req.bi_opf = op;
- return dm_io(&lc->io_req, 1, &lc->header_location, NULL, IOPRIO_DEFAULT);
+ return dm_io(&lc->io_req, 1, &lc->header_location, NULL, NULL, IOPRIO_DEFAULT);
}
static int flush_header(struct log_c *lc)
@@ -313,7 +313,7 @@ static int flush_header(struct log_c *lc)
lc->io_req.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
- return dm_io(&lc->io_req, 1, &null_location, NULL, IOPRIO_DEFAULT);
+ return dm_io(&lc->io_req, 1, &null_location, NULL, NULL, IOPRIO_DEFAULT);
}
static int read_header(struct log_c *log)
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index de5c00704e69..da2a5e2002ec 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -258,7 +258,7 @@ out:
static int mirror_flush(struct dm_target *ti)
{
struct mirror_set *ms = ti->private;
- unsigned long error_bits;
+ unsigned long error_bits, unsup_bits;
unsigned int i;
struct dm_io_region io[MAX_NR_MIRRORS];
@@ -277,8 +277,8 @@ static int mirror_flush(struct dm_target *ti)
}
error_bits = -1;
- dm_io(&io_req, ms->nr_mirrors, io, &error_bits, IOPRIO_DEFAULT);
- if (unlikely(error_bits != 0)) {
+ dm_io(&io_req, ms->nr_mirrors, io, &error_bits, &unsup_bits, IOPRIO_DEFAULT);
+ if (unlikely((error_bits | unsup_bits) != 0)) {
for (i = 0; i < ms->nr_mirrors; i++)
if (test_bit(i, &error_bits))
fail_mirror(ms->mirror + i,
@@ -511,7 +511,7 @@ static void hold_bio(struct mirror_set *ms, struct bio *bio)
* Reads
*---------------------------------------------------------------
*/
-static void read_callback(unsigned long error, void *context)
+static void read_callback(unsigned long error, unsigned long unsup, void *context)
{
struct bio *bio = context;
struct mirror *m;
@@ -520,6 +520,8 @@ static void read_callback(unsigned long error, void *context)
bio_set_m(bio, NULL);
if (likely(!error)) {
+ if (unlikely(unsup != 0))
+ bio->bi_status = BLK_STS_INVAL;
bio_endio(bio);
return;
}
@@ -553,7 +555,7 @@ static void read_async_bio(struct mirror *m, struct bio *bio)
map_region(&io, m, bio);
bio_set_m(bio, m);
- BUG_ON(dm_io(&io_req, 1, &io, NULL, IOPRIO_DEFAULT));
+ BUG_ON(dm_io(&io_req, 1, &io, NULL, NULL, IOPRIO_DEFAULT));
}
static inline int region_in_sync(struct mirror_set *ms, region_t region,
@@ -600,7 +602,7 @@ static void do_reads(struct mirror_set *ms, struct bio_list *reads)
* NOSYNC: increment pending, just write to the default mirror
*---------------------------------------------------------------------
*/
-static void write_callback(unsigned long error, void *context)
+static void write_callback(unsigned long error, unsigned long unsup, void *context)
{
unsigned int i;
struct bio *bio = context;
@@ -617,7 +619,7 @@ static void write_callback(unsigned long error, void *context)
* This way we handle both writes to SYNC and NOSYNC
* regions with the same code.
*/
- if (likely(!error)) {
+ if (likely(!(error | unsup))) {
bio_endio(bio);
return;
}
@@ -632,6 +634,12 @@ static void write_callback(unsigned long error, void *context)
return;
}
+ if (!error && unsup) {
+ bio->bi_status = BLK_STS_INVAL;
+ bio_endio(bio);
+ return;
+ }
+
for (i = 0; i < ms->nr_mirrors; i++)
if (test_bit(i, &error))
fail_mirror(ms->mirror + i, DM_RAID1_WRITE_ERROR);
@@ -680,7 +688,7 @@ static void do_write(struct mirror_set *ms, struct bio *bio)
*/
bio_set_m(bio, get_default_mirror(ms));
- BUG_ON(dm_io(&io_req, ms->nr_mirrors, io, NULL, IOPRIO_DEFAULT));
+ BUG_ON(dm_io(&io_req, ms->nr_mirrors, io, NULL, NULL, IOPRIO_DEFAULT));
}
static void do_writes(struct mirror_set *ms, struct bio_list *writes)
@@ -1262,7 +1270,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
return DM_ENDIO_DONE;
}
- if (*error == BLK_STS_NOTSUPP)
+ if (*error == BLK_STS_NOTSUPP || *error == BLK_STS_INVAL)
goto out;
if (bio->bi_opf & REQ_RAHEAD)
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index aa239ccda270..e86d929b0e95 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -223,7 +223,7 @@ static void do_metadata(struct work_struct *work)
{
struct mdata_req *req = container_of(work, struct mdata_req, work);
- req->result = dm_io(req->io_req, 1, req->where, NULL, IOPRIO_DEFAULT);
+ req->result = dm_io(req->io_req, 1, req->where, NULL, NULL, IOPRIO_DEFAULT);
}
/*
@@ -247,7 +247,7 @@ static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, blk_opf_t opf,
struct mdata_req req;
if (!metadata)
- return dm_io(&io_req, 1, &where, NULL, IOPRIO_DEFAULT);
+ return dm_io(&io_req, 1, &where, NULL, NULL, IOPRIO_DEFAULT);
req.where = &where;
req.io_req = &io_req;
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index 241d3f3747e7..cb105ccc47ec 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -393,7 +393,7 @@ static noinline int verity_recheck(struct dm_verity *v, struct dm_verity_io *io,
io_loc.bdev = v->data_dev->bdev;
io_loc.sector = cur_block << (v->data_dev_block_bits - SECTOR_SHIFT);
io_loc.count = 1 << (v->data_dev_block_bits - SECTOR_SHIFT);
- r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
+ r = dm_io(&io_req, 1, &io_loc, NULL, NULL, IOPRIO_DEFAULT);
if (unlikely(r))
goto free_ret;
diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
index 493f5202ad04..f02305de1c88 100644
--- a/drivers/md/dm-writecache.c
+++ b/drivers/md/dm-writecache.c
@@ -474,12 +474,14 @@ struct io_notify {
atomic_t count;
};
-static void writecache_notify_io(unsigned long error, void *context)
+static void writecache_notify_io(unsigned long error, unsigned long unsup, void *context)
{
struct io_notify *endio = context;
if (unlikely(error != 0))
writecache_error(endio->wc, -EIO, "error writing metadata");
+ else if (unlikely(unsup != 0))
+ writecache_error(endio->wc, -EOPNOTSUPP, "error writing metadata");
BUG_ON(atomic_read(&endio->count) <= 0);
if (atomic_dec_and_test(&endio->count))
complete(&endio->c);
@@ -530,11 +532,11 @@ static void ssd_commit_flushed(struct dm_writecache *wc, bool wait_for_ios)
req.notify.context = &endio;
/* writing via async dm-io (implied by notify.fn above) won't return an error */
- (void) dm_io(&req, 1, &region, NULL, IOPRIO_DEFAULT);
+ (void) dm_io(&req, 1, &region, NULL, NULL, IOPRIO_DEFAULT);
i = j;
}
- writecache_notify_io(0, &endio);
+ writecache_notify_io(0, 0, &endio);
wait_for_completion_io(&endio.c);
if (wait_for_ios)
@@ -567,7 +569,7 @@ static void ssd_commit_superblock(struct dm_writecache *wc)
req.notify.fn = NULL;
req.notify.context = NULL;
- r = dm_io(&req, 1, &region, NULL, IOPRIO_DEFAULT);
+ r = dm_io(&req, 1, &region, NULL, NULL, IOPRIO_DEFAULT);
if (unlikely(r))
writecache_error(wc, r, "error writing superblock");
}
@@ -595,7 +597,7 @@ static void writecache_disk_flush(struct dm_writecache *wc, struct dm_dev *dev)
req.client = wc->dm_io;
req.notify.fn = NULL;
- r = dm_io(&req, 1, &region, NULL, IOPRIO_DEFAULT);
+ r = dm_io(&req, 1, &region, NULL, NULL, IOPRIO_DEFAULT);
if (unlikely(r))
writecache_error(wc, r, "error flushing metadata: %d", r);
}
@@ -989,7 +991,7 @@ static int writecache_read_metadata(struct dm_writecache *wc, sector_t n_sectors
req.client = wc->dm_io;
req.notify.fn = NULL;
- return dm_io(&req, 1, &region, NULL, IOPRIO_DEFAULT);
+ return dm_io(&req, 1, &region, NULL, NULL, IOPRIO_DEFAULT);
}
static void writecache_resume(struct dm_target *ti)
diff --git a/include/linux/dm-io.h b/include/linux/dm-io.h
index 7b2968612b7e..674683894064 100644
--- a/include/linux/dm-io.h
+++ b/include/linux/dm-io.h
@@ -27,7 +27,7 @@ struct page_list {
struct page *page;
};
-typedef void (*io_notify_fn)(unsigned int long error, void *context);
+typedef void (*io_notify_fn)(unsigned long int error, unsigned long int unsup, void *context);
enum dm_io_mem_type {
DM_IO_PAGE_LIST,/* Page list */
@@ -80,8 +80,8 @@ void dm_io_client_destroy(struct dm_io_client *client);
* error occurred doing io to the corresponding region.
*/
int dm_io(struct dm_io_request *io_req, unsigned int num_regions,
- struct dm_io_region *region, unsigned int long *sync_error_bits,
- unsigned short ioprio);
+ struct dm_io_region *region, unsigned long int *sync_error_bits,
+ unsigned long int *sync_unsup_bits, unsigned short ioprio);
#endif /* __KERNEL__ */
#endif /* _LINUX_DM_IO_H */