From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx2.suse.de ([195.135.220.15]:45905 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750774AbeBTUGu (ORCPT ); Tue, 20 Feb 2018 15:06:50 -0500 From: NeilBrown To: gregkh@linuxfoundation.org, gmazyland@gmail.com, snitzer@redhat.com Date: Wed, 21 Feb 2018 07:06:39 +1100 Cc: stable@vger.kernel.org Subject: [PATCH - 4.4-stable] dm: correctly handle chained bios in dec_pending() In-Reply-To: <1519140886222194@kroah.com> References: <1519140886222194@kroah.com> Message-ID: <87inarjui8.fsf@notabene.neil.brown.name> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" Sender: stable-owner@vger.kernel.org List-ID: --=-=-= Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Commit 8dd601fa8317243be887458c49f6c29c2f3d719f upstream. dec_pending() is given an error status (possibly 0) to be recorded against a bio. It can be called several times on the one 'struct dm_io', and it is careful to only assign a non-zero error to io->status. However when it then assigned io->status to bio->bi_status, it is not careful and could overwrite a genuine error status with 0. This can happen when chained bios are in use. If a bio is chained beneath the bio that this dm_io is handling, the child bio might complete and set bio->bi_status before the dm_io completes. This has been possible since chained bios were introduced in 3.14, and has become a lot easier to trigger with commit 18a25da84354 ("dm: ensure bio submission follows a depth-first tree walk") as that commit caused dm to start using chained bios itself. A particular failure mode is that if a bio spans an 'error' target and a working target, the 'error' fragment will complete instantly and set the =2D>bi_status, and the other fragment will normally complete a little later, and will clear ->bi_status. The fix is simply to only assign io_error to bio->bi_status when io_error is not zero. Reported-and-tested-by: Milan Broz Cc: stable@vger.kernel.org (v3.14+) Signed-off-by: NeilBrown Signed-off-by: Mike Snitzer =2D-- drivers/md/dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 9ec6948e3b8b..3d9a80759d95 100644 =2D-- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -974,7 +974,8 @@ static void dec_pending(struct dm_io *io, int error) } else { /* done with normal IO or empty flush */ trace_block_bio_complete(md->queue, bio, io_error); =2D bio->bi_error =3D io_error; + if (io_error) + bio->bi_error =3D io_error; bio_endio(bio); } } =2D-=20 2.14.0.rc0.dirty --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEG8Yp69OQ2HB7X0l6Oeye3VZigbkFAlqMf9AACgkQOeye3VZi gbk7Fg/8DjRa9vuxxdS3VkF6jw5297rjs1G9Ua7frDqKTyD+kjVvmMQaIOMVkB8z qOyX9xayl3EC8f/rG9cY9Bf3m91oyeiy+WIymH0Rce3cm/O/R6bl5jJOdEvy+Y5+ 69xxgviklbn+OCcxMHjRuzOXgL3UparvDz0YMWGo8dc1kCkvCgQ9BxEqhuXCY/tN LZ0rydXF3LZvM0IDNkGfy75I8e3e0exgfbj3PDQJeE26mi5uzkuGPyYPPJi8JS2M T6uW/uczkhleDZmG2KA8HreT3iQ5VRvv8vtW+bhKgEkPhNFrU5WvhC1K0a8kllCC l/zhKuN193dTHVvYJ3TIdh+zofKnY0yYkGuw+yALH+qLBu8h99d4/J4T8H4iB6g7 wi3NW2utBrhpaSX5ChFKNTpnl7anTrZ30599RY/IAADo6IeRL30FOuRdGgFgv+6C 0GY0HGDtqKyBIjKWIk5bBKdNTjaLaLQbmHb7wEVzdc70nXkZWdjlT0kPK07LCAar r3W6oT0uUylITPygVmfIctVykJcnXCb50+Egs3pi8RQE5FaUhQTQtNuvntUpoFca 6dq++uEqVl6q5oJAshZ3Ll1lY++d4ajrugTUkGT8OJbFUSBqA+XF2kc0iUIURT0+ kXf1hupj5rE1V/S6EJXO3rp5a77FwXHwSI15a178HnIe3XIFPHk= =ioov -----END PGP SIGNATURE----- --=-=-=--