#if defined(HAVE_DIO_ITER)
kvfree(pages);
#else
- OBD_FREE_LARGE(pages, npages * sizeof(*pages));
+ OBD_FREE_PTR_ARRAY_LARGE(pages, npages);
#endif
}
size = min_t(size_t, maxsize, iter->iov->iov_len);
page_count = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- OBD_ALLOC_LARGE(*pages, page_count * sizeof(**pages));
+ OBD_ALLOC_PTR_ARRAY_LARGE(*pages, page_count);
if (*pages == NULL)
return -ENOMEM;
* then truncate this to be a full-sized RPC. For 4kB PAGE_SIZE this is
* up to 22MB for 128kB kmalloc and up to 682MB for 4MB kmalloc. */
#define MAX_DIO_SIZE ((MAX_MALLOC / sizeof(struct brw_page) * PAGE_SIZE) & \
- ~(DT_MAX_BRW_SIZE - 1))
+ ~((size_t)DT_MAX_BRW_SIZE - 1))
static ssize_t
ll_direct_IO_impl(struct kiocb *iocb, struct iov_iter *iter, int rw)
return result;
}
-static int ll_tiny_write_begin(struct page *vmpage)
+static int ll_tiny_write_begin(struct page *vmpage, struct address_space *mapping)
{
/* Page must be present, up to date, dirty, and not in writeback. */
if (!vmpage || !PageUptodate(vmpage) || !PageDirty(vmpage) ||
- PageWriteback(vmpage))
+ PageWriteback(vmpage) || vmpage->mapping != mapping)
return -ENODATA;
return 0;
lcc = ll_cl_find(file);
if (lcc == NULL) {
vmpage = grab_cache_page_nowait(mapping, index);
- result = ll_tiny_write_begin(vmpage);
+ result = ll_tiny_write_begin(vmpage, mapping);
GOTO(out, result);
}
}
}
+ /* page was truncated */
+ if (mapping != vmpage->mapping) {
+ CDEBUG(D_VFSTRACE, "page: %lu was truncated\n", index);
+ unlock_page(vmpage);
+ put_page(vmpage);
+ vmpage = NULL;
+ goto again;
+ }
+
page = cl_page_find(env, clob, vmpage->index, vmpage, CPT_CACHEABLE);
if (IS_ERR(page))
GOTO(out, result = PTR_ERR(page));