diff options
-rw-r--r-- | fs/splice.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/fs/splice.c b/fs/splice.c index 7fb04970c72d..27f5e3738a7b 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -647,11 +647,24 @@ find_page: | |||
647 | } | 647 | } |
648 | 648 | ||
649 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); | 649 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); |
650 | if (ret == AOP_TRUNCATED_PAGE) { | 650 | if (unlikely(ret)) { |
651 | loff_t isize = i_size_read(mapping->host); | ||
652 | |||
653 | if (ret != AOP_TRUNCATED_PAGE) | ||
654 | unlock_page(page); | ||
651 | page_cache_release(page); | 655 | page_cache_release(page); |
652 | goto find_page; | 656 | if (ret == AOP_TRUNCATED_PAGE) |
653 | } else if (ret) | 657 | goto find_page; |
658 | |||
659 | /* | ||
660 | * prepare_write() may have instantiated a few blocks | ||
661 | * outside i_size. Trim these off again. | ||
662 | */ | ||
663 | if (sd->pos + this_len > isize) | ||
664 | vmtruncate(mapping->host, isize); | ||
665 | |||
654 | goto out; | 666 | goto out; |
667 | } | ||
655 | 668 | ||
656 | if (buf->page != page) { | 669 | if (buf->page != page) { |
657 | /* | 670 | /* |