aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/aoe/aoedev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/aoe/aoedev.c')
-rw-r--r--drivers/block/aoe/aoedev.c87
1 files changed, 68 insertions, 19 deletions
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{