diff options
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 51 |
1 files changed, 18 insertions, 33 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, |