Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dm io: don't call the async_io notify.fn on invalid num_regions

If dm_io() returned an error, callers that set a notify.fn and wanted it
called on an error need to check the return value and call notify.fn
themselves if it was -EINVAL but not if it was -EIO. None of them do
this (granted, all the existing async_io users of dm_io call it in a way
that is guaranteed to not return an error).

Simplify the interface by never calling the notify.fn if dm_io returns
an error. This works with the existing dm_io callers which check for an
error and handle it using the same methods as the notify.fn.

This also allows us to move the now equivalent num_regions checks out of
sync_io() and async_io() and into dm_io() itself. Additionally, change
async_io() into a void function, since it can no longer fail.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>

authored by

Benjamin Marzinski and committed by
Mikulas Patocka
b0042ba7 06a0b333

+12 -19
+12 -19
drivers/md/dm-io.c
··· 431 431 struct io *io; 432 432 struct sync_io sio; 433 433 434 - if (num_regions > 1 && !op_is_write(opf)) { 435 - WARN_ON(1); 436 - return -EIO; 437 - } 438 - 439 434 init_completion(&sio.wait); 440 435 441 436 io = mempool_alloc(&client->pool, GFP_NOIO); ··· 453 458 return sio.error_bits ? -EIO : 0; 454 459 } 455 460 456 - static int async_io(struct dm_io_client *client, unsigned int num_regions, 457 - struct dm_io_region *where, blk_opf_t opf, 458 - struct dpages *dp, io_notify_fn fn, void *context, 459 - unsigned short ioprio) 461 + static void async_io(struct dm_io_client *client, unsigned int num_regions, 462 + struct dm_io_region *where, blk_opf_t opf, 463 + struct dpages *dp, io_notify_fn fn, void *context, 464 + unsigned short ioprio) 460 465 { 461 466 struct io *io; 462 - 463 - if (num_regions > 1 && !op_is_write(opf)) { 464 - WARN_ON(1); 465 - fn(1, context); 466 - return -EIO; 467 - } 468 467 469 468 io = mempool_alloc(&client->pool, GFP_NOIO); 470 469 io->error_bits = 0; ··· 471 482 io->vma_invalidate_size = dp->vma_invalidate_size; 472 483 473 484 dispatch_io(opf, num_regions, where, dp, io, 0, ioprio); 474 - return 0; 475 485 } 476 486 477 487 static int dp_init(struct dm_io_request *io_req, struct dpages *dp, ··· 517 529 int r; 518 530 struct dpages dp; 519 531 532 + if (num_regions > 1 && !op_is_write(io_req->bi_opf)) { 533 + WARN_ON(1); 534 + return -EIO; 535 + } 536 + 520 537 r = dp_init(io_req, &dp, (unsigned long)where->count << SECTOR_SHIFT); 521 538 if (r) 522 539 return r; ··· 530 537 return sync_io(io_req->client, num_regions, where, 531 538 io_req->bi_opf, &dp, sync_error_bits, ioprio); 532 539 533 - return async_io(io_req->client, num_regions, where, 534 - io_req->bi_opf, &dp, io_req->notify.fn, 535 - io_req->notify.context, ioprio); 540 + async_io(io_req->client, num_regions, where, io_req->bi_opf, &dp, 541 + io_req->notify.fn, io_req->notify.context, ioprio); 542 + return 0; 536 543 } 537 544 EXPORT_SYMBOL(dm_io); 538 545