@@ -1183,7 +1183,46 @@ iomap_page_mkwrite_actor(struct inode *inode, loff_t pos, loff_t length,
void *data, struct iomap *iomap)
{
struct page *page = data;
- int ret;
+ loff_t ret;
+
+ /*
+ * if we need to zero-around, we have to unlock the page we were given.
+ * No big deal, we just have to repeat the "is this page ours" checks
+ * after relocking it
+ */
+ if (iomap_need_zero_around(iomap)) {
+ loff_t size;
+
+ /*
+ * This only happens for block size > page size, so the file
+ * offset of a page fault should always be page aligned.
+ */
+ WARN_ON(offset_in_page(pos));
+
+ unlock_page(page);
+ ret = iomap_zero_around(inode, pos, length, iomap);
+ lock_page(page);
+ size = i_size_read(inode);
+ if ((page->mapping != inode->i_mapping) ||
+ (page_offset(page) > size)) {
+ /* We overload EFAULT to mean page got truncated */
+ return -EFAULT;
+ }
+
+ if (page_offset(page) != pos) {
+ /* it moved in the file! */
+ return -EFAULT;
+ }
+
+ /* return failure now if zeroing had an error */
+ if (ret)
+ return ret;
+
+ /* trim down the length is we straddle EOF. */
+ if (((page->index + 1) << PAGE_SHIFT) > size)
+ length = offset_in_page(size);
+
+ }
if (iomap->flags & IOMAP_F_BUFFER_HEAD) {
ret = __block_write_begin_int(page, pos, length, NULL, iomap);