| .. | .. |
|---|
| 6 | 6 | |
|---|
| 7 | 7 | #include <linux/kernel.h> |
|---|
| 8 | 8 | #include <linux/hdreg.h> |
|---|
| 9 | | -#include <linux/blkdev.h> |
|---|
| 9 | +#include <linux/blk-mq.h> |
|---|
| 10 | 10 | #include <linux/backing-dev.h> |
|---|
| 11 | 11 | #include <linux/fs.h> |
|---|
| 12 | 12 | #include <linux/ioctl.h> |
|---|
| .. | .. |
|---|
| 87 | 87 | if (*nd == NULL) |
|---|
| 88 | 88 | return snprintf(page, PAGE_SIZE, "none\n"); |
|---|
| 89 | 89 | for (p = page; nd < ne; nd++) |
|---|
| 90 | | - p += snprintf(p, PAGE_SIZE - (p-page), "%s%s", |
|---|
| 90 | + p += scnprintf(p, PAGE_SIZE - (p-page), "%s%s", |
|---|
| 91 | 91 | p == page ? "" : ",", (*nd)->name); |
|---|
| 92 | | - p += snprintf(p, PAGE_SIZE - (p-page), "\n"); |
|---|
| 92 | + p += scnprintf(p, PAGE_SIZE - (p-page), "\n"); |
|---|
| 93 | 93 | return p-page; |
|---|
| 94 | 94 | } |
|---|
| 95 | 95 | /* firmware version */ |
|---|
| .. | .. |
|---|
| 177 | 177 | NULL, |
|---|
| 178 | 178 | }; |
|---|
| 179 | 179 | |
|---|
| 180 | | -static const struct attribute_group attr_group = { |
|---|
| 180 | +static const struct attribute_group aoe_attr_group = { |
|---|
| 181 | 181 | .attrs = aoe_attrs, |
|---|
| 182 | +}; |
|---|
| 183 | + |
|---|
| 184 | +static const struct attribute_group *aoe_attr_groups[] = { |
|---|
| 185 | + &aoe_attr_group, |
|---|
| 186 | + NULL, |
|---|
| 182 | 187 | }; |
|---|
| 183 | 188 | |
|---|
| 184 | 189 | static const struct file_operations aoe_debugfs_fops = { |
|---|
| .. | .. |
|---|
| 191 | 196 | static void |
|---|
| 192 | 197 | aoedisk_add_debugfs(struct aoedev *d) |
|---|
| 193 | 198 | { |
|---|
| 194 | | - struct dentry *entry; |
|---|
| 195 | 199 | char *p; |
|---|
| 196 | 200 | |
|---|
| 197 | 201 | if (aoe_debugfs_dir == NULL) |
|---|
| .. | .. |
|---|
| 202 | 206 | else |
|---|
| 203 | 207 | p++; |
|---|
| 204 | 208 | BUG_ON(*p == '\0'); |
|---|
| 205 | | - entry = debugfs_create_file(p, 0444, aoe_debugfs_dir, d, |
|---|
| 206 | | - &aoe_debugfs_fops); |
|---|
| 207 | | - if (IS_ERR_OR_NULL(entry)) { |
|---|
| 208 | | - pr_info("aoe: cannot create debugfs file for %s\n", |
|---|
| 209 | | - d->gd->disk_name); |
|---|
| 210 | | - return; |
|---|
| 211 | | - } |
|---|
| 212 | | - BUG_ON(d->debugfs); |
|---|
| 213 | | - d->debugfs = entry; |
|---|
| 209 | + d->debugfs = debugfs_create_file(p, 0444, aoe_debugfs_dir, d, |
|---|
| 210 | + &aoe_debugfs_fops); |
|---|
| 214 | 211 | } |
|---|
| 215 | 212 | void |
|---|
| 216 | 213 | aoedisk_rm_debugfs(struct aoedev *d) |
|---|
| 217 | 214 | { |
|---|
| 218 | 215 | debugfs_remove(d->debugfs); |
|---|
| 219 | 216 | d->debugfs = NULL; |
|---|
| 220 | | -} |
|---|
| 221 | | - |
|---|
| 222 | | -static int |
|---|
| 223 | | -aoedisk_add_sysfs(struct aoedev *d) |
|---|
| 224 | | -{ |
|---|
| 225 | | - return sysfs_create_group(&disk_to_dev(d->gd)->kobj, &attr_group); |
|---|
| 226 | | -} |
|---|
| 227 | | -void |
|---|
| 228 | | -aoedisk_rm_sysfs(struct aoedev *d) |
|---|
| 229 | | -{ |
|---|
| 230 | | - sysfs_remove_group(&disk_to_dev(d->gd)->kobj, &attr_group); |
|---|
| 231 | 217 | } |
|---|
| 232 | 218 | |
|---|
| 233 | 219 | static int |
|---|
| .. | .. |
|---|
| 274 | 260 | spin_unlock_irqrestore(&d->lock, flags); |
|---|
| 275 | 261 | } |
|---|
| 276 | 262 | |
|---|
| 277 | | -static void |
|---|
| 278 | | -aoeblk_request(struct request_queue *q) |
|---|
| 263 | +static blk_status_t aoeblk_queue_rq(struct blk_mq_hw_ctx *hctx, |
|---|
| 264 | + const struct blk_mq_queue_data *bd) |
|---|
| 279 | 265 | { |
|---|
| 280 | | - struct aoedev *d; |
|---|
| 281 | | - struct request *rq; |
|---|
| 266 | + struct aoedev *d = hctx->queue->queuedata; |
|---|
| 282 | 267 | |
|---|
| 283 | | - d = q->queuedata; |
|---|
| 268 | + spin_lock_irq(&d->lock); |
|---|
| 269 | + |
|---|
| 284 | 270 | if ((d->flags & DEVFL_UP) == 0) { |
|---|
| 285 | 271 | pr_info_ratelimited("aoe: device %ld.%d is not up\n", |
|---|
| 286 | 272 | d->aoemajor, d->aoeminor); |
|---|
| 287 | | - while ((rq = blk_peek_request(q))) { |
|---|
| 288 | | - blk_start_request(rq); |
|---|
| 289 | | - aoe_end_request(d, rq, 1); |
|---|
| 290 | | - } |
|---|
| 291 | | - return; |
|---|
| 273 | + spin_unlock_irq(&d->lock); |
|---|
| 274 | + blk_mq_start_request(bd->rq); |
|---|
| 275 | + return BLK_STS_IOERR; |
|---|
| 292 | 276 | } |
|---|
| 277 | + |
|---|
| 278 | + list_add_tail(&bd->rq->queuelist, &d->rq_list); |
|---|
| 293 | 279 | aoecmd_work(d); |
|---|
| 280 | + spin_unlock_irq(&d->lock); |
|---|
| 281 | + return BLK_STS_OK; |
|---|
| 294 | 282 | } |
|---|
| 295 | 283 | |
|---|
| 296 | 284 | static int |
|---|
| .. | .. |
|---|
| 341 | 329 | .open = aoeblk_open, |
|---|
| 342 | 330 | .release = aoeblk_release, |
|---|
| 343 | 331 | .ioctl = aoeblk_ioctl, |
|---|
| 332 | + .compat_ioctl = blkdev_compat_ptr_ioctl, |
|---|
| 344 | 333 | .getgeo = aoeblk_getgeo, |
|---|
| 345 | 334 | .owner = THIS_MODULE, |
|---|
| 335 | +}; |
|---|
| 336 | + |
|---|
| 337 | +static const struct blk_mq_ops aoeblk_mq_ops = { |
|---|
| 338 | + .queue_rq = aoeblk_queue_rq, |
|---|
| 346 | 339 | }; |
|---|
| 347 | 340 | |
|---|
| 348 | 341 | /* alloc_disk and add_disk can sleep */ |
|---|
| .. | .. |
|---|
| 353 | 346 | struct gendisk *gd; |
|---|
| 354 | 347 | mempool_t *mp; |
|---|
| 355 | 348 | struct request_queue *q; |
|---|
| 356 | | - enum { KB = 1024, MB = KB * KB, READ_AHEAD = 2 * MB, }; |
|---|
| 349 | + struct blk_mq_tag_set *set; |
|---|
| 357 | 350 | ulong flags; |
|---|
| 358 | 351 | int late = 0; |
|---|
| 352 | + int err; |
|---|
| 359 | 353 | |
|---|
| 360 | 354 | spin_lock_irqsave(&d->lock, flags); |
|---|
| 361 | 355 | if (d->flags & DEVFL_GDALLOC |
|---|
| .. | .. |
|---|
| 382 | 376 | d->aoemajor, d->aoeminor); |
|---|
| 383 | 377 | goto err_disk; |
|---|
| 384 | 378 | } |
|---|
| 385 | | - q = blk_init_queue(aoeblk_request, &d->lock); |
|---|
| 386 | | - if (q == NULL) { |
|---|
| 379 | + |
|---|
| 380 | + set = &d->tag_set; |
|---|
| 381 | + set->ops = &aoeblk_mq_ops; |
|---|
| 382 | + set->cmd_size = sizeof(struct aoe_req); |
|---|
| 383 | + set->nr_hw_queues = 1; |
|---|
| 384 | + set->queue_depth = 128; |
|---|
| 385 | + set->numa_node = NUMA_NO_NODE; |
|---|
| 386 | + set->flags = BLK_MQ_F_SHOULD_MERGE; |
|---|
| 387 | + err = blk_mq_alloc_tag_set(set); |
|---|
| 388 | + if (err) { |
|---|
| 389 | + pr_err("aoe: cannot allocate tag set for %ld.%d\n", |
|---|
| 390 | + d->aoemajor, d->aoeminor); |
|---|
| 391 | + goto err_mempool; |
|---|
| 392 | + } |
|---|
| 393 | + |
|---|
| 394 | + q = blk_mq_init_queue(set); |
|---|
| 395 | + if (IS_ERR(q)) { |
|---|
| 387 | 396 | pr_err("aoe: cannot allocate block queue for %ld.%d\n", |
|---|
| 388 | 397 | d->aoemajor, d->aoeminor); |
|---|
| 398 | + blk_mq_free_tag_set(set); |
|---|
| 389 | 399 | goto err_mempool; |
|---|
| 390 | 400 | } |
|---|
| 391 | 401 | |
|---|
| .. | .. |
|---|
| 396 | 406 | WARN_ON(d->gd); |
|---|
| 397 | 407 | WARN_ON(d->flags & DEVFL_UP); |
|---|
| 398 | 408 | blk_queue_max_hw_sectors(q, BLK_DEF_MAX_SECTORS); |
|---|
| 399 | | - q->backing_dev_info->name = "aoe"; |
|---|
| 400 | | - q->backing_dev_info->ra_pages = READ_AHEAD / PAGE_SIZE; |
|---|
| 409 | + blk_queue_io_opt(q, SZ_2M); |
|---|
| 401 | 410 | d->bufpool = mp; |
|---|
| 402 | 411 | d->blkq = gd->queue = q; |
|---|
| 403 | 412 | q->queuedata = d; |
|---|
| .. | .. |
|---|
| 417 | 426 | |
|---|
| 418 | 427 | spin_unlock_irqrestore(&d->lock, flags); |
|---|
| 419 | 428 | |
|---|
| 420 | | - add_disk(gd); |
|---|
| 421 | | - aoedisk_add_sysfs(d); |
|---|
| 429 | + device_add_disk(NULL, gd, aoe_attr_groups); |
|---|
| 422 | 430 | aoedisk_add_debugfs(d); |
|---|
| 423 | 431 | |
|---|
| 424 | 432 | spin_lock_irqsave(&d->lock, flags); |
|---|
| .. | .. |
|---|
| 455 | 463 | if (buf_pool_cache == NULL) |
|---|
| 456 | 464 | return -ENOMEM; |
|---|
| 457 | 465 | aoe_debugfs_dir = debugfs_create_dir("aoe", NULL); |
|---|
| 458 | | - if (IS_ERR_OR_NULL(aoe_debugfs_dir)) { |
|---|
| 459 | | - pr_info("aoe: cannot create debugfs directory\n"); |
|---|
| 460 | | - aoe_debugfs_dir = NULL; |
|---|
| 461 | | - } |
|---|
| 462 | 466 | return 0; |
|---|
| 463 | 467 | } |
|---|
| 464 | 468 | |
|---|