| .. | .. |
|---|
| 5 | 5 | */ |
|---|
| 6 | 6 | |
|---|
| 7 | 7 | #include <linux/hdreg.h> |
|---|
| 8 | | -#include <linux/blkdev.h> |
|---|
| 8 | +#include <linux/blk-mq.h> |
|---|
| 9 | 9 | #include <linux/netdevice.h> |
|---|
| 10 | 10 | #include <linux/delay.h> |
|---|
| 11 | 11 | #include <linux/slab.h> |
|---|
| .. | .. |
|---|
| 160 | 160 | aoe_failip(struct aoedev *d) |
|---|
| 161 | 161 | { |
|---|
| 162 | 162 | struct request *rq; |
|---|
| 163 | + struct aoe_req *req; |
|---|
| 163 | 164 | struct bio *bio; |
|---|
| 164 | | - unsigned long n; |
|---|
| 165 | 165 | |
|---|
| 166 | 166 | aoe_failbuf(d, d->ip.buf); |
|---|
| 167 | | - |
|---|
| 168 | 167 | rq = d->ip.rq; |
|---|
| 169 | 168 | if (rq == NULL) |
|---|
| 170 | 169 | return; |
|---|
| 170 | + |
|---|
| 171 | + req = blk_mq_rq_to_pdu(rq); |
|---|
| 171 | 172 | while ((bio = d->ip.nxbio)) { |
|---|
| 172 | 173 | bio->bi_status = BLK_STS_IOERR; |
|---|
| 173 | 174 | d->ip.nxbio = bio->bi_next; |
|---|
| 174 | | - n = (unsigned long) rq->special; |
|---|
| 175 | | - rq->special = (void *) --n; |
|---|
| 175 | + req->nr_bios--; |
|---|
| 176 | 176 | } |
|---|
| 177 | | - if ((unsigned long) rq->special == 0) |
|---|
| 177 | + |
|---|
| 178 | + if (!req->nr_bios) |
|---|
| 178 | 179 | aoe_end_request(d, rq, 0); |
|---|
| 179 | 180 | } |
|---|
| 180 | 181 | |
|---|
| .. | .. |
|---|
| 197 | 198 | { |
|---|
| 198 | 199 | struct aoetgt *t, **tt, **te; |
|---|
| 199 | 200 | struct list_head *head, *pos, *nx; |
|---|
| 200 | | - struct request *rq; |
|---|
| 201 | 201 | int i; |
|---|
| 202 | 202 | |
|---|
| 203 | 203 | d->flags &= ~DEVFL_UP; |
|---|
| .. | .. |
|---|
| 225 | 225 | |
|---|
| 226 | 226 | /* fast fail all pending I/O */ |
|---|
| 227 | 227 | if (d->blkq) { |
|---|
| 228 | | - while ((rq = blk_peek_request(d->blkq))) { |
|---|
| 229 | | - blk_start_request(rq); |
|---|
| 230 | | - aoe_end_request(d, rq, 1); |
|---|
| 231 | | - } |
|---|
| 228 | + /* UP is cleared, freeze+quiesce to insure all are errored */ |
|---|
| 229 | + blk_mq_freeze_queue(d->blkq); |
|---|
| 230 | + blk_mq_quiesce_queue(d->blkq); |
|---|
| 231 | + blk_mq_unquiesce_queue(d->blkq); |
|---|
| 232 | + blk_mq_unfreeze_queue(d->blkq); |
|---|
| 232 | 233 | } |
|---|
| 233 | 234 | |
|---|
| 234 | 235 | if (d->gd) |
|---|
| .. | .. |
|---|
| 275 | 276 | del_timer_sync(&d->timer); |
|---|
| 276 | 277 | if (d->gd) { |
|---|
| 277 | 278 | aoedisk_rm_debugfs(d); |
|---|
| 278 | | - aoedisk_rm_sysfs(d); |
|---|
| 279 | 279 | del_gendisk(d->gd); |
|---|
| 280 | 280 | put_disk(d->gd); |
|---|
| 281 | + blk_mq_free_tag_set(&d->tag_set); |
|---|
| 281 | 282 | blk_cleanup_queue(d->blkq); |
|---|
| 282 | 283 | } |
|---|
| 283 | 284 | t = d->targets; |
|---|
| .. | .. |
|---|
| 322 | 323 | } |
|---|
| 323 | 324 | |
|---|
| 324 | 325 | flush_scheduled_work(); |
|---|
| 325 | | - /* pass one: without sleeping, do aoedev_downdev */ |
|---|
| 326 | + /* pass one: do aoedev_downdev, which might sleep */ |
|---|
| 327 | +restart1: |
|---|
| 326 | 328 | spin_lock_irqsave(&devlist_lock, flags); |
|---|
| 327 | 329 | for (d = devlist; d; d = d->next) { |
|---|
| 328 | 330 | spin_lock(&d->lock); |
|---|
| 331 | + if (d->flags & DEVFL_TKILL) |
|---|
| 332 | + goto cont; |
|---|
| 333 | + |
|---|
| 329 | 334 | if (exiting) { |
|---|
| 330 | 335 | /* unconditionally take each device down */ |
|---|
| 331 | 336 | } else if (specified) { |
|---|
| .. | .. |
|---|
| 337 | 342 | || d->ref) |
|---|
| 338 | 343 | goto cont; |
|---|
| 339 | 344 | |
|---|
| 345 | + spin_unlock(&d->lock); |
|---|
| 346 | + spin_unlock_irqrestore(&devlist_lock, flags); |
|---|
| 340 | 347 | aoedev_downdev(d); |
|---|
| 341 | 348 | d->flags |= DEVFL_TKILL; |
|---|
| 349 | + goto restart1; |
|---|
| 342 | 350 | cont: |
|---|
| 343 | 351 | spin_unlock(&d->lock); |
|---|
| 344 | 352 | } |
|---|
| .. | .. |
|---|
| 347 | 355 | /* pass two: call freedev, which might sleep, |
|---|
| 348 | 356 | * for aoedevs marked with DEVFL_TKILL |
|---|
| 349 | 357 | */ |
|---|
| 350 | | -restart: |
|---|
| 358 | +restart2: |
|---|
| 351 | 359 | spin_lock_irqsave(&devlist_lock, flags); |
|---|
| 352 | 360 | for (d = devlist; d; d = d->next) { |
|---|
| 353 | 361 | spin_lock(&d->lock); |
|---|
| .. | .. |
|---|
| 356 | 364 | spin_unlock(&d->lock); |
|---|
| 357 | 365 | spin_unlock_irqrestore(&devlist_lock, flags); |
|---|
| 358 | 366 | freedev(d); |
|---|
| 359 | | - goto restart; |
|---|
| 367 | + goto restart2; |
|---|
| 360 | 368 | } |
|---|
| 361 | 369 | spin_unlock(&d->lock); |
|---|
| 362 | 370 | } |
|---|
| .. | .. |
|---|
| 464 | 472 | d->ntargets = NTARGETS; |
|---|
| 465 | 473 | INIT_WORK(&d->work, aoecmd_sleepwork); |
|---|
| 466 | 474 | spin_lock_init(&d->lock); |
|---|
| 475 | + INIT_LIST_HEAD(&d->rq_list); |
|---|
| 467 | 476 | skb_queue_head_init(&d->skbpool); |
|---|
| 468 | 477 | timer_setup(&d->timer, dummy_timer, 0); |
|---|
| 469 | 478 | d->timer.expires = jiffies + HZ; |
|---|