diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/btrfs_inode.h | 2 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 13 | ||||
-rw-r--r-- | fs/btrfs/file.c | 56 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 53 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 2 |
5 files changed, 51 insertions, 75 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index a0cf3e56fe20..4794923c410c 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
@@ -279,7 +279,7 @@ static inline void btrfs_inode_block_unlocked_dio(struct inode *inode) | |||
279 | 279 | ||
280 | static inline void btrfs_inode_resume_unlocked_dio(struct inode *inode) | 280 | static inline void btrfs_inode_resume_unlocked_dio(struct inode *inode) |
281 | { | 281 | { |
282 | smp_mb__before_clear_bit(); | 282 | smp_mb__before_atomic(); |
283 | clear_bit(BTRFS_INODE_READDIO_NEED_LOCK, | 283 | clear_bit(BTRFS_INODE_READDIO_NEED_LOCK, |
284 | &BTRFS_I(inode)->runtime_flags); | 284 | &BTRFS_I(inode)->runtime_flags); |
285 | } | 285 | } |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 23398ad430a0..a389820d158b 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -3523,7 +3523,7 @@ lock_extent_buffer_for_io(struct extent_buffer *eb, | |||
3523 | static void end_extent_buffer_writeback(struct extent_buffer *eb) | 3523 | static void end_extent_buffer_writeback(struct extent_buffer *eb) |
3524 | { | 3524 | { |
3525 | clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags); | 3525 | clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags); |
3526 | smp_mb__after_clear_bit(); | 3526 | smp_mb__after_atomic(); |
3527 | wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK); | 3527 | wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK); |
3528 | } | 3528 | } |
3529 | 3529 | ||
@@ -4576,7 +4576,8 @@ static void check_buffer_tree_ref(struct extent_buffer *eb) | |||
4576 | spin_unlock(&eb->refs_lock); | 4576 | spin_unlock(&eb->refs_lock); |
4577 | } | 4577 | } |
4578 | 4578 | ||
4579 | static void mark_extent_buffer_accessed(struct extent_buffer *eb) | 4579 | static void mark_extent_buffer_accessed(struct extent_buffer *eb, |
4580 | struct page *accessed) | ||
4580 | { | 4581 | { |
4581 | unsigned long num_pages, i; | 4582 | unsigned long num_pages, i; |
4582 | 4583 | ||
@@ -4585,7 +4586,8 @@ static void mark_extent_buffer_accessed(struct extent_buffer *eb) | |||
4585 | num_pages = num_extent_pages(eb->start, eb->len); | 4586 | num_pages = num_extent_pages(eb->start, eb->len); |
4586 | for (i = 0; i < num_pages; i++) { | 4587 | for (i = 0; i < num_pages; i++) { |
4587 | struct page *p = extent_buffer_page(eb, i); | 4588 | struct page *p = extent_buffer_page(eb, i); |
4588 | mark_page_accessed(p); | 4589 | if (p != accessed) |
4590 | mark_page_accessed(p); | ||
4589 | } | 4591 | } |
4590 | } | 4592 | } |
4591 | 4593 | ||
@@ -4599,7 +4601,7 @@ struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info, | |||
4599 | start >> PAGE_CACHE_SHIFT); | 4601 | start >> PAGE_CACHE_SHIFT); |
4600 | if (eb && atomic_inc_not_zero(&eb->refs)) { | 4602 | if (eb && atomic_inc_not_zero(&eb->refs)) { |
4601 | rcu_read_unlock(); | 4603 | rcu_read_unlock(); |
4602 | mark_extent_buffer_accessed(eb); | 4604 | mark_extent_buffer_accessed(eb, NULL); |
4603 | return eb; | 4605 | return eb; |
4604 | } | 4606 | } |
4605 | rcu_read_unlock(); | 4607 | rcu_read_unlock(); |
@@ -4694,7 +4696,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, | |||
4694 | spin_unlock(&mapping->private_lock); | 4696 | spin_unlock(&mapping->private_lock); |
4695 | unlock_page(p); | 4697 | unlock_page(p); |
4696 | page_cache_release(p); | 4698 | page_cache_release(p); |
4697 | mark_extent_buffer_accessed(exists); | 4699 | mark_extent_buffer_accessed(exists, p); |
4698 | goto free_eb; | 4700 | goto free_eb; |
4699 | } | 4701 | } |
4700 | 4702 | ||
@@ -4709,7 +4711,6 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, | |||
4709 | attach_extent_buffer_page(eb, p); | 4711 | attach_extent_buffer_page(eb, p); |
4710 | spin_unlock(&mapping->private_lock); | 4712 | spin_unlock(&mapping->private_lock); |
4711 | WARN_ON(PageDirty(p)); | 4713 | WARN_ON(PageDirty(p)); |
4712 | mark_page_accessed(p); | ||
4713 | eb->pages[i] = p; | 4714 | eb->pages[i] = p; |
4714 | if (!PageUptodate(p)) | 4715 | if (!PageUptodate(p)) |
4715 | uptodate = 0; | 4716 | uptodate = 0; |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index ad7c05909a49..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 | ||
@@ -471,11 +471,12 @@ static void btrfs_drop_pages(struct page **pages, size_t num_pages) | |||
471 | for (i = 0; i < num_pages; i++) { | 471 | for (i = 0; i < num_pages; i++) { |
472 | /* page checked is some magic around finding pages that | 472 | /* page checked is some magic around finding pages that |
473 | * have been modified without going through btrfs_set_page_dirty | 473 | * have been modified without going through btrfs_set_page_dirty |
474 | * clear it here | 474 | * clear it here. There should be no need to mark the pages |
475 | * accessed as prepare_pages should have marked them accessed | ||
476 | * in prepare_pages via find_or_create_page() | ||
475 | */ | 477 | */ |
476 | ClearPageChecked(pages[i]); | 478 | ClearPageChecked(pages[i]); |
477 | unlock_page(pages[i]); | 479 | unlock_page(pages[i]); |
478 | mark_page_accessed(pages[i]); | ||
479 | page_cache_release(pages[i]); | 480 | page_cache_release(pages[i]); |
480 | } | 481 | } |
481 | } | 482 | } |
@@ -1674,27 +1675,22 @@ again: | |||
1674 | } | 1675 | } |
1675 | 1676 | ||
1676 | static ssize_t __btrfs_direct_write(struct kiocb *iocb, | 1677 | static ssize_t __btrfs_direct_write(struct kiocb *iocb, |
1677 | const struct iovec *iov, | 1678 | struct iov_iter *from, |
1678 | unsigned long nr_segs, loff_t pos, | 1679 | loff_t pos) |
1679 | size_t count, size_t ocount) | ||
1680 | { | 1680 | { |
1681 | struct file *file = iocb->ki_filp; | 1681 | struct file *file = iocb->ki_filp; |
1682 | struct iov_iter i; | ||
1683 | ssize_t written; | 1682 | ssize_t written; |
1684 | ssize_t written_buffered; | 1683 | ssize_t written_buffered; |
1685 | loff_t endbyte; | 1684 | loff_t endbyte; |
1686 | int err; | 1685 | int err; |
1687 | 1686 | ||
1688 | written = generic_file_direct_write(iocb, iov, &nr_segs, pos, | 1687 | written = generic_file_direct_write(iocb, from, pos); |
1689 | count, ocount); | ||
1690 | 1688 | ||
1691 | if (written < 0 || written == count) | 1689 | if (written < 0 || !iov_iter_count(from)) |
1692 | return written; | 1690 | return written; |
1693 | 1691 | ||
1694 | pos += written; | 1692 | pos += written; |
1695 | count -= written; | 1693 | written_buffered = __btrfs_buffered_write(file, from, pos); |
1696 | iov_iter_init(&i, iov, nr_segs, count, written); | ||
1697 | written_buffered = __btrfs_buffered_write(file, &i, pos); | ||
1698 | if (written_buffered < 0) { | 1694 | if (written_buffered < 0) { |
1699 | err = written_buffered; | 1695 | err = written_buffered; |
1700 | goto out; | 1696 | goto out; |
@@ -1729,9 +1725,8 @@ static void update_time_for_write(struct inode *inode) | |||
1729 | inode_inc_iversion(inode); | 1725 | inode_inc_iversion(inode); |
1730 | } | 1726 | } |
1731 | 1727 | ||
1732 | static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | 1728 | static ssize_t btrfs_file_write_iter(struct kiocb *iocb, |
1733 | const struct iovec *iov, | 1729 | struct iov_iter *from) |
1734 | unsigned long nr_segs, loff_t pos) | ||
1735 | { | 1730 | { |
1736 | struct file *file = iocb->ki_filp; | 1731 | struct file *file = iocb->ki_filp; |
1737 | struct inode *inode = file_inode(file); | 1732 | struct inode *inode = file_inode(file); |
@@ -1740,18 +1735,12 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1740 | u64 end_pos; | 1735 | u64 end_pos; |
1741 | ssize_t num_written = 0; | 1736 | ssize_t num_written = 0; |
1742 | ssize_t err = 0; | 1737 | ssize_t err = 0; |
1743 | size_t count, ocount; | 1738 | size_t count = iov_iter_count(from); |
1744 | 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; | ||
1745 | 1741 | ||
1746 | mutex_lock(&inode->i_mutex); | 1742 | mutex_lock(&inode->i_mutex); |
1747 | 1743 | ||
1748 | err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); | ||
1749 | if (err) { | ||
1750 | mutex_unlock(&inode->i_mutex); | ||
1751 | goto out; | ||
1752 | } | ||
1753 | count = ocount; | ||
1754 | |||
1755 | current->backing_dev_info = inode->i_mapping->backing_dev_info; | 1744 | current->backing_dev_info = inode->i_mapping->backing_dev_info; |
1756 | 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)); |
1757 | if (err) { | 1746 | if (err) { |
@@ -1764,6 +1753,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1764 | goto out; | 1753 | goto out; |
1765 | } | 1754 | } |
1766 | 1755 | ||
1756 | iov_iter_truncate(from, count); | ||
1757 | |||
1767 | err = file_remove_suid(file); | 1758 | err = file_remove_suid(file); |
1768 | if (err) { | 1759 | if (err) { |
1769 | mutex_unlock(&inode->i_mutex); | 1760 | mutex_unlock(&inode->i_mutex); |
@@ -1805,14 +1796,9 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1805 | atomic_inc(&BTRFS_I(inode)->sync_writers); | 1796 | atomic_inc(&BTRFS_I(inode)->sync_writers); |
1806 | 1797 | ||
1807 | if (unlikely(file->f_flags & O_DIRECT)) { | 1798 | if (unlikely(file->f_flags & O_DIRECT)) { |
1808 | num_written = __btrfs_direct_write(iocb, iov, nr_segs, | 1799 | num_written = __btrfs_direct_write(iocb, from, pos); |
1809 | pos, count, ocount); | ||
1810 | } else { | 1800 | } else { |
1811 | struct iov_iter i; | 1801 | num_written = __btrfs_buffered_write(file, from, pos); |
1812 | |||
1813 | iov_iter_init(&i, iov, nr_segs, count, num_written); | ||
1814 | |||
1815 | num_written = __btrfs_buffered_write(file, &i, pos); | ||
1816 | if (num_written > 0) | 1802 | if (num_written > 0) |
1817 | iocb->ki_pos = pos + num_written; | 1803 | iocb->ki_pos = pos + num_written; |
1818 | } | 1804 | } |
@@ -2739,11 +2725,11 @@ out: | |||
2739 | 2725 | ||
2740 | const struct file_operations btrfs_file_operations = { | 2726 | const struct file_operations btrfs_file_operations = { |
2741 | .llseek = btrfs_file_llseek, | 2727 | .llseek = btrfs_file_llseek, |
2742 | .read = do_sync_read, | 2728 | .read = new_sync_read, |
2743 | .write = do_sync_write, | 2729 | .write = new_sync_write, |
2744 | .aio_read = generic_file_aio_read, | 2730 | .read_iter = generic_file_read_iter, |
2745 | .splice_read = generic_file_splice_read, | 2731 | .splice_read = generic_file_splice_read, |
2746 | .aio_write = btrfs_file_aio_write, | 2732 | .write_iter = btrfs_file_write_iter, |
2747 | .mmap = btrfs_file_mmap, | 2733 | .mmap = btrfs_file_mmap, |
2748 | .open = generic_file_open, | 2734 | .open = generic_file_open, |
2749 | .release = btrfs_release_file, | 2735 | .release = btrfs_release_file, |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 6b65fab27a1a..3668048e16f8 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -7199,7 +7199,7 @@ static void btrfs_end_dio_bio(struct bio *bio, int err) | |||
7199 | * before atomic variable goto zero, we must make sure | 7199 | * before atomic variable goto zero, we must make sure |
7200 | * dip->errors is perceived to be set. | 7200 | * dip->errors is perceived to be set. |
7201 | */ | 7201 | */ |
7202 | smp_mb__before_atomic_dec(); | 7202 | smp_mb__before_atomic(); |
7203 | } | 7203 | } |
7204 | 7204 | ||
7205 | /* if there are more bios still pending for this dio, just exit */ | 7205 | /* if there are more bios still pending for this dio, just exit */ |
@@ -7379,7 +7379,7 @@ out_err: | |||
7379 | * before atomic variable goto zero, we must | 7379 | * before atomic variable goto zero, we must |
7380 | * make sure dip->errors is perceived to be set. | 7380 | * make sure dip->errors is perceived to be set. |
7381 | */ | 7381 | */ |
7382 | smp_mb__before_atomic_dec(); | 7382 | smp_mb__before_atomic(); |
7383 | if (atomic_dec_and_test(&dip->pending_bios)) | 7383 | if (atomic_dec_and_test(&dip->pending_bios)) |
7384 | bio_io_error(dip->orig_bio); | 7384 | bio_io_error(dip->orig_bio); |
7385 | 7385 | ||
@@ -7464,39 +7464,30 @@ free_ordered: | |||
7464 | } | 7464 | } |
7465 | 7465 | ||
7466 | static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb, | 7466 | static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb, |
7467 | const struct iovec *iov, loff_t offset, | 7467 | const struct iov_iter *iter, loff_t offset) |
7468 | unsigned long nr_segs) | ||
7469 | { | 7468 | { |
7470 | int seg; | 7469 | int seg; |
7471 | int i; | 7470 | int i; |
7472 | size_t size; | ||
7473 | unsigned long addr; | ||
7474 | unsigned blocksize_mask = root->sectorsize - 1; | 7471 | unsigned blocksize_mask = root->sectorsize - 1; |
7475 | ssize_t retval = -EINVAL; | 7472 | ssize_t retval = -EINVAL; |
7476 | loff_t end = offset; | ||
7477 | 7473 | ||
7478 | if (offset & blocksize_mask) | 7474 | if (offset & blocksize_mask) |
7479 | goto out; | 7475 | goto out; |
7480 | 7476 | ||
7481 | /* Check the memory alignment. Blocks cannot straddle pages */ | 7477 | if (iov_iter_alignment(iter) & blocksize_mask) |
7482 | for (seg = 0; seg < nr_segs; seg++) { | 7478 | goto out; |
7483 | addr = (unsigned long)iov[seg].iov_base; | ||
7484 | size = iov[seg].iov_len; | ||
7485 | end += size; | ||
7486 | if ((addr & blocksize_mask) || (size & blocksize_mask)) | ||
7487 | goto out; | ||
7488 | |||
7489 | /* If this is a write we don't need to check anymore */ | ||
7490 | if (rw & WRITE) | ||
7491 | continue; | ||
7492 | 7479 | ||
7493 | /* | 7480 | /* If this is a write we don't need to check anymore */ |
7494 | * Check to make sure we don't have duplicate iov_base's in this | 7481 | if (rw & WRITE) |
7495 | * iovec, if so return EINVAL, otherwise we'll get csum errors | 7482 | return 0; |
7496 | * when reading back. | 7483 | /* |
7497 | */ | 7484 | * Check to make sure we don't have duplicate iov_base's in this |
7498 | for (i = seg + 1; i < nr_segs; i++) { | 7485 | * iovec, if so return EINVAL, otherwise we'll get csum errors |
7499 | if (iov[seg].iov_base == iov[i].iov_base) | 7486 | * when reading back. |
7487 | */ | ||
7488 | for (seg = 0; seg < iter->nr_segs; seg++) { | ||
7489 | for (i = seg + 1; i < iter->nr_segs; i++) { | ||
7490 | if (iter->iov[seg].iov_base == iter->iov[i].iov_base) | ||
7500 | goto out; | 7491 | goto out; |
7501 | } | 7492 | } |
7502 | } | 7493 | } |
@@ -7506,8 +7497,7 @@ out: | |||
7506 | } | 7497 | } |
7507 | 7498 | ||
7508 | static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | 7499 | static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, |
7509 | const struct iovec *iov, loff_t offset, | 7500 | struct iov_iter *iter, loff_t offset) |
7510 | unsigned long nr_segs) | ||
7511 | { | 7501 | { |
7512 | struct file *file = iocb->ki_filp; | 7502 | struct file *file = iocb->ki_filp; |
7513 | struct inode *inode = file->f_mapping->host; | 7503 | struct inode *inode = file->f_mapping->host; |
@@ -7517,12 +7507,11 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
7517 | bool relock = false; | 7507 | bool relock = false; |
7518 | ssize_t ret; | 7508 | ssize_t ret; |
7519 | 7509 | ||
7520 | if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iov, | 7510 | if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iter, offset)) |
7521 | offset, nr_segs)) | ||
7522 | return 0; | 7511 | return 0; |
7523 | 7512 | ||
7524 | atomic_inc(&inode->i_dio_count); | 7513 | atomic_inc(&inode->i_dio_count); |
7525 | smp_mb__after_atomic_inc(); | 7514 | smp_mb__after_atomic(); |
7526 | 7515 | ||
7527 | /* | 7516 | /* |
7528 | * The generic stuff only does filemap_write_and_wait_range, which | 7517 | * The generic stuff only does filemap_write_and_wait_range, which |
@@ -7530,7 +7519,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
7530 | * we need to flush the dirty pages again to make absolutely sure | 7519 | * we need to flush the dirty pages again to make absolutely sure |
7531 | * that any outstanding dirty pages are on disk. | 7520 | * that any outstanding dirty pages are on disk. |
7532 | */ | 7521 | */ |
7533 | count = iov_length(iov, nr_segs); | 7522 | count = iov_iter_count(iter); |
7534 | if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, | 7523 | if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, |
7535 | &BTRFS_I(inode)->runtime_flags)) | 7524 | &BTRFS_I(inode)->runtime_flags)) |
7536 | filemap_fdatawrite_range(inode->i_mapping, offset, count); | 7525 | filemap_fdatawrite_range(inode->i_mapping, offset, count); |
@@ -7557,7 +7546,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
7557 | 7546 | ||
7558 | ret = __blockdev_direct_IO(rw, iocb, inode, | 7547 | ret = __blockdev_direct_IO(rw, iocb, inode, |
7559 | BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev, | 7548 | BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev, |
7560 | iov, offset, nr_segs, btrfs_get_blocks_direct, NULL, | 7549 | iter, offset, btrfs_get_blocks_direct, NULL, |
7561 | btrfs_submit_direct, flags); | 7550 | btrfs_submit_direct, flags); |
7562 | if (rw & WRITE) { | 7551 | if (rw & WRITE) { |
7563 | if (ret < 0 && ret != -EIOCBQUEUED) | 7552 | if (ret < 0 && ret != -EIOCBQUEUED) |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 6ea15469c63f..0d321c23069a 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -643,7 +643,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, | |||
643 | return -EINVAL; | 643 | return -EINVAL; |
644 | 644 | ||
645 | atomic_inc(&root->will_be_snapshoted); | 645 | atomic_inc(&root->will_be_snapshoted); |
646 | smp_mb__after_atomic_inc(); | 646 | smp_mb__after_atomic(); |
647 | btrfs_wait_nocow_write(root); | 647 | btrfs_wait_nocow_write(root); |
648 | 648 | ||
649 | ret = btrfs_start_delalloc_inodes(root, 0); | 649 | ret = btrfs_start_delalloc_inodes(root, 0); |