aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/file.c51
-rw-r--r--fs/btrfs/inode.c47
2 files changed, 36 insertions, 62 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index ae6af072b635..17e7393c50f0 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -447,7 +447,7 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages,
447 write_bytes -= copied; 447 write_bytes -= copied;
448 total_copied += copied; 448 total_copied += copied;
449 449
450 /* Return to btrfs_file_aio_write to fault page */ 450 /* Return to btrfs_file_write_iter to fault page */
451 if (unlikely(copied == 0)) 451 if (unlikely(copied == 0))
452 break; 452 break;
453 453
@@ -1658,27 +1658,22 @@ again:
1658} 1658}
1659 1659
1660static ssize_t __btrfs_direct_write(struct kiocb *iocb, 1660static ssize_t __btrfs_direct_write(struct kiocb *iocb,
1661 const struct iovec *iov, 1661 struct iov_iter *from,
1662 unsigned long nr_segs, loff_t pos, 1662 loff_t pos)
1663 size_t count, size_t ocount)
1664{ 1663{
1665 struct file *file = iocb->ki_filp; 1664 struct file *file = iocb->ki_filp;
1666 struct iov_iter i;
1667 ssize_t written; 1665 ssize_t written;
1668 ssize_t written_buffered; 1666 ssize_t written_buffered;
1669 loff_t endbyte; 1667 loff_t endbyte;
1670 int err; 1668 int err;
1671 1669
1672 written = generic_file_direct_write(iocb, iov, &nr_segs, pos, 1670 written = generic_file_direct_write(iocb, from, pos);
1673 count, ocount);
1674 1671
1675 if (written < 0 || written == count) 1672 if (written < 0 || !iov_iter_count(from))
1676 return written; 1673 return written;
1677 1674
1678 pos += written; 1675 pos += written;
1679 count -= written; 1676 written_buffered = __btrfs_buffered_write(file, from, pos);
1680 iov_iter_init(&i, iov, nr_segs, count, written);
1681 written_buffered = __btrfs_buffered_write(file, &i, pos);
1682 if (written_buffered < 0) { 1677 if (written_buffered < 0) {
1683 err = written_buffered; 1678 err = written_buffered;
1684 goto out; 1679 goto out;
@@ -1713,9 +1708,8 @@ static void update_time_for_write(struct inode *inode)
1713 inode_inc_iversion(inode); 1708 inode_inc_iversion(inode);
1714} 1709}
1715 1710
1716static ssize_t btrfs_file_aio_write(struct kiocb *iocb, 1711static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
1717 const struct iovec *iov, 1712 struct iov_iter *from)
1718 unsigned long nr_segs, loff_t pos)
1719{ 1713{
1720 struct file *file = iocb->ki_filp; 1714 struct file *file = iocb->ki_filp;
1721 struct inode *inode = file_inode(file); 1715 struct inode *inode = file_inode(file);
@@ -1724,18 +1718,12 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1724 u64 end_pos; 1718 u64 end_pos;
1725 ssize_t num_written = 0; 1719 ssize_t num_written = 0;
1726 ssize_t err = 0; 1720 ssize_t err = 0;
1727 size_t count, ocount; 1721 size_t count = iov_iter_count(from);
1728 bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host); 1722 bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host);
1723 loff_t pos = iocb->ki_pos;
1729 1724
1730 mutex_lock(&inode->i_mutex); 1725 mutex_lock(&inode->i_mutex);
1731 1726
1732 err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
1733 if (err) {
1734 mutex_unlock(&inode->i_mutex);
1735 goto out;
1736 }
1737 count = ocount;
1738
1739 current->backing_dev_info = inode->i_mapping->backing_dev_info; 1727 current->backing_dev_info = inode->i_mapping->backing_dev_info;
1740 err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); 1728 err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
1741 if (err) { 1729 if (err) {
@@ -1748,6 +1736,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1748 goto out; 1736 goto out;
1749 } 1737 }
1750 1738
1739 iov_iter_truncate(from, count);
1740
1751 err = file_remove_suid(file); 1741 err = file_remove_suid(file);
1752 if (err) { 1742 if (err) {
1753 mutex_unlock(&inode->i_mutex); 1743 mutex_unlock(&inode->i_mutex);
@@ -1789,14 +1779,9 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1789 atomic_inc(&BTRFS_I(inode)->sync_writers); 1779 atomic_inc(&BTRFS_I(inode)->sync_writers);
1790 1780
1791 if (unlikely(file->f_flags & O_DIRECT)) { 1781 if (unlikely(file->f_flags & O_DIRECT)) {
1792 num_written = __btrfs_direct_write(iocb, iov, nr_segs, 1782 num_written = __btrfs_direct_write(iocb, from, pos);
1793 pos, count, ocount);
1794 } else { 1783 } else {
1795 struct iov_iter i; 1784 num_written = __btrfs_buffered_write(file, from, pos);
1796
1797 iov_iter_init(&i, iov, nr_segs, count, num_written);
1798
1799 num_written = __btrfs_buffered_write(file, &i, pos);
1800 if (num_written > 0) 1785 if (num_written > 0)
1801 iocb->ki_pos = pos + num_written; 1786 iocb->ki_pos = pos + num_written;
1802 } 1787 }
@@ -2633,11 +2618,11 @@ out:
2633 2618
2634const struct file_operations btrfs_file_operations = { 2619const struct file_operations btrfs_file_operations = {
2635 .llseek = btrfs_file_llseek, 2620 .llseek = btrfs_file_llseek,
2636 .read = do_sync_read, 2621 .read = new_sync_read,
2637 .write = do_sync_write, 2622 .write = new_sync_write,
2638 .aio_read = generic_file_aio_read, 2623 .read_iter = generic_file_read_iter,
2639 .splice_read = generic_file_splice_read, 2624 .splice_read = generic_file_splice_read,
2640 .aio_write = btrfs_file_aio_write, 2625 .write_iter = btrfs_file_write_iter,
2641 .mmap = btrfs_file_mmap, 2626 .mmap = btrfs_file_mmap,
2642 .open = generic_file_open, 2627 .open = generic_file_open,
2643 .release = btrfs_release_file, 2628 .release = btrfs_release_file,
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 5f805bc944fa..c8386f1961f0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7391,39 +7391,30 @@ free_ordered:
7391} 7391}
7392 7392
7393static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb, 7393static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb,
7394 const struct iovec *iov, loff_t offset, 7394 const struct iov_iter *iter, loff_t offset)
7395 unsigned long nr_segs)
7396{ 7395{
7397 int seg; 7396 int seg;
7398 int i; 7397 int i;
7399 size_t size;
7400 unsigned long addr;
7401 unsigned blocksize_mask = root->sectorsize - 1; 7398 unsigned blocksize_mask = root->sectorsize - 1;
7402 ssize_t retval = -EINVAL; 7399 ssize_t retval = -EINVAL;
7403 loff_t end = offset;
7404 7400
7405 if (offset & blocksize_mask) 7401 if (offset & blocksize_mask)
7406 goto out; 7402 goto out;
7407 7403
7408 /* Check the memory alignment. Blocks cannot straddle pages */ 7404 if (iov_iter_alignment(iter) & blocksize_mask)
7409 for (seg = 0; seg < nr_segs; seg++) { 7405 goto out;
7410 addr = (unsigned long)iov[seg].iov_base;
7411 size = iov[seg].iov_len;
7412 end += size;
7413 if ((addr & blocksize_mask) || (size & blocksize_mask))
7414 goto out;
7415
7416 /* If this is a write we don't need to check anymore */
7417 if (rw & WRITE)
7418 continue;
7419 7406
7420 /* 7407 /* If this is a write we don't need to check anymore */
7421 * Check to make sure we don't have duplicate iov_base's in this 7408 if (rw & WRITE)
7422 * iovec, if so return EINVAL, otherwise we'll get csum errors 7409 return 0;
7423 * when reading back. 7410 /*
7424 */ 7411 * Check to make sure we don't have duplicate iov_base's in this
7425 for (i = seg + 1; i < nr_segs; i++) { 7412 * iovec, if so return EINVAL, otherwise we'll get csum errors
7426 if (iov[seg].iov_base == iov[i].iov_base) 7413 * when reading back.
7414 */
7415 for (seg = 0; seg < iter->nr_segs; seg++) {
7416 for (i = seg + 1; i < iter->nr_segs; i++) {
7417 if (iter->iov[seg].iov_base == iter->iov[i].iov_base)
7427 goto out; 7418 goto out;
7428 } 7419 }
7429 } 7420 }
@@ -7433,8 +7424,7 @@ out:
7433} 7424}
7434 7425
7435static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, 7426static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
7436 const struct iovec *iov, loff_t offset, 7427 struct iov_iter *iter, loff_t offset)
7437 unsigned long nr_segs)
7438{ 7428{
7439 struct file *file = iocb->ki_filp; 7429 struct file *file = iocb->ki_filp;
7440 struct inode *inode = file->f_mapping->host; 7430 struct inode *inode = file->f_mapping->host;
@@ -7444,8 +7434,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
7444 bool relock = false; 7434 bool relock = false;
7445 ssize_t ret; 7435 ssize_t ret;
7446 7436
7447 if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iov, 7437 if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iter, offset))
7448 offset, nr_segs))
7449 return 0; 7438 return 0;
7450 7439
7451 atomic_inc(&inode->i_dio_count); 7440 atomic_inc(&inode->i_dio_count);
@@ -7457,7 +7446,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
7457 * we need to flush the dirty pages again to make absolutely sure 7446 * we need to flush the dirty pages again to make absolutely sure
7458 * that any outstanding dirty pages are on disk. 7447 * that any outstanding dirty pages are on disk.
7459 */ 7448 */
7460 count = iov_length(iov, nr_segs); 7449 count = iov_iter_count(iter);
7461 if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, 7450 if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
7462 &BTRFS_I(inode)->runtime_flags)) 7451 &BTRFS_I(inode)->runtime_flags))
7463 filemap_fdatawrite_range(inode->i_mapping, offset, count); 7452 filemap_fdatawrite_range(inode->i_mapping, offset, count);
@@ -7484,7 +7473,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
7484 7473
7485 ret = __blockdev_direct_IO(rw, iocb, inode, 7474 ret = __blockdev_direct_IO(rw, iocb, inode,
7486 BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev, 7475 BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev,
7487 iov, offset, nr_segs, btrfs_get_blocks_direct, NULL, 7476 iter, offset, btrfs_get_blocks_direct, NULL,
7488 btrfs_submit_direct, flags); 7477 btrfs_submit_direct, flags);
7489 if (rw & WRITE) { 7478 if (rw & WRITE) {
7490 if (ret < 0 && ret != -EIOCBQUEUED) 7479 if (ret < 0 && ret != -EIOCBQUEUED)