[PATCH] splice: fix unlocking of page on error ->prepare_write()
authorJens Axboe <axboe@suse.de>
Wed, 3 May 2006 08:35:10 +0000 (10:35 +0200)
committerJens Axboe <axboe@nelson.home.kernel.dk>
Thu, 4 May 2006 04:55:12 +0000 (06:55 +0200)
Looking at generic_file_buffered_write(), we need to unlock_page() if
prepare write fails and it isn't due to racing with truncate().

Also trim the size if ->prepare_write() fails, if we have to.

Signed-off-by: Jens Axboe <axboe@suse.de>
fs/splice.c

index 7fb04970c72d853e53874e4ec03d9df48911dcb3..27f5e3738a7bf62709f781b9dcd6aac9dc56d4a6 100644 (file)
@@ -647,11 +647,24 @@ find_page:
        }
 
        ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len);
-       if (ret == AOP_TRUNCATED_PAGE) {
+       if (unlikely(ret)) {
+               loff_t isize = i_size_read(mapping->host);
+
+               if (ret != AOP_TRUNCATED_PAGE)
+                       unlock_page(page);
                page_cache_release(page);
-               goto find_page;
-       } else if (ret)
+               if (ret == AOP_TRUNCATED_PAGE)
+                       goto find_page;
+
+               /*
+                * prepare_write() may have instantiated a few blocks
+                * outside i_size.  Trim these off again.
+                */
+               if (sd->pos + this_len > isize)
+                       vmtruncate(mapping->host, isize);
+
                goto out;
+       }
 
        if (buf->page != page) {
                /*