aboutsummaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/aio.c b/fs/aio.c
index a0ed6c7d2cd2..56b28607c32d 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1241,6 +1241,7 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
1241 1241
1242typedef ssize_t (aio_rw_op)(struct kiocb *, const struct iovec *, 1242typedef ssize_t (aio_rw_op)(struct kiocb *, const struct iovec *,
1243 unsigned long, loff_t); 1243 unsigned long, loff_t);
1244typedef ssize_t (rw_iter_op)(struct kiocb *, struct iov_iter *);
1244 1245
1245static ssize_t aio_setup_vectored_rw(struct kiocb *kiocb, 1246static ssize_t aio_setup_vectored_rw(struct kiocb *kiocb,
1246 int rw, char __user *buf, 1247 int rw, char __user *buf,
@@ -1298,7 +1299,9 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
1298 int rw; 1299 int rw;
1299 fmode_t mode; 1300 fmode_t mode;
1300 aio_rw_op *rw_op; 1301 aio_rw_op *rw_op;
1302 rw_iter_op *iter_op;
1301 struct iovec inline_vec, *iovec = &inline_vec; 1303 struct iovec inline_vec, *iovec = &inline_vec;
1304 struct iov_iter iter;
1302 1305
1303 switch (opcode) { 1306 switch (opcode) {
1304 case IOCB_CMD_PREAD: 1307 case IOCB_CMD_PREAD:
@@ -1306,6 +1309,7 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
1306 mode = FMODE_READ; 1309 mode = FMODE_READ;
1307 rw = READ; 1310 rw = READ;
1308 rw_op = file->f_op->aio_read; 1311 rw_op = file->f_op->aio_read;
1312 iter_op = file->f_op->read_iter;
1309 goto rw_common; 1313 goto rw_common;
1310 1314
1311 case IOCB_CMD_PWRITE: 1315 case IOCB_CMD_PWRITE:
@@ -1313,12 +1317,13 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
1313 mode = FMODE_WRITE; 1317 mode = FMODE_WRITE;
1314 rw = WRITE; 1318 rw = WRITE;
1315 rw_op = file->f_op->aio_write; 1319 rw_op = file->f_op->aio_write;
1320 iter_op = file->f_op->write_iter;
1316 goto rw_common; 1321 goto rw_common;
1317rw_common: 1322rw_common:
1318 if (unlikely(!(file->f_mode & mode))) 1323 if (unlikely(!(file->f_mode & mode)))
1319 return -EBADF; 1324 return -EBADF;
1320 1325
1321 if (!rw_op) 1326 if (!rw_op && !iter_op)
1322 return -EINVAL; 1327 return -EINVAL;
1323 1328
1324 ret = (opcode == IOCB_CMD_PREADV || 1329 ret = (opcode == IOCB_CMD_PREADV ||
@@ -1347,7 +1352,12 @@ rw_common:
1347 if (rw == WRITE) 1352 if (rw == WRITE)
1348 file_start_write(file); 1353 file_start_write(file);
1349 1354
1350 ret = rw_op(req, iovec, nr_segs, req->ki_pos); 1355 if (iter_op) {
1356 iov_iter_init(&iter, rw, iovec, nr_segs, req->ki_nbytes);
1357 ret = iter_op(req, &iter);
1358 } else {
1359 ret = rw_op(req, iovec, nr_segs, req->ki_pos);
1360 }
1351 1361
1352 if (rw == WRITE) 1362 if (rw == WRITE)
1353 file_end_write(file); 1363 file_end_write(file);