Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag '6.8-rc1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull smb client fixes from Steve French:
"Nine cifs/smb client fixes

- Four network error fixes (three relating to replays of requests
that need to be retried, and one fixing some places where we were
returning the wrong rc up the stack on network errors)

- Two multichannel fixes including locking fix and case where subset
of channels need reconnect

- netfs integration fixup: share remote i_size with netfslib

- Two small cleanups (one for addressing a clang warning)"

* tag '6.8-rc1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
cifs: fix stray unlock in cifs_chan_skip_or_disable
cifs: set replay flag for retries of write command
cifs: commands that are retried should have replay flag set
cifs: helper function to check replayable error codes
cifs: translate network errors on send to -ECONNABORTED
cifs: cifs_pick_channel should try selecting active channels
cifs: Share server EOF pos with netfslib
smb: Work around Clang __bdos() type confusion
smb: client: delete "true", "false" defines

+469 -76
+20 -4
fs/smb/client/cached_dir.c
··· 145 145 struct cached_fid *cfid; 146 146 struct cached_fids *cfids; 147 147 const char *npath; 148 + int retries = 0, cur_sleep = 1; 148 149 149 150 if (tcon == NULL || tcon->cfids == NULL || tcon->nohandlecache || 150 151 is_smb1_server(tcon->ses->server) || (dir_cache_timeout == 0)) 151 152 return -EOPNOTSUPP; 152 153 153 154 ses = tcon->ses; 154 - server = cifs_pick_channel(ses); 155 155 cfids = tcon->cfids; 156 - 157 - if (!server->ops->new_lease_key) 158 - return -EIO; 159 156 160 157 if (cifs_sb->root == NULL) 161 158 return -ENOENT; 159 + 160 + replay_again: 161 + /* reinitialize for possible replay */ 162 + flags = 0; 163 + oplock = SMB2_OPLOCK_LEVEL_II; 164 + server = cifs_pick_channel(ses); 165 + 166 + if (!server->ops->new_lease_key) 167 + return -EIO; 162 168 163 169 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); 164 170 if (!utf16_path) ··· 274 268 */ 275 269 cfid->has_lease = true; 276 270 271 + if (retries) { 272 + smb2_set_replay(server, &rqst[0]); 273 + smb2_set_replay(server, &rqst[1]); 274 + } 275 + 277 276 rc = compound_send_recv(xid, ses, server, 278 277 flags, 2, rqst, 279 278 resp_buftype, rsp_iov); ··· 378 367 atomic_inc(&tcon->num_remote_opens); 379 368 } 380 369 kfree(utf16_path); 370 + 371 + if (is_replayable_error(rc) && 372 + smb2_should_replay(tcon, &retries, &cur_sleep)) 373 + goto replay_again; 374 + 381 375 return rc; 382 376 } 383 377
+1 -1
fs/smb/client/cifsencrypt.c
··· 572 572 len = cifs_strtoUTF16(user, ses->user_name, len, nls_cp); 573 573 UniStrupr(user); 574 574 } else { 575 - memset(user, '\0', 2); 575 + *(u16 *)user = 0; 576 576 } 577 577 578 578 rc = crypto_shash_update(ses->server->secmech.hmacmd5,
+14 -3
fs/smb/client/cifsfs.c
··· 396 396 spin_lock_init(&cifs_inode->writers_lock); 397 397 cifs_inode->writers = 0; 398 398 cifs_inode->netfs.inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 399 - cifs_inode->server_eof = 0; 399 + cifs_inode->netfs.remote_i_size = 0; 400 400 cifs_inode->uniqueid = 0; 401 401 cifs_inode->createtime = 0; 402 402 cifs_inode->epoch = 0; ··· 1380 1380 struct inode *src_inode = file_inode(src_file); 1381 1381 struct inode *target_inode = file_inode(dst_file); 1382 1382 struct cifsInodeInfo *src_cifsi = CIFS_I(src_inode); 1383 + struct cifsInodeInfo *target_cifsi = CIFS_I(target_inode); 1383 1384 struct cifsFileInfo *smb_file_src; 1384 1385 struct cifsFileInfo *smb_file_target; 1385 1386 struct cifs_tcon *src_tcon; ··· 1429 1428 * Advance the EOF marker after the flush above to the end of the range 1430 1429 * if it's short of that. 1431 1430 */ 1432 - if (src_cifsi->server_eof < off + len) { 1431 + if (src_cifsi->netfs.remote_i_size < off + len) { 1433 1432 rc = cifs_precopy_set_eof(src_inode, src_cifsi, src_tcon, xid, off + len); 1434 1433 if (rc < 0) 1435 1434 goto unlock; ··· 1453 1452 /* Discard all the folios that overlap the destination region. */ 1454 1453 truncate_inode_pages_range(&target_inode->i_data, fstart, fend); 1455 1454 1455 + fscache_invalidate(cifs_inode_cookie(target_inode), NULL, 1456 + i_size_read(target_inode), 0); 1457 + 1456 1458 rc = file_modified(dst_file); 1457 1459 if (!rc) { 1458 1460 rc = target_tcon->ses->server->ops->copychunk_range(xid, 1459 1461 smb_file_src, smb_file_target, off, len, destoff); 1460 - if (rc > 0 && destoff + rc > i_size_read(target_inode)) 1462 + if (rc > 0 && destoff + rc > i_size_read(target_inode)) { 1461 1463 truncate_setsize(target_inode, destoff + rc); 1464 + netfs_resize_file(&target_cifsi->netfs, 1465 + i_size_read(target_inode), true); 1466 + fscache_resize_cookie(cifs_inode_cookie(target_inode), 1467 + i_size_read(target_inode)); 1468 + } 1469 + if (rc > 0 && destoff + rc > target_cifsi->netfs.zero_point) 1470 + target_cifsi->netfs.zero_point = destoff + rc; 1462 1471 } 1463 1472 1464 1473 file_accessed(src_file);
+13 -1
fs/smb/client/cifsglob.h
··· 50 50 #define CIFS_DEF_ACTIMEO (1 * HZ) 51 51 52 52 /* 53 + * max sleep time before retry to server 54 + */ 55 + #define CIFS_MAX_SLEEP 2000 56 + 57 + /* 53 58 * max attribute cache timeout (jiffies) - 2^30 54 59 */ 55 60 #define CIFS_MAX_ACTIMEO (1 << 30) ··· 1506 1501 struct smbd_mr *mr; 1507 1502 #endif 1508 1503 struct cifs_credits credits; 1504 + bool replay; 1509 1505 }; 1510 1506 1511 1507 /* ··· 1567 1561 spinlock_t writers_lock; 1568 1562 unsigned int writers; /* Number of writers on this inode */ 1569 1563 unsigned long time; /* jiffies of last update of inode */ 1570 - u64 server_eof; /* current file size on server -- protected by i_lock */ 1571 1564 u64 uniqueid; /* server inode number */ 1572 1565 u64 createtime; /* creation time on server */ 1573 1566 __u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for this inode */ ··· 1832 1827 static inline bool is_retryable_error(int error) 1833 1828 { 1834 1829 if (is_interrupt_error(error) || error == -EAGAIN) 1830 + return true; 1831 + return false; 1832 + } 1833 + 1834 + static inline bool is_replayable_error(int error) 1835 + { 1836 + if (error == -EAGAIN || error == -ECONNABORTED) 1835 1837 return true; 1836 1838 return false; 1837 1839 }
+5 -4
fs/smb/client/file.c
··· 2120 2120 { 2121 2121 loff_t end_of_write = offset + bytes_written; 2122 2122 2123 - if (end_of_write > cifsi->server_eof) 2124 - cifsi->server_eof = end_of_write; 2123 + if (end_of_write > cifsi->netfs.remote_i_size) 2124 + netfs_resize_file(&cifsi->netfs, end_of_write, true); 2125 2125 } 2126 2126 2127 2127 static ssize_t ··· 3247 3247 3248 3248 spin_lock(&inode->i_lock); 3249 3249 cifs_update_eof(cifsi, wdata->offset, wdata->bytes); 3250 - if (cifsi->server_eof > inode->i_size) 3251 - i_size_write(inode, cifsi->server_eof); 3250 + if (cifsi->netfs.remote_i_size > inode->i_size) 3251 + i_size_write(inode, cifsi->netfs.remote_i_size); 3252 3252 spin_unlock(&inode->i_lock); 3253 3253 3254 3254 complete(&wdata->done); ··· 3300 3300 if (wdata->cfile->invalidHandle) 3301 3301 rc = -EAGAIN; 3302 3302 else { 3303 + wdata->replay = true; 3303 3304 #ifdef CONFIG_CIFS_SMB_DIRECT 3304 3305 if (wdata->mr) { 3305 3306 wdata->mr->need_invalidate = true;
+5 -3
fs/smb/client/inode.c
··· 104 104 fattr->cf_mtime = timestamp_truncate(fattr->cf_mtime, inode); 105 105 mtime = inode_get_mtime(inode); 106 106 if (timespec64_equal(&mtime, &fattr->cf_mtime) && 107 - cifs_i->server_eof == fattr->cf_eof) { 107 + cifs_i->netfs.remote_i_size == fattr->cf_eof) { 108 108 cifs_dbg(FYI, "%s: inode %llu is unchanged\n", 109 109 __func__, cifs_i->uniqueid); 110 110 return; ··· 194 194 else 195 195 clear_bit(CIFS_INO_DELETE_PENDING, &cifs_i->flags); 196 196 197 - cifs_i->server_eof = fattr->cf_eof; 197 + cifs_i->netfs.remote_i_size = fattr->cf_eof; 198 198 /* 199 199 * Can't safely change the file size here if the client is writing to 200 200 * it due to potential races. ··· 2858 2858 2859 2859 set_size_out: 2860 2860 if (rc == 0) { 2861 - cifsInode->server_eof = attrs->ia_size; 2861 + netfs_resize_file(&cifsInode->netfs, attrs->ia_size, true); 2862 2862 cifs_setsize(inode, attrs->ia_size); 2863 2863 /* 2864 2864 * i_blocks is not related to (i_size / i_blksize), but instead ··· 3011 3011 if ((attrs->ia_valid & ATTR_SIZE) && 3012 3012 attrs->ia_size != i_size_read(inode)) { 3013 3013 truncate_setsize(inode, attrs->ia_size); 3014 + netfs_resize_file(&cifsInode->netfs, attrs->ia_size, true); 3014 3015 fscache_resize_cookie(cifs_inode_cookie(inode), attrs->ia_size); 3015 3016 } 3016 3017 ··· 3211 3210 if ((attrs->ia_valid & ATTR_SIZE) && 3212 3211 attrs->ia_size != i_size_read(inode)) { 3213 3212 truncate_setsize(inode, attrs->ia_size); 3213 + netfs_resize_file(&cifsInode->netfs, attrs->ia_size, true); 3214 3214 fscache_resize_cookie(cifs_inode_cookie(inode), attrs->ia_size); 3215 3215 } 3216 3216
+1 -1
fs/smb/client/readdir.c
··· 141 141 if (likely(reparse_inode_match(inode, fattr))) { 142 142 fattr->cf_mode = inode->i_mode; 143 143 fattr->cf_rdev = inode->i_rdev; 144 - fattr->cf_eof = CIFS_I(inode)->server_eof; 144 + fattr->cf_eof = CIFS_I(inode)->netfs.remote_i_size; 145 145 fattr->cf_symlink_target = NULL; 146 146 } else { 147 147 CIFS_I(inode)->time = 0;
+27 -6
fs/smb/client/smb2inode.c
··· 120 120 unsigned int size[2]; 121 121 void *data[2]; 122 122 int len; 123 + int retries = 0, cur_sleep = 1; 124 + 125 + replay_again: 126 + /* reinitialize for possible replay */ 127 + flags = 0; 128 + oplock = SMB2_OPLOCK_LEVEL_NONE; 129 + num_rqst = 0; 130 + server = cifs_pick_channel(ses); 123 131 124 132 vars = kzalloc(sizeof(*vars), GFP_ATOMIC); 125 133 if (vars == NULL) 126 134 return -ENOMEM; 127 135 rqst = &vars->rqst[0]; 128 136 rsp_iov = &vars->rsp_iov[0]; 129 - 130 - server = cifs_pick_channel(ses); 131 137 132 138 if (smb3_encryption_required(tcon)) 133 139 flags |= CIFS_TRANSFORM_REQ; ··· 469 463 num_rqst++; 470 464 471 465 if (cfile) { 466 + if (retries) 467 + for (i = 1; i < num_rqst - 2; i++) 468 + smb2_set_replay(server, &rqst[i]); 469 + 472 470 rc = compound_send_recv(xid, ses, server, 473 471 flags, num_rqst - 2, 474 472 &rqst[1], &resp_buftype[1], 475 473 &rsp_iov[1]); 476 - } else 474 + } else { 475 + if (retries) 476 + for (i = 0; i < num_rqst; i++) 477 + smb2_set_replay(server, &rqst[i]); 478 + 477 479 rc = compound_send_recv(xid, ses, server, 478 480 flags, num_rqst, 479 481 rqst, resp_buftype, 480 482 rsp_iov); 483 + } 481 484 482 485 finished: 483 486 num_rqst = 0; ··· 635 620 } 636 621 SMB2_close_free(&rqst[num_rqst]); 637 622 638 - if (cfile) 639 - cifsFileInfo_put(cfile); 640 - 641 623 num_cmds += 2; 642 624 if (out_iov && out_buftype) { 643 625 memcpy(out_iov, rsp_iov, num_cmds * sizeof(*out_iov)); ··· 644 632 for (i = 0; i < num_cmds; i++) 645 633 free_rsp_buf(resp_buftype[i], rsp_iov[i].iov_base); 646 634 } 635 + num_cmds -= 2; /* correct num_cmds as there could be a retry */ 647 636 kfree(vars); 637 + 638 + if (is_replayable_error(rc) && 639 + smb2_should_replay(tcon, &retries, &cur_sleep)) 640 + goto replay_again; 641 + 642 + if (cfile) 643 + cifsFileInfo_put(cfile); 644 + 648 645 return rc; 649 646 } 650 647
+127 -14
fs/smb/client/smb2ops.c
··· 1108 1108 { 1109 1109 struct smb2_compound_vars *vars; 1110 1110 struct cifs_ses *ses = tcon->ses; 1111 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 1111 + struct TCP_Server_Info *server; 1112 1112 struct smb_rqst *rqst; 1113 1113 struct kvec *rsp_iov; 1114 1114 __le16 *utf16_path = NULL; ··· 1124 1124 struct smb2_file_full_ea_info *ea = NULL; 1125 1125 struct smb2_query_info_rsp *rsp; 1126 1126 int rc, used_len = 0; 1127 + int retries = 0, cur_sleep = 1; 1128 + 1129 + replay_again: 1130 + /* reinitialize for possible replay */ 1131 + flags = CIFS_CP_CREATE_CLOSE_OP; 1132 + oplock = SMB2_OPLOCK_LEVEL_NONE; 1133 + server = cifs_pick_channel(ses); 1127 1134 1128 1135 if (smb3_encryption_required(tcon)) 1129 1136 flags |= CIFS_TRANSFORM_REQ; ··· 1251 1244 goto sea_exit; 1252 1245 smb2_set_related(&rqst[2]); 1253 1246 1247 + if (retries) { 1248 + smb2_set_replay(server, &rqst[0]); 1249 + smb2_set_replay(server, &rqst[1]); 1250 + smb2_set_replay(server, &rqst[2]); 1251 + } 1252 + 1254 1253 rc = compound_send_recv(xid, ses, server, 1255 1254 flags, 3, rqst, 1256 1255 resp_buftype, rsp_iov); ··· 1273 1260 kfree(vars); 1274 1261 out_free_path: 1275 1262 kfree(utf16_path); 1263 + 1264 + if (is_replayable_error(rc) && 1265 + smb2_should_replay(tcon, &retries, &cur_sleep)) 1266 + goto replay_again; 1267 + 1276 1268 return rc; 1277 1269 } 1278 1270 #endif ··· 1502 1484 struct smb_rqst *rqst; 1503 1485 struct kvec *rsp_iov; 1504 1486 struct cifs_ses *ses = tcon->ses; 1505 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 1487 + struct TCP_Server_Info *server; 1506 1488 char __user *arg = (char __user *)p; 1507 1489 struct smb_query_info qi; 1508 1490 struct smb_query_info __user *pqi; ··· 1519 1501 void *data[2]; 1520 1502 int create_options = is_dir ? CREATE_NOT_FILE : CREATE_NOT_DIR; 1521 1503 void (*free_req1_func)(struct smb_rqst *r); 1504 + int retries = 0, cur_sleep = 1; 1505 + 1506 + replay_again: 1507 + /* reinitialize for possible replay */ 1508 + flags = CIFS_CP_CREATE_CLOSE_OP; 1509 + oplock = SMB2_OPLOCK_LEVEL_NONE; 1510 + server = cifs_pick_channel(ses); 1522 1511 1523 1512 vars = kzalloc(sizeof(*vars), GFP_ATOMIC); 1524 1513 if (vars == NULL) ··· 1666 1641 goto free_req_1; 1667 1642 smb2_set_related(&rqst[2]); 1668 1643 1644 + if (retries) { 1645 + smb2_set_replay(server, &rqst[0]); 1646 + smb2_set_replay(server, &rqst[1]); 1647 + smb2_set_replay(server, &rqst[2]); 1648 + } 1649 + 1669 1650 rc = compound_send_recv(xid, ses, server, 1670 1651 flags, 3, rqst, 1671 1652 resp_buftype, rsp_iov); ··· 1732 1701 kfree(buffer); 1733 1702 free_vars: 1734 1703 kfree(vars); 1704 + 1705 + if (is_replayable_error(rc) && 1706 + smb2_should_replay(tcon, &retries, &cur_sleep)) 1707 + goto replay_again; 1708 + 1735 1709 return rc; 1736 1710 } 1737 1711 ··· 2263 2227 struct cifs_open_parms oparms; 2264 2228 struct smb2_query_directory_rsp *qd_rsp = NULL; 2265 2229 struct smb2_create_rsp *op_rsp = NULL; 2266 - struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); 2267 - int retry_count = 0; 2230 + struct TCP_Server_Info *server; 2231 + int retries = 0, cur_sleep = 1; 2232 + 2233 + replay_again: 2234 + /* reinitialize for possible replay */ 2235 + flags = 0; 2236 + oplock = SMB2_OPLOCK_LEVEL_NONE; 2237 + server = cifs_pick_channel(tcon->ses); 2268 2238 2269 2239 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); 2270 2240 if (!utf16_path) ··· 2320 2278 2321 2279 smb2_set_related(&rqst[1]); 2322 2280 2323 - again: 2281 + if (retries) { 2282 + smb2_set_replay(server, &rqst[0]); 2283 + smb2_set_replay(server, &rqst[1]); 2284 + } 2285 + 2324 2286 rc = compound_send_recv(xid, tcon->ses, server, 2325 2287 flags, 2, rqst, 2326 2288 resp_buftype, rsp_iov); 2327 - 2328 - if (rc == -EAGAIN && retry_count++ < 10) 2329 - goto again; 2330 2289 2331 2290 /* If the open failed there is nothing to do */ 2332 2291 op_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base; ··· 2376 2333 SMB2_query_directory_free(&rqst[1]); 2377 2334 free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); 2378 2335 free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); 2336 + 2337 + if (is_replayable_error(rc) && 2338 + smb2_should_replay(tcon, &retries, &cur_sleep)) 2339 + goto replay_again; 2340 + 2379 2341 return rc; 2380 2342 } 2381 2343 ··· 2506 2458 } 2507 2459 2508 2460 void 2461 + smb2_set_replay(struct TCP_Server_Info *server, struct smb_rqst *rqst) 2462 + { 2463 + struct smb2_hdr *shdr; 2464 + 2465 + if (server->dialect < SMB30_PROT_ID) 2466 + return; 2467 + 2468 + shdr = (struct smb2_hdr *)(rqst->rq_iov[0].iov_base); 2469 + if (shdr == NULL) { 2470 + cifs_dbg(FYI, "shdr NULL in smb2_set_related\n"); 2471 + return; 2472 + } 2473 + shdr->Flags |= SMB2_FLAGS_REPLAY_OPERATION; 2474 + } 2475 + 2476 + void 2509 2477 smb2_set_related(struct smb_rqst *rqst) 2510 2478 { 2511 2479 struct smb2_hdr *shdr; ··· 2594 2530 } 2595 2531 2596 2532 /* 2533 + * helper function for exponential backoff and check if replayable 2534 + */ 2535 + bool smb2_should_replay(struct cifs_tcon *tcon, 2536 + int *pretries, 2537 + int *pcur_sleep) 2538 + { 2539 + if (!pretries || !pcur_sleep) 2540 + return false; 2541 + 2542 + if (tcon->retry || (*pretries)++ < tcon->ses->server->retrans) { 2543 + msleep(*pcur_sleep); 2544 + (*pcur_sleep) = ((*pcur_sleep) << 1); 2545 + if ((*pcur_sleep) > CIFS_MAX_SLEEP) 2546 + (*pcur_sleep) = CIFS_MAX_SLEEP; 2547 + return true; 2548 + } 2549 + 2550 + return false; 2551 + } 2552 + 2553 + /* 2597 2554 * Passes the query info response back to the caller on success. 2598 2555 * Caller need to free this with free_rsp_buf(). 2599 2556 */ ··· 2627 2542 { 2628 2543 struct smb2_compound_vars *vars; 2629 2544 struct cifs_ses *ses = tcon->ses; 2630 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 2545 + struct TCP_Server_Info *server; 2631 2546 int flags = CIFS_CP_CREATE_CLOSE_OP; 2632 2547 struct smb_rqst *rqst; 2633 2548 int resp_buftype[3]; ··· 2638 2553 int rc; 2639 2554 __le16 *utf16_path; 2640 2555 struct cached_fid *cfid = NULL; 2556 + int retries = 0, cur_sleep = 1; 2557 + 2558 + replay_again: 2559 + /* reinitialize for possible replay */ 2560 + flags = CIFS_CP_CREATE_CLOSE_OP; 2561 + oplock = SMB2_OPLOCK_LEVEL_NONE; 2562 + server = cifs_pick_channel(ses); 2641 2563 2642 2564 if (!path) 2643 2565 path = ""; ··· 2725 2633 goto qic_exit; 2726 2634 smb2_set_related(&rqst[2]); 2727 2635 2636 + if (retries) { 2637 + if (!cfid) { 2638 + smb2_set_replay(server, &rqst[0]); 2639 + smb2_set_replay(server, &rqst[2]); 2640 + } 2641 + smb2_set_replay(server, &rqst[1]); 2642 + } 2643 + 2728 2644 if (cfid) { 2729 2645 rc = compound_send_recv(xid, ses, server, 2730 2646 flags, 1, &rqst[1], ··· 2765 2665 kfree(vars); 2766 2666 out_free_path: 2767 2667 kfree(utf16_path); 2668 + 2669 + if (is_replayable_error(rc) && 2670 + smb2_should_replay(tcon, &retries, &cur_sleep)) 2671 + goto replay_again; 2672 + 2768 2673 return rc; 2769 2674 } 2770 2675 ··· 3318 3213 cfile->fid.volatile_fid, cfile->pid, new_size); 3319 3214 if (rc >= 0) { 3320 3215 truncate_setsize(inode, new_size); 3216 + netfs_resize_file(&cifsi->netfs, new_size, true); 3217 + if (offset < cifsi->netfs.zero_point) 3218 + cifsi->netfs.zero_point = offset; 3321 3219 fscache_resize_cookie(cifs_inode_cookie(inode), new_size); 3322 3220 } 3323 3221 } ··· 3544 3436 rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid, 3545 3437 cfile->fid.volatile_fid, cfile->pid, new_eof); 3546 3438 if (rc == 0) { 3547 - cifsi->server_eof = new_eof; 3439 + netfs_resize_file(&cifsi->netfs, new_eof, true); 3548 3440 cifs_setsize(inode, new_eof); 3549 3441 cifs_truncate_page(inode->i_mapping, inode->i_size); 3550 3442 truncate_setsize(inode, new_eof); ··· 3636 3528 int rc; 3637 3529 unsigned int xid; 3638 3530 struct inode *inode = file_inode(file); 3639 - struct cifsFileInfo *cfile = file->private_data; 3640 3531 struct cifsInodeInfo *cifsi = CIFS_I(inode); 3532 + struct cifsFileInfo *cfile = file->private_data; 3533 + struct netfs_inode *ictx = &cifsi->netfs; 3641 3534 loff_t old_eof, new_eof; 3642 3535 3643 3536 xid = get_xid(); ··· 3658 3549 goto out_2; 3659 3550 3660 3551 truncate_pagecache_range(inode, off, old_eof); 3552 + ictx->zero_point = old_eof; 3661 3553 3662 3554 rc = smb2_copychunk_range(xid, cfile, cfile, off + len, 3663 3555 old_eof - off - len, off); ··· 3673 3563 3674 3564 rc = 0; 3675 3565 3676 - cifsi->server_eof = i_size_read(inode) - len; 3677 - truncate_setsize(inode, cifsi->server_eof); 3678 - fscache_resize_cookie(cifs_inode_cookie(inode), cifsi->server_eof); 3566 + truncate_setsize(inode, new_eof); 3567 + netfs_resize_file(&cifsi->netfs, new_eof, true); 3568 + ictx->zero_point = new_eof; 3569 + fscache_resize_cookie(cifs_inode_cookie(inode), new_eof); 3679 3570 out_2: 3680 3571 filemap_invalidate_unlock(inode->i_mapping); 3681 3572 out: ··· 3692 3581 unsigned int xid; 3693 3582 struct cifsFileInfo *cfile = file->private_data; 3694 3583 struct inode *inode = file_inode(file); 3584 + struct cifsInodeInfo *cifsi = CIFS_I(inode); 3695 3585 __u64 count, old_eof, new_eof; 3696 3586 3697 3587 xid = get_xid(); ··· 3720 3608 goto out_2; 3721 3609 3722 3610 truncate_setsize(inode, new_eof); 3611 + netfs_resize_file(&cifsi->netfs, i_size_read(inode), true); 3723 3612 fscache_resize_cookie(cifs_inode_cookie(inode), i_size_read(inode)); 3724 3613 3725 3614 rc = smb2_copychunk_range(xid, cfile, cfile, off, count, off + len);
+239 -30
fs/smb/client/smb2pdu.c
··· 195 195 pserver = server->primary_server; 196 196 cifs_signal_cifsd_for_reconnect(pserver, false); 197 197 skip_terminate: 198 - mutex_unlock(&ses->session_mutex); 199 198 return -EHOSTDOWN; 200 199 } 201 200 ··· 2764 2765 int flags = 0; 2765 2766 unsigned int total_len; 2766 2767 __le16 *utf16_path = NULL; 2767 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 2768 + struct TCP_Server_Info *server; 2769 + int retries = 0, cur_sleep = 1; 2770 + 2771 + replay_again: 2772 + /* reinitialize for possible replay */ 2773 + flags = 0; 2774 + n_iov = 2; 2775 + server = cifs_pick_channel(ses); 2768 2776 2769 2777 cifs_dbg(FYI, "mkdir\n"); 2770 2778 ··· 2875 2869 /* no need to inc num_remote_opens because we close it just below */ 2876 2870 trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, full_path, CREATE_NOT_FILE, 2877 2871 FILE_WRITE_ATTRIBUTES); 2872 + 2873 + if (retries) 2874 + smb2_set_replay(server, &rqst); 2875 + 2878 2876 /* resource #4: response buffer */ 2879 2877 rc = cifs_send_recv(xid, ses, server, 2880 2878 &rqst, &resp_buftype, flags, &rsp_iov); ··· 2916 2906 cifs_small_buf_release(req); 2917 2907 err_free_path: 2918 2908 kfree(utf16_path); 2909 + 2910 + if (is_replayable_error(rc) && 2911 + smb2_should_replay(tcon, &retries, &cur_sleep)) 2912 + goto replay_again; 2913 + 2919 2914 return rc; 2920 2915 } 2921 2916 ··· 3116 3101 struct smb2_create_rsp *rsp = NULL; 3117 3102 struct cifs_tcon *tcon = oparms->tcon; 3118 3103 struct cifs_ses *ses = tcon->ses; 3119 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 3104 + struct TCP_Server_Info *server; 3120 3105 struct kvec iov[SMB2_CREATE_IOV_SIZE]; 3121 3106 struct kvec rsp_iov = {NULL, 0}; 3122 3107 int resp_buftype = CIFS_NO_BUFFER; 3123 3108 int rc = 0; 3124 3109 int flags = 0; 3110 + int retries = 0, cur_sleep = 1; 3111 + 3112 + replay_again: 3113 + /* reinitialize for possible replay */ 3114 + flags = 0; 3115 + server = cifs_pick_channel(ses); 3125 3116 3126 3117 cifs_dbg(FYI, "create/open\n"); 3127 3118 if (!ses || !server) ··· 3148 3127 3149 3128 trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid, oparms->path, 3150 3129 oparms->create_options, oparms->desired_access); 3130 + 3131 + if (retries) 3132 + smb2_set_replay(server, &rqst); 3151 3133 3152 3134 rc = cifs_send_recv(xid, ses, server, 3153 3135 &rqst, &resp_buftype, flags, ··· 3205 3181 creat_exit: 3206 3182 SMB2_open_free(&rqst); 3207 3183 free_rsp_buf(resp_buftype, rsp); 3184 + 3185 + if (is_replayable_error(rc) && 3186 + smb2_should_replay(tcon, &retries, &cur_sleep)) 3187 + goto replay_again; 3188 + 3208 3189 return rc; 3209 3190 } 3210 3191 ··· 3334 3305 int resp_buftype = CIFS_NO_BUFFER; 3335 3306 int rc = 0; 3336 3307 int flags = 0; 3308 + int retries = 0, cur_sleep = 1; 3309 + 3310 + if (!tcon) 3311 + return -EIO; 3312 + 3313 + ses = tcon->ses; 3314 + if (!ses) 3315 + return -EIO; 3316 + 3317 + replay_again: 3318 + /* reinitialize for possible replay */ 3319 + flags = 0; 3320 + server = cifs_pick_channel(ses); 3321 + 3322 + if (!server) 3323 + return -EIO; 3337 3324 3338 3325 cifs_dbg(FYI, "SMB2 IOCTL\n"); 3339 3326 ··· 3359 3314 /* zero out returned data len, in case of error */ 3360 3315 if (plen) 3361 3316 *plen = 0; 3362 - 3363 - if (!tcon) 3364 - return -EIO; 3365 - 3366 - ses = tcon->ses; 3367 - if (!ses) 3368 - return -EIO; 3369 - 3370 - server = cifs_pick_channel(ses); 3371 - if (!server) 3372 - return -EIO; 3373 3317 3374 3318 if (smb3_encryption_required(tcon)) 3375 3319 flags |= CIFS_TRANSFORM_REQ; ··· 3373 3339 in_data, indatalen, max_out_data_len); 3374 3340 if (rc) 3375 3341 goto ioctl_exit; 3342 + 3343 + if (retries) 3344 + smb2_set_replay(server, &rqst); 3376 3345 3377 3346 rc = cifs_send_recv(xid, ses, server, 3378 3347 &rqst, &resp_buftype, flags, ··· 3446 3409 ioctl_exit: 3447 3410 SMB2_ioctl_free(&rqst); 3448 3411 free_rsp_buf(resp_buftype, rsp); 3412 + 3413 + if (is_replayable_error(rc) && 3414 + smb2_should_replay(tcon, &retries, &cur_sleep)) 3415 + goto replay_again; 3416 + 3449 3417 return rc; 3450 3418 } 3451 3419 ··· 3522 3480 struct smb_rqst rqst; 3523 3481 struct smb2_close_rsp *rsp = NULL; 3524 3482 struct cifs_ses *ses = tcon->ses; 3525 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 3483 + struct TCP_Server_Info *server; 3526 3484 struct kvec iov[1]; 3527 3485 struct kvec rsp_iov; 3528 3486 int resp_buftype = CIFS_NO_BUFFER; 3529 3487 int rc = 0; 3530 3488 int flags = 0; 3531 3489 bool query_attrs = false; 3490 + int retries = 0, cur_sleep = 1; 3491 + 3492 + replay_again: 3493 + /* reinitialize for possible replay */ 3494 + flags = 0; 3495 + query_attrs = false; 3496 + server = cifs_pick_channel(ses); 3532 3497 3533 3498 cifs_dbg(FYI, "Close\n"); 3534 3499 ··· 3560 3511 query_attrs); 3561 3512 if (rc) 3562 3513 goto close_exit; 3514 + 3515 + if (retries) 3516 + smb2_set_replay(server, &rqst); 3563 3517 3564 3518 rc = cifs_send_recv(xid, ses, server, 3565 3519 &rqst, &resp_buftype, flags, &rsp_iov); ··· 3597 3545 cifs_dbg(VFS, "handle cancelled close fid 0x%llx returned error %d\n", 3598 3546 persistent_fid, tmp_rc); 3599 3547 } 3548 + 3549 + if (is_replayable_error(rc) && 3550 + smb2_should_replay(tcon, &retries, &cur_sleep)) 3551 + goto replay_again; 3552 + 3600 3553 return rc; 3601 3554 } 3602 3555 ··· 3732 3675 struct TCP_Server_Info *server; 3733 3676 int flags = 0; 3734 3677 bool allocated = false; 3678 + int retries = 0, cur_sleep = 1; 3735 3679 3736 3680 cifs_dbg(FYI, "Query Info\n"); 3737 3681 3738 3682 if (!ses) 3739 3683 return -EIO; 3684 + 3685 + replay_again: 3686 + /* reinitialize for possible replay */ 3687 + flags = 0; 3688 + allocated = false; 3740 3689 server = cifs_pick_channel(ses); 3690 + 3741 3691 if (!server) 3742 3692 return -EIO; 3743 3693 ··· 3765 3701 3766 3702 trace_smb3_query_info_enter(xid, persistent_fid, tcon->tid, 3767 3703 ses->Suid, info_class, (__u32)info_type); 3704 + 3705 + if (retries) 3706 + smb2_set_replay(server, &rqst); 3768 3707 3769 3708 rc = cifs_send_recv(xid, ses, server, 3770 3709 &rqst, &resp_buftype, flags, &rsp_iov); ··· 3811 3744 qinf_exit: 3812 3745 SMB2_query_info_free(&rqst); 3813 3746 free_rsp_buf(resp_buftype, rsp); 3747 + 3748 + if (is_replayable_error(rc) && 3749 + smb2_should_replay(tcon, &retries, &cur_sleep)) 3750 + goto replay_again; 3751 + 3814 3752 return rc; 3815 3753 } 3816 3754 ··· 3916 3844 u32 *plen /* returned data len */) 3917 3845 { 3918 3846 struct cifs_ses *ses = tcon->ses; 3919 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 3847 + struct TCP_Server_Info *server; 3920 3848 struct smb_rqst rqst; 3921 3849 struct smb2_change_notify_rsp *smb_rsp; 3922 3850 struct kvec iov[1]; ··· 3924 3852 int resp_buftype = CIFS_NO_BUFFER; 3925 3853 int flags = 0; 3926 3854 int rc = 0; 3855 + int retries = 0, cur_sleep = 1; 3856 + 3857 + replay_again: 3858 + /* reinitialize for possible replay */ 3859 + flags = 0; 3860 + server = cifs_pick_channel(ses); 3927 3861 3928 3862 cifs_dbg(FYI, "change notify\n"); 3929 3863 if (!ses || !server) ··· 3954 3876 3955 3877 trace_smb3_notify_enter(xid, persistent_fid, tcon->tid, ses->Suid, 3956 3878 (u8)watch_tree, completion_filter); 3879 + 3880 + if (retries) 3881 + smb2_set_replay(server, &rqst); 3882 + 3957 3883 rc = cifs_send_recv(xid, ses, server, 3958 3884 &rqst, &resp_buftype, flags, &rsp_iov); 3959 3885 ··· 3992 3910 if (rqst.rq_iov) 3993 3911 cifs_small_buf_release(rqst.rq_iov[0].iov_base); /* request */ 3994 3912 free_rsp_buf(resp_buftype, rsp_iov.iov_base); 3913 + 3914 + if (is_replayable_error(rc) && 3915 + smb2_should_replay(tcon, &retries, &cur_sleep)) 3916 + goto replay_again; 3917 + 3995 3918 return rc; 3996 3919 } 3997 3920 ··· 4239 4152 struct smb_rqst rqst; 4240 4153 struct kvec iov[1]; 4241 4154 struct kvec rsp_iov = {NULL, 0}; 4242 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 4155 + struct TCP_Server_Info *server; 4243 4156 int resp_buftype = CIFS_NO_BUFFER; 4244 4157 int flags = 0; 4245 4158 int rc = 0; 4159 + int retries = 0, cur_sleep = 1; 4160 + 4161 + replay_again: 4162 + /* reinitialize for possible replay */ 4163 + flags = 0; 4164 + server = cifs_pick_channel(ses); 4246 4165 4247 4166 cifs_dbg(FYI, "flush\n"); 4248 4167 if (!ses || !(ses->server)) ··· 4268 4175 goto flush_exit; 4269 4176 4270 4177 trace_smb3_flush_enter(xid, persistent_fid, tcon->tid, ses->Suid); 4178 + 4179 + if (retries) 4180 + smb2_set_replay(server, &rqst); 4181 + 4271 4182 rc = cifs_send_recv(xid, ses, server, 4272 4183 &rqst, &resp_buftype, flags, &rsp_iov); 4273 4184 ··· 4286 4189 flush_exit: 4287 4190 SMB2_flush_free(&rqst); 4288 4191 free_rsp_buf(resp_buftype, rsp_iov.iov_base); 4192 + 4193 + if (is_replayable_error(rc) && 4194 + smb2_should_replay(tcon, &retries, &cur_sleep)) 4195 + goto replay_again; 4196 + 4289 4197 return rc; 4290 4198 } 4291 4199 ··· 4770 4668 struct cifs_io_parms *io_parms = NULL; 4771 4669 int credit_request; 4772 4670 4773 - if (!wdata->server) 4671 + if (!wdata->server || wdata->replay) 4774 4672 server = wdata->server = cifs_pick_channel(tcon->ses); 4775 4673 4776 4674 /* ··· 4855 4753 rqst.rq_nvec = 1; 4856 4754 rqst.rq_iter = wdata->iter; 4857 4755 rqst.rq_iter_size = iov_iter_count(&rqst.rq_iter); 4756 + if (wdata->replay) 4757 + smb2_set_replay(server, &rqst); 4858 4758 #ifdef CONFIG_CIFS_SMB_DIRECT 4859 4759 if (wdata->mr) 4860 4760 iov[0].iov_len += sizeof(struct smbd_buffer_descriptor_v1); ··· 4930 4826 int flags = 0; 4931 4827 unsigned int total_len; 4932 4828 struct TCP_Server_Info *server; 4829 + int retries = 0, cur_sleep = 1; 4933 4830 4831 + replay_again: 4832 + /* reinitialize for possible replay */ 4833 + flags = 0; 4934 4834 *nbytes = 0; 4935 - 4936 - if (n_vec < 1) 4937 - return rc; 4938 - 4939 4835 if (!io_parms->server) 4940 4836 io_parms->server = cifs_pick_channel(io_parms->tcon->ses); 4941 4837 server = io_parms->server; 4942 4838 if (server == NULL) 4943 4839 return -ECONNABORTED; 4840 + 4841 + if (n_vec < 1) 4842 + return rc; 4944 4843 4945 4844 rc = smb2_plain_req_init(SMB2_WRITE, io_parms->tcon, server, 4946 4845 (void **) &req, &total_len); ··· 4978 4871 rqst.rq_iov = iov; 4979 4872 rqst.rq_nvec = n_vec + 1; 4980 4873 4874 + if (retries) 4875 + smb2_set_replay(server, &rqst); 4876 + 4981 4877 rc = cifs_send_recv(xid, io_parms->tcon->ses, server, 4982 4878 &rqst, 4983 4879 &resp_buftype, flags, &rsp_iov); ··· 5005 4895 5006 4896 cifs_small_buf_release(req); 5007 4897 free_rsp_buf(resp_buftype, rsp); 4898 + 4899 + if (is_replayable_error(rc) && 4900 + smb2_should_replay(io_parms->tcon, &retries, &cur_sleep)) 4901 + goto replay_again; 4902 + 5008 4903 return rc; 5009 4904 } 5010 4905 ··· 5321 5206 struct kvec rsp_iov; 5322 5207 int rc = 0; 5323 5208 struct cifs_ses *ses = tcon->ses; 5324 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 5209 + struct TCP_Server_Info *server; 5325 5210 int flags = 0; 5211 + int retries = 0, cur_sleep = 1; 5212 + 5213 + replay_again: 5214 + /* reinitialize for possible replay */ 5215 + flags = 0; 5216 + server = cifs_pick_channel(ses); 5326 5217 5327 5218 if (!ses || !(ses->server)) 5328 5219 return -EIO; ··· 5347 5226 srch_inf->info_level); 5348 5227 if (rc) 5349 5228 goto qdir_exit; 5229 + 5230 + if (retries) 5231 + smb2_set_replay(server, &rqst); 5350 5232 5351 5233 rc = cifs_send_recv(xid, ses, server, 5352 5234 &rqst, &resp_buftype, flags, &rsp_iov); ··· 5385 5261 qdir_exit: 5386 5262 SMB2_query_directory_free(&rqst); 5387 5263 free_rsp_buf(resp_buftype, rsp); 5264 + 5265 + if (is_replayable_error(rc) && 5266 + smb2_should_replay(tcon, &retries, &cur_sleep)) 5267 + goto replay_again; 5268 + 5388 5269 return rc; 5389 5270 } 5390 5271 ··· 5456 5327 int rc = 0; 5457 5328 int resp_buftype; 5458 5329 struct cifs_ses *ses = tcon->ses; 5459 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 5330 + struct TCP_Server_Info *server; 5460 5331 int flags = 0; 5332 + int retries = 0, cur_sleep = 1; 5333 + 5334 + replay_again: 5335 + /* reinitialize for possible replay */ 5336 + flags = 0; 5337 + server = cifs_pick_channel(ses); 5461 5338 5462 5339 if (!ses || !server) 5463 5340 return -EIO; ··· 5491 5356 return rc; 5492 5357 } 5493 5358 5359 + if (retries) 5360 + smb2_set_replay(server, &rqst); 5494 5361 5495 5362 rc = cifs_send_recv(xid, ses, server, 5496 5363 &rqst, &resp_buftype, flags, ··· 5508 5371 5509 5372 free_rsp_buf(resp_buftype, rsp); 5510 5373 kfree(iov); 5374 + 5375 + if (is_replayable_error(rc) && 5376 + smb2_should_replay(tcon, &retries, &cur_sleep)) 5377 + goto replay_again; 5378 + 5511 5379 return rc; 5512 5380 } 5513 5381 ··· 5565 5423 int rc; 5566 5424 struct smb2_oplock_break *req = NULL; 5567 5425 struct cifs_ses *ses = tcon->ses; 5568 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 5426 + struct TCP_Server_Info *server; 5569 5427 int flags = CIFS_OBREAK_OP; 5570 5428 unsigned int total_len; 5571 5429 struct kvec iov[1]; 5572 5430 struct kvec rsp_iov; 5573 5431 int resp_buf_type; 5432 + int retries = 0, cur_sleep = 1; 5433 + 5434 + replay_again: 5435 + /* reinitialize for possible replay */ 5436 + flags = CIFS_OBREAK_OP; 5437 + server = cifs_pick_channel(ses); 5574 5438 5575 5439 cifs_dbg(FYI, "SMB2_oplock_break\n"); 5576 5440 rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, server, ··· 5601 5453 rqst.rq_iov = iov; 5602 5454 rqst.rq_nvec = 1; 5603 5455 5456 + if (retries) 5457 + smb2_set_replay(server, &rqst); 5458 + 5604 5459 rc = cifs_send_recv(xid, ses, server, 5605 5460 &rqst, &resp_buf_type, flags, &rsp_iov); 5606 5461 cifs_small_buf_release(req); 5607 - 5608 5462 if (rc) { 5609 5463 cifs_stats_fail_inc(tcon, SMB2_OPLOCK_BREAK_HE); 5610 5464 cifs_dbg(FYI, "Send error in Oplock Break = %d\n", rc); 5611 5465 } 5466 + 5467 + if (is_replayable_error(rc) && 5468 + smb2_should_replay(tcon, &retries, &cur_sleep)) 5469 + goto replay_again; 5612 5470 5613 5471 return rc; 5614 5472 } ··· 5701 5547 int rc = 0; 5702 5548 int resp_buftype; 5703 5549 struct cifs_ses *ses = tcon->ses; 5704 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 5550 + struct TCP_Server_Info *server; 5705 5551 FILE_SYSTEM_POSIX_INFO *info = NULL; 5706 5552 int flags = 0; 5553 + int retries = 0, cur_sleep = 1; 5554 + 5555 + replay_again: 5556 + /* reinitialize for possible replay */ 5557 + flags = 0; 5558 + server = cifs_pick_channel(ses); 5707 5559 5708 5560 rc = build_qfs_info_req(&iov, tcon, server, 5709 5561 FS_POSIX_INFORMATION, ··· 5724 5564 memset(&rqst, 0, sizeof(struct smb_rqst)); 5725 5565 rqst.rq_iov = &iov; 5726 5566 rqst.rq_nvec = 1; 5567 + 5568 + if (retries) 5569 + smb2_set_replay(server, &rqst); 5727 5570 5728 5571 rc = cifs_send_recv(xid, ses, server, 5729 5572 &rqst, &resp_buftype, flags, &rsp_iov); ··· 5747 5584 5748 5585 posix_qfsinf_exit: 5749 5586 free_rsp_buf(resp_buftype, rsp_iov.iov_base); 5587 + 5588 + if (is_replayable_error(rc) && 5589 + smb2_should_replay(tcon, &retries, &cur_sleep)) 5590 + goto replay_again; 5591 + 5750 5592 return rc; 5751 5593 } 5752 5594 ··· 5766 5598 int rc = 0; 5767 5599 int resp_buftype; 5768 5600 struct cifs_ses *ses = tcon->ses; 5769 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 5601 + struct TCP_Server_Info *server; 5770 5602 struct smb2_fs_full_size_info *info = NULL; 5771 5603 int flags = 0; 5604 + int retries = 0, cur_sleep = 1; 5605 + 5606 + replay_again: 5607 + /* reinitialize for possible replay */ 5608 + flags = 0; 5609 + server = cifs_pick_channel(ses); 5772 5610 5773 5611 rc = build_qfs_info_req(&iov, tcon, server, 5774 5612 FS_FULL_SIZE_INFORMATION, ··· 5789 5615 memset(&rqst, 0, sizeof(struct smb_rqst)); 5790 5616 rqst.rq_iov = &iov; 5791 5617 rqst.rq_nvec = 1; 5618 + 5619 + if (retries) 5620 + smb2_set_replay(server, &rqst); 5792 5621 5793 5622 rc = cifs_send_recv(xid, ses, server, 5794 5623 &rqst, &resp_buftype, flags, &rsp_iov); ··· 5812 5635 5813 5636 qfsinf_exit: 5814 5637 free_rsp_buf(resp_buftype, rsp_iov.iov_base); 5638 + 5639 + if (is_replayable_error(rc) && 5640 + smb2_should_replay(tcon, &retries, &cur_sleep)) 5641 + goto replay_again; 5642 + 5815 5643 return rc; 5816 5644 } 5817 5645 ··· 5831 5649 int rc = 0; 5832 5650 int resp_buftype, max_len, min_len; 5833 5651 struct cifs_ses *ses = tcon->ses; 5834 - struct TCP_Server_Info *server = cifs_pick_channel(ses); 5652 + struct TCP_Server_Info *server; 5835 5653 unsigned int rsp_len, offset; 5836 5654 int flags = 0; 5655 + int retries = 0, cur_sleep = 1; 5656 + 5657 + replay_again: 5658 + /* reinitialize for possible replay */ 5659 + flags = 0; 5660 + server = cifs_pick_channel(ses); 5837 5661 5838 5662 if (level == FS_DEVICE_INFORMATION) { 5839 5663 max_len = sizeof(FILE_SYSTEM_DEVICE_INFO); ··· 5870 5682 memset(&rqst, 0, sizeof(struct smb_rqst)); 5871 5683 rqst.rq_iov = &iov; 5872 5684 rqst.rq_nvec = 1; 5685 + 5686 + if (retries) 5687 + smb2_set_replay(server, &rqst); 5873 5688 5874 5689 rc = cifs_send_recv(xid, ses, server, 5875 5690 &rqst, &resp_buftype, flags, &rsp_iov); ··· 5911 5720 5912 5721 qfsattr_exit: 5913 5722 free_rsp_buf(resp_buftype, rsp_iov.iov_base); 5723 + 5724 + if (is_replayable_error(rc) && 5725 + smb2_should_replay(tcon, &retries, &cur_sleep)) 5726 + goto replay_again; 5727 + 5914 5728 return rc; 5915 5729 } 5916 5730 ··· 5933 5737 unsigned int count; 5934 5738 int flags = CIFS_NO_RSP_BUF; 5935 5739 unsigned int total_len; 5936 - struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); 5740 + struct TCP_Server_Info *server; 5741 + int retries = 0, cur_sleep = 1; 5742 + 5743 + replay_again: 5744 + /* reinitialize for possible replay */ 5745 + flags = CIFS_NO_RSP_BUF; 5746 + server = cifs_pick_channel(tcon->ses); 5937 5747 5938 5748 cifs_dbg(FYI, "smb2_lockv num lock %d\n", num_lock); 5939 5749 ··· 5970 5768 rqst.rq_iov = iov; 5971 5769 rqst.rq_nvec = 2; 5972 5770 5771 + if (retries) 5772 + smb2_set_replay(server, &rqst); 5773 + 5973 5774 rc = cifs_send_recv(xid, tcon->ses, server, 5974 5775 &rqst, &resp_buf_type, flags, 5975 5776 &rsp_iov); ··· 5983 5778 trace_smb3_lock_err(xid, persist_fid, tcon->tid, 5984 5779 tcon->ses->Suid, rc); 5985 5780 } 5781 + 5782 + if (is_replayable_error(rc) && 5783 + smb2_should_replay(tcon, &retries, &cur_sleep)) 5784 + goto replay_again; 5986 5785 5987 5786 return rc; 5988 5787 }
+5
fs/smb/client/smb2proto.h
··· 122 122 extern void smb2_set_next_command(struct cifs_tcon *tcon, 123 123 struct smb_rqst *rqst); 124 124 extern void smb2_set_related(struct smb_rqst *rqst); 125 + extern void smb2_set_replay(struct TCP_Server_Info *server, 126 + struct smb_rqst *rqst); 127 + extern bool smb2_should_replay(struct cifs_tcon *tcon, 128 + int *pretries, 129 + int *pcur_sleep); 125 130 126 131 /* 127 132 * SMB2 Worker functions - most of protocol specific implementation details
-7
fs/smb/client/smbencrypt.c
··· 26 26 #include "cifsproto.h" 27 27 #include "../common/md4.h" 28 28 29 - #ifndef false 30 - #define false 0 31 - #endif 32 - #ifndef true 33 - #define true 1 34 - #endif 35 - 36 29 /* following came from the other byteorder.h to avoid include conflicts */ 37 30 #define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) 38 31 #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
+12 -2
fs/smb/client/transport.c
··· 400 400 server->conn_id, server->hostname); 401 401 } 402 402 smbd_done: 403 - if (rc < 0 && rc != -EINTR) 403 + /* 404 + * there's hardly any use for the layers above to know the 405 + * actual error code here. All they should do at this point is 406 + * to retry the connection and hope it goes away. 407 + */ 408 + if (rc < 0 && rc != -EINTR && rc != -EAGAIN) { 404 409 cifs_server_dbg(VFS, "Error %d sending data on socket to server\n", 405 410 rc); 406 - else if (rc > 0) 411 + rc = -ECONNABORTED; 412 + cifs_signal_cifsd_for_reconnect(server, false); 413 + } else if (rc > 0) 407 414 rc = 0; 408 415 out: 409 416 cifs_in_send_dec(server); ··· 1031 1024 for (i = 0; i < ses->chan_count; i++) { 1032 1025 server = ses->chans[i].server; 1033 1026 if (!server || server->terminate) 1027 + continue; 1028 + 1029 + if (CIFS_CHAN_NEEDS_RECONNECT(ses, i)) 1034 1030 continue; 1035 1031 1036 1032 /*