Skip to content

Commit

Permalink
dm: change ->end_io calling convention
Browse files Browse the repository at this point in the history
Turn the error paramter into a pointer so that target drivers can change
the value, and make sure only DM_ENDIO_* values are returned from the
methods.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
  • Loading branch information
Christoph Hellwig authored and Jens Axboe committed Jun 9, 2017
1 parent 846785e commit 1be5690
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 50 deletions.
4 changes: 2 additions & 2 deletions drivers/md/dm-cache-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -2820,7 +2820,7 @@ static int cache_map(struct dm_target *ti, struct bio *bio)
return r;
}

static int cache_end_io(struct dm_target *ti, struct bio *bio, int error)
static int cache_end_io(struct dm_target *ti, struct bio *bio, int *error)
{
struct cache *cache = ti->private;
unsigned long flags;
Expand All @@ -2838,7 +2838,7 @@ static int cache_end_io(struct dm_target *ti, struct bio *bio, int error)
bio_drop_shared_lock(cache, bio);
accounted_complete(cache, bio);

return 0;
return DM_ENDIO_DONE;
}

static int write_dirty_bitset(struct cache *cache)
Expand Down
8 changes: 4 additions & 4 deletions drivers/md/dm-flakey.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,12 +358,12 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_REMAPPED;
}

static int flakey_end_io(struct dm_target *ti, struct bio *bio, int error)
static int flakey_end_io(struct dm_target *ti, struct bio *bio, int *error)
{
struct flakey_c *fc = ti->private;
struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data));

if (!error && pb->bio_submitted && (bio_data_dir(bio) == READ)) {
if (!*error && pb->bio_submitted && (bio_data_dir(bio) == READ)) {
if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) &&
all_corrupt_bio_flags_match(bio, fc)) {
/*
Expand All @@ -377,11 +377,11 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, int error)
* Error read during the down_interval if drop_writes
* and error_writes were not configured.
*/
return -EIO;
*error = -EIO;
}
}

return error;
return DM_ENDIO_DONE;
}

static void flakey_status(struct dm_target *ti, status_type_t type,
Expand Down
4 changes: 2 additions & 2 deletions drivers/md/dm-log-writes.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ static int log_writes_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_REMAPPED;
}

static int normal_end_io(struct dm_target *ti, struct bio *bio, int error)
static int normal_end_io(struct dm_target *ti, struct bio *bio, int *error)
{
struct log_writes_c *lc = ti->private;
struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data));
Expand All @@ -686,7 +686,7 @@ static int normal_end_io(struct dm_target *ti, struct bio *bio, int error)
spin_unlock_irqrestore(&lc->blocks_lock, flags);
}

return error;
return DM_ENDIO_DONE;
}

/*
Expand Down
11 changes: 6 additions & 5 deletions drivers/md/dm-mpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -1517,14 +1517,15 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone,
return r;
}

static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone, int error)
static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone, int *error)
{
struct multipath *m = ti->private;
struct dm_mpath_io *mpio = get_mpio_from_bio(clone);
struct pgpath *pgpath = mpio->pgpath;
unsigned long flags;
int r = DM_ENDIO_DONE;

if (!error || noretry_error(error))
if (!*error || noretry_error(*error))
goto done;

if (pgpath)
Expand All @@ -1533,7 +1534,7 @@ static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone, int err
if (atomic_read(&m->nr_valid_paths) == 0 &&
!test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) {
dm_report_EIO(m);
error = -EIO;
*error = -EIO;
goto done;
}

Expand All @@ -1546,7 +1547,7 @@ static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone, int err
if (!test_bit(MPATHF_QUEUE_IO, &m->flags))
queue_work(kmultipathd, &m->process_queued_bios);

error = DM_ENDIO_INCOMPLETE;
r = DM_ENDIO_INCOMPLETE;
done:
if (pgpath) {
struct path_selector *ps = &pgpath->pg->ps;
Expand All @@ -1555,7 +1556,7 @@ static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone, int err
ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes);
}

return error;
return r;
}

/*
Expand Down
14 changes: 7 additions & 7 deletions drivers/md/dm-raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,7 +1236,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_REMAPPED;
}

static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
static int mirror_end_io(struct dm_target *ti, struct bio *bio, int *error)
{
int rw = bio_data_dir(bio);
struct mirror_set *ms = (struct mirror_set *) ti->private;
Expand All @@ -1252,16 +1252,16 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
if (!(bio->bi_opf & REQ_PREFLUSH) &&
bio_op(bio) != REQ_OP_DISCARD)
dm_rh_dec(ms->rh, bio_record->write_region);
return error;
return DM_ENDIO_DONE;
}

if (error == -EOPNOTSUPP)
return error;
if (*error == -EOPNOTSUPP)
return DM_ENDIO_DONE;

if (bio->bi_opf & REQ_RAHEAD)
return error;
return DM_ENDIO_DONE;

if (unlikely(error)) {
if (unlikely(*error)) {
m = bio_record->m;

DMERR("Mirror read failed from %s. Trying alternative device.",
Expand All @@ -1285,7 +1285,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
DMERR("All replicated volumes dead, failing I/O");
}

return error;
return DM_ENDIO_DONE;
}

static void mirror_presuspend(struct dm_target *ti)
Expand Down
4 changes: 2 additions & 2 deletions drivers/md/dm-snap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1851,14 +1851,14 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
return r;
}

static int snapshot_end_io(struct dm_target *ti, struct bio *bio, int error)
static int snapshot_end_io(struct dm_target *ti, struct bio *bio, int *error)
{
struct dm_snapshot *s = ti->private;

if (is_bio_tracked(bio))
stop_tracking_chunk(s, bio);

return 0;
return DM_ENDIO_DONE;
}

static void snapshot_merge_presuspend(struct dm_target *ti)
Expand Down
14 changes: 7 additions & 7 deletions drivers/md/dm-stripe.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,20 +375,20 @@ static void stripe_status(struct dm_target *ti, status_type_t type,
}
}

static int stripe_end_io(struct dm_target *ti, struct bio *bio, int error)
static int stripe_end_io(struct dm_target *ti, struct bio *bio, int *error)
{
unsigned i;
char major_minor[16];
struct stripe_c *sc = ti->private;

if (!error)
return 0; /* I/O complete */
if (!*error)
return DM_ENDIO_DONE; /* I/O complete */

if (bio->bi_opf & REQ_RAHEAD)
return error;
return DM_ENDIO_DONE;

if (error == -EOPNOTSUPP)
return error;
if (*error == -EOPNOTSUPP)
return DM_ENDIO_DONE;

memset(major_minor, 0, sizeof(major_minor));
sprintf(major_minor, "%d:%d",
Expand All @@ -409,7 +409,7 @@ static int stripe_end_io(struct dm_target *ti, struct bio *bio, int error)
schedule_work(&sc->trigger_event);
}

return error;
return DM_ENDIO_DONE;
}

static int stripe_iterate_devices(struct dm_target *ti,
Expand Down
4 changes: 2 additions & 2 deletions drivers/md/dm-thin.c
Original file line number Diff line number Diff line change
Expand Up @@ -4177,7 +4177,7 @@ static int thin_map(struct dm_target *ti, struct bio *bio)
return thin_bio_map(ti, bio);
}

static int thin_endio(struct dm_target *ti, struct bio *bio, int err)
static int thin_endio(struct dm_target *ti, struct bio *bio, int *err)
{
unsigned long flags;
struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
Expand Down Expand Up @@ -4212,7 +4212,7 @@ static int thin_endio(struct dm_target *ti, struct bio *bio, int err)
if (h->cell)
cell_defer_no_holder(h->tc, h->cell);

return 0;
return DM_ENDIO_DONE;
}

static void thin_presuspend(struct dm_target *ti)
Expand Down
36 changes: 18 additions & 18 deletions drivers/md/dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -845,24 +845,7 @@ static void clone_endio(struct bio *bio)
struct mapped_device *md = tio->io->md;
dm_endio_fn endio = tio->ti->type->end_io;

if (endio) {
r = endio(tio->ti, bio, error);
if (r < 0 || r == DM_ENDIO_REQUEUE)
/*
* error and requeue request are handled
* in dec_pending().
*/
error = r;
else if (r == DM_ENDIO_INCOMPLETE)
/* The target will handle the io */
return;
else if (r) {
DMWARN("unimplemented target endio return value: %d", r);
BUG();
}
}

if (unlikely(r == -EREMOTEIO)) {
if (unlikely(error == -EREMOTEIO)) {
if (bio_op(bio) == REQ_OP_WRITE_SAME &&
!bdev_get_queue(bio->bi_bdev)->limits.max_write_same_sectors)
disable_write_same(md);
Expand All @@ -871,6 +854,23 @@ static void clone_endio(struct bio *bio)
disable_write_zeroes(md);
}

if (endio) {
r = endio(tio->ti, bio, &error);
switch (r) {
case DM_ENDIO_REQUEUE:
error = DM_ENDIO_REQUEUE;
/*FALLTHRU*/
case DM_ENDIO_DONE:
break;
case DM_ENDIO_INCOMPLETE:
/* The target will handle the io */
return;
default:
DMWARN("unimplemented target endio return value: %d", r);
BUG();
}
}

free_tio(tio);
dec_pending(io, error);
}
Expand Down
2 changes: 1 addition & 1 deletion include/linux/device-mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ typedef void (*dm_release_clone_request_fn) (struct request *clone);
* 2 : The target wants to push back the io
*/
typedef int (*dm_endio_fn) (struct dm_target *ti,
struct bio *bio, int error);
struct bio *bio, int *error);
typedef int (*dm_request_endio_fn) (struct dm_target *ti,
struct request *clone, int error,
union map_info *map_context);
Expand Down

0 comments on commit 1be5690

Please sign in to comment.