diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-02-07 17:06:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-02-07 17:06:18 -0500 |
commit | cb5520f02c010e3cb974b9ac06f30aafa2eebc38 (patch) | |
tree | 8342407cebb6420f04f46694b8d812552a14cb49 /fs/btrfs/file.c | |
parent | eee4da2cef8e2dc2b15066e9ebb5b2ff63396eb3 (diff) | |
parent | 3a90983dbdcb2f4f48c0d771d8e5b4d88f27fae6 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (33 commits)
Btrfs: Fix page count calculation
btrfs: Drop __exit attribute on btrfs_exit_compress
btrfs: cleanup error handling in btrfs_unlink_inode()
Btrfs: exclude super blocks when we read in block groups
Btrfs: make sure search_bitmap finds something in remove_from_bitmap
btrfs: fix return value check of btrfs_start_transaction()
btrfs: checking NULL or not in some functions
Btrfs: avoid uninit variable warnings in ordered-data.c
Btrfs: catch errors from btrfs_sync_log
Btrfs: make shrink_delalloc a little friendlier
Btrfs: handle no memory properly in prepare_pages
Btrfs: do error checking in btrfs_del_csums
Btrfs: use the global block reserve if we cannot reserve space
Btrfs: do not release more reserved bytes to the global_block_rsv than we need
Btrfs: fix check_path_shared so it returns the right value
btrfs: check return value of btrfs_start_ioctl_transaction() properly
btrfs: fix return value check of btrfs_join_transaction()
fs/btrfs/inode.c: Add missing IS_ERR test
btrfs: fix missing break in switch phrase
btrfs: fix several uncheck memory allocations
...
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 c800d58f3013..c1d3a818731a 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) |