|
23 | 23 | struct queue_sysfs_entry {
|
24 | 24 | struct attribute attr;
|
25 | 25 | ssize_t (*show)(struct gendisk *disk, char *page);
|
| 26 | + int (*load_module)(struct gendisk *disk, const char *page, size_t count); |
26 | 27 | ssize_t (*store)(struct gendisk *disk, const char *page, size_t count);
|
27 | 28 | };
|
28 | 29 |
|
@@ -413,14 +414,22 @@ static struct queue_sysfs_entry _prefix##_entry = { \
|
413 | 414 | .store = _prefix##_store, \
|
414 | 415 | };
|
415 | 416 |
|
| 417 | +#define QUEUE_RW_LOAD_MODULE_ENTRY(_prefix, _name) \ |
| 418 | +static struct queue_sysfs_entry _prefix##_entry = { \ |
| 419 | + .attr = { .name = _name, .mode = 0644 }, \ |
| 420 | + .show = _prefix##_show, \ |
| 421 | + .load_module = _prefix##_load_module, \ |
| 422 | + .store = _prefix##_store, \ |
| 423 | +} |
| 424 | + |
416 | 425 | QUEUE_RW_ENTRY(queue_requests, "nr_requests");
|
417 | 426 | QUEUE_RW_ENTRY(queue_ra, "read_ahead_kb");
|
418 | 427 | QUEUE_RW_ENTRY(queue_max_sectors, "max_sectors_kb");
|
419 | 428 | QUEUE_RO_ENTRY(queue_max_hw_sectors, "max_hw_sectors_kb");
|
420 | 429 | QUEUE_RO_ENTRY(queue_max_segments, "max_segments");
|
421 | 430 | QUEUE_RO_ENTRY(queue_max_integrity_segments, "max_integrity_segments");
|
422 | 431 | QUEUE_RO_ENTRY(queue_max_segment_size, "max_segment_size");
|
423 |
| -QUEUE_RW_ENTRY(elv_iosched, "scheduler"); |
| 432 | +QUEUE_RW_LOAD_MODULE_ENTRY(elv_iosched, "scheduler"); |
424 | 433 |
|
425 | 434 | QUEUE_RO_ENTRY(queue_logical_block_size, "logical_block_size");
|
426 | 435 | QUEUE_RO_ENTRY(queue_physical_block_size, "physical_block_size");
|
@@ -670,6 +679,17 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr,
|
670 | 679 | if (!entry->store)
|
671 | 680 | return -EIO;
|
672 | 681 |
|
| 682 | + /* |
| 683 | + * If the attribute needs to load a module, do it before freezing the |
| 684 | + * queue to ensure that the module file can be read when the request |
| 685 | + * queue is the one for the device storing the module file. |
| 686 | + */ |
| 687 | + if (entry->load_module) { |
| 688 | + res = entry->load_module(disk, page, length); |
| 689 | + if (res) |
| 690 | + return res; |
| 691 | + } |
| 692 | + |
673 | 693 | blk_mq_freeze_queue(q);
|
674 | 694 | mutex_lock(&q->sysfs_lock);
|
675 | 695 | res = entry->store(disk, page, length);
|
|
0 commit comments