Multipath: rename rdac.c to dm-ps-rdac.c --- diff/drivers/md/Makefile 2004-04-06 15:55:00.733273960 +0100 +++ source/drivers/md/Makefile 2004-04-06 15:55:02.793960688 +0100 @@ -22,11 +22,11 @@ obj-$(CONFIG_MD_RAID1) += raid1.o obj-$(CONFIG_MD_RAID5) += raid5.o xor.o obj-$(CONFIG_MD_RAID6) += raid6.o xor.o obj-$(CONFIG_MD_MULTIPATH) += multipath.o -obj-$(CONFIG_DM_RDAC) += rdac.o obj-$(CONFIG_BLK_DEV_MD) += md.o obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o obj-$(CONFIG_DM_CRYPT) += dm-crypt.o obj-$(CONFIG_DM_MULTIPATH) += dm-multipath.o +obj-$(CONFIG_DM_RDAC) += dm-ps-rdac.o quiet_cmd_unroll = UNROLL $@ cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \ --- diff/drivers/md/dm-ps-rdac.c 1970-01-01 01:00:00.000000000 +0100 +++ source/drivers/md/dm-ps-rdac.c 2004-04-06 15:55:02.794960536 +0100 @@ -0,0 +1,292 @@ +#include <linux/slab.h> +#include <linux/list.h> +#include <linux/fs.h> +#include <linux/blkdev.h> +#include <linux/init.h> +#include <linux/module.h> +#include <scsi/scsi.h> +#include <scsi/scsi_cmnd.h> + +#include "dm.h" +#include "dm-path-selector.h" + +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) +{ + struct path_info *pi; + + list_for_each_entry (pi, head, list) + if (pi->path == p) + return pi; + + return NULL; +} + +/* FIXME: get rid of this */ +#define MPATH_FAIL_COUNT 1 + +/* Failover modes */ +enum { + NONE, + AVT, + RDAC, +}; + +struct selector { + spinlock_t path_lock; + + struct list_head active_paths; + struct list_head failed_paths; + + int failover; +}; + +static struct selector *alloc_selector(void) +{ + struct selector *s = kmalloc(sizeof(*s), GFP_KERNEL); + + if (s) { + INIT_LIST_HEAD(&s->active_paths); + INIT_LIST_HEAD(&s->failed_paths); + s->path_lock = SPIN_LOCK_UNLOCKED; + /* + * TODO modify arg passing. + */ + s->failover = RDAC; + } + + return s; +} + +static int rdac_ctr(struct path_selector *ps) +{ + struct selector *s; + + s = alloc_selector(); + if (!s) + return -ENOMEM; + + ps->context = s; + return 0; +} + +static void free_paths(struct list_head *paths) +{ + struct path_info *pi, *next; + + list_for_each_entry_safe (pi, next, paths, list) { + list_del(&pi->list); + kfree(pi); + } +} + +static void rdac_dtr(struct path_selector *ps) +{ + struct selector *s = (struct selector *) ps->context; + free_paths(&s->active_paths); + free_paths(&s->failed_paths); + kfree(s); +} + +static int send_failover_cmd(struct block_device *bdev) +{ + struct request *rq; + request_queue_t *q = bdev_get_queue(bdev); + struct gendisk *bd_disk = bdev->bd_contains->bd_disk; + int err; + /* tmp test */ + char sense[SCSI_SENSE_BUFFERSIZE]; + static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0}; + + printk (KERN_ERR "get_request\n"); + + if (!q) + return -EPERM; + + rq = blk_get_request(q, READ, __GFP_WAIT); + + printk (KERN_ERR "got it\n"); + + + memcpy(rq->cmd, tur_command, sizeof(tur_command)); + rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); + + memset(sense, 0, sizeof(sense)); + rq->sense = sense; + rq->sense_len = 0; + + rq->data = NULL; + rq->data_len = 0; + +// rq->data = buffer; +// rq->data_len = bytes; + rq->flags |= REQ_BLOCK_PC; + + printk (KERN_ERR "sending\n"); + + err = blk_execute_rq(q, bd_disk, rq); + if (rq->errors) + printk(KERN_ERR "send_failover_cmd failed\n"); + else + printk(KERN_ERR "send_failover_cmd succeeded\n"); + blk_put_request(rq); + + return err; +} + +static int rdac_init(struct path_selector *ps) +{ + struct selector *s = (struct selector *) ps->context; + struct path_info *pi; + + if (s->failover != RDAC) + return 0; + + /* + * This is called before any IO has been sent to + * these paths and after all paths have been added, + * so we do not need to hold the path lock. + */ + while (!list_empty(&s->active_paths)) { + pi = list_entry(s->active_paths.next, struct path_info, list); + + if (!send_failover_cmd(dm_path_to_bdev(pi->path))) + return 0; + else + list_move(&pi->list, &s->failed_paths); + } + + return -EPERM; +} + +static int rdac_add_path(struct path_selector *ps, struct path *path, + int argc, char **argv, char **error) +{ + struct selector *s = (struct selector *) ps->context; + struct path_info *pi; + + /* parse the path arguments */ + if (argc != 0) { + *error = "rdac ps: incorrect number of arguments"; + return -EINVAL; + } + + /* allocate the path */ + pi = kmalloc(sizeof(*pi), GFP_KERNEL); + if (!pi) { + *error = "rdac ps: Error allocating path context"; + return -ENOMEM; + } + + pi->fail_count = MPATH_FAIL_COUNT; + pi->path = path; + + spin_lock(&s->path_lock); + list_add(&pi->list, &s->active_paths); + spin_unlock(&s->path_lock); + + return 0; +} + +static void rdac_update_path(struct path_selector *ps, struct path *p, + int error) +{ + unsigned long flags; + struct selector *s = (struct selector *) ps->context; + struct path_info *pi; + + /* + * This function will be called infrequently so we don't + * mind the expense of these searches. + */ + spin_lock_irqsave(&s->path_lock, flags); + + pi = path_lookup(&s->active_paths, p); + if (pi && !--pi->fail_count) + list_move(&pi->list, &s->failed_paths); + + spin_unlock_irqrestore(&s->path_lock, flags); +} + +static struct path *rdac_select_path(struct path_selector *ps) +{ + unsigned long flags; + struct selector *s = (struct selector *) ps->context; + struct path_info *pi = NULL; + + spin_lock_irqsave(&s->path_lock, flags); + if (!list_empty(&s->active_paths)) { + pi = list_entry(s->active_paths.next, struct path_info, list); + list_move_tail(&pi->list, &s->active_paths); + } + spin_unlock_irqrestore(&s->path_lock, flags); + + return pi ? pi->path : NULL; +} + +static int rdac_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->path_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->active_paths, path); + if (!pi) { + failed = 1; + pi = path_lookup(&s->failed_paths, path); + } + + sz = scnprintf(result, maxlen, "%s %u ", failed ? "F" : "A", + pi->fail_count); + + spin_unlock_irqrestore(&s->path_lock, flags); + + return sz; +} + +static struct path_selector_type rdac_ps = { + .name = "rdac", + .ctr = rdac_ctr, + .init = rdac_init, + .dtr = rdac_dtr, + .add_path = rdac_add_path, + .update_path = rdac_update_path, + .select_path = rdac_select_path, + .status = rdac_status, +}; + +int __init init_rdac(void) +{ + return dm_register_path_selector(&rdac_ps); +} + +void __exit exit_rdac(void) +{ + dm_unregister_path_selector(&rdac_ps); +} + +module_init(init_rdac); +module_exit(exit_rdac); + +MODULE_DESCRIPTION("RDAC/AVT Path Selector"); +MODULE_AUTHOR("Mike Christie"); +MODULE_LICENSE("GPL"); --- diff/drivers/md/rdac.c 2004-04-06 15:55:00.733273960 +0100 +++ source/drivers/md/rdac.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,292 +0,0 @@ -#include <linux/slab.h> -#include <linux/list.h> -#include <linux/fs.h> -#include <linux/blkdev.h> -#include <linux/init.h> -#include <linux/module.h> -#include <scsi/scsi.h> -#include <scsi/scsi_cmnd.h> - -#include "dm.h" -#include "dm-path-selector.h" - -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) -{ - struct path_info *pi; - - list_for_each_entry (pi, head, list) - if (pi->path == p) - return pi; - - return NULL; -} - -/* FIXME: get rid of this */ -#define MPATH_FAIL_COUNT 1 - -/* Failover modes */ -enum { - NONE, - AVT, - RDAC, -}; - -struct selector { - spinlock_t path_lock; - - struct list_head active_paths; - struct list_head failed_paths; - - int failover; -}; - -static struct selector *alloc_selector(void) -{ - struct selector *s = kmalloc(sizeof(*s), GFP_KERNEL); - - if (s) { - INIT_LIST_HEAD(&s->active_paths); - INIT_LIST_HEAD(&s->failed_paths); - s->path_lock = SPIN_LOCK_UNLOCKED; - /* - * TODO modify arg passing. - */ - s->failover = RDAC; - } - - return s; -} - -static int rdac_ctr(struct path_selector *ps) -{ - struct selector *s; - - s = alloc_selector(); - if (!s) - return -ENOMEM; - - ps->context = s; - return 0; -} - -static void free_paths(struct list_head *paths) -{ - struct path_info *pi, *next; - - list_for_each_entry_safe (pi, next, paths, list) { - list_del(&pi->list); - kfree(pi); - } -} - -static void rdac_dtr(struct path_selector *ps) -{ - struct selector *s = (struct selector *) ps->context; - free_paths(&s->active_paths); - free_paths(&s->failed_paths); - kfree(s); -} - -static int send_failover_cmd(struct block_device *bdev) -{ - struct request *rq; - request_queue_t *q = bdev_get_queue(bdev); - struct gendisk *bd_disk = bdev->bd_contains->bd_disk; - int err; - /* tmp test */ - char sense[SCSI_SENSE_BUFFERSIZE]; - static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0}; - - printk (KERN_ERR "get_request\n"); - - if (!q) - return -EPERM; - - rq = blk_get_request(q, READ, __GFP_WAIT); - - printk (KERN_ERR "got it\n"); - - - memcpy(rq->cmd, tur_command, sizeof(tur_command)); - rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); - - memset(sense, 0, sizeof(sense)); - rq->sense = sense; - rq->sense_len = 0; - - rq->data = NULL; - rq->data_len = 0; - -// rq->data = buffer; -// rq->data_len = bytes; - rq->flags |= REQ_BLOCK_PC; - - printk (KERN_ERR "sending\n"); - - err = blk_execute_rq(q, bd_disk, rq); - if (rq->errors) - printk(KERN_ERR "send_failover_cmd failed\n"); - else - printk(KERN_ERR "send_failover_cmd succeeded\n"); - blk_put_request(rq); - - return err; -} - -static int rdac_init(struct path_selector *ps) -{ - struct selector *s = (struct selector *) ps->context; - struct path_info *pi; - - if (s->failover != RDAC) - return 0; - - /* - * This is called before any IO has been sent to - * these paths and after all paths have been added, - * so we do not need to hold the path lock. - */ - while (!list_empty(&s->active_paths)) { - pi = list_entry(s->active_paths.next, struct path_info, list); - - if (!send_failover_cmd(dm_path_to_bdev(pi->path))) - return 0; - else - list_move(&pi->list, &s->failed_paths); - } - - return -EPERM; -} - -static int rdac_add_path(struct path_selector *ps, struct path *path, - int argc, char **argv, char **error) -{ - struct selector *s = (struct selector *) ps->context; - struct path_info *pi; - - /* parse the path arguments */ - if (argc != 0) { - *error = "rdac ps: incorrect number of arguments"; - return -EINVAL; - } - - /* allocate the path */ - pi = kmalloc(sizeof(*pi), GFP_KERNEL); - if (!pi) { - *error = "rdac ps: Error allocating path context"; - return -ENOMEM; - } - - pi->fail_count = MPATH_FAIL_COUNT; - pi->path = path; - - spin_lock(&s->path_lock); - list_add(&pi->list, &s->active_paths); - spin_unlock(&s->path_lock); - - return 0; -} - -static void rdac_update_path(struct path_selector *ps, struct path *p, - int error) -{ - unsigned long flags; - struct selector *s = (struct selector *) ps->context; - struct path_info *pi; - - /* - * This function will be called infrequently so we don't - * mind the expense of these searches. - */ - spin_lock_irqsave(&s->path_lock, flags); - - pi = path_lookup(&s->active_paths, p); - if (pi && !--pi->fail_count) - list_move(&pi->list, &s->failed_paths); - - spin_unlock_irqrestore(&s->path_lock, flags); -} - -static struct path *rdac_select_path(struct path_selector *ps) -{ - unsigned long flags; - struct selector *s = (struct selector *) ps->context; - struct path_info *pi = NULL; - - spin_lock_irqsave(&s->path_lock, flags); - if (!list_empty(&s->active_paths)) { - pi = list_entry(s->active_paths.next, struct path_info, list); - list_move_tail(&pi->list, &s->active_paths); - } - spin_unlock_irqrestore(&s->path_lock, flags); - - return pi ? pi->path : NULL; -} - -static int rdac_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->path_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->active_paths, path); - if (!pi) { - failed = 1; - pi = path_lookup(&s->failed_paths, path); - } - - sz = scnprintf(result, maxlen, "%s %u ", failed ? "F" : "A", - pi->fail_count); - - spin_unlock_irqrestore(&s->path_lock, flags); - - return sz; -} - -static struct path_selector_type rdac_ps = { - .name = "rdac", - .ctr = rdac_ctr, - .init = rdac_init, - .dtr = rdac_dtr, - .add_path = rdac_add_path, - .update_path = rdac_update_path, - .select_path = rdac_select_path, - .status = rdac_status, -}; - -int __init init_rdac(void) -{ - return dm_register_path_selector(&rdac_ps); -} - -void __exit exit_rdac(void) -{ - dm_unregister_path_selector(&rdac_ps); -} - -module_init(init_rdac); -module_exit(exit_rdac); - -MODULE_DESCRIPTION("RDAC/AVT Path Selector"); -MODULE_AUTHOR("Mike Christie"); -MODULE_LICENSE("GPL");