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.c168
1 files changed, 79 insertions, 89 deletions
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index 51f50710e5fc..a4d625aefeaa 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -15,15 +15,18 @@ static spinlock_t devlist_lock;
15int 15int
16aoedev_isbusy(struct aoedev *d) 16aoedev_isbusy(struct aoedev *d)
17{ 17{
18 struct aoetgt **t, **te;
18 struct frame *f, *e; 19 struct frame *f, *e;
19 20
20 f = d->frames; 21 t = d->targets;
21 e = f + d->nframes; 22 te = t + NTARGETS;
22 do { 23 for (; t < te && *t; t++) {
23 if (f->tag != FREETAG) 24 f = (*t)->frames;
24 return 1; 25 e = f + (*t)->nframes;
25 } while (++f < e); 26 for (; f < e; f++)
26 27 if (f->tag != FREETAG)
28 return 1;
29 }
27 return 0; 30 return 0;
28} 31}
29 32
@@ -55,75 +58,41 @@ dummy_timer(ulong vp)
55 add_timer(&d->timer); 58 add_timer(&d->timer);
56} 59}
57 60
58/* called with devlist lock held */
59static struct aoedev *
60aoedev_newdev(ulong nframes)
61{
62 struct aoedev *d;
63 struct frame *f, *e;
64
65 d = kzalloc(sizeof *d, GFP_ATOMIC);
66 f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
67 switch (!d || !f) {
68 case 0:
69 d->nframes = nframes;
70 d->frames = f;
71 e = f + nframes;
72 for (; f<e; f++) {
73 f->tag = FREETAG;
74 f->skb = new_skb(ETH_ZLEN);
75 if (!f->skb)
76 break;
77 }
78 if (f == e)
79 break;
80 while (f > d->frames) {
81 f--;
82 dev_kfree_skb(f->skb);
83 }
84 default:
85 if (f)
86 kfree(f);
87 if (d)
88 kfree(d);
89 return NULL;
90 }
91 INIT_WORK(&d->work, aoecmd_sleepwork);
92 spin_lock_init(&d->lock);
93 init_timer(&d->timer);
94 d->timer.data = (ulong) d;
95 d->timer.function = dummy_timer;
96 d->timer.expires = jiffies + HZ;
97 add_timer(&d->timer);
98 d->bufpool = NULL; /* defer to aoeblk_gdalloc */
99 INIT_LIST_HEAD(&d->bufq);
100 d->next = devlist;
101 devlist = d;
102
103 return d;
104}
105
106void 61void
107aoedev_downdev(struct aoedev *d) 62aoedev_downdev(struct aoedev *d)
108{ 63{
64 struct aoetgt **t, **te;
109 struct frame *f, *e; 65 struct frame *f, *e;
110 struct buf *buf; 66 struct buf *buf;
111 struct bio *bio; 67 struct bio *bio;
112 68
113 f = d->frames; 69 t = d->targets;
114 e = f + d->nframes; 70 te = t + NTARGETS;
115 for (; f<e; f->tag = FREETAG, f->buf = NULL, f++) { 71 for (; t < te && *t; t++) {
116 if (f->tag == FREETAG || f->buf == NULL) 72 f = (*t)->frames;
117 continue; 73 e = f + (*t)->nframes;
118 buf = f->buf; 74 for (; f < e; f->tag = FREETAG, f->buf = NULL, f++) {
119 bio = buf->bio; 75 if (f->tag == FREETAG || f->buf == NULL)
120 if (--buf->nframesout == 0) { 76 continue;
121 mempool_free(buf, d->bufpool); 77 buf = f->buf;
122 bio_endio(bio, -EIO); 78 bio = buf->bio;
79 if (--buf->nframesout == 0
80 && buf != d->inprocess) {
81 mempool_free(buf, d->bufpool);
82 bio_endio(bio, -EIO);
83 }
123 } 84 }
124 skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0; 85 (*t)->maxout = (*t)->nframes;
86 (*t)->nout = 0;
87 }
88 buf = d->inprocess;
89 if (buf) {
90 bio = buf->bio;
91 mempool_free(buf, d->bufpool);
92 bio_endio(bio, -EIO);
125 } 93 }
126 d->inprocess = NULL; 94 d->inprocess = NULL;
95 d->htgt = NULL;
127 96
128 while (!list_empty(&d->bufq)) { 97 while (!list_empty(&d->bufq)) {
129 buf = container_of(d->bufq.next, struct buf, bufs); 98 buf = container_of(d->bufq.next, struct buf, bufs);
@@ -136,12 +105,12 @@ aoedev_downdev(struct aoedev *d)
136 if (d->gd) 105 if (d->gd)
137 d->gd->capacity = 0; 106 d->gd->capacity = 0;
138 107
139 d->flags &= ~(DEVFL_UP | DEVFL_PAUSE); 108 d->flags &= ~DEVFL_UP;
140} 109}
141 110
142/* find it or malloc it */ 111/* find it or malloc it */
143struct aoedev * 112struct aoedev *
144aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt) 113aoedev_by_sysminor_m(ulong sysminor)
145{ 114{
146 struct aoedev *d; 115 struct aoedev *d;
147 ulong flags; 116 ulong flags;
@@ -151,40 +120,61 @@ aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
151 for (d=devlist; d; d=d->next) 120 for (d=devlist; d; d=d->next)
152 if (d->sysminor == sysminor) 121 if (d->sysminor == sysminor)
153 break; 122 break;
154 123 if (d)
155 if (d == NULL) { 124 goto out;
156 d = aoedev_newdev(bufcnt); 125 d = kcalloc(1, sizeof *d, GFP_ATOMIC);
157 if (d == NULL) { 126 if (!d)
158 spin_unlock_irqrestore(&devlist_lock, flags); 127 goto out;
159 printk(KERN_INFO "aoe: aoedev_newdev failure.\n"); 128 INIT_WORK(&d->work, aoecmd_sleepwork);
160 return NULL; 129 spin_lock_init(&d->lock);
161 } 130 init_timer(&d->timer);
162 d->sysminor = sysminor; 131 d->timer.data = (ulong) d;
163 d->aoemajor = AOEMAJOR(sysminor); 132 d->timer.function = dummy_timer;
164 d->aoeminor = AOEMINOR(sysminor); 133 d->timer.expires = jiffies + HZ;
165 } 134 add_timer(&d->timer);
166 135 d->bufpool = NULL; /* defer to aoeblk_gdalloc */
136 d->tgt = d->targets;
137 INIT_LIST_HEAD(&d->bufq);
138 d->sysminor = sysminor;
139 d->aoemajor = AOEMAJOR(sysminor);
140 d->aoeminor = AOEMINOR(sysminor);
141 d->mintimer = MINTIMER;
142 d->next = devlist;
143 devlist = d;
144 out:
167 spin_unlock_irqrestore(&devlist_lock, flags); 145 spin_unlock_irqrestore(&devlist_lock, flags);
168 return d; 146 return d;
169} 147}
170 148
171static void 149static void
172aoedev_freedev(struct aoedev *d) 150freetgt(struct aoetgt *t)
173{ 151{
174 struct frame *f, *e; 152 struct frame *f, *e;
175 153
154 f = t->frames;
155 e = f + t->nframes;
156 for (; f < e; f++) {
157 skb_shinfo(f->skb)->nr_frags = 0;
158 dev_kfree_skb(f->skb);
159 }
160 kfree(t->frames);
161 kfree(t);
162}
163
164static void
165aoedev_freedev(struct aoedev *d)
166{
167 struct aoetgt **t, **e;
168
176 if (d->gd) { 169 if (d->gd) {
177 aoedisk_rm_sysfs(d); 170 aoedisk_rm_sysfs(d);
178 del_gendisk(d->gd); 171 del_gendisk(d->gd);
179 put_disk(d->gd); 172 put_disk(d->gd);
180 } 173 }
181 f = d->frames; 174 t = d->targets;
182 e = f + d->nframes; 175 e = t + NTARGETS;
183 for (; f<e; f++) { 176 for (; t < e && *t; t++)
184 skb_shinfo(f->skb)->nr_frags = 0; 177 freetgt(*t);
185 dev_kfree_skb(f->skb);
186 }
187 kfree(d->frames);
188 if (d->bufpool) 178 if (d->bufpool)
189 mempool_destroy(d->bufpool); 179 mempool_destroy(d->bufpool);
190 kfree(d); 180 kfree(d);