diff options
Diffstat (limited to 'drivers/block/aoe/aoechr.c')
-rw-r--r-- | drivers/block/aoe/aoechr.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 41ae0ede619a..5327f553b4f5 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c | |||
@@ -13,6 +13,7 @@ enum { | |||
13 | MINOR_ERR = 2, | 13 | MINOR_ERR = 2, |
14 | MINOR_DISCOVER, | 14 | MINOR_DISCOVER, |
15 | MINOR_INTERFACES, | 15 | MINOR_INTERFACES, |
16 | MINOR_REVALIDATE, | ||
16 | MSGSZ = 2048, | 17 | MSGSZ = 2048, |
17 | NARGS = 10, | 18 | NARGS = 10, |
18 | NMSG = 100, /* message backlog to retain */ | 19 | NMSG = 100, /* message backlog to retain */ |
@@ -41,6 +42,7 @@ static struct aoe_chardev chardevs[] = { | |||
41 | { MINOR_ERR, "err" }, | 42 | { MINOR_ERR, "err" }, |
42 | { MINOR_DISCOVER, "discover" }, | 43 | { MINOR_DISCOVER, "discover" }, |
43 | { MINOR_INTERFACES, "interfaces" }, | 44 | { MINOR_INTERFACES, "interfaces" }, |
45 | { MINOR_REVALIDATE, "revalidate" }, | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | static int | 48 | static int |
@@ -62,6 +64,39 @@ interfaces(const char __user *str, size_t size) | |||
62 | return 0; | 64 | return 0; |
63 | } | 65 | } |
64 | 66 | ||
67 | static int | ||
68 | revalidate(const char __user *str, size_t size) | ||
69 | { | ||
70 | int major, minor, n; | ||
71 | ulong flags; | ||
72 | struct aoedev *d; | ||
73 | char buf[16]; | ||
74 | |||
75 | if (size >= sizeof buf) | ||
76 | return -EINVAL; | ||
77 | buf[sizeof buf - 1] = '\0'; | ||
78 | if (copy_from_user(buf, str, size)) | ||
79 | return -EFAULT; | ||
80 | |||
81 | /* should be e%d.%d format */ | ||
82 | n = sscanf(buf, "e%d.%d", &major, &minor); | ||
83 | if (n != 2) { | ||
84 | printk(KERN_ERR "aoe: %s: invalid device specification\n", | ||
85 | __FUNCTION__); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | d = aoedev_by_aoeaddr(major, minor); | ||
89 | if (!d) | ||
90 | return -EINVAL; | ||
91 | |||
92 | spin_lock_irqsave(&d->lock, flags); | ||
93 | d->flags |= DEVFL_PAUSE; | ||
94 | spin_unlock_irqrestore(&d->lock, flags); | ||
95 | aoecmd_cfg(major, minor); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
65 | void | 100 | void |
66 | aoechr_error(char *msg) | 101 | aoechr_error(char *msg) |
67 | { | 102 | { |
@@ -114,6 +149,8 @@ aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp | |||
114 | case MINOR_INTERFACES: | 149 | case MINOR_INTERFACES: |
115 | ret = interfaces(buf, cnt); | 150 | ret = interfaces(buf, cnt); |
116 | break; | 151 | break; |
152 | case MINOR_REVALIDATE: | ||
153 | ret = revalidate(buf, cnt); | ||
117 | } | 154 | } |
118 | if (ret == 0) | 155 | if (ret == 0) |
119 | ret = cnt; | 156 | ret = cnt; |