diff -aurp linux-2.6.7-rc2/drivers/md/dm-path-selector.c linux-2.6.7-rc2-pg/drivers/md/dm-path-selector.c --- linux-2.6.7-rc2/drivers/md/dm-path-selector.c 2004-06-04 03:52:23.334727147 -0700 +++ linux-2.6.7-rc2-pg/drivers/md/dm-path-selector.c 2004-06-04 02:18:57.000000000 -0700 @@ -1,5 +1,6 @@ /* * Copyright (C) 2003 Sistina Software. + * Copyright (C) 2004 IBM Corporation * * Module Author: Heinz Mauelshagen * @@ -142,13 +143,9 @@ EXPORT_SYMBOL(dm_unregister_path_selecto * Path handling code, paths are held in lists *---------------------------------------------------------------*/ -/* FIXME: get rid of this */ -#define RR_FAIL_COUNT 1 - struct path_info { struct list_head list; struct path *path; - unsigned fail_count; }; static struct path_info *path_lookup(struct list_head *head, struct path *p) @@ -244,35 +241,42 @@ static int rr_add_path(struct path_selec return -ENOMEM; } - pi->fail_count = 0; pi->path = path; spin_lock(&s->lock); - list_add(&pi->list, &s->valid_paths); + list_add_tail(&pi->list, &s->valid_paths); spin_unlock(&s->lock); return 0; } -static void rr_end_io(struct path_selector *ps, struct bio *bio, int error, - union map_info *info) +static void rr_update_path(struct path_selector *ps, struct path *p, + int status) { unsigned long flags; + struct path_info *pi; struct selector *s = (struct selector *) ps->context; - struct path_info *pi = (struct path_info *)info->ptr; - - if (likely(!error)) - return; spin_lock_irqsave(&s->lock, flags); - if (++pi->fail_count == RR_FAIL_COUNT) { + if (status) { + pi = path_lookup(&s->valid_paths, p); + if (!pi) + goto done; + list_move(&pi->list, &s->invalid_paths); if (pi == s->current_path) s->current_path = NULL; + } else { + pi = path_lookup(&s->invalid_paths, p); + if (!pi) + goto done; + + list_move(&pi->list, &s->valid_paths); } + done: spin_unlock_irqrestore(&s->lock, flags); } @@ -303,44 +307,9 @@ static struct path *rr_select_path(struc done: spin_unlock_irqrestore(&s->lock, flags); - info->ptr = pi; return pi ? pi->path : NULL; } -/* Path status */ -static int rr_status(struct path_selector *ps, struct path *path, - status_type_t type, char *result, unsigned int maxlen) -{ - unsigned long flags; - struct path_info *pi; - int failed = 0; - struct selector *s = (struct selector *) ps->context; - int sz = 0; - - if (type == STATUSTYPE_TABLE) - return 0; - - spin_lock_irqsave(&s->lock, flags); - - /* - * Is status called often for testing or something? - * If so maybe a ps's info should be allocated w/ path - * so a simple container_of can be used. - */ - pi = path_lookup(&s->valid_paths, path); - if (!pi) { - failed = 1; - pi = path_lookup(&s->invalid_paths, path); - } - - sz = scnprintf(result, maxlen, "%s %u ", failed ? "F" : "A", - pi->fail_count); - - spin_unlock_irqrestore(&s->lock, flags); - - return sz; -} - static struct path_selector_type rr_ps = { .name = "round-robin", .module = THIS_MODULE, @@ -349,9 +318,8 @@ static struct path_selector_type rr_ps = .ctr = rr_ctr, .dtr = rr_dtr, .add_path = rr_add_path, - .end_io = rr_end_io, + .update_path = rr_update_path, .select_path = rr_select_path, - .status = rr_status, }; /* diff -aurp linux-2.6.7-rc2/drivers/md/dm-path-selector.h linux-2.6.7-rc2-pg/drivers/md/dm-path-selector.h --- linux-2.6.7-rc2/drivers/md/dm-path-selector.h 2004-06-04 03:52:23.364723227 -0700 +++ linux-2.6.7-rc2-pg/drivers/md/dm-path-selector.h 2004-06-03 22:55:58.000000000 -0700 @@ -16,8 +16,6 @@ struct path; -struct block_device *dm_path_to_bdev(struct path *path); - /* * We provide an abstraction for the code that chooses which path * to send some io down. @@ -35,22 +33,6 @@ typedef int (*ps_ctr_fn) (struct path_se typedef void (*ps_dtr_fn) (struct path_selector *ps); /* - * Allows the ps to initialize itself. It should return one - * of the following return values. iif DM_PS_INITIALIZING is - * returned the path-selector must call dm_ps_init_complete - * when the initializtion has completed. - */ -enum { - DM_PS_SUCCESS, - DM_PS_FAILED, - DM_PS_INITIALIZING, -}; - -void dm_ps_init_complete(struct path_selector *ps); - -typedef int (*ps_init_fn) (struct path_selector *ps); - -/* * Add an opaque path object, along with some selector specific * path args (eg, path priority). */ @@ -70,16 +52,28 @@ typedef int (*ps_add_path_fn) (struct pa typedef struct path *(*ps_select_path_fn) (struct path_selector *ps, struct bio *bio, union map_info *info); +/* + * The error value here is informative only. + * The ps should not offline the path as a result of this value, + * this operation is only done through the ps_update_path_fn. + */ typedef void (*ps_end_io) (struct path_selector *ps, struct bio *bio, int error, union map_info *info); /* + * Notify the selector the path's status has changed. + * status != 0 indicates a failure, status == 0 indicates + * path reacitvation. + */ +typedef void (*ps_update_path_fn) (struct path_selector *ps, + struct path *path, int status); + +/* * Table content based on parameters added in ps_add_path_fn * or path selector status */ typedef int (*ps_status_fn) (struct path_selector *ps, - struct path *path, - status_type_t type, + struct path *path, status_type_t type, char *result, unsigned int maxlen); /* Information about a path selector type */ @@ -91,11 +85,11 @@ struct path_selector_type { unsigned int info_args; ps_ctr_fn ctr; ps_dtr_fn dtr; - ps_init_fn init; ps_add_path_fn add_path; ps_select_path_fn select_path; ps_end_io end_io; + ps_update_path_fn update_path; ps_status_fn status; };