mpath bug fixes --- diff/drivers/md/dm-mpath.c 2003-12-29 10:16:52.000000000 +0000 +++ source/drivers/md/dm-mpath.c 2003-12-29 10:16:58.000000000 +0000 @@ -78,7 +78,7 @@ } path->test_page = alloc_page(GFP_KERNEL); - if (!p->test_page) { + if (!path->test_page) { bio_put(path->test_bio); kfree(path); return NULL; @@ -92,7 +92,7 @@ { ClearPageLocked(p->test_page); __free_page(p->test_page); - bio_put(&p->test_bio); + bio_put(p->test_bio); kfree(p); } @@ -101,10 +101,18 @@ struct priority_group *pg; pg = kmalloc(sizeof(*pg), GFP_KERNEL); - if (pg) { - INIT_LIST_HEAD(&pg->valid_paths); - INIT_LIST_HEAD(&pg->invalid_paths); + if (!pg) + return NULL; + + pg->ps = kmalloc(sizeof(*pg->ps), GFP_KERNEL); + if (!pg->ps) { + kfree(pg); + return NULL; } + memset(pg->ps, 0, sizeof(*pg->ps)); + + INIT_LIST_HEAD(&pg->valid_paths); + INIT_LIST_HEAD(&pg->invalid_paths); return pg; } @@ -123,11 +131,14 @@ static void free_priority_group(struct priority_group *pg, struct dm_target *ti) { - struct path_selector *ps = &pg->ps; + struct path_selector *ps = pg->ps; -??? if (ps) { - ps->type->dtr(ps); - dm_put_path_selector(ps->type); + if (ps) { + if (ps->type) { + ps->type->dtr(ps); + dm_put_path_selector(ps->type); + } + kfree(ps); } free_paths(&pg->valid_paths, ti); @@ -178,12 +189,11 @@ path->has_failed = 1; // path->fail_time = jiffies; atomic_inc(&path->fail_total); - list_del(&path->list); - list_add(&path->list, &path->pg->invalid_paths); - path->pg->ps.type->set_path_state(&path->pg->ps, path, 0); + list_move(&path->list, &path->pg->invalid_paths); + path->pg->ps->type->set_path_state(path->pg->ps, path, 0); } -static void test_endio(struct bio *bio, unsigned int done, int error) +static int test_endio(struct bio *bio, unsigned int done, int error) { struct path *path = (struct path *) bio->bi_private; @@ -193,7 +203,8 @@ if (error) __fail_path(path); - up(&p->test_lock); + up(&path->test_lock); + return 0; } static void test_path(struct path *p) @@ -201,7 +212,7 @@ if (down_trylock(&p->test_lock)) return; /* last test io still pending */ - submit_bio(p->test_bio); + generic_make_request(p->test_bio); } /*----------------------------------------------------------------- @@ -257,7 +268,7 @@ iterate_paths(m, test_path); if (atomic_dec_and_test(&m->trigger_event)) - dm_table_event(m->ti); + dm_table_event(m->ti->table); } spin_unlock(&_mpath_lock); @@ -298,9 +309,13 @@ static char *shift(struct arg_set *as) { + char *r; + if (as->argc) { as->argc--; - return *as->argv++; + r = *as->argv; + as->argv++; + return r; } return NULL; @@ -317,12 +332,12 @@ { struct bio *bio = p->test_bio; - bio->bi_sector = 0 + bio->bi_sector = 0; bio->bi_rw |= (1 << BIO_RW_FAILFAST); - bio->bi_bdev = path->dev->bdev; + bio->bi_bdev = p->dev->bdev; bio->bi_end_io = test_endio; bio->bi_private = p; - bio_add_page(bio, p->test_page, ??? hard sect size ???, 0); + bio_add_page(bio, p->test_page, bdev_hardsect_size(p->dev->bdev), 0); } static struct path *parse_path(struct arg_set *as, struct path_selector *ps, @@ -371,8 +386,8 @@ { static struct param _params[] = { {0, 1024, ESTR("invalid priority")}, - {0, 1024, ESTR("invalid number of selector args")}, - {1, 1024, ESTR("invalid number of paths")} + {1, 1024, ESTR("invalid number of paths")}, + {0, 1024, ESTR("invalid number of selector args")} }; int r; @@ -381,6 +396,7 @@ struct path_selector_type *pst; if (as->argc < 3) { + as->argc = 0; ti->error = ESTR("not enough priority group aruments"); return NULL; } @@ -400,27 +416,28 @@ ti->error = ESTR("unknown path selector type"); goto bad; } - pg->ps.type = pst; - r = pst->ctr(&pg->ps); + r = pst->ctr(pg->ps); if (r) { /* FIXME: need to put the pst ? fix after * factoring out the register */ goto bad; } + pg->ps->type = pst; - r = read_param(_params + 1, shift(as), &nr_selector_args, &ti->error); - if (r) - goto bad; /* * read the paths */ - nr_params = 1 + nr_selector_args; - r = read_param(_params + 2, shift(as), &nr_paths, &ti->error); + r = read_param(_params + 1, shift(as), &nr_paths, &ti->error); if (r) goto bad; + r = read_param(_params + 2, shift(as), &nr_selector_args, &ti->error); + if (r) + goto bad; + + nr_params = 1 + nr_selector_args; for (i = 0; i < nr_paths; i++) { struct path *path; struct arg_set path_args; @@ -431,7 +448,7 @@ path_args.argc = nr_params; path_args.argv = as->argv; - path = parse_path(&path_args, &pg->ps, ti); + path = parse_path(&path_args, pg->ps, ti); if (!path) goto bad; @@ -503,7 +520,9 @@ /* parse the priority groups */ while (as.argc) { - struct priority_group *pg = parse_priority_group(&as, m, ti); + struct priority_group *pg; + DMERR("calling parse priority group"); + pg = parse_priority_group(&as, m, ti); if (pg) __insert_priority_group(m, pg); } @@ -557,7 +576,7 @@ return -EIO; /* select a path */ - path = pg->ps.type->select_path(&pg->ps); + path = pg->ps->type->select_path(pg->ps); if (!path) return -EIO; /* No valid path found */ @@ -683,8 +702,8 @@ return r; } -static void lock_path(struct path *p) {down(&path->test_lock);} -static void unlock_path(struct path *p) {up(&path->test_lock);} +static void lock_path(struct path *p) {down(&p->test_lock);} +static void unlock_path(struct path *p) {up(&p->test_lock);} static void multipath_suspend(struct dm_target *ti) { @@ -715,6 +734,8 @@ .dtr = multipath_dtr, .map = multipath_map, .end_io = multipath_end_io, + .suspend = multipath_suspend, + .resume = multipath_resume, .status = multipath_status, }; --- diff/drivers/md/dm-path-selector.c 2003-12-29 10:16:39.000000000 +0000 +++ source/drivers/md/dm-path-selector.c 2003-12-29 10:16:58.000000000 +0000 @@ -6,7 +6,6 @@ * This file is released under the GPL. * * Path selector housekeeping (register/unregister/...) - * */ #include "dm.h" @@ -257,10 +256,9 @@ if (!pi) DMWARN("asked to change the state of an unknown path"); - else { - list_del(&pi->list); - list_add(&pi->list, valid ? &s->valid_paths : &s->invalid_paths); - } + else + list_move(&pi->list, + valid ? &s->valid_paths : &s->invalid_paths); spin_unlock_irqrestore(&s->lock, flags); } @@ -275,8 +273,7 @@ spin_lock_irqsave(&s->lock, flags); if (!list_empty(&s->valid_paths)) { pi = list_entry(s->valid_paths.next, struct path_info, list); - list_del(&pi->list); - list_add_tail(&pi->list, &s->valid_paths); + list_move_tail(&pi->list, &s->valid_paths); } spin_unlock_irqrestore(&s->lock, flags);