diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-12 13:30:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-12 13:30:18 -0400 |
commit | 16b9057804c02e2d351e9c8f606e909b43cbd9e7 (patch) | |
tree | a3ac6e1d9d57a8abf4267e5ead3f2de1309335eb /fs/btrfs | |
parent | 5c02c392cd2320e8d612376d6b72b6548a680923 (diff) | |
parent | c2338f2dc7c1e9f6202f370c64ffd7f44f3d4b51 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro:
"This the bunch that sat in -next + lock_parent() fix. This is the
minimal set; there's more pending stuff.
In particular, I really hope to get acct.c fixes merged this cycle -
we need that to deal sanely with delayed-mntput stuff. In the next
pile, hopefully - that series is fairly short and localized
(kernel/acct.c, fs/super.c and fs/namespace.c). In this pile: more
iov_iter work. Most of prereqs for ->splice_write with sane locking
order are there and Kent's dio rewrite would also fit nicely on top of
this pile"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (70 commits)
lock_parent: don't step on stale ->d_parent of all-but-freed one
kill generic_file_splice_write()
ceph: switch to iter_file_splice_write()
shmem: switch to iter_file_splice_write()
nfs: switch to iter_splice_write_file()
fs/splice.c: remove unneeded exports
ocfs2: switch to iter_file_splice_write()
->splice_write() via ->write_iter()
bio_vec-backed iov_iter
optimize copy_page_{to,from}_iter()
bury generic_file_aio_{read,write}
lustre: get rid of messing with iovecs
ceph: switch to ->write_iter()
ceph_sync_direct_write: stop poking into iov_iter guts
ceph_sync_read: stop poking into iov_iter guts
new helper: copy_page_from_iter()
fuse: switch to ->write_iter()
btrfs: switch to ->write_iter()
ocfs2: switch to ->write_iter()
xfs: switch to ->write_iter()
...
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/file.c | 51 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 47 |
2 files changed, 36 insertions, 62 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e472441feb5d..1f2b99cb55ea 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -448,7 +448,7 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, | |||
448 | write_bytes -= copied; | 448 | write_bytes -= copied; |
449 | total_copied += copied; | 449 | total_copied += copied; |
450 | 450 | ||
451 | /* Return to btrfs_file_aio_write to fault page */ | 451 | /* Return to btrfs_file_write_iter to fault page */ |
452 | if (unlikely(copied == 0)) | 452 | if (unlikely(copied == 0)) |
453 | break; | 453 | break; |
454 | 454 | ||
@@ -1675,27 +1675,22 @@ again: | |||
1675 | } | 1675 | } |
1676 | 1676 | ||
1677 | static ssize_t __btrfs_direct_write(struct kiocb *iocb, | 1677 | static ssize_t __btrfs_direct_write(struct kiocb *iocb, |
1678 | const struct iovec *iov, | 1678 | struct iov_iter *from, |
1679 | unsigned long nr_segs, loff_t pos, | 1679 | loff_t pos) |
1680 | size_t count, size_t ocount) | ||
1681 | { | 1680 | { |
1682 | struct file *file = iocb->ki_filp; | 1681 | struct file *file = iocb->ki_filp; |
1683 | struct iov_iter i; | ||
1684 | ssize_t written; | 1682 | ssize_t written; |
1685 | ssize_t written_buffered; | 1683 | ssize_t written_buffered; |
1686 | loff_t endbyte; | 1684 | loff_t endbyte; |
1687 | int err; | 1685 | int err; |
1688 | 1686 | ||
1689 | written = generic_file_direct_write(iocb, iov, &nr_segs, pos, | 1687 | written = generic_file_direct_write(iocb, from, pos); |
1690 | count, ocount); | ||
1691 | 1688 | ||
1692 | if (written < 0 || written == count) | 1689 | if (written < 0 || !iov_iter_count(from)) |
1693 | return written; | 1690 | return written; |
1694 | 1691 | ||
1695 | pos += written; | 1692 | pos += written; |
1696 | count -= written; | 1693 | written_buffered = __btrfs_buffered_write(file, from, pos); |
1697 | iov_iter_init(&i, iov, nr_segs, count, written); | ||
1698 | written_buffered = __btrfs_buffered_write(file, &i, pos); | ||
1699 | if (written_buffered < 0) { | 1694 | if (written_buffered < 0) { |
1700 | err = written_buffered; | 1695 | err = written_buffered; |
1701 | goto out; | 1696 | goto out; |
@@ -1730,9 +1725,8 @@ static void update_time_for_write(struct inode *inode) | |||
1730 | inode_inc_iversion(inode); | 1725 | inode_inc_iversion(inode); |
1731 | } | 1726 | } |
1732 | 1727 | ||
1733 | static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | 1728 | static ssize_t btrfs_file_write_iter(struct kiocb *iocb, |
1734 | const struct iovec *iov, | 1729 | struct iov_iter *from) |
1735 | unsigned long nr_segs, loff_t pos) | ||
1736 | { | 1730 | { |
1737 | struct file *file = iocb->ki_filp; | 1731 | struct file *file = iocb->ki_filp; |
1738 | struct inode *inode = file_inode(file); | 1732 | struct inode *inode = file_inode(file); |
@@ -1741,18 +1735,12 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1741 | u64 end_pos; | 1735 | u64 end_pos; |
1742 | ssize_t num_written = 0; | 1736 | ssize_t num_written = 0; |
1743 | ssize_t err = 0; | 1737 | ssize_t err = 0; |
1744 | size_t count, ocount; | 1738 | size_t count = iov_iter_count(from); |
1745 | bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); | 1739 | bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); |
1740 | loff_t pos = iocb->ki_pos; | ||
1746 | 1741 | ||
1747 | mutex_lock(&inode->i_mutex); | 1742 | mutex_lock(&inode->i_mutex); |
1748 | 1743 | ||
1749 | err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); | ||
1750 | if (err) { | ||
1751 | mutex_unlock(&inode->i_mutex); | ||
1752 | goto out; | ||
1753 | } | ||
1754 | count = ocount; | ||
1755 | |||
1756 | current->backing_dev_info = inode->i_mapping->backing_dev_info; | 1744 | current->backing_dev_info = inode->i_mapping->backing_dev_info; |
1757 | err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); | 1745 | err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); |
1758 | if (err) { | 1746 | if (err) { |
@@ -1765,6 +1753,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1765 | goto out; | 1753 | goto out; |
1766 | } | 1754 | } |
1767 | 1755 | ||
1756 | iov_iter_truncate(from, count); | ||
1757 | |||
1768 | err = file_remove_suid(file); | 1758 | err = file_remove_suid(file); |
1769 | if (err) { | 1759 | if (err) { |
1770 | mutex_unlock(&inode->i_mutex); | 1760 | mutex_unlock(&inode->i_mutex); |
@@ -1806,14 +1796,9 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1806 | atomic_inc(&BTRFS_I(inode)->sync_writers); | 1796 | atomic_inc(&BTRFS_I(inode)->sync_writers); |
1807 | 1797 | ||
1808 | if (unlikely(file->f_flags & O_DIRECT)) { | 1798 | if (unlikely(file->f_flags & O_DIRECT)) { |
1809 | num_written = __btrfs_direct_write(iocb, iov, nr_segs, | 1799 | num_written = __btrfs_direct_write(iocb, from, pos); |
1810 | pos, count, ocount); | ||
1811 | } else { | 1800 | } else { |
1812 | struct iov_iter i; | 1801 | num_written = __btrfs_buffered_write(file, from, pos); |
1813 | |||
1814 | iov_iter_init(&i, iov, nr_segs, count, num_written); | ||
1815 | |||
1816 | num_written = __btrfs_buffered_write(file, &i, pos); | ||
1817 | if (num_written > 0) | 1802 | if (num_written > 0) |
1818 | iocb->ki_pos = pos + num_written; | 1803 | iocb->ki_pos = pos + num_written; |
1819 | } | 1804 | } |
@@ -2740,11 +2725,11 @@ out: | |||
2740 | 2725 | ||
2741 | const struct file_operations btrfs_file_operations = { | 2726 | const struct file_operations btrfs_file_operations = { |
2742 | .llseek = btrfs_file_llseek, | 2727 | .llseek = btrfs_file_llseek, |
2743 | .read = do_sync_read, | 2728 | .read = new_sync_read, |
2744 | .write = do_sync_write, | 2729 | .write = new_sync_write, |
2745 | .aio_read = generic_file_aio_read, | 2730 | .read_iter = generic_file_read_iter, |
2746 | .splice_read = generic_file_splice_read, | 2731 | .splice_read = generic_file_splice_read, |
2747 | .aio_write = btrfs_file_aio_write, | 2732 | .write_iter = btrfs_file_write_iter, |
2748 | .mmap = btrfs_file_mmap, | 2733 | .mmap = btrfs_file_mmap, |
2749 | .open = generic_file_open, | 2734 | .open = generic_file_open, |
2750 | .release = btrfs_release_file, | 2735 | .release = btrfs_release_file, |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 7fa5f7fd7bc7..8925f66a1411 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -7445,39 +7445,30 @@ free_ordered: | |||
7445 | } | 7445 | } |
7446 | 7446 | ||
7447 | static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb, | 7447 | static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb, |
7448 | const struct iovec *iov, loff_t offset, | 7448 | const struct iov_iter *iter, loff_t offset) |
7449 | unsigned long nr_segs) | ||
7450 | { | 7449 | { |
7451 | int seg; | 7450 | int seg; |
7452 | int i; | 7451 | int i; |
7453 | size_t size; | ||
7454 | unsigned long addr; | ||
7455 | unsigned blocksize_mask = root->sectorsize - 1; | 7452 | unsigned blocksize_mask = root->sectorsize - 1; |
7456 | ssize_t retval = -EINVAL; | 7453 | ssize_t retval = -EINVAL; |
7457 | loff_t end = offset; | ||
7458 | 7454 | ||
7459 | if (offset & blocksize_mask) | 7455 | if (offset & blocksize_mask) |
7460 | goto out; | 7456 | goto out; |
7461 | 7457 | ||
7462 | /* Check the memory alignment. Blocks cannot straddle pages */ | 7458 | if (iov_iter_alignment(iter) & blocksize_mask) |
7463 | for (seg = 0; seg < nr_segs; seg++) { | 7459 | goto out; |
7464 | addr = (unsigned long)iov[seg].iov_base; | ||
7465 | size = iov[seg].iov_len; | ||
7466 | end += size; | ||
7467 | if ((addr & blocksize_mask) || (size & blocksize_mask)) | ||
7468 | goto out; | ||
7469 | |||
7470 | /* If this is a write we don't need to check anymore */ | ||
7471 | if (rw & WRITE) | ||
7472 | continue; | ||
7473 | 7460 | ||
7474 | /* | 7461 | /* If this is a write we don't need to check anymore */ |
7475 | * Check to make sure we don't have duplicate iov_base's in this | 7462 | if (rw & WRITE) |
7476 | * iovec, if so return EINVAL, otherwise we'll get csum errors | 7463 | return 0; |
7477 | * when reading back. | 7464 | /* |
7478 | */ | 7465 | * Check to make sure we don't have duplicate iov_base's in this |
7479 | for (i = seg + 1; i < nr_segs; i++) { | 7466 | * iovec, if so return EINVAL, otherwise we'll get csum errors |
7480 | if (iov[seg].iov_base == iov[i].iov_base) | 7467 | * when reading back. |
7468 | */ | ||
7469 | for (seg = 0; seg < iter->nr_segs; seg++) { | ||
7470 | for (i = seg + 1; i < iter->nr_segs; i++) { | ||
7471 | if (iter->iov[seg].iov_base == iter->iov[i].iov_base) | ||
7481 | goto out; | 7472 | goto out; |
7482 | } | 7473 | } |
7483 | } | 7474 | } |
@@ -7487,8 +7478,7 @@ out: | |||
7487 | } | 7478 | } |
7488 | 7479 | ||
7489 | static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | 7480 | static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, |
7490 | const struct iovec *iov, loff_t offset, | 7481 | struct iov_iter *iter, loff_t offset) |
7491 | unsigned long nr_segs) | ||
7492 | { | 7482 | { |
7493 | struct file *file = iocb->ki_filp; | 7483 | struct file *file = iocb->ki_filp; |
7494 | struct inode *inode = file->f_mapping->host; | 7484 | struct inode *inode = file->f_mapping->host; |
@@ -7498,8 +7488,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
7498 | bool relock = false; | 7488 | bool relock = false; |
7499 | ssize_t ret; | 7489 | ssize_t ret; |
7500 | 7490 | ||
7501 | if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iov, | 7491 | if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iter, offset)) |
7502 | offset, nr_segs)) | ||
7503 | return 0; | 7492 | return 0; |
7504 | 7493 | ||
7505 | atomic_inc(&inode->i_dio_count); | 7494 | atomic_inc(&inode->i_dio_count); |
@@ -7511,7 +7500,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
7511 | * we need to flush the dirty pages again to make absolutely sure | 7500 | * we need to flush the dirty pages again to make absolutely sure |
7512 | * that any outstanding dirty pages are on disk. | 7501 | * that any outstanding dirty pages are on disk. |
7513 | */ | 7502 | */ |
7514 | count = iov_length(iov, nr_segs); | 7503 | count = iov_iter_count(iter); |
7515 | if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, | 7504 | if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, |
7516 | &BTRFS_I(inode)->runtime_flags)) | 7505 | &BTRFS_I(inode)->runtime_flags)) |
7517 | filemap_fdatawrite_range(inode->i_mapping, offset, count); | 7506 | filemap_fdatawrite_range(inode->i_mapping, offset, count); |
@@ -7538,7 +7527,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
7538 | 7527 | ||
7539 | ret = __blockdev_direct_IO(rw, iocb, inode, | 7528 | ret = __blockdev_direct_IO(rw, iocb, inode, |
7540 | BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev, | 7529 | BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev, |
7541 | iov, offset, nr_segs, btrfs_get_blocks_direct, NULL, | 7530 | iter, offset, btrfs_get_blocks_direct, NULL, |
7542 | btrfs_submit_direct, flags); | 7531 | btrfs_submit_direct, flags); |
7543 | if (rw & WRITE) { | 7532 | if (rw & WRITE) { |
7544 | if (ret < 0 && ret != -EIOCBQUEUED) | 7533 | if (ret < 0 && ret != -EIOCBQUEUED) |