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 '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

+22 -42
+5 -6
fs/cifs/connect.c
··· 1562 1562 /* fscache server cookies are based on primary channel only */ 1563 1563 if (!CIFS_SERVER_IS_CHAN(tcp_ses)) 1564 1564 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 */ 1565 1569 1566 1570 /* queue echo request delayed work */ 1567 1571 queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval); ··· 3050 3046 cifs_dbg(VFS, "read only mount of RW share\n"); 3051 3047 /* no need to log a RW mount of a typical RW share */ 3052 3048 } 3053 - /* 3054 - * The cookie is initialized from volume info returned above. 3055 - * Inside cifs_fscache_get_super_cookie it checks 3056 - * that we do not get super cookie twice. 3057 - */ 3058 - cifs_fscache_get_super_cookie(tcon); 3059 3049 } 3060 3050 3061 3051 /* ··· 3424 3426 */ 3425 3427 mount_put_conns(mnt_ctx); 3426 3428 mount_get_dfs_conns(mnt_ctx); 3429 + set_root_ses(mnt_ctx); 3427 3430 3428 3431 full_path = build_unc_path_to_root(ctx, cifs_sb, true); 3429 3432 if (IS_ERR(full_path))
+10 -36
fs/cifs/fscache.c
··· 16 16 * Key layout of CIFS server cache index object 17 17 */ 18 18 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; 27 20 } __packed; 28 21 29 22 /* ··· 24 31 */ 25 32 void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) 26 33 { 27 - const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr; 28 - const struct sockaddr_in *addr = (struct sockaddr_in *) sa; 29 - const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa; 30 34 struct cifs_server_key key; 31 - uint16_t key_len = sizeof(key.hdr); 32 - 33 - memset(&key, 0, sizeof(key)); 34 35 35 36 /* 36 - * Should not be a problem as sin_family/sin6_family overlays 37 - * sa_family field 37 + * Check if cookie was already initialized so don't reinitialize it. 38 + * In the future, as we integrate with newer fscache features, 39 + * we may want to instead add a check if cookie has changed 38 40 */ 39 - key.hdr.family = sa->sa_family; 40 - switch (sa->sa_family) { 41 - case AF_INET: 42 - key.hdr.port = addr->sin_port; 43 - key.ipv4_addr = addr->sin_addr; 44 - key_len += sizeof(key.ipv4_addr); 45 - break; 46 - 47 - case AF_INET6: 48 - key.hdr.port = addr6->sin6_port; 49 - key.ipv6_addr = addr6->sin6_addr; 50 - key_len += sizeof(key.ipv6_addr); 51 - break; 52 - 53 - default: 54 - cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family); 55 - server->fscache = NULL; 41 + if (server->fscache) 56 42 return; 57 - } 43 + 44 + memset(&key, 0, sizeof(key)); 45 + key.conn_id = server->conn_id; 58 46 59 47 server->fscache = 60 48 fscache_acquire_cookie(cifs_fscache_netfs.primary_index, 61 49 &cifs_fscache_server_index_def, 62 - &key, key_len, 50 + &key, sizeof(key), 63 51 NULL, 0, 64 52 server, 0, true); 65 53 cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", ··· 66 92 * In the future, as we integrate with newer fscache features, 67 93 * we may want to instead add a check if cookie has changed 68 94 */ 69 - if (tcon->fscache == NULL) 95 + if (tcon->fscache) 70 96 return; 71 97 72 98 sharename = extract_sharename(tcon->treeName);
+7
fs/cifs/inode.c
··· 1376 1376 inode = ERR_PTR(rc); 1377 1377 } 1378 1378 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 + 1379 1386 out: 1380 1387 kfree(path); 1381 1388 free_xid(xid);