mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2025-04-19 20:58:31 +09:00
smb client fixes
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmgC/bEACgkQiiy9cAdy T1Fhtwv/THJBLHY7HVZAdhVGbWOi/zQ+hKpIyglDJ8bcoxU+UA0qRMFcrrL/2qMd 4dGwtlQBgWEV2Ixb2q1j9gAcg0Q7n2jtp6+1iBB3re/SA5ykyLzC+REcBSo7GnXQ OL+FPEfo1/JS8W955ZTgzpA/k18btI0b1IIgx5409SiPt5pcmxwodar7CQUrT3gU LWDApQbRG+/HR24MPSBY4q5Xx5CWGEYlpy2Sra44VFtig31YrPaGO372qPwzu3k+ NBeQ5IWe64ema6fhmHK70oSz+ZUih0llr5oVlGFn8IGrhG3HryY0KD4ORRzVubmq XXwFI2+sDNTlTwu7kwXLw/GKKV2UBPCDemsEBm3MPFiKi/TKOObgE0HK4y4mXySI Lv1iIUcCkxD/MYuMPED3ntI6akV60KdFMZWxaBiV29FjJPT9pxryViMsDwMhgTaS xOKV0IbrnmldrRo7GGTTOn+54QuRijyFgxxF1rs2lANAoC2hi4AtlgFeg6912Haa mDofaZL4 =92E5 -----END PGP SIGNATURE----- Merge tag '6.15-rc2-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6 Pull smb client fixes from Steve French: - Fix hard link lease key problem when close is deferred - Revert the socket lockdep/refcount workarounds done in cifs.ko now that it is fixed at the socket layer * tag '6.15-rc2-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: Revert "smb: client: fix TCP timers deadlock after rmmod" Revert "smb: client: Fix netns refcount imbalance causing leaks and use-after-free" smb3 client: fix open hardlink on deferred close file error
This commit is contained in:
commit
8560697b23
@ -163,6 +163,8 @@ extern int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
|
||||
extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
|
||||
extern int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
|
||||
struct cifsFileInfo **ret_file);
|
||||
extern int cifs_get_hardlink_path(struct cifs_tcon *tcon, struct inode *inode,
|
||||
struct file *file);
|
||||
extern unsigned int smbCalcSize(void *buf);
|
||||
extern int decode_negTokenInit(unsigned char *security_blob, int length,
|
||||
struct TCP_Server_Info *server);
|
||||
|
@ -300,7 +300,6 @@ cifs_abort_connection(struct TCP_Server_Info *server)
|
||||
server->ssocket->flags);
|
||||
sock_release(server->ssocket);
|
||||
server->ssocket = NULL;
|
||||
put_net(cifs_net_ns(server));
|
||||
}
|
||||
server->sequence_number = 0;
|
||||
server->session_estab = false;
|
||||
@ -1074,13 +1073,9 @@ clean_demultiplex_info(struct TCP_Server_Info *server)
|
||||
msleep(125);
|
||||
if (cifs_rdma_enabled(server))
|
||||
smbd_destroy(server);
|
||||
|
||||
if (server->ssocket) {
|
||||
sock_release(server->ssocket);
|
||||
server->ssocket = NULL;
|
||||
|
||||
/* Release netns reference for the socket. */
|
||||
put_net(cifs_net_ns(server));
|
||||
}
|
||||
|
||||
if (!list_empty(&server->pending_mid_q)) {
|
||||
@ -1128,7 +1123,6 @@ clean_demultiplex_info(struct TCP_Server_Info *server)
|
||||
*/
|
||||
}
|
||||
|
||||
/* Release netns reference for this server. */
|
||||
put_net(cifs_net_ns(server));
|
||||
kfree(server->leaf_fullpath);
|
||||
kfree(server->hostname);
|
||||
@ -1774,8 +1768,6 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
|
||||
|
||||
tcp_ses->ops = ctx->ops;
|
||||
tcp_ses->vals = ctx->vals;
|
||||
|
||||
/* Grab netns reference for this server. */
|
||||
cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
|
||||
|
||||
tcp_ses->sign = ctx->sign;
|
||||
@ -1903,7 +1895,6 @@ smbd_connected:
|
||||
out_err_crypto_release:
|
||||
cifs_crypto_secmech_release(tcp_ses);
|
||||
|
||||
/* Release netns reference for this server. */
|
||||
put_net(cifs_net_ns(tcp_ses));
|
||||
|
||||
out_err:
|
||||
@ -1912,10 +1903,8 @@ out_err:
|
||||
cifs_put_tcp_session(tcp_ses->primary_server, false);
|
||||
kfree(tcp_ses->hostname);
|
||||
kfree(tcp_ses->leaf_fullpath);
|
||||
if (tcp_ses->ssocket) {
|
||||
if (tcp_ses->ssocket)
|
||||
sock_release(tcp_ses->ssocket);
|
||||
put_net(cifs_net_ns(tcp_ses));
|
||||
}
|
||||
kfree(tcp_ses);
|
||||
}
|
||||
return ERR_PTR(rc);
|
||||
@ -3359,24 +3348,20 @@ generic_ip_connect(struct TCP_Server_Info *server)
|
||||
socket = server->ssocket;
|
||||
} else {
|
||||
struct net *net = cifs_net_ns(server);
|
||||
struct sock *sk;
|
||||
|
||||
rc = sock_create_kern(net, sfamily, SOCK_STREAM, IPPROTO_TCP, &server->ssocket);
|
||||
rc = __sock_create(net, sfamily, SOCK_STREAM,
|
||||
IPPROTO_TCP, &server->ssocket, 1);
|
||||
if (rc < 0) {
|
||||
cifs_server_dbg(VFS, "Error %d creating socket\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Grab netns reference for the socket.
|
||||
*
|
||||
* This reference will be released in several situations:
|
||||
* - In the failure path before the cifsd thread is started.
|
||||
* - In the all place where server->socket is released, it is
|
||||
* also set to NULL.
|
||||
* - Ultimately in clean_demultiplex_info(), during the final
|
||||
* teardown.
|
||||
*/
|
||||
get_net(net);
|
||||
sk = server->ssocket->sk;
|
||||
__netns_tracker_free(net, &sk->ns_tracker, false);
|
||||
sk->sk_net_refcnt = 1;
|
||||
get_net_track(net, &sk->ns_tracker, GFP_KERNEL);
|
||||
sock_inuse_add(net, 1);
|
||||
|
||||
/* BB other socket options to set KEEPALIVE, NODELAY? */
|
||||
cifs_dbg(FYI, "Socket created\n");
|
||||
@ -3428,7 +3413,6 @@ generic_ip_connect(struct TCP_Server_Info *server)
|
||||
if (rc < 0) {
|
||||
cifs_dbg(FYI, "Error %d connecting to server\n", rc);
|
||||
trace_smb3_connect_err(server->hostname, server->conn_id, &server->dstaddr, rc);
|
||||
put_net(cifs_net_ns(server));
|
||||
sock_release(socket);
|
||||
server->ssocket = NULL;
|
||||
return rc;
|
||||
|
@ -1007,6 +1007,11 @@ int cifs_open(struct inode *inode, struct file *file)
|
||||
} else {
|
||||
_cifsFileInfo_put(cfile, true, false);
|
||||
}
|
||||
} else {
|
||||
/* hard link on the defeered close file */
|
||||
rc = cifs_get_hardlink_path(tcon, inode, file);
|
||||
if (rc)
|
||||
cifs_close_deferred_file(CIFS_I(inode));
|
||||
}
|
||||
|
||||
if (server->oplocks)
|
||||
@ -2071,6 +2076,29 @@ cifs_move_llist(struct list_head *source, struct list_head *dest)
|
||||
list_move(li, dest);
|
||||
}
|
||||
|
||||
int
|
||||
cifs_get_hardlink_path(struct cifs_tcon *tcon, struct inode *inode,
|
||||
struct file *file)
|
||||
{
|
||||
struct cifsFileInfo *open_file = NULL;
|
||||
struct cifsInodeInfo *cinode = CIFS_I(inode);
|
||||
int rc = 0;
|
||||
|
||||
spin_lock(&tcon->open_file_lock);
|
||||
spin_lock(&cinode->open_file_lock);
|
||||
|
||||
list_for_each_entry(open_file, &cinode->openFileList, flist) {
|
||||
if (file->f_flags == open_file->f_flags) {
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&cinode->open_file_lock);
|
||||
spin_unlock(&tcon->open_file_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
cifs_free_llist(struct list_head *llist)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user