mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +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;
|
||||
}
|
||||
|
||||
static bool blkdev_dio_invalid(struct block_device *bdev, loff_t pos,
|
||||
struct iov_iter *iter, bool is_atomic)
|
||||
static bool blkdev_dio_invalid(struct block_device *bdev, struct kiocb *iocb,
|
||||
struct iov_iter *iter)
|
||||
{
|
||||
if (is_atomic && !generic_atomic_write_valid(iter, pos))
|
||||
return true;
|
||||
|
||||
return pos & (bdev_logical_block_size(bdev) - 1) ||
|
||||
return iocb->ki_pos & (bdev_logical_block_size(bdev) - 1) ||
|
||||
!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)
|
||||
{
|
||||
struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
|
||||
bool is_atomic = iocb->ki_flags & IOCB_ATOMIC;
|
||||
unsigned int nr_pages;
|
||||
|
||||
if (!iov_iter_count(iter))
|
||||
return 0;
|
||||
|
||||
if (blkdev_dio_invalid(bdev, iocb->ki_pos, iter, is_atomic))
|
||||
if (blkdev_dio_invalid(bdev, iocb, iter))
|
||||
return -EINVAL;
|
||||
|
||||
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,
|
||||
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 __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)
|
||||
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;
|
||||
|
||||
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)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (iocb->ki_flags & IOCB_ATOMIC) {
|
||||
ret = generic_atomic_write_valid(iocb, from);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
size -= iocb->ki_pos;
|
||||
if (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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!iter_is_ubuf(iter))
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
if (!is_power_of_2(len))
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
if (!IS_ALIGNED(pos, len))
|
||||
return false;
|
||||
if (!IS_ALIGNED(iocb->ki_pos, len))
|
||||
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;
|
||||
}
|
||||
|
||||
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 = { }
|
||||
|
||||
#endif /* _LINUX_BLKDEV_H */
|
||||
|
@ -3726,6 +3726,6 @@ static inline bool vfs_empty_path(int dfd, const char __user *path)
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user