3 SMB3 multichannel/fscache fixes and a DFS fix
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmGr0HsACgkQiiy9cAdy T1FXmgv+LxMKh3FtGdLyzeJ9OJeUP87WtHCn8Tek5b0BUYxBrC12lzdLuYl8+zQr O09RcJ8THZwWYKqTDlkaQg4NnNeMEVeouottGIEQPuBztLVWNmvXD6g5c1YPhYMI 0AfeUbkCQ9Gb+zoAJtXTLMCkqYj/x+jVrgO56V12gjIfZCB1XRPhnhJOao2BRo88 go35pSn8l3lv8dLeQxUCBZ73+z/R8Kwk/8NgkFPT/N7vQwuSK7Ax27h8pyV0m8Zx lziNBiVM0HRTB5WREJsMWVD8NRcm8e+Xf7bFjhR0FbT7U3cSy4kLOPTd9RDKxxkj sGI56r1OoRCQFrv456kz6SPLLYx2ecP9WzDp6ghOvGENJ3UYFoUcv0L9+aQL1gyy Gxn+bTng6TMHxjpzhRgS4pJg3TME2US4HQepsRrrNZ0FXM67Gt4pFwoxtA/ZLy4X WyuROJ1Xy46G7Yn0glTPWGJ3yDDud88etLdF3RbH+wWtB88WvBtIjyPQ0QCEOFpU 0UMD4ow9 =hChf -----END PGP SIGNATURE----- Merge tag '5.16-rc3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6 Pull cifs fixes from Steve French: "Three SMB3 multichannel/fscache fixes and a DFS fix. In testing multichannel reconnect scenarios recently various problems with the cifs.ko implementation of fscache were found (e.g. incorrect initialization of fscache cookies in some cases)" * tag '5.16-rc3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: avoid use of dstaddr as key for fscache client cookie cifs: add server conn_id to fscache client cookie cifs: wait for tcon resource_id before getting fscache super cifs: fix missed refcounting of ipc tcon
This commit is contained in:
commit
23b55d673d
|
@ -1562,6 +1562,10 @@ smbd_connected:
|
|||
/* fscache server cookies are based on primary channel only */
|
||||
if (!CIFS_SERVER_IS_CHAN(tcp_ses))
|
||||
cifs_fscache_get_client_cookie(tcp_ses);
|
||||
#ifdef CONFIG_CIFS_FSCACHE
|
||||
else
|
||||
tcp_ses->fscache = tcp_ses->primary_server->fscache;
|
||||
#endif /* CONFIG_CIFS_FSCACHE */
|
||||
|
||||
/* queue echo request delayed work */
|
||||
queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval);
|
||||
|
@ -3046,12 +3050,6 @@ static int mount_get_conns(struct mount_ctx *mnt_ctx)
|
|||
cifs_dbg(VFS, "read only mount of RW share\n");
|
||||
/* no need to log a RW mount of a typical RW share */
|
||||
}
|
||||
/*
|
||||
* The cookie is initialized from volume info returned above.
|
||||
* Inside cifs_fscache_get_super_cookie it checks
|
||||
* that we do not get super cookie twice.
|
||||
*/
|
||||
cifs_fscache_get_super_cookie(tcon);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3426,6 +3424,7 @@ static int connect_dfs_root(struct mount_ctx *mnt_ctx, struct dfs_cache_tgt_list
|
|||
*/
|
||||
mount_put_conns(mnt_ctx);
|
||||
mount_get_dfs_conns(mnt_ctx);
|
||||
set_root_ses(mnt_ctx);
|
||||
|
||||
full_path = build_unc_path_to_root(ctx, cifs_sb, true);
|
||||
if (IS_ERR(full_path))
|
||||
|
|
|
@ -16,14 +16,7 @@
|
|||
* Key layout of CIFS server cache index object
|
||||
*/
|
||||
struct cifs_server_key {
|
||||
struct {
|
||||
uint16_t family; /* address family */
|
||||
__be16 port; /* IP port */
|
||||
} hdr;
|
||||
union {
|
||||
struct in_addr ipv4_addr;
|
||||
struct in6_addr ipv6_addr;
|
||||
};
|
||||
__u64 conn_id;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
|
@ -31,42 +24,23 @@ struct cifs_server_key {
|
|||
*/
|
||||
void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
|
||||
{
|
||||
const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr;
|
||||
const struct sockaddr_in *addr = (struct sockaddr_in *) sa;
|
||||
const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa;
|
||||
struct cifs_server_key key;
|
||||
uint16_t key_len = sizeof(key.hdr);
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
||||
/*
|
||||
* Should not be a problem as sin_family/sin6_family overlays
|
||||
* sa_family field
|
||||
* Check if cookie was already initialized so don't reinitialize it.
|
||||
* In the future, as we integrate with newer fscache features,
|
||||
* we may want to instead add a check if cookie has changed
|
||||
*/
|
||||
key.hdr.family = sa->sa_family;
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
key.hdr.port = addr->sin_port;
|
||||
key.ipv4_addr = addr->sin_addr;
|
||||
key_len += sizeof(key.ipv4_addr);
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
key.hdr.port = addr6->sin6_port;
|
||||
key.ipv6_addr = addr6->sin6_addr;
|
||||
key_len += sizeof(key.ipv6_addr);
|
||||
break;
|
||||
|
||||
default:
|
||||
cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family);
|
||||
server->fscache = NULL;
|
||||
if (server->fscache)
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.conn_id = server->conn_id;
|
||||
|
||||
server->fscache =
|
||||
fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
|
||||
&cifs_fscache_server_index_def,
|
||||
&key, key_len,
|
||||
&key, sizeof(key),
|
||||
NULL, 0,
|
||||
server, 0, true);
|
||||
cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
|
||||
|
@ -92,7 +66,7 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
|
|||
* In the future, as we integrate with newer fscache features,
|
||||
* we may want to instead add a check if cookie has changed
|
||||
*/
|
||||
if (tcon->fscache == NULL)
|
||||
if (tcon->fscache)
|
||||
return;
|
||||
|
||||
sharename = extract_sharename(tcon->treeName);
|
||||
|
|
|
@ -1376,6 +1376,13 @@ iget_no_retry:
|
|||
inode = ERR_PTR(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* The cookie is initialized from volume info returned above.
|
||||
* Inside cifs_fscache_get_super_cookie it checks
|
||||
* that we do not get super cookie twice.
|
||||
*/
|
||||
cifs_fscache_get_super_cookie(tcon);
|
||||
|
||||
out:
|
||||
kfree(path);
|
||||
free_xid(xid);
|
||||
|
|
Loading…
Reference in New Issue