aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c269
1 files changed, 185 insertions, 84 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 659ce1b92c44..4c144c1f50eb 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1842,24 +1842,30 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
1842 return NULL; 1842 return NULL;
1843} 1843}
1844 1844
1845struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, 1845/* Return -EBADF if no handle is found and general rc otherwise */
1846 bool fsuid_only) 1846int
1847cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only,
1848 struct cifsFileInfo **ret_file)
1847{ 1849{
1848 struct cifsFileInfo *open_file, *inv_file = NULL; 1850 struct cifsFileInfo *open_file, *inv_file = NULL;
1849 struct cifs_sb_info *cifs_sb; 1851 struct cifs_sb_info *cifs_sb;
1850 struct cifs_tcon *tcon; 1852 struct cifs_tcon *tcon;
1851 bool any_available = false; 1853 bool any_available = false;
1852 int rc; 1854 int rc = -EBADF;
1853 unsigned int refind = 0; 1855 unsigned int refind = 0;
1854 1856
1855 /* Having a null inode here (because mapping->host was set to zero by 1857 *ret_file = NULL;
1856 the VFS or MM) should not happen but we had reports of on oops (due to 1858
1857 it being zero) during stress testcases so we need to check for it */ 1859 /*
1860 * Having a null inode here (because mapping->host was set to zero by
1861 * the VFS or MM) should not happen but we had reports of on oops (due
1862 * to it being zero) during stress testcases so we need to check for it
1863 */
1858 1864
1859 if (cifs_inode == NULL) { 1865 if (cifs_inode == NULL) {
1860 cifs_dbg(VFS, "Null inode passed to cifs_writeable_file\n"); 1866 cifs_dbg(VFS, "Null inode passed to cifs_writeable_file\n");
1861 dump_stack(); 1867 dump_stack();
1862 return NULL; 1868 return rc;
1863 } 1869 }
1864 1870
1865 cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); 1871 cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
@@ -1873,7 +1879,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
1873refind_writable: 1879refind_writable:
1874 if (refind > MAX_REOPEN_ATT) { 1880 if (refind > MAX_REOPEN_ATT) {
1875 spin_unlock(&tcon->open_file_lock); 1881 spin_unlock(&tcon->open_file_lock);
1876 return NULL; 1882 return rc;
1877 } 1883 }
1878 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 1884 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
1879 if (!any_available && open_file->pid != current->tgid) 1885 if (!any_available && open_file->pid != current->tgid)
@@ -1885,7 +1891,8 @@ refind_writable:
1885 /* found a good writable file */ 1891 /* found a good writable file */
1886 cifsFileInfo_get(open_file); 1892 cifsFileInfo_get(open_file);
1887 spin_unlock(&tcon->open_file_lock); 1893 spin_unlock(&tcon->open_file_lock);
1888 return open_file; 1894 *ret_file = open_file;
1895 return 0;
1889 } else { 1896 } else {
1890 if (!inv_file) 1897 if (!inv_file)
1891 inv_file = open_file; 1898 inv_file = open_file;
@@ -1907,22 +1914,35 @@ refind_writable:
1907 1914
1908 if (inv_file) { 1915 if (inv_file) {
1909 rc = cifs_reopen_file(inv_file, false); 1916 rc = cifs_reopen_file(inv_file, false);
1910 if (!rc) 1917 if (!rc) {
1911 return inv_file; 1918 *ret_file = inv_file;
1912 else { 1919 return 0;
1913 spin_lock(&tcon->open_file_lock);
1914 list_move_tail(&inv_file->flist,
1915 &cifs_inode->openFileList);
1916 spin_unlock(&tcon->open_file_lock);
1917 cifsFileInfo_put(inv_file);
1918 ++refind;
1919 inv_file = NULL;
1920 spin_lock(&tcon->open_file_lock);
1921 goto refind_writable;
1922 } 1920 }
1921
1922 spin_lock(&tcon->open_file_lock);
1923 list_move_tail(&inv_file->flist, &cifs_inode->openFileList);
1924 spin_unlock(&tcon->open_file_lock);
1925 cifsFileInfo_put(inv_file);
1926 ++refind;
1927 inv_file = NULL;
1928 spin_lock(&tcon->open_file_lock);
1929 goto refind_writable;
1923 } 1930 }
1924 1931
1925 return NULL; 1932 return rc;
1933}
1934
1935struct cifsFileInfo *
1936find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only)
1937{
1938 struct cifsFileInfo *cfile;
1939 int rc;
1940
1941 rc = cifs_get_writable_file(cifs_inode, fsuid_only, &cfile);
1942 if (rc)
1943 cifs_dbg(FYI, "couldn't find writable handle rc=%d", rc);
1944
1945 return cfile;
1926} 1946}
1927 1947
1928static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) 1948static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
@@ -1959,8 +1979,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1959 if (mapping->host->i_size - offset < (loff_t)to) 1979 if (mapping->host->i_size - offset < (loff_t)to)
1960 to = (unsigned)(mapping->host->i_size - offset); 1980 to = (unsigned)(mapping->host->i_size - offset);
1961 1981
1962 open_file = find_writable_file(CIFS_I(mapping->host), false); 1982 rc = cifs_get_writable_file(CIFS_I(mapping->host), false, &open_file);
1963 if (open_file) { 1983 if (!rc) {
1964 bytes_written = cifs_write(open_file, open_file->pid, 1984 bytes_written = cifs_write(open_file, open_file->pid,
1965 write_data, to - from, &offset); 1985 write_data, to - from, &offset);
1966 cifsFileInfo_put(open_file); 1986 cifsFileInfo_put(open_file);
@@ -1970,9 +1990,12 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1970 rc = 0; 1990 rc = 0;
1971 else if (bytes_written < 0) 1991 else if (bytes_written < 0)
1972 rc = bytes_written; 1992 rc = bytes_written;
1993 else
1994 rc = -EFAULT;
1973 } else { 1995 } else {
1974 cifs_dbg(FYI, "No writeable filehandles for inode\n"); 1996 cifs_dbg(FYI, "No writable handle for write page rc=%d\n", rc);
1975 rc = -EIO; 1997 if (!is_retryable_error(rc))
1998 rc = -EIO;
1976 } 1999 }
1977 2000
1978 kunmap(page); 2001 kunmap(page);
@@ -2079,9 +2102,9 @@ static int
2079wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages, 2102wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
2080 struct address_space *mapping, struct writeback_control *wbc) 2103 struct address_space *mapping, struct writeback_control *wbc)
2081{ 2104{
2082 int rc = 0; 2105 int rc;
2083 struct TCP_Server_Info *server; 2106 struct TCP_Server_Info *server =
2084 unsigned int i; 2107 tlink_tcon(wdata->cfile->tlink)->ses->server;
2085 2108
2086 wdata->sync_mode = wbc->sync_mode; 2109 wdata->sync_mode = wbc->sync_mode;
2087 wdata->nr_pages = nr_pages; 2110 wdata->nr_pages = nr_pages;
@@ -2091,21 +2114,16 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
2091 page_offset(wdata->pages[nr_pages - 1]), 2114 page_offset(wdata->pages[nr_pages - 1]),
2092 (loff_t)PAGE_SIZE); 2115 (loff_t)PAGE_SIZE);
2093 wdata->bytes = ((nr_pages - 1) * PAGE_SIZE) + wdata->tailsz; 2116 wdata->bytes = ((nr_pages - 1) * PAGE_SIZE) + wdata->tailsz;
2117 wdata->pid = wdata->cfile->pid;
2094 2118
2095 if (wdata->cfile != NULL) 2119 rc = adjust_credits(server, &wdata->credits, wdata->bytes);
2096 cifsFileInfo_put(wdata->cfile); 2120 if (rc)
2097 wdata->cfile = find_writable_file(CIFS_I(mapping->host), false); 2121 return rc;
2098 if (!wdata->cfile) {
2099 cifs_dbg(VFS, "No writable handles for inode\n");
2100 rc = -EBADF;
2101 } else {
2102 wdata->pid = wdata->cfile->pid;
2103 server = tlink_tcon(wdata->cfile->tlink)->ses->server;
2104 rc = server->ops->async_writev(wdata, cifs_writedata_release);
2105 }
2106 2122
2107 for (i = 0; i < nr_pages; ++i) 2123 if (wdata->cfile->invalidHandle)
2108 unlock_page(wdata->pages[i]); 2124 rc = -EAGAIN;
2125 else
2126 rc = server->ops->async_writev(wdata, cifs_writedata_release);
2109 2127
2110 return rc; 2128 return rc;
2111} 2129}
@@ -2113,11 +2131,13 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
2113static int cifs_writepages(struct address_space *mapping, 2131static int cifs_writepages(struct address_space *mapping,
2114 struct writeback_control *wbc) 2132 struct writeback_control *wbc)
2115{ 2133{
2116 struct cifs_sb_info *cifs_sb = CIFS_SB(mapping->host->i_sb); 2134 struct inode *inode = mapping->host;
2135 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2117 struct TCP_Server_Info *server; 2136 struct TCP_Server_Info *server;
2118 bool done = false, scanned = false, range_whole = false; 2137 bool done = false, scanned = false, range_whole = false;
2119 pgoff_t end, index; 2138 pgoff_t end, index;
2120 struct cifs_writedata *wdata; 2139 struct cifs_writedata *wdata;
2140 struct cifsFileInfo *cfile = NULL;
2121 int rc = 0; 2141 int rc = 0;
2122 int saved_rc = 0; 2142 int saved_rc = 0;
2123 unsigned int xid; 2143 unsigned int xid;
@@ -2143,11 +2163,23 @@ static int cifs_writepages(struct address_space *mapping,
2143 server = cifs_sb_master_tcon(cifs_sb)->ses->server; 2163 server = cifs_sb_master_tcon(cifs_sb)->ses->server;
2144retry: 2164retry:
2145 while (!done && index <= end) { 2165 while (!done && index <= end) {
2146 unsigned int i, nr_pages, found_pages, wsize, credits; 2166 unsigned int i, nr_pages, found_pages, wsize;
2147 pgoff_t next = 0, tofind, saved_index = index; 2167 pgoff_t next = 0, tofind, saved_index = index;
2168 struct cifs_credits credits_on_stack;
2169 struct cifs_credits *credits = &credits_on_stack;
2170 int get_file_rc = 0;
2171
2172 if (cfile)
2173 cifsFileInfo_put(cfile);
2174
2175 rc = cifs_get_writable_file(CIFS_I(inode), false, &cfile);
2176
2177 /* in case of an error store it to return later */
2178 if (rc)
2179 get_file_rc = rc;
2148 2180
2149 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize, 2181 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
2150 &wsize, &credits); 2182 &wsize, credits);
2151 if (rc != 0) { 2183 if (rc != 0) {
2152 done = true; 2184 done = true;
2153 break; 2185 break;
@@ -2180,13 +2212,26 @@ retry:
2180 continue; 2212 continue;
2181 } 2213 }
2182 2214
2183 wdata->credits = credits; 2215 wdata->credits = credits_on_stack;
2216 wdata->cfile = cfile;
2217 cfile = NULL;
2184 2218
2185 rc = wdata_send_pages(wdata, nr_pages, mapping, wbc); 2219 if (!wdata->cfile) {
2220 cifs_dbg(VFS, "No writable handle in writepages rc=%d\n",
2221 get_file_rc);
2222 if (is_retryable_error(get_file_rc))
2223 rc = get_file_rc;
2224 else
2225 rc = -EBADF;
2226 } else
2227 rc = wdata_send_pages(wdata, nr_pages, mapping, wbc);
2228
2229 for (i = 0; i < nr_pages; ++i)
2230 unlock_page(wdata->pages[i]);
2186 2231
2187 /* send failure -- clean up the mess */ 2232 /* send failure -- clean up the mess */
2188 if (rc != 0) { 2233 if (rc != 0) {
2189 add_credits_and_wake_if(server, wdata->credits, 0); 2234 add_credits_and_wake_if(server, &wdata->credits, 0);
2190 for (i = 0; i < nr_pages; ++i) { 2235 for (i = 0; i < nr_pages; ++i) {
2191 if (is_retryable_error(rc)) 2236 if (is_retryable_error(rc))
2192 redirty_page_for_writepage(wbc, 2237 redirty_page_for_writepage(wbc,
@@ -2238,6 +2283,8 @@ retry:
2238 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) 2283 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
2239 mapping->writeback_index = index; 2284 mapping->writeback_index = index;
2240 2285
2286 if (cfile)
2287 cifsFileInfo_put(cfile);
2241 free_xid(xid); 2288 free_xid(xid);
2242 return rc; 2289 return rc;
2243} 2290}
@@ -2567,7 +2614,8 @@ static int
2567cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list, 2614cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
2568 struct cifs_aio_ctx *ctx) 2615 struct cifs_aio_ctx *ctx)
2569{ 2616{
2570 unsigned int wsize, credits; 2617 unsigned int wsize;
2618 struct cifs_credits credits;
2571 int rc; 2619 int rc;
2572 struct TCP_Server_Info *server = 2620 struct TCP_Server_Info *server =
2573 tlink_tcon(wdata->cfile->tlink)->ses->server; 2621 tlink_tcon(wdata->cfile->tlink)->ses->server;
@@ -2577,18 +2625,19 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
2577 * Note: we are attempting to resend the whole wdata not in segments 2625 * Note: we are attempting to resend the whole wdata not in segments
2578 */ 2626 */
2579 do { 2627 do {
2580 rc = server->ops->wait_mtu_credits( 2628 rc = server->ops->wait_mtu_credits(server, wdata->bytes, &wsize,
2581 server, wdata->bytes, &wsize, &credits); 2629 &credits);
2582 2630
2583 if (rc) 2631 if (rc)
2584 goto out; 2632 goto out;
2585 2633
2586 if (wsize < wdata->bytes) { 2634 if (wsize < wdata->bytes) {
2587 add_credits_and_wake_if(server, credits, 0); 2635 add_credits_and_wake_if(server, &credits, 0);
2588 msleep(1000); 2636 msleep(1000);
2589 } 2637 }
2590 } while (wsize < wdata->bytes); 2638 } while (wsize < wdata->bytes);
2591 2639
2640 wdata->credits = credits;
2592 rc = -EAGAIN; 2641 rc = -EAGAIN;
2593 while (rc == -EAGAIN) { 2642 while (rc == -EAGAIN) {
2594 rc = 0; 2643 rc = 0;
@@ -2604,7 +2653,7 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
2604 return 0; 2653 return 0;
2605 } 2654 }
2606 2655
2607 add_credits_and_wake_if(server, wdata->credits, 0); 2656 add_credits_and_wake_if(server, &wdata->credits, 0);
2608out: 2657out:
2609 kref_put(&wdata->refcount, cifs_uncached_writedata_release); 2658 kref_put(&wdata->refcount, cifs_uncached_writedata_release);
2610 2659
@@ -2627,6 +2676,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
2627 struct TCP_Server_Info *server; 2676 struct TCP_Server_Info *server;
2628 struct page **pagevec; 2677 struct page **pagevec;
2629 size_t start; 2678 size_t start;
2679 unsigned int xid;
2630 2680
2631 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) 2681 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
2632 pid = open_file->pid; 2682 pid = open_file->pid;
@@ -2634,12 +2684,23 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
2634 pid = current->tgid; 2684 pid = current->tgid;
2635 2685
2636 server = tlink_tcon(open_file->tlink)->ses->server; 2686 server = tlink_tcon(open_file->tlink)->ses->server;
2687 xid = get_xid();
2637 2688
2638 do { 2689 do {
2639 unsigned int wsize, credits; 2690 unsigned int wsize;
2691 struct cifs_credits credits_on_stack;
2692 struct cifs_credits *credits = &credits_on_stack;
2693
2694 if (open_file->invalidHandle) {
2695 rc = cifs_reopen_file(open_file, false);
2696 if (rc == -EAGAIN)
2697 continue;
2698 else if (rc)
2699 break;
2700 }
2640 2701
2641 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize, 2702 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
2642 &wsize, &credits); 2703 &wsize, credits);
2643 if (rc) 2704 if (rc)
2644 break; 2705 break;
2645 2706
@@ -2731,16 +2792,22 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
2731 wdata->pid = pid; 2792 wdata->pid = pid;
2732 wdata->bytes = cur_len; 2793 wdata->bytes = cur_len;
2733 wdata->pagesz = PAGE_SIZE; 2794 wdata->pagesz = PAGE_SIZE;
2734 wdata->credits = credits; 2795 wdata->credits = credits_on_stack;
2735 wdata->ctx = ctx; 2796 wdata->ctx = ctx;
2736 kref_get(&ctx->refcount); 2797 kref_get(&ctx->refcount);
2737 2798
2738 if (!wdata->cfile->invalidHandle || 2799 rc = adjust_credits(server, &wdata->credits, wdata->bytes);
2739 !(rc = cifs_reopen_file(wdata->cfile, false))) 2800
2740 rc = server->ops->async_writev(wdata, 2801 if (!rc) {
2802 if (wdata->cfile->invalidHandle)
2803 rc = -EAGAIN;
2804 else
2805 rc = server->ops->async_writev(wdata,
2741 cifs_uncached_writedata_release); 2806 cifs_uncached_writedata_release);
2807 }
2808
2742 if (rc) { 2809 if (rc) {
2743 add_credits_and_wake_if(server, wdata->credits, 0); 2810 add_credits_and_wake_if(server, &wdata->credits, 0);
2744 kref_put(&wdata->refcount, 2811 kref_put(&wdata->refcount,
2745 cifs_uncached_writedata_release); 2812 cifs_uncached_writedata_release);
2746 if (rc == -EAGAIN) { 2813 if (rc == -EAGAIN) {
@@ -2756,6 +2823,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
2756 len -= cur_len; 2823 len -= cur_len;
2757 } while (len > 0); 2824 } while (len > 0);
2758 2825
2826 free_xid(xid);
2759 return rc; 2827 return rc;
2760} 2828}
2761 2829
@@ -3028,14 +3096,16 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)
3028 * these pages but not on the region from pos to ppos+len-1. 3096 * these pages but not on the region from pos to ppos+len-1.
3029 */ 3097 */
3030 written = cifs_user_writev(iocb, from); 3098 written = cifs_user_writev(iocb, from);
3031 if (written > 0 && CIFS_CACHE_READ(cinode)) { 3099 if (CIFS_CACHE_READ(cinode)) {
3032 /* 3100 /*
3033 * Windows 7 server can delay breaking level2 oplock if a write 3101 * We have read level caching and we have just sent a write
3034 * request comes - break it on the client to prevent reading 3102 * request to the server thus making data in the cache stale.
3035 * an old data. 3103 * Zap the cache and set oplock/lease level to NONE to avoid
3104 * reading stale data from the cache. All subsequent read
3105 * operations will read new data from the server.
3036 */ 3106 */
3037 cifs_zap_mapping(inode); 3107 cifs_zap_mapping(inode);
3038 cifs_dbg(FYI, "Set no oplock for inode=%p after a write operation\n", 3108 cifs_dbg(FYI, "Set Oplock/Lease to NONE for inode=%p after write\n",
3039 inode); 3109 inode);
3040 cinode->oplock = 0; 3110 cinode->oplock = 0;
3041 } 3111 }
@@ -3260,7 +3330,8 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
3260 struct list_head *rdata_list, 3330 struct list_head *rdata_list,
3261 struct cifs_aio_ctx *ctx) 3331 struct cifs_aio_ctx *ctx)
3262{ 3332{
3263 unsigned int rsize, credits; 3333 unsigned int rsize;
3334 struct cifs_credits credits;
3264 int rc; 3335 int rc;
3265 struct TCP_Server_Info *server = 3336 struct TCP_Server_Info *server =
3266 tlink_tcon(rdata->cfile->tlink)->ses->server; 3337 tlink_tcon(rdata->cfile->tlink)->ses->server;
@@ -3277,11 +3348,12 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
3277 goto out; 3348 goto out;
3278 3349
3279 if (rsize < rdata->bytes) { 3350 if (rsize < rdata->bytes) {
3280 add_credits_and_wake_if(server, credits, 0); 3351 add_credits_and_wake_if(server, &credits, 0);
3281 msleep(1000); 3352 msleep(1000);
3282 } 3353 }
3283 } while (rsize < rdata->bytes); 3354 } while (rsize < rdata->bytes);
3284 3355
3356 rdata->credits = credits;
3285 rc = -EAGAIN; 3357 rc = -EAGAIN;
3286 while (rc == -EAGAIN) { 3358 while (rc == -EAGAIN) {
3287 rc = 0; 3359 rc = 0;
@@ -3297,7 +3369,7 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
3297 return 0; 3369 return 0;
3298 } 3370 }
3299 3371
3300 add_credits_and_wake_if(server, rdata->credits, 0); 3372 add_credits_and_wake_if(server, &rdata->credits, 0);
3301out: 3373out:
3302 kref_put(&rdata->refcount, 3374 kref_put(&rdata->refcount,
3303 cifs_uncached_readdata_release); 3375 cifs_uncached_readdata_release);
@@ -3311,7 +3383,9 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
3311 struct cifs_aio_ctx *ctx) 3383 struct cifs_aio_ctx *ctx)
3312{ 3384{
3313 struct cifs_readdata *rdata; 3385 struct cifs_readdata *rdata;
3314 unsigned int npages, rsize, credits; 3386 unsigned int npages, rsize;
3387 struct cifs_credits credits_on_stack;
3388 struct cifs_credits *credits = &credits_on_stack;
3315 size_t cur_len; 3389 size_t cur_len;
3316 int rc; 3390 int rc;
3317 pid_t pid; 3391 pid_t pid;
@@ -3331,8 +3405,16 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
3331 iov_iter_advance(&direct_iov, offset - ctx->pos); 3405 iov_iter_advance(&direct_iov, offset - ctx->pos);
3332 3406
3333 do { 3407 do {
3408 if (open_file->invalidHandle) {
3409 rc = cifs_reopen_file(open_file, true);
3410 if (rc == -EAGAIN)
3411 continue;
3412 else if (rc)
3413 break;
3414 }
3415
3334 rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize, 3416 rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
3335 &rsize, &credits); 3417 &rsize, credits);
3336 if (rc) 3418 if (rc)
3337 break; 3419 break;
3338 3420
@@ -3406,15 +3488,21 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
3406 rdata->pagesz = PAGE_SIZE; 3488 rdata->pagesz = PAGE_SIZE;
3407 rdata->read_into_pages = cifs_uncached_read_into_pages; 3489 rdata->read_into_pages = cifs_uncached_read_into_pages;
3408 rdata->copy_into_pages = cifs_uncached_copy_into_pages; 3490 rdata->copy_into_pages = cifs_uncached_copy_into_pages;
3409 rdata->credits = credits; 3491 rdata->credits = credits_on_stack;
3410 rdata->ctx = ctx; 3492 rdata->ctx = ctx;
3411 kref_get(&ctx->refcount); 3493 kref_get(&ctx->refcount);
3412 3494
3413 if (!rdata->cfile->invalidHandle || 3495 rc = adjust_credits(server, &rdata->credits, rdata->bytes);
3414 !(rc = cifs_reopen_file(rdata->cfile, true))) 3496
3415 rc = server->ops->async_readv(rdata); 3497 if (!rc) {
3498 if (rdata->cfile->invalidHandle)
3499 rc = -EAGAIN;
3500 else
3501 rc = server->ops->async_readv(rdata);
3502 }
3503
3416 if (rc) { 3504 if (rc) {
3417 add_credits_and_wake_if(server, rdata->credits, 0); 3505 add_credits_and_wake_if(server, &rdata->credits, 0);
3418 kref_put(&rdata->refcount, 3506 kref_put(&rdata->refcount,
3419 cifs_uncached_readdata_release); 3507 cifs_uncached_readdata_release);
3420 if (rc == -EAGAIN) { 3508 if (rc == -EAGAIN) {
@@ -3533,8 +3621,6 @@ again:
3533 ctx->total_len = ctx->len - iov_iter_count(to); 3621 ctx->total_len = ctx->len - iov_iter_count(to);
3534 } 3622 }
3535 3623
3536 cifs_stats_bytes_read(tcon, ctx->total_len);
3537
3538 /* mask nodata case */ 3624 /* mask nodata case */
3539 if (rc == -ENODATA) 3625 if (rc == -ENODATA)
3540 rc = 0; 3626 rc = 0;
@@ -4095,10 +4181,19 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
4095 loff_t offset; 4181 loff_t offset;
4096 struct page *page, *tpage; 4182 struct page *page, *tpage;
4097 struct cifs_readdata *rdata; 4183 struct cifs_readdata *rdata;
4098 unsigned credits; 4184 struct cifs_credits credits_on_stack;
4185 struct cifs_credits *credits = &credits_on_stack;
4186
4187 if (open_file->invalidHandle) {
4188 rc = cifs_reopen_file(open_file, true);
4189 if (rc == -EAGAIN)
4190 continue;
4191 else if (rc)
4192 break;
4193 }
4099 4194
4100 rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize, 4195 rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
4101 &rsize, &credits); 4196 &rsize, credits);
4102 if (rc) 4197 if (rc)
4103 break; 4198 break;
4104 4199
@@ -4144,18 +4239,24 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
4144 rdata->tailsz = PAGE_SIZE; 4239 rdata->tailsz = PAGE_SIZE;
4145 rdata->read_into_pages = cifs_readpages_read_into_pages; 4240 rdata->read_into_pages = cifs_readpages_read_into_pages;
4146 rdata->copy_into_pages = cifs_readpages_copy_into_pages; 4241 rdata->copy_into_pages = cifs_readpages_copy_into_pages;
4147 rdata->credits = credits; 4242 rdata->credits = credits_on_stack;
4148 4243
4149 list_for_each_entry_safe(page, tpage, &tmplist, lru) { 4244 list_for_each_entry_safe(page, tpage, &tmplist, lru) {
4150 list_del(&page->lru); 4245 list_del(&page->lru);
4151 rdata->pages[rdata->nr_pages++] = page; 4246 rdata->pages[rdata->nr_pages++] = page;
4152 } 4247 }
4153 4248
4154 if (!rdata->cfile->invalidHandle || 4249 rc = adjust_credits(server, &rdata->credits, rdata->bytes);
4155 !(rc = cifs_reopen_file(rdata->cfile, true))) 4250
4156 rc = server->ops->async_readv(rdata); 4251 if (!rc) {
4252 if (rdata->cfile->invalidHandle)
4253 rc = -EAGAIN;
4254 else
4255 rc = server->ops->async_readv(rdata);
4256 }
4257
4157 if (rc) { 4258 if (rc) {
4158 add_credits_and_wake_if(server, rdata->credits, 0); 4259 add_credits_and_wake_if(server, &rdata->credits, 0);
4159 for (i = 0; i < rdata->nr_pages; i++) { 4260 for (i = 0; i < rdata->nr_pages; i++) {
4160 page = rdata->pages[i]; 4261 page = rdata->pages[i];
4161 lru_cache_add_file(page); 4262 lru_cache_add_file(page);