mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
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()
This commit is contained in:
commit
fdad1a20cd
22
block/fops.c
22
block/fops.c
@ -35,13 +35,10 @@ static blk_opf_t dio_bio_write_op(struct kiocb *iocb)
|
|||||||
return opf;
|
return opf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool blkdev_dio_invalid(struct block_device *bdev, loff_t pos,
|
static bool blkdev_dio_invalid(struct block_device *bdev, struct kiocb *iocb,
|
||||||
struct iov_iter *iter, bool is_atomic)
|
struct iov_iter *iter)
|
||||||
{
|
{
|
||||||
if (is_atomic && !generic_atomic_write_valid(iter, pos))
|
return iocb->ki_pos & (bdev_logical_block_size(bdev) - 1) ||
|
||||||
return true;
|
|
||||||
|
|
||||||
return pos & (bdev_logical_block_size(bdev) - 1) ||
|
|
||||||
!bdev_iter_is_aligned(bdev, iter);
|
!bdev_iter_is_aligned(bdev, iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,13 +365,12 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb,
|
|||||||
static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
|
static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
|
||||||
{
|
{
|
||||||
struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
|
struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
|
||||||
bool is_atomic = iocb->ki_flags & IOCB_ATOMIC;
|
|
||||||
unsigned int nr_pages;
|
unsigned int nr_pages;
|
||||||
|
|
||||||
if (!iov_iter_count(iter))
|
if (!iov_iter_count(iter))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (blkdev_dio_invalid(bdev, iocb->ki_pos, iter, is_atomic))
|
if (blkdev_dio_invalid(bdev, iocb, iter))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS + 1);
|
nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS + 1);
|
||||||
@ -383,7 +379,7 @@ static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
|
|||||||
return __blkdev_direct_IO_simple(iocb, iter, bdev,
|
return __blkdev_direct_IO_simple(iocb, iter, bdev,
|
||||||
nr_pages);
|
nr_pages);
|
||||||
return __blkdev_direct_IO_async(iocb, iter, bdev, nr_pages);
|
return __blkdev_direct_IO_async(iocb, iter, bdev, nr_pages);
|
||||||
} else if (is_atomic) {
|
} else if (iocb->ki_flags & IOCB_ATOMIC) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return __blkdev_direct_IO(iocb, iter, bdev, bio_max_segs(nr_pages));
|
return __blkdev_direct_IO(iocb, iter, bdev, bio_max_segs(nr_pages));
|
||||||
@ -625,7 +621,7 @@ static int blkdev_open(struct inode *inode, struct file *filp)
|
|||||||
if (!bdev)
|
if (!bdev)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
if (bdev_can_atomic_write(bdev) && filp->f_flags & O_DIRECT)
|
if (bdev_can_atomic_write(bdev))
|
||||||
filp->f_mode |= FMODE_CAN_ATOMIC_WRITE;
|
filp->f_mode |= FMODE_CAN_ATOMIC_WRITE;
|
||||||
|
|
||||||
ret = bdev_open(bdev, mode, filp->private_data, NULL, filp);
|
ret = bdev_open(bdev, mode, filp->private_data, NULL, filp);
|
||||||
@ -700,6 +696,12 @@ static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
|||||||
if ((iocb->ki_flags & (IOCB_NOWAIT | IOCB_DIRECT)) == IOCB_NOWAIT)
|
if ((iocb->ki_flags & (IOCB_NOWAIT | IOCB_DIRECT)) == IOCB_NOWAIT)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
if (iocb->ki_flags & IOCB_ATOMIC) {
|
||||||
|
ret = generic_atomic_write_valid(iocb, from);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
size -= iocb->ki_pos;
|
size -= iocb->ki_pos;
|
||||||
if (iov_iter_count(from) > size) {
|
if (iov_iter_count(from) > size) {
|
||||||
shorted = iov_iter_count(from) - size;
|
shorted = iov_iter_count(from) - size;
|
||||||
|
@ -1830,18 +1830,21 @@ int generic_file_rw_checks(struct file *file_in, struct file *file_out)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool generic_atomic_write_valid(struct iov_iter *iter, loff_t pos)
|
int generic_atomic_write_valid(struct kiocb *iocb, struct iov_iter *iter)
|
||||||
{
|
{
|
||||||
size_t len = iov_iter_count(iter);
|
size_t len = iov_iter_count(iter);
|
||||||
|
|
||||||
if (!iter_is_ubuf(iter))
|
if (!iter_is_ubuf(iter))
|
||||||
return false;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!is_power_of_2(len))
|
if (!is_power_of_2(len))
|
||||||
return false;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!IS_ALIGNED(pos, len))
|
if (!IS_ALIGNED(iocb->ki_pos, len))
|
||||||
return false;
|
return -EINVAL;
|
||||||
|
|
||||||
return true;
|
if (!(iocb->ki_flags & IOCB_DIRECT))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1682,6 +1682,22 @@ static inline bool bdev_can_atomic_write(struct block_device *bdev)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
bdev_atomic_write_unit_min_bytes(struct block_device *bdev)
|
||||||
|
{
|
||||||
|
if (!bdev_can_atomic_write(bdev))
|
||||||
|
return 0;
|
||||||
|
return queue_atomic_write_unit_min_bytes(bdev_get_queue(bdev));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
bdev_atomic_write_unit_max_bytes(struct block_device *bdev)
|
||||||
|
{
|
||||||
|
if (!bdev_can_atomic_write(bdev))
|
||||||
|
return 0;
|
||||||
|
return queue_atomic_write_unit_max_bytes(bdev_get_queue(bdev));
|
||||||
|
}
|
||||||
|
|
||||||
#define DEFINE_IO_COMP_BATCH(name) struct io_comp_batch name = { }
|
#define DEFINE_IO_COMP_BATCH(name) struct io_comp_batch name = { }
|
||||||
|
|
||||||
#endif /* _LINUX_BLKDEV_H */
|
#endif /* _LINUX_BLKDEV_H */
|
||||||
|
@ -3726,6 +3726,6 @@ static inline bool vfs_empty_path(int dfd, const char __user *path)
|
|||||||
return !c;
|
return !c;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool generic_atomic_write_valid(struct iov_iter *iter, loff_t pos);
|
int generic_atomic_write_valid(struct kiocb *iocb, struct iov_iter *iter);
|
||||||
|
|
||||||
#endif /* _LINUX_FS_H */
|
#endif /* _LINUX_FS_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user