summaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilov@microsoft.com>2019-01-29 15:15:11 -0500
committerSteve French <stfrench@microsoft.com>2019-03-05 19:10:04 -0500
commitfe768d51c832ebde70a83221b0633dc7bc9640a6 (patch)
tree06304ab7a40e0372eb79a3af3014e59c4eadc4d0 /fs/cifs/file.c
parentc4b8f657d55b4ed60cb0a2187e940706de23f2b2 (diff)
CIFS: Return error code when getting file handle for writeback
Now we just return NULL cifsFileInfo pointer in cases we didn't find or couldn't reopen a file. This hides errors from cifs_reopen_file() especially retryable errors which should be handled appropriately. Create new cifs_get_writable_file() routine that returns error codes from cifs_reopen_file() and use it in the writeback codepath. Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c90
1 files changed, 61 insertions, 29 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 8d5fec497792..9b53f33137b3 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);
@@ -2144,11 +2167,16 @@ retry:
2144 pgoff_t next = 0, tofind, saved_index = index; 2167 pgoff_t next = 0, tofind, saved_index = index;
2145 struct cifs_credits credits_on_stack; 2168 struct cifs_credits credits_on_stack;
2146 struct cifs_credits *credits = &credits_on_stack; 2169 struct cifs_credits *credits = &credits_on_stack;
2170 int get_file_rc = 0;
2147 2171
2148 if (cfile) 2172 if (cfile)
2149 cifsFileInfo_put(cfile); 2173 cifsFileInfo_put(cfile);
2150 2174
2151 cfile = find_writable_file(CIFS_I(inode), false); 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;
2152 2180
2153 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize, 2181 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
2154 &wsize, credits); 2182 &wsize, credits);
@@ -2189,8 +2217,12 @@ retry:
2189 cfile = NULL; 2217 cfile = NULL;
2190 2218
2191 if (!wdata->cfile) { 2219 if (!wdata->cfile) {
2192 cifs_dbg(VFS, "No writable handle in writepages\n"); 2220 cifs_dbg(VFS, "No writable handle in writepages rc=%d\n",
2193 rc = -EBADF; 2221 get_file_rc);
2222 if (is_retryable_error(get_file_rc))
2223 rc = get_file_rc;
2224 else
2225 rc = -EBADF;
2194 } else 2226 } else
2195 rc = wdata_send_pages(wdata, nr_pages, mapping, wbc); 2227 rc = wdata_send_pages(wdata, nr_pages, mapping, wbc);
2196 2228