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: relax atomic write boundary vs chunk size check

blk_validate_atomic_write_limits() ensures that any boundary fits into
and is aligned to any chunk size.

However, it should also be possible to fit the chunk size into any
boundary. That check is already made in
blk_stack_atomic_writes_boundary_head().

Relax the check in blk_validate_atomic_write_limits() by reusing (and
renaming) blk_stack_atomic_writes_boundary_head().

Signed-off-by: John Garry <john.g.garry@oracle.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

John Garry and committed by
Jens Axboe
da7b97ba f2d8c5a2

+26 -40
+26 -40
block/blk-settings.c
··· 224 224 lim->atomic_write_hw_boundary >> SECTOR_SHIFT; 225 225 } 226 226 227 + /* 228 + * Test whether any boundary is aligned with any chunk size. Stacked 229 + * devices store any stripe size in t->chunk_sectors. 230 + */ 231 + static bool blk_valid_atomic_writes_boundary(unsigned int chunk_sectors, 232 + unsigned int boundary_sectors) 233 + { 234 + if (!chunk_sectors || !boundary_sectors) 235 + return true; 236 + 237 + if (boundary_sectors > chunk_sectors && 238 + boundary_sectors % chunk_sectors) 239 + return false; 240 + 241 + if (chunk_sectors > boundary_sectors && 242 + chunk_sectors % boundary_sectors) 243 + return false; 244 + 245 + return true; 246 + } 247 + 227 248 static void blk_validate_atomic_write_limits(struct queue_limits *lim) 228 249 { 229 250 unsigned int boundary_sectors; ··· 285 264 if (WARN_ON_ONCE(lim->atomic_write_hw_max > 286 265 lim->atomic_write_hw_boundary)) 287 266 goto unsupported; 288 - /* 289 - * A feature of boundary support is that it disallows bios to 290 - * be merged which would result in a merged request which 291 - * crosses either a chunk sector or atomic write HW boundary, 292 - * even though chunk sectors may be just set for performance. 293 - * For simplicity, disallow atomic writes for a chunk sector 294 - * which is non-zero and smaller than atomic write HW boundary. 295 - * Furthermore, chunk sectors must be a multiple of atomic 296 - * write HW boundary. Otherwise boundary support becomes 297 - * complicated. 298 - * Devices which do not conform to these rules can be dealt 299 - * with if and when they show up. 300 - */ 301 - if (WARN_ON_ONCE(lim->chunk_sectors % boundary_sectors)) 267 + 268 + if (WARN_ON_ONCE(!blk_valid_atomic_writes_boundary( 269 + lim->chunk_sectors, boundary_sectors))) 302 270 goto unsupported; 303 271 304 272 /* ··· 654 644 return true; 655 645 } 656 646 657 - /* Check for valid boundary of first bottom device */ 658 - static bool blk_stack_atomic_writes_boundary_head(struct queue_limits *t, 659 - struct queue_limits *b) 660 - { 661 - unsigned int boundary_sectors; 662 - 663 - if (!b->atomic_write_hw_boundary || !t->chunk_sectors) 664 - return true; 665 - 666 - boundary_sectors = b->atomic_write_hw_boundary >> SECTOR_SHIFT; 667 - 668 - /* 669 - * Ensure atomic write boundary is aligned with chunk sectors. Stacked 670 - * devices store any stripe size in t->chunk_sectors. 671 - */ 672 - if (boundary_sectors > t->chunk_sectors && 673 - boundary_sectors % t->chunk_sectors) 674 - return false; 675 - if (t->chunk_sectors > boundary_sectors && 676 - t->chunk_sectors % boundary_sectors) 677 - return false; 678 - 679 - return true; 680 - } 681 - 682 647 static void blk_stack_atomic_writes_chunk_sectors(struct queue_limits *t) 683 648 { 684 649 unsigned int chunk_bytes; ··· 691 706 static bool blk_stack_atomic_writes_head(struct queue_limits *t, 692 707 struct queue_limits *b) 693 708 { 694 - if (!blk_stack_atomic_writes_boundary_head(t, b)) 709 + if (!blk_valid_atomic_writes_boundary(t->chunk_sectors, 710 + b->atomic_write_hw_boundary >> SECTOR_SHIFT)) 695 711 return false; 696 712 697 713 t->atomic_write_hw_unit_max = b->atomic_write_hw_unit_max;