Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

block: add a store_limit operations for sysfs entries

De-duplicate the code for updating queue limits by adding a store_limit
method that allows having common code handle the actual queue limits
update.

Note that this is a pure refactoring patch and does not address the
existing freeze vs limits lock order problem in the refactored code,
which will be addressed next.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Link: https://lore.kernel.org/r/20250110054726.1499538-6-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Christoph Hellwig and committed by
Jens Axboe
a1623064 d432c817

+61 -67
+61 -67
block/blk-sysfs.c
··· 24 24 struct attribute attr; 25 25 ssize_t (*show)(struct gendisk *disk, char *page); 26 26 ssize_t (*store)(struct gendisk *disk, const char *page, size_t count); 27 + int (*store_limit)(struct gendisk *disk, const char *page, 28 + size_t count, struct queue_limits *lim); 27 29 void (*load_module)(struct gendisk *disk, const char *page, size_t count); 28 30 }; 29 31 ··· 155 153 QUEUE_SYSFS_SHOW_CONST(write_same_max, 0) 156 154 QUEUE_SYSFS_SHOW_CONST(poll_delay, -1) 157 155 158 - static ssize_t queue_max_discard_sectors_store(struct gendisk *disk, 159 - const char *page, size_t count) 156 + static int queue_max_discard_sectors_store(struct gendisk *disk, 157 + const char *page, size_t count, struct queue_limits *lim) 160 158 { 161 159 unsigned long max_discard_bytes; 162 - struct queue_limits lim; 163 160 ssize_t ret; 164 - int err; 165 161 166 162 ret = queue_var_store(&max_discard_bytes, page, count); 167 163 if (ret < 0) ··· 171 171 if ((max_discard_bytes >> SECTOR_SHIFT) > UINT_MAX) 172 172 return -EINVAL; 173 173 174 - lim = queue_limits_start_update(disk->queue); 175 - lim.max_user_discard_sectors = max_discard_bytes >> SECTOR_SHIFT; 176 - err = queue_limits_commit_update(disk->queue, &lim); 177 - if (err) 178 - return err; 179 - return ret; 174 + lim->max_user_discard_sectors = max_discard_bytes >> SECTOR_SHIFT; 175 + return 0; 180 176 } 181 177 182 - static ssize_t 183 - queue_max_sectors_store(struct gendisk *disk, const char *page, size_t count) 178 + static int 179 + queue_max_sectors_store(struct gendisk *disk, const char *page, size_t count, 180 + struct queue_limits *lim) 184 181 { 185 182 unsigned long max_sectors_kb; 186 - struct queue_limits lim; 187 183 ssize_t ret; 188 - int err; 189 184 190 185 ret = queue_var_store(&max_sectors_kb, page, count); 191 186 if (ret < 0) 192 187 return ret; 193 188 194 - lim = queue_limits_start_update(disk->queue); 195 - lim.max_user_sectors = max_sectors_kb << 1; 196 - err = queue_limits_commit_update(disk->queue, &lim); 197 - if (err) 198 - return err; 199 - return ret; 189 + lim->max_user_sectors = max_sectors_kb << 1; 190 + return 0; 200 191 } 201 192 202 193 static ssize_t queue_feature_store(struct gendisk *disk, const char *page, 203 - size_t count, blk_features_t feature) 194 + size_t count, struct queue_limits *lim, blk_features_t feature) 204 195 { 205 - struct queue_limits lim; 206 196 unsigned long val; 207 197 ssize_t ret; 208 198 ··· 200 210 if (ret < 0) 201 211 return ret; 202 212 203 - lim = queue_limits_start_update(disk->queue); 204 213 if (val) 205 - lim.features |= feature; 214 + lim->features |= feature; 206 215 else 207 - lim.features &= ~feature; 208 - ret = queue_limits_commit_update(disk->queue, &lim); 209 - if (ret) 210 - return ret; 211 - return count; 216 + lim->features &= ~feature; 217 + return 0; 212 218 } 213 219 214 220 #define QUEUE_SYSFS_FEATURE(_name, _feature) \ ··· 213 227 return sysfs_emit(page, "%u\n", \ 214 228 !!(disk->queue->limits.features & _feature)); \ 215 229 } \ 216 - static ssize_t queue_##_name##_store(struct gendisk *disk, \ 217 - const char *page, size_t count) \ 230 + static int queue_##_name##_store(struct gendisk *disk, \ 231 + const char *page, size_t count, struct queue_limits *lim) \ 218 232 { \ 219 - return queue_feature_store(disk, page, count, _feature); \ 233 + return queue_feature_store(disk, page, count, lim, _feature); \ 220 234 } 221 235 222 236 QUEUE_SYSFS_FEATURE(rotational, BLK_FEAT_ROTATIONAL) ··· 259 273 return queue_var_show(!!blk_queue_passthrough_stat(disk->queue), page); 260 274 } 261 275 262 - static ssize_t queue_iostats_passthrough_store(struct gendisk *disk, 263 - const char *page, size_t count) 276 + static int queue_iostats_passthrough_store(struct gendisk *disk, 277 + const char *page, size_t count, struct queue_limits *lim) 264 278 { 265 - struct queue_limits lim; 266 279 unsigned long ios; 267 280 ssize_t ret; 268 281 ··· 269 284 if (ret < 0) 270 285 return ret; 271 286 272 - lim = queue_limits_start_update(disk->queue); 273 287 if (ios) 274 - lim.flags |= BLK_FLAG_IOSTATS_PASSTHROUGH; 288 + lim->flags |= BLK_FLAG_IOSTATS_PASSTHROUGH; 275 289 else 276 - lim.flags &= ~BLK_FLAG_IOSTATS_PASSTHROUGH; 277 - 278 - ret = queue_limits_commit_update(disk->queue, &lim); 279 - if (ret) 280 - return ret; 281 - 282 - return count; 290 + lim->flags &= ~BLK_FLAG_IOSTATS_PASSTHROUGH; 291 + return 0; 283 292 } 293 + 284 294 static ssize_t queue_nomerges_show(struct gendisk *disk, char *page) 285 295 { 286 296 return queue_var_show((blk_queue_nomerges(disk->queue) << 1) | ··· 378 398 return sysfs_emit(page, "write through\n"); 379 399 } 380 400 381 - static ssize_t queue_wc_store(struct gendisk *disk, const char *page, 382 - size_t count) 401 + static int queue_wc_store(struct gendisk *disk, const char *page, 402 + size_t count, struct queue_limits *lim) 383 403 { 384 - struct queue_limits lim; 385 404 bool disable; 386 - int err; 387 405 388 406 if (!strncmp(page, "write back", 10)) { 389 407 disable = false; ··· 392 414 return -EINVAL; 393 415 } 394 416 395 - lim = queue_limits_start_update(disk->queue); 396 417 if (disable) 397 - lim.flags |= BLK_FLAG_WRITE_CACHE_DISABLED; 418 + lim->flags |= BLK_FLAG_WRITE_CACHE_DISABLED; 398 419 else 399 - lim.flags &= ~BLK_FLAG_WRITE_CACHE_DISABLED; 400 - err = queue_limits_commit_update(disk->queue, &lim); 401 - if (err) 402 - return err; 403 - return count; 420 + lim->flags &= ~BLK_FLAG_WRITE_CACHE_DISABLED; 421 + return 0; 404 422 } 405 423 406 424 #define QUEUE_RO_ENTRY(_prefix, _name) \ ··· 412 438 .store = _prefix##_store, \ 413 439 }; 414 440 441 + #define QUEUE_LIM_RW_ENTRY(_prefix, _name) \ 442 + static struct queue_sysfs_entry _prefix##_entry = { \ 443 + .attr = { .name = _name, .mode = 0644 }, \ 444 + .show = _prefix##_show, \ 445 + .store_limit = _prefix##_store, \ 446 + } 447 + 415 448 #define QUEUE_RW_LOAD_MODULE_ENTRY(_prefix, _name) \ 416 449 static struct queue_sysfs_entry _prefix##_entry = { \ 417 450 .attr = { .name = _name, .mode = 0644 }, \ ··· 429 448 430 449 QUEUE_RW_ENTRY(queue_requests, "nr_requests"); 431 450 QUEUE_RW_ENTRY(queue_ra, "read_ahead_kb"); 432 - QUEUE_RW_ENTRY(queue_max_sectors, "max_sectors_kb"); 451 + QUEUE_LIM_RW_ENTRY(queue_max_sectors, "max_sectors_kb"); 433 452 QUEUE_RO_ENTRY(queue_max_hw_sectors, "max_hw_sectors_kb"); 434 453 QUEUE_RO_ENTRY(queue_max_segments, "max_segments"); 435 454 QUEUE_RO_ENTRY(queue_max_integrity_segments, "max_integrity_segments"); ··· 445 464 QUEUE_RO_ENTRY(queue_max_discard_segments, "max_discard_segments"); 446 465 QUEUE_RO_ENTRY(queue_discard_granularity, "discard_granularity"); 447 466 QUEUE_RO_ENTRY(queue_max_hw_discard_sectors, "discard_max_hw_bytes"); 448 - QUEUE_RW_ENTRY(queue_max_discard_sectors, "discard_max_bytes"); 467 + QUEUE_LIM_RW_ENTRY(queue_max_discard_sectors, "discard_max_bytes"); 449 468 QUEUE_RO_ENTRY(queue_discard_zeroes_data, "discard_zeroes_data"); 450 469 451 470 QUEUE_RO_ENTRY(queue_atomic_write_max_sectors, "atomic_write_max_bytes"); ··· 465 484 QUEUE_RO_ENTRY(queue_max_active_zones, "max_active_zones"); 466 485 467 486 QUEUE_RW_ENTRY(queue_nomerges, "nomerges"); 468 - QUEUE_RW_ENTRY(queue_iostats_passthrough, "iostats_passthrough"); 487 + QUEUE_LIM_RW_ENTRY(queue_iostats_passthrough, "iostats_passthrough"); 469 488 QUEUE_RW_ENTRY(queue_rq_affinity, "rq_affinity"); 470 489 QUEUE_RW_ENTRY(queue_poll, "io_poll"); 471 490 QUEUE_RW_ENTRY(queue_poll_delay, "io_poll_delay"); 472 - QUEUE_RW_ENTRY(queue_wc, "write_cache"); 491 + QUEUE_LIM_RW_ENTRY(queue_wc, "write_cache"); 473 492 QUEUE_RO_ENTRY(queue_fua, "fua"); 474 493 QUEUE_RO_ENTRY(queue_dax, "dax"); 475 494 QUEUE_RW_ENTRY(queue_io_timeout, "io_timeout"); ··· 482 501 .show = queue_logical_block_size_show, 483 502 }; 484 503 485 - QUEUE_RW_ENTRY(queue_rotational, "rotational"); 486 - QUEUE_RW_ENTRY(queue_iostats, "iostats"); 487 - QUEUE_RW_ENTRY(queue_add_random, "add_random"); 488 - QUEUE_RW_ENTRY(queue_stable_writes, "stable_writes"); 504 + QUEUE_LIM_RW_ENTRY(queue_rotational, "rotational"); 505 + QUEUE_LIM_RW_ENTRY(queue_iostats, "iostats"); 506 + QUEUE_LIM_RW_ENTRY(queue_add_random, "add_random"); 507 + QUEUE_LIM_RW_ENTRY(queue_stable_writes, "stable_writes"); 489 508 490 509 #ifdef CONFIG_BLK_WBT 491 510 static ssize_t queue_var_store64(s64 *var, const char *page) ··· 683 702 struct request_queue *q = disk->queue; 684 703 ssize_t res; 685 704 686 - if (!entry->store) 705 + if (!entry->store_limit && !entry->store) 687 706 return -EIO; 688 707 689 708 /* ··· 694 713 if (entry->load_module) 695 714 entry->load_module(disk, page, length); 696 715 697 - blk_mq_freeze_queue(q); 698 716 mutex_lock(&q->sysfs_lock); 699 - res = entry->store(disk, page, length); 700 - mutex_unlock(&q->sysfs_lock); 717 + blk_mq_freeze_queue(q); 718 + if (entry->store_limit) { 719 + struct queue_limits lim = queue_limits_start_update(q); 720 + 721 + res = entry->store_limit(disk, page, length, &lim); 722 + if (res < 0) { 723 + queue_limits_cancel_update(q); 724 + } else { 725 + res = queue_limits_commit_update(q, &lim); 726 + if (!res) 727 + res = length; 728 + } 729 + } else { 730 + res = entry->store(disk, page, length); 731 + } 701 732 blk_mq_unfreeze_queue(q); 733 + mutex_unlock(&q->sysfs_lock); 702 734 return res; 703 735 } 704 736