diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2014-06-19 08:11:00 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2014-08-02 02:23:02 -0400 |
commit | 90ac1387c2dfcd9b4bd302fce03b9ddff73d0093 (patch) | |
tree | 4dabbd15cf3cb9399f64adbf3ed5f402d3fb9ad8 /fs/cifs | |
parent | 619aa48edbab47367fa8a65e568f63fd64d6b4af (diff) |
CIFS: Separate pages initialization from writepages
Reviewed-by: Shirish Pargaonkar <spargaonkar@suse.com>
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/file.c | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index e76581ffcf77..0064d38fdb76 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1878,6 +1878,40 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) | |||
1878 | return rc; | 1878 | return rc; |
1879 | } | 1879 | } |
1880 | 1880 | ||
1881 | static struct cifs_writedata * | ||
1882 | wdata_alloc_and_fillpages(pgoff_t tofind, struct address_space *mapping, | ||
1883 | pgoff_t end, pgoff_t *index, | ||
1884 | unsigned int *found_pages) | ||
1885 | { | ||
1886 | unsigned int nr_pages; | ||
1887 | struct page **pages; | ||
1888 | struct cifs_writedata *wdata; | ||
1889 | |||
1890 | wdata = cifs_writedata_alloc((unsigned int)tofind, | ||
1891 | cifs_writev_complete); | ||
1892 | if (!wdata) | ||
1893 | return NULL; | ||
1894 | |||
1895 | /* | ||
1896 | * find_get_pages_tag seems to return a max of 256 on each | ||
1897 | * iteration, so we must call it several times in order to | ||
1898 | * fill the array or the wsize is effectively limited to | ||
1899 | * 256 * PAGE_CACHE_SIZE. | ||
1900 | */ | ||
1901 | *found_pages = 0; | ||
1902 | pages = wdata->pages; | ||
1903 | do { | ||
1904 | nr_pages = find_get_pages_tag(mapping, index, | ||
1905 | PAGECACHE_TAG_DIRTY, tofind, | ||
1906 | pages); | ||
1907 | *found_pages += nr_pages; | ||
1908 | tofind -= nr_pages; | ||
1909 | pages += nr_pages; | ||
1910 | } while (nr_pages && tofind && *index <= end); | ||
1911 | |||
1912 | return wdata; | ||
1913 | } | ||
1914 | |||
1881 | static unsigned int | 1915 | static unsigned int |
1882 | wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages, | 1916 | wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages, |
1883 | struct address_space *mapping, | 1917 | struct address_space *mapping, |
@@ -2025,35 +2059,17 @@ retry: | |||
2025 | while (!done && index <= end) { | 2059 | while (!done && index <= end) { |
2026 | unsigned int i, nr_pages, found_pages; | 2060 | unsigned int i, nr_pages, found_pages; |
2027 | pgoff_t next = 0, tofind; | 2061 | pgoff_t next = 0, tofind; |
2028 | struct page **pages; | ||
2029 | 2062 | ||
2030 | tofind = min((cifs_sb->wsize / PAGE_CACHE_SIZE) - 1, | 2063 | tofind = min((cifs_sb->wsize / PAGE_CACHE_SIZE) - 1, |
2031 | end - index) + 1; | 2064 | end - index) + 1; |
2032 | 2065 | ||
2033 | wdata = cifs_writedata_alloc((unsigned int)tofind, | 2066 | wdata = wdata_alloc_and_fillpages(tofind, mapping, end, &index, |
2034 | cifs_writev_complete); | 2067 | &found_pages); |
2035 | if (!wdata) { | 2068 | if (!wdata) { |
2036 | rc = -ENOMEM; | 2069 | rc = -ENOMEM; |
2037 | break; | 2070 | break; |
2038 | } | 2071 | } |
2039 | 2072 | ||
2040 | /* | ||
2041 | * find_get_pages_tag seems to return a max of 256 on each | ||
2042 | * iteration, so we must call it several times in order to | ||
2043 | * fill the array or the wsize is effectively limited to | ||
2044 | * 256 * PAGE_CACHE_SIZE. | ||
2045 | */ | ||
2046 | found_pages = 0; | ||
2047 | pages = wdata->pages; | ||
2048 | do { | ||
2049 | nr_pages = find_get_pages_tag(mapping, &index, | ||
2050 | PAGECACHE_TAG_DIRTY, | ||
2051 | tofind, pages); | ||
2052 | found_pages += nr_pages; | ||
2053 | tofind -= nr_pages; | ||
2054 | pages += nr_pages; | ||
2055 | } while (nr_pages && tofind && index <= end); | ||
2056 | |||
2057 | if (found_pages == 0) { | 2073 | if (found_pages == 0) { |
2058 | kref_put(&wdata->refcount, cifs_writedata_release); | 2074 | kref_put(&wdata->refcount, cifs_writedata_release); |
2059 | break; | 2075 | break; |