aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/aoe/aoe.h1
-rw-r--r--drivers/block/aoe/aoechr.c5
-rw-r--r--drivers/block/aoe/aoedev.c87
3 files changed, 74 insertions, 19 deletions
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index aecaac3f2e58..2248ab226576 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -191,6 +191,7 @@ struct aoedev *aoedev_by_aoeaddr(int maj, int min);
191struct aoedev *aoedev_by_sysminor_m(ulong sysminor); 191struct aoedev *aoedev_by_sysminor_m(ulong sysminor);
192void aoedev_downdev(struct aoedev *d); 192void aoedev_downdev(struct aoedev *d);
193int aoedev_isbusy(struct aoedev *d); 193int aoedev_isbusy(struct aoedev *d);
194int aoedev_flush(const char __user *str, size_t size);
194 195
195int aoenet_init(void); 196int aoenet_init(void);
196void aoenet_exit(void); 197void aoenet_exit(void);
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index f1124664c5c9..1bc85aa2271f 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -15,6 +15,7 @@ enum {
15 MINOR_DISCOVER, 15 MINOR_DISCOVER,
16 MINOR_INTERFACES, 16 MINOR_INTERFACES,
17 MINOR_REVALIDATE, 17 MINOR_REVALIDATE,
18 MINOR_FLUSH,
18 MSGSZ = 2048, 19 MSGSZ = 2048,
19 NMSG = 100, /* message backlog to retain */ 20 NMSG = 100, /* message backlog to retain */
20}; 21};
@@ -43,6 +44,7 @@ static struct aoe_chardev chardevs[] = {
43 { MINOR_DISCOVER, "discover" }, 44 { MINOR_DISCOVER, "discover" },
44 { MINOR_INTERFACES, "interfaces" }, 45 { MINOR_INTERFACES, "interfaces" },
45 { MINOR_REVALIDATE, "revalidate" }, 46 { MINOR_REVALIDATE, "revalidate" },
47 { MINOR_FLUSH, "flush" },
46}; 48};
47 49
48static int 50static int
@@ -158,6 +160,9 @@ aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp
158 break; 160 break;
159 case MINOR_REVALIDATE: 161 case MINOR_REVALIDATE:
160 ret = revalidate(buf, cnt); 162 ret = revalidate(buf, cnt);
163 break;
164 case MINOR_FLUSH:
165 ret = aoedev_flush(buf, cnt);
161 } 166 }
162 if (ret == 0) 167 if (ret == 0)
163 ret = cnt; 168 ret = cnt;
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index a4d625aefeaa..e26f6f4a28a2 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -9,6 +9,10 @@
9#include <linux/netdevice.h> 9#include <linux/netdevice.h>
10#include "aoe.h" 10#include "aoe.h"
11 11
12static void dummy_timer(ulong);
13static void aoedev_freedev(struct aoedev *);
14static void freetgt(struct aoetgt *t);
15
12static struct aoedev *devlist; 16static struct aoedev *devlist;
13static spinlock_t devlist_lock; 17static spinlock_t devlist_lock;
14 18
@@ -108,6 +112,70 @@ aoedev_downdev(struct aoedev *d)
108 d->flags &= ~DEVFL_UP; 112 d->flags &= ~DEVFL_UP;
109} 113}
110 114
115static void
116aoedev_freedev(struct aoedev *d)
117{
118 struct aoetgt **t, **e;
119
120 if (d->gd) {
121 aoedisk_rm_sysfs(d);
122 del_gendisk(d->gd);
123 put_disk(d->gd);
124 }
125 t = d->targets;
126 e = t + NTARGETS;
127 for (; t < e && *t; t++)
128 freetgt(*t);
129 if (d->bufpool)
130 mempool_destroy(d->bufpool);
131 kfree(d);
132}
133
134int
135aoedev_flush(const char __user *str, size_t cnt)
136{
137 ulong flags;
138 struct aoedev *d, **dd;
139 struct aoedev *rmd = NULL;
140 char buf[16];
141 int all = 0;
142
143 if (cnt >= 3) {
144 if (cnt > sizeof buf)
145 cnt = sizeof buf;
146 if (copy_from_user(buf, str, cnt))
147 return -EFAULT;
148 all = !strncmp(buf, "all", 3);
149 }
150
151 flush_scheduled_work();
152 spin_lock_irqsave(&devlist_lock, flags);
153 dd = &devlist;
154 while ((d = *dd)) {
155 spin_lock(&d->lock);
156 if ((!all && (d->flags & DEVFL_UP))
157 || (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE))
158 || d->nopen) {
159 spin_unlock(&d->lock);
160 dd = &d->next;
161 continue;
162 }
163 *dd = d->next;
164 aoedev_downdev(d);
165 d->flags |= DEVFL_TKILL;
166 spin_unlock(&d->lock);
167 d->next = rmd;
168 rmd = d;
169 }
170 spin_unlock_irqrestore(&devlist_lock, flags);
171 while ((d = rmd)) {
172 rmd = d->next;
173 del_timer_sync(&d->timer);
174 aoedev_freedev(d); /* must be able to sleep */
175 }
176 return 0;
177}
178
111/* find it or malloc it */ 179/* find it or malloc it */
112struct aoedev * 180struct aoedev *
113aoedev_by_sysminor_m(ulong sysminor) 181aoedev_by_sysminor_m(ulong sysminor)
@@ -161,25 +229,6 @@ freetgt(struct aoetgt *t)
161 kfree(t); 229 kfree(t);
162} 230}
163 231
164static void
165aoedev_freedev(struct aoedev *d)
166{
167 struct aoetgt **t, **e;
168
169 if (d->gd) {
170 aoedisk_rm_sysfs(d);
171 del_gendisk(d->gd);
172 put_disk(d->gd);
173 }
174 t = d->targets;
175 e = t + NTARGETS;
176 for (; t < e && *t; t++)
177 freetgt(*t);
178 if (d->bufpool)
179 mempool_destroy(d->bufpool);
180 kfree(d);
181}
182
183void 232void
184aoedev_exit(void) 233aoedev_exit(void)
185{ 234{