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

Merge branch 'for-6.13/block-atomic' into for-6.13/block

Merge in block/fs prep patches for the atomic write support.

* for-6.13/block-atomic:
block: Add bdev atomic write limits helpers
fs/block: Check for IOCB_DIRECT in generic_atomic_write_valid()
block/fs: Pass an iocb to generic_atomic_write_valid()

+38 -17
+12 -10
block/fops.c
··· 35 35 return opf; 36 36 } 37 37 38 - static bool blkdev_dio_invalid(struct block_device *bdev, loff_t pos, 39 - struct iov_iter *iter, bool is_atomic) 38 + static bool blkdev_dio_invalid(struct block_device *bdev, struct kiocb *iocb, 39 + struct iov_iter *iter) 40 40 { 41 - if (is_atomic && !generic_atomic_write_valid(iter, pos)) 42 - return true; 43 - 44 - return pos & (bdev_logical_block_size(bdev) - 1) || 41 + return iocb->ki_pos & (bdev_logical_block_size(bdev) - 1) || 45 42 !bdev_iter_is_aligned(bdev, iter); 46 43 } 47 44 ··· 365 368 static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter) 366 369 { 367 370 struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); 368 - bool is_atomic = iocb->ki_flags & IOCB_ATOMIC; 369 371 unsigned int nr_pages; 370 372 371 373 if (!iov_iter_count(iter)) 372 374 return 0; 373 375 374 - if (blkdev_dio_invalid(bdev, iocb->ki_pos, iter, is_atomic)) 376 + if (blkdev_dio_invalid(bdev, iocb, iter)) 375 377 return -EINVAL; 376 378 377 379 nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS + 1); ··· 379 383 return __blkdev_direct_IO_simple(iocb, iter, bdev, 380 384 nr_pages); 381 385 return __blkdev_direct_IO_async(iocb, iter, bdev, nr_pages); 382 - } else if (is_atomic) { 386 + } else if (iocb->ki_flags & IOCB_ATOMIC) { 383 387 return -EINVAL; 384 388 } 385 389 return __blkdev_direct_IO(iocb, iter, bdev, bio_max_segs(nr_pages)); ··· 621 625 if (!bdev) 622 626 return -ENXIO; 623 627 624 - if (bdev_can_atomic_write(bdev) && filp->f_flags & O_DIRECT) 628 + if (bdev_can_atomic_write(bdev)) 625 629 filp->f_mode |= FMODE_CAN_ATOMIC_WRITE; 626 630 627 631 ret = bdev_open(bdev, mode, filp->private_data, NULL, filp); ··· 695 699 696 700 if ((iocb->ki_flags & (IOCB_NOWAIT | IOCB_DIRECT)) == IOCB_NOWAIT) 697 701 return -EOPNOTSUPP; 702 + 703 + if (iocb->ki_flags & IOCB_ATOMIC) { 704 + ret = generic_atomic_write_valid(iocb, from); 705 + if (ret) 706 + return ret; 707 + } 698 708 699 709 size -= iocb->ki_pos; 700 710 if (iov_iter_count(from) > size) {
+9 -6
fs/read_write.c
··· 1830 1830 return 0; 1831 1831 } 1832 1832 1833 - bool generic_atomic_write_valid(struct iov_iter *iter, loff_t pos) 1833 + int generic_atomic_write_valid(struct kiocb *iocb, struct iov_iter *iter) 1834 1834 { 1835 1835 size_t len = iov_iter_count(iter); 1836 1836 1837 1837 if (!iter_is_ubuf(iter)) 1838 - return false; 1838 + return -EINVAL; 1839 1839 1840 1840 if (!is_power_of_2(len)) 1841 - return false; 1841 + return -EINVAL; 1842 1842 1843 - if (!IS_ALIGNED(pos, len)) 1844 - return false; 1843 + if (!IS_ALIGNED(iocb->ki_pos, len)) 1844 + return -EINVAL; 1845 1845 1846 - return true; 1846 + if (!(iocb->ki_flags & IOCB_DIRECT)) 1847 + return -EOPNOTSUPP; 1848 + 1849 + return 0; 1847 1850 }
+16
include/linux/blkdev.h
··· 1682 1682 return true; 1683 1683 } 1684 1684 1685 + static inline unsigned int 1686 + bdev_atomic_write_unit_min_bytes(struct block_device *bdev) 1687 + { 1688 + if (!bdev_can_atomic_write(bdev)) 1689 + return 0; 1690 + return queue_atomic_write_unit_min_bytes(bdev_get_queue(bdev)); 1691 + } 1692 + 1693 + static inline unsigned int 1694 + bdev_atomic_write_unit_max_bytes(struct block_device *bdev) 1695 + { 1696 + if (!bdev_can_atomic_write(bdev)) 1697 + return 0; 1698 + return queue_atomic_write_unit_max_bytes(bdev_get_queue(bdev)); 1699 + } 1700 + 1685 1701 #define DEFINE_IO_COMP_BATCH(name) struct io_comp_batch name = { } 1686 1702 1687 1703 #endif /* _LINUX_BLKDEV_H */
+1 -1
include/linux/fs.h
··· 3726 3726 return !c; 3727 3727 } 3728 3728 3729 - bool generic_atomic_write_valid(struct iov_iter *iter, loff_t pos); 3729 + int generic_atomic_write_valid(struct kiocb *iocb, struct iov_iter *iter); 3730 3730 3731 3731 #endif /* _LINUX_FS_H */