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.

Merge tag 'zonefs-6.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs

Pull zonefs fix from Damien Le Moal:

- The switch to using iomap for executing a direct synchronous write to
sequential files using a zone append BIO overlooked cases where the
BIO built by iomap is too large and needs splitting, which is not
allowed with zone append.

Fix this by using regular write commands instead. The use of zone
append commands will be reintroduced later with proper support from
iomap.

* tag 'zonefs-6.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs:
zonefs: fix synchronous direct writes to sequential files

+4 -118
+3 -108
fs/zonefs/file.c
··· 341 341 return generic_file_llseek_size(file, offset, whence, isize, isize); 342 342 } 343 343 344 - struct zonefs_zone_append_bio { 345 - /* The target inode of the BIO */ 346 - struct inode *inode; 347 - 348 - /* For sync writes, the target append write offset */ 349 - u64 append_offset; 350 - 351 - /* 352 - * This member must come last, bio_alloc_bioset will allocate enough 353 - * bytes for entire zonefs_bio but relies on bio being last. 354 - */ 355 - struct bio bio; 356 - }; 357 - 358 - static inline struct zonefs_zone_append_bio * 359 - zonefs_zone_append_bio(struct bio *bio) 360 - { 361 - return container_of(bio, struct zonefs_zone_append_bio, bio); 362 - } 363 - 364 - static void zonefs_file_zone_append_dio_bio_end_io(struct bio *bio) 365 - { 366 - struct zonefs_zone_append_bio *za_bio = zonefs_zone_append_bio(bio); 367 - struct zonefs_zone *z = zonefs_inode_zone(za_bio->inode); 368 - sector_t za_sector; 369 - 370 - if (bio->bi_status != BLK_STS_OK) 371 - goto bio_end; 372 - 373 - /* 374 - * If the file zone was written underneath the file system, the zone 375 - * append operation can still succedd (if the zone is not full) but 376 - * the write append location will not be where we expect it to be. 377 - * Check that we wrote where we intended to, that is, at z->z_wpoffset. 378 - */ 379 - za_sector = z->z_sector + (za_bio->append_offset >> SECTOR_SHIFT); 380 - if (bio->bi_iter.bi_sector != za_sector) { 381 - zonefs_warn(za_bio->inode->i_sb, 382 - "Invalid write sector %llu for zone at %llu\n", 383 - bio->bi_iter.bi_sector, z->z_sector); 384 - bio->bi_status = BLK_STS_IOERR; 385 - } 386 - 387 - bio_end: 388 - iomap_dio_bio_end_io(bio); 389 - } 390 - 391 - static void zonefs_file_zone_append_dio_submit_io(const struct iomap_iter *iter, 392 - struct bio *bio, 393 - loff_t file_offset) 394 - { 395 - struct zonefs_zone_append_bio *za_bio = zonefs_zone_append_bio(bio); 396 - struct inode *inode = iter->inode; 397 - struct zonefs_zone *z = zonefs_inode_zone(inode); 398 - 399 - /* 400 - * Issue a zone append BIO to process sync dio writes. The append 401 - * file offset is saved to check the zone append write location 402 - * on completion of the BIO. 403 - */ 404 - za_bio->inode = inode; 405 - za_bio->append_offset = file_offset; 406 - 407 - bio->bi_opf &= ~REQ_OP_WRITE; 408 - bio->bi_opf |= REQ_OP_ZONE_APPEND; 409 - bio->bi_iter.bi_sector = z->z_sector; 410 - bio->bi_end_io = zonefs_file_zone_append_dio_bio_end_io; 411 - 412 - submit_bio(bio); 413 - } 414 - 415 344 static int zonefs_file_write_dio_end_io(struct kiocb *iocb, ssize_t size, 416 345 int error, unsigned int flags) 417 346 { ··· 370 441 371 442 return 0; 372 443 } 373 - 374 - static struct bio_set zonefs_zone_append_bio_set; 375 - 376 - static const struct iomap_dio_ops zonefs_zone_append_dio_ops = { 377 - .submit_io = zonefs_file_zone_append_dio_submit_io, 378 - .end_io = zonefs_file_write_dio_end_io, 379 - .bio_set = &zonefs_zone_append_bio_set, 380 - }; 381 444 382 445 static const struct iomap_dio_ops zonefs_write_dio_ops = { 383 446 .end_io = zonefs_file_write_dio_end_io, ··· 454 533 struct zonefs_inode_info *zi = ZONEFS_I(inode); 455 534 struct zonefs_zone *z = zonefs_inode_zone(inode); 456 535 struct super_block *sb = inode->i_sb; 457 - const struct iomap_dio_ops *dio_ops; 458 - bool sync = is_sync_kiocb(iocb); 459 - bool append = false; 460 536 ssize_t ret, count; 461 537 462 538 /* ··· 461 543 * as this can cause write reordering (e.g. the first aio gets EAGAIN 462 544 * on the inode lock but the second goes through but is now unaligned). 463 545 */ 464 - if (zonefs_zone_is_seq(z) && !sync && (iocb->ki_flags & IOCB_NOWAIT)) 546 + if (zonefs_zone_is_seq(z) && !is_sync_kiocb(iocb) && 547 + (iocb->ki_flags & IOCB_NOWAIT)) 465 548 return -EOPNOTSUPP; 466 549 467 550 if (iocb->ki_flags & IOCB_NOWAIT) { ··· 492 573 goto inode_unlock; 493 574 } 494 575 mutex_unlock(&zi->i_truncate_mutex); 495 - append = sync; 496 - } 497 - 498 - if (append) { 499 - unsigned int max = bdev_max_zone_append_sectors(sb->s_bdev); 500 - 501 - max = ALIGN_DOWN(max << SECTOR_SHIFT, sb->s_blocksize); 502 - iov_iter_truncate(from, max); 503 - 504 - dio_ops = &zonefs_zone_append_dio_ops; 505 - } else { 506 - dio_ops = &zonefs_write_dio_ops; 507 576 } 508 577 509 578 /* ··· 500 593 * the user can make sense of the error. 501 594 */ 502 595 ret = iomap_dio_rw(iocb, from, &zonefs_write_iomap_ops, 503 - dio_ops, 0, NULL, 0); 596 + &zonefs_write_dio_ops, 0, NULL, 0); 504 597 if (ret == -ENOTBLK) 505 598 ret = -EBUSY; 506 599 ··· 845 938 .splice_write = iter_file_splice_write, 846 939 .iopoll = iocb_bio_iopoll, 847 940 }; 848 - 849 - int zonefs_file_bioset_init(void) 850 - { 851 - return bioset_init(&zonefs_zone_append_bio_set, BIO_POOL_SIZE, 852 - offsetof(struct zonefs_zone_append_bio, bio), 853 - BIOSET_NEED_BVECS); 854 - } 855 - 856 - void zonefs_file_bioset_exit(void) 857 - { 858 - bioset_exit(&zonefs_zone_append_bio_set); 859 - }
+1 -8
fs/zonefs/super.c
··· 1412 1412 1413 1413 BUILD_BUG_ON(sizeof(struct zonefs_super) != ZONEFS_SUPER_SIZE); 1414 1414 1415 - ret = zonefs_file_bioset_init(); 1416 - if (ret) 1417 - return ret; 1418 - 1419 1415 ret = zonefs_init_inodecache(); 1420 1416 if (ret) 1421 - goto destroy_bioset; 1417 + return ret; 1422 1418 1423 1419 ret = zonefs_sysfs_init(); 1424 1420 if (ret) ··· 1430 1434 zonefs_sysfs_exit(); 1431 1435 destroy_inodecache: 1432 1436 zonefs_destroy_inodecache(); 1433 - destroy_bioset: 1434 - zonefs_file_bioset_exit(); 1435 1437 1436 1438 return ret; 1437 1439 } ··· 1439 1445 unregister_filesystem(&zonefs_type); 1440 1446 zonefs_sysfs_exit(); 1441 1447 zonefs_destroy_inodecache(); 1442 - zonefs_file_bioset_exit(); 1443 1448 } 1444 1449 1445 1450 MODULE_AUTHOR("Damien Le Moal");
-2
fs/zonefs/zonefs.h
··· 279 279 extern const struct address_space_operations zonefs_file_aops; 280 280 extern const struct file_operations zonefs_file_operations; 281 281 int zonefs_file_truncate(struct inode *inode, loff_t isize); 282 - int zonefs_file_bioset_init(void); 283 - void zonefs_file_bioset_exit(void); 284 282 285 283 /* In sysfs.c */ 286 284 int zonefs_sysfs_register(struct super_block *sb);