|
@@ -1878,6 +1878,40 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static struct cifs_writedata *
|
|
|
+wdata_alloc_and_fillpages(pgoff_t tofind, struct address_space *mapping,
|
|
|
+ pgoff_t end, pgoff_t *index,
|
|
|
+ unsigned int *found_pages)
|
|
|
+{
|
|
|
+ unsigned int nr_pages;
|
|
|
+ struct page **pages;
|
|
|
+ struct cifs_writedata *wdata;
|
|
|
+
|
|
|
+ wdata = cifs_writedata_alloc((unsigned int)tofind,
|
|
|
+ cifs_writev_complete);
|
|
|
+ if (!wdata)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * find_get_pages_tag seems to return a max of 256 on each
|
|
|
+ * iteration, so we must call it several times in order to
|
|
|
+ * fill the array or the wsize is effectively limited to
|
|
|
+ * 256 * PAGE_CACHE_SIZE.
|
|
|
+ */
|
|
|
+ *found_pages = 0;
|
|
|
+ pages = wdata->pages;
|
|
|
+ do {
|
|
|
+ nr_pages = find_get_pages_tag(mapping, index,
|
|
|
+ PAGECACHE_TAG_DIRTY, tofind,
|
|
|
+ pages);
|
|
|
+ *found_pages += nr_pages;
|
|
|
+ tofind -= nr_pages;
|
|
|
+ pages += nr_pages;
|
|
|
+ } while (nr_pages && tofind && *index <= end);
|
|
|
+
|
|
|
+ return wdata;
|
|
|
+}
|
|
|
+
|
|
|
static unsigned int
|
|
|
wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages,
|
|
|
struct address_space *mapping,
|
|
@@ -2025,35 +2059,17 @@ retry:
|
|
|
while (!done && index <= end) {
|
|
|
unsigned int i, nr_pages, found_pages;
|
|
|
pgoff_t next = 0, tofind;
|
|
|
- struct page **pages;
|
|
|
|
|
|
tofind = min((cifs_sb->wsize / PAGE_CACHE_SIZE) - 1,
|
|
|
end - index) + 1;
|
|
|
|
|
|
- wdata = cifs_writedata_alloc((unsigned int)tofind,
|
|
|
- cifs_writev_complete);
|
|
|
+ wdata = wdata_alloc_and_fillpages(tofind, mapping, end, &index,
|
|
|
+ &found_pages);
|
|
|
if (!wdata) {
|
|
|
rc = -ENOMEM;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- * find_get_pages_tag seems to return a max of 256 on each
|
|
|
- * iteration, so we must call it several times in order to
|
|
|
- * fill the array or the wsize is effectively limited to
|
|
|
- * 256 * PAGE_CACHE_SIZE.
|
|
|
- */
|
|
|
- found_pages = 0;
|
|
|
- pages = wdata->pages;
|
|
|
- do {
|
|
|
- nr_pages = find_get_pages_tag(mapping, &index,
|
|
|
- PAGECACHE_TAG_DIRTY,
|
|
|
- tofind, pages);
|
|
|
- found_pages += nr_pages;
|
|
|
- tofind -= nr_pages;
|
|
|
- pages += nr_pages;
|
|
|
- } while (nr_pages && tofind && index <= end);
|
|
|
-
|
|
|
if (found_pages == 0) {
|
|
|
kref_put(&wdata->refcount, cifs_writedata_release);
|
|
|
break;
|