diff options
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index c800d58f301..c1d3a818731 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -793,8 +793,12 @@ again: | |||
793 | for (i = 0; i < num_pages; i++) { | 793 | for (i = 0; i < num_pages; i++) { |
794 | pages[i] = grab_cache_page(inode->i_mapping, index + i); | 794 | pages[i] = grab_cache_page(inode->i_mapping, index + i); |
795 | if (!pages[i]) { | 795 | if (!pages[i]) { |
796 | err = -ENOMEM; | 796 | int c; |
797 | BUG_ON(1); | 797 | for (c = i - 1; c >= 0; c--) { |
798 | unlock_page(pages[c]); | ||
799 | page_cache_release(pages[c]); | ||
800 | } | ||
801 | return -ENOMEM; | ||
798 | } | 802 | } |
799 | wait_on_page_writeback(pages[i]); | 803 | wait_on_page_writeback(pages[i]); |
800 | } | 804 | } |
@@ -946,6 +950,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
946 | PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / | 950 | PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / |
947 | (sizeof(struct page *))); | 951 | (sizeof(struct page *))); |
948 | pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); | 952 | pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); |
953 | if (!pages) { | ||
954 | ret = -ENOMEM; | ||
955 | goto out; | ||
956 | } | ||
949 | 957 | ||
950 | /* generic_write_checks can change our pos */ | 958 | /* generic_write_checks can change our pos */ |
951 | start_pos = pos; | 959 | start_pos = pos; |
@@ -984,8 +992,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
984 | size_t write_bytes = min(iov_iter_count(&i), | 992 | size_t write_bytes = min(iov_iter_count(&i), |
985 | nrptrs * (size_t)PAGE_CACHE_SIZE - | 993 | nrptrs * (size_t)PAGE_CACHE_SIZE - |
986 | offset); | 994 | offset); |
987 | size_t num_pages = (write_bytes + PAGE_CACHE_SIZE - 1) >> | 995 | size_t num_pages = (write_bytes + offset + |
988 | PAGE_CACHE_SHIFT; | 996 | PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
989 | 997 | ||
990 | WARN_ON(num_pages > nrptrs); | 998 | WARN_ON(num_pages > nrptrs); |
991 | memset(pages, 0, sizeof(struct page *) * nrptrs); | 999 | memset(pages, 0, sizeof(struct page *) * nrptrs); |
@@ -1015,8 +1023,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1015 | 1023 | ||
1016 | copied = btrfs_copy_from_user(pos, num_pages, | 1024 | copied = btrfs_copy_from_user(pos, num_pages, |
1017 | write_bytes, pages, &i); | 1025 | write_bytes, pages, &i); |
1018 | dirty_pages = (copied + PAGE_CACHE_SIZE - 1) >> | 1026 | dirty_pages = (copied + offset + PAGE_CACHE_SIZE - 1) >> |
1019 | PAGE_CACHE_SHIFT; | 1027 | PAGE_CACHE_SHIFT; |
1020 | 1028 | ||
1021 | if (num_pages > dirty_pages) { | 1029 | if (num_pages > dirty_pages) { |
1022 | if (copied > 0) | 1030 | if (copied > 0) |