connect.c 108.3 KB
Newer Older
S
Steve French 已提交
1
// SPDX-License-Identifier: LGPL-2.1
L
Linus Torvalds 已提交
2 3
/*
 *
4
 *   Copyright (C) International Business Machines  Corp., 2002,2011
L
Linus Torvalds 已提交
5 6 7 8 9 10
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 */
#include <linux/fs.h>
#include <linux/net.h>
#include <linux/string.h>
11
#include <linux/sched/mm.h>
12
#include <linux/sched/signal.h>
L
Linus Torvalds 已提交
13 14
#include <linux/list.h>
#include <linux/wait.h>
15
#include <linux/slab.h>
L
Linus Torvalds 已提交
16 17 18 19
#include <linux/pagemap.h>
#include <linux/ctype.h>
#include <linux/utsname.h>
#include <linux/mempool.h>
20
#include <linux/delay.h>
21
#include <linux/completion.h>
22
#include <linux/kthread.h>
23
#include <linux/pagevec.h>
24
#include <linux/freezer.h>
25
#include <linux/namei.h>
26
#include <linux/uuid.h>
27
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
28
#include <asm/processor.h>
29
#include <linux/inet.h>
30
#include <linux/module.h>
31
#include <keys/user-type.h>
32
#include <net/ipv6.h>
33
#include <linux/parser.h>
34
#include <linux/bvec.h>
L
Linus Torvalds 已提交
35 36 37 38 39 40 41 42 43
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsproto.h"
#include "cifs_unicode.h"
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
#include "ntlmssp.h"
#include "nterr.h"
#include "rfc1002pdu.h"
44
#include "fscache.h"
45
#include "smb2proto.h"
46
#include "smbdirect.h"
47 48
#include "dns_resolve.h"
#ifdef CONFIG_CIFS_DFS_UPCALL
49
#include "dfs.h"
50 51
#include "dfs_cache.h"
#endif
52
#include "fs_context.h"
53
#include "cifs_swn.h"
L
Linus Torvalds 已提交
54 55

extern mempool_t *cifs_req_poolp;
56
extern bool disable_legacy_dialects;
L
Linus Torvalds 已提交
57

58
/* FIXME: should these be tunable? */
59
#define TLINK_ERROR_EXPIRE	(1 * HZ)
60
#define TLINK_IDLE_EXPIRE	(600 * HZ)
61

62 63 64
/* Drop the connection to not overload the server */
#define NUM_STATUS_IO_TIMEOUT   5

65 66
static int ip_connect(struct TCP_Server_Info *server);
static int generic_ip_connect(struct TCP_Server_Info *server);
J
Jeff Layton 已提交
67
static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
68
static void cifs_prune_tlinks(struct work_struct *work);
69

70 71 72 73 74 75
/*
 * Resolve hostname and set ip addr in tcp ses. Useful for hostnames that may
 * get their ip addresses changed at some point.
 *
 * This should be called with server->srv_mutex held.
 */
76
static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
77 78 79
{
	int rc;
	int len;
80 81
	char *unc;
	struct sockaddr_storage ss;
82 83 84 85

	if (!server->hostname)
		return -EINVAL;

86 87 88 89
	/* if server hostname isn't populated, there's nothing to do here */
	if (server->hostname[0] == '\0')
		return 0;

90 91 92 93 94 95 96
	len = strlen(server->hostname) + 3;

	unc = kmalloc(len, GFP_KERNEL);
	if (!unc) {
		cifs_dbg(FYI, "%s: failed to create UNC path\n", __func__);
		return -ENOMEM;
	}
97
	scnprintf(unc, len, "\\\\%s", server->hostname);
98

99 100 101 102
	spin_lock(&server->srv_lock);
	ss = server->dstaddr;
	spin_unlock(&server->srv_lock);

103
	rc = dns_resolve_server_name_to_ip(unc, (struct sockaddr *)&ss, NULL);
104 105 106 107 108
	kfree(unc);

	if (rc < 0) {
		cifs_dbg(FYI, "%s: failed to resolve server part of %s to IP: %d\n",
			 __func__, server->hostname, rc);
109 110 111 112 113
	} else {
		spin_lock(&server->srv_lock);
		memcpy(&server->dstaddr, &ss, sizeof(server->dstaddr));
		spin_unlock(&server->srv_lock);
		rc = 0;
114 115
	}

116 117 118
	return rc;
}

119 120 121 122 123 124 125 126 127 128
static void smb2_query_server_interfaces(struct work_struct *work)
{
	int rc;
	struct cifs_tcon *tcon = container_of(work,
					struct cifs_tcon,
					query_interfaces.work);

	/*
	 * query server network interfaces, in case they change
	 */
129
	rc = SMB3_request_interfaces(0, tcon, false);
130 131 132 133 134 135 136 137
	if (rc) {
		cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n",
				__func__, rc);
	}

	queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
			   (SMB_INTERFACE_POLL_INTERVAL * HZ));
}
138

139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
/*
 * Update the tcpStatus for the server.
 * This is used to signal the cifsd thread to call cifs_reconnect
 * ONLY cifsd thread should call cifs_reconnect. For any other
 * thread, use this function
 *
 * @server: the tcp ses for which reconnect is needed
 * @all_channels: if this needs to be done for all channels
 */
void
cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server,
				bool all_channels)
{
	struct TCP_Server_Info *pserver;
	struct cifs_ses *ses;
	int i;

	/* If server is a channel, select the primary channel */
	pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;

159
	spin_lock(&pserver->srv_lock);
160 161
	if (!all_channels) {
		pserver->tcpStatus = CifsNeedReconnect;
162
		spin_unlock(&pserver->srv_lock);
163 164
		return;
	}
165
	spin_unlock(&pserver->srv_lock);
166

167
	spin_lock(&cifs_tcp_ses_lock);
168 169
	list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
		spin_lock(&ses->chan_lock);
170 171
		for (i = 0; i < ses->chan_count; i++) {
			spin_lock(&ses->chans[i].server->srv_lock);
172
			ses->chans[i].server->tcpStatus = CifsNeedReconnect;
173 174
			spin_unlock(&ses->chans[i].server->srv_lock);
		}
175 176 177 178 179
		spin_unlock(&ses->chan_lock);
	}
	spin_unlock(&cifs_tcp_ses_lock);
}

180
/*
181
 * Mark all sessions and tcons for reconnect.
182 183 184
 * IMPORTANT: make sure that this gets called only from
 * cifsd thread. For any other thread, use
 * cifs_signal_cifsd_for_reconnect
185
 *
186
 * @server: the tcp ses for which reconnect is needed
187
 * @server needs to be previously set to CifsNeedReconnect.
188
 * @mark_smb_session: whether even sessions need to be marked
189
 */
190
void
191 192
cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
				      bool mark_smb_session)
L
Linus Torvalds 已提交
193
{
194
	struct TCP_Server_Info *pserver;
195
	struct cifs_ses *ses, *nses;
196
	struct cifs_tcon *tcon;
L
Linus Torvalds 已提交
197

198 199 200 201
	/*
	 * before reconnecting the tcp session, mark the smb session (uid) and the tid bad so they
	 * are not used until reconnected.
	 */
202
	cifs_dbg(FYI, "%s: marking necessary sessions and tcons for reconnect\n", __func__);
203 204 205 206

	/* If server is a channel, select the primary channel */
	pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;

207

208
	spin_lock(&cifs_tcp_ses_lock);
209
	list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) {
210
		/* check if iface is still active */
211
		if (!cifs_chan_is_iface_active(ses, server))
212 213
			cifs_chan_update_iface(ses, server);

214
		spin_lock(&ses->chan_lock);
215
		if (!mark_smb_session && cifs_chan_needs_reconnect(ses, server))
216 217
			goto next_session;

218 219 220 221
		if (mark_smb_session)
			CIFS_SET_ALL_CHANS_NEED_RECONNECT(ses);
		else
			cifs_chan_set_need_reconnect(ses, server);
222 223

		/* If all channels need reconnect, then tcon needs reconnect */
224
		if (!mark_smb_session && !CIFS_ALL_CHANS_NEED_RECONNECT(ses))
225 226
			goto next_session;

227
		ses->ses_status = SES_NEED_RECON;
228

229
		list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
S
Steve French 已提交
230
			tcon->need_reconnect = true;
231
			tcon->status = TID_NEED_RECON;
232
		}
233
		if (ses->tcon_ipc) {
A
Aurelien Aptel 已提交
234
			ses->tcon_ipc->need_reconnect = true;
235 236
			ses->tcon_ipc->status = TID_NEED_RECON;
		}
237 238 239

next_session:
		spin_unlock(&ses->chan_lock);
L
Linus Torvalds 已提交
240
	}
241
	spin_unlock(&cifs_tcp_ses_lock);
242 243 244 245 246 247 248 249 250 251
}

static void
cifs_abort_connection(struct TCP_Server_Info *server)
{
	struct mid_q_entry *mid, *nmid;
	struct list_head retry_list;

	server->maxBuf = 0;
	server->max_read = 0;
252

L
Linus Torvalds 已提交
253
	/* do not want to be sending data on a socket we are freeing */
254
	cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
255
	cifs_server_lock(server);
256
	if (server->ssocket) {
257 258
		cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n", server->ssocket->state,
			 server->ssocket->flags);
259
		kernel_sock_shutdown(server->ssocket, SHUT_WR);
260 261
		cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n", server->ssocket->state,
			 server->ssocket->flags);
262 263 264 265 266
		sock_release(server->ssocket);
		server->ssocket = NULL;
	}
	server->sequence_number = 0;
	server->session_estab = false;
267
	kfree_sensitive(server->session_key.response);
268 269 270
	server->session_key.response = NULL;
	server->session_key.len = 0;
	server->lstrp = jiffies;
L
Linus Torvalds 已提交
271

272
	/* mark submitted MIDs for retry and issue callback */
273
	INIT_LIST_HEAD(&retry_list);
274
	cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
275
	spin_lock(&server->mid_lock);
276 277 278 279 280 281
	list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) {
		kref_get(&mid->refcount);
		if (mid->mid_state == MID_REQUEST_SUBMITTED)
			mid->mid_state = MID_RETRY_NEEDED;
		list_move(&mid->qhead, &retry_list);
		mid->mid_flags |= MID_DELETED;
282
	}
283
	spin_unlock(&server->mid_lock);
284
	cifs_server_unlock(server);
285

286
	cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
287 288 289
	list_for_each_entry_safe(mid, nmid, &retry_list, qhead) {
		list_del_init(&mid->qhead);
		mid->callback(mid);
290
		release_mid(mid);
L
Linus Torvalds 已提交
291 292
	}

293
	if (cifs_rdma_enabled(server)) {
294
		cifs_server_lock(server);
295
		smbd_destroy(server);
296
		cifs_server_unlock(server);
297
	}
298 299
}

300 301
static bool cifs_tcp_ses_needs_reconnect(struct TCP_Server_Info *server, int num_targets)
{
302
	spin_lock(&server->srv_lock);
303 304 305
	server->nr_targets = num_targets;
	if (server->tcpStatus == CifsExiting) {
		/* the demux thread will exit normally next time through the loop */
306
		spin_unlock(&server->srv_lock);
307 308 309
		wake_up(&server->response_q);
		return false;
	}
310 311 312 313

	cifs_dbg(FYI, "Mark tcp session as need reconnect\n");
	trace_smb3_reconnect(server->CurrentMid, server->conn_id,
			     server->hostname);
314
	server->tcpStatus = CifsNeedReconnect;
315

316
	spin_unlock(&server->srv_lock);
317 318 319
	return true;
}

320 321 322 323 324 325 326
/*
 * cifs tcp session reconnection
 *
 * mark tcp session as reconnecting so temporarily locked
 * mark all smb sessions as reconnecting for tcp session
 * reconnect tcp session
 * wake up waiters on reconnection? - (not needed currently)
327 328 329 330 331
 *
 * if mark_smb_session is passed as true, unconditionally mark
 * the smb session (and tcon) for reconnect as well. This value
 * doesn't really matter for non-multichannel scenario.
 *
332
 */
333 334
static int __cifs_reconnect(struct TCP_Server_Info *server,
			    bool mark_smb_session)
335 336 337
{
	int rc = 0;

338 339
	if (!cifs_tcp_ses_needs_reconnect(server, 1))
		return 0;
340

341
	cifs_mark_tcp_ses_conns_for_reconnect(server, mark_smb_session);
342

343 344
	cifs_abort_connection(server);

345
	do {
346
		try_to_freeze();
347
		cifs_server_lock(server);
348

349
		if (!cifs_swn_set_server_dstaddr(server)) {
350
			/* resolve the hostname again to make sure that IP address is up-to-date */
351
			rc = reconn_set_ipaddr_from_hostname(server);
352
			cifs_dbg(FYI, "%s: reconn_set_ipaddr_from_hostname: rc=%d\n", __func__, rc);
353
		}
354

355 356 357 358
		if (cifs_rdma_enabled(server))
			rc = smbd_reconnect(server);
		else
			rc = generic_ip_connect(server);
S
Steve French 已提交
359
		if (rc) {
360
			cifs_server_unlock(server);
361
			cifs_dbg(FYI, "%s: reconnect error %d\n", __func__, rc);
362
			msleep(3000);
L
Linus Torvalds 已提交
363 364
		} else {
			atomic_inc(&tcpSesReconnectCount);
365
			set_credits(server, 1);
366
			spin_lock(&server->srv_lock);
367
			if (server->tcpStatus != CifsExiting)
368
				server->tcpStatus = CifsNeedNegotiate;
369
			spin_unlock(&server->srv_lock);
370
			cifs_swn_reset_server_dstaddr(server);
371
			cifs_server_unlock(server);
372
			mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
L
Linus Torvalds 已提交
373
		}
374
	} while (server->tcpStatus == CifsNeedReconnect);
375

376
	spin_lock(&server->srv_lock);
377 378
	if (server->tcpStatus == CifsNeedNegotiate)
		mod_delayed_work(cifsiod_wq, &server->echo, 0);
379
	spin_unlock(&server->srv_lock);
380 381 382 383 384

	wake_up(&server->response_q);
	return rc;
}

385
#ifdef CONFIG_CIFS_DFS_UPCALL
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
static int __reconnect_target_unlocked(struct TCP_Server_Info *server, const char *target)
{
	int rc;
	char *hostname;

	if (!cifs_swn_set_server_dstaddr(server)) {
		if (server->hostname != target) {
			hostname = extract_hostname(target);
			if (!IS_ERR(hostname)) {
				kfree(server->hostname);
				server->hostname = hostname;
			} else {
				cifs_dbg(FYI, "%s: couldn't extract hostname or address from dfs target: %ld\n",
					 __func__, PTR_ERR(hostname));
				cifs_dbg(FYI, "%s: default to last target server: %s\n", __func__,
					 server->hostname);
			}
		}
		/* resolve the hostname again to make sure that IP address is up-to-date. */
		rc = reconn_set_ipaddr_from_hostname(server);
		cifs_dbg(FYI, "%s: reconn_set_ipaddr_from_hostname: rc=%d\n", __func__, rc);
	}
	/* Reconnect the socket */
	if (cifs_rdma_enabled(server))
		rc = smbd_reconnect(server);
	else
		rc = generic_ip_connect(server);

	return rc;
}

static int reconnect_target_unlocked(struct TCP_Server_Info *server, struct dfs_cache_tgt_list *tl,
				     struct dfs_cache_tgt_iterator **target_hint)
{
	int rc;
	struct dfs_cache_tgt_iterator *tit;

	*target_hint = NULL;

	/* If dfs target list is empty, then reconnect to last server */
	tit = dfs_cache_get_tgt_iterator(tl);
	if (!tit)
		return __reconnect_target_unlocked(server, server->hostname);

	/* Otherwise, try every dfs target in @tl */
	for (; tit; tit = dfs_cache_get_next_tgt(tl, tit)) {
		rc = __reconnect_target_unlocked(server, dfs_cache_get_tgt_name(tit));
		if (!rc) {
			*target_hint = tit;
			break;
		}
	}
	return rc;
}

441
static int reconnect_dfs_server(struct TCP_Server_Info *server)
442 443
{
	int rc = 0;
444
	const char *refpath = server->current_fullpath + 1;
445
	struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT(tl);
446 447
	struct dfs_cache_tgt_iterator *target_hint = NULL;
	int num_targets = 0;
448 449 450 451 452 453 454 455 456

	/*
	 * Determine the number of dfs targets the referral path in @cifs_sb resolves to.
	 *
	 * smb2_reconnect() needs to know how long it should wait based upon the number of dfs
	 * targets (server->nr_targets).  It's also possible that the cached referral was cleared
	 * through /proc/fs/cifs/dfscache or the target list is empty due to server settings after
	 * refreshing the referral, so, in this case, default it to 1.
	 */
457
	if (!dfs_cache_noreq_find(refpath, NULL, &tl))
458
		num_targets = dfs_cache_get_nr_tgts(&tl);
459 460
	if (!num_targets)
		num_targets = 1;
461 462 463 464

	if (!cifs_tcp_ses_needs_reconnect(server, num_targets))
		return 0;

465 466 467 468 469 470
	/*
	 * Unconditionally mark all sessions & tcons for reconnect as we might be connecting to a
	 * different server or share during failover.  It could be improved by adding some logic to
	 * only do that in case it connects to a different server or share, though.
	 */
	cifs_mark_tcp_ses_conns_for_reconnect(server, true);
471

472 473
	cifs_abort_connection(server);

474 475
	do {
		try_to_freeze();
476
		cifs_server_lock(server);
477

478
		rc = reconnect_target_unlocked(server, &tl, &target_hint);
479
		if (rc) {
480
			/* Failed to reconnect socket */
481
			cifs_server_unlock(server);
482 483 484
			cifs_dbg(FYI, "%s: reconnect error %d\n", __func__, rc);
			msleep(3000);
			continue;
485
		}
486 487 488 489 490 491 492
		/*
		 * Socket was created.  Update tcp session status to CifsNeedNegotiate so that a
		 * process waiting for reconnect will know it needs to re-establish session and tcon
		 * through the reconnected target server.
		 */
		atomic_inc(&tcpSesReconnectCount);
		set_credits(server, 1);
493
		spin_lock(&server->srv_lock);
494 495
		if (server->tcpStatus != CifsExiting)
			server->tcpStatus = CifsNeedNegotiate;
496
		spin_unlock(&server->srv_lock);
497
		cifs_swn_reset_server_dstaddr(server);
498
		cifs_server_unlock(server);
499
		mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
500 501
	} while (server->tcpStatus == CifsNeedReconnect);

502
	dfs_cache_noreq_update_tgthint(refpath, target_hint);
503 504 505
	dfs_cache_free_tgts(&tl);

	/* Need to set up echo worker again once connection has been established */
506
	spin_lock(&server->srv_lock);
507 508
	if (server->tcpStatus == CifsNeedNegotiate)
		mod_delayed_work(cifsiod_wq, &server->echo, 0);
509
	spin_unlock(&server->srv_lock);
510

511
	wake_up(&server->response_q);
L
Linus Torvalds 已提交
512 513 514
	return rc;
}

515
int cifs_reconnect(struct TCP_Server_Info *server, bool mark_smb_session)
516
{
517
	mutex_lock(&server->refpath_lock);
518
	if (!server->leaf_fullpath) {
519 520 521 522 523
		mutex_unlock(&server->refpath_lock);
		return __cifs_reconnect(server, mark_smb_session);
	}
	mutex_unlock(&server->refpath_lock);

524
	return reconnect_dfs_server(server);
525 526
}
#else
527
int cifs_reconnect(struct TCP_Server_Info *server, bool mark_smb_session)
528
{
529
	return __cifs_reconnect(server, mark_smb_session);
530 531 532
}
#endif

533 534 535 536 537 538 539
static void
cifs_echo_request(struct work_struct *work)
{
	int rc;
	struct TCP_Server_Info *server = container_of(work,
					struct TCP_Server_Info, echo.work);

540
	/*
541 542
	 * We cannot send an echo if it is disabled.
	 * Also, no need to ping if we got a response recently.
543
	 */
544 545

	if (server->tcpStatus == CifsNeedReconnect ||
546 547
	    server->tcpStatus == CifsExiting ||
	    server->tcpStatus == CifsNew ||
548
	    (server->ops->can_echo && !server->ops->can_echo(server)) ||
549
	    time_before(jiffies, server->lstrp + server->echo_interval - HZ))
550 551
		goto requeue_echo;

552
	rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS;
553
	if (rc)
554 555
		cifs_dbg(FYI, "Unable to send echo request to server: %s\n",
			 server->hostname);
556

557 558 559
	/* Check witness registrations */
	cifs_swn_check();

560
requeue_echo:
561
	queue_delayed_work(cifsiod_wq, &server->echo, server->echo_interval);
562 563
}

564
static bool
565
allocate_buffers(struct TCP_Server_Info *server)
566
{
567 568 569
	if (!server->bigbuf) {
		server->bigbuf = (char *)cifs_buf_get();
		if (!server->bigbuf) {
570
			cifs_server_dbg(VFS, "No memory for large SMB response\n");
571 572 573 574
			msleep(3000);
			/* retry will check if exiting */
			return false;
		}
575
	} else if (server->large_buf) {
576
		/* we are reusing a dirty large buf, clear its start */
577
		memset(server->bigbuf, 0, HEADER_SIZE(server));
578 579
	}

580 581 582
	if (!server->smallbuf) {
		server->smallbuf = (char *)cifs_small_buf_get();
		if (!server->smallbuf) {
583
			cifs_server_dbg(VFS, "No memory for SMB response\n");
584 585 586 587 588 589 590
			msleep(1000);
			/* retry will check if exiting */
			return false;
		}
		/* beginning of smb buffer is cleared in our buf_get */
	} else {
		/* if existing small buf clear beginning */
591
		memset(server->smallbuf, 0, HEADER_SIZE(server));
592 593 594 595 596
	}

	return true;
}

597 598 599
static bool
server_unresponsive(struct TCP_Server_Info *server)
{
600
	/*
601
	 * We need to wait 3 echo intervals to make sure we handle such
602 603
	 * situations right:
	 * 1s  client sends a normal SMB request
604
	 * 2s  client gets a response
605 606 607 608 609 610
	 * 30s echo workqueue job pops, and decides we got a response recently
	 *     and don't need to send another
	 * ...
	 * 65s kernel_recvmsg times out, and we see that we haven't gotten
	 *     a response in >60s.
	 */
611
	spin_lock(&server->srv_lock);
612 613
	if ((server->tcpStatus == CifsGood ||
	    server->tcpStatus == CifsNeedNegotiate) &&
614
	    (!server->ops->can_echo || server->ops->can_echo(server)) &&
615
	    time_after(jiffies, server->lstrp + 3 * server->echo_interval)) {
616
		spin_unlock(&server->srv_lock);
617 618
		cifs_server_dbg(VFS, "has not responded in %lu seconds. Reconnecting...\n",
			 (3 * server->echo_interval) / HZ);
619
		cifs_reconnect(server, false);
620 621
		return true;
	}
622
	spin_unlock(&server->srv_lock);
623 624 625 626

	return false;
}

627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
static inline bool
zero_credits(struct TCP_Server_Info *server)
{
	int val;

	spin_lock(&server->req_lock);
	val = server->credits + server->echo_credits + server->oplock_credits;
	if (server->in_flight == 0 && val == 0) {
		spin_unlock(&server->req_lock);
		return true;
	}
	spin_unlock(&server->req_lock);
	return false;
}

642 643
static int
cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
644
{
J
Jeff Layton 已提交
645 646
	int length = 0;
	int total_read;
647

648
	for (total_read = 0; msg_data_left(smb_msg); total_read += length) {
649 650
		try_to_freeze();

651 652
		/* reconnect if no credits and no requests in flight */
		if (zero_credits(server)) {
653
			cifs_reconnect(server, false);
654 655 656
			return -ECONNABORTED;
		}

657 658
		if (server_unresponsive(server))
			return -ECONNABORTED;
659 660 661 662
		if (cifs_rdma_enabled(server) && server->smbd_conn)
			length = smbd_recv(server->smbd_conn, smb_msg);
		else
			length = sock_recvmsg(server->ssocket, smb_msg, 0);
663

664
		spin_lock(&server->srv_lock);
665
		if (server->tcpStatus == CifsExiting) {
666
			spin_unlock(&server->srv_lock);
667
			return -ESHUTDOWN;
668
		}
669

670
		if (server->tcpStatus == CifsNeedReconnect) {
671
			spin_unlock(&server->srv_lock);
672
			cifs_reconnect(server, false);
673 674
			return -ECONNABORTED;
		}
675
		spin_unlock(&server->srv_lock);
676 677 678 679

		if (length == -ERESTARTSYS ||
		    length == -EAGAIN ||
		    length == -EINTR) {
680 681 682 683 684 685 686
			/*
			 * Minimum sleep to prevent looping, allowing socket
			 * to clear and app threads to set tcpStatus
			 * CifsNeedReconnect if server hung.
			 */
			usleep_range(1000, 2000);
			length = 0;
J
Jeff Layton 已提交
687
			continue;
688 689 690
		}

		if (length <= 0) {
691
			cifs_dbg(FYI, "Received no data or error: %d\n", length);
692
			cifs_reconnect(server, false);
693
			return -ECONNABORTED;
694 695
		}
	}
J
Jeff Layton 已提交
696
	return total_read;
697 698
}

J
Jeff Layton 已提交
699 700 701
int
cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
		      unsigned int to_read)
702
{
703
	struct msghdr smb_msg = {};
704
	struct kvec iov = {.iov_base = buf, .iov_len = to_read};
705
	iov_iter_kvec(&smb_msg.msg_iter, ITER_DEST, &iov, 1, to_read);
706

707 708
	return cifs_readv_from_socket(server, &smb_msg);
}
709

710 711 712
ssize_t
cifs_discard_from_socket(struct TCP_Server_Info *server, size_t to_read)
{
713
	struct msghdr smb_msg = {};
714 715 716 717 718 719

	/*
	 *  iov_iter_discard already sets smb_msg.type and count and iov_offset
	 *  and cifs_readv_from_socket sets msg_control and msg_controllen
	 *  so little to initialize in struct msghdr
	 */
720
	iov_iter_discard(&smb_msg.msg_iter, ITER_DEST, to_read);
721 722 723 724

	return cifs_readv_from_socket(server, &smb_msg);
}

725 726
int
cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page,
L
Long Li 已提交
727
	unsigned int page_offset, unsigned int to_read)
728
{
729
	struct msghdr smb_msg = {};
730 731 732
	struct bio_vec bv;

	bvec_set_page(&bv, page, to_read, page_offset);
733
	iov_iter_bvec(&smb_msg.msg_iter, ITER_DEST, &bv, 1, to_read);
734
	return cifs_readv_from_socket(server, &smb_msg);
735 736
}

737 738 739 740 741 742 743 744 745 746 747 748 749 750
int
cifs_read_iter_from_socket(struct TCP_Server_Info *server, struct iov_iter *iter,
			   unsigned int to_read)
{
	struct msghdr smb_msg = { .msg_iter = *iter };
	int ret;

	iov_iter_truncate(&smb_msg.msg_iter, to_read);
	ret = cifs_readv_from_socket(server, &smb_msg);
	if (ret > 0)
		iov_iter_advance(iter, ret);
	return ret;
}

751
static bool
J
Jeff Layton 已提交
752
is_smb_response(struct TCP_Server_Info *server, unsigned char type)
753 754 755 756 757 758
{
	/*
	 * The first byte big endian of the length field,
	 * is actually not part of the length but the type
	 * with the most common, zero, as regular data.
	 */
J
Jeff Layton 已提交
759 760 761 762 763
	switch (type) {
	case RFC1002_SESSION_MESSAGE:
		/* Regular SMB response */
		return true;
	case RFC1002_SESSION_KEEP_ALIVE:
764
		cifs_dbg(FYI, "RFC 1002 session keep alive\n");
J
Jeff Layton 已提交
765 766
		break;
	case RFC1002_POSITIVE_SESSION_RESPONSE:
767
		cifs_dbg(FYI, "RFC 1002 positive session response\n");
J
Jeff Layton 已提交
768 769
		break;
	case RFC1002_NEGATIVE_SESSION_RESPONSE:
770 771 772 773
		/*
		 * We get this from Windows 98 instead of an error on
		 * SMB negprot response.
		 */
774
		cifs_dbg(FYI, "RFC 1002 negative session response\n");
775 776 777 778 779 780 781 782
		/* give server a second to clean up */
		msleep(1000);
		/*
		 * Always try 445 first on reconnect since we get NACK
		 * on some if we ever connected to port 139 (the NACK
		 * is since we do not begin with RFC1001 session
		 * initialize frame).
		 */
J
Jeff Layton 已提交
783
		cifs_set_port((struct sockaddr *)&server->dstaddr, CIFS_PORT);
784
		cifs_reconnect(server, true);
J
Jeff Layton 已提交
785 786
		break;
	default:
787
		cifs_server_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", type);
788
		cifs_reconnect(server, true);
789 790
	}

J
Jeff Layton 已提交
791
	return false;
792 793
}

J
Jeff Layton 已提交
794 795
void
dequeue_mid(struct mid_q_entry *mid, bool malformed)
796
{
797
#ifdef CONFIG_CIFS_STATS2
798
	mid->when_received = jiffies;
799
#endif
800
	spin_lock(&mid->server->mid_lock);
801
	if (!malformed)
802
		mid->mid_state = MID_RESPONSE_RECEIVED;
803
	else
804
		mid->mid_state = MID_RESPONSE_MALFORMED;
805 806 807 808
	/*
	 * Trying to handle/dequeue a mid after the send_recv()
	 * function has finished processing it is a bug.
	 */
809
	if (mid->mid_flags & MID_DELETED) {
810
		spin_unlock(&mid->server->mid_lock);
J
Joe Perches 已提交
811
		pr_warn_once("trying to dequeue a deleted mid\n");
812
	} else {
813
		list_del_init(&mid->qhead);
814
		mid->mid_flags |= MID_DELETED;
815
		spin_unlock(&mid->server->mid_lock);
816
	}
817
}
818

819 820 821
static unsigned int
smb2_get_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
{
822
	struct smb2_hdr *shdr = (struct smb2_hdr *)buffer;
823 824 825 826

	/*
	 * SMB1 does not use credits.
	 */
827
	if (is_smb1(server))
828 829 830 831 832
		return 0;

	return le16_to_cpu(shdr->CreditRequest);
}

833 834
static void
handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server,
835
	   char *buf, int malformed)
836
{
837 838
	if (server->ops->check_trans2 &&
	    server->ops->check_trans2(mid, server, buf, malformed))
839
		return;
840
	mid->credits_received = smb2_get_credits_from_hdr(buf, server);
841
	mid->resp_buf = buf;
842
	mid->large_buf = server->large_buf;
843 844 845 846 847 848 849 850
	/* Was previous buf put in mpx struct for multi-rsp? */
	if (!mid->multiRsp) {
		/* smb buffer will be freed by user thread */
		if (server->large_buf)
			server->bigbuf = NULL;
		else
			server->smallbuf = NULL;
	}
851
	dequeue_mid(mid, malformed);
852 853
}

854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900
int
cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
{
	bool srv_sign_required = server->sec_mode & server->vals->signing_required;
	bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled;
	bool mnt_sign_enabled;

	/*
	 * Is signing required by mnt options? If not then check
	 * global_secflags to see if it is there.
	 */
	if (!mnt_sign_required)
		mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) ==
						CIFSSEC_MUST_SIGN);

	/*
	 * If signing is required then it's automatically enabled too,
	 * otherwise, check to see if the secflags allow it.
	 */
	mnt_sign_enabled = mnt_sign_required ? mnt_sign_required :
				(global_secflags & CIFSSEC_MAY_SIGN);

	/* If server requires signing, does client allow it? */
	if (srv_sign_required) {
		if (!mnt_sign_enabled) {
			cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n");
			return -EOPNOTSUPP;
		}
		server->sign = true;
	}

	/* If client requires signing, does server allow it? */
	if (mnt_sign_required) {
		if (!srv_sign_enabled) {
			cifs_dbg(VFS, "Server does not support signing!\n");
			return -EOPNOTSUPP;
		}
		server->sign = true;
	}

	if (cifs_rdma_enabled(server) && server->sign)
		cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n");

	return 0;
}


901 902 903 904 905
static void clean_demultiplex_info(struct TCP_Server_Info *server)
{
	int length;

	/* take it off the list, if it's not already */
906
	spin_lock(&server->srv_lock);
907
	list_del_init(&server->tcp_ses_list);
908
	spin_unlock(&server->srv_lock);
909

910 911
	cancel_delayed_work_sync(&server->echo);

912
	spin_lock(&server->srv_lock);
913
	server->tcpStatus = CifsExiting;
914
	spin_unlock(&server->srv_lock);
915 916
	wake_up_all(&server->response_q);

917
	/* check if we have blocked requests that need to free */
P
Pavel Shilovsky 已提交
918
	spin_lock(&server->req_lock);
919 920
	if (server->credits <= 0)
		server->credits = 1;
P
Pavel Shilovsky 已提交
921
	spin_unlock(&server->req_lock);
922 923 924 925 926 927 928 929 930 931
	/*
	 * Although there should not be any requests blocked on this queue it
	 * can not hurt to be paranoid and try to wake up requests that may
	 * haven been blocked when more than 50 at time were on the wire to the
	 * same server - they now will see the session is in exit state and get
	 * out of SendReceive.
	 */
	wake_up_all(&server->request_q);
	/* give those requests time to exit */
	msleep(125);
932 933
	if (cifs_rdma_enabled(server))
		smbd_destroy(server);
934 935 936 937 938 939 940 941 942 943 944
	if (server->ssocket) {
		sock_release(server->ssocket);
		server->ssocket = NULL;
	}

	if (!list_empty(&server->pending_mid_q)) {
		struct list_head dispose_list;
		struct mid_q_entry *mid_entry;
		struct list_head *tmp, *tmp2;

		INIT_LIST_HEAD(&dispose_list);
945
		spin_lock(&server->mid_lock);
946 947
		list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
948
			cifs_dbg(FYI, "Clearing mid %llu\n", mid_entry->mid);
949
			kref_get(&mid_entry->refcount);
950
			mid_entry->mid_state = MID_SHUTDOWN;
951
			list_move(&mid_entry->qhead, &dispose_list);
952
			mid_entry->mid_flags |= MID_DELETED;
953
		}
954
		spin_unlock(&server->mid_lock);
955 956 957 958

		/* now walk dispose list and issue callbacks */
		list_for_each_safe(tmp, tmp2, &dispose_list) {
			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
959
			cifs_dbg(FYI, "Callback mid %llu\n", mid_entry->mid);
960 961
			list_del_init(&mid_entry->qhead);
			mid_entry->callback(mid_entry);
962
			release_mid(mid_entry);
963 964 965 966 967 968 969 970 971 972 973 974 975 976
		}
		/* 1/8th of sec is more than enough time for them to exit */
		msleep(125);
	}

	if (!list_empty(&server->pending_mid_q)) {
		/*
		 * mpx threads have not exited yet give them at least the smb
		 * send timeout time for long ops.
		 *
		 * Due to delays on oplock break requests, we need to wait at
		 * least 45 seconds before giving up on a request getting a
		 * response and going ahead and killing cifsd.
		 */
977
		cifs_dbg(FYI, "Wait for exit from demultiplex thread\n");
978 979 980 981 982 983 984
		msleep(46000);
		/*
		 * If threads still have not exited they are probably never
		 * coming home not much else we can do but free the memory.
		 */
	}

985 986 987 988
#ifdef CONFIG_CIFS_DFS_UPCALL
	kfree(server->origin_fullpath);
	kfree(server->leaf_fullpath);
#endif
989 990 991 992
	kfree(server);

	length = atomic_dec_return(&tcpSesAllocCount);
	if (length > 0)
993
		mempool_resize(cifs_req_poolp, length + cifs_min_rcv);
994 995
}

996 997 998 999 1000
static int
standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
{
	int length;
	char *buf = server->smallbuf;
1001
	unsigned int pdu_length = server->pdu_size;
1002 1003

	/* make sure this will fit in a large buffer */
1004
	if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) -
1005
	    HEADER_PREAMBLE_SIZE(server)) {
1006
		cifs_server_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length);
1007
		cifs_reconnect(server, true);
1008
		return -ECONNABORTED;
1009 1010 1011 1012 1013
	}

	/* switch to large buffer if too big for a small one */
	if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
		server->large_buf = true;
1014
		memcpy(server->bigbuf, buf, server->total_read);
1015 1016 1017 1018
		buf = server->bigbuf;
	}

	/* now read the rest */
1019
	length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1,
1020
				       pdu_length - MID_HEADER_SIZE(server));
1021

1022 1023 1024 1025
	if (length < 0)
		return length;
	server->total_read += length;

1026
	dump_smb(buf, server->total_read);
1027

1028 1029 1030 1031 1032 1033 1034
	return cifs_handle_standard(server, mid);
}

int
cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
{
	char *buf = server->large_buf ? server->bigbuf : server->smallbuf;
1035
	int rc;
1036

1037 1038 1039
	/*
	 * We know that we received enough to get to the MID as we
	 * checked the pdu_length earlier. Now check to see
1040
	 * if the rest of the header is OK.
1041 1042 1043 1044
	 *
	 * 48 bytes is enough to display the header and a little bit
	 * into the payload for debugging purposes.
	 */
1045 1046
	rc = server->ops->check_message(buf, server->total_read, server);
	if (rc)
1047 1048 1049
		cifs_dump_mem("Bad SMB: ", buf,
			min_t(unsigned int, server->total_read, 48));

1050 1051
	if (server->ops->is_session_expired &&
	    server->ops->is_session_expired(buf)) {
1052
		cifs_reconnect(server, true);
1053 1054 1055
		return -1;
	}

P
Pavel Shilovsky 已提交
1056
	if (server->ops->is_status_pending &&
1057
	    server->ops->is_status_pending(buf, server))
P
Pavel Shilovsky 已提交
1058 1059
		return -1;

1060
	if (!mid)
1061
		return rc;
1062

1063
	handle_mid(mid, server, buf, rc);
1064
	return 0;
1065 1066
}

1067 1068 1069
static void
smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
{
1070
	struct smb2_hdr *shdr = (struct smb2_hdr *)buffer;
1071
	int scredits, in_flight;
1072 1073 1074 1075

	/*
	 * SMB1 does not use credits.
	 */
1076
	if (is_smb1(server))
1077 1078 1079 1080 1081
		return;

	if (shdr->CreditRequest) {
		spin_lock(&server->req_lock);
		server->credits += le16_to_cpu(shdr->CreditRequest);
1082 1083
		scredits = server->credits;
		in_flight = server->in_flight;
1084 1085
		spin_unlock(&server->req_lock);
		wake_up(&server->request_q);
1086

1087
		trace_smb3_hdr_credits(server->CurrentMid,
1088 1089
				server->conn_id, server->hostname, scredits,
				le16_to_cpu(shdr->CreditRequest), in_flight);
1090 1091 1092
		cifs_server_dbg(FYI, "%s: added %u credits total=%d\n",
				__func__, le16_to_cpu(shdr->CreditRequest),
				scredits);
1093 1094 1095 1096
	}
}


L
Linus Torvalds 已提交
1097
static int
1098
cifs_demultiplex_thread(void *p)
L
Linus Torvalds 已提交
1099
{
1100
	int i, num_mids, length;
1101
	struct TCP_Server_Info *server = p;
1102
	unsigned int pdu_length;
1103
	unsigned int next_offset;
1104
	char *buf = NULL;
1105
	struct task_struct *task_to_wake = NULL;
1106 1107
	struct mid_q_entry *mids[MAX_COMPOUND];
	char *bufs[MAX_COMPOUND];
1108
	unsigned int noreclaim_flag, num_io_timeout = 0;
L
Linus Torvalds 已提交
1109

1110
	noreclaim_flag = memalloc_noreclaim_save();
1111
	cifs_dbg(FYI, "Demultiplex PID: %d\n", task_pid_nr(current));
1112 1113 1114

	length = atomic_inc_return(&tcpSesAllocCount);
	if (length > 1)
1115
		mempool_resize(cifs_req_poolp, length + cifs_min_rcv);
L
Linus Torvalds 已提交
1116

1117
	set_freezable();
1118
	allow_kernel_signal(SIGKILL);
1119
	while (server->tcpStatus != CifsExiting) {
1120 1121
		if (try_to_freeze())
			continue;
1122

1123
		if (!allocate_buffers(server))
1124
			continue;
1125

1126 1127
		server->large_buf = false;
		buf = server->smallbuf;
1128
		pdu_length = 4; /* enough to get RFC1001 header */
1129

J
Jeff Layton 已提交
1130
		length = cifs_read_from_socket(server, buf, pdu_length);
J
Jeff Layton 已提交
1131
		if (length < 0)
L
Linus Torvalds 已提交
1132
			continue;
1133

1134
		if (is_smb1(server))
1135
			server->total_read = length;
1136 1137
		else
			server->total_read = 0;
L
Linus Torvalds 已提交
1138

1139 1140 1141 1142
		/*
		 * The right amount was read from socket - 4 bytes,
		 * so we can now interpret the length field.
		 */
1143
		pdu_length = get_rfc1002_length(buf);
1144

1145
		cifs_dbg(FYI, "RFC1002 header 0x%x\n", pdu_length);
J
Jeff Layton 已提交
1146
		if (!is_smb_response(server, buf[0]))
S
Steve French 已提交
1147
			continue;
1148 1149
next_pdu:
		server->pdu_size = pdu_length;
1150

1151
		/* make sure we have enough to get to the MID */
1152
		if (server->pdu_size < MID_HEADER_SIZE(server)) {
1153
			cifs_server_dbg(VFS, "SMB response too short (%u bytes)\n",
1154
				 server->pdu_size);
1155
			cifs_reconnect(server, true);
1156
			continue;
1157
		}
1158

1159
		/* read down to the MID */
1160
		length = cifs_read_from_socket(server,
1161
			     buf + HEADER_PREAMBLE_SIZE(server),
1162
			     MID_HEADER_SIZE(server));
1163
		if (length < 0)
1164
			continue;
1165
		server->total_read += length;
L
Linus Torvalds 已提交
1166

1167 1168 1169 1170 1171 1172
		if (server->ops->next_header) {
			next_offset = server->ops->next_header(buf);
			if (next_offset)
				server->pdu_size = next_offset;
		}

1173 1174 1175 1176
		memset(mids, 0, sizeof(mids));
		memset(bufs, 0, sizeof(bufs));
		num_mids = 0;

1177 1178 1179 1180
		if (server->ops->is_transform_hdr &&
		    server->ops->receive_transform &&
		    server->ops->is_transform_hdr(buf)) {
			length = server->ops->receive_transform(server,
1181 1182 1183
								mids,
								bufs,
								&num_mids);
1184
		} else {
1185 1186
			mids[0] = server->ops->find_mid(server, buf);
			bufs[0] = buf;
1187
			num_mids = 1;
1188

1189 1190
			if (!mids[0] || !mids[0]->receive)
				length = standard_receive3(server, mids[0]);
1191
			else
1192
				length = mids[0]->receive(server, mids[0]);
1193
		}
1194

1195
		if (length < 0) {
1196 1197
			for (i = 0; i < num_mids; i++)
				if (mids[i])
1198
					release_mid(mids[i]);
J
Jeff Layton 已提交
1199
			continue;
1200
		}
L
Linus Torvalds 已提交
1201

1202 1203 1204 1205
		if (server->ops->is_status_io_timeout &&
		    server->ops->is_status_io_timeout(buf)) {
			num_io_timeout++;
			if (num_io_timeout > NUM_STATUS_IO_TIMEOUT) {
1206
				cifs_reconnect(server, false);
1207 1208 1209 1210 1211
				num_io_timeout = 0;
				continue;
			}
		}

1212
		server->lstrp = jiffies;
S
Sachin Prabhu 已提交
1213

1214 1215 1216
		for (i = 0; i < num_mids; i++) {
			if (mids[i] != NULL) {
				mids[i]->resp_buf_size = server->pdu_size;
1217

1218 1219 1220 1221
				if (bufs[i] && server->ops->is_network_name_deleted)
					server->ops->is_network_name_deleted(bufs[i],
									server);

1222 1223 1224
				if (!mids[i]->multiRsp || mids[i]->multiEnd)
					mids[i]->callback(mids[i]);

1225
				release_mid(mids[i]);
1226 1227 1228
			} else if (server->ops->is_oplock_break &&
				   server->ops->is_oplock_break(bufs[i],
								server)) {
1229
				smb2_add_credits_from_hdr(bufs[i], server);
1230 1231
				cifs_dbg(FYI, "Received oplock break\n");
			} else {
J
Joe Perches 已提交
1232
				cifs_server_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n",
1233
						atomic_read(&mid_count));
1234 1235
				cifs_dump_mem("Received Data is: ", bufs[i],
					      HEADER_SIZE(server));
1236
				smb2_add_credits_from_hdr(bufs[i], server);
1237
#ifdef CONFIG_CIFS_DEBUG2
1238 1239 1240 1241
				if (server->ops->dump_detail)
					server->ops->dump_detail(bufs[i],
								 server);
				cifs_dump_mids(server);
1242
#endif /* CIFS_DEBUG2 */
1243
			}
1244
		}
1245

1246 1247 1248 1249 1250 1251 1252 1253
		if (pdu_length > server->pdu_size) {
			if (!allocate_buffers(server))
				continue;
			pdu_length -= server->pdu_size;
			server->total_read = 0;
			server->large_buf = false;
			buf = server->smallbuf;
			goto next_pdu;
1254 1255 1256
		}
	} /* end while !EXITING */

1257
	/* buffer usually freed in free_mid - need to free it here on exit */
1258 1259 1260
	cifs_buf_release(server->bigbuf);
	if (server->smallbuf) /* no sense logging a debug message if NULL */
		cifs_small_buf_release(server->smallbuf);
L
Linus Torvalds 已提交
1261

1262
	task_to_wake = xchg(&server->tsk, NULL);
1263
	clean_demultiplex_info(server);
1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274

	/* if server->tsk was NULL then wait for a signal before exiting */
	if (!task_to_wake) {
		set_current_state(TASK_INTERRUPTIBLE);
		while (!signal_pending(current)) {
			schedule();
			set_current_state(TASK_INTERRUPTIBLE);
		}
		set_current_state(TASK_RUNNING);
	}

1275
	memalloc_noreclaim_restore(noreclaim_flag);
1276
	module_put_and_kthread_exit(0);
L
Linus Torvalds 已提交
1277 1278
}

1279
/*
1280 1281
 * Returns true if srcaddr isn't specified and rhs isn't specified, or
 * if srcaddr is specified and matches the IP address of the rhs argument
1282
 */
1283 1284
bool
cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs)
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295
{
	switch (srcaddr->sa_family) {
	case AF_UNSPEC:
		return (rhs->sa_family == AF_UNSPEC);
	case AF_INET: {
		struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
		struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
		return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
	}
	case AF_INET6: {
		struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
1296
		struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)rhs;
1297 1298
		return (ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr)
			&& saddr6->sin6_scope_id == vaddr6->sin6_scope_id);
1299 1300 1301 1302 1303 1304 1305
	}
	default:
		WARN_ON(1);
		return false; /* don't expect to be here */
	}
}

1306 1307 1308 1309 1310 1311 1312 1313
/*
 * If no port is specified in addr structure, we try to match with 445 port
 * and if it fails - with 139 ports. It should be called only if address
 * families of server and addr are equal.
 */
static bool
match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
{
1314
	__be16 port, *sport;
1315

1316 1317 1318 1319
	/* SMBDirect manages its own ports, don't match it here */
	if (server->rdma)
		return true;

1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343
	switch (addr->sa_family) {
	case AF_INET:
		sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
		port = ((struct sockaddr_in *) addr)->sin_port;
		break;
	case AF_INET6:
		sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port;
		port = ((struct sockaddr_in6 *) addr)->sin6_port;
		break;
	default:
		WARN_ON(1);
		return false;
	}

	if (!port) {
		port = htons(CIFS_PORT);
		if (port == *sport)
			return true;

		port = htons(RFC1001_PORT);
	}

	return port == *sport;
}
1344

1345
static bool match_server_address(struct TCP_Server_Info *server, struct sockaddr *addr)
1346
{
1347 1348
	if (!cifs_match_ipaddr(addr, (struct sockaddr *)&server->dstaddr))
		return false;
1349 1350 1351 1352

	return true;
}

1353
static bool
1354
match_security(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
1355
{
1356
	/*
1357
	 * The select_sectype function should either return the ctx->sectype
1358 1359 1360
	 * that was specified, or "Unspecified" if that sectype was not
	 * compatible with the given NEGOTIATE request.
	 */
1361
	if (server->ops->select_sectype(server, ctx->sectype)
S
Sachin Prabhu 已提交
1362
	     == Unspecified)
1363 1364
		return false;

1365 1366 1367 1368 1369
	/*
	 * Now check if signing mode is acceptable. No need to check
	 * global_secflags at this point since if MUST_SIGN is set then
	 * the server->sign had better be too.
	 */
1370
	if (ctx->sign && !server->sign)
1371
		return false;
1372 1373 1374 1375

	return true;
}

1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389
static bool dfs_src_pathname_equal(const char *s1, const char *s2)
{
	if (strlen(s1) != strlen(s2))
		return false;
	for (; *s1; s1++, s2++) {
		if (*s1 == '/' || *s1 == '\\') {
			if (*s2 != '/' && *s2 != '\\')
				return false;
		} else if (tolower(*s1) != tolower(*s2))
			return false;
	}
	return true;
}

1390
/* this function must be called with srv_lock held */
1391 1392
static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *ctx,
			bool dfs_super_cmp)
1393
{
1394
	struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;
1395

1396
	if (ctx->nosharesock)
1397 1398 1399 1400
		return 0;

	/* this server does not share socket */
	if (server->nosharesock)
1401 1402
		return 0;

1403
	/* If multidialect negotiation see if existing sessions match one */
1404
	if (strcmp(ctx->vals->version_string, SMB3ANY_VERSION_STRING) == 0) {
1405 1406
		if (server->vals->protocol_id < SMB30_PROT_ID)
			return 0;
1407
	} else if (strcmp(ctx->vals->version_string,
1408 1409 1410
		   SMBDEFAULT_VERSION_STRING) == 0) {
		if (server->vals->protocol_id < SMB21_PROT_ID)
			return 0;
1411
	} else if ((server->vals != ctx->vals) || (server->ops != ctx->ops))
1412 1413
		return 0;

1414 1415 1416
	if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
		return 0;

1417 1418
	if (!cifs_match_ipaddr((struct sockaddr *)&ctx->srcaddr,
			       (struct sockaddr *)&server->srcaddr))
1419
		return 0;
1420 1421 1422 1423 1424 1425 1426
	/*
	 * When matching DFS superblocks, we only check for original source pathname as the
	 * currently connected target might be different than the one parsed earlier in i.e.
	 * mount.cifs(8).
	 */
	if (dfs_super_cmp) {
		if (!ctx->source || !server->origin_fullpath ||
1427
		    !dfs_src_pathname_equal(server->origin_fullpath, ctx->source))
1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440
			return 0;
	} else {
		/* Skip addr, hostname and port matching for DFS connections */
		if (server->leaf_fullpath) {
			if (!ctx->leaf_fullpath ||
			    strcasecmp(server->leaf_fullpath, ctx->leaf_fullpath))
				return 0;
		} else if (strcasecmp(server->hostname, ctx->server_hostname) ||
			   !match_server_address(server, addr) ||
			   !match_port(server, addr)) {
			return 0;
		}
	}
1441

1442
	if (!match_security(server, ctx))
1443 1444
		return 0;

1445
	if (server->echo_interval != ctx->echo_interval * HZ)
S
Steve French 已提交
1446 1447
		return 0;

1448
	if (server->rdma != ctx->rdma)
L
Long Li 已提交
1449 1450
		return 0;

1451
	if (server->ignore_signature != ctx->ignore_signature)
1452 1453
		return 0;

1454
	if (server->min_offload != ctx->min_offload)
1455 1456
		return 0;

1457 1458 1459
	return 1;
}

P
Paulo Alcantara 已提交
1460
struct TCP_Server_Info *
1461
cifs_find_tcp_session(struct smb3_fs_context *ctx)
L
Linus Torvalds 已提交
1462
{
1463 1464
	struct TCP_Server_Info *server;

1465
	spin_lock(&cifs_tcp_ses_lock);
1466
	list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1467
		spin_lock(&server->srv_lock);
1468 1469 1470 1471
		/*
		 * Skip ses channels since they're only handled in lower layers
		 * (e.g. cifs_send_recv).
		 */
1472
		if (CIFS_SERVER_IS_CHAN(server) || !match_server(server, ctx, false)) {
1473
			spin_unlock(&server->srv_lock);
1474
			continue;
1475 1476
		}
		spin_unlock(&server->srv_lock);
1477

1478
		++server->srv_count;
1479
		spin_unlock(&cifs_tcp_ses_lock);
1480
		cifs_dbg(FYI, "Existing tcp session with server found\n");
1481
		return server;
L
Linus Torvalds 已提交
1482
	}
1483
	spin_unlock(&cifs_tcp_ses_lock);
L
Linus Torvalds 已提交
1484 1485
	return NULL;
}
1486

1487 1488
void
cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
L
Linus Torvalds 已提交
1489
{
1490 1491
	struct task_struct *task;

1492
	spin_lock(&cifs_tcp_ses_lock);
1493
	if (--server->srv_count > 0) {
1494
		spin_unlock(&cifs_tcp_ses_lock);
1495
		return;
L
Linus Torvalds 已提交
1496
	}
1497

1498 1499 1500
	/* srv_count can never go negative */
	WARN_ON(server->srv_count < 0);

1501 1502
	put_net(cifs_net_ns(server));

1503
	list_del_init(&server->tcp_ses_list);
1504
	spin_unlock(&cifs_tcp_ses_lock);
1505

1506 1507 1508 1509
	/* For secondary channels, we pick up ref-count on the primary server */
	if (CIFS_SERVER_IS_CHAN(server))
		cifs_put_tcp_session(server->primary_server, from_reconnect);

1510 1511
	cancel_delayed_work_sync(&server->echo);

1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522
	if (from_reconnect)
		/*
		 * Avoid deadlock here: reconnect work calls
		 * cifs_put_tcp_session() at its end. Need to be sure
		 * that reconnect work does nothing with server pointer after
		 * that step.
		 */
		cancel_delayed_work(&server->reconnect);
	else
		cancel_delayed_work_sync(&server->reconnect);

1523
	spin_lock(&server->srv_lock);
1524
	server->tcpStatus = CifsExiting;
1525
	spin_unlock(&server->srv_lock);
1526

1527
	cifs_crypto_secmech_release(server);
1528

1529
	kfree_sensitive(server->session_key.response);
1530 1531
	server->session_key.response = NULL;
	server->session_key.len = 0;
1532
	kfree(server->hostname);
1533
	server->hostname = NULL;
1534 1535 1536

	task = xchg(&server->tsk, NULL);
	if (task)
1537
		send_sig(SIGKILL, task, 1);
L
Linus Torvalds 已提交
1538 1539
}

1540
struct TCP_Server_Info *
1541 1542
cifs_get_tcp_session(struct smb3_fs_context *ctx,
		     struct TCP_Server_Info *primary_server)
1543 1544 1545 1546
{
	struct TCP_Server_Info *tcp_ses = NULL;
	int rc;

1547
	cifs_dbg(FYI, "UNC: %s\n", ctx->UNC);
1548 1549

	/* see if we already have a matching tcp_ses */
1550
	tcp_ses = cifs_find_tcp_session(ctx);
1551 1552 1553 1554 1555 1556 1557 1558 1559
	if (tcp_ses)
		return tcp_ses;

	tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
	if (!tcp_ses) {
		rc = -ENOMEM;
		goto out_err;
	}

1560 1561 1562 1563 1564 1565
	tcp_ses->hostname = kstrdup(ctx->server_hostname, GFP_KERNEL);
	if (!tcp_ses->hostname) {
		rc = -ENOMEM;
		goto out_err;
	}

1566 1567 1568 1569 1570 1571 1572 1573 1574
	if (ctx->leaf_fullpath) {
		tcp_ses->leaf_fullpath = kstrdup(ctx->leaf_fullpath, GFP_KERNEL);
		if (!tcp_ses->leaf_fullpath) {
			rc = -ENOMEM;
			goto out_err;
		}
		tcp_ses->current_fullpath = tcp_ses->leaf_fullpath;
	}

1575 1576 1577
	if (ctx->nosharesock)
		tcp_ses->nosharesock = true;

1578 1579
	tcp_ses->ops = ctx->ops;
	tcp_ses->vals = ctx->vals;
1580
	cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
1581

1582
	tcp_ses->conn_id = atomic_inc_return(&tcpSesNextId);
1583 1584 1585 1586 1587
	tcp_ses->noblockcnt = ctx->rootfs;
	tcp_ses->noblocksnd = ctx->noblocksnd || ctx->rootfs;
	tcp_ses->noautotune = ctx->noautotune;
	tcp_ses->tcp_nodelay = ctx->sockopt_tcp_nodelay;
	tcp_ses->rdma = ctx->rdma;
P
Pavel Shilovsky 已提交
1588
	tcp_ses->in_flight = 0;
1589
	tcp_ses->max_in_flight = 0;
1590
	tcp_ses->credits = 1;
1591
	if (primary_server) {
1592
		spin_lock(&cifs_tcp_ses_lock);
1593
		++primary_server->srv_count;
1594
		spin_unlock(&cifs_tcp_ses_lock);
1595
		tcp_ses->primary_server = primary_server;
1596
	}
1597 1598 1599
	init_waitqueue_head(&tcp_ses->response_q);
	init_waitqueue_head(&tcp_ses->request_q);
	INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
1600
	mutex_init(&tcp_ses->_srv_mutex);
1601
	memcpy(tcp_ses->workstation_RFC1001_name,
1602
		ctx->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1603
	memcpy(tcp_ses->server_RFC1001_name,
1604
		ctx->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1605
	tcp_ses->session_estab = false;
1606
	tcp_ses->sequence_number = 0;
1607
	tcp_ses->reconnect_instance = 1;
1608
	tcp_ses->lstrp = jiffies;
1609
	tcp_ses->compress_algorithm = cpu_to_le16(ctx->compression);
1610
	spin_lock_init(&tcp_ses->req_lock);
1611 1612
	spin_lock_init(&tcp_ses->srv_lock);
	spin_lock_init(&tcp_ses->mid_lock);
1613 1614
	INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
	INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1615
	INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
1616 1617
	INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server);
	mutex_init(&tcp_ses->reconnect_mutex);
1618 1619 1620
#ifdef CONFIG_CIFS_DFS_UPCALL
	mutex_init(&tcp_ses->refpath_lock);
#endif
1621
	memcpy(&tcp_ses->srcaddr, &ctx->srcaddr,
1622
	       sizeof(tcp_ses->srcaddr));
1623
	memcpy(&tcp_ses->dstaddr, &ctx->dstaddr,
1624
		sizeof(tcp_ses->dstaddr));
1625 1626
	if (ctx->use_client_guid)
		memcpy(tcp_ses->client_guid, ctx->client_guid,
1627 1628 1629
		       SMB2_CLIENT_GUID_SIZE);
	else
		generate_random_uuid(tcp_ses->client_guid);
1630 1631 1632 1633 1634 1635 1636 1637
	/*
	 * at this point we are the only ones with the pointer
	 * to the struct since the kernel thread not created yet
	 * no need to spinlock this init of tcpStatus or srv_count
	 */
	tcp_ses->tcpStatus = CifsNew;
	++tcp_ses->srv_count;

1638 1639 1640
	if (ctx->echo_interval >= SMB_ECHO_INTERVAL_MIN &&
		ctx->echo_interval <= SMB_ECHO_INTERVAL_MAX)
		tcp_ses->echo_interval = ctx->echo_interval * HZ;
S
Steve French 已提交
1641 1642
	else
		tcp_ses->echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ;
1643 1644 1645 1646 1647 1648 1649
	if (tcp_ses->rdma) {
#ifndef CONFIG_CIFS_SMB_DIRECT
		cifs_dbg(VFS, "CONFIG_CIFS_SMB_DIRECT is not enabled\n");
		rc = -ENOENT;
		goto out_err_crypto_release;
#endif
		tcp_ses->smbd_conn = smbd_get_connection(
1650
			tcp_ses, (struct sockaddr *)&ctx->dstaddr);
1651 1652 1653 1654 1655 1656 1657 1658 1659
		if (tcp_ses->smbd_conn) {
			cifs_dbg(VFS, "RDMA transport established\n");
			rc = 0;
			goto smbd_connected;
		} else {
			rc = -ENOENT;
			goto out_err_crypto_release;
		}
	}
1660
	rc = ip_connect(tcp_ses);
1661
	if (rc < 0) {
1662
		cifs_dbg(VFS, "Error connecting to socket. Aborting operation.\n");
1663
		goto out_err_crypto_release;
1664
	}
1665
smbd_connected:
1666 1667 1668 1669 1670
	/*
	 * since we're in a cifs function already, we know that
	 * this will succeed. No need for try_module_get().
	 */
	__module_get(THIS_MODULE);
1671
	tcp_ses->tsk = kthread_run(cifs_demultiplex_thread,
1672 1673 1674
				  tcp_ses, "cifsd");
	if (IS_ERR(tcp_ses->tsk)) {
		rc = PTR_ERR(tcp_ses->tsk);
1675
		cifs_dbg(VFS, "error %d create cifsd thread\n", rc);
1676
		module_put(THIS_MODULE);
1677
		goto out_err_crypto_release;
1678
	}
1679
	tcp_ses->min_offload = ctx->min_offload;
1680 1681 1682 1683 1684
	/*
	 * at this point we are the only ones with the pointer
	 * to the struct since the kernel thread not created yet
	 * no need to spinlock this update of tcpStatus
	 */
1685
	spin_lock(&tcp_ses->srv_lock);
1686
	tcp_ses->tcpStatus = CifsNeedNegotiate;
1687
	spin_unlock(&tcp_ses->srv_lock);
1688

1689 1690 1691 1692 1693
	if ((ctx->max_credits < 20) || (ctx->max_credits > 60000))
		tcp_ses->max_credits = SMB2_MAX_CREDITS_AVAILABLE;
	else
		tcp_ses->max_credits = ctx->max_credits;

1694
	tcp_ses->nr_targets = 1;
1695
	tcp_ses->ignore_signature = ctx->ignore_signature;
1696
	/* thread spawned, put it on the list */
1697
	spin_lock(&cifs_tcp_ses_lock);
1698
	list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1699
	spin_unlock(&cifs_tcp_ses_lock);
1700

1701
	/* queue echo request delayed work */
S
Steve French 已提交
1702
	queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval);
1703

1704 1705
	return tcp_ses;

1706
out_err_crypto_release:
1707
	cifs_crypto_secmech_release(tcp_ses);
1708

1709 1710
	put_net(cifs_net_ns(tcp_ses));

1711 1712
out_err:
	if (tcp_ses) {
1713 1714
		if (CIFS_SERVER_IS_CHAN(tcp_ses))
			cifs_put_tcp_session(tcp_ses->primary_server, false);
1715
		kfree(tcp_ses->hostname);
1716
		kfree(tcp_ses->leaf_fullpath);
1717 1718 1719 1720 1721 1722 1723
		if (tcp_ses->ssocket)
			sock_release(tcp_ses->ssocket);
		kfree(tcp_ses);
	}
	return ERR_PTR(rc);
}

1724
/* this function must be called with ses_lock held */
1725
static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
1726
{
1727 1728
	if (ctx->sectype != Unspecified &&
	    ctx->sectype != ses->sectype)
1729 1730
		return 0;

1731 1732 1733 1734
	/*
	 * If an existing session is limited to less channels than
	 * requested, it should not be reused
	 */
1735 1736 1737
	spin_lock(&ses->chan_lock);
	if (ses->chan_max < ctx->max_channels) {
		spin_unlock(&ses->chan_lock);
1738
		return 0;
1739 1740
	}
	spin_unlock(&ses->chan_lock);
1741

1742
	switch (ses->sectype) {
1743
	case Kerberos:
1744
		if (!uid_eq(ctx->cred_uid, ses->cred_uid))
1745 1746 1747
			return 0;
		break;
	default:
J
Jeff Layton 已提交
1748 1749
		/* NULL username means anonymous session */
		if (ses->user_name == NULL) {
1750
			if (!ctx->nullauth)
J
Jeff Layton 已提交
1751 1752 1753 1754
				return 0;
			break;
		}

1755
		/* anything else takes username/password */
J
Jeff Layton 已提交
1756
		if (strncmp(ses->user_name,
1757
			    ctx->username ? ctx->username : "",
1758
			    CIFS_MAX_USERNAME_LEN))
1759
			return 0;
1760
		if ((ctx->username && strlen(ctx->username) != 0) &&
1761 1762
		    ses->password != NULL &&
		    strncmp(ses->password,
1763
			    ctx->password ? ctx->password : "",
1764
			    CIFS_MAX_PASSWORD_LEN))
1765 1766 1767 1768 1769
			return 0;
	}
	return 1;
}

A
Aurelien Aptel 已提交
1770 1771
/**
 * cifs_setup_ipc - helper to setup the IPC tcon for the session
1772 1773 1774
 * @ses: smb session to issue the request on
 * @ctx: the superblock configuration context to use for building the
 *       new tree connection for the IPC (interprocess communication RPC)
A
Aurelien Aptel 已提交
1775 1776 1777 1778 1779
 *
 * A new IPC connection is made and stored in the session
 * tcon_ipc. The IPC tcon has the same lifetime as the session.
 */
static int
1780
cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)
A
Aurelien Aptel 已提交
1781 1782 1783 1784 1785
{
	int rc = 0, xid;
	struct cifs_tcon *tcon;
	char unc[SERVER_NAME_LENGTH + sizeof("//x/IPC$")] = {0};
	bool seal = false;
1786
	struct TCP_Server_Info *server = ses->server;
A
Aurelien Aptel 已提交
1787 1788 1789 1790 1791

	/*
	 * If the mount request that resulted in the creation of the
	 * session requires encryption, force IPC to be encrypted too.
	 */
1792
	if (ctx->seal) {
1793
		if (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)
A
Aurelien Aptel 已提交
1794 1795
			seal = true;
		else {
1796
			cifs_server_dbg(VFS,
A
Aurelien Aptel 已提交
1797 1798 1799 1800 1801 1802 1803 1804 1805
				 "IPC: server doesn't support encryption\n");
			return -EOPNOTSUPP;
		}
	}

	tcon = tconInfoAlloc();
	if (tcon == NULL)
		return -ENOMEM;

1806
	scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", server->hostname);
A
Aurelien Aptel 已提交
1807 1808 1809 1810 1811

	xid = get_xid();
	tcon->ses = ses;
	tcon->ipc = true;
	tcon->seal = seal;
1812
	rc = server->ops->tree_connect(xid, ses, unc, tcon, ctx->local_nls);
A
Aurelien Aptel 已提交
1813 1814 1815
	free_xid(xid);

	if (rc) {
1816
		cifs_server_dbg(VFS, "failed to connect to IPC (rc=%d)\n", rc);
A
Aurelien Aptel 已提交
1817 1818 1819 1820
		tconInfoFree(tcon);
		goto out;
	}

E
Enzo Matsumiya 已提交
1821
	cifs_dbg(FYI, "IPC tcon rc=%d ipc tid=0x%x\n", rc, tcon->tid);
A
Aurelien Aptel 已提交
1822

1823 1824 1825
	spin_lock(&tcon->tc_lock);
	tcon->status = TID_GOOD;
	spin_unlock(&tcon->tc_lock);
A
Aurelien Aptel 已提交
1826 1827 1828 1829 1830 1831 1832
	ses->tcon_ipc = tcon;
out:
	return rc;
}

/**
 * cifs_free_ipc - helper to release the session IPC tcon
1833
 * @ses: smb session to unmount the IPC from
A
Aurelien Aptel 已提交
1834
 *
1835 1836 1837 1838 1839 1840 1841
 * Needs to be called everytime a session is destroyed.
 *
 * On session close, the IPC is closed and the server must release all tcons of the session.
 * No need to send a tree disconnect here.
 *
 * Besides, it will make the server to not close durable and resilient files on session close, as
 * specified in MS-SMB2 3.3.5.6 Receiving an SMB2 LOGOFF Request.
A
Aurelien Aptel 已提交
1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852
 */
static int
cifs_free_ipc(struct cifs_ses *ses)
{
	struct cifs_tcon *tcon = ses->tcon_ipc;

	if (tcon == NULL)
		return 0;

	tconInfoFree(tcon);
	ses->tcon_ipc = NULL;
1853
	return 0;
A
Aurelien Aptel 已提交
1854 1855
}

1856
static struct cifs_ses *
1857
cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
L
Linus Torvalds 已提交
1858
{
1859
	struct cifs_ses *ses;
1860

1861
	spin_lock(&cifs_tcp_ses_lock);
1862
	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1863 1864 1865
		spin_lock(&ses->ses_lock);
		if (ses->ses_status == SES_EXITING) {
			spin_unlock(&ses->ses_lock);
1866
			continue;
1867 1868 1869
		}
		if (!match_session(ses, ctx)) {
			spin_unlock(&ses->ses_lock);
1870
			continue;
1871 1872 1873
		}
		spin_unlock(&ses->ses_lock);

1874
		++ses->ses_count;
1875
		spin_unlock(&cifs_tcp_ses_lock);
1876 1877
		return ses;
	}
1878
	spin_unlock(&cifs_tcp_ses_lock);
1879 1880
	return NULL;
}
1881

1882
void cifs_put_smb_ses(struct cifs_ses *ses)
1883
{
1884
	unsigned int rc, xid;
1885
	unsigned int chan_count;
1886
	struct TCP_Server_Info *server = ses->server;
1887

1888
	spin_lock(&ses->ses_lock);
1889
	if (ses->ses_status == SES_EXITING) {
1890
		spin_unlock(&ses->ses_lock);
1891 1892
		return;
	}
1893
	spin_unlock(&ses->ses_lock);
1894 1895

	cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count);
1896 1897
	cifs_dbg(FYI,
		 "%s: ses ipc: %s\n", __func__, ses->tcon_ipc ? ses->tcon_ipc->tree_name : "NONE");
1898

1899
	spin_lock(&cifs_tcp_ses_lock);
1900
	if (--ses->ses_count > 0) {
1901
		spin_unlock(&cifs_tcp_ses_lock);
1902 1903
		return;
	}
1904
	spin_unlock(&cifs_tcp_ses_lock);
1905

1906 1907 1908
	/* ses_count can never go negative */
	WARN_ON(ses->ses_count < 0);

1909 1910
	if (ses->ses_status == SES_GOOD)
		ses->ses_status = SES_EXITING;
1911

A
Aurelien Aptel 已提交
1912 1913
	cifs_free_ipc(ses);

1914
	if (ses->ses_status == SES_EXITING && server->ops->logoff) {
1915
		xid = get_xid();
1916 1917
		rc = server->ops->logoff(xid, ses);
		if (rc)
1918
			cifs_server_dbg(VFS, "%s: Session Logoff failure rc=%d\n",
1919
				__func__, rc);
1920
		_free_xid(xid);
1921
	}
1922 1923 1924 1925 1926

	spin_lock(&cifs_tcp_ses_lock);
	list_del_init(&ses->smb_ses_list);
	spin_unlock(&cifs_tcp_ses_lock);

1927 1928
	chan_count = ses->chan_count;

1929
	/* close any extra channels */
1930
	if (chan_count > 1) {
1931 1932
		int i;

1933
		for (i = 1; i < chan_count; i++) {
1934 1935 1936 1937
			if (ses->chans[i].iface) {
				kref_put(&ses->chans[i].iface->refcount, release_iface);
				ses->chans[i].iface = NULL;
			}
1938
			cifs_put_tcp_session(ses->chans[i].server, 0);
1939 1940
			ses->chans[i].server = NULL;
		}
1941 1942
	}

1943
	sesInfoFree(ses);
1944
	cifs_put_tcp_session(server, 0);
1945
}
1946

1947 1948
#ifdef CONFIG_KEYS

1949 1950
/* strlen("cifs:a:") + CIFS_MAX_DOMAINNAME_LEN + 1 */
#define CIFSCREDS_DESC_SIZE (7 + CIFS_MAX_DOMAINNAME_LEN + 1)
1951 1952 1953

/* Populate username and pw fields from keyring if possible */
static int
1954
cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses)
1955 1956
{
	int rc = 0;
1957
	int is_domain = 0;
1958 1959
	const char *delim, *payload;
	char *desc;
1960 1961 1962 1963 1964
	ssize_t len;
	struct key *key;
	struct TCP_Server_Info *server = ses->server;
	struct sockaddr_in *sa;
	struct sockaddr_in6 *sa6;
1965
	const struct user_key_payload *upayload;
1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981

	desc = kmalloc(CIFSCREDS_DESC_SIZE, GFP_KERNEL);
	if (!desc)
		return -ENOMEM;

	/* try to find an address key first */
	switch (server->dstaddr.ss_family) {
	case AF_INET:
		sa = (struct sockaddr_in *)&server->dstaddr;
		sprintf(desc, "cifs:a:%pI4", &sa->sin_addr.s_addr);
		break;
	case AF_INET6:
		sa6 = (struct sockaddr_in6 *)&server->dstaddr;
		sprintf(desc, "cifs:a:%pI6c", &sa6->sin6_addr.s6_addr);
		break;
	default:
1982 1983
		cifs_dbg(FYI, "Bad ss_family (%hu)\n",
			 server->dstaddr.ss_family);
1984 1985 1986 1987
		rc = -EINVAL;
		goto out_err;
	}

1988
	cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc);
1989
	key = request_key(&key_type_logon, desc, "");
1990 1991
	if (IS_ERR(key)) {
		if (!ses->domainName) {
1992
			cifs_dbg(FYI, "domainName is NULL\n");
1993 1994 1995 1996 1997 1998
			rc = PTR_ERR(key);
			goto out_err;
		}

		/* didn't work, try to find a domain key */
		sprintf(desc, "cifs:d:%s", ses->domainName);
1999
		cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc);
2000
		key = request_key(&key_type_logon, desc, "");
2001 2002 2003 2004
		if (IS_ERR(key)) {
			rc = PTR_ERR(key);
			goto out_err;
		}
2005
		is_domain = 1;
2006 2007 2008
	}

	down_read(&key->sem);
2009
	upayload = user_key_payload_locked(key);
2010
	if (IS_ERR_OR_NULL(upayload)) {
2011
		rc = upayload ? PTR_ERR(upayload) : -EINVAL;
2012 2013 2014 2015
		goto out_key_put;
	}

	/* find first : in payload */
2016
	payload = upayload->data;
2017
	delim = strnchr(payload, upayload->datalen, ':');
2018
	cifs_dbg(FYI, "payload=%s\n", payload);
2019
	if (!delim) {
2020 2021
		cifs_dbg(FYI, "Unable to find ':' in payload (datalen=%d)\n",
			 upayload->datalen);
2022 2023 2024 2025 2026
		rc = -EINVAL;
		goto out_key_put;
	}

	len = delim - payload;
2027
	if (len > CIFS_MAX_USERNAME_LEN || len <= 0) {
2028 2029
		cifs_dbg(FYI, "Bad value from username search (len=%zd)\n",
			 len);
2030 2031 2032 2033
		rc = -EINVAL;
		goto out_key_put;
	}

2034 2035
	ctx->username = kstrndup(payload, len, GFP_KERNEL);
	if (!ctx->username) {
2036 2037
		cifs_dbg(FYI, "Unable to allocate %zd bytes for username\n",
			 len);
2038 2039 2040
		rc = -ENOMEM;
		goto out_key_put;
	}
2041
	cifs_dbg(FYI, "%s: username=%s\n", __func__, ctx->username);
2042 2043

	len = key->datalen - (len + 1);
2044
	if (len > CIFS_MAX_PASSWORD_LEN || len <= 0) {
2045
		cifs_dbg(FYI, "Bad len for password search (len=%zd)\n", len);
2046
		rc = -EINVAL;
2047 2048
		kfree(ctx->username);
		ctx->username = NULL;
2049 2050 2051 2052
		goto out_key_put;
	}

	++delim;
2053 2054
	ctx->password = kstrndup(delim, len, GFP_KERNEL);
	if (!ctx->password) {
2055 2056
		cifs_dbg(FYI, "Unable to allocate %zd bytes for password\n",
			 len);
2057
		rc = -ENOMEM;
2058 2059
		kfree(ctx->username);
		ctx->username = NULL;
2060 2061 2062
		goto out_key_put;
	}

2063 2064 2065 2066 2067
	/*
	 * If we have a domain key then we must set the domainName in the
	 * for the request.
	 */
	if (is_domain && ses->domainName) {
A
Al Viro 已提交
2068
		ctx->domainname = kstrdup(ses->domainName, GFP_KERNEL);
2069
		if (!ctx->domainname) {
J
Joe Perches 已提交
2070 2071
			cifs_dbg(FYI, "Unable to allocate %zd bytes for domain\n",
				 len);
2072
			rc = -ENOMEM;
2073 2074 2075 2076
			kfree(ctx->username);
			ctx->username = NULL;
			kfree_sensitive(ctx->password);
			ctx->password = NULL;
2077 2078 2079 2080
			goto out_key_put;
		}
	}

2081
	strscpy(ctx->workstation_name, ses->workstation_name, sizeof(ctx->workstation_name));
2082

2083 2084 2085 2086 2087
out_key_put:
	up_read(&key->sem);
	key_put(key);
out_err:
	kfree(desc);
2088
	cifs_dbg(FYI, "%s: returning %d\n", __func__, rc);
2089 2090 2091 2092
	return rc;
}
#else /* ! CONFIG_KEYS */
static inline int
2093
cifs_set_cifscreds(struct smb3_fs_context *ctx __attribute__((unused)),
2094 2095 2096 2097 2098 2099
		   struct cifs_ses *ses __attribute__((unused)))
{
	return -ENOSYS;
}
#endif /* CONFIG_KEYS */

2100
/**
2101
 * cifs_get_smb_ses - get a session matching @ctx data from @server
2102 2103
 * @server: server to setup the session to
 * @ctx: superblock configuration context to use to setup the session
2104 2105 2106 2107 2108
 *
 * This function assumes it is being called from cifs_mount() where we
 * already got a server reference (server refcount +1). See
 * cifs_get_tcon() for refcount explanations.
 */
2109
struct cifs_ses *
2110
cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
2111
{
2112
	int rc = 0;
2113
	unsigned int xid;
2114
	struct cifs_ses *ses;
2115 2116
	struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
	struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
2117

2118
	xid = get_xid();
2119

2120
	ses = cifs_find_smb_ses(server, ctx);
2121
	if (ses) {
2122
		cifs_dbg(FYI, "Existing smb sess found (status=%d)\n",
2123
			 ses->ses_status);
2124

2125 2126 2127
		spin_lock(&ses->chan_lock);
		if (cifs_chan_needs_reconnect(ses, server)) {
			spin_unlock(&ses->chan_lock);
2128
			cifs_dbg(FYI, "Session needs reconnect\n");
2129

2130
			mutex_lock(&ses->session_mutex);
2131
			rc = cifs_negotiate_protocol(xid, ses, server);
2132 2133 2134 2135 2136 2137 2138 2139
			if (rc) {
				mutex_unlock(&ses->session_mutex);
				/* problem -- put our ses reference */
				cifs_put_smb_ses(ses);
				free_xid(xid);
				return ERR_PTR(rc);
			}

2140
			rc = cifs_setup_session(xid, ses, server,
2141
						ctx->local_nls);
2142 2143 2144 2145
			if (rc) {
				mutex_unlock(&ses->session_mutex);
				/* problem -- put our reference */
				cifs_put_smb_ses(ses);
2146
				free_xid(xid);
2147 2148
				return ERR_PTR(rc);
			}
2149 2150
			mutex_unlock(&ses->session_mutex);

2151
			spin_lock(&ses->chan_lock);
2152
		}
2153
		spin_unlock(&ses->chan_lock);
2154 2155

		/* existing SMB ses has a server reference already */
2156
		cifs_put_tcp_session(server, 0);
2157
		free_xid(xid);
2158 2159 2160
		return ses;
	}

2161 2162
	rc = -ENOMEM;

2163
	cifs_dbg(FYI, "Existing smb sess not found\n");
2164 2165 2166 2167 2168 2169
	ses = sesInfoAlloc();
	if (ses == NULL)
		goto get_ses_fail;

	/* new SMB session uses our server ref */
	ses->server = server;
2170
	if (server->dstaddr.ss_family == AF_INET6)
2171
		sprintf(ses->ip_addr, "%pI6", &addr6->sin6_addr);
2172
	else
2173
		sprintf(ses->ip_addr, "%pI4", &addr->sin_addr);
2174

2175 2176
	if (ctx->username) {
		ses->user_name = kstrdup(ctx->username, GFP_KERNEL);
2177 2178 2179
		if (!ses->user_name)
			goto get_ses_fail;
	}
2180

2181 2182 2183
	/* ctx->password freed at unmount */
	if (ctx->password) {
		ses->password = kstrdup(ctx->password, GFP_KERNEL);
2184 2185 2186
		if (!ses->password)
			goto get_ses_fail;
	}
2187 2188
	if (ctx->domainname) {
		ses->domainName = kstrdup(ctx->domainname, GFP_KERNEL);
2189 2190
		if (!ses->domainName)
			goto get_ses_fail;
2191
	}
2192 2193 2194

	strscpy(ses->workstation_name, ctx->workstation_name, sizeof(ses->workstation_name));

2195 2196 2197 2198
	if (ctx->domainauto)
		ses->domainAuto = ctx->domainauto;
	ses->cred_uid = ctx->cred_uid;
	ses->linux_uid = ctx->linux_uid;
2199

2200 2201
	ses->sectype = ctx->sectype;
	ses->sign = ctx->sign;
2202 2203

	/* add server as first channel */
2204
	spin_lock(&ses->chan_lock);
2205 2206
	ses->chans[0].server = server;
	ses->chan_count = 1;
2207
	ses->chan_max = ctx->multichannel ? ctx->max_channels:1;
2208
	ses->chans_need_reconnect = 1;
2209
	spin_unlock(&ses->chan_lock);
2210

2211
	mutex_lock(&ses->session_mutex);
2212
	rc = cifs_negotiate_protocol(xid, ses, server);
2213
	if (!rc)
2214
		rc = cifs_setup_session(xid, ses, server, ctx->local_nls);
2215
	mutex_unlock(&ses->session_mutex);
2216 2217

	/* each channel uses a different signing key */
2218
	spin_lock(&ses->chan_lock);
2219 2220
	memcpy(ses->chans[0].signkey, ses->smb3signingkey,
	       sizeof(ses->smb3signingkey));
2221
	spin_unlock(&ses->chan_lock);
2222

2223
	if (rc)
2224 2225
		goto get_ses_fail;

2226 2227 2228 2229 2230
	/*
	 * success, put it on the list and add it as first channel
	 * note: the session becomes active soon after this. So you'll
	 * need to lock before changing something in the session.
	 */
2231
	spin_lock(&cifs_tcp_ses_lock);
2232
	ses->dfs_root_ses = ctx->dfs_root_ses;
2233
	list_add(&ses->smb_ses_list, &server->smb_ses_list);
2234
	spin_unlock(&cifs_tcp_ses_lock);
2235

2236
	cifs_setup_ipc(ses, ctx);
A
Aurelien Aptel 已提交
2237

2238 2239
	free_xid(xid);

2240 2241 2242 2243
	return ses;

get_ses_fail:
	sesInfoFree(ses);
2244
	free_xid(xid);
2245 2246 2247
	return ERR_PTR(rc);
}

2248
/* this function must be called with tc_lock held */
2249
static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx, bool dfs_super_cmp)
2250
{
2251
	if (tcon->status == TID_EXITING)
2252
		return 0;
2253 2254
	/* Skip UNC validation when matching DFS superblocks */
	if (!dfs_super_cmp && strncmp(tcon->tree_name, ctx->UNC, MAX_TREE_SIZE))
2255
		return 0;
2256
	if (tcon->seal != ctx->seal)
2257
		return 0;
2258
	if (tcon->snapshot_time != ctx->snapshot_time)
2259
		return 0;
2260
	if (tcon->handle_timeout != ctx->handle_timeout)
2261
		return 0;
2262
	if (tcon->no_lease != ctx->no_lease)
2263
		return 0;
2264
	if (tcon->nodelete != ctx->nodelete)
S
Steve French 已提交
2265
		return 0;
2266 2267 2268
	return 1;
}

2269
static struct cifs_tcon *
2270
cifs_find_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
2271
{
2272
	struct cifs_tcon *tcon;
2273

2274
	spin_lock(&cifs_tcp_ses_lock);
2275
	list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
2276
		spin_lock(&tcon->tc_lock);
2277
		if (!match_tcon(tcon, ctx, false)) {
2278
			spin_unlock(&tcon->tc_lock);
2279
			continue;
2280
		}
2281
		++tcon->tc_count;
2282
		spin_unlock(&tcon->tc_lock);
2283
		spin_unlock(&cifs_tcp_ses_lock);
2284
		return tcon;
L
Linus Torvalds 已提交
2285
	}
2286
	spin_unlock(&cifs_tcp_ses_lock);
L
Linus Torvalds 已提交
2287 2288 2289
	return NULL;
}

2290
void
2291
cifs_put_tcon(struct cifs_tcon *tcon)
2292
{
2293
	unsigned int xid;
A
Aurelien Aptel 已提交
2294
	struct cifs_ses *ses;
2295

A
Aurelien Aptel 已提交
2296 2297 2298 2299 2300 2301 2302 2303
	/*
	 * IPC tcon share the lifetime of their session and are
	 * destroyed in the session put function
	 */
	if (tcon == NULL || tcon->ipc)
		return;

	ses = tcon->ses;
2304
	cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
2305
	spin_lock(&cifs_tcp_ses_lock);
2306
	spin_lock(&tcon->tc_lock);
2307
	if (--tcon->tc_count > 0) {
2308
		spin_unlock(&tcon->tc_lock);
2309
		spin_unlock(&cifs_tcp_ses_lock);
2310 2311 2312
		return;
	}

2313 2314 2315
	/* tc_count can never go negative */
	WARN_ON(tcon->tc_count < 0);

2316
	list_del_init(&tcon->tcon_list);
2317
	spin_unlock(&tcon->tc_lock);
2318 2319
	spin_unlock(&cifs_tcp_ses_lock);

2320 2321 2322
	/* cancel polling of interfaces */
	cancel_delayed_work_sync(&tcon->query_interfaces);

2323 2324 2325 2326 2327 2328 2329 2330 2331
	if (tcon->use_witness) {
		int rc;

		rc = cifs_swn_unregister(tcon);
		if (rc < 0) {
			cifs_dbg(VFS, "%s: Failed to unregister for witness notifications: %d\n",
					__func__, rc);
		}
	}
2332

2333
	xid = get_xid();
2334 2335
	if (ses->server->ops->tree_disconnect)
		ses->server->ops->tree_disconnect(xid, tcon);
2336
	_free_xid(xid);
2337

2338
	cifs_fscache_release_super_cookie(tcon);
2339
	tconInfoFree(tcon);
2340 2341 2342
	cifs_put_smb_ses(ses);
}

2343
/**
2344
 * cifs_get_tcon - get a tcon matching @ctx data from @ses
2345 2346
 * @ses: smb session to issue the request on
 * @ctx: the superblock configuration context to use for building the
2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364
 *
 * - tcon refcount is the number of mount points using the tcon.
 * - ses refcount is the number of tcon using the session.
 *
 * 1. This function assumes it is being called from cifs_mount() where
 *    we already got a session reference (ses refcount +1).
 *
 * 2. Since we're in the context of adding a mount point, the end
 *    result should be either:
 *
 * a) a new tcon already allocated with refcount=1 (1 mount point) and
 *    its session refcount incremented (1 new tcon). This +1 was
 *    already done in (1).
 *
 * b) an existing tcon with refcount+1 (add a mount point to it) and
 *    identical ses refcount (no new tcon). Because of (1) we need to
 *    decrement the ses refcount.
 */
2365
static struct cifs_tcon *
2366
cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
2367 2368
{
	int rc, xid;
2369
	struct cifs_tcon *tcon;
2370

2371
	tcon = cifs_find_tcon(ses, ctx);
2372
	if (tcon) {
2373 2374 2375 2376
		/*
		 * tcon has refcount already incremented but we need to
		 * decrement extra ses reference gotten by caller (case b)
		 */
2377
		cifs_dbg(FYI, "Found match on UNC path\n");
2378 2379 2380 2381
		cifs_put_smb_ses(ses);
		return tcon;
	}

2382 2383 2384 2385 2386
	if (!ses->server->ops->tree_connect) {
		rc = -ENOSYS;
		goto out_fail;
	}

2387 2388 2389 2390 2391 2392
	tcon = tconInfoAlloc();
	if (tcon == NULL) {
		rc = -ENOMEM;
		goto out_fail;
	}

2393
	if (ctx->snapshot_time) {
2394 2395 2396 2397 2398 2399
		if (ses->server->vals->protocol_id == 0) {
			cifs_dbg(VFS,
			     "Use SMB2 or later for snapshot mount option\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		} else
2400
			tcon->snapshot_time = ctx->snapshot_time;
2401 2402
	}

2403
	if (ctx->handle_timeout) {
2404 2405 2406 2407 2408 2409
		if (ses->server->vals->protocol_id == 0) {
			cifs_dbg(VFS,
			     "Use SMB2.1 or later for handle timeout option\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		} else
2410
			tcon->handle_timeout = ctx->handle_timeout;
2411 2412
	}

2413
	tcon->ses = ses;
2414 2415
	if (ctx->password) {
		tcon->password = kstrdup(ctx->password, GFP_KERNEL);
2416 2417 2418 2419 2420 2421
		if (!tcon->password) {
			rc = -ENOMEM;
			goto out_fail;
		}
	}

2422
	if (ctx->seal) {
2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437
		if (ses->server->vals->protocol_id == 0) {
			cifs_dbg(VFS,
				 "SMB3 or later required for encryption\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		} else if (tcon->ses->server->capabilities &
					SMB2_GLOBAL_CAP_ENCRYPTION)
			tcon->seal = true;
		else {
			cifs_dbg(VFS, "Encryption is not supported on share\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		}
	}

2438
	if (ctx->linux_ext) {
2439
		if (ses->server->posix_ext_supported) {
2440
			tcon->posix_extensions = true;
J
Joe Perches 已提交
2441
			pr_warn_once("SMB3.11 POSIX Extensions are experimental\n");
2442 2443 2444 2445 2446
		} else if ((ses->server->vals->protocol_id == SMB311_PROT_ID) ||
		    (strcmp(ses->server->vals->version_string,
		     SMB3ANY_VERSION_STRING) == 0) ||
		    (strcmp(ses->server->vals->version_string,
		     SMBDEFAULT_VERSION_STRING) == 0)) {
J
Joe Perches 已提交
2447
			cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions\n");
2448 2449
			rc = -EOPNOTSUPP;
			goto out_fail;
2450 2451 2452 2453 2454
		} else {
			cifs_dbg(VFS, "Check vers= mount option. SMB3.11 "
				"disabled but required for POSIX extensions\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
2455
		}
2456 2457
	}

2458
	xid = get_xid();
2459 2460
	rc = ses->server->ops->tree_connect(xid, ses, ctx->UNC, tcon,
					    ctx->local_nls);
2461
	free_xid(xid);
2462
	cifs_dbg(FYI, "Tcon rc = %d\n", rc);
2463 2464 2465
	if (rc)
		goto out_fail;

2466 2467
	tcon->use_persistent = false;
	/* check if SMB2 or later, CIFS does not support persistent handles */
2468
	if (ctx->persistent) {
2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484
		if (ses->server->vals->protocol_id == 0) {
			cifs_dbg(VFS,
			     "SMB3 or later required for persistent handles\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		} else if (ses->server->capabilities &
			   SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
			tcon->use_persistent = true;
		else /* persistent handles requested but not supported */ {
			cifs_dbg(VFS,
				"Persistent handles not supported on share\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		}
	} else if ((tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
	     && (ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
2485
	     && (ctx->nopersistent == false)) {
2486 2487
		cifs_dbg(FYI, "enabling persistent handles\n");
		tcon->use_persistent = true;
2488
	} else if (ctx->resilient) {
S
Steve French 已提交
2489 2490 2491 2492 2493 2494 2495
		if (ses->server->vals->protocol_id == 0) {
			cifs_dbg(VFS,
			     "SMB2.1 or later required for resilient handles\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		}
		tcon->use_resilient = true;
2496
	}
2497

2498
	tcon->use_witness = false;
2499
	if (IS_ENABLED(CONFIG_CIFS_SWN_UPCALL) && ctx->witness) {
2500 2501
		if (ses->server->vals->protocol_id >= SMB30_PROT_ID) {
			if (tcon->capabilities & SMB2_SHARE_CAP_CLUSTER) {
2502 2503 2504 2505
				/*
				 * Set witness in use flag in first place
				 * to retry registration in the echo task
				 */
2506
				tcon->use_witness = true;
2507 2508 2509 2510 2511 2512
				/* And try to register immediately */
				rc = cifs_swn_register(tcon);
				if (rc < 0) {
					cifs_dbg(VFS, "Failed to register for witness notifications: %d\n", rc);
					goto out_fail;
				}
2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524
			} else {
				/* TODO: try to extend for non-cluster uses (eg multichannel) */
				cifs_dbg(VFS, "witness requested on mount but no CLUSTER capability on share\n");
				rc = -EOPNOTSUPP;
				goto out_fail;
			}
		} else {
			cifs_dbg(VFS, "SMB3 or later required for witness option\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		}
	}
2525

2526 2527
	/* If the user really knows what they are doing they can override */
	if (tcon->share_flags & SMB2_SHAREFLAG_NO_CACHING) {
2528
		if (ctx->cache_ro)
2529
			cifs_dbg(VFS, "cache=ro requested on mount but NO_CACHING flag set on share\n");
2530
		else if (ctx->cache_rw)
2531 2532 2533
			cifs_dbg(VFS, "cache=singleclient requested on mount but NO_CACHING flag set on share\n");
	}

2534
	if (ctx->no_lease) {
2535 2536 2537 2538 2539 2540
		if (ses->server->vals->protocol_id == 0) {
			cifs_dbg(VFS,
				"SMB2 or later required for nolease option\n");
			rc = -EOPNOTSUPP;
			goto out_fail;
		} else
2541
			tcon->no_lease = ctx->no_lease;
2542 2543
	}

2544 2545 2546 2547 2548
	/*
	 * We can have only one retry value for a connection to a share so for
	 * resources mounted more than once to the same server share the last
	 * value passed in for the retry flag is used.
	 */
2549 2550
	tcon->retry = ctx->retry;
	tcon->nocase = ctx->nocase;
S
Steve French 已提交
2551
	tcon->broken_sparse_sup = ctx->no_sparse;
2552
	if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING)
2553
		tcon->nohandlecache = ctx->nohandlecache;
2554
	else
2555
		tcon->nohandlecache = true;
2556 2557
	tcon->nodelete = ctx->nodelete;
	tcon->local_lease = ctx->local_lease;
2558
	INIT_LIST_HEAD(&tcon->pending_opens);
2559
	tcon->status = TID_GOOD;
2560

2561 2562
	INIT_DELAYED_WORK(&tcon->query_interfaces,
			  smb2_query_server_interfaces);
2563 2564 2565 2566 2567 2568
	if (ses->server->dialect >= SMB30_PROT_ID &&
	    (ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
		/* schedule query interfaces poll */
		queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
				   (SMB_INTERFACE_POLL_INTERVAL * HZ));
	}
2569

2570
	spin_lock(&cifs_tcp_ses_lock);
2571
	list_add(&tcon->tcon_list, &ses->tcon_list);
2572
	spin_unlock(&cifs_tcp_ses_lock);
2573 2574 2575 2576 2577 2578 2579 2580

	return tcon;

out_fail:
	tconInfoFree(tcon);
	return ERR_PTR(rc);
}

2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597
void
cifs_put_tlink(struct tcon_link *tlink)
{
	if (!tlink || IS_ERR(tlink))
		return;

	if (!atomic_dec_and_test(&tlink->tl_count) ||
	    test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
		tlink->tl_time = jiffies;
		return;
	}

	if (!IS_ERR(tlink_tcon(tlink)))
		cifs_put_tcon(tlink_tcon(tlink));
	kfree(tlink);
	return;
}
2598

2599 2600 2601 2602 2603
static int
compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
{
	struct cifs_sb_info *old = CIFS_SB(sb);
	struct cifs_sb_info *new = mnt_data->cifs_sb;
2604 2605
	unsigned int oldflags = old->mnt_cifs_flags & CIFS_MOUNT_MASK;
	unsigned int newflags = new->mnt_cifs_flags & CIFS_MOUNT_MASK;
2606 2607 2608 2609

	if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
		return 0;

2610 2611 2612 2613
	if (old->mnt_cifs_serverino_autodisabled)
		newflags &= ~CIFS_MOUNT_SERVER_INUM;

	if (oldflags != newflags)
2614 2615 2616
		return 0;

	/*
2617 2618
	 * We want to share sb only if we don't specify an r/wsize or
	 * specified r/wsize is greater than or equal to existing one.
2619
	 */
2620
	if (new->ctx->wsize && new->ctx->wsize < old->ctx->wsize)
2621 2622
		return 0;

2623
	if (new->ctx->rsize && new->ctx->rsize < old->ctx->rsize)
2624 2625
		return 0;

2626 2627
	if (!uid_eq(old->ctx->linux_uid, new->ctx->linux_uid) ||
	    !gid_eq(old->ctx->linux_gid, new->ctx->linux_gid))
2628 2629
		return 0;

2630 2631
	if (old->ctx->file_mode != new->ctx->file_mode ||
	    old->ctx->dir_mode != new->ctx->dir_mode)
2632 2633 2634 2635 2636
		return 0;

	if (strcmp(old->local_nls->charset, new->local_nls->charset))
		return 0;

2637
	if (old->ctx->acregmax != new->ctx->acregmax)
2638
		return 0;
2639 2640
	if (old->ctx->acdirmax != new->ctx->acdirmax)
		return 0;
2641 2642
	if (old->ctx->closetimeo != new->ctx->closetimeo)
		return 0;
2643 2644 2645 2646

	return 1;
}

2647 2648 2649 2650 2651
static int
match_prepath(struct super_block *sb, struct cifs_mnt_data *mnt_data)
{
	struct cifs_sb_info *old = CIFS_SB(sb);
	struct cifs_sb_info *new = mnt_data->cifs_sb;
2652 2653 2654 2655
	bool old_set = (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
		old->prepath;
	bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
		new->prepath;
2656

S
Sachin Prabhu 已提交
2657
	if (old_set && new_set && !strcmp(new->prepath, old->prepath))
2658
		return 1;
S
Sachin Prabhu 已提交
2659 2660 2661
	else if (!old_set && !new_set)
		return 1;

2662 2663 2664
	return 0;
}

2665 2666 2667
int
cifs_match_super(struct super_block *sb, void *data)
{
Y
Yu Zhe 已提交
2668
	struct cifs_mnt_data *mnt_data = data;
2669
	struct smb3_fs_context *ctx;
2670 2671
	struct cifs_sb_info *cifs_sb;
	struct TCP_Server_Info *tcp_srv;
2672 2673
	struct cifs_ses *ses;
	struct cifs_tcon *tcon;
2674
	struct tcon_link *tlink;
2675
	bool dfs_super_cmp;
2676 2677 2678 2679 2680
	int rc = 0;

	spin_lock(&cifs_tcp_ses_lock);
	cifs_sb = CIFS_SB(sb);
	tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
2681 2682
	if (tlink == NULL) {
		/* can not match superblock if tlink were ever null */
2683
		spin_unlock(&cifs_tcp_ses_lock);
2684
		return 0;
2685 2686 2687 2688 2689
	}
	tcon = tlink_tcon(tlink);
	ses = tcon->ses;
	tcp_srv = ses->server;

2690 2691
	dfs_super_cmp = IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) && tcp_srv->origin_fullpath;

2692
	ctx = mnt_data->ctx;
2693

2694 2695 2696
	spin_lock(&tcp_srv->srv_lock);
	spin_lock(&ses->ses_lock);
	spin_lock(&tcon->tc_lock);
2697
	if (!match_server(tcp_srv, ctx, dfs_super_cmp) ||
2698
	    !match_session(ses, ctx) ||
2699
	    !match_tcon(tcon, ctx, dfs_super_cmp) ||
2700
	    !match_prepath(sb, mnt_data)) {
2701 2702 2703 2704 2705 2706
		rc = 0;
		goto out;
	}

	rc = compare_mount_options(sb, mnt_data);
out:
2707 2708 2709 2710
	spin_unlock(&tcon->tc_lock);
	spin_unlock(&ses->ses_lock);
	spin_unlock(&tcp_srv->srv_lock);

2711
	spin_unlock(&cifs_tcp_ses_lock);
2712
	cifs_put_tlink(tlink);
2713 2714 2715
	return rc;
}

2716 2717 2718 2719 2720 2721 2722 2723
#ifdef CONFIG_DEBUG_LOCK_ALLOC
static struct lock_class_key cifs_key[2];
static struct lock_class_key cifs_slock_key[2];

static inline void
cifs_reclassify_socket4(struct socket *sock)
{
	struct sock *sk = sock->sk;
2724
	BUG_ON(!sock_allow_reclassification(sk));
2725 2726 2727 2728 2729 2730 2731 2732
	sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
		&cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
}

static inline void
cifs_reclassify_socket6(struct socket *sock)
{
	struct sock *sk = sock->sk;
2733
	BUG_ON(!sock_allow_reclassification(sk));
2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748
	sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
		&cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
}
#else
static inline void
cifs_reclassify_socket4(struct socket *sock)
{
}

static inline void
cifs_reclassify_socket6(struct socket *sock)
{
}
#endif

L
Linus Torvalds 已提交
2749
/* See RFC1001 section 14 on representation of Netbios names */
2750
static void rfc1002mangle(char *target, char *source, unsigned int length)
L
Linus Torvalds 已提交
2751
{
2752
	unsigned int i, j;
L
Linus Torvalds 已提交
2753

2754
	for (i = 0, j = 0; i < (length); i++) {
L
Linus Torvalds 已提交
2755 2756 2757
		/* mask a nibble at a time and encode */
		target[j] = 'A' + (0x0F & (source[i] >> 4));
		target[j+1] = 'A' + (0x0F & source[i]);
2758
		j += 2;
L
Linus Torvalds 已提交
2759 2760 2761 2762
	}

}

2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778
static int
bind_socket(struct TCP_Server_Info *server)
{
	int rc = 0;
	if (server->srcaddr.ss_family != AF_UNSPEC) {
		/* Bind to the specified local IP address */
		struct socket *socket = server->ssocket;
		rc = socket->ops->bind(socket,
				       (struct sockaddr *) &server->srcaddr,
				       sizeof(server->srcaddr));
		if (rc < 0) {
			struct sockaddr_in *saddr4;
			struct sockaddr_in6 *saddr6;
			saddr4 = (struct sockaddr_in *)&server->srcaddr;
			saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
			if (saddr6->sin6_family == AF_INET6)
2779
				cifs_server_dbg(VFS, "Failed to bind to: %pI6c, error: %d\n",
2780
					 &saddr6->sin6_addr, rc);
2781
			else
2782
				cifs_server_dbg(VFS, "Failed to bind to: %pI4, error: %d\n",
2783
					 &saddr4->sin_addr.s_addr, rc);
2784 2785 2786 2787
		}
	}
	return rc;
}
L
Linus Torvalds 已提交
2788 2789

static int
2790
ip_rfc1001_connect(struct TCP_Server_Info *server)
L
Linus Torvalds 已提交
2791 2792
{
	int rc = 0;
2793 2794 2795 2796 2797
	/*
	 * some servers require RFC1001 sessinit before sending
	 * negprot - BB check reconnection in case where second
	 * sessinit is sent but no second negprot
	 */
2798 2799 2800
	struct rfc1002_session_packet req = {};
	struct smb_hdr *smb_buf = (struct smb_hdr *)&req;
	unsigned int len;
2801

2802
	req.trailer.session_req.called_len = sizeof(req.trailer.session_req.called_name);
2803

2804 2805 2806 2807 2808 2809 2810 2811
	if (server->server_RFC1001_name[0] != 0)
		rfc1002mangle(req.trailer.session_req.called_name,
			      server->server_RFC1001_name,
			      RFC1001_NAME_LEN_WITH_NULL);
	else
		rfc1002mangle(req.trailer.session_req.called_name,
			      DEFAULT_CIFS_CALLED_NAME,
			      RFC1001_NAME_LEN_WITH_NULL);
2812

2813
	req.trailer.session_req.calling_len = sizeof(req.trailer.session_req.calling_name);
2814

2815 2816 2817 2818 2819 2820 2821 2822 2823
	/* calling name ends in null (byte 16) from old smb convention */
	if (server->workstation_RFC1001_name[0] != 0)
		rfc1002mangle(req.trailer.session_req.calling_name,
			      server->workstation_RFC1001_name,
			      RFC1001_NAME_LEN_WITH_NULL);
	else
		rfc1002mangle(req.trailer.session_req.calling_name,
			      "LINUX_CIFS_CLNT",
			      RFC1001_NAME_LEN_WITH_NULL);
2824 2825

	/*
2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837
	 * As per rfc1002, @len must be the number of bytes that follows the
	 * length field of a rfc1002 session request payload.
	 */
	len = sizeof(req) - offsetof(struct rfc1002_session_packet, trailer.session_req);

	smb_buf->smb_buf_length = cpu_to_be32((RFC1002_SESSION_REQUEST << 24) | len);
	rc = smb_send(server, smb_buf, len);
	/*
	 * RFC1001 layer in at least one server requires very short break before
	 * negprot presumably because not expecting negprot to follow so fast.
	 * This is a simple solution that works without complicating the code
	 * and causes no significant slowing down on mount for everyone else
2838
	 */
2839
	usleep_range(1000, 2000);
2840 2841 2842 2843 2844 2845 2846 2847

	return rc;
}

static int
generic_ip_connect(struct TCP_Server_Info *server)
{
	int rc = 0;
2848
	__be16 sport;
2849
	int slen, sfamily;
2850
	struct socket *socket = server->ssocket;
2851 2852 2853 2854 2855
	struct sockaddr *saddr;

	saddr = (struct sockaddr *) &server->dstaddr;

	if (server->dstaddr.ss_family == AF_INET6) {
2856 2857 2858
		struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&server->dstaddr;

		sport = ipv6->sin6_port;
2859 2860
		slen = sizeof(struct sockaddr_in6);
		sfamily = AF_INET6;
2861 2862
		cifs_dbg(FYI, "%s: connecting to [%pI6]:%d\n", __func__, &ipv6->sin6_addr,
				ntohs(sport));
2863
	} else {
2864 2865 2866
		struct sockaddr_in *ipv4 = (struct sockaddr_in *)&server->dstaddr;

		sport = ipv4->sin_port;
2867 2868
		slen = sizeof(struct sockaddr_in);
		sfamily = AF_INET;
2869 2870
		cifs_dbg(FYI, "%s: connecting to %pI4:%d\n", __func__, &ipv4->sin_addr,
				ntohs(sport));
2871
	}
L
Linus Torvalds 已提交
2872

2873
	if (socket == NULL) {
2874 2875
		rc = __sock_create(cifs_net_ns(server), sfamily, SOCK_STREAM,
				   IPPROTO_TCP, &socket, 1);
L
Linus Torvalds 已提交
2876
		if (rc < 0) {
2877
			cifs_server_dbg(VFS, "Error %d creating socket\n", rc);
2878
			server->ssocket = NULL;
L
Linus Torvalds 已提交
2879 2880
			return rc;
		}
2881 2882

		/* BB other socket options to set KEEPALIVE, NODELAY? */
2883
		cifs_dbg(FYI, "Socket created\n");
2884 2885
		server->ssocket = socket;
		socket->sk->sk_allocation = GFP_NOFS;
2886
		socket->sk->sk_use_task_frag = false;
2887 2888 2889 2890
		if (sfamily == AF_INET6)
			cifs_reclassify_socket6(socket);
		else
			cifs_reclassify_socket4(socket);
L
Linus Torvalds 已提交
2891 2892
	}

2893 2894 2895 2896
	rc = bind_socket(server);
	if (rc < 0)
		return rc;

2897 2898
	/*
	 * Eventually check for other socket options to change from
2899 2900
	 * the default. sock_setsockopt not used because it expects
	 * user space buffer
2901 2902
	 */
	socket->sk->sk_rcvtimeo = 7 * HZ;
2903
	socket->sk->sk_sndtimeo = 5 * HZ;
2904

2905
	/* make the bufsizes depend on wsize/rsize and max requests */
2906 2907 2908 2909 2910
	if (server->noautotune) {
		if (socket->sk->sk_sndbuf < (200 * 1024))
			socket->sk->sk_sndbuf = 200 * 1024;
		if (socket->sk->sk_rcvbuf < (140 * 1024))
			socket->sk->sk_rcvbuf = 140 * 1024;
2911
	}
L
Linus Torvalds 已提交
2912

2913 2914
	if (server->tcp_nodelay)
		tcp_sock_set_nodelay(socket->sk);
2915

2916
	cifs_dbg(FYI, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx\n",
2917
		 socket->sk->sk_sndbuf,
2918
		 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
2919

2920 2921
	rc = socket->ops->connect(socket, saddr, slen,
				  server->noblockcnt ? O_NONBLOCK : 0);
2922 2923 2924 2925 2926 2927
	/*
	 * When mounting SMB root file systems, we do not want to block in
	 * connect. Otherwise bail out and then let cifs_reconnect() perform
	 * reconnect failover - if possible.
	 */
	if (server->noblockcnt && rc == -EINPROGRESS)
2928
		rc = 0;
2929
	if (rc < 0) {
2930
		cifs_dbg(FYI, "Error %d connecting to server\n", rc);
2931
		trace_smb3_connect_err(server->hostname, server->conn_id, &server->dstaddr, rc);
2932 2933 2934 2935
		sock_release(socket);
		server->ssocket = NULL;
		return rc;
	}
2936
	trace_smb3_connect_done(server->hostname, server->conn_id, &server->dstaddr);
2937 2938
	if (sport == htons(RFC1001_PORT))
		rc = ip_rfc1001_connect(server);
2939

L
Linus Torvalds 已提交
2940 2941 2942 2943
	return rc;
}

static int
2944
ip_connect(struct TCP_Server_Info *server)
L
Linus Torvalds 已提交
2945
{
2946
	__be16 *sport;
2947 2948
	struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
	struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
L
Linus Torvalds 已提交
2949

2950 2951 2952 2953
	if (server->dstaddr.ss_family == AF_INET6)
		sport = &addr6->sin6_port;
	else
		sport = &addr->sin_port;
L
Linus Torvalds 已提交
2954

2955 2956
	if (*sport == 0) {
		int rc;
L
Linus Torvalds 已提交
2957

2958 2959
		/* try with 445 port at first */
		*sport = htons(CIFS_PORT);
2960

2961
		rc = generic_ip_connect(server);
L
Linus Torvalds 已提交
2962
		if (rc >= 0)
2963
			return rc;
2964

2965 2966
		/* if it failed, try with 139 port */
		*sport = htons(RFC1001_PORT);
2967 2968
	}

2969
	return generic_ip_connect(server);
L
Linus Torvalds 已提交
2970 2971
}

2972
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
2973
void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
2974
			  struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
2975
{
2976 2977
	/*
	 * If we are reconnecting then should we check to see if
2978 2979 2980 2981 2982 2983 2984
	 * any requested capabilities changed locally e.g. via
	 * remount but we can not do much about it here
	 * if they have (even if we could detect it by the following)
	 * Perhaps we could add a backpointer to array of sb from tcon
	 * or if we change to make all sb to same share the same
	 * sb as NFS - then we only have one backpointer to sb.
	 * What if we wanted to mount the server share twice once with
2985 2986
	 * and once without posixacls or posix paths?
	 */
2987
	__u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2988

2989
	if (ctx && ctx->no_linux_ext) {
2990 2991
		tcon->fsUnixInfo.Capability = 0;
		tcon->unix_ext = 0; /* Unix Extensions disabled */
2992
		cifs_dbg(FYI, "Linux protocol extensions disabled\n");
2993
		return;
2994
	} else if (ctx)
2995 2996
		tcon->unix_ext = 1; /* Unix Extensions supported */

2997
	if (!tcon->unix_ext) {
2998
		cifs_dbg(FYI, "Unix extensions disabled so not set on reconnect\n");
2999 3000
		return;
	}
3001

S
Steve French 已提交
3002
	if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
3003
		__u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
3004
		cifs_dbg(FYI, "unix caps which server supports %lld\n", cap);
3005 3006 3007 3008
		/*
		 * check for reconnect case in which we do not
		 * want to change the mount behavior if we can avoid it
		 */
3009
		if (ctx == NULL) {
3010 3011 3012 3013
			/*
			 * turn off POSIX ACL and PATHNAMES if not set
			 * originally at mount time
			 */
3014 3015
			if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
				cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
3016 3017
			if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
				if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
3018
					cifs_dbg(VFS, "POSIXPATH support change\n");
3019
				cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
3020
			} else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
3021 3022
				cifs_dbg(VFS, "possible reconnect error\n");
				cifs_dbg(VFS, "server disabled POSIX path support\n");
3023
			}
3024
		}
3025

3026
		if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
3027
			cifs_dbg(VFS, "per-share encryption not supported yet\n");
3028

3029
		cap &= CIFS_UNIX_CAP_MASK;
3030
		if (ctx && ctx->no_psx_acl)
3031
			cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
3032
		else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
3033
			cifs_dbg(FYI, "negotiated posix acl support\n");
3034 3035 3036
			if (cifs_sb)
				cifs_sb->mnt_cifs_flags |=
					CIFS_MOUNT_POSIXACL;
3037 3038
		}

3039
		if (ctx && ctx->posix_paths == 0)
3040
			cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
3041
		else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
3042
			cifs_dbg(FYI, "negotiate posix pathnames\n");
3043 3044
			if (cifs_sb)
				cifs_sb->mnt_cifs_flags |=
3045 3046
					CIFS_MOUNT_POSIX_PATHS;
		}
3047

3048
		cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap);
3049
#ifdef CONFIG_CIFS_DEBUG2
3050
		if (cap & CIFS_UNIX_FCNTL_CAP)
3051
			cifs_dbg(FYI, "FCNTL cap\n");
3052
		if (cap & CIFS_UNIX_EXTATTR_CAP)
3053
			cifs_dbg(FYI, "EXTATTR cap\n");
3054
		if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
3055
			cifs_dbg(FYI, "POSIX path cap\n");
3056
		if (cap & CIFS_UNIX_XATTR_CAP)
3057
			cifs_dbg(FYI, "XATTR cap\n");
3058
		if (cap & CIFS_UNIX_POSIX_ACL_CAP)
3059
			cifs_dbg(FYI, "POSIX ACL cap\n");
3060
		if (cap & CIFS_UNIX_LARGE_READ_CAP)
3061
			cifs_dbg(FYI, "very large read cap\n");
3062
		if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
3063
			cifs_dbg(FYI, "very large write cap\n");
3064
		if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)
3065
			cifs_dbg(FYI, "transport encryption cap\n");
3066
		if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
3067
			cifs_dbg(FYI, "mandatory transport encryption cap\n");
3068 3069
#endif /* CIFS_DEBUG2 */
		if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
3070
			if (ctx == NULL)
3071
				cifs_dbg(FYI, "resetting capabilities failed\n");
3072
			else
3073
				cifs_dbg(VFS, "Negotiating Unix capabilities with the server failed. Consider mounting with the Unix Extensions disabled if problems are found by specifying the nounix mount option.\n");
3074

3075 3076 3077
		}
	}
}
3078
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
3079

3080
int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
3081
{
3082 3083
	struct smb3_fs_context *ctx = cifs_sb->ctx;

3084 3085
	INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);

3086 3087 3088
	spin_lock_init(&cifs_sb->tlink_tree_lock);
	cifs_sb->tlink_tree = RB_ROOT;

3089
	cifs_dbg(FYI, "file mode: %04ho  dir mode: %04ho\n",
3090
		 ctx->file_mode, ctx->dir_mode);
S
Steve French 已提交
3091

3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104
	/* this is needed for ASCII cp to Unicode converts */
	if (ctx->iocharset == NULL) {
		/* load_nls_default cannot return null */
		cifs_sb->local_nls = load_nls_default();
	} else {
		cifs_sb->local_nls = load_nls(ctx->iocharset);
		if (cifs_sb->local_nls == NULL) {
			cifs_dbg(VFS, "CIFS mount error: iocharset %s not found\n",
				 ctx->iocharset);
			return -ELIBACC;
		}
	}
	ctx->local_nls = cifs_sb->local_nls;
3105

3106 3107 3108
	smb3_update_mnt_flags(cifs_sb);

	if (ctx->direct_io)
3109
		cifs_dbg(FYI, "mounting share using direct i/o\n");
3110
	if (ctx->cache_ro) {
3111 3112
		cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n");
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE;
3113
	} else if (ctx->cache_rw) {
3114 3115 3116
		cifs_dbg(VFS, "mounting share in single client RW caching mode. Ensure that no other systems will be accessing the share.\n");
		cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE |
					    CIFS_MOUNT_RW_CACHE);
3117
	}
S
Steve French 已提交
3118

3119
	if ((ctx->cifs_acl) && (ctx->dynperm))
3120
		cifs_dbg(VFS, "mount option dynperm ignored if cifsacl mount option supported\n");
3121

3122 3123
	if (ctx->prepath) {
		cifs_sb->prepath = kstrdup(ctx->prepath, GFP_KERNEL);
3124 3125
		if (cifs_sb->prepath == NULL)
			return -ENOMEM;
3126
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
3127 3128 3129
	}

	return 0;
3130 3131
}

P
Paulo Alcantara 已提交
3132
/* Release all succeed connections */
3133
void cifs_mount_put_conns(struct cifs_mount_ctx *mnt_ctx)
P
Paulo Alcantara 已提交
3134 3135 3136
{
	int rc = 0;

3137 3138 3139 3140 3141 3142 3143 3144
	if (mnt_ctx->tcon)
		cifs_put_tcon(mnt_ctx->tcon);
	else if (mnt_ctx->ses)
		cifs_put_smb_ses(mnt_ctx->ses);
	else if (mnt_ctx->server)
		cifs_put_tcp_session(mnt_ctx->server, 0);
	mnt_ctx->cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_POSIX_PATHS;
	free_xid(mnt_ctx->xid);
P
Paulo Alcantara 已提交
3145 3146
}

3147
int cifs_mount_get_session(struct cifs_mount_ctx *mnt_ctx)
P
Paulo Alcantara 已提交
3148
{
3149
	struct TCP_Server_Info *server = NULL;
3150
	struct smb3_fs_context *ctx;
3151 3152
	struct cifs_ses *ses = NULL;
	unsigned int xid;
3153
	int rc = 0;
P
Paulo Alcantara 已提交
3154

3155
	xid = get_xid();
P
Paulo Alcantara 已提交
3156

3157 3158 3159 3160 3161 3162
	if (WARN_ON_ONCE(!mnt_ctx || !mnt_ctx->fs_ctx)) {
		rc = -EINVAL;
		goto out;
	}
	ctx = mnt_ctx->fs_ctx;

P
Paulo Alcantara 已提交
3163
	/* get a reference to a tcp session */
3164
	server = cifs_get_tcp_session(ctx, NULL);
P
Paulo Alcantara 已提交
3165 3166
	if (IS_ERR(server)) {
		rc = PTR_ERR(server);
3167 3168
		server = NULL;
		goto out;
P
Paulo Alcantara 已提交
3169 3170 3171
	}

	/* get a reference to a SMB session */
3172
	ses = cifs_get_smb_ses(server, ctx);
P
Paulo Alcantara 已提交
3173 3174
	if (IS_ERR(ses)) {
		rc = PTR_ERR(ses);
3175 3176
		ses = NULL;
		goto out;
P
Paulo Alcantara 已提交
3177 3178
	}

3179
	if ((ctx->persistent == true) && (!(ses->server->capabilities &
P
Paulo Alcantara 已提交
3180
					    SMB2_GLOBAL_CAP_PERSISTENT_HANDLES))) {
3181
		cifs_server_dbg(VFS, "persistent handles not supported by server\n");
3182
		rc = -EOPNOTSUPP;
3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204
	}

out:
	mnt_ctx->xid = xid;
	mnt_ctx->server = server;
	mnt_ctx->ses = ses;
	mnt_ctx->tcon = NULL;

	return rc;
}

int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
{
	struct TCP_Server_Info *server;
	struct cifs_sb_info *cifs_sb;
	struct smb3_fs_context *ctx;
	struct cifs_tcon *tcon = NULL;
	int rc = 0;

	if (WARN_ON_ONCE(!mnt_ctx || !mnt_ctx->server || !mnt_ctx->ses || !mnt_ctx->fs_ctx ||
			 !mnt_ctx->cifs_sb)) {
		rc = -EINVAL;
3205
		goto out;
P
Paulo Alcantara 已提交
3206
	}
3207 3208 3209
	server = mnt_ctx->server;
	ctx = mnt_ctx->fs_ctx;
	cifs_sb = mnt_ctx->cifs_sb;
P
Paulo Alcantara 已提交
3210 3211

	/* search for existing tcon to this server share */
3212
	tcon = cifs_get_tcon(mnt_ctx->ses, ctx);
P
Paulo Alcantara 已提交
3213 3214
	if (IS_ERR(tcon)) {
		rc = PTR_ERR(tcon);
3215 3216
		tcon = NULL;
		goto out;
P
Paulo Alcantara 已提交
3217 3218 3219 3220 3221 3222
	}

	/* if new SMB3.11 POSIX extensions are supported do not remap / and \ */
	if (tcon->posix_extensions)
		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;

3223
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
P
Paulo Alcantara 已提交
3224 3225 3226 3227 3228 3229
	/* tell server which Unix caps we support */
	if (cap_unix(tcon->ses)) {
		/*
		 * reset of caps checks mount to see if unix extensions disabled
		 * for just this mount.
		 */
3230
		reset_cifs_unix_caps(mnt_ctx->xid, tcon, cifs_sb, ctx);
3231
		spin_lock(&tcon->ses->server->srv_lock);
P
Paulo Alcantara 已提交
3232 3233
		if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&
		    (le64_to_cpu(tcon->fsUnixInfo.Capability) &
3234
		     CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) {
3235
			spin_unlock(&tcon->ses->server->srv_lock);
3236 3237 3238
			rc = -EACCES;
			goto out;
		}
3239
		spin_unlock(&tcon->ses->server->srv_lock);
P
Paulo Alcantara 已提交
3240
	} else
3241
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
P
Paulo Alcantara 已提交
3242 3243 3244
		tcon->unix_ext = 0; /* server does not support them */

	/* do not care if a following call succeed - informational */
3245
	if (!tcon->pipe && server->ops->qfs_tcon) {
3246
		server->ops->qfs_tcon(mnt_ctx->xid, tcon, cifs_sb);
3247 3248
		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) {
			if (tcon->fsDevInfo.DeviceCharacteristics &
3249
			    cpu_to_le32(FILE_READ_ONLY_DEVICE))
3250
				cifs_dbg(VFS, "mounted to read only share\n");
3251 3252
			else if ((cifs_sb->mnt_cifs_flags &
				  CIFS_MOUNT_RW_CACHE) == 0)
3253
				cifs_dbg(VFS, "read only mount of RW share\n");
3254
			/* no need to log a RW mount of a typical RW share */
3255 3256
		}
	}
P
Paulo Alcantara 已提交
3257

3258 3259
	/*
	 * Clamp the rsize/wsize mount arguments if they are too big for the server
3260 3261
	 * and set the rsize/wsize to the negotiated values if not passed in by
	 * the user on mount
3262
	 */
3263 3264
	if ((cifs_sb->ctx->wsize == 0) ||
	    (cifs_sb->ctx->wsize > server->ops->negotiate_wsize(tcon, ctx)))
3265
		cifs_sb->ctx->wsize = server->ops->negotiate_wsize(tcon, ctx);
3266 3267
	if ((cifs_sb->ctx->rsize == 0) ||
	    (cifs_sb->ctx->rsize > server->ops->negotiate_rsize(tcon, ctx)))
3268
		cifs_sb->ctx->rsize = server->ops->negotiate_rsize(tcon, ctx);
P
Paulo Alcantara 已提交
3269

3270 3271 3272 3273 3274
	/*
	 * 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.
	 */
3275 3276
	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE)
		cifs_fscache_get_super_cookie(tcon);
3277

3278 3279 3280
out:
	mnt_ctx->tcon = tcon;
	return rc;
P
Paulo Alcantara 已提交
3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307
}

static int mount_setup_tlink(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
			     struct cifs_tcon *tcon)
{
	struct tcon_link *tlink;

	/* hang the tcon off of the superblock */
	tlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
	if (tlink == NULL)
		return -ENOMEM;

	tlink->tl_uid = ses->linux_uid;
	tlink->tl_tcon = tcon;
	tlink->tl_time = jiffies;
	set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
	set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);

	cifs_sb->master_tlink = tlink;
	spin_lock(&cifs_sb->tlink_tree_lock);
	tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
	spin_unlock(&cifs_sb->tlink_tree_lock);

	queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks,
				TLINK_IDLE_EXPIRE);
	return 0;
}
J
Jeff Layton 已提交
3308

3309 3310 3311 3312 3313
static int
cifs_are_all_path_components_accessible(struct TCP_Server_Info *server,
					unsigned int xid,
					struct cifs_tcon *tcon,
					struct cifs_sb_info *cifs_sb,
3314 3315
					char *full_path,
					int added_treename)
3316 3317 3318 3319
{
	int rc;
	char *s;
	char sep, tmp;
3320
	int skip = added_treename ? 1 : 0;
3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334

	sep = CIFS_DIR_SEP(cifs_sb);
	s = full_path;

	rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, "");
	while (rc == 0) {
		/* skip separators */
		while (*s == sep)
			s++;
		if (!*s)
			break;
		/* next separator */
		while (*s && *s != sep)
			s++;
3335 3336 3337 3338 3339 3340 3341 3342
		/*
		 * if the treename is added, we then have to skip the first
		 * part within the separators
		 */
		if (skip) {
			skip = 0;
			continue;
		}
3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355
		/*
		 * temporarily null-terminate the path at the end of
		 * the current component
		 */
		tmp = *s;
		*s = 0;
		rc = server->ops->is_path_accessible(xid, tcon, cifs_sb,
						     full_path);
		*s = tmp;
	}
	return rc;
}

P
Paulo Alcantara 已提交
3356
/*
3357 3358 3359
 * Check if path is remote (i.e. a DFS share).
 *
 * Return -EREMOTE if it is, otherwise 0 or -errno.
P
Paulo Alcantara 已提交
3360
 */
3361
int cifs_is_path_remote(struct cifs_mount_ctx *mnt_ctx)
3362
{
3363
	int rc;
3364 3365 3366 3367 3368
	struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
	struct TCP_Server_Info *server = mnt_ctx->server;
	unsigned int xid = mnt_ctx->xid;
	struct cifs_tcon *tcon = mnt_ctx->tcon;
	struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
P
Paulo Alcantara 已提交
3369
	char *full_path;
3370

P
Paulo Alcantara 已提交
3371 3372
	if (!server->ops->is_path_accessible)
		return -EOPNOTSUPP;
3373

P
Paulo Alcantara 已提交
3374 3375 3376
	/*
	 * cifs_build_path_to_root works only when we have a valid tcon
	 */
3377
	full_path = cifs_build_path_to_root(ctx, cifs_sb, tcon,
P
Paulo Alcantara 已提交
3378 3379 3380
					    tcon->Flags & SMB_SHARE_IS_IN_DFS);
	if (full_path == NULL)
		return -ENOMEM;
3381

P
Paulo Alcantara 已提交
3382
	cifs_dbg(FYI, "%s: full_path: %s\n", __func__, full_path);
L
Linus Torvalds 已提交
3383

P
Paulo Alcantara 已提交
3384 3385
	rc = server->ops->is_path_accessible(xid, tcon, cifs_sb,
					     full_path);
3386 3387
	if (rc != 0 && rc != -EREMOTE)
		goto out;
S
Steve French 已提交
3388

P
Paulo Alcantara 已提交
3389 3390
	if (rc != -EREMOTE) {
		rc = cifs_are_all_path_components_accessible(server, xid, tcon,
3391
			cifs_sb, full_path, tcon->Flags & SMB_SHARE_IS_IN_DFS);
P
Paulo Alcantara 已提交
3392
		if (rc != 0) {
J
Joe Perches 已提交
3393
			cifs_server_dbg(VFS, "cannot query dirs between root and final path, enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
P
Paulo Alcantara 已提交
3394 3395 3396
			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
			rc = 0;
		}
3397
	}
I
Igor Mammedov 已提交
3398

3399
out:
P
Paulo Alcantara 已提交
3400 3401 3402
	kfree(full_path);
	return rc;
}
3403

P
Paulo Alcantara 已提交
3404
#ifdef CONFIG_CIFS_DFS_UPCALL
3405 3406
int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
{
3407
	struct cifs_mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, };
3408
	bool isdfs;
3409
	int rc;
3410

3411 3412
	INIT_LIST_HEAD(&mnt_ctx.dfs_ses_list);

3413
	rc = dfs_mount_share(&mnt_ctx, &isdfs);
3414
	if (rc)
P
Paulo Alcantara 已提交
3415
		goto error;
3416 3417
	if (!isdfs)
		goto out;
3418

3419
	/*
3420 3421
	 * After reconnecting to a different server, unique ids won't match anymore, so we disable
	 * serverino. This prevents dentry revalidation to think the dentry are stale (ESTALE).
3422 3423
	 */
	cifs_autodisable_serverino(cifs_sb);
3424
	/*
3425 3426
	 * Force the use of prefix path to support failover on DFS paths that resolve to targets
	 * that have different prefix paths.
3427 3428 3429
	 */
	cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
	kfree(cifs_sb->prepath);
3430 3431
	cifs_sb->prepath = ctx->prepath;
	ctx->prepath = NULL;
3432

P
Paulo Alcantara 已提交
3433
out:
3434
	cifs_try_adding_channels(cifs_sb, mnt_ctx.ses);
3435 3436 3437 3438 3439 3440
	rc = mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon);
	if (rc)
		goto error;

	free_xid(mnt_ctx.xid);
	return rc;
3441

P
Paulo Alcantara 已提交
3442
error:
3443
	dfs_put_root_smb_sessions(&mnt_ctx.dfs_ses_list);
3444 3445
	kfree(mnt_ctx.origin_fullpath);
	kfree(mnt_ctx.leaf_fullpath);
3446
	cifs_mount_put_conns(&mnt_ctx);
P
Paulo Alcantara 已提交
3447 3448 3449
	return rc;
}
#else
3450
int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
P
Paulo Alcantara 已提交
3451 3452
{
	int rc = 0;
3453
	struct cifs_mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, };
3454

3455
	rc = cifs_mount_get_session(&mnt_ctx);
P
Paulo Alcantara 已提交
3456 3457
	if (rc)
		goto error;
3458

3459 3460 3461 3462 3463 3464 3465 3466 3467
	rc = cifs_mount_get_tcon(&mnt_ctx);
	if (rc)
		goto error;

	rc = cifs_is_path_remote(&mnt_ctx);
	if (rc == -EREMOTE)
		rc = -EOPNOTSUPP;
	if (rc)
		goto error;
I
Igor Mammedov 已提交
3468

3469 3470 3471 3472
	rc = mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon);
	if (rc)
		goto error;

3473
	free_xid(mnt_ctx.xid);
3474
	return rc;
P
Paulo Alcantara 已提交
3475 3476

error:
3477
	cifs_mount_put_conns(&mnt_ctx);
L
Linus Torvalds 已提交
3478 3479
	return rc;
}
P
Paulo Alcantara 已提交
3480
#endif
L
Linus Torvalds 已提交
3481

3482
/*
A
Aurelien Aptel 已提交
3483
 * Issue a TREE_CONNECT request.
3484
 */
L
Linus Torvalds 已提交
3485
int
3486
CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
3487
	 const char *tree, struct cifs_tcon *tcon,
L
Linus Torvalds 已提交
3488 3489 3490 3491 3492 3493 3494 3495
	 const struct nls_table *nls_codepage)
{
	struct smb_hdr *smb_buffer;
	struct smb_hdr *smb_buffer_response;
	TCONX_REQ *pSMB;
	TCONX_RSP *pSMBr;
	unsigned char *bcc_ptr;
	int rc = 0;
3496 3497
	int length;
	__u16 bytes_left, count;
L
Linus Torvalds 已提交
3498 3499 3500 3501 3502

	if (ses == NULL)
		return -EIO;

	smb_buffer = cifs_buf_get();
S
Steve French 已提交
3503
	if (smb_buffer == NULL)
L
Linus Torvalds 已提交
3504
		return -ENOMEM;
S
Steve French 已提交
3505

L
Linus Torvalds 已提交
3506 3507 3508 3509
	smb_buffer_response = smb_buffer;

	header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
			NULL /*no tid */ , 4 /*wct */ );
3510

3511
	smb_buffer->Mid = get_next_mid(ses->server);
L
Linus Torvalds 已提交
3512 3513 3514 3515 3516 3517 3518
	smb_buffer->Uid = ses->Suid;
	pSMB = (TCONX_REQ *) smb_buffer;
	pSMBr = (TCONX_RSP *) smb_buffer_response;

	pSMB->AndXCommand = 0xFF;
	pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
	bcc_ptr = &pSMB->Password[0];
3519 3520 3521 3522 3523

	pSMB->PasswordLength = cpu_to_le16(1);	/* minimum */
	*bcc_ptr = 0; /* password is null byte */
	bcc_ptr++;              /* skip password */
	/* already aligned so no need to do it below */
L
Linus Torvalds 已提交
3524

3525
	if (ses->server->sign)
L
Linus Torvalds 已提交
3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536
		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;

	if (ses->capabilities & CAP_STATUS32) {
		smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
	}
	if (ses->capabilities & CAP_DFS) {
		smb_buffer->Flags2 |= SMBFLG2_DFS;
	}
	if (ses->capabilities & CAP_UNICODE) {
		smb_buffer->Flags2 |= SMBFLG2_UNICODE;
		length =
3537
		    cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
3538
			6 /* max utf8 char length in bytes */ *
3539 3540
			(/* server len*/ + 256 /* share len */), nls_codepage);
		bcc_ptr += 2 * length;	/* convert num 16 bit words to bytes */
L
Linus Torvalds 已提交
3541 3542 3543 3544 3545 3546 3547 3548 3549
		bcc_ptr += 2;	/* skip trailing null */
	} else {		/* ASCII */
		strcpy(bcc_ptr, tree);
		bcc_ptr += strlen(tree) + 1;
	}
	strcpy(bcc_ptr, "?????");
	bcc_ptr += strlen("?????");
	bcc_ptr += 1;
	count = bcc_ptr - &pSMB->Password[0];
3550
	be32_add_cpu(&pSMB->hdr.smb_buf_length, count);
L
Linus Torvalds 已提交
3551 3552
	pSMB->ByteCount = cpu_to_le16(count);

3553
	rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3554
			 0);
L
Linus Torvalds 已提交
3555 3556

	/* above now done in SendReceive */
A
Aurelien Aptel 已提交
3557
	if (rc == 0) {
3558 3559
		bool is_unicode;

L
Linus Torvalds 已提交
3560 3561
		tcon->tid = smb_buffer_response->Tid;
		bcc_ptr = pByteArea(smb_buffer_response);
3562
		bytes_left = get_bcc(smb_buffer_response);
3563
		length = strnlen(bcc_ptr, bytes_left - 2);
3564 3565 3566 3567 3568
		if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
			is_unicode = true;
		else
			is_unicode = false;

3569

3570
		/* skip service field (NB: this field is always ASCII) */
3571 3572 3573
		if (length == 3) {
			if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
			    (bcc_ptr[2] == 'C')) {
3574
				cifs_dbg(FYI, "IPC connection\n");
A
Aurelien Aptel 已提交
3575 3576
				tcon->ipc = true;
				tcon->pipe = true;
3577 3578 3579 3580
			}
		} else if (length == 2) {
			if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
				/* the most common case */
3581
				cifs_dbg(FYI, "disk share connection\n");
3582 3583
			}
		}
3584
		bcc_ptr += length + 1;
3585
		bytes_left -= (length + 1);
3586
		strscpy(tcon->tree_name, tree, sizeof(tcon->tree_name));
3587 3588

		/* mostly informational -- no need to fail on error here */
3589
		kfree(tcon->nativeFileSystem);
3590
		tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
3591
						      bytes_left, is_unicode,
3592 3593
						      nls_codepage);

3594
		cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
3595

S
Steve French 已提交
3596
		if ((smb_buffer_response->WordCount == 3) ||
S
Steve French 已提交
3597 3598
			 (smb_buffer_response->WordCount == 7))
			/* field is in same location */
3599 3600 3601
			tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
		else
			tcon->Flags = 0;
3602
		cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
L
Linus Torvalds 已提交
3603 3604
	}

3605
	cifs_buf_release(smb_buffer);
L
Linus Torvalds 已提交
3606 3607 3608
	return rc;
}

3609 3610
static void delayed_free(struct rcu_head *p)
{
3611 3612 3613
	struct cifs_sb_info *cifs_sb = container_of(p, struct cifs_sb_info, rcu);

	unload_nls(cifs_sb->local_nls);
3614
	smb3_cleanup_fs_context(cifs_sb->ctx);
3615
	kfree(cifs_sb);
3616 3617
}

A
Al Viro 已提交
3618 3619
void
cifs_umount(struct cifs_sb_info *cifs_sb)
L
Linus Torvalds 已提交
3620
{
J
Jeff Layton 已提交
3621 3622 3623
	struct rb_root *root = &cifs_sb->tlink_tree;
	struct rb_node *node;
	struct tcon_link *tlink;
3624

3625 3626
	cancel_delayed_work_sync(&cifs_sb->prune_tlinks);

J
Jeff Layton 已提交
3627 3628 3629 3630 3631 3632
	spin_lock(&cifs_sb->tlink_tree_lock);
	while ((node = rb_first(root))) {
		tlink = rb_entry(node, struct tcon_link, tl_rbnode);
		cifs_get_tlink(tlink);
		clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
		rb_erase(node, root);
L
Linus Torvalds 已提交
3633

J
Jeff Layton 已提交
3634 3635 3636 3637 3638
		spin_unlock(&cifs_sb->tlink_tree_lock);
		cifs_put_tlink(tlink);
		spin_lock(&cifs_sb->tlink_tree_lock);
	}
	spin_unlock(&cifs_sb->tlink_tree_lock);
3639

3640
	kfree(cifs_sb->prepath);
3641
	call_rcu(&cifs_sb->rcu, delayed_free);
3642
}
L
Linus Torvalds 已提交
3643

3644
int
3645 3646
cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses,
			struct TCP_Server_Info *server)
L
Linus Torvalds 已提交
3647 3648 3649
{
	int rc = 0;

3650 3651 3652
	if (!server->ops->need_neg || !server->ops->negotiate)
		return -ENOSYS;

3653
	/* only send once per connect */
3654
	spin_lock(&server->srv_lock);
3655 3656
	if (!server->ops->need_neg(server) ||
	    server->tcpStatus != CifsNeedNegotiate) {
3657
		spin_unlock(&server->srv_lock);
3658
		return 0;
3659 3660
	}
	server->tcpStatus = CifsInNegotiate;
3661
	spin_unlock(&server->srv_lock);
3662

3663
	rc = server->ops->negotiate(xid, ses, server);
3664
	if (rc == 0) {
3665
		spin_lock(&server->srv_lock);
3666
		if (server->tcpStatus == CifsInNegotiate)
3667
			server->tcpStatus = CifsGood;
3668 3669
		else
			rc = -EHOSTDOWN;
3670
		spin_unlock(&server->srv_lock);
3671
	} else {
3672
		spin_lock(&server->srv_lock);
3673 3674
		if (server->tcpStatus == CifsInNegotiate)
			server->tcpStatus = CifsNeedNegotiate;
3675
		spin_unlock(&server->srv_lock);
3676 3677 3678 3679 3680
	}

	return rc;
}

3681 3682
int
cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
3683
		   struct TCP_Server_Info *server,
3684
		   struct nls_table *nls_info)
3685
{
3686
	int rc = -ENOSYS;
3687 3688 3689
	struct TCP_Server_Info *pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
	struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&pserver->dstaddr;
	struct sockaddr_in *addr = (struct sockaddr_in *)&pserver->dstaddr;
3690
	bool is_binding = false;
3691

3692
	spin_lock(&ses->ses_lock);
3693 3694 3695
	if (ses->ses_status != SES_GOOD &&
	    ses->ses_status != SES_NEW &&
	    ses->ses_status != SES_NEED_RECON) {
3696
		spin_unlock(&ses->ses_lock);
3697 3698
		return 0;
	}
3699

3700 3701 3702 3703 3704
	/* only send once per connect */
	spin_lock(&ses->chan_lock);
	if (CIFS_ALL_CHANS_GOOD(ses) ||
	    cifs_chan_in_reconnect(ses, server)) {
		spin_unlock(&ses->chan_lock);
3705
		spin_unlock(&ses->ses_lock);
3706 3707 3708 3709 3710 3711
		return 0;
	}
	is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
	cifs_chan_set_in_reconnect(ses, server);
	spin_unlock(&ses->chan_lock);

3712 3713
	if (!is_binding)
		ses->ses_status = SES_IN_SETUP;
3714
	spin_unlock(&ses->ses_lock);
3715

3716 3717 3718 3719 3720 3721 3722 3723
	/* update ses ip_addr only for primary chan */
	if (server == pserver) {
		if (server->dstaddr.ss_family == AF_INET6)
			scnprintf(ses->ip_addr, sizeof(ses->ip_addr), "%pI6", &addr6->sin6_addr);
		else
			scnprintf(ses->ip_addr, sizeof(ses->ip_addr), "%pI4", &addr->sin_addr);
	}

3724
	if (!is_binding) {
3725
		ses->capabilities = server->capabilities;
3726
		if (!linuxExtEnabled)
3727 3728 3729 3730 3731
			ses->capabilities &= (~server->vals->cap_unix);

		if (ses->auth_key.response) {
			cifs_dbg(FYI, "Free previous auth_key.response = %p\n",
				 ses->auth_key.response);
3732
			kfree_sensitive(ses->auth_key.response);
3733 3734 3735 3736
			ses->auth_key.response = NULL;
			ses->auth_key.len = 0;
		}
	}
3737

3738
	cifs_dbg(FYI, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d\n",
3739
		 server->sec_mode, server->capabilities, server->timeAdj);
3740

3741
	if (server->ops->sess_setup)
3742
		rc = server->ops->sess_setup(xid, ses, server, nls_info);
3743

3744
	if (rc) {
3745
		cifs_server_dbg(VFS, "Send error in SessSetup = %d\n", rc);
3746
		spin_lock(&ses->ses_lock);
3747 3748
		if (ses->ses_status == SES_IN_SETUP)
			ses->ses_status = SES_NEED_RECON;
3749 3750 3751
		spin_lock(&ses->chan_lock);
		cifs_chan_clear_in_reconnect(ses, server);
		spin_unlock(&ses->chan_lock);
3752
		spin_unlock(&ses->ses_lock);
3753
	} else {
3754
		spin_lock(&ses->ses_lock);
3755 3756
		if (ses->ses_status == SES_IN_SETUP)
			ses->ses_status = SES_GOOD;
3757
		spin_lock(&ses->chan_lock);
3758
		cifs_chan_clear_in_reconnect(ses, server);
3759 3760
		cifs_chan_clear_need_reconnect(ses, server);
		spin_unlock(&ses->chan_lock);
3761
		spin_unlock(&ses->ses_lock);
3762
	}
3763

L
Linus Torvalds 已提交
3764 3765 3766
	return rc;
}

3767
static int
3768
cifs_set_vol_auth(struct smb3_fs_context *ctx, struct cifs_ses *ses)
3769
{
3770
	ctx->sectype = ses->sectype;
3771 3772

	/* krb5 is special, since we don't need username or pw */
3773
	if (ctx->sectype == Kerberos)
3774 3775
		return 0;

3776
	return cifs_set_cifscreds(ctx, ses);
3777 3778
}

3779
static struct cifs_tcon *
3780
cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
3781
{
3782
	int rc;
3783 3784 3785
	struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb);
	struct cifs_ses *ses;
	struct cifs_tcon *tcon = NULL;
3786
	struct smb3_fs_context *ctx;
3787

3788 3789
	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (ctx == NULL)
3790
		return ERR_PTR(-ENOMEM);
3791

3792 3793 3794
	ctx->local_nls = cifs_sb->local_nls;
	ctx->linux_uid = fsuid;
	ctx->cred_uid = fsuid;
3795
	ctx->UNC = master_tcon->tree_name;
3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808
	ctx->retry = master_tcon->retry;
	ctx->nocase = master_tcon->nocase;
	ctx->nohandlecache = master_tcon->nohandlecache;
	ctx->local_lease = master_tcon->local_lease;
	ctx->no_lease = master_tcon->no_lease;
	ctx->resilient = master_tcon->use_resilient;
	ctx->persistent = master_tcon->use_persistent;
	ctx->handle_timeout = master_tcon->handle_timeout;
	ctx->no_linux_ext = !master_tcon->unix_ext;
	ctx->linux_ext = master_tcon->posix_extensions;
	ctx->sectype = master_tcon->ses->sectype;
	ctx->sign = master_tcon->ses->sign;
	ctx->seal = master_tcon->seal;
3809
	ctx->witness = master_tcon->use_witness;
3810 3811

	rc = cifs_set_vol_auth(ctx, master_tcon->ses);
3812 3813 3814 3815
	if (rc) {
		tcon = ERR_PTR(rc);
		goto out;
	}
3816 3817

	/* get a reference for the same TCP session */
3818
	spin_lock(&cifs_tcp_ses_lock);
3819
	++master_tcon->ses->server->srv_count;
3820
	spin_unlock(&cifs_tcp_ses_lock);
3821

3822
	ses = cifs_get_smb_ses(master_tcon->ses->server, ctx);
3823
	if (IS_ERR(ses)) {
3824
		tcon = (struct cifs_tcon *)ses;
3825
		cifs_put_tcp_session(master_tcon->ses->server, 0);
3826 3827 3828
		goto out;
	}

3829
	tcon = cifs_get_tcon(ses, ctx);
3830 3831 3832 3833 3834
	if (IS_ERR(tcon)) {
		cifs_put_smb_ses(ses);
		goto out;
	}

3835
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
3836
	if (cap_unix(ses))
3837
		reset_cifs_unix_caps(0, tcon, NULL, ctx);
3838
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
3839

3840
out:
3841 3842 3843
	kfree(ctx->username);
	kfree_sensitive(ctx->password);
	kfree(ctx);
3844 3845 3846 3847

	return tcon;
}

3848
struct cifs_tcon *
3849 3850 3851 3852 3853
cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
{
	return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
}

J
Jeff Layton 已提交
3854 3855
/* find and return a tlink with given uid */
static struct tcon_link *
3856
tlink_rb_search(struct rb_root *root, kuid_t uid)
J
Jeff Layton 已提交
3857 3858 3859 3860 3861 3862 3863
{
	struct rb_node *node = root->rb_node;
	struct tcon_link *tlink;

	while (node) {
		tlink = rb_entry(node, struct tcon_link, tl_rbnode);

3864
		if (uid_gt(tlink->tl_uid, uid))
J
Jeff Layton 已提交
3865
			node = node->rb_left;
3866
		else if (uid_lt(tlink->tl_uid, uid))
J
Jeff Layton 已提交
3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884
			node = node->rb_right;
		else
			return tlink;
	}
	return NULL;
}

/* insert a tcon_link into the tree */
static void
tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
{
	struct rb_node **new = &(root->rb_node), *parent = NULL;
	struct tcon_link *tlink;

	while (*new) {
		tlink = rb_entry(*new, struct tcon_link, tl_rbnode);
		parent = *new;

3885
		if (uid_gt(tlink->tl_uid, new_tlink->tl_uid))
J
Jeff Layton 已提交
3886 3887 3888 3889 3890 3891 3892 3893 3894
			new = &((*new)->rb_left);
		else
			new = &((*new)->rb_right);
	}

	rb_link_node(&new_tlink->tl_rbnode, parent, new);
	rb_insert_color(&new_tlink->tl_rbnode, root);
}

3895 3896 3897 3898 3899 3900 3901
/*
 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
 * current task.
 *
 * If the superblock doesn't refer to a multiuser mount, then just return
 * the master tcon for the mount.
 *
3902
 * First, search the rbtree for an existing tcon for this fsuid. If one
3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914
 * exists, then check to see if it's pending construction. If it is then wait
 * for construction to complete. Once it's no longer pending, check to see if
 * it failed and either return an error or retry construction, depending on
 * the timeout.
 *
 * If one doesn't exist then insert a new tcon_link struct into the tree and
 * try to construct a new one.
 */
struct tcon_link *
cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
{
	int ret;
3915
	kuid_t fsuid = current_fsuid();
3916 3917 3918 3919 3920 3921
	struct tcon_link *tlink, *newtlink;

	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
		return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));

	spin_lock(&cifs_sb->tlink_tree_lock);
J
Jeff Layton 已提交
3922
	tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
3923 3924 3925 3926 3927 3928 3929 3930
	if (tlink)
		cifs_get_tlink(tlink);
	spin_unlock(&cifs_sb->tlink_tree_lock);

	if (tlink == NULL) {
		newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
		if (newtlink == NULL)
			return ERR_PTR(-ENOMEM);
J
Jeff Layton 已提交
3931
		newtlink->tl_uid = fsuid;
3932 3933 3934 3935 3936 3937 3938
		newtlink->tl_tcon = ERR_PTR(-EACCES);
		set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
		set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
		cifs_get_tlink(newtlink);

		spin_lock(&cifs_sb->tlink_tree_lock);
		/* was one inserted after previous search? */
J
Jeff Layton 已提交
3939
		tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
3940 3941 3942 3943 3944 3945 3946
		if (tlink) {
			cifs_get_tlink(tlink);
			spin_unlock(&cifs_sb->tlink_tree_lock);
			kfree(newtlink);
			goto wait_for_construction;
		}
		tlink = newtlink;
J
Jeff Layton 已提交
3947 3948
		tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
		spin_unlock(&cifs_sb->tlink_tree_lock);
3949 3950 3951 3952 3953 3954
	} else {
wait_for_construction:
		ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
				  TASK_INTERRUPTIBLE);
		if (ret) {
			cifs_put_tlink(tlink);
3955
			return ERR_PTR(-ERESTARTSYS);
3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982
		}

		/* if it's good, return it */
		if (!IS_ERR(tlink->tl_tcon))
			return tlink;

		/* return error if we tried this already recently */
		if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
			cifs_put_tlink(tlink);
			return ERR_PTR(-EACCES);
		}

		if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
			goto wait_for_construction;
	}

	tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
	clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
	wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);

	if (IS_ERR(tlink->tl_tcon)) {
		cifs_put_tlink(tlink);
		return ERR_PTR(-EACCES);
	}

	return tlink;
}
3983 3984 3985 3986 3987 3988 3989 3990 3991 3992

/*
 * periodic workqueue job that scans tcon_tree for a superblock and closes
 * out tcons.
 */
static void
cifs_prune_tlinks(struct work_struct *work)
{
	struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info,
						    prune_tlinks.work);
J
Jeff Layton 已提交
3993
	struct rb_root *root = &cifs_sb->tlink_tree;
3994
	struct rb_node *node;
J
Jeff Layton 已提交
3995 3996
	struct rb_node *tmp;
	struct tcon_link *tlink;
3997

J
Jeff Layton 已提交
3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015
	/*
	 * Because we drop the spinlock in the loop in order to put the tlink
	 * it's not guarded against removal of links from the tree. The only
	 * places that remove entries from the tree are this function and
	 * umounts. Because this function is non-reentrant and is canceled
	 * before umount can proceed, this is safe.
	 */
	spin_lock(&cifs_sb->tlink_tree_lock);
	node = rb_first(root);
	while (node != NULL) {
		tmp = node;
		node = rb_next(tmp);
		tlink = rb_entry(tmp, struct tcon_link, tl_rbnode);

		if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) ||
		    atomic_read(&tlink->tl_count) != 0 ||
		    time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies))
			continue;
4016

J
Jeff Layton 已提交
4017 4018 4019 4020 4021 4022 4023 4024 4025
		cifs_get_tlink(tlink);
		clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
		rb_erase(tmp, root);

		spin_unlock(&cifs_sb->tlink_tree_lock);
		cifs_put_tlink(tlink);
		spin_lock(&cifs_sb->tlink_tree_lock);
	}
	spin_unlock(&cifs_sb->tlink_tree_lock);
4026

J
Jeff Layton 已提交
4027
	queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks,
4028 4029
				TLINK_IDLE_EXPIRE);
}
4030

4031
#ifndef CONFIG_CIFS_DFS_UPCALL
4032 4033
int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc)
{
4034
	int rc;
4035 4036
	const struct smb_version_operations *ops = tcon->ses->server->ops;

4037
	/* only send once per connect */
4038
	spin_lock(&tcon->tc_lock);
4039
	if (tcon->ses->ses_status != SES_GOOD ||
4040 4041
	    (tcon->status != TID_NEW &&
	    tcon->status != TID_NEED_TCON)) {
4042
		spin_unlock(&tcon->tc_lock);
4043 4044
		return 0;
	}
4045
	tcon->status = TID_IN_TCON;
4046
	spin_unlock(&tcon->tc_lock);
4047

4048
	rc = ops->tree_connect(xid, tcon->ses, tcon->tree_name, tcon, nlsc);
4049
	if (rc) {
4050
		spin_lock(&tcon->tc_lock);
4051 4052
		if (tcon->status == TID_IN_TCON)
			tcon->status = TID_NEED_TCON;
4053
		spin_unlock(&tcon->tc_lock);
4054
	} else {
4055
		spin_lock(&tcon->tc_lock);
4056 4057
		if (tcon->status == TID_IN_TCON)
			tcon->status = TID_GOOD;
4058
		tcon->need_reconnect = false;
4059
		spin_unlock(&tcon->tc_lock);
4060 4061 4062
	}

	return rc;
4063 4064
}
#endif