summaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e3e3a7550205..2c7689f3998d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -733,7 +733,8 @@ reopen_success:
733 733
734 if (can_flush) { 734 if (can_flush) {
735 rc = filemap_write_and_wait(inode->i_mapping); 735 rc = filemap_write_and_wait(inode->i_mapping);
736 mapping_set_error(inode->i_mapping, rc); 736 if (!is_interrupt_error(rc))
737 mapping_set_error(inode->i_mapping, rc);
737 738
738 if (tcon->unix_ext) 739 if (tcon->unix_ext)
739 rc = cifs_get_inode_info_unix(&inode, full_path, 740 rc = cifs_get_inode_info_unix(&inode, full_path,
@@ -1132,14 +1133,18 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
1132 1133
1133 /* 1134 /*
1134 * Accessing maxBuf is racy with cifs_reconnect - need to store value 1135 * Accessing maxBuf is racy with cifs_reconnect - need to store value
1135 * and check it for zero before using. 1136 * and check it before using.
1136 */ 1137 */
1137 max_buf = tcon->ses->server->maxBuf; 1138 max_buf = tcon->ses->server->maxBuf;
1138 if (!max_buf) { 1139 if (max_buf < (sizeof(struct smb_hdr) + sizeof(LOCKING_ANDX_RANGE))) {
1139 free_xid(xid); 1140 free_xid(xid);
1140 return -EINVAL; 1141 return -EINVAL;
1141 } 1142 }
1142 1143
1144 BUILD_BUG_ON(sizeof(struct smb_hdr) + sizeof(LOCKING_ANDX_RANGE) >
1145 PAGE_SIZE);
1146 max_buf = min_t(unsigned int, max_buf - sizeof(struct smb_hdr),
1147 PAGE_SIZE);
1143 max_num = (max_buf - sizeof(struct smb_hdr)) / 1148 max_num = (max_buf - sizeof(struct smb_hdr)) /
1144 sizeof(LOCKING_ANDX_RANGE); 1149 sizeof(LOCKING_ANDX_RANGE);
1145 buf = kcalloc(max_num, sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); 1150 buf = kcalloc(max_num, sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
@@ -1472,12 +1477,16 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,
1472 1477
1473 /* 1478 /*
1474 * Accessing maxBuf is racy with cifs_reconnect - need to store value 1479 * Accessing maxBuf is racy with cifs_reconnect - need to store value
1475 * and check it for zero before using. 1480 * and check it before using.
1476 */ 1481 */
1477 max_buf = tcon->ses->server->maxBuf; 1482 max_buf = tcon->ses->server->maxBuf;
1478 if (!max_buf) 1483 if (max_buf < (sizeof(struct smb_hdr) + sizeof(LOCKING_ANDX_RANGE)))
1479 return -EINVAL; 1484 return -EINVAL;
1480 1485
1486 BUILD_BUG_ON(sizeof(struct smb_hdr) + sizeof(LOCKING_ANDX_RANGE) >
1487 PAGE_SIZE);
1488 max_buf = min_t(unsigned int, max_buf - sizeof(struct smb_hdr),
1489 PAGE_SIZE);
1481 max_num = (max_buf - sizeof(struct smb_hdr)) / 1490 max_num = (max_buf - sizeof(struct smb_hdr)) /
1482 sizeof(LOCKING_ANDX_RANGE); 1491 sizeof(LOCKING_ANDX_RANGE);
1483 buf = kcalloc(max_num, sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); 1492 buf = kcalloc(max_num, sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
@@ -2110,6 +2119,7 @@ static int cifs_writepages(struct address_space *mapping,
2110 pgoff_t end, index; 2119 pgoff_t end, index;
2111 struct cifs_writedata *wdata; 2120 struct cifs_writedata *wdata;
2112 int rc = 0; 2121 int rc = 0;
2122 int saved_rc = 0;
2113 unsigned int xid; 2123 unsigned int xid;
2114 2124
2115 /* 2125 /*
@@ -2138,8 +2148,10 @@ retry:
2138 2148
2139 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize, 2149 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
2140 &wsize, &credits); 2150 &wsize, &credits);
2141 if (rc) 2151 if (rc != 0) {
2152 done = true;
2142 break; 2153 break;
2154 }
2143 2155
2144 tofind = min((wsize / PAGE_SIZE) - 1, end - index) + 1; 2156 tofind = min((wsize / PAGE_SIZE) - 1, end - index) + 1;
2145 2157
@@ -2147,6 +2159,7 @@ retry:
2147 &found_pages); 2159 &found_pages);
2148 if (!wdata) { 2160 if (!wdata) {
2149 rc = -ENOMEM; 2161 rc = -ENOMEM;
2162 done = true;
2150 add_credits_and_wake_if(server, credits, 0); 2163 add_credits_and_wake_if(server, credits, 0);
2151 break; 2164 break;
2152 } 2165 }
@@ -2175,7 +2188,7 @@ retry:
2175 if (rc != 0) { 2188 if (rc != 0) {
2176 add_credits_and_wake_if(server, wdata->credits, 0); 2189 add_credits_and_wake_if(server, wdata->credits, 0);
2177 for (i = 0; i < nr_pages; ++i) { 2190 for (i = 0; i < nr_pages; ++i) {
2178 if (rc == -EAGAIN) 2191 if (is_retryable_error(rc))
2179 redirty_page_for_writepage(wbc, 2192 redirty_page_for_writepage(wbc,
2180 wdata->pages[i]); 2193 wdata->pages[i]);
2181 else 2194 else
@@ -2183,7 +2196,7 @@ retry:
2183 end_page_writeback(wdata->pages[i]); 2196 end_page_writeback(wdata->pages[i]);
2184 put_page(wdata->pages[i]); 2197 put_page(wdata->pages[i]);
2185 } 2198 }
2186 if (rc != -EAGAIN) 2199 if (!is_retryable_error(rc))
2187 mapping_set_error(mapping, rc); 2200 mapping_set_error(mapping, rc);
2188 } 2201 }
2189 kref_put(&wdata->refcount, cifs_writedata_release); 2202 kref_put(&wdata->refcount, cifs_writedata_release);
@@ -2193,6 +2206,15 @@ retry:
2193 continue; 2206 continue;
2194 } 2207 }
2195 2208
2209 /* Return immediately if we received a signal during writing */
2210 if (is_interrupt_error(rc)) {
2211 done = true;
2212 break;
2213 }
2214
2215 if (rc != 0 && saved_rc == 0)
2216 saved_rc = rc;
2217
2196 wbc->nr_to_write -= nr_pages; 2218 wbc->nr_to_write -= nr_pages;
2197 if (wbc->nr_to_write <= 0) 2219 if (wbc->nr_to_write <= 0)
2198 done = true; 2220 done = true;
@@ -2210,6 +2232,9 @@ retry:
2210 goto retry; 2232 goto retry;
2211 } 2233 }
2212 2234
2235 if (saved_rc != 0)
2236 rc = saved_rc;
2237
2213 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) 2238 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
2214 mapping->writeback_index = index; 2239 mapping->writeback_index = index;
2215 2240
@@ -2242,8 +2267,8 @@ cifs_writepage_locked(struct page *page, struct writeback_control *wbc)
2242 set_page_writeback(page); 2267 set_page_writeback(page);
2243retry_write: 2268retry_write:
2244 rc = cifs_partialpagewrite(page, 0, PAGE_SIZE); 2269 rc = cifs_partialpagewrite(page, 0, PAGE_SIZE);
2245 if (rc == -EAGAIN) { 2270 if (is_retryable_error(rc)) {
2246 if (wbc->sync_mode == WB_SYNC_ALL) 2271 if (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN)
2247 goto retry_write; 2272 goto retry_write;
2248 redirty_page_for_writepage(wbc, page); 2273 redirty_page_for_writepage(wbc, page);
2249 } else if (rc != 0) { 2274 } else if (rc != 0) {