diff options
| author | Michal Marek <mmarek@suse.cz> | 2010-10-27 18:15:57 -0400 |
|---|---|---|
| committer | Michal Marek <mmarek@suse.cz> | 2010-10-27 18:15:57 -0400 |
| commit | b74b953b998bcc2db91b694446f3a2619ec32de6 (patch) | |
| tree | 6ce24caabd730f6ae9287ed0676ec32e6ff31e9d /fs/btrfs/file.c | |
| parent | abb438526201c6a79949ad45375c051b6681c253 (diff) | |
| parent | f6f94e2ab1b33f0082ac22d71f66385a60d8157f (diff) | |
Merge commit 'v2.6.36' into kbuild/misc
Update to be able to fix a recent change to scripts/basic/docproc.c
(commit eda603f).
Diffstat (limited to 'fs/btrfs/file.c')
| -rw-r--r-- | fs/btrfs/file.c | 213 |
1 files changed, 134 insertions, 79 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index c02033596f02..e354c33df082 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/writeback.h> | 28 | #include <linux/writeback.h> |
| 29 | #include <linux/statfs.h> | 29 | #include <linux/statfs.h> |
| 30 | #include <linux/compat.h> | 30 | #include <linux/compat.h> |
| 31 | #include <linux/slab.h> | ||
| 31 | #include "ctree.h" | 32 | #include "ctree.h" |
| 32 | #include "disk-io.h" | 33 | #include "disk-io.h" |
| 33 | #include "transaction.h" | 34 | #include "transaction.h" |
| @@ -45,32 +46,42 @@ | |||
| 45 | static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, | 46 | static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, |
| 46 | int write_bytes, | 47 | int write_bytes, |
| 47 | struct page **prepared_pages, | 48 | struct page **prepared_pages, |
| 48 | const char __user *buf) | 49 | struct iov_iter *i) |
| 49 | { | 50 | { |
| 50 | long page_fault = 0; | 51 | size_t copied; |
| 51 | int i; | 52 | int pg = 0; |
| 52 | int offset = pos & (PAGE_CACHE_SIZE - 1); | 53 | int offset = pos & (PAGE_CACHE_SIZE - 1); |
| 53 | 54 | ||
| 54 | for (i = 0; i < num_pages && write_bytes > 0; i++, offset = 0) { | 55 | while (write_bytes > 0) { |
| 55 | size_t count = min_t(size_t, | 56 | size_t count = min_t(size_t, |
| 56 | PAGE_CACHE_SIZE - offset, write_bytes); | 57 | PAGE_CACHE_SIZE - offset, write_bytes); |
| 57 | struct page *page = prepared_pages[i]; | 58 | struct page *page = prepared_pages[pg]; |
| 58 | fault_in_pages_readable(buf, count); | 59 | again: |
| 60 | if (unlikely(iov_iter_fault_in_readable(i, count))) | ||
| 61 | return -EFAULT; | ||
| 59 | 62 | ||
| 60 | /* Copy data from userspace to the current page */ | 63 | /* Copy data from userspace to the current page */ |
| 61 | kmap(page); | 64 | copied = iov_iter_copy_from_user(page, i, offset, count); |
| 62 | page_fault = __copy_from_user(page_address(page) + offset, | 65 | |
| 63 | buf, count); | ||
| 64 | /* Flush processor's dcache for this page */ | 66 | /* Flush processor's dcache for this page */ |
| 65 | flush_dcache_page(page); | 67 | flush_dcache_page(page); |
| 66 | kunmap(page); | 68 | iov_iter_advance(i, copied); |
| 67 | buf += count; | 69 | write_bytes -= copied; |
| 68 | write_bytes -= count; | ||
| 69 | 70 | ||
| 70 | if (page_fault) | 71 | if (unlikely(copied == 0)) { |
| 71 | break; | 72 | count = min_t(size_t, PAGE_CACHE_SIZE - offset, |
| 73 | iov_iter_single_seg_count(i)); | ||
| 74 | goto again; | ||
| 75 | } | ||
| 76 | |||
| 77 | if (unlikely(copied < PAGE_CACHE_SIZE - offset)) { | ||
| 78 | offset += copied; | ||
| 79 | } else { | ||
| 80 | pg++; | ||
| 81 | offset = 0; | ||
| 82 | } | ||
| 72 | } | 83 | } |
| 73 | return page_fault ? -EFAULT : 0; | 84 | return 0; |
| 74 | } | 85 | } |
| 75 | 86 | ||
| 76 | /* | 87 | /* |
| @@ -123,9 +134,9 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
| 123 | root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | 134 | root->sectorsize - 1) & ~((u64)root->sectorsize - 1); |
| 124 | 135 | ||
| 125 | end_of_last_block = start_pos + num_bytes - 1; | 136 | end_of_last_block = start_pos + num_bytes - 1; |
| 126 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block); | 137 | err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, |
| 127 | if (err) | 138 | NULL); |
| 128 | return err; | 139 | BUG_ON(err); |
| 129 | 140 | ||
| 130 | for (i = 0; i < num_pages; i++) { | 141 | for (i = 0; i < num_pages; i++) { |
| 131 | struct page *p = pages[i]; | 142 | struct page *p = pages[i]; |
| @@ -140,7 +151,7 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
| 140 | * at this time. | 151 | * at this time. |
| 141 | */ | 152 | */ |
| 142 | } | 153 | } |
| 143 | return err; | 154 | return 0; |
| 144 | } | 155 | } |
| 145 | 156 | ||
| 146 | /* | 157 | /* |
| @@ -720,13 +731,15 @@ again: | |||
| 720 | inode->i_ino, orig_offset); | 731 | inode->i_ino, orig_offset); |
| 721 | BUG_ON(ret); | 732 | BUG_ON(ret); |
| 722 | } | 733 | } |
| 723 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
| 724 | struct btrfs_file_extent_item); | ||
| 725 | if (del_nr == 0) { | 734 | if (del_nr == 0) { |
| 735 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
| 736 | struct btrfs_file_extent_item); | ||
| 726 | btrfs_set_file_extent_type(leaf, fi, | 737 | btrfs_set_file_extent_type(leaf, fi, |
| 727 | BTRFS_FILE_EXTENT_REG); | 738 | BTRFS_FILE_EXTENT_REG); |
| 728 | btrfs_mark_buffer_dirty(leaf); | 739 | btrfs_mark_buffer_dirty(leaf); |
| 729 | } else { | 740 | } else { |
| 741 | fi = btrfs_item_ptr(leaf, del_slot - 1, | ||
| 742 | struct btrfs_file_extent_item); | ||
| 730 | btrfs_set_file_extent_type(leaf, fi, | 743 | btrfs_set_file_extent_type(leaf, fi, |
| 731 | BTRFS_FILE_EXTENT_REG); | 744 | BTRFS_FILE_EXTENT_REG); |
| 732 | btrfs_set_file_extent_num_bytes(leaf, fi, | 745 | btrfs_set_file_extent_num_bytes(leaf, fi, |
| @@ -751,6 +764,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, | |||
| 751 | loff_t pos, unsigned long first_index, | 764 | loff_t pos, unsigned long first_index, |
| 752 | unsigned long last_index, size_t write_bytes) | 765 | unsigned long last_index, size_t write_bytes) |
| 753 | { | 766 | { |
| 767 | struct extent_state *cached_state = NULL; | ||
| 754 | int i; | 768 | int i; |
| 755 | unsigned long index = pos >> PAGE_CACHE_SHIFT; | 769 | unsigned long index = pos >> PAGE_CACHE_SHIFT; |
| 756 | struct inode *inode = fdentry(file)->d_inode; | 770 | struct inode *inode = fdentry(file)->d_inode; |
| @@ -779,16 +793,18 @@ again: | |||
| 779 | } | 793 | } |
| 780 | if (start_pos < inode->i_size) { | 794 | if (start_pos < inode->i_size) { |
| 781 | struct btrfs_ordered_extent *ordered; | 795 | struct btrfs_ordered_extent *ordered; |
| 782 | lock_extent(&BTRFS_I(inode)->io_tree, | 796 | lock_extent_bits(&BTRFS_I(inode)->io_tree, |
| 783 | start_pos, last_pos - 1, GFP_NOFS); | 797 | start_pos, last_pos - 1, 0, &cached_state, |
| 798 | GFP_NOFS); | ||
| 784 | ordered = btrfs_lookup_first_ordered_extent(inode, | 799 | ordered = btrfs_lookup_first_ordered_extent(inode, |
| 785 | last_pos - 1); | 800 | last_pos - 1); |
| 786 | if (ordered && | 801 | if (ordered && |
| 787 | ordered->file_offset + ordered->len > start_pos && | 802 | ordered->file_offset + ordered->len > start_pos && |
| 788 | ordered->file_offset < last_pos) { | 803 | ordered->file_offset < last_pos) { |
| 789 | btrfs_put_ordered_extent(ordered); | 804 | btrfs_put_ordered_extent(ordered); |
| 790 | unlock_extent(&BTRFS_I(inode)->io_tree, | 805 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, |
| 791 | start_pos, last_pos - 1, GFP_NOFS); | 806 | start_pos, last_pos - 1, |
| 807 | &cached_state, GFP_NOFS); | ||
| 792 | for (i = 0; i < num_pages; i++) { | 808 | for (i = 0; i < num_pages; i++) { |
| 793 | unlock_page(pages[i]); | 809 | unlock_page(pages[i]); |
| 794 | page_cache_release(pages[i]); | 810 | page_cache_release(pages[i]); |
| @@ -800,12 +816,13 @@ again: | |||
| 800 | if (ordered) | 816 | if (ordered) |
| 801 | btrfs_put_ordered_extent(ordered); | 817 | btrfs_put_ordered_extent(ordered); |
| 802 | 818 | ||
| 803 | clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos, | 819 | clear_extent_bit(&BTRFS_I(inode)->io_tree, start_pos, |
| 804 | last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC | | 820 | last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC | |
| 805 | EXTENT_DO_ACCOUNTING, | 821 | EXTENT_DO_ACCOUNTING, 0, 0, &cached_state, |
| 806 | GFP_NOFS); | 822 | GFP_NOFS); |
| 807 | unlock_extent(&BTRFS_I(inode)->io_tree, | 823 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, |
| 808 | start_pos, last_pos - 1, GFP_NOFS); | 824 | start_pos, last_pos - 1, &cached_state, |
| 825 | GFP_NOFS); | ||
| 809 | } | 826 | } |
| 810 | for (i = 0; i < num_pages; i++) { | 827 | for (i = 0; i < num_pages; i++) { |
| 811 | clear_page_dirty_for_io(pages[i]); | 828 | clear_page_dirty_for_io(pages[i]); |
| @@ -815,45 +832,46 @@ again: | |||
| 815 | return 0; | 832 | return 0; |
| 816 | } | 833 | } |
| 817 | 834 | ||
| 818 | static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | 835 | static ssize_t btrfs_file_aio_write(struct kiocb *iocb, |
| 819 | size_t count, loff_t *ppos) | 836 | const struct iovec *iov, |
| 837 | unsigned long nr_segs, loff_t pos) | ||
| 820 | { | 838 | { |
| 821 | loff_t pos; | 839 | struct file *file = iocb->ki_filp; |
| 840 | struct inode *inode = fdentry(file)->d_inode; | ||
| 841 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 842 | struct page *pinned[2]; | ||
| 843 | struct page **pages = NULL; | ||
| 844 | struct iov_iter i; | ||
| 845 | loff_t *ppos = &iocb->ki_pos; | ||
| 822 | loff_t start_pos; | 846 | loff_t start_pos; |
| 823 | ssize_t num_written = 0; | 847 | ssize_t num_written = 0; |
| 824 | ssize_t err = 0; | 848 | ssize_t err = 0; |
| 849 | size_t count; | ||
| 850 | size_t ocount; | ||
| 825 | int ret = 0; | 851 | int ret = 0; |
| 826 | struct inode *inode = fdentry(file)->d_inode; | ||
| 827 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 828 | struct page **pages = NULL; | ||
| 829 | int nrptrs; | 852 | int nrptrs; |
| 830 | struct page *pinned[2]; | ||
| 831 | unsigned long first_index; | 853 | unsigned long first_index; |
| 832 | unsigned long last_index; | 854 | unsigned long last_index; |
| 833 | int will_write; | 855 | int will_write; |
| 856 | int buffered = 0; | ||
| 834 | 857 | ||
| 835 | will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) || | 858 | will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) || |
| 836 | (file->f_flags & O_DIRECT)); | 859 | (file->f_flags & O_DIRECT)); |
| 837 | 860 | ||
| 838 | nrptrs = min((count + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE, | ||
| 839 | PAGE_CACHE_SIZE / (sizeof(struct page *))); | ||
| 840 | pinned[0] = NULL; | 861 | pinned[0] = NULL; |
| 841 | pinned[1] = NULL; | 862 | pinned[1] = NULL; |
| 842 | 863 | ||
| 843 | pos = *ppos; | ||
| 844 | start_pos = pos; | 864 | start_pos = pos; |
| 845 | 865 | ||
| 846 | vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); | 866 | vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); |
| 847 | 867 | ||
| 848 | /* do the reserve before the mutex lock in case we have to do some | ||
| 849 | * flushing. We wouldn't deadlock, but this is more polite. | ||
| 850 | */ | ||
| 851 | err = btrfs_reserve_metadata_for_delalloc(root, inode, 1); | ||
| 852 | if (err) | ||
| 853 | goto out_nolock; | ||
| 854 | |||
| 855 | mutex_lock(&inode->i_mutex); | 868 | mutex_lock(&inode->i_mutex); |
| 856 | 869 | ||
| 870 | err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); | ||
| 871 | if (err) | ||
| 872 | goto out; | ||
| 873 | count = ocount; | ||
| 874 | |||
| 857 | current->backing_dev_info = inode->i_mapping->backing_dev_info; | 875 | current->backing_dev_info = inode->i_mapping->backing_dev_info; |
| 858 | err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); | 876 | err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); |
| 859 | if (err) | 877 | if (err) |
| @@ -867,15 +885,53 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 867 | goto out; | 885 | goto out; |
| 868 | 886 | ||
| 869 | file_update_time(file); | 887 | file_update_time(file); |
| 888 | BTRFS_I(inode)->sequence++; | ||
| 870 | 889 | ||
| 890 | if (unlikely(file->f_flags & O_DIRECT)) { | ||
| 891 | num_written = generic_file_direct_write(iocb, iov, &nr_segs, | ||
| 892 | pos, ppos, count, | ||
| 893 | ocount); | ||
| 894 | /* | ||
| 895 | * the generic O_DIRECT will update in-memory i_size after the | ||
| 896 | * DIOs are done. But our endio handlers that update the on | ||
| 897 | * disk i_size never update past the in memory i_size. So we | ||
| 898 | * need one more update here to catch any additions to the | ||
| 899 | * file | ||
| 900 | */ | ||
| 901 | if (inode->i_size != BTRFS_I(inode)->disk_i_size) { | ||
| 902 | btrfs_ordered_update_i_size(inode, inode->i_size, NULL); | ||
| 903 | mark_inode_dirty(inode); | ||
| 904 | } | ||
| 905 | |||
| 906 | if (num_written < 0) { | ||
| 907 | ret = num_written; | ||
| 908 | num_written = 0; | ||
| 909 | goto out; | ||
| 910 | } else if (num_written == count) { | ||
| 911 | /* pick up pos changes done by the generic code */ | ||
| 912 | pos = *ppos; | ||
| 913 | goto out; | ||
| 914 | } | ||
| 915 | /* | ||
| 916 | * We are going to do buffered for the rest of the range, so we | ||
| 917 | * need to make sure to invalidate the buffered pages when we're | ||
| 918 | * done. | ||
| 919 | */ | ||
| 920 | buffered = 1; | ||
| 921 | pos += num_written; | ||
| 922 | } | ||
| 923 | |||
| 924 | iov_iter_init(&i, iov, nr_segs, count, num_written); | ||
| 925 | nrptrs = min((iov_iter_count(&i) + PAGE_CACHE_SIZE - 1) / | ||
| 926 | PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / | ||
| 927 | (sizeof(struct page *))); | ||
| 871 | pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); | 928 | pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); |
| 872 | 929 | ||
| 873 | /* generic_write_checks can change our pos */ | 930 | /* generic_write_checks can change our pos */ |
| 874 | start_pos = pos; | 931 | start_pos = pos; |
| 875 | 932 | ||
| 876 | BTRFS_I(inode)->sequence++; | ||
| 877 | first_index = pos >> PAGE_CACHE_SHIFT; | 933 | first_index = pos >> PAGE_CACHE_SHIFT; |
| 878 | last_index = (pos + count) >> PAGE_CACHE_SHIFT; | 934 | last_index = (pos + iov_iter_count(&i)) >> PAGE_CACHE_SHIFT; |
| 879 | 935 | ||
| 880 | /* | 936 | /* |
| 881 | * there are lots of better ways to do this, but this code | 937 | * there are lots of better ways to do this, but this code |
| @@ -892,7 +948,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 892 | unlock_page(pinned[0]); | 948 | unlock_page(pinned[0]); |
| 893 | } | 949 | } |
| 894 | } | 950 | } |
| 895 | if ((pos + count) & (PAGE_CACHE_SIZE - 1)) { | 951 | if ((pos + iov_iter_count(&i)) & (PAGE_CACHE_SIZE - 1)) { |
| 896 | pinned[1] = grab_cache_page(inode->i_mapping, last_index); | 952 | pinned[1] = grab_cache_page(inode->i_mapping, last_index); |
| 897 | if (!PageUptodate(pinned[1])) { | 953 | if (!PageUptodate(pinned[1])) { |
| 898 | ret = btrfs_readpage(NULL, pinned[1]); | 954 | ret = btrfs_readpage(NULL, pinned[1]); |
| @@ -903,10 +959,10 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 903 | } | 959 | } |
| 904 | } | 960 | } |
| 905 | 961 | ||
| 906 | while (count > 0) { | 962 | while (iov_iter_count(&i) > 0) { |
| 907 | size_t offset = pos & (PAGE_CACHE_SIZE - 1); | 963 | size_t offset = pos & (PAGE_CACHE_SIZE - 1); |
| 908 | size_t write_bytes = min(count, nrptrs * | 964 | size_t write_bytes = min(iov_iter_count(&i), |
| 909 | (size_t)PAGE_CACHE_SIZE - | 965 | nrptrs * (size_t)PAGE_CACHE_SIZE - |
| 910 | offset); | 966 | offset); |
| 911 | size_t num_pages = (write_bytes + PAGE_CACHE_SIZE - 1) >> | 967 | size_t num_pages = (write_bytes + PAGE_CACHE_SIZE - 1) >> |
| 912 | PAGE_CACHE_SHIFT; | 968 | PAGE_CACHE_SHIFT; |
| @@ -914,7 +970,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 914 | WARN_ON(num_pages > nrptrs); | 970 | WARN_ON(num_pages > nrptrs); |
| 915 | memset(pages, 0, sizeof(struct page *) * nrptrs); | 971 | memset(pages, 0, sizeof(struct page *) * nrptrs); |
| 916 | 972 | ||
| 917 | ret = btrfs_check_data_free_space(root, inode, write_bytes); | 973 | ret = btrfs_delalloc_reserve_space(inode, write_bytes); |
| 918 | if (ret) | 974 | if (ret) |
| 919 | goto out; | 975 | goto out; |
| 920 | 976 | ||
| @@ -922,26 +978,20 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 922 | pos, first_index, last_index, | 978 | pos, first_index, last_index, |
| 923 | write_bytes); | 979 | write_bytes); |
| 924 | if (ret) { | 980 | if (ret) { |
| 925 | btrfs_free_reserved_data_space(root, inode, | 981 | btrfs_delalloc_release_space(inode, write_bytes); |
| 926 | write_bytes); | ||
| 927 | goto out; | 982 | goto out; |
| 928 | } | 983 | } |
| 929 | 984 | ||
| 930 | ret = btrfs_copy_from_user(pos, num_pages, | 985 | ret = btrfs_copy_from_user(pos, num_pages, |
| 931 | write_bytes, pages, buf); | 986 | write_bytes, pages, &i); |
| 932 | if (ret) { | 987 | if (ret == 0) { |
| 933 | btrfs_free_reserved_data_space(root, inode, | 988 | dirty_and_release_pages(NULL, root, file, pages, |
| 934 | write_bytes); | 989 | num_pages, pos, write_bytes); |
| 935 | btrfs_drop_pages(pages, num_pages); | ||
| 936 | goto out; | ||
| 937 | } | 990 | } |
| 938 | 991 | ||
| 939 | ret = dirty_and_release_pages(NULL, root, file, pages, | ||
| 940 | num_pages, pos, write_bytes); | ||
| 941 | btrfs_drop_pages(pages, num_pages); | 992 | btrfs_drop_pages(pages, num_pages); |
| 942 | if (ret) { | 993 | if (ret) { |
| 943 | btrfs_free_reserved_data_space(root, inode, | 994 | btrfs_delalloc_release_space(inode, write_bytes); |
| 944 | write_bytes); | ||
| 945 | goto out; | 995 | goto out; |
| 946 | } | 996 | } |
| 947 | 997 | ||
| @@ -957,8 +1007,6 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 957 | btrfs_throttle(root); | 1007 | btrfs_throttle(root); |
| 958 | } | 1008 | } |
| 959 | 1009 | ||
| 960 | buf += write_bytes; | ||
| 961 | count -= write_bytes; | ||
| 962 | pos += write_bytes; | 1010 | pos += write_bytes; |
| 963 | num_written += write_bytes; | 1011 | num_written += write_bytes; |
| 964 | 1012 | ||
| @@ -968,9 +1016,7 @@ out: | |||
| 968 | mutex_unlock(&inode->i_mutex); | 1016 | mutex_unlock(&inode->i_mutex); |
| 969 | if (ret) | 1017 | if (ret) |
| 970 | err = ret; | 1018 | err = ret; |
| 971 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | ||
| 972 | 1019 | ||
| 973 | out_nolock: | ||
| 974 | kfree(pages); | 1020 | kfree(pages); |
| 975 | if (pinned[0]) | 1021 | if (pinned[0]) |
| 976 | page_cache_release(pinned[0]); | 1022 | page_cache_release(pinned[0]); |
| @@ -1000,7 +1046,7 @@ out_nolock: | |||
| 1000 | num_written = err; | 1046 | num_written = err; |
| 1001 | 1047 | ||
| 1002 | if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { | 1048 | if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { |
| 1003 | trans = btrfs_start_transaction(root, 1); | 1049 | trans = btrfs_start_transaction(root, 0); |
| 1004 | ret = btrfs_log_dentry_safe(trans, root, | 1050 | ret = btrfs_log_dentry_safe(trans, root, |
| 1005 | file->f_dentry); | 1051 | file->f_dentry); |
| 1006 | if (ret == 0) { | 1052 | if (ret == 0) { |
| @@ -1015,7 +1061,7 @@ out_nolock: | |||
| 1015 | btrfs_end_transaction(trans, root); | 1061 | btrfs_end_transaction(trans, root); |
| 1016 | } | 1062 | } |
| 1017 | } | 1063 | } |
| 1018 | if (file->f_flags & O_DIRECT) { | 1064 | if (file->f_flags & O_DIRECT && buffered) { |
| 1019 | invalidate_mapping_pages(inode->i_mapping, | 1065 | invalidate_mapping_pages(inode->i_mapping, |
| 1020 | start_pos >> PAGE_CACHE_SHIFT, | 1066 | start_pos >> PAGE_CACHE_SHIFT, |
| 1021 | (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); | 1067 | (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); |
| @@ -1055,8 +1101,9 @@ int btrfs_release_file(struct inode *inode, struct file *filp) | |||
| 1055 | * important optimization for directories because holding the mutex prevents | 1101 | * important optimization for directories because holding the mutex prevents |
| 1056 | * new operations on the dir while we write to disk. | 1102 | * new operations on the dir while we write to disk. |
| 1057 | */ | 1103 | */ |
| 1058 | int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | 1104 | int btrfs_sync_file(struct file *file, int datasync) |
| 1059 | { | 1105 | { |
| 1106 | struct dentry *dentry = file->f_path.dentry; | ||
| 1060 | struct inode *inode = dentry->d_inode; | 1107 | struct inode *inode = dentry->d_inode; |
| 1061 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1108 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 1062 | int ret = 0; | 1109 | int ret = 0; |
| @@ -1093,12 +1140,12 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1093 | /* | 1140 | /* |
| 1094 | * ok we haven't committed the transaction yet, lets do a commit | 1141 | * ok we haven't committed the transaction yet, lets do a commit |
| 1095 | */ | 1142 | */ |
| 1096 | if (file && file->private_data) | 1143 | if (file->private_data) |
| 1097 | btrfs_ioctl_trans_end(file); | 1144 | btrfs_ioctl_trans_end(file); |
| 1098 | 1145 | ||
| 1099 | trans = btrfs_start_transaction(root, 1); | 1146 | trans = btrfs_start_transaction(root, 0); |
| 1100 | if (!trans) { | 1147 | if (IS_ERR(trans)) { |
| 1101 | ret = -ENOMEM; | 1148 | ret = PTR_ERR(trans); |
| 1102 | goto out; | 1149 | goto out; |
| 1103 | } | 1150 | } |
| 1104 | 1151 | ||
| @@ -1133,7 +1180,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1133 | } | 1180 | } |
| 1134 | mutex_lock(&dentry->d_inode->i_mutex); | 1181 | mutex_lock(&dentry->d_inode->i_mutex); |
| 1135 | out: | 1182 | out: |
| 1136 | return ret > 0 ? EIO : ret; | 1183 | return ret > 0 ? -EIO : ret; |
| 1137 | } | 1184 | } |
| 1138 | 1185 | ||
| 1139 | static const struct vm_operations_struct btrfs_file_vm_ops = { | 1186 | static const struct vm_operations_struct btrfs_file_vm_ops = { |
| @@ -1143,17 +1190,25 @@ static const struct vm_operations_struct btrfs_file_vm_ops = { | |||
| 1143 | 1190 | ||
| 1144 | static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma) | 1191 | static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma) |
| 1145 | { | 1192 | { |
| 1146 | vma->vm_ops = &btrfs_file_vm_ops; | 1193 | struct address_space *mapping = filp->f_mapping; |
| 1194 | |||
| 1195 | if (!mapping->a_ops->readpage) | ||
| 1196 | return -ENOEXEC; | ||
| 1197 | |||
| 1147 | file_accessed(filp); | 1198 | file_accessed(filp); |
| 1199 | vma->vm_ops = &btrfs_file_vm_ops; | ||
| 1200 | vma->vm_flags |= VM_CAN_NONLINEAR; | ||
| 1201 | |||
| 1148 | return 0; | 1202 | return 0; |
| 1149 | } | 1203 | } |
| 1150 | 1204 | ||
| 1151 | const struct file_operations btrfs_file_operations = { | 1205 | const struct file_operations btrfs_file_operations = { |
| 1152 | .llseek = generic_file_llseek, | 1206 | .llseek = generic_file_llseek, |
| 1153 | .read = do_sync_read, | 1207 | .read = do_sync_read, |
| 1208 | .write = do_sync_write, | ||
| 1154 | .aio_read = generic_file_aio_read, | 1209 | .aio_read = generic_file_aio_read, |
| 1155 | .splice_read = generic_file_splice_read, | 1210 | .splice_read = generic_file_splice_read, |
| 1156 | .write = btrfs_file_write, | 1211 | .aio_write = btrfs_file_aio_write, |
| 1157 | .mmap = btrfs_file_mmap, | 1212 | .mmap = btrfs_file_mmap, |
| 1158 | .open = generic_file_open, | 1213 | .open = generic_file_open, |
| 1159 | .release = btrfs_release_file, | 1214 | .release = btrfs_release_file, |
