aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2014-06-19 07:01:03 -0400
committerSteve French <smfrench@gmail.com>2014-08-02 02:23:01 -0400
commit7e48ff82026d99fe498a280faa55e5842288d72f (patch)
tree3f3e59c19eed9f19b3ce60578605477f8746866b /fs/cifs
parent038bc961c31b070269ecd07349a7ee2e839d4fec (diff)
CIFS: Separate page processing from writepages
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Reviewed-by: Jeff Layton <jlayton@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/file.c152
1 files changed, 82 insertions, 70 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 6b6df30cfd89..69d176396d04 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1878,6 +1878,86 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1878 return rc; 1878 return rc;
1879} 1879}
1880 1880
1881static unsigned int
1882wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages,
1883 struct address_space *mapping,
1884 struct writeback_control *wbc,
1885 pgoff_t end, pgoff_t *index, pgoff_t *next, bool *done)
1886{
1887 unsigned int nr_pages = 0, i;
1888 struct page *page;
1889
1890 for (i = 0; i < found_pages; i++) {
1891 page = wdata->pages[i];
1892 /*
1893 * At this point we hold neither mapping->tree_lock nor
1894 * lock on the page itself: the page may be truncated or
1895 * invalidated (changing page->mapping to NULL), or even
1896 * swizzled back from swapper_space to tmpfs file
1897 * mapping
1898 */
1899
1900 if (nr_pages == 0)
1901 lock_page(page);
1902 else if (!trylock_page(page))
1903 break;
1904
1905 if (unlikely(page->mapping != mapping)) {
1906 unlock_page(page);
1907 break;
1908 }
1909
1910 if (!wbc->range_cyclic && page->index > end) {
1911 *done = true;
1912 unlock_page(page);
1913 break;
1914 }
1915
1916 if (*next && (page->index != *next)) {
1917 /* Not next consecutive page */
1918 unlock_page(page);
1919 break;
1920 }
1921
1922 if (wbc->sync_mode != WB_SYNC_NONE)
1923 wait_on_page_writeback(page);
1924
1925 if (PageWriteback(page) ||
1926 !clear_page_dirty_for_io(page)) {
1927 unlock_page(page);
1928 break;
1929 }
1930
1931 /*
1932 * This actually clears the dirty bit in the radix tree.
1933 * See cifs_writepage() for more commentary.
1934 */
1935 set_page_writeback(page);
1936 if (page_offset(page) >= i_size_read(mapping->host)) {
1937 *done = true;
1938 unlock_page(page);
1939 end_page_writeback(page);
1940 break;
1941 }
1942
1943 wdata->pages[i] = page;
1944 *next = page->index + 1;
1945 ++nr_pages;
1946 }
1947
1948 /* reset index to refind any pages skipped */
1949 if (nr_pages == 0)
1950 *index = wdata->pages[0]->index + 1;
1951
1952 /* put any pages we aren't going to use */
1953 for (i = nr_pages; i < found_pages; i++) {
1954 page_cache_release(wdata->pages[i]);
1955 wdata->pages[i] = NULL;
1956 }
1957
1958 return nr_pages;
1959}
1960
1881static int cifs_writepages(struct address_space *mapping, 1961static int cifs_writepages(struct address_space *mapping,
1882 struct writeback_control *wbc) 1962 struct writeback_control *wbc)
1883{ 1963{
@@ -1886,7 +1966,6 @@ static int cifs_writepages(struct address_space *mapping,
1886 pgoff_t end, index; 1966 pgoff_t end, index;
1887 struct cifs_writedata *wdata; 1967 struct cifs_writedata *wdata;
1888 struct TCP_Server_Info *server; 1968 struct TCP_Server_Info *server;
1889 struct page *page;
1890 int rc = 0; 1969 int rc = 0;
1891 1970
1892 /* 1971 /*
@@ -1944,75 +2023,8 @@ retry:
1944 break; 2023 break;
1945 } 2024 }
1946 2025
1947 nr_pages = 0; 2026 nr_pages = wdata_prepare_pages(wdata, found_pages, mapping, wbc,
1948 for (i = 0; i < found_pages; i++) { 2027 end, &index, &next, &done);
1949 page = wdata->pages[i];
1950 /*
1951 * At this point we hold neither mapping->tree_lock nor
1952 * lock on the page itself: the page may be truncated or
1953 * invalidated (changing page->mapping to NULL), or even
1954 * swizzled back from swapper_space to tmpfs file
1955 * mapping
1956 */
1957
1958 if (nr_pages == 0)
1959 lock_page(page);
1960 else if (!trylock_page(page))
1961 break;
1962
1963 if (unlikely(page->mapping != mapping)) {
1964 unlock_page(page);
1965 break;
1966 }
1967
1968 if (!wbc->range_cyclic && page->index > end) {
1969 done = true;
1970 unlock_page(page);
1971 break;
1972 }
1973
1974 if (next && (page->index != next)) {
1975 /* Not next consecutive page */
1976 unlock_page(page);
1977 break;
1978 }
1979
1980 if (wbc->sync_mode != WB_SYNC_NONE)
1981 wait_on_page_writeback(page);
1982
1983 if (PageWriteback(page) ||
1984 !clear_page_dirty_for_io(page)) {
1985 unlock_page(page);
1986 break;
1987 }
1988
1989 /*
1990 * This actually clears the dirty bit in the radix tree.
1991 * See cifs_writepage() for more commentary.
1992 */
1993 set_page_writeback(page);
1994
1995 if (page_offset(page) >= i_size_read(mapping->host)) {
1996 done = true;
1997 unlock_page(page);
1998 end_page_writeback(page);
1999 break;
2000 }
2001
2002 wdata->pages[i] = page;
2003 next = page->index + 1;
2004 ++nr_pages;
2005 }
2006
2007 /* reset index to refind any pages skipped */
2008 if (nr_pages == 0)
2009 index = wdata->pages[0]->index + 1;
2010
2011 /* put any pages we aren't going to use */
2012 for (i = nr_pages; i < found_pages; i++) {
2013 page_cache_release(wdata->pages[i]);
2014 wdata->pages[i] = NULL;
2015 }
2016 2028
2017 /* nothing to write? */ 2029 /* nothing to write? */
2018 if (nr_pages == 0) { 2030 if (nr_pages == 0) {