diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 08760ff9bab7..40b4a8ec17fe 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1180,19 +1180,26 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) | |||
1180 | goto out; | 1180 | goto out; |
1181 | 1181 | ||
1182 | ret = -ENOMEM; | 1182 | ret = -ENOMEM; |
1183 | again: | ||
1183 | page = grab_cache_page(mapping, index); | 1184 | page = grab_cache_page(mapping, index); |
1184 | if (!page) | 1185 | if (!page) |
1185 | goto out; | 1186 | goto out; |
1186 | if (!PageUptodate(page)) { | 1187 | if (!PageUptodate(page)) { |
1187 | ret = btrfs_readpage(NULL, page); | 1188 | ret = btrfs_readpage(NULL, page); |
1188 | lock_page(page); | 1189 | lock_page(page); |
1190 | if (page->mapping != mapping) { | ||
1191 | unlock_page(page); | ||
1192 | page_cache_release(page); | ||
1193 | goto again; | ||
1194 | } | ||
1189 | if (!PageUptodate(page)) { | 1195 | if (!PageUptodate(page)) { |
1190 | ret = -EIO; | 1196 | ret = -EIO; |
1191 | goto out; | 1197 | goto out; |
1192 | } | 1198 | } |
1193 | } | 1199 | } |
1194 | page_start = (u64)page->index << PAGE_CACHE_SHIFT; | ||
1195 | 1200 | ||
1201 | page_start = (u64)page->index << PAGE_CACHE_SHIFT; | ||
1202 | wait_on_page_writeback(page); | ||
1196 | ret = btrfs_cow_one_page(inode, page, offset); | 1203 | ret = btrfs_cow_one_page(inode, page, offset); |
1197 | 1204 | ||
1198 | unlock_page(page); | 1205 | unlock_page(page); |