diff options
Diffstat (limited to 'fs/direct-io.c')
-rw-r--r-- | fs/direct-io.c | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/fs/direct-io.c b/fs/direct-io.c index 472037732daf..3bf3f20f8ecc 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -224,9 +224,9 @@ static inline struct page *dio_get_page(struct dio *dio, | |||
224 | * filesystems can use it to hold additional state between get_block calls and | 224 | * filesystems can use it to hold additional state between get_block calls and |
225 | * dio_complete. | 225 | * dio_complete. |
226 | */ | 226 | */ |
227 | static ssize_t dio_complete(struct dio *dio, loff_t offset, ssize_t ret, | 227 | static ssize_t dio_complete(struct dio *dio, ssize_t ret, bool is_async) |
228 | bool is_async) | ||
229 | { | 228 | { |
229 | loff_t offset = dio->iocb->ki_pos; | ||
230 | ssize_t transferred = 0; | 230 | ssize_t transferred = 0; |
231 | 231 | ||
232 | /* | 232 | /* |
@@ -256,6 +256,7 @@ static ssize_t dio_complete(struct dio *dio, loff_t offset, ssize_t ret, | |||
256 | if (dio->end_io) { | 256 | if (dio->end_io) { |
257 | int err; | 257 | int err; |
258 | 258 | ||
259 | // XXX: ki_pos?? | ||
259 | err = dio->end_io(dio->iocb, offset, ret, dio->private); | 260 | err = dio->end_io(dio->iocb, offset, ret, dio->private); |
260 | if (err) | 261 | if (err) |
261 | ret = err; | 262 | ret = err; |
@@ -265,15 +266,15 @@ static ssize_t dio_complete(struct dio *dio, loff_t offset, ssize_t ret, | |||
265 | inode_dio_end(dio->inode); | 266 | inode_dio_end(dio->inode); |
266 | 267 | ||
267 | if (is_async) { | 268 | if (is_async) { |
268 | if (dio->rw & WRITE) { | 269 | /* |
269 | int err; | 270 | * generic_write_sync expects ki_pos to have been updated |
270 | 271 | * already, but the submission path only does this for | |
271 | err = generic_write_sync(dio->iocb->ki_filp, offset, | 272 | * synchronous I/O. |
272 | transferred); | 273 | */ |
273 | if (err < 0 && ret > 0) | 274 | dio->iocb->ki_pos += transferred; |
274 | ret = err; | ||
275 | } | ||
276 | 275 | ||
276 | if (dio->rw & WRITE) | ||
277 | ret = generic_write_sync(dio->iocb, transferred); | ||
277 | dio->iocb->ki_complete(dio->iocb, ret, 0); | 278 | dio->iocb->ki_complete(dio->iocb, ret, 0); |
278 | } | 279 | } |
279 | 280 | ||
@@ -285,7 +286,7 @@ static void dio_aio_complete_work(struct work_struct *work) | |||
285 | { | 286 | { |
286 | struct dio *dio = container_of(work, struct dio, complete_work); | 287 | struct dio *dio = container_of(work, struct dio, complete_work); |
287 | 288 | ||
288 | dio_complete(dio, dio->iocb->ki_pos, 0, true); | 289 | dio_complete(dio, 0, true); |
289 | } | 290 | } |
290 | 291 | ||
291 | static int dio_bio_complete(struct dio *dio, struct bio *bio); | 292 | static int dio_bio_complete(struct dio *dio, struct bio *bio); |
@@ -314,7 +315,7 @@ static void dio_bio_end_aio(struct bio *bio) | |||
314 | queue_work(dio->inode->i_sb->s_dio_done_wq, | 315 | queue_work(dio->inode->i_sb->s_dio_done_wq, |
315 | &dio->complete_work); | 316 | &dio->complete_work); |
316 | } else { | 317 | } else { |
317 | dio_complete(dio, dio->iocb->ki_pos, 0, true); | 318 | dio_complete(dio, 0, true); |
318 | } | 319 | } |
319 | } | 320 | } |
320 | } | 321 | } |
@@ -1113,7 +1114,7 @@ static inline int drop_refcount(struct dio *dio) | |||
1113 | static inline ssize_t | 1114 | static inline ssize_t |
1114 | do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, | 1115 | do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, |
1115 | struct block_device *bdev, struct iov_iter *iter, | 1116 | struct block_device *bdev, struct iov_iter *iter, |
1116 | loff_t offset, get_block_t get_block, dio_iodone_t end_io, | 1117 | get_block_t get_block, dio_iodone_t end_io, |
1117 | dio_submit_t submit_io, int flags) | 1118 | dio_submit_t submit_io, int flags) |
1118 | { | 1119 | { |
1119 | unsigned i_blkbits = ACCESS_ONCE(inode->i_blkbits); | 1120 | unsigned i_blkbits = ACCESS_ONCE(inode->i_blkbits); |
@@ -1121,6 +1122,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, | |||
1121 | unsigned blocksize_mask = (1 << blkbits) - 1; | 1122 | unsigned blocksize_mask = (1 << blkbits) - 1; |
1122 | ssize_t retval = -EINVAL; | 1123 | ssize_t retval = -EINVAL; |
1123 | size_t count = iov_iter_count(iter); | 1124 | size_t count = iov_iter_count(iter); |
1125 | loff_t offset = iocb->ki_pos; | ||
1124 | loff_t end = offset + count; | 1126 | loff_t end = offset + count; |
1125 | struct dio *dio; | 1127 | struct dio *dio; |
1126 | struct dio_submit sdio = { 0, }; | 1128 | struct dio_submit sdio = { 0, }; |
@@ -1318,7 +1320,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, | |||
1318 | dio_await_completion(dio); | 1320 | dio_await_completion(dio); |
1319 | 1321 | ||
1320 | if (drop_refcount(dio) == 0) { | 1322 | if (drop_refcount(dio) == 0) { |
1321 | retval = dio_complete(dio, offset, retval, false); | 1323 | retval = dio_complete(dio, retval, false); |
1322 | } else | 1324 | } else |
1323 | BUG_ON(retval != -EIOCBQUEUED); | 1325 | BUG_ON(retval != -EIOCBQUEUED); |
1324 | 1326 | ||
@@ -1328,7 +1330,7 @@ out: | |||
1328 | 1330 | ||
1329 | ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, | 1331 | ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, |
1330 | struct block_device *bdev, struct iov_iter *iter, | 1332 | struct block_device *bdev, struct iov_iter *iter, |
1331 | loff_t offset, get_block_t get_block, | 1333 | get_block_t get_block, |
1332 | dio_iodone_t end_io, dio_submit_t submit_io, | 1334 | dio_iodone_t end_io, dio_submit_t submit_io, |
1333 | int flags) | 1335 | int flags) |
1334 | { | 1336 | { |
@@ -1344,7 +1346,7 @@ ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, | |||
1344 | prefetch(bdev->bd_queue); | 1346 | prefetch(bdev->bd_queue); |
1345 | prefetch((char *)bdev->bd_queue + SMP_CACHE_BYTES); | 1347 | prefetch((char *)bdev->bd_queue + SMP_CACHE_BYTES); |
1346 | 1348 | ||
1347 | return do_blockdev_direct_IO(iocb, inode, bdev, iter, offset, get_block, | 1349 | return do_blockdev_direct_IO(iocb, inode, bdev, iter, get_block, |
1348 | end_io, submit_io, flags); | 1350 | end_io, submit_io, flags); |
1349 | } | 1351 | } |
1350 | 1352 | ||