X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fblock%2Faoe%2Faoechr.c;h=e22b4c9520a9fdecee3317636bb532ea6404cda6;hb=refs%2Fheads%2Fvserver;hp=41ae0ede619a84a9be5bef17844dd9dcfb647ca4;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 41ae0ede6..e22b4c952 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ +/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ /* * aoechr.c * AoE character device driver @@ -13,8 +13,8 @@ enum { MINOR_ERR = 2, MINOR_DISCOVER, MINOR_INTERFACES, + MINOR_REVALIDATE, MSGSZ = 2048, - NARGS = 10, NMSG = 100, /* message backlog to retain */ }; @@ -41,6 +41,7 @@ static struct aoe_chardev chardevs[] = { { MINOR_ERR, "err" }, { MINOR_DISCOVER, "discover" }, { MINOR_INTERFACES, "interfaces" }, + { MINOR_REVALIDATE, "revalidate" }, }; static int @@ -54,14 +55,46 @@ static int interfaces(const char __user *str, size_t size) { if (set_aoe_iflist(str, size)) { - printk(KERN_CRIT - "%s: could not set interface list: %s\n", - __FUNCTION__, "too many interfaces"); + printk(KERN_ERR + "aoe: could not set interface list: too many interfaces\n"); return -EINVAL; } return 0; } +static int +revalidate(const char __user *str, size_t size) +{ + int major, minor, n; + ulong flags; + struct aoedev *d; + char buf[16]; + + if (size >= sizeof buf) + return -EINVAL; + buf[sizeof buf - 1] = '\0'; + if (copy_from_user(buf, str, size)) + return -EFAULT; + + /* should be e%d.%d format */ + n = sscanf(buf, "e%d.%d", &major, &minor); + if (n != 2) { + printk(KERN_ERR "aoe: invalid device specification\n"); + return -EINVAL; + } + d = aoedev_by_aoeaddr(major, minor); + if (!d) + return -EINVAL; + + spin_lock_irqsave(&d->lock, flags); + d->flags &= ~DEVFL_MAXBCNT; + d->flags |= DEVFL_PAUSE; + spin_unlock_irqrestore(&d->lock, flags); + aoecmd_cfg(major, minor); + + return 0; +} + void aoechr_error(char *msg) { @@ -81,7 +114,7 @@ bail: spin_unlock_irqrestore(&emsgs_lock, flags); mp = kmalloc(n, GFP_ATOMIC); if (mp == NULL) { - printk(KERN_CRIT "aoe: aoechr_error: allocation failure, len=%ld\n", n); + printk(KERN_ERR "aoe: allocation failure, len=%ld\n", n); goto bail; } @@ -106,7 +139,7 @@ aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp switch ((unsigned long) filp->private_data) { default: - printk(KERN_INFO "aoe: aoechr_write: can't write to that file.\n"); + printk(KERN_INFO "aoe: can't write to that file.\n"); break; case MINOR_DISCOVER: ret = discover(); @@ -114,6 +147,8 @@ aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp case MINOR_INTERFACES: ret = interfaces(buf, cnt); break; + case MINOR_REVALIDATE: + ret = revalidate(buf, cnt); } if (ret == 0) ret = cnt; @@ -125,7 +160,7 @@ aoechr_open(struct inode *inode, struct file *filp) { int n, i; - n = MINOR(inode->i_rdev); + n = iminor(inode); filp->private_data = (void *) (unsigned long) n; for (i = 0; i < ARRAY_SIZE(chardevs); ++i) @@ -213,7 +248,7 @@ aoechr_init(void) n = register_chrdev(AOE_MAJOR, "aoechr", &aoe_fops); if (n < 0) { - printk(KERN_ERR "aoe: aoechr_init: can't register char device\n"); + printk(KERN_ERR "aoe: can't register char device\n"); return n; } sema_init(&emsgs_sema, 0);