@@ -271,7 +271,7 @@ static int iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
271271 * clearing the WRITE_THROUGH flag in the dio request.
272272 */
273273static inline blk_opf_t iomap_dio_bio_opflags (struct iomap_dio * dio ,
274- const struct iomap * iomap , bool use_fua )
274+ const struct iomap * iomap , bool use_fua , bool atomic )
275275{
276276 blk_opf_t opflags = REQ_SYNC | REQ_IDLE ;
277277
@@ -283,6 +283,8 @@ static inline blk_opf_t iomap_dio_bio_opflags(struct iomap_dio *dio,
283283 opflags |= REQ_FUA ;
284284 else
285285 dio -> flags &= ~IOMAP_DIO_WRITE_THROUGH ;
286+ if (atomic )
287+ opflags |= REQ_ATOMIC ;
286288
287289 return opflags ;
288290}
@@ -293,7 +295,8 @@ static loff_t iomap_dio_bio_iter(const struct iomap_iter *iter,
293295 const struct iomap * iomap = & iter -> iomap ;
294296 struct inode * inode = iter -> inode ;
295297 unsigned int fs_block_size = i_blocksize (inode ), pad ;
296- loff_t length = iomap_length (iter );
298+ const loff_t length = iomap_length (iter );
299+ bool atomic = iter -> flags & IOMAP_ATOMIC ;
297300 loff_t pos = iter -> pos ;
298301 blk_opf_t bio_opf ;
299302 struct bio * bio ;
@@ -303,6 +306,9 @@ static loff_t iomap_dio_bio_iter(const struct iomap_iter *iter,
303306 size_t copied = 0 ;
304307 size_t orig_count ;
305308
309+ if (atomic && length != fs_block_size )
310+ return - EINVAL ;
311+
306312 if ((pos | length ) & (bdev_logical_block_size (iomap -> bdev ) - 1 ) ||
307313 !bdev_iter_is_aligned (iomap -> bdev , dio -> submit .iter ))
308314 return - EINVAL ;
@@ -382,7 +388,7 @@ static loff_t iomap_dio_bio_iter(const struct iomap_iter *iter,
382388 * can set up the page vector appropriately for a ZONE_APPEND
383389 * operation.
384390 */
385- bio_opf = iomap_dio_bio_opflags (dio , iomap , use_fua );
391+ bio_opf = iomap_dio_bio_opflags (dio , iomap , use_fua , atomic );
386392
387393 nr_pages = bio_iov_vecs_to_alloc (dio -> submit .iter , BIO_MAX_VECS );
388394 do {
@@ -415,6 +421,17 @@ static loff_t iomap_dio_bio_iter(const struct iomap_iter *iter,
415421 }
416422
417423 n = bio -> bi_iter .bi_size ;
424+ if (WARN_ON_ONCE (atomic && n != length )) {
425+ /*
426+ * This bio should have covered the complete length,
427+ * which it doesn't, so error. We may need to zero out
428+ * the tail (complete FS block), similar to when
429+ * bio_iov_iter_get_pages() returns an error, above.
430+ */
431+ ret = - EINVAL ;
432+ bio_put (bio );
433+ goto zero_tail ;
434+ }
418435 if (dio -> flags & IOMAP_DIO_WRITE ) {
419436 task_io_account_write (n );
420437 } else {
@@ -598,6 +615,9 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
598615 if (iocb -> ki_flags & IOCB_NOWAIT )
599616 iomi .flags |= IOMAP_NOWAIT ;
600617
618+ if (iocb -> ki_flags & IOCB_ATOMIC )
619+ iomi .flags |= IOMAP_ATOMIC ;
620+
601621 if (iov_iter_rw (iter ) == READ ) {
602622 /* reads can always complete inline */
603623 dio -> flags |= IOMAP_DIO_INLINE_COMP ;
@@ -659,7 +679,17 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
659679 if (ret != - EAGAIN ) {
660680 trace_iomap_dio_invalidate_fail (inode , iomi .pos ,
661681 iomi .len );
662- ret = - ENOTBLK ;
682+ if (iocb -> ki_flags & IOCB_ATOMIC ) {
683+ /*
684+ * folio invalidation failed, maybe
685+ * this is transient, unlock and see if
686+ * the caller tries again.
687+ */
688+ ret = - EAGAIN ;
689+ } else {
690+ /* fall back to buffered write */
691+ ret = - ENOTBLK ;
692+ }
663693 }
664694 goto out_free_dio ;
665695 }
0 commit comments