diff options
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 872 |
1 files changed, 533 insertions, 339 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index b88b1ade4d3d..4ab2f79ffa7a 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1670,8 +1670,8 @@ cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data, | |||
1670 | break; | 1670 | break; |
1671 | } | 1671 | } |
1672 | 1672 | ||
1673 | len = min((size_t)cifs_sb->wsize, | 1673 | len = min(server->ops->wp_retry_size(dentry->d_inode), |
1674 | write_size - total_written); | 1674 | (unsigned int)write_size - total_written); |
1675 | /* iov[0] is reserved for smb header */ | 1675 | /* iov[0] is reserved for smb header */ |
1676 | iov[1].iov_base = (char *)write_data + total_written; | 1676 | iov[1].iov_base = (char *)write_data + total_written; |
1677 | iov[1].iov_len = len; | 1677 | iov[1].iov_len = len; |
@@ -1878,15 +1878,163 @@ 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 | |||
1915 | static unsigned int | ||
1916 | wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages, | ||
1917 | struct address_space *mapping, | ||
1918 | struct writeback_control *wbc, | ||
1919 | pgoff_t end, pgoff_t *index, pgoff_t *next, bool *done) | ||
1920 | { | ||
1921 | unsigned int nr_pages = 0, i; | ||
1922 | struct page *page; | ||
1923 | |||
1924 | for (i = 0; i < found_pages; i++) { | ||
1925 | page = wdata->pages[i]; | ||
1926 | /* | ||
1927 | * At this point we hold neither mapping->tree_lock nor | ||
1928 | * lock on the page itself: the page may be truncated or | ||
1929 | * invalidated (changing page->mapping to NULL), or even | ||
1930 | * swizzled back from swapper_space to tmpfs file | ||
1931 | * mapping | ||
1932 | */ | ||
1933 | |||
1934 | if (nr_pages == 0) | ||
1935 | lock_page(page); | ||
1936 | else if (!trylock_page(page)) | ||
1937 | break; | ||
1938 | |||
1939 | if (unlikely(page->mapping != mapping)) { | ||
1940 | unlock_page(page); | ||
1941 | break; | ||
1942 | } | ||
1943 | |||
1944 | if (!wbc->range_cyclic && page->index > end) { | ||
1945 | *done = true; | ||
1946 | unlock_page(page); | ||
1947 | break; | ||
1948 | } | ||
1949 | |||
1950 | if (*next && (page->index != *next)) { | ||
1951 | /* Not next consecutive page */ | ||
1952 | unlock_page(page); | ||
1953 | break; | ||
1954 | } | ||
1955 | |||
1956 | if (wbc->sync_mode != WB_SYNC_NONE) | ||
1957 | wait_on_page_writeback(page); | ||
1958 | |||
1959 | if (PageWriteback(page) || | ||
1960 | !clear_page_dirty_for_io(page)) { | ||
1961 | unlock_page(page); | ||
1962 | break; | ||
1963 | } | ||
1964 | |||
1965 | /* | ||
1966 | * This actually clears the dirty bit in the radix tree. | ||
1967 | * See cifs_writepage() for more commentary. | ||
1968 | */ | ||
1969 | set_page_writeback(page); | ||
1970 | if (page_offset(page) >= i_size_read(mapping->host)) { | ||
1971 | *done = true; | ||
1972 | unlock_page(page); | ||
1973 | end_page_writeback(page); | ||
1974 | break; | ||
1975 | } | ||
1976 | |||
1977 | wdata->pages[i] = page; | ||
1978 | *next = page->index + 1; | ||
1979 | ++nr_pages; | ||
1980 | } | ||
1981 | |||
1982 | /* reset index to refind any pages skipped */ | ||
1983 | if (nr_pages == 0) | ||
1984 | *index = wdata->pages[0]->index + 1; | ||
1985 | |||
1986 | /* put any pages we aren't going to use */ | ||
1987 | for (i = nr_pages; i < found_pages; i++) { | ||
1988 | page_cache_release(wdata->pages[i]); | ||
1989 | wdata->pages[i] = NULL; | ||
1990 | } | ||
1991 | |||
1992 | return nr_pages; | ||
1993 | } | ||
1994 | |||
1995 | static int | ||
1996 | wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages, | ||
1997 | struct address_space *mapping, struct writeback_control *wbc) | ||
1998 | { | ||
1999 | int rc = 0; | ||
2000 | struct TCP_Server_Info *server; | ||
2001 | unsigned int i; | ||
2002 | |||
2003 | wdata->sync_mode = wbc->sync_mode; | ||
2004 | wdata->nr_pages = nr_pages; | ||
2005 | wdata->offset = page_offset(wdata->pages[0]); | ||
2006 | wdata->pagesz = PAGE_CACHE_SIZE; | ||
2007 | wdata->tailsz = min(i_size_read(mapping->host) - | ||
2008 | page_offset(wdata->pages[nr_pages - 1]), | ||
2009 | (loff_t)PAGE_CACHE_SIZE); | ||
2010 | wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) + wdata->tailsz; | ||
2011 | |||
2012 | if (wdata->cfile != NULL) | ||
2013 | cifsFileInfo_put(wdata->cfile); | ||
2014 | wdata->cfile = find_writable_file(CIFS_I(mapping->host), false); | ||
2015 | if (!wdata->cfile) { | ||
2016 | cifs_dbg(VFS, "No writable handles for inode\n"); | ||
2017 | rc = -EBADF; | ||
2018 | } else { | ||
2019 | wdata->pid = wdata->cfile->pid; | ||
2020 | server = tlink_tcon(wdata->cfile->tlink)->ses->server; | ||
2021 | rc = server->ops->async_writev(wdata, cifs_writedata_release); | ||
2022 | } | ||
2023 | |||
2024 | for (i = 0; i < nr_pages; ++i) | ||
2025 | unlock_page(wdata->pages[i]); | ||
2026 | |||
2027 | return rc; | ||
2028 | } | ||
2029 | |||
1881 | static int cifs_writepages(struct address_space *mapping, | 2030 | static int cifs_writepages(struct address_space *mapping, |
1882 | struct writeback_control *wbc) | 2031 | struct writeback_control *wbc) |
1883 | { | 2032 | { |
1884 | struct cifs_sb_info *cifs_sb = CIFS_SB(mapping->host->i_sb); | 2033 | struct cifs_sb_info *cifs_sb = CIFS_SB(mapping->host->i_sb); |
2034 | struct TCP_Server_Info *server; | ||
1885 | bool done = false, scanned = false, range_whole = false; | 2035 | bool done = false, scanned = false, range_whole = false; |
1886 | pgoff_t end, index; | 2036 | pgoff_t end, index; |
1887 | struct cifs_writedata *wdata; | 2037 | struct cifs_writedata *wdata; |
1888 | struct TCP_Server_Info *server; | ||
1889 | struct page *page; | ||
1890 | int rc = 0; | 2038 | int rc = 0; |
1891 | 2039 | ||
1892 | /* | 2040 | /* |
@@ -1906,152 +2054,50 @@ static int cifs_writepages(struct address_space *mapping, | |||
1906 | range_whole = true; | 2054 | range_whole = true; |
1907 | scanned = true; | 2055 | scanned = true; |
1908 | } | 2056 | } |
2057 | server = cifs_sb_master_tcon(cifs_sb)->ses->server; | ||
1909 | retry: | 2058 | retry: |
1910 | while (!done && index <= end) { | 2059 | while (!done && index <= end) { |
1911 | unsigned int i, nr_pages, found_pages; | 2060 | unsigned int i, nr_pages, found_pages, wsize, credits; |
1912 | pgoff_t next = 0, tofind; | 2061 | pgoff_t next = 0, tofind, saved_index = index; |
1913 | struct page **pages; | 2062 | |
2063 | rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize, | ||
2064 | &wsize, &credits); | ||
2065 | if (rc) | ||
2066 | break; | ||
1914 | 2067 | ||
1915 | tofind = min((cifs_sb->wsize / PAGE_CACHE_SIZE) - 1, | 2068 | tofind = min((wsize / PAGE_CACHE_SIZE) - 1, end - index) + 1; |
1916 | end - index) + 1; | ||
1917 | 2069 | ||
1918 | wdata = cifs_writedata_alloc((unsigned int)tofind, | 2070 | wdata = wdata_alloc_and_fillpages(tofind, mapping, end, &index, |
1919 | cifs_writev_complete); | 2071 | &found_pages); |
1920 | if (!wdata) { | 2072 | if (!wdata) { |
1921 | rc = -ENOMEM; | 2073 | rc = -ENOMEM; |
2074 | add_credits_and_wake_if(server, credits, 0); | ||
1922 | break; | 2075 | break; |
1923 | } | 2076 | } |
1924 | 2077 | ||
1925 | /* | ||
1926 | * find_get_pages_tag seems to return a max of 256 on each | ||
1927 | * iteration, so we must call it several times in order to | ||
1928 | * fill the array or the wsize is effectively limited to | ||
1929 | * 256 * PAGE_CACHE_SIZE. | ||
1930 | */ | ||
1931 | found_pages = 0; | ||
1932 | pages = wdata->pages; | ||
1933 | do { | ||
1934 | nr_pages = find_get_pages_tag(mapping, &index, | ||
1935 | PAGECACHE_TAG_DIRTY, | ||
1936 | tofind, pages); | ||
1937 | found_pages += nr_pages; | ||
1938 | tofind -= nr_pages; | ||
1939 | pages += nr_pages; | ||
1940 | } while (nr_pages && tofind && index <= end); | ||
1941 | |||
1942 | if (found_pages == 0) { | 2078 | if (found_pages == 0) { |
1943 | kref_put(&wdata->refcount, cifs_writedata_release); | 2079 | kref_put(&wdata->refcount, cifs_writedata_release); |
2080 | add_credits_and_wake_if(server, credits, 0); | ||
1944 | break; | 2081 | break; |
1945 | } | 2082 | } |
1946 | 2083 | ||
1947 | nr_pages = 0; | 2084 | nr_pages = wdata_prepare_pages(wdata, found_pages, mapping, wbc, |
1948 | for (i = 0; i < found_pages; i++) { | 2085 | 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 | 2086 | ||
2017 | /* nothing to write? */ | 2087 | /* nothing to write? */ |
2018 | if (nr_pages == 0) { | 2088 | if (nr_pages == 0) { |
2019 | kref_put(&wdata->refcount, cifs_writedata_release); | 2089 | kref_put(&wdata->refcount, cifs_writedata_release); |
2090 | add_credits_and_wake_if(server, credits, 0); | ||
2020 | continue; | 2091 | continue; |
2021 | } | 2092 | } |
2022 | 2093 | ||
2023 | wdata->sync_mode = wbc->sync_mode; | 2094 | wdata->credits = credits; |
2024 | wdata->nr_pages = nr_pages; | ||
2025 | wdata->offset = page_offset(wdata->pages[0]); | ||
2026 | wdata->pagesz = PAGE_CACHE_SIZE; | ||
2027 | wdata->tailsz = | ||
2028 | min(i_size_read(mapping->host) - | ||
2029 | page_offset(wdata->pages[nr_pages - 1]), | ||
2030 | (loff_t)PAGE_CACHE_SIZE); | ||
2031 | wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) + | ||
2032 | wdata->tailsz; | ||
2033 | |||
2034 | do { | ||
2035 | if (wdata->cfile != NULL) | ||
2036 | cifsFileInfo_put(wdata->cfile); | ||
2037 | wdata->cfile = find_writable_file(CIFS_I(mapping->host), | ||
2038 | false); | ||
2039 | if (!wdata->cfile) { | ||
2040 | cifs_dbg(VFS, "No writable handles for inode\n"); | ||
2041 | rc = -EBADF; | ||
2042 | break; | ||
2043 | } | ||
2044 | wdata->pid = wdata->cfile->pid; | ||
2045 | server = tlink_tcon(wdata->cfile->tlink)->ses->server; | ||
2046 | rc = server->ops->async_writev(wdata, | ||
2047 | cifs_writedata_release); | ||
2048 | } while (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN); | ||
2049 | 2095 | ||
2050 | for (i = 0; i < nr_pages; ++i) | 2096 | rc = wdata_send_pages(wdata, nr_pages, mapping, wbc); |
2051 | unlock_page(wdata->pages[i]); | ||
2052 | 2097 | ||
2053 | /* send failure -- clean up the mess */ | 2098 | /* send failure -- clean up the mess */ |
2054 | if (rc != 0) { | 2099 | if (rc != 0) { |
2100 | add_credits_and_wake_if(server, wdata->credits, 0); | ||
2055 | for (i = 0; i < nr_pages; ++i) { | 2101 | for (i = 0; i < nr_pages; ++i) { |
2056 | if (rc == -EAGAIN) | 2102 | if (rc == -EAGAIN) |
2057 | redirty_page_for_writepage(wbc, | 2103 | redirty_page_for_writepage(wbc, |
@@ -2066,6 +2112,11 @@ retry: | |||
2066 | } | 2112 | } |
2067 | kref_put(&wdata->refcount, cifs_writedata_release); | 2113 | kref_put(&wdata->refcount, cifs_writedata_release); |
2068 | 2114 | ||
2115 | if (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN) { | ||
2116 | index = saved_index; | ||
2117 | continue; | ||
2118 | } | ||
2119 | |||
2069 | wbc->nr_to_write -= nr_pages; | 2120 | wbc->nr_to_write -= nr_pages; |
2070 | if (wbc->nr_to_write <= 0) | 2121 | if (wbc->nr_to_write <= 0) |
2071 | done = true; | 2122 | done = true; |
@@ -2362,123 +2413,109 @@ cifs_uncached_writev_complete(struct work_struct *work) | |||
2362 | kref_put(&wdata->refcount, cifs_uncached_writedata_release); | 2413 | kref_put(&wdata->refcount, cifs_uncached_writedata_release); |
2363 | } | 2414 | } |
2364 | 2415 | ||
2365 | /* attempt to send write to server, retry on any -EAGAIN errors */ | ||
2366 | static int | 2416 | static int |
2367 | cifs_uncached_retry_writev(struct cifs_writedata *wdata) | 2417 | wdata_fill_from_iovec(struct cifs_writedata *wdata, struct iov_iter *from, |
2418 | size_t *len, unsigned long *num_pages) | ||
2368 | { | 2419 | { |
2369 | int rc; | 2420 | size_t save_len, copied, bytes, cur_len = *len; |
2370 | struct TCP_Server_Info *server; | 2421 | unsigned long i, nr_pages = *num_pages; |
2371 | 2422 | ||
2372 | server = tlink_tcon(wdata->cfile->tlink)->ses->server; | 2423 | save_len = cur_len; |
2424 | for (i = 0; i < nr_pages; i++) { | ||
2425 | bytes = min_t(const size_t, cur_len, PAGE_SIZE); | ||
2426 | copied = copy_page_from_iter(wdata->pages[i], 0, bytes, from); | ||
2427 | cur_len -= copied; | ||
2428 | /* | ||
2429 | * If we didn't copy as much as we expected, then that | ||
2430 | * may mean we trod into an unmapped area. Stop copying | ||
2431 | * at that point. On the next pass through the big | ||
2432 | * loop, we'll likely end up getting a zero-length | ||
2433 | * write and bailing out of it. | ||
2434 | */ | ||
2435 | if (copied < bytes) | ||
2436 | break; | ||
2437 | } | ||
2438 | cur_len = save_len - cur_len; | ||
2439 | *len = cur_len; | ||
2373 | 2440 | ||
2374 | do { | 2441 | /* |
2375 | if (wdata->cfile->invalidHandle) { | 2442 | * If we have no data to send, then that probably means that |
2376 | rc = cifs_reopen_file(wdata->cfile, false); | 2443 | * the copy above failed altogether. That's most likely because |
2377 | if (rc != 0) | 2444 | * the address in the iovec was bogus. Return -EFAULT and let |
2378 | continue; | 2445 | * the caller free anything we allocated and bail out. |
2379 | } | 2446 | */ |
2380 | rc = server->ops->async_writev(wdata, | 2447 | if (!cur_len) |
2381 | cifs_uncached_writedata_release); | 2448 | return -EFAULT; |
2382 | } while (rc == -EAGAIN); | ||
2383 | 2449 | ||
2384 | return rc; | 2450 | /* |
2451 | * i + 1 now represents the number of pages we actually used in | ||
2452 | * the copy phase above. | ||
2453 | */ | ||
2454 | *num_pages = i + 1; | ||
2455 | return 0; | ||
2385 | } | 2456 | } |
2386 | 2457 | ||
2387 | static ssize_t | 2458 | static int |
2388 | cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset) | 2459 | cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, |
2460 | struct cifsFileInfo *open_file, | ||
2461 | struct cifs_sb_info *cifs_sb, struct list_head *wdata_list) | ||
2389 | { | 2462 | { |
2390 | unsigned long nr_pages, i; | 2463 | int rc = 0; |
2391 | size_t bytes, copied, len, cur_len; | 2464 | size_t cur_len; |
2392 | ssize_t total_written = 0; | 2465 | unsigned long nr_pages, num_pages, i; |
2393 | loff_t offset; | 2466 | struct cifs_writedata *wdata; |
2394 | struct cifsFileInfo *open_file; | 2467 | struct iov_iter saved_from; |
2395 | struct cifs_tcon *tcon; | 2468 | loff_t saved_offset = offset; |
2396 | struct cifs_sb_info *cifs_sb; | ||
2397 | struct cifs_writedata *wdata, *tmp; | ||
2398 | struct list_head wdata_list; | ||
2399 | int rc; | ||
2400 | pid_t pid; | 2469 | pid_t pid; |
2401 | 2470 | struct TCP_Server_Info *server; | |
2402 | len = iov_iter_count(from); | ||
2403 | rc = generic_write_checks(file, poffset, &len, 0); | ||
2404 | if (rc) | ||
2405 | return rc; | ||
2406 | |||
2407 | if (!len) | ||
2408 | return 0; | ||
2409 | |||
2410 | iov_iter_truncate(from, len); | ||
2411 | |||
2412 | INIT_LIST_HEAD(&wdata_list); | ||
2413 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | ||
2414 | open_file = file->private_data; | ||
2415 | tcon = tlink_tcon(open_file->tlink); | ||
2416 | |||
2417 | if (!tcon->ses->server->ops->async_writev) | ||
2418 | return -ENOSYS; | ||
2419 | |||
2420 | offset = *poffset; | ||
2421 | 2471 | ||
2422 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) | 2472 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) |
2423 | pid = open_file->pid; | 2473 | pid = open_file->pid; |
2424 | else | 2474 | else |
2425 | pid = current->tgid; | 2475 | pid = current->tgid; |
2426 | 2476 | ||
2477 | server = tlink_tcon(open_file->tlink)->ses->server; | ||
2478 | memcpy(&saved_from, from, sizeof(struct iov_iter)); | ||
2479 | |||
2427 | do { | 2480 | do { |
2428 | size_t save_len; | 2481 | unsigned int wsize, credits; |
2482 | |||
2483 | rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize, | ||
2484 | &wsize, &credits); | ||
2485 | if (rc) | ||
2486 | break; | ||
2429 | 2487 | ||
2430 | nr_pages = get_numpages(cifs_sb->wsize, len, &cur_len); | 2488 | nr_pages = get_numpages(wsize, len, &cur_len); |
2431 | wdata = cifs_writedata_alloc(nr_pages, | 2489 | wdata = cifs_writedata_alloc(nr_pages, |
2432 | cifs_uncached_writev_complete); | 2490 | cifs_uncached_writev_complete); |
2433 | if (!wdata) { | 2491 | if (!wdata) { |
2434 | rc = -ENOMEM; | 2492 | rc = -ENOMEM; |
2493 | add_credits_and_wake_if(server, credits, 0); | ||
2435 | break; | 2494 | break; |
2436 | } | 2495 | } |
2437 | 2496 | ||
2438 | rc = cifs_write_allocate_pages(wdata->pages, nr_pages); | 2497 | rc = cifs_write_allocate_pages(wdata->pages, nr_pages); |
2439 | if (rc) { | 2498 | if (rc) { |
2440 | kfree(wdata); | 2499 | kfree(wdata); |
2500 | add_credits_and_wake_if(server, credits, 0); | ||
2441 | break; | 2501 | break; |
2442 | } | 2502 | } |
2443 | 2503 | ||
2444 | save_len = cur_len; | 2504 | num_pages = nr_pages; |
2445 | for (i = 0; i < nr_pages; i++) { | 2505 | rc = wdata_fill_from_iovec(wdata, from, &cur_len, &num_pages); |
2446 | bytes = min_t(size_t, cur_len, PAGE_SIZE); | 2506 | if (rc) { |
2447 | copied = copy_page_from_iter(wdata->pages[i], 0, bytes, | ||
2448 | from); | ||
2449 | cur_len -= copied; | ||
2450 | /* | ||
2451 | * If we didn't copy as much as we expected, then that | ||
2452 | * may mean we trod into an unmapped area. Stop copying | ||
2453 | * at that point. On the next pass through the big | ||
2454 | * loop, we'll likely end up getting a zero-length | ||
2455 | * write and bailing out of it. | ||
2456 | */ | ||
2457 | if (copied < bytes) | ||
2458 | break; | ||
2459 | } | ||
2460 | cur_len = save_len - cur_len; | ||
2461 | |||
2462 | /* | ||
2463 | * If we have no data to send, then that probably means that | ||
2464 | * the copy above failed altogether. That's most likely because | ||
2465 | * the address in the iovec was bogus. Set the rc to -EFAULT, | ||
2466 | * free anything we allocated and bail out. | ||
2467 | */ | ||
2468 | if (!cur_len) { | ||
2469 | for (i = 0; i < nr_pages; i++) | 2507 | for (i = 0; i < nr_pages; i++) |
2470 | put_page(wdata->pages[i]); | 2508 | put_page(wdata->pages[i]); |
2471 | kfree(wdata); | 2509 | kfree(wdata); |
2472 | rc = -EFAULT; | 2510 | add_credits_and_wake_if(server, credits, 0); |
2473 | break; | 2511 | break; |
2474 | } | 2512 | } |
2475 | 2513 | ||
2476 | /* | 2514 | /* |
2477 | * i + 1 now represents the number of pages we actually used in | 2515 | * Bring nr_pages down to the number of pages we actually used, |
2478 | * the copy phase above. Bring nr_pages down to that, and free | 2516 | * and free any pages that we didn't use. |
2479 | * any pages that we didn't use. | ||
2480 | */ | 2517 | */ |
2481 | for ( ; nr_pages > i + 1; nr_pages--) | 2518 | for ( ; nr_pages > num_pages; nr_pages--) |
2482 | put_page(wdata->pages[nr_pages - 1]); | 2519 | put_page(wdata->pages[nr_pages - 1]); |
2483 | 2520 | ||
2484 | wdata->sync_mode = WB_SYNC_ALL; | 2521 | wdata->sync_mode = WB_SYNC_ALL; |
@@ -2489,18 +2526,69 @@ cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset) | |||
2489 | wdata->bytes = cur_len; | 2526 | wdata->bytes = cur_len; |
2490 | wdata->pagesz = PAGE_SIZE; | 2527 | wdata->pagesz = PAGE_SIZE; |
2491 | wdata->tailsz = cur_len - ((nr_pages - 1) * PAGE_SIZE); | 2528 | wdata->tailsz = cur_len - ((nr_pages - 1) * PAGE_SIZE); |
2492 | rc = cifs_uncached_retry_writev(wdata); | 2529 | wdata->credits = credits; |
2530 | |||
2531 | if (!wdata->cfile->invalidHandle || | ||
2532 | !cifs_reopen_file(wdata->cfile, false)) | ||
2533 | rc = server->ops->async_writev(wdata, | ||
2534 | cifs_uncached_writedata_release); | ||
2493 | if (rc) { | 2535 | if (rc) { |
2536 | add_credits_and_wake_if(server, wdata->credits, 0); | ||
2494 | kref_put(&wdata->refcount, | 2537 | kref_put(&wdata->refcount, |
2495 | cifs_uncached_writedata_release); | 2538 | cifs_uncached_writedata_release); |
2539 | if (rc == -EAGAIN) { | ||
2540 | memcpy(from, &saved_from, | ||
2541 | sizeof(struct iov_iter)); | ||
2542 | iov_iter_advance(from, offset - saved_offset); | ||
2543 | continue; | ||
2544 | } | ||
2496 | break; | 2545 | break; |
2497 | } | 2546 | } |
2498 | 2547 | ||
2499 | list_add_tail(&wdata->list, &wdata_list); | 2548 | list_add_tail(&wdata->list, wdata_list); |
2500 | offset += cur_len; | 2549 | offset += cur_len; |
2501 | len -= cur_len; | 2550 | len -= cur_len; |
2502 | } while (len > 0); | 2551 | } while (len > 0); |
2503 | 2552 | ||
2553 | return rc; | ||
2554 | } | ||
2555 | |||
2556 | static ssize_t | ||
2557 | cifs_iovec_write(struct file *file, struct iov_iter *from, loff_t *poffset) | ||
2558 | { | ||
2559 | size_t len; | ||
2560 | ssize_t total_written = 0; | ||
2561 | struct cifsFileInfo *open_file; | ||
2562 | struct cifs_tcon *tcon; | ||
2563 | struct cifs_sb_info *cifs_sb; | ||
2564 | struct cifs_writedata *wdata, *tmp; | ||
2565 | struct list_head wdata_list; | ||
2566 | struct iov_iter saved_from; | ||
2567 | int rc; | ||
2568 | |||
2569 | len = iov_iter_count(from); | ||
2570 | rc = generic_write_checks(file, poffset, &len, 0); | ||
2571 | if (rc) | ||
2572 | return rc; | ||
2573 | |||
2574 | if (!len) | ||
2575 | return 0; | ||
2576 | |||
2577 | iov_iter_truncate(from, len); | ||
2578 | |||
2579 | INIT_LIST_HEAD(&wdata_list); | ||
2580 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | ||
2581 | open_file = file->private_data; | ||
2582 | tcon = tlink_tcon(open_file->tlink); | ||
2583 | |||
2584 | if (!tcon->ses->server->ops->async_writev) | ||
2585 | return -ENOSYS; | ||
2586 | |||
2587 | memcpy(&saved_from, from, sizeof(struct iov_iter)); | ||
2588 | |||
2589 | rc = cifs_write_from_iter(*poffset, len, from, open_file, cifs_sb, | ||
2590 | &wdata_list); | ||
2591 | |||
2504 | /* | 2592 | /* |
2505 | * If at least one write was successfully sent, then discard any rc | 2593 | * If at least one write was successfully sent, then discard any rc |
2506 | * value from the later writes. If the other write succeeds, then | 2594 | * value from the later writes. If the other write succeeds, then |
@@ -2529,7 +2617,25 @@ restart_loop: | |||
2529 | 2617 | ||
2530 | /* resend call if it's a retryable error */ | 2618 | /* resend call if it's a retryable error */ |
2531 | if (rc == -EAGAIN) { | 2619 | if (rc == -EAGAIN) { |
2532 | rc = cifs_uncached_retry_writev(wdata); | 2620 | struct list_head tmp_list; |
2621 | struct iov_iter tmp_from; | ||
2622 | |||
2623 | INIT_LIST_HEAD(&tmp_list); | ||
2624 | list_del_init(&wdata->list); | ||
2625 | |||
2626 | memcpy(&tmp_from, &saved_from, | ||
2627 | sizeof(struct iov_iter)); | ||
2628 | iov_iter_advance(&tmp_from, | ||
2629 | wdata->offset - *poffset); | ||
2630 | |||
2631 | rc = cifs_write_from_iter(wdata->offset, | ||
2632 | wdata->bytes, &tmp_from, | ||
2633 | open_file, cifs_sb, &tmp_list); | ||
2634 | |||
2635 | list_splice(&tmp_list, &wdata_list); | ||
2636 | |||
2637 | kref_put(&wdata->refcount, | ||
2638 | cifs_uncached_writedata_release); | ||
2533 | goto restart_loop; | 2639 | goto restart_loop; |
2534 | } | 2640 | } |
2535 | } | 2641 | } |
@@ -2722,26 +2828,6 @@ cifs_uncached_readdata_release(struct kref *refcount) | |||
2722 | cifs_readdata_release(refcount); | 2828 | cifs_readdata_release(refcount); |
2723 | } | 2829 | } |
2724 | 2830 | ||
2725 | static int | ||
2726 | cifs_retry_async_readv(struct cifs_readdata *rdata) | ||
2727 | { | ||
2728 | int rc; | ||
2729 | struct TCP_Server_Info *server; | ||
2730 | |||
2731 | server = tlink_tcon(rdata->cfile->tlink)->ses->server; | ||
2732 | |||
2733 | do { | ||
2734 | if (rdata->cfile->invalidHandle) { | ||
2735 | rc = cifs_reopen_file(rdata->cfile, true); | ||
2736 | if (rc != 0) | ||
2737 | continue; | ||
2738 | } | ||
2739 | rc = server->ops->async_readv(rdata); | ||
2740 | } while (rc == -EAGAIN); | ||
2741 | |||
2742 | return rc; | ||
2743 | } | ||
2744 | |||
2745 | /** | 2831 | /** |
2746 | * cifs_readdata_to_iov - copy data from pages in response to an iovec | 2832 | * cifs_readdata_to_iov - copy data from pages in response to an iovec |
2747 | * @rdata: the readdata response with list of pages holding data | 2833 | * @rdata: the readdata response with list of pages holding data |
@@ -2754,7 +2840,7 @@ cifs_retry_async_readv(struct cifs_readdata *rdata) | |||
2754 | static int | 2840 | static int |
2755 | cifs_readdata_to_iov(struct cifs_readdata *rdata, struct iov_iter *iter) | 2841 | cifs_readdata_to_iov(struct cifs_readdata *rdata, struct iov_iter *iter) |
2756 | { | 2842 | { |
2757 | size_t remaining = rdata->bytes; | 2843 | size_t remaining = rdata->got_bytes; |
2758 | unsigned int i; | 2844 | unsigned int i; |
2759 | 2845 | ||
2760 | for (i = 0; i < rdata->nr_pages; i++) { | 2846 | for (i = 0; i < rdata->nr_pages; i++) { |
@@ -2782,11 +2868,12 @@ static int | |||
2782 | cifs_uncached_read_into_pages(struct TCP_Server_Info *server, | 2868 | cifs_uncached_read_into_pages(struct TCP_Server_Info *server, |
2783 | struct cifs_readdata *rdata, unsigned int len) | 2869 | struct cifs_readdata *rdata, unsigned int len) |
2784 | { | 2870 | { |
2785 | int total_read = 0, result = 0; | 2871 | int result = 0; |
2786 | unsigned int i; | 2872 | unsigned int i; |
2787 | unsigned int nr_pages = rdata->nr_pages; | 2873 | unsigned int nr_pages = rdata->nr_pages; |
2788 | struct kvec iov; | 2874 | struct kvec iov; |
2789 | 2875 | ||
2876 | rdata->got_bytes = 0; | ||
2790 | rdata->tailsz = PAGE_SIZE; | 2877 | rdata->tailsz = PAGE_SIZE; |
2791 | for (i = 0; i < nr_pages; i++) { | 2878 | for (i = 0; i < nr_pages; i++) { |
2792 | struct page *page = rdata->pages[i]; | 2879 | struct page *page = rdata->pages[i]; |
@@ -2820,55 +2907,45 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server, | |||
2820 | if (result < 0) | 2907 | if (result < 0) |
2821 | break; | 2908 | break; |
2822 | 2909 | ||
2823 | total_read += result; | 2910 | rdata->got_bytes += result; |
2824 | } | 2911 | } |
2825 | 2912 | ||
2826 | return total_read > 0 ? total_read : result; | 2913 | return rdata->got_bytes > 0 && result != -ECONNABORTED ? |
2914 | rdata->got_bytes : result; | ||
2827 | } | 2915 | } |
2828 | 2916 | ||
2829 | ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to) | 2917 | static int |
2918 | cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, | ||
2919 | struct cifs_sb_info *cifs_sb, struct list_head *rdata_list) | ||
2830 | { | 2920 | { |
2831 | struct file *file = iocb->ki_filp; | 2921 | struct cifs_readdata *rdata; |
2832 | ssize_t rc; | 2922 | unsigned int npages, rsize, credits; |
2833 | size_t len, cur_len; | 2923 | size_t cur_len; |
2834 | ssize_t total_read = 0; | 2924 | int rc; |
2835 | loff_t offset = iocb->ki_pos; | ||
2836 | unsigned int npages; | ||
2837 | struct cifs_sb_info *cifs_sb; | ||
2838 | struct cifs_tcon *tcon; | ||
2839 | struct cifsFileInfo *open_file; | ||
2840 | struct cifs_readdata *rdata, *tmp; | ||
2841 | struct list_head rdata_list; | ||
2842 | pid_t pid; | 2925 | pid_t pid; |
2926 | struct TCP_Server_Info *server; | ||
2843 | 2927 | ||
2844 | len = iov_iter_count(to); | 2928 | server = tlink_tcon(open_file->tlink)->ses->server; |
2845 | if (!len) | ||
2846 | return 0; | ||
2847 | |||
2848 | INIT_LIST_HEAD(&rdata_list); | ||
2849 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | ||
2850 | open_file = file->private_data; | ||
2851 | tcon = tlink_tcon(open_file->tlink); | ||
2852 | |||
2853 | if (!tcon->ses->server->ops->async_readv) | ||
2854 | return -ENOSYS; | ||
2855 | 2929 | ||
2856 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) | 2930 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) |
2857 | pid = open_file->pid; | 2931 | pid = open_file->pid; |
2858 | else | 2932 | else |
2859 | pid = current->tgid; | 2933 | pid = current->tgid; |
2860 | 2934 | ||
2861 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | ||
2862 | cifs_dbg(FYI, "attempting read on write only file instance\n"); | ||
2863 | |||
2864 | do { | 2935 | do { |
2865 | cur_len = min_t(const size_t, len - total_read, cifs_sb->rsize); | 2936 | rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize, |
2937 | &rsize, &credits); | ||
2938 | if (rc) | ||
2939 | break; | ||
2940 | |||
2941 | cur_len = min_t(const size_t, len, rsize); | ||
2866 | npages = DIV_ROUND_UP(cur_len, PAGE_SIZE); | 2942 | npages = DIV_ROUND_UP(cur_len, PAGE_SIZE); |
2867 | 2943 | ||
2868 | /* allocate a readdata struct */ | 2944 | /* allocate a readdata struct */ |
2869 | rdata = cifs_readdata_alloc(npages, | 2945 | rdata = cifs_readdata_alloc(npages, |
2870 | cifs_uncached_readv_complete); | 2946 | cifs_uncached_readv_complete); |
2871 | if (!rdata) { | 2947 | if (!rdata) { |
2948 | add_credits_and_wake_if(server, credits, 0); | ||
2872 | rc = -ENOMEM; | 2949 | rc = -ENOMEM; |
2873 | break; | 2950 | break; |
2874 | } | 2951 | } |
@@ -2884,44 +2961,113 @@ ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to) | |||
2884 | rdata->pid = pid; | 2961 | rdata->pid = pid; |
2885 | rdata->pagesz = PAGE_SIZE; | 2962 | rdata->pagesz = PAGE_SIZE; |
2886 | rdata->read_into_pages = cifs_uncached_read_into_pages; | 2963 | rdata->read_into_pages = cifs_uncached_read_into_pages; |
2964 | rdata->credits = credits; | ||
2887 | 2965 | ||
2888 | rc = cifs_retry_async_readv(rdata); | 2966 | if (!rdata->cfile->invalidHandle || |
2967 | !cifs_reopen_file(rdata->cfile, true)) | ||
2968 | rc = server->ops->async_readv(rdata); | ||
2889 | error: | 2969 | error: |
2890 | if (rc) { | 2970 | if (rc) { |
2971 | add_credits_and_wake_if(server, rdata->credits, 0); | ||
2891 | kref_put(&rdata->refcount, | 2972 | kref_put(&rdata->refcount, |
2892 | cifs_uncached_readdata_release); | 2973 | cifs_uncached_readdata_release); |
2974 | if (rc == -EAGAIN) | ||
2975 | continue; | ||
2893 | break; | 2976 | break; |
2894 | } | 2977 | } |
2895 | 2978 | ||
2896 | list_add_tail(&rdata->list, &rdata_list); | 2979 | list_add_tail(&rdata->list, rdata_list); |
2897 | offset += cur_len; | 2980 | offset += cur_len; |
2898 | len -= cur_len; | 2981 | len -= cur_len; |
2899 | } while (len > 0); | 2982 | } while (len > 0); |
2900 | 2983 | ||
2984 | return rc; | ||
2985 | } | ||
2986 | |||
2987 | ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to) | ||
2988 | { | ||
2989 | struct file *file = iocb->ki_filp; | ||
2990 | ssize_t rc; | ||
2991 | size_t len; | ||
2992 | ssize_t total_read = 0; | ||
2993 | loff_t offset = iocb->ki_pos; | ||
2994 | struct cifs_sb_info *cifs_sb; | ||
2995 | struct cifs_tcon *tcon; | ||
2996 | struct cifsFileInfo *open_file; | ||
2997 | struct cifs_readdata *rdata, *tmp; | ||
2998 | struct list_head rdata_list; | ||
2999 | |||
3000 | len = iov_iter_count(to); | ||
3001 | if (!len) | ||
3002 | return 0; | ||
3003 | |||
3004 | INIT_LIST_HEAD(&rdata_list); | ||
3005 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | ||
3006 | open_file = file->private_data; | ||
3007 | tcon = tlink_tcon(open_file->tlink); | ||
3008 | |||
3009 | if (!tcon->ses->server->ops->async_readv) | ||
3010 | return -ENOSYS; | ||
3011 | |||
3012 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | ||
3013 | cifs_dbg(FYI, "attempting read on write only file instance\n"); | ||
3014 | |||
3015 | rc = cifs_send_async_read(offset, len, open_file, cifs_sb, &rdata_list); | ||
3016 | |||
2901 | /* if at least one read request send succeeded, then reset rc */ | 3017 | /* if at least one read request send succeeded, then reset rc */ |
2902 | if (!list_empty(&rdata_list)) | 3018 | if (!list_empty(&rdata_list)) |
2903 | rc = 0; | 3019 | rc = 0; |
2904 | 3020 | ||
2905 | len = iov_iter_count(to); | 3021 | len = iov_iter_count(to); |
2906 | /* the loop below should proceed in the order of increasing offsets */ | 3022 | /* the loop below should proceed in the order of increasing offsets */ |
3023 | again: | ||
2907 | list_for_each_entry_safe(rdata, tmp, &rdata_list, list) { | 3024 | list_for_each_entry_safe(rdata, tmp, &rdata_list, list) { |
2908 | again: | ||
2909 | if (!rc) { | 3025 | if (!rc) { |
2910 | /* FIXME: freezable sleep too? */ | 3026 | /* FIXME: freezable sleep too? */ |
2911 | rc = wait_for_completion_killable(&rdata->done); | 3027 | rc = wait_for_completion_killable(&rdata->done); |
2912 | if (rc) | 3028 | if (rc) |
2913 | rc = -EINTR; | 3029 | rc = -EINTR; |
2914 | else if (rdata->result) { | 3030 | else if (rdata->result == -EAGAIN) { |
2915 | rc = rdata->result; | ||
2916 | /* resend call if it's a retryable error */ | 3031 | /* resend call if it's a retryable error */ |
2917 | if (rc == -EAGAIN) { | 3032 | struct list_head tmp_list; |
2918 | rc = cifs_retry_async_readv(rdata); | 3033 | unsigned int got_bytes = rdata->got_bytes; |
2919 | goto again; | 3034 | |
3035 | list_del_init(&rdata->list); | ||
3036 | INIT_LIST_HEAD(&tmp_list); | ||
3037 | |||
3038 | /* | ||
3039 | * Got a part of data and then reconnect has | ||
3040 | * happened -- fill the buffer and continue | ||
3041 | * reading. | ||
3042 | */ | ||
3043 | if (got_bytes && got_bytes < rdata->bytes) { | ||
3044 | rc = cifs_readdata_to_iov(rdata, to); | ||
3045 | if (rc) { | ||
3046 | kref_put(&rdata->refcount, | ||
3047 | cifs_uncached_readdata_release); | ||
3048 | continue; | ||
3049 | } | ||
2920 | } | 3050 | } |
2921 | } else { | 3051 | |
3052 | rc = cifs_send_async_read( | ||
3053 | rdata->offset + got_bytes, | ||
3054 | rdata->bytes - got_bytes, | ||
3055 | rdata->cfile, cifs_sb, | ||
3056 | &tmp_list); | ||
3057 | |||
3058 | list_splice(&tmp_list, &rdata_list); | ||
3059 | |||
3060 | kref_put(&rdata->refcount, | ||
3061 | cifs_uncached_readdata_release); | ||
3062 | goto again; | ||
3063 | } else if (rdata->result) | ||
3064 | rc = rdata->result; | ||
3065 | else | ||
2922 | rc = cifs_readdata_to_iov(rdata, to); | 3066 | rc = cifs_readdata_to_iov(rdata, to); |
2923 | } | ||
2924 | 3067 | ||
3068 | /* if there was a short read -- discard anything left */ | ||
3069 | if (rdata->got_bytes && rdata->got_bytes < rdata->bytes) | ||
3070 | rc = -ENODATA; | ||
2925 | } | 3071 | } |
2926 | list_del_init(&rdata->list); | 3072 | list_del_init(&rdata->list); |
2927 | kref_put(&rdata->refcount, cifs_uncached_readdata_release); | 3073 | kref_put(&rdata->refcount, cifs_uncached_readdata_release); |
@@ -3030,18 +3176,19 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset) | |||
3030 | 3176 | ||
3031 | for (total_read = 0, cur_offset = read_data; read_size > total_read; | 3177 | for (total_read = 0, cur_offset = read_data; read_size > total_read; |
3032 | total_read += bytes_read, cur_offset += bytes_read) { | 3178 | total_read += bytes_read, cur_offset += bytes_read) { |
3033 | current_read_size = min_t(uint, read_size - total_read, rsize); | 3179 | do { |
3034 | /* | 3180 | current_read_size = min_t(uint, read_size - total_read, |
3035 | * For windows me and 9x we do not want to request more than it | 3181 | rsize); |
3036 | * negotiated since it will refuse the read then. | 3182 | /* |
3037 | */ | 3183 | * For windows me and 9x we do not want to request more |
3038 | if ((tcon->ses) && !(tcon->ses->capabilities & | 3184 | * than it negotiated since it will refuse the read |
3185 | * then. | ||
3186 | */ | ||
3187 | if ((tcon->ses) && !(tcon->ses->capabilities & | ||
3039 | tcon->ses->server->vals->cap_large_files)) { | 3188 | tcon->ses->server->vals->cap_large_files)) { |
3040 | current_read_size = min_t(uint, current_read_size, | 3189 | current_read_size = min_t(uint, |
3041 | CIFSMaxBufSize); | 3190 | current_read_size, CIFSMaxBufSize); |
3042 | } | 3191 | } |
3043 | rc = -EAGAIN; | ||
3044 | while (rc == -EAGAIN) { | ||
3045 | if (open_file->invalidHandle) { | 3192 | if (open_file->invalidHandle) { |
3046 | rc = cifs_reopen_file(open_file, true); | 3193 | rc = cifs_reopen_file(open_file, true); |
3047 | if (rc != 0) | 3194 | if (rc != 0) |
@@ -3054,7 +3201,8 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset) | |||
3054 | rc = server->ops->sync_read(xid, open_file, &io_parms, | 3201 | rc = server->ops->sync_read(xid, open_file, &io_parms, |
3055 | &bytes_read, &cur_offset, | 3202 | &bytes_read, &cur_offset, |
3056 | &buf_type); | 3203 | &buf_type); |
3057 | } | 3204 | } while (rc == -EAGAIN); |
3205 | |||
3058 | if (rc || (bytes_read == 0)) { | 3206 | if (rc || (bytes_read == 0)) { |
3059 | if (total_read) { | 3207 | if (total_read) { |
3060 | break; | 3208 | break; |
@@ -3133,25 +3281,30 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
3133 | static void | 3281 | static void |
3134 | cifs_readv_complete(struct work_struct *work) | 3282 | cifs_readv_complete(struct work_struct *work) |
3135 | { | 3283 | { |
3136 | unsigned int i; | 3284 | unsigned int i, got_bytes; |
3137 | struct cifs_readdata *rdata = container_of(work, | 3285 | struct cifs_readdata *rdata = container_of(work, |
3138 | struct cifs_readdata, work); | 3286 | struct cifs_readdata, work); |
3139 | 3287 | ||
3288 | got_bytes = rdata->got_bytes; | ||
3140 | for (i = 0; i < rdata->nr_pages; i++) { | 3289 | for (i = 0; i < rdata->nr_pages; i++) { |
3141 | struct page *page = rdata->pages[i]; | 3290 | struct page *page = rdata->pages[i]; |
3142 | 3291 | ||
3143 | lru_cache_add_file(page); | 3292 | lru_cache_add_file(page); |
3144 | 3293 | ||
3145 | if (rdata->result == 0) { | 3294 | if (rdata->result == 0 || |
3295 | (rdata->result == -EAGAIN && got_bytes)) { | ||
3146 | flush_dcache_page(page); | 3296 | flush_dcache_page(page); |
3147 | SetPageUptodate(page); | 3297 | SetPageUptodate(page); |
3148 | } | 3298 | } |
3149 | 3299 | ||
3150 | unlock_page(page); | 3300 | unlock_page(page); |
3151 | 3301 | ||
3152 | if (rdata->result == 0) | 3302 | if (rdata->result == 0 || |
3303 | (rdata->result == -EAGAIN && got_bytes)) | ||
3153 | cifs_readpage_to_fscache(rdata->mapping->host, page); | 3304 | cifs_readpage_to_fscache(rdata->mapping->host, page); |
3154 | 3305 | ||
3306 | got_bytes -= min_t(unsigned int, PAGE_CACHE_SIZE, got_bytes); | ||
3307 | |||
3155 | page_cache_release(page); | 3308 | page_cache_release(page); |
3156 | rdata->pages[i] = NULL; | 3309 | rdata->pages[i] = NULL; |
3157 | } | 3310 | } |
@@ -3162,7 +3315,7 @@ static int | |||
3162 | cifs_readpages_read_into_pages(struct TCP_Server_Info *server, | 3315 | cifs_readpages_read_into_pages(struct TCP_Server_Info *server, |
3163 | struct cifs_readdata *rdata, unsigned int len) | 3316 | struct cifs_readdata *rdata, unsigned int len) |
3164 | { | 3317 | { |
3165 | int total_read = 0, result = 0; | 3318 | int result = 0; |
3166 | unsigned int i; | 3319 | unsigned int i; |
3167 | u64 eof; | 3320 | u64 eof; |
3168 | pgoff_t eof_index; | 3321 | pgoff_t eof_index; |
@@ -3174,6 +3327,7 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server, | |||
3174 | eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0; | 3327 | eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0; |
3175 | cifs_dbg(FYI, "eof=%llu eof_index=%lu\n", eof, eof_index); | 3328 | cifs_dbg(FYI, "eof=%llu eof_index=%lu\n", eof, eof_index); |
3176 | 3329 | ||
3330 | rdata->got_bytes = 0; | ||
3177 | rdata->tailsz = PAGE_CACHE_SIZE; | 3331 | rdata->tailsz = PAGE_CACHE_SIZE; |
3178 | for (i = 0; i < nr_pages; i++) { | 3332 | for (i = 0; i < nr_pages; i++) { |
3179 | struct page *page = rdata->pages[i]; | 3333 | struct page *page = rdata->pages[i]; |
@@ -3228,10 +3382,70 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server, | |||
3228 | if (result < 0) | 3382 | if (result < 0) |
3229 | break; | 3383 | break; |
3230 | 3384 | ||
3231 | total_read += result; | 3385 | rdata->got_bytes += result; |
3232 | } | 3386 | } |
3233 | 3387 | ||
3234 | return total_read > 0 ? total_read : result; | 3388 | return rdata->got_bytes > 0 && result != -ECONNABORTED ? |
3389 | rdata->got_bytes : result; | ||
3390 | } | ||
3391 | |||
3392 | static int | ||
3393 | readpages_get_pages(struct address_space *mapping, struct list_head *page_list, | ||
3394 | unsigned int rsize, struct list_head *tmplist, | ||
3395 | unsigned int *nr_pages, loff_t *offset, unsigned int *bytes) | ||
3396 | { | ||
3397 | struct page *page, *tpage; | ||
3398 | unsigned int expected_index; | ||
3399 | int rc; | ||
3400 | |||
3401 | INIT_LIST_HEAD(tmplist); | ||
3402 | |||
3403 | page = list_entry(page_list->prev, struct page, lru); | ||
3404 | |||
3405 | /* | ||
3406 | * Lock the page and put it in the cache. Since no one else | ||
3407 | * should have access to this page, we're safe to simply set | ||
3408 | * PG_locked without checking it first. | ||
3409 | */ | ||
3410 | __set_page_locked(page); | ||
3411 | rc = add_to_page_cache_locked(page, mapping, | ||
3412 | page->index, GFP_KERNEL); | ||
3413 | |||
3414 | /* give up if we can't stick it in the cache */ | ||
3415 | if (rc) { | ||
3416 | __clear_page_locked(page); | ||
3417 | return rc; | ||
3418 | } | ||
3419 | |||
3420 | /* move first page to the tmplist */ | ||
3421 | *offset = (loff_t)page->index << PAGE_CACHE_SHIFT; | ||
3422 | *bytes = PAGE_CACHE_SIZE; | ||
3423 | *nr_pages = 1; | ||
3424 | list_move_tail(&page->lru, tmplist); | ||
3425 | |||
3426 | /* now try and add more pages onto the request */ | ||
3427 | expected_index = page->index + 1; | ||
3428 | list_for_each_entry_safe_reverse(page, tpage, page_list, lru) { | ||
3429 | /* discontinuity ? */ | ||
3430 | if (page->index != expected_index) | ||
3431 | break; | ||
3432 | |||
3433 | /* would this page push the read over the rsize? */ | ||
3434 | if (*bytes + PAGE_CACHE_SIZE > rsize) | ||
3435 | break; | ||
3436 | |||
3437 | __set_page_locked(page); | ||
3438 | if (add_to_page_cache_locked(page, mapping, page->index, | ||
3439 | GFP_KERNEL)) { | ||
3440 | __clear_page_locked(page); | ||
3441 | break; | ||
3442 | } | ||
3443 | list_move_tail(&page->lru, tmplist); | ||
3444 | (*bytes) += PAGE_CACHE_SIZE; | ||
3445 | expected_index++; | ||
3446 | (*nr_pages)++; | ||
3447 | } | ||
3448 | return rc; | ||
3235 | } | 3449 | } |
3236 | 3450 | ||
3237 | static int cifs_readpages(struct file *file, struct address_space *mapping, | 3451 | static int cifs_readpages(struct file *file, struct address_space *mapping, |
@@ -3241,19 +3455,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
3241 | struct list_head tmplist; | 3455 | struct list_head tmplist; |
3242 | struct cifsFileInfo *open_file = file->private_data; | 3456 | struct cifsFileInfo *open_file = file->private_data; |
3243 | struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 3457 | struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
3244 | unsigned int rsize = cifs_sb->rsize; | 3458 | struct TCP_Server_Info *server; |
3245 | pid_t pid; | 3459 | pid_t pid; |
3246 | 3460 | ||
3247 | /* | 3461 | /* |
3248 | * Give up immediately if rsize is too small to read an entire page. | ||
3249 | * The VFS will fall back to readpage. We should never reach this | ||
3250 | * point however since we set ra_pages to 0 when the rsize is smaller | ||
3251 | * than a cache page. | ||
3252 | */ | ||
3253 | if (unlikely(rsize < PAGE_CACHE_SIZE)) | ||
3254 | return 0; | ||
3255 | |||
3256 | /* | ||
3257 | * Reads as many pages as possible from fscache. Returns -ENOBUFS | 3462 | * Reads as many pages as possible from fscache. Returns -ENOBUFS |
3258 | * immediately if the cookie is negative | 3463 | * immediately if the cookie is negative |
3259 | * | 3464 | * |
@@ -3271,7 +3476,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
3271 | pid = current->tgid; | 3476 | pid = current->tgid; |
3272 | 3477 | ||
3273 | rc = 0; | 3478 | rc = 0; |
3274 | INIT_LIST_HEAD(&tmplist); | 3479 | server = tlink_tcon(open_file->tlink)->ses->server; |
3275 | 3480 | ||
3276 | cifs_dbg(FYI, "%s: file=%p mapping=%p num_pages=%u\n", | 3481 | cifs_dbg(FYI, "%s: file=%p mapping=%p num_pages=%u\n", |
3277 | __func__, file, mapping, num_pages); | 3482 | __func__, file, mapping, num_pages); |
@@ -3288,58 +3493,35 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
3288 | * the rdata->pages, then we want them in increasing order. | 3493 | * the rdata->pages, then we want them in increasing order. |
3289 | */ | 3494 | */ |
3290 | while (!list_empty(page_list)) { | 3495 | while (!list_empty(page_list)) { |
3291 | unsigned int i; | 3496 | unsigned int i, nr_pages, bytes, rsize; |
3292 | unsigned int bytes = PAGE_CACHE_SIZE; | ||
3293 | unsigned int expected_index; | ||
3294 | unsigned int nr_pages = 1; | ||
3295 | loff_t offset; | 3497 | loff_t offset; |
3296 | struct page *page, *tpage; | 3498 | struct page *page, *tpage; |
3297 | struct cifs_readdata *rdata; | 3499 | struct cifs_readdata *rdata; |
3500 | unsigned credits; | ||
3298 | 3501 | ||
3299 | page = list_entry(page_list->prev, struct page, lru); | 3502 | rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize, |
3503 | &rsize, &credits); | ||
3504 | if (rc) | ||
3505 | break; | ||
3300 | 3506 | ||
3301 | /* | 3507 | /* |
3302 | * Lock the page and put it in the cache. Since no one else | 3508 | * Give up immediately if rsize is too small to read an entire |
3303 | * should have access to this page, we're safe to simply set | 3509 | * page. The VFS will fall back to readpage. We should never |
3304 | * PG_locked without checking it first. | 3510 | * reach this point however since we set ra_pages to 0 when the |
3511 | * rsize is smaller than a cache page. | ||
3305 | */ | 3512 | */ |
3306 | __set_page_locked(page); | 3513 | if (unlikely(rsize < PAGE_CACHE_SIZE)) { |
3307 | rc = add_to_page_cache_locked(page, mapping, | 3514 | add_credits_and_wake_if(server, credits, 0); |
3308 | page->index, GFP_KERNEL); | 3515 | return 0; |
3516 | } | ||
3309 | 3517 | ||
3310 | /* give up if we can't stick it in the cache */ | 3518 | rc = readpages_get_pages(mapping, page_list, rsize, &tmplist, |
3519 | &nr_pages, &offset, &bytes); | ||
3311 | if (rc) { | 3520 | if (rc) { |
3312 | __clear_page_locked(page); | 3521 | add_credits_and_wake_if(server, credits, 0); |
3313 | break; | 3522 | break; |
3314 | } | 3523 | } |
3315 | 3524 | ||
3316 | /* move first page to the tmplist */ | ||
3317 | offset = (loff_t)page->index << PAGE_CACHE_SHIFT; | ||
3318 | list_move_tail(&page->lru, &tmplist); | ||
3319 | |||
3320 | /* now try and add more pages onto the request */ | ||
3321 | expected_index = page->index + 1; | ||
3322 | list_for_each_entry_safe_reverse(page, tpage, page_list, lru) { | ||
3323 | /* discontinuity ? */ | ||
3324 | if (page->index != expected_index) | ||
3325 | break; | ||
3326 | |||
3327 | /* would this page push the read over the rsize? */ | ||
3328 | if (bytes + PAGE_CACHE_SIZE > rsize) | ||
3329 | break; | ||
3330 | |||
3331 | __set_page_locked(page); | ||
3332 | if (add_to_page_cache_locked(page, mapping, | ||
3333 | page->index, GFP_KERNEL)) { | ||
3334 | __clear_page_locked(page); | ||
3335 | break; | ||
3336 | } | ||
3337 | list_move_tail(&page->lru, &tmplist); | ||
3338 | bytes += PAGE_CACHE_SIZE; | ||
3339 | expected_index++; | ||
3340 | nr_pages++; | ||
3341 | } | ||
3342 | |||
3343 | rdata = cifs_readdata_alloc(nr_pages, cifs_readv_complete); | 3525 | rdata = cifs_readdata_alloc(nr_pages, cifs_readv_complete); |
3344 | if (!rdata) { | 3526 | if (!rdata) { |
3345 | /* best to give up if we're out of mem */ | 3527 | /* best to give up if we're out of mem */ |
@@ -3350,6 +3532,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
3350 | page_cache_release(page); | 3532 | page_cache_release(page); |
3351 | } | 3533 | } |
3352 | rc = -ENOMEM; | 3534 | rc = -ENOMEM; |
3535 | add_credits_and_wake_if(server, credits, 0); | ||
3353 | break; | 3536 | break; |
3354 | } | 3537 | } |
3355 | 3538 | ||
@@ -3360,21 +3543,32 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
3360 | rdata->pid = pid; | 3543 | rdata->pid = pid; |
3361 | rdata->pagesz = PAGE_CACHE_SIZE; | 3544 | rdata->pagesz = PAGE_CACHE_SIZE; |
3362 | rdata->read_into_pages = cifs_readpages_read_into_pages; | 3545 | rdata->read_into_pages = cifs_readpages_read_into_pages; |
3546 | rdata->credits = credits; | ||
3363 | 3547 | ||
3364 | list_for_each_entry_safe(page, tpage, &tmplist, lru) { | 3548 | list_for_each_entry_safe(page, tpage, &tmplist, lru) { |
3365 | list_del(&page->lru); | 3549 | list_del(&page->lru); |
3366 | rdata->pages[rdata->nr_pages++] = page; | 3550 | rdata->pages[rdata->nr_pages++] = page; |
3367 | } | 3551 | } |
3368 | 3552 | ||
3369 | rc = cifs_retry_async_readv(rdata); | 3553 | if (!rdata->cfile->invalidHandle || |
3370 | if (rc != 0) { | 3554 | !cifs_reopen_file(rdata->cfile, true)) |
3555 | rc = server->ops->async_readv(rdata); | ||
3556 | if (rc) { | ||
3557 | add_credits_and_wake_if(server, rdata->credits, 0); | ||
3371 | for (i = 0; i < rdata->nr_pages; i++) { | 3558 | for (i = 0; i < rdata->nr_pages; i++) { |
3372 | page = rdata->pages[i]; | 3559 | page = rdata->pages[i]; |
3373 | lru_cache_add_file(page); | 3560 | lru_cache_add_file(page); |
3374 | unlock_page(page); | 3561 | unlock_page(page); |
3375 | page_cache_release(page); | 3562 | page_cache_release(page); |
3563 | if (rc == -EAGAIN) | ||
3564 | list_add_tail(&page->lru, &tmplist); | ||
3376 | } | 3565 | } |
3377 | kref_put(&rdata->refcount, cifs_readdata_release); | 3566 | kref_put(&rdata->refcount, cifs_readdata_release); |
3567 | if (rc == -EAGAIN) { | ||
3568 | /* Re-add pages to the page_list and retry */ | ||
3569 | list_splice(&tmplist, page_list); | ||
3570 | continue; | ||
3571 | } | ||
3378 | break; | 3572 | break; |
3379 | } | 3573 | } |
3380 | 3574 | ||