Skip to content

Commit fdad1a2

Browse files
committed
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()
2 parents 919b513 + 1eadb15 commit fdad1a2

File tree

4 files changed

+38
-17
lines changed

4 files changed

+38
-17
lines changed

block/fops.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,10 @@ static blk_opf_t dio_bio_write_op(struct kiocb *iocb)
3535
return opf;
3636
}
3737

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)
4040
{
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) ||
4542
!bdev_iter_is_aligned(bdev, iter);
4643
}
4744

@@ -368,13 +365,12 @@ static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb,
368365
static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
369366
{
370367
struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
371-
bool is_atomic = iocb->ki_flags & IOCB_ATOMIC;
372368
unsigned int nr_pages;
373369

374370
if (!iov_iter_count(iter))
375371
return 0;
376372

377-
if (blkdev_dio_invalid(bdev, iocb->ki_pos, iter, is_atomic))
373+
if (blkdev_dio_invalid(bdev, iocb, iter))
378374
return -EINVAL;
379375

380376
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)
383379
return __blkdev_direct_IO_simple(iocb, iter, bdev,
384380
nr_pages);
385381
return __blkdev_direct_IO_async(iocb, iter, bdev, nr_pages);
386-
} else if (is_atomic) {
382+
} else if (iocb->ki_flags & IOCB_ATOMIC) {
387383
return -EINVAL;
388384
}
389385
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)
625621
if (!bdev)
626622
return -ENXIO;
627623

628-
if (bdev_can_atomic_write(bdev) && filp->f_flags & O_DIRECT)
624+
if (bdev_can_atomic_write(bdev))
629625
filp->f_mode |= FMODE_CAN_ATOMIC_WRITE;
630626

631627
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)
700696
if ((iocb->ki_flags & (IOCB_NOWAIT | IOCB_DIRECT)) == IOCB_NOWAIT)
701697
return -EOPNOTSUPP;
702698

699+
if (iocb->ki_flags & IOCB_ATOMIC) {
700+
ret = generic_atomic_write_valid(iocb, from);
701+
if (ret)
702+
return ret;
703+
}
704+
703705
size -= iocb->ki_pos;
704706
if (iov_iter_count(from) > size) {
705707
shorted = iov_iter_count(from) - size;

fs/read_write.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,18 +1830,21 @@ int generic_file_rw_checks(struct file *file_in, struct file *file_out)
18301830
return 0;
18311831
}
18321832

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)
18341834
{
18351835
size_t len = iov_iter_count(iter);
18361836

18371837
if (!iter_is_ubuf(iter))
1838-
return false;
1838+
return -EINVAL;
18391839

18401840
if (!is_power_of_2(len))
1841-
return false;
1841+
return -EINVAL;
1842+
1843+
if (!IS_ALIGNED(iocb->ki_pos, len))
1844+
return -EINVAL;
18421845

1843-
if (!IS_ALIGNED(pos, len))
1844-
return false;
1846+
if (!(iocb->ki_flags & IOCB_DIRECT))
1847+
return -EOPNOTSUPP;
18451848

1846-
return true;
1849+
return 0;
18471850
}

include/linux/blkdev.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,6 +1682,22 @@ static inline bool bdev_can_atomic_write(struct block_device *bdev)
16821682
return true;
16831683
}
16841684

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+
16851701
#define DEFINE_IO_COMP_BATCH(name) struct io_comp_batch name = { }
16861702

16871703
#endif /* _LINUX_BLKDEV_H */

include/linux/fs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3726,6 +3726,6 @@ static inline bool vfs_empty_path(int dfd, const char __user *path)
37263726
return !c;
37273727
}
37283728

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);
37303730

37313731
#endif /* _LINUX_FS_H */

0 commit comments

Comments
 (0)