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 | /* |
