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.2-rc2-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
"cifs/smb3 client fixes:

- two multichannel fixes

- three reconnect fixes

- unmap fix"

* tag '6.2-rc2-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
cifs: fix interface count calculation during refresh
cifs: refcount only the selected iface during interface update
cifs: protect access of TCP_Server_Info::{dstaddr,hostname}
cifs: fix race in assemble_neg_contexts()
cifs: ignore ipc reconnect failures during dfs failover
cifs: Fix kmap_local_page() unmapping

+27 -26
+12 -13
fs/cifs/dfs.c
··· 327 327 return rc; 328 328 } 329 329 330 - static int target_share_matches_server(struct TCP_Server_Info *server, const char *tcp_host, 331 - size_t tcp_host_len, char *share, bool *target_match) 330 + static int target_share_matches_server(struct TCP_Server_Info *server, char *share, 331 + bool *target_match) 332 332 { 333 333 int rc = 0; 334 334 const char *dfs_host; ··· 338 338 extract_unc_hostname(share, &dfs_host, &dfs_host_len); 339 339 340 340 /* Check if hostnames or addresses match */ 341 - if (dfs_host_len != tcp_host_len || strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) { 342 - cifs_dbg(FYI, "%s: %.*s doesn't match %.*s\n", __func__, (int)dfs_host_len, 343 - dfs_host, (int)tcp_host_len, tcp_host); 341 + cifs_server_lock(server); 342 + if (dfs_host_len != strlen(server->hostname) || 343 + strncasecmp(dfs_host, server->hostname, dfs_host_len)) { 344 + cifs_dbg(FYI, "%s: %.*s doesn't match %s\n", __func__, 345 + (int)dfs_host_len, dfs_host, server->hostname); 344 346 rc = match_target_ip(server, dfs_host, dfs_host_len, target_match); 345 347 if (rc) 346 348 cifs_dbg(VFS, "%s: failed to match target ip: %d\n", __func__, rc); 347 349 } 350 + cifs_server_unlock(server); 348 351 return rc; 349 352 } 350 353 ··· 361 358 struct cifs_ses *root_ses = CIFS_DFS_ROOT_SES(tcon->ses); 362 359 struct cifs_tcon *ipc = root_ses->tcon_ipc; 363 360 char *share = NULL, *prefix = NULL; 364 - const char *tcp_host; 365 - size_t tcp_host_len; 366 361 struct dfs_cache_tgt_iterator *tit; 367 362 bool target_match; 368 - 369 - extract_unc_hostname(server->hostname, &tcp_host, &tcp_host_len); 370 363 371 364 tit = dfs_cache_get_tgt_iterator(tl); 372 365 if (!tit) { ··· 386 387 break; 387 388 } 388 389 389 - rc = target_share_matches_server(server, tcp_host, tcp_host_len, share, 390 - &target_match); 390 + rc = target_share_matches_server(server, share, &target_match); 391 391 if (rc) 392 392 break; 393 393 if (!target_match) { ··· 399 401 if (ipc->need_reconnect) { 400 402 scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname); 401 403 rc = ops->tree_connect(xid, ipc->ses, tree, ipc, cifs_sb->local_nls); 402 - if (rc) 403 - break; 404 + cifs_dbg(FYI, "%s: reconnect ipc: %d\n", __func__, rc); 404 405 } 405 406 406 407 scnprintf(tree, MAX_TREE_SIZE, "\\%s", share); ··· 495 498 } 496 499 497 500 if (tcon->ipc) { 501 + cifs_server_lock(server); 498 502 scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname); 503 + cifs_server_unlock(server); 499 504 rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc); 500 505 goto out; 501 506 }
+2
fs/cifs/misc.c
··· 1277 1277 if (rc < 0) 1278 1278 return rc; 1279 1279 1280 + spin_lock(&server->srv_lock); 1280 1281 *result = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, (struct sockaddr *)&ss); 1282 + spin_unlock(&server->srv_lock); 1281 1283 cifs_dbg(FYI, "%s: ip addresses match: %u\n", __func__, *result); 1282 1284 return 0; 1283 1285 }
+2 -1
fs/cifs/sess.c
··· 292 292 continue; 293 293 } 294 294 kref_get(&iface->refcount); 295 + break; 295 296 } 296 297 297 - if (!list_entry_is_head(iface, &ses->iface_list, iface_head)) { 298 + if (list_entry_is_head(iface, &ses->iface_list, iface_head)) { 298 299 rc = 1; 299 300 iface = NULL; 300 301 cifs_dbg(FYI, "unable to find a suitable iface\n");
+4 -8
fs/cifs/smb2ops.c
··· 530 530 p = buf; 531 531 532 532 spin_lock(&ses->iface_lock); 533 - ses->iface_count = 0; 534 533 /* 535 534 * Go through iface_list and do kref_put to remove 536 535 * any unused ifaces. ifaces in use will be removed ··· 539 540 iface_head) { 540 541 iface->is_active = 0; 541 542 kref_put(&iface->refcount, release_iface); 543 + ses->iface_count--; 542 544 } 543 545 spin_unlock(&ses->iface_lock); 544 546 ··· 618 618 /* just get a ref so that it doesn't get picked/freed */ 619 619 iface->is_active = 1; 620 620 kref_get(&iface->refcount); 621 + ses->iface_count++; 621 622 spin_unlock(&ses->iface_lock); 622 623 goto next_iface; 623 624 } else if (ret < 0) { ··· 4489 4488 4490 4489 /* copy pages form the old */ 4491 4490 for (j = 0; j < npages; j++) { 4492 - char *dst, *src; 4493 4491 unsigned int offset, len; 4494 4492 4495 4493 rqst_page_get_length(new, j, &len, &offset); 4496 4494 4497 - dst = kmap_local_page(new->rq_pages[j]) + offset; 4498 - src = kmap_local_page(old->rq_pages[j]) + offset; 4499 - 4500 - memcpy(dst, src, len); 4501 - kunmap(new->rq_pages[j]); 4502 - kunmap(old->rq_pages[j]); 4495 + memcpy_page(new->rq_pages[j], offset, 4496 + old->rq_pages[j], offset, len); 4503 4497 } 4504 4498 } 4505 4499
+7 -4
fs/cifs/smb2pdu.c
··· 541 541 assemble_neg_contexts(struct smb2_negotiate_req *req, 542 542 struct TCP_Server_Info *server, unsigned int *total_len) 543 543 { 544 - char *pneg_ctxt; 545 - char *hostname = NULL; 546 544 unsigned int ctxt_len, neg_context_count; 545 + struct TCP_Server_Info *pserver; 546 + char *pneg_ctxt; 547 + char *hostname; 547 548 548 549 if (*total_len > 200) { 549 550 /* In case length corrupted don't want to overrun smb buffer */ ··· 575 574 * secondary channels don't have the hostname field populated 576 575 * use the hostname field in the primary channel instead 577 576 */ 578 - hostname = CIFS_SERVER_IS_CHAN(server) ? 579 - server->primary_server->hostname : server->hostname; 577 + pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server; 578 + cifs_server_lock(pserver); 579 + hostname = pserver->hostname; 580 580 if (hostname && (hostname[0] != 0)) { 581 581 ctxt_len = build_netname_ctxt((struct smb2_netname_neg_context *)pneg_ctxt, 582 582 hostname); ··· 586 584 neg_context_count = 3; 587 585 } else 588 586 neg_context_count = 2; 587 + cifs_server_unlock(pserver); 589 588 590 589 build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); 591 590 *total_len += sizeof(struct smb2_posix_neg_context);