diff --git a/block/fops.c b/block/fops.c index 2ce7c6c4714e..38959ebae80c 100644 --- a/block/fops.c +++ b/block/fops.c @@ -728,6 +728,7 @@ static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) bool atomic = iocb->ki_flags & IOCB_ATOMIC; loff_t size = bdev_nr_bytes(bdev); size_t shorted = 0; + bool need_sync = false; ssize_t ret; if (bdev_read_only(bdev)) @@ -765,9 +766,11 @@ static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) if (iocb->ki_flags & IOCB_DIRECT) { ret = blkdev_direct_write(iocb, from); - if (ret >= 0 && iov_iter_count(from)) + if (ret >= 0 && iov_iter_count(from)) { ret = direct_write_fallback(iocb, from, ret, blkdev_buffered_write(iocb, from)); + need_sync = true; + } } else { /* * Take i_rwsem and invalidate_lock to avoid racing with @@ -777,9 +780,10 @@ static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) inode_lock_shared(bd_inode); ret = blkdev_buffered_write(iocb, from); inode_unlock_shared(bd_inode); + need_sync = true; } - if (ret > 0) + if (ret > 0 && need_sync) ret = generic_write_sync(iocb, ret); iov_iter_reexpand(from, iov_iter_count(from) + shorted); return ret;