[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:02 UTC 2004


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)





More information about the dm-devel mailing list