summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2016-01-18 08:04:23 +0100
committerDaniel Vetter <daniel.vetter@ffwll.ch>2016-01-18 08:18:16 +0100
commit2da80b57c69a2a5ae0e16dead8cdbfab46f970bc (patch)
tree402529def53a1b32066493f5581c3e1810d11a1d /fs/btrfs/file.c
parent2d7f3bdb2cf6656386cb9ca1b02dd6df66fb05e8 (diff)
parent1df59b8497f47495e873c23abd6d3d290c730505 (diff)
downloadlinux-2da80b57c69a2a5ae0e16dead8cdbfab46f970bc.tar.bz2
Merge remote-tracking branch 'airlied/drm-next' into drm-intel-next-queued
Pull in Dave's drm-next pull request to have a clean base for 4.6. Also, we need the various atomic state extensions Maarten recently created. Conflicts are just adjacent changes that all resolve to nothing in git diff. Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 72e73461c064..0f09526aa7d9 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1291,7 +1291,8 @@ out:
* on error we return an unlocked page and the error value
* on success we return a locked page and 0
*/
-static int prepare_uptodate_page(struct page *page, u64 pos,
+static int prepare_uptodate_page(struct inode *inode,
+ struct page *page, u64 pos,
bool force_uptodate)
{
int ret = 0;
@@ -1306,6 +1307,10 @@ static int prepare_uptodate_page(struct page *page, u64 pos,
unlock_page(page);
return -EIO;
}
+ if (page->mapping != inode->i_mapping) {
+ unlock_page(page);
+ return -EAGAIN;
+ }
}
return 0;
}
@@ -1324,6 +1329,7 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
int faili;
for (i = 0; i < num_pages; i++) {
+again:
pages[i] = find_or_create_page(inode->i_mapping, index + i,
mask | __GFP_WRITE);
if (!pages[i]) {
@@ -1333,13 +1339,17 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
}
if (i == 0)
- err = prepare_uptodate_page(pages[i], pos,
+ err = prepare_uptodate_page(inode, pages[i], pos,
force_uptodate);
- if (i == num_pages - 1)
- err = prepare_uptodate_page(pages[i],
+ if (!err && i == num_pages - 1)
+ err = prepare_uptodate_page(inode, pages[i],
pos + write_bytes, false);
if (err) {
page_cache_release(pages[i]);
+ if (err == -EAGAIN) {
+ err = 0;
+ goto again;
+ }
faili = i - 1;
goto fail;
}