[dm-devel] [PATCH] use uptodate bit to test status of bios (take 2)
Mike Christie
michaelc at cs.wisc.edu
Mon Mar 8 05:14:01 UTC 2004
Mike Christie wrote:
> Kevin Corry wrote:
>
>> On Friday 05 March 2004 3:32 pm, Mike Christie wrote:
>>
>>> If there is an error on a partially completed bio it's uptodate
>>> bit is cleared and an error value is retured, but DM will see
>>> that bi_size is not yet zero and ignore it. SCSI will fail the rest
>>> of the IO if the fail fast bit is set, so DM multipath will
>>> eventually see the error from them. However, if that behavior is not
>>> a requirement the patch below would be needed to detect errors in
>>> bios where the begining is not uptodate but the end completed without
>>> errors.
>>>
>>> SCSI will not always fail the rest of the IO when the fail fast bit
>>> is not set, so this may be a bug in dm-crypt and dm-raid1.
>>>
>>> Mike Christie
>>>
>>>
>>> --- linux-2.6.4-rc1-udm1.orig/drivers/md/dm-mpath.c 2004-03-03
>>> 19:56:43.000000000 -0800 +++
>>> linux-2.6.4-rc1-udm1/drivers/md/dm-mpath.c 2004-03-03
>>> 19:52:55.000000000
>>> -0800 @@ -551,8 +551,9 @@ static int do_end_io(struct multipath *m
>>> int error, struct mpath_io *io)
>>> {
>>> int r;
>>> + int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
>>>
>>> - if (error) {
>>> + if (uptodate) {
>>> spin_lock(&m->lock);
>>> if (!m->nr_valid_paths) {
>>> spin_unlock(&m->lock);
>>
>>
>>
>> It looks like this test should be "if (!uptodate) {".
>>
>
> darn.
>
>> Also, couldn't we do this in clone_endio() in dm.c and not have to
>> change all the targets? Something like this.
>>
>
>
> We also want to preserve the error value. Hopefully soon they will
> be meaningful ;) This means we have the normal error case, and the funky
> one
> where uptodate is cleared and error is 0.
>
>
>
> --- linux-2.6.4-rc1-udm1.orig/drivers/md/dm.c 2004-03-03
> 19:56:43.000000000 -0800
> +++ linux-2.6.4-rc1-udm1/drivers/md/dm.c 2004-03-05
> 14:08:11.801747069 -0800
> @@ -278,6 +278,9 @@ static int clone_endio(struct bio *bio,
> if (bio->bi_size)
> return 1;
>
> + if (!bio_flagged(bio, BIO_UPTODATE) && !error)
> + error = -EIO;
> +
> if (endio) {
> r = endio(tio->ti, bio, error, &tio->info);
> if (r < 0)
>
>
oops that's wrong too.
More information about the dm-devel
mailing list