diff options
Diffstat (limited to 'drivers/block/aoe/aoechr.c')
-rw-r--r-- | drivers/block/aoe/aoechr.c | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 03c7f4ab5624..f1124664c5c9 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c | |||
@@ -194,52 +194,51 @@ aoechr_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off) | |||
194 | ulong flags; | 194 | ulong flags; |
195 | 195 | ||
196 | n = (unsigned long) filp->private_data; | 196 | n = (unsigned long) filp->private_data; |
197 | switch (n) { | 197 | if (n != MINOR_ERR) |
198 | case MINOR_ERR: | 198 | return -EFAULT; |
199 | spin_lock_irqsave(&emsgs_lock, flags); | 199 | |
200 | loop: | 200 | spin_lock_irqsave(&emsgs_lock, flags); |
201 | em = emsgs + emsgs_head_idx; | ||
202 | if ((em->flags & EMFL_VALID) == 0) { | ||
203 | if (filp->f_flags & O_NDELAY) { | ||
204 | spin_unlock_irqrestore(&emsgs_lock, flags); | ||
205 | return -EAGAIN; | ||
206 | } | ||
207 | nblocked_emsgs_readers++; | ||
208 | 201 | ||
202 | for (;;) { | ||
203 | em = emsgs + emsgs_head_idx; | ||
204 | if ((em->flags & EMFL_VALID) != 0) | ||
205 | break; | ||
206 | if (filp->f_flags & O_NDELAY) { | ||
209 | spin_unlock_irqrestore(&emsgs_lock, flags); | 207 | spin_unlock_irqrestore(&emsgs_lock, flags); |
208 | return -EAGAIN; | ||
209 | } | ||
210 | nblocked_emsgs_readers++; | ||
211 | |||
212 | spin_unlock_irqrestore(&emsgs_lock, flags); | ||
210 | 213 | ||
211 | n = down_interruptible(&emsgs_sema); | 214 | n = down_interruptible(&emsgs_sema); |
212 | 215 | ||
213 | spin_lock_irqsave(&emsgs_lock, flags); | 216 | spin_lock_irqsave(&emsgs_lock, flags); |
214 | 217 | ||
215 | nblocked_emsgs_readers--; | 218 | nblocked_emsgs_readers--; |
216 | 219 | ||
217 | if (n) { | 220 | if (n) { |
218 | spin_unlock_irqrestore(&emsgs_lock, flags); | ||
219 | return -ERESTARTSYS; | ||
220 | } | ||
221 | goto loop; | ||
222 | } | ||
223 | if (em->len > cnt) { | ||
224 | spin_unlock_irqrestore(&emsgs_lock, flags); | 221 | spin_unlock_irqrestore(&emsgs_lock, flags); |
225 | return -EAGAIN; | 222 | return -ERESTARTSYS; |
226 | } | 223 | } |
227 | mp = em->msg; | 224 | } |
228 | len = em->len; | 225 | if (em->len > cnt) { |
229 | em->msg = NULL; | 226 | spin_unlock_irqrestore(&emsgs_lock, flags); |
230 | em->flags &= ~EMFL_VALID; | 227 | return -EAGAIN; |
228 | } | ||
229 | mp = em->msg; | ||
230 | len = em->len; | ||
231 | em->msg = NULL; | ||
232 | em->flags &= ~EMFL_VALID; | ||
231 | 233 | ||
232 | emsgs_head_idx++; | 234 | emsgs_head_idx++; |
233 | emsgs_head_idx %= ARRAY_SIZE(emsgs); | 235 | emsgs_head_idx %= ARRAY_SIZE(emsgs); |
234 | 236 | ||
235 | spin_unlock_irqrestore(&emsgs_lock, flags); | 237 | spin_unlock_irqrestore(&emsgs_lock, flags); |
236 | 238 | ||
237 | n = copy_to_user(buf, mp, len); | 239 | n = copy_to_user(buf, mp, len); |
238 | kfree(mp); | 240 | kfree(mp); |
239 | return n == 0 ? len : -EFAULT; | 241 | return n == 0 ? len : -EFAULT; |
240 | default: | ||
241 | return -EFAULT; | ||
242 | } | ||
243 | } | 242 | } |
244 | 243 | ||
245 | static const struct file_operations aoe_fops = { | 244 | static const struct file_operations aoe_fops = { |