Skip to content

Commit 23b55d6

Browse files
committed
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
2 parents bbef3c7 + bbb9db5 commit 23b55d6

File tree

3 files changed

+22
-42
lines changed

3 files changed

+22
-42
lines changed

fs/cifs/connect.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,6 +1562,10 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
15621562
/* fscache server cookies are based on primary channel only */
15631563
if (!CIFS_SERVER_IS_CHAN(tcp_ses))
15641564
cifs_fscache_get_client_cookie(tcp_ses);
1565+
#ifdef CONFIG_CIFS_FSCACHE
1566+
else
1567+
tcp_ses->fscache = tcp_ses->primary_server->fscache;
1568+
#endif /* CONFIG_CIFS_FSCACHE */
15651569

15661570
/* queue echo request delayed work */
15671571
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)
30463050
cifs_dbg(VFS, "read only mount of RW share\n");
30473051
/* no need to log a RW mount of a typical RW share */
30483052
}
3049-
/*
3050-
* The cookie is initialized from volume info returned above.
3051-
* Inside cifs_fscache_get_super_cookie it checks
3052-
* that we do not get super cookie twice.
3053-
*/
3054-
cifs_fscache_get_super_cookie(tcon);
30553053
}
30563054

30573055
/*
@@ -3426,6 +3424,7 @@ static int connect_dfs_root(struct mount_ctx *mnt_ctx, struct dfs_cache_tgt_list
34263424
*/
34273425
mount_put_conns(mnt_ctx);
34283426
mount_get_dfs_conns(mnt_ctx);
3427+
set_root_ses(mnt_ctx);
34293428

34303429
full_path = build_unc_path_to_root(ctx, cifs_sb, true);
34313430
if (IS_ERR(full_path))

fs/cifs/fscache.c

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -16,57 +16,31 @@
1616
* Key layout of CIFS server cache index object
1717
*/
1818
struct cifs_server_key {
19-
struct {
20-
uint16_t family; /* address family */
21-
__be16 port; /* IP port */
22-
} hdr;
23-
union {
24-
struct in_addr ipv4_addr;
25-
struct in6_addr ipv6_addr;
26-
};
19+
__u64 conn_id;
2720
} __packed;
2821

2922
/*
3023
* Get a cookie for a server object keyed by {IPaddress,port,family} tuple
3124
*/
3225
void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
3326
{
34-
const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr;
35-
const struct sockaddr_in *addr = (struct sockaddr_in *) sa;
36-
const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa;
3727
struct cifs_server_key key;
38-
uint16_t key_len = sizeof(key.hdr);
39-
40-
memset(&key, 0, sizeof(key));
4128

4229
/*
43-
* Should not be a problem as sin_family/sin6_family overlays
44-
* sa_family field
30+
* Check if cookie was already initialized so don't reinitialize it.
31+
* In the future, as we integrate with newer fscache features,
32+
* we may want to instead add a check if cookie has changed
4533
*/
46-
key.hdr.family = sa->sa_family;
47-
switch (sa->sa_family) {
48-
case AF_INET:
49-
key.hdr.port = addr->sin_port;
50-
key.ipv4_addr = addr->sin_addr;
51-
key_len += sizeof(key.ipv4_addr);
52-
break;
53-
54-
case AF_INET6:
55-
key.hdr.port = addr6->sin6_port;
56-
key.ipv6_addr = addr6->sin6_addr;
57-
key_len += sizeof(key.ipv6_addr);
58-
break;
59-
60-
default:
61-
cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family);
62-
server->fscache = NULL;
34+
if (server->fscache)
6335
return;
64-
}
36+
37+
memset(&key, 0, sizeof(key));
38+
key.conn_id = server->conn_id;
6539

6640
server->fscache =
6741
fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
6842
&cifs_fscache_server_index_def,
69-
&key, key_len,
43+
&key, sizeof(key),
7044
NULL, 0,
7145
server, 0, true);
7246
cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
@@ -92,7 +66,7 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
9266
* In the future, as we integrate with newer fscache features,
9367
* we may want to instead add a check if cookie has changed
9468
*/
95-
if (tcon->fscache == NULL)
69+
if (tcon->fscache)
9670
return;
9771

9872
sharename = extract_sharename(tcon->treeName);

fs/cifs/inode.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,13 @@ struct inode *cifs_root_iget(struct super_block *sb)
13761376
inode = ERR_PTR(rc);
13771377
}
13781378

1379+
/*
1380+
* The cookie is initialized from volume info returned above.
1381+
* Inside cifs_fscache_get_super_cookie it checks
1382+
* that we do not get super cookie twice.
1383+
*/
1384+
cifs_fscache_get_super_cookie(tcon);
1385+
13791386
out:
13801387
kfree(path);
13811388
free_xid(xid);

0 commit comments

Comments
 (0)