aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-11-11 12:19:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-11-11 12:19:01 -0500
commitc5e4ca6da93f69939542385ca23d7ccebddc3f7d (patch)
treeda01507b6d050f5ac9face51a7be904ed5cc18dd /fs
parentef091b3cef2d699568b51559ae8340b996f43230 (diff)
parente519e7774784f3fa7728657d780863805ed1c983 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull VFS fixes from Al Viro: "Christoph's and Jan's aio fixes, fixup for generic_file_splice_read (removal of pointless detritus that actually breaks it when used for gfs2 ->splice_read()) and fixup for generic_file_read_iter() interaction with ITER_PIPE destinations." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: splice: remove detritus from generic_file_splice_read() mm/filemap: don't allow partially uptodate page for pipes aio: fix freeze protection of aio writes fs: remove aio_run_iocb fs: remove the never implemented aio_fsync file operation aio: hold an extra file reference over AIO read/write operations
Diffstat (limited to 'fs')
-rw-r--r--fs/aio.c207
-rw-r--r--fs/ntfs/dir.c2
-rw-r--r--fs/splice.c5
3 files changed, 109 insertions, 105 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 1157e13a36d6..428484f2f841 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1078,6 +1078,17 @@ static void aio_complete(struct kiocb *kiocb, long res, long res2)
1078 unsigned tail, pos, head; 1078 unsigned tail, pos, head;
1079 unsigned long flags; 1079 unsigned long flags;
1080 1080
1081 if (kiocb->ki_flags & IOCB_WRITE) {
1082 struct file *file = kiocb->ki_filp;
1083
1084 /*
1085 * Tell lockdep we inherited freeze protection from submission
1086 * thread.
1087 */
1088 __sb_writers_acquired(file_inode(file)->i_sb, SB_FREEZE_WRITE);
1089 file_end_write(file);
1090 }
1091
1081 /* 1092 /*
1082 * Special case handling for sync iocbs: 1093 * Special case handling for sync iocbs:
1083 * - events go directly into the iocb for fast handling 1094 * - events go directly into the iocb for fast handling
@@ -1392,122 +1403,106 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
1392 return -EINVAL; 1403 return -EINVAL;
1393} 1404}
1394 1405
1395typedef ssize_t (rw_iter_op)(struct kiocb *, struct iov_iter *); 1406static int aio_setup_rw(int rw, struct iocb *iocb, struct iovec **iovec,
1396 1407 bool vectored, bool compat, struct iov_iter *iter)
1397static int aio_setup_vectored_rw(int rw, char __user *buf, size_t len,
1398 struct iovec **iovec,
1399 bool compat,
1400 struct iov_iter *iter)
1401{ 1408{
1409 void __user *buf = (void __user *)(uintptr_t)iocb->aio_buf;
1410 size_t len = iocb->aio_nbytes;
1411
1412 if (!vectored) {
1413 ssize_t ret = import_single_range(rw, buf, len, *iovec, iter);
1414 *iovec = NULL;
1415 return ret;
1416 }
1402#ifdef CONFIG_COMPAT 1417#ifdef CONFIG_COMPAT
1403 if (compat) 1418 if (compat)
1404 return compat_import_iovec(rw, 1419 return compat_import_iovec(rw, buf, len, UIO_FASTIOV, iovec,
1405 (struct compat_iovec __user *)buf, 1420 iter);
1406 len, UIO_FASTIOV, iovec, iter);
1407#endif 1421#endif
1408 return import_iovec(rw, (struct iovec __user *)buf, 1422 return import_iovec(rw, buf, len, UIO_FASTIOV, iovec, iter);
1409 len, UIO_FASTIOV, iovec, iter);
1410} 1423}
1411 1424
1412/* 1425static inline ssize_t aio_ret(struct kiocb *req, ssize_t ret)
1413 * aio_run_iocb: 1426{
1414 * Performs the initial checks and io submission. 1427 switch (ret) {
1415 */ 1428 case -EIOCBQUEUED:
1416static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode, 1429 return ret;
1417 char __user *buf, size_t len, bool compat) 1430 case -ERESTARTSYS:
1431 case -ERESTARTNOINTR:
1432 case -ERESTARTNOHAND:
1433 case -ERESTART_RESTARTBLOCK:
1434 /*
1435 * There's no easy way to restart the syscall since other AIO's
1436 * may be already running. Just fail this IO with EINTR.
1437 */
1438 ret = -EINTR;
1439 /*FALLTHRU*/
1440 default:
1441 aio_complete(req, ret, 0);
1442 return 0;
1443 }
1444}
1445
1446static ssize_t aio_read(struct kiocb *req, struct iocb *iocb, bool vectored,
1447 bool compat)
1418{ 1448{
1419 struct file *file = req->ki_filp; 1449 struct file *file = req->ki_filp;
1420 ssize_t ret;
1421 int rw;
1422 fmode_t mode;
1423 rw_iter_op *iter_op;
1424 struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; 1450 struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
1425 struct iov_iter iter; 1451 struct iov_iter iter;
1452 ssize_t ret;
1426 1453
1427 switch (opcode) { 1454 if (unlikely(!(file->f_mode & FMODE_READ)))
1428 case IOCB_CMD_PREAD: 1455 return -EBADF;
1429 case IOCB_CMD_PREADV: 1456 if (unlikely(!file->f_op->read_iter))
1430 mode = FMODE_READ; 1457 return -EINVAL;
1431 rw = READ;
1432 iter_op = file->f_op->read_iter;
1433 goto rw_common;
1434
1435 case IOCB_CMD_PWRITE:
1436 case IOCB_CMD_PWRITEV:
1437 mode = FMODE_WRITE;
1438 rw = WRITE;
1439 iter_op = file->f_op->write_iter;
1440 goto rw_common;
1441rw_common:
1442 if (unlikely(!(file->f_mode & mode)))
1443 return -EBADF;
1444
1445 if (!iter_op)
1446 return -EINVAL;
1447
1448 if (opcode == IOCB_CMD_PREADV || opcode == IOCB_CMD_PWRITEV)
1449 ret = aio_setup_vectored_rw(rw, buf, len,
1450 &iovec, compat, &iter);
1451 else {
1452 ret = import_single_range(rw, buf, len, iovec, &iter);
1453 iovec = NULL;
1454 }
1455 if (!ret)
1456 ret = rw_verify_area(rw, file, &req->ki_pos,
1457 iov_iter_count(&iter));
1458 if (ret < 0) {
1459 kfree(iovec);
1460 return ret;
1461 }
1462
1463 if (rw == WRITE)
1464 file_start_write(file);
1465
1466 ret = iter_op(req, &iter);
1467
1468 if (rw == WRITE)
1469 file_end_write(file);
1470 kfree(iovec);
1471 break;
1472
1473 case IOCB_CMD_FDSYNC:
1474 if (!file->f_op->aio_fsync)
1475 return -EINVAL;
1476
1477 ret = file->f_op->aio_fsync(req, 1);
1478 break;
1479 1458
1480 case IOCB_CMD_FSYNC: 1459 ret = aio_setup_rw(READ, iocb, &iovec, vectored, compat, &iter);
1481 if (!file->f_op->aio_fsync) 1460 if (ret)
1482 return -EINVAL; 1461 return ret;
1462 ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter));
1463 if (!ret)
1464 ret = aio_ret(req, file->f_op->read_iter(req, &iter));
1465 kfree(iovec);
1466 return ret;
1467}
1483 1468
1484 ret = file->f_op->aio_fsync(req, 0); 1469static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored,
1485 break; 1470 bool compat)
1471{
1472 struct file *file = req->ki_filp;
1473 struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
1474 struct iov_iter iter;
1475 ssize_t ret;
1486 1476
1487 default: 1477 if (unlikely(!(file->f_mode & FMODE_WRITE)))
1488 pr_debug("EINVAL: no operation provided\n"); 1478 return -EBADF;
1479 if (unlikely(!file->f_op->write_iter))
1489 return -EINVAL; 1480 return -EINVAL;
1490 }
1491 1481
1492 if (ret != -EIOCBQUEUED) { 1482 ret = aio_setup_rw(WRITE, iocb, &iovec, vectored, compat, &iter);
1483 if (ret)
1484 return ret;
1485 ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter));
1486 if (!ret) {
1487 req->ki_flags |= IOCB_WRITE;
1488 file_start_write(file);
1489 ret = aio_ret(req, file->f_op->write_iter(req, &iter));
1493 /* 1490 /*
1494 * There's no easy way to restart the syscall since other AIO's 1491 * We release freeze protection in aio_complete(). Fool lockdep
1495 * may be already running. Just fail this IO with EINTR. 1492 * by telling it the lock got released so that it doesn't
1493 * complain about held lock when we return to userspace.
1496 */ 1494 */
1497 if (unlikely(ret == -ERESTARTSYS || ret == -ERESTARTNOINTR || 1495 __sb_writers_release(file_inode(file)->i_sb, SB_FREEZE_WRITE);
1498 ret == -ERESTARTNOHAND ||
1499 ret == -ERESTART_RESTARTBLOCK))
1500 ret = -EINTR;
1501 aio_complete(req, ret, 0);
1502 } 1496 }
1503 1497 kfree(iovec);
1504 return 0; 1498 return ret;
1505} 1499}
1506 1500
1507static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, 1501static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
1508 struct iocb *iocb, bool compat) 1502 struct iocb *iocb, bool compat)
1509{ 1503{
1510 struct aio_kiocb *req; 1504 struct aio_kiocb *req;
1505 struct file *file;
1511 ssize_t ret; 1506 ssize_t ret;
1512 1507
1513 /* enforce forwards compatibility on users */ 1508 /* enforce forwards compatibility on users */
@@ -1530,7 +1525,7 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
1530 if (unlikely(!req)) 1525 if (unlikely(!req))
1531 return -EAGAIN; 1526 return -EAGAIN;
1532 1527
1533 req->common.ki_filp = fget(iocb->aio_fildes); 1528 req->common.ki_filp = file = fget(iocb->aio_fildes);
1534 if (unlikely(!req->common.ki_filp)) { 1529 if (unlikely(!req->common.ki_filp)) {
1535 ret = -EBADF; 1530 ret = -EBADF;
1536 goto out_put_req; 1531 goto out_put_req;
@@ -1565,13 +1560,29 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
1565 req->ki_user_iocb = user_iocb; 1560 req->ki_user_iocb = user_iocb;
1566 req->ki_user_data = iocb->aio_data; 1561 req->ki_user_data = iocb->aio_data;
1567 1562
1568 ret = aio_run_iocb(&req->common, iocb->aio_lio_opcode, 1563 get_file(file);
1569 (char __user *)(unsigned long)iocb->aio_buf, 1564 switch (iocb->aio_lio_opcode) {
1570 iocb->aio_nbytes, 1565 case IOCB_CMD_PREAD:
1571 compat); 1566 ret = aio_read(&req->common, iocb, false, compat);
1572 if (ret) 1567 break;
1573 goto out_put_req; 1568 case IOCB_CMD_PWRITE:
1569 ret = aio_write(&req->common, iocb, false, compat);
1570 break;
1571 case IOCB_CMD_PREADV:
1572 ret = aio_read(&req->common, iocb, true, compat);
1573 break;
1574 case IOCB_CMD_PWRITEV:
1575 ret = aio_write(&req->common, iocb, true, compat);
1576 break;
1577 default:
1578 pr_debug("invalid aio operation %d\n", iocb->aio_lio_opcode);
1579 ret = -EINVAL;
1580 break;
1581 }
1582 fput(file);
1574 1583
1584 if (ret && ret != -EIOCBQUEUED)
1585 goto out_put_req;
1575 return 0; 1586 return 0;
1576out_put_req: 1587out_put_req:
1577 put_reqs_available(ctx, 1); 1588 put_reqs_available(ctx, 1);
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index a18613579001..0ee19ecc982d 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -1544,8 +1544,6 @@ const struct file_operations ntfs_dir_ops = {
1544 .iterate = ntfs_readdir, /* Read directory contents. */ 1544 .iterate = ntfs_readdir, /* Read directory contents. */
1545#ifdef NTFS_RW 1545#ifdef NTFS_RW
1546 .fsync = ntfs_dir_fsync, /* Sync a directory to disk. */ 1546 .fsync = ntfs_dir_fsync, /* Sync a directory to disk. */
1547 /*.aio_fsync = ,*/ /* Sync all outstanding async
1548 i/o operations on a kiocb. */
1549#endif /* NTFS_RW */ 1547#endif /* NTFS_RW */
1550 /*.ioctl = ,*/ /* Perform function on the 1548 /*.ioctl = ,*/ /* Perform function on the
1551 mounted filesystem. */ 1549 mounted filesystem. */
diff --git a/fs/splice.c b/fs/splice.c
index 153d4f3bd441..dcaf185a5731 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -299,13 +299,8 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
299{ 299{
300 struct iov_iter to; 300 struct iov_iter to;
301 struct kiocb kiocb; 301 struct kiocb kiocb;
302 loff_t isize;
303 int idx, ret; 302 int idx, ret;
304 303
305 isize = i_size_read(in->f_mapping->host);
306 if (unlikely(*ppos >= isize))
307 return 0;
308
309 iov_iter_pipe(&to, ITER_PIPE | READ, pipe, len); 304 iov_iter_pipe(&to, ITER_PIPE | READ, pipe, len);
310 idx = to.idx; 305 idx = to.idx;
311 init_sync_kiocb(&kiocb, in); 306 init_sync_kiocb(&kiocb, in);