2323struct queue_sysfs_entry {
2424 struct attribute attr ;
2525 ssize_t (* show )(struct gendisk * disk , char * page );
26+ ssize_t (* show_limit )(struct gendisk * disk , char * page );
27+
2628 ssize_t (* store )(struct gendisk * disk , const char * page , size_t count );
2729 int (* store_limit )(struct gendisk * disk , const char * page ,
2830 size_t count , struct queue_limits * lim );
31+
2932 void (* load_module )(struct gendisk * disk , const char * page , size_t count );
3033};
3134
@@ -412,10 +415,16 @@ static struct queue_sysfs_entry _prefix##_entry = { \
412415 .store = _prefix##_store, \
413416};
414417
418+ #define QUEUE_LIM_RO_ENTRY (_prefix , _name ) \
419+ static struct queue_sysfs_entry _prefix##_entry = { \
420+ .attr = { .name = _name, .mode = 0444 }, \
421+ .show_limit = _prefix##_show, \
422+ }
423+
415424#define QUEUE_LIM_RW_ENTRY (_prefix , _name ) \
416425static struct queue_sysfs_entry _prefix##_entry = { \
417426 .attr = { .name = _name, .mode = 0644 }, \
418- .show = _prefix##_show, \
427+ .show_limit = _prefix##_show, \
419428 .store_limit = _prefix##_store, \
420429}
421430
@@ -430,56 +439,56 @@ static struct queue_sysfs_entry _prefix##_entry = { \
430439QUEUE_RW_ENTRY (queue_requests , "nr_requests" );
431440QUEUE_RW_ENTRY (queue_ra , "read_ahead_kb" );
432441QUEUE_LIM_RW_ENTRY (queue_max_sectors , "max_sectors_kb" );
433- QUEUE_RO_ENTRY (queue_max_hw_sectors , "max_hw_sectors_kb" );
434- QUEUE_RO_ENTRY (queue_max_segments , "max_segments" );
435- QUEUE_RO_ENTRY (queue_max_integrity_segments , "max_integrity_segments" );
436- QUEUE_RO_ENTRY (queue_max_segment_size , "max_segment_size" );
442+ QUEUE_LIM_RO_ENTRY (queue_max_hw_sectors , "max_hw_sectors_kb" );
443+ QUEUE_LIM_RO_ENTRY (queue_max_segments , "max_segments" );
444+ QUEUE_LIM_RO_ENTRY (queue_max_integrity_segments , "max_integrity_segments" );
445+ QUEUE_LIM_RO_ENTRY (queue_max_segment_size , "max_segment_size" );
437446QUEUE_RW_LOAD_MODULE_ENTRY (elv_iosched , "scheduler" );
438447
439- QUEUE_RO_ENTRY (queue_logical_block_size , "logical_block_size" );
440- QUEUE_RO_ENTRY (queue_physical_block_size , "physical_block_size" );
441- QUEUE_RO_ENTRY (queue_chunk_sectors , "chunk_sectors" );
442- QUEUE_RO_ENTRY (queue_io_min , "minimum_io_size" );
443- QUEUE_RO_ENTRY (queue_io_opt , "optimal_io_size" );
448+ QUEUE_LIM_RO_ENTRY (queue_logical_block_size , "logical_block_size" );
449+ QUEUE_LIM_RO_ENTRY (queue_physical_block_size , "physical_block_size" );
450+ QUEUE_LIM_RO_ENTRY (queue_chunk_sectors , "chunk_sectors" );
451+ QUEUE_LIM_RO_ENTRY (queue_io_min , "minimum_io_size" );
452+ QUEUE_LIM_RO_ENTRY (queue_io_opt , "optimal_io_size" );
444453
445- QUEUE_RO_ENTRY (queue_max_discard_segments , "max_discard_segments" );
446- QUEUE_RO_ENTRY (queue_discard_granularity , "discard_granularity" );
447- QUEUE_RO_ENTRY (queue_max_hw_discard_sectors , "discard_max_hw_bytes" );
454+ QUEUE_LIM_RO_ENTRY (queue_max_discard_segments , "max_discard_segments" );
455+ QUEUE_LIM_RO_ENTRY (queue_discard_granularity , "discard_granularity" );
456+ QUEUE_LIM_RO_ENTRY (queue_max_hw_discard_sectors , "discard_max_hw_bytes" );
448457QUEUE_LIM_RW_ENTRY (queue_max_discard_sectors , "discard_max_bytes" );
449458QUEUE_RO_ENTRY (queue_discard_zeroes_data , "discard_zeroes_data" );
450459
451- QUEUE_RO_ENTRY (queue_atomic_write_max_sectors , "atomic_write_max_bytes" );
452- QUEUE_RO_ENTRY (queue_atomic_write_boundary_sectors ,
460+ QUEUE_LIM_RO_ENTRY (queue_atomic_write_max_sectors , "atomic_write_max_bytes" );
461+ QUEUE_LIM_RO_ENTRY (queue_atomic_write_boundary_sectors ,
453462 "atomic_write_boundary_bytes" );
454- QUEUE_RO_ENTRY (queue_atomic_write_unit_max , "atomic_write_unit_max_bytes" );
455- QUEUE_RO_ENTRY (queue_atomic_write_unit_min , "atomic_write_unit_min_bytes" );
463+ QUEUE_LIM_RO_ENTRY (queue_atomic_write_unit_max , "atomic_write_unit_max_bytes" );
464+ QUEUE_LIM_RO_ENTRY (queue_atomic_write_unit_min , "atomic_write_unit_min_bytes" );
456465
457466QUEUE_RO_ENTRY (queue_write_same_max , "write_same_max_bytes" );
458- QUEUE_RO_ENTRY (queue_max_write_zeroes_sectors , "write_zeroes_max_bytes" );
459- QUEUE_RO_ENTRY (queue_max_zone_append_sectors , "zone_append_max_bytes" );
460- QUEUE_RO_ENTRY (queue_zone_write_granularity , "zone_write_granularity" );
467+ QUEUE_LIM_RO_ENTRY (queue_max_write_zeroes_sectors , "write_zeroes_max_bytes" );
468+ QUEUE_LIM_RO_ENTRY (queue_max_zone_append_sectors , "zone_append_max_bytes" );
469+ QUEUE_LIM_RO_ENTRY (queue_zone_write_granularity , "zone_write_granularity" );
461470
462- QUEUE_RO_ENTRY (queue_zoned , "zoned" );
471+ QUEUE_LIM_RO_ENTRY (queue_zoned , "zoned" );
463472QUEUE_RO_ENTRY (queue_nr_zones , "nr_zones" );
464- QUEUE_RO_ENTRY (queue_max_open_zones , "max_open_zones" );
465- QUEUE_RO_ENTRY (queue_max_active_zones , "max_active_zones" );
473+ QUEUE_LIM_RO_ENTRY (queue_max_open_zones , "max_open_zones" );
474+ QUEUE_LIM_RO_ENTRY (queue_max_active_zones , "max_active_zones" );
466475
467476QUEUE_RW_ENTRY (queue_nomerges , "nomerges" );
468477QUEUE_LIM_RW_ENTRY (queue_iostats_passthrough , "iostats_passthrough" );
469478QUEUE_RW_ENTRY (queue_rq_affinity , "rq_affinity" );
470479QUEUE_RW_ENTRY (queue_poll , "io_poll" );
471480QUEUE_RW_ENTRY (queue_poll_delay , "io_poll_delay" );
472481QUEUE_LIM_RW_ENTRY (queue_wc , "write_cache" );
473- QUEUE_RO_ENTRY (queue_fua , "fua" );
474- QUEUE_RO_ENTRY (queue_dax , "dax" );
482+ QUEUE_LIM_RO_ENTRY (queue_fua , "fua" );
483+ QUEUE_LIM_RO_ENTRY (queue_dax , "dax" );
475484QUEUE_RW_ENTRY (queue_io_timeout , "io_timeout" );
476- QUEUE_RO_ENTRY (queue_virt_boundary_mask , "virt_boundary_mask" );
477- QUEUE_RO_ENTRY (queue_dma_alignment , "dma_alignment" );
485+ QUEUE_LIM_RO_ENTRY (queue_virt_boundary_mask , "virt_boundary_mask" );
486+ QUEUE_LIM_RO_ENTRY (queue_dma_alignment , "dma_alignment" );
478487
479488/* legacy alias for logical_block_size: */
480489static struct queue_sysfs_entry queue_hw_sector_size_entry = {
481- .attr = {.name = "hw_sector_size" , .mode = 0444 },
482- .show = queue_logical_block_size_show ,
490+ .attr = {.name = "hw_sector_size" , .mode = 0444 },
491+ .show_limit = queue_logical_block_size_show ,
483492};
484493
485494QUEUE_LIM_RW_ENTRY (queue_rotational , "rotational" );
@@ -561,7 +570,9 @@ QUEUE_RW_ENTRY(queue_wb_lat, "wbt_lat_usec");
561570
562571/* Common attributes for bio-based and request-based queues. */
563572static struct attribute * queue_attrs [] = {
564- & queue_ra_entry .attr ,
573+ /*
574+ * Attributes which are protected with q->limits_lock.
575+ */
565576 & queue_max_hw_sectors_entry .attr ,
566577 & queue_max_sectors_entry .attr ,
567578 & queue_max_segments_entry .attr ,
@@ -577,37 +588,46 @@ static struct attribute *queue_attrs[] = {
577588 & queue_discard_granularity_entry .attr ,
578589 & queue_max_discard_sectors_entry .attr ,
579590 & queue_max_hw_discard_sectors_entry .attr ,
580- & queue_discard_zeroes_data_entry .attr ,
581591 & queue_atomic_write_max_sectors_entry .attr ,
582592 & queue_atomic_write_boundary_sectors_entry .attr ,
583593 & queue_atomic_write_unit_min_entry .attr ,
584594 & queue_atomic_write_unit_max_entry .attr ,
585- & queue_write_same_max_entry .attr ,
586595 & queue_max_write_zeroes_sectors_entry .attr ,
587596 & queue_max_zone_append_sectors_entry .attr ,
588597 & queue_zone_write_granularity_entry .attr ,
589598 & queue_rotational_entry .attr ,
590599 & queue_zoned_entry .attr ,
591- & queue_nr_zones_entry .attr ,
592600 & queue_max_open_zones_entry .attr ,
593601 & queue_max_active_zones_entry .attr ,
594- & queue_nomerges_entry .attr ,
595602 & queue_iostats_passthrough_entry .attr ,
596603 & queue_iostats_entry .attr ,
597604 & queue_stable_writes_entry .attr ,
598605 & queue_add_random_entry .attr ,
599- & queue_poll_entry .attr ,
600606 & queue_wc_entry .attr ,
601607 & queue_fua_entry .attr ,
602608 & queue_dax_entry .attr ,
603- & queue_poll_delay_entry .attr ,
604609 & queue_virt_boundary_mask_entry .attr ,
605610 & queue_dma_alignment_entry .attr ,
611+
612+ /*
613+ * Attributes which are protected with q->sysfs_lock.
614+ */
615+ & queue_ra_entry .attr ,
616+ & queue_discard_zeroes_data_entry .attr ,
617+ & queue_write_same_max_entry .attr ,
618+ & queue_nr_zones_entry .attr ,
619+ & queue_nomerges_entry .attr ,
620+ & queue_poll_entry .attr ,
621+ & queue_poll_delay_entry .attr ,
622+
606623 NULL ,
607624};
608625
609626/* Request-based queue attributes that are not relevant for bio-based queues. */
610627static struct attribute * blk_mq_queue_attrs [] = {
628+ /*
629+ * Attributes which are protected with q->sysfs_lock.
630+ */
611631 & queue_requests_entry .attr ,
612632 & elv_iosched_entry .attr ,
613633 & queue_rq_affinity_entry .attr ,
@@ -666,8 +686,16 @@ queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
666686 struct gendisk * disk = container_of (kobj , struct gendisk , queue_kobj );
667687 ssize_t res ;
668688
669- if (!entry -> show )
689+ if (!entry -> show && ! entry -> show_limit )
670690 return - EIO ;
691+
692+ if (entry -> show_limit ) {
693+ mutex_lock (& disk -> queue -> limits_lock );
694+ res = entry -> show_limit (disk , page );
695+ mutex_unlock (& disk -> queue -> limits_lock );
696+ return res ;
697+ }
698+
671699 mutex_lock (& disk -> queue -> sysfs_lock );
672700 res = entry -> show (disk , page );
673701 mutex_unlock (& disk -> queue -> sysfs_lock );
0 commit comments