[dm-devel] RFC: Patch to dm-raid1 to allow error type in status output - even when !errors_handled

malahal at us.ibm.com malahal at us.ibm.com
Thu Nov 6 18:50:48 UTC 2008


The patch looks fine, but instead of having this in the mirror target,
how about a separate target that handles this? I believe, reads and
writes are not distinguished with this patch, in other words
applications (like pvmove) doesn't know the write failures until it
actually checks your error status bits.

As I said, how about a failure target that accepts only read failure,
only write failure, maybe all kinds of failures. Pvmove can use
'ignore failures' target on top of a PV while moving to ignore any read
failures from it.

--Malahal.

Jonathan Brassow [jbrassow at redhat.com] wrote:
> I have not compiled or tested this patch at this point... just looking
> for feedback.
> 
>  brassow
> 
> Device-mapper mirrors are allowed to either handle or ignore
> device errors/failures.  In some cases, it is desirable to
> ignore errors.  For example, when using 'pvmove' to move data
> off of a failing device, we just want to get all the data we
> can and not stop for failures.
> 
> Currently, when failures are ignored, they are completely ignored.
> They are not recorded and have no affect on the mirror.  I think
> it would be more beneficial to at least record the information -
> even though no action is taken.  This way, the status output could
> indicate that a problem occurred.  Since the status output is
> backwards compatible with older programs, those older programs
> would simply ignore the new information.  Newer or updated programs,
> on the other hand, would be able to see that something had happened
> - even if they didn't want to take action.  (Imagine copying off
> data from a failing drive.  You may want to copy all that you can
> without stopping for failures, but you still want to know if some
> regions didn't get copied properly.)
> 
> The way to do this is to move the 'errors_handled' check after the
> error accounting in fail_mirror (but before action is taken to
> change the primary mirror, etc.).  The error accounting is done by
> incrementing 'error_count' and setting 'error_type'.  Since these
> variables can now have non-zero value, even when not handling
> errors, we must couple a check for 'errors_handled' in the places
> where 'error_count' is checked - specifically, 'choose_mirror',
> 'default_ok', and 'do_reads'.
> 
> We handle 'choose_mirror' a little bit more cleverly than just
> mitigating the 'error_count' with a check for 'errors_handled'.
> In this case, if the region is in sync, we still try to find
> a mirror that has not failed (just in case we would read stale
> data); but if there is no other option, we can still give the
> default mirror if we are ignoring errors.
> 
> 
> Index: linux-2.6/drivers/md/dm-raid1.c
> ===================================================================
> --- linux-2.6.orig/drivers/md/dm-raid1.c
> +++ linux-2.6/drivers/md/dm-raid1.c
> @@ -197,9 +197,6 @@ static void fail_mirror(struct mirror *m
>  	struct mirror_set *ms = m->ms;
>  	struct mirror *new;
> 
> -	if (!errors_handled(ms))
> -		return;
> -
>  	/*
>  	 * error_count is used for nothing more than a
>  	 * simple way to tell if a device has encountered
> @@ -210,6 +207,9 @@ static void fail_mirror(struct mirror *m
>  	if (test_and_set_bit(error_type, &m->error_type))
>  		return;
> 
> +	if (!errors_handled(ms))
> +		return;
> +
>  	if (m != get_default_mirror(ms))
>  		goto out;
> 
> @@ -369,14 +369,15 @@ static struct mirror *choose_mirror(stru
>  			m += ms->nr_mirrors;
>  	} while (m != get_default_mirror(ms));
> 
> -	return NULL;
> +	return (errors_handled(ms)) ? NULL : m;
>  }
> 
>  static int default_ok(struct mirror *m)
>  {
>  	struct mirror *default_mirror = get_default_mirror(m->ms);
> 
> -	return !atomic_read(&default_mirror->error_count);
> +	return !errors_handled(m->ms) ||
> +		!atomic_read(&default_mirror->error_count);
>  }
> 
>  static int mirror_available(struct mirror_set *ms, struct bio *bio)
> @@ -483,7 +484,8 @@ static void do_reads(struct mirror_set *
>  		 */
>  		if (likely(region_in_sync(ms, region, 1)))
>  			m = choose_mirror(ms, bio->bi_sector);
> -		else if (m && atomic_read(&m->error_count))
> +		else if (m && errors_handled(ms) &&
> +			 atomic_read(&m->error_count))
>  			m = NULL;
> 
>  		if (likely(m))
> 
> 
> --
> dm-devel mailing list
> dm-devel at redhat.com
> https://www.redhat.com/mailman/listinfo/dm-devel




More information about the dm-devel mailing list