connect.c 138 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3
/*
 *   fs/cifs/connect.c
 *
4
 *   Copyright (C) International Business Machines  Corp., 2002,2011
Linus Torvalds's avatar
Linus Torvalds committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *   the GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with this library; if not, write to the Free Software
Steve French's avatar
Steve French committed
19
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Linus Torvalds's avatar
Linus Torvalds committed
20 21 22 23
 */
#include <linux/fs.h>
#include <linux/net.h>
#include <linux/string.h>
24
#include <linux/sched/signal.h>
Linus Torvalds's avatar
Linus Torvalds committed
25 26
#include <linux/list.h>
#include <linux/wait.h>
27
#include <linux/slab.h>
Linus Torvalds's avatar
Linus Torvalds committed
28 29 30 31
#include <linux/pagemap.h>
#include <linux/ctype.h>
#include <linux/utsname.h>
#include <linux/mempool.h>
32
#include <linux/delay.h>
33
#include <linux/completion.h>
34
#include <linux/kthread.h>
35
#include <linux/pagevec.h>
36
#include <linux/freezer.h>
37
#include <linux/namei.h>
38
#include <linux/uuid.h>
39
#include <linux/uaccess.h>
Linus Torvalds's avatar
Linus Torvalds committed
40
#include <asm/processor.h>
41
#include <linux/inet.h>
42
#include <linux/module.h>
43
#include <keys/user-type.h>
44
#include <net/ipv6.h>
45
#include <linux/parser.h>
46
#include <linux/bvec.h>
Linus Torvalds's avatar
Linus Torvalds committed
47 48 49 50 51 52 53 54 55
#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"
56
#include "fscache.h"
57
#include "smb2proto.h"
58
#include "smbdirect.h"
59
#include "dns_resolve.h"
60
#include "cifsfs.h"
61 62 63
#ifdef CONFIG_CIFS_DFS_UPCALL
#include "dfs_cache.h"
#endif
Linus Torvalds's avatar
Linus Torvalds committed
64 65

extern mempool_t *cifs_req_poolp;
66
extern bool disable_legacy_dialects;
Linus Torvalds's avatar
Linus Torvalds committed
67

68
/* FIXME: should these be tunable? */
69
#define TLINK_ERROR_EXPIRE	(1 * HZ)
70
#define TLINK_IDLE_EXPIRE	(600 * HZ)
71

72 73 74 75
enum {
	/* Mount options that take no arguments */
	Opt_user_xattr, Opt_nouser_xattr,
	Opt_forceuid, Opt_noforceuid,
76
	Opt_forcegid, Opt_noforcegid,
77 78
	Opt_noblocksend, Opt_noautotune,
	Opt_hard, Opt_soft, Opt_perm, Opt_noperm,
79
	Opt_mapposix, Opt_nomapposix,
80 81
	Opt_mapchars, Opt_nomapchars, Opt_sfu,
	Opt_nosfu, Opt_nodfs, Opt_posixpaths,
82
	Opt_noposixpaths, Opt_nounix, Opt_unix,
83 84
	Opt_nocase,
	Opt_brl, Opt_nobrl,
85
	Opt_handlecache, Opt_nohandlecache,
86
	Opt_forcemandatorylock, Opt_setuidfromacl, Opt_setuids,
87 88 89 90 91 92 93
	Opt_nosetuids, Opt_dynperm, Opt_nodynperm,
	Opt_nohard, Opt_nosoft,
	Opt_nointr, Opt_intr,
	Opt_nostrictsync, Opt_strictsync,
	Opt_serverino, Opt_noserverino,
	Opt_rwpidforward, Opt_cifsacl, Opt_nocifsacl,
	Opt_acl, Opt_noacl, Opt_locallease,
94
	Opt_sign, Opt_seal, Opt_noac,
95
	Opt_fsc, Opt_mfsymlinks,
96
	Opt_multiuser, Opt_sloppy, Opt_nosharesock,
97
	Opt_persistent, Opt_nopersistent,
Steve French's avatar
Steve French committed
98
	Opt_resilient, Opt_noresilient,
99
	Opt_domainauto, Opt_rdma, Opt_modesid,
100
	Opt_compress,
101 102 103 104 105

	/* Mount options which take numeric value */
	Opt_backupuid, Opt_backupgid, Opt_uid,
	Opt_cruid, Opt_gid, Opt_file_mode,
	Opt_dirmode, Opt_port,
106
	Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo,
107
	Opt_echo_interval, Opt_max_credits, Opt_handletimeout,
108
	Opt_snapshot,
109 110 111

	/* Mount options which take string value */
	Opt_user, Opt_pass, Opt_ip,
112
	Opt_domain, Opt_srcaddr, Opt_iocharset,
113
	Opt_netbiosname, Opt_servern,
114
	Opt_ver, Opt_vers, Opt_sec, Opt_cache,
115 116 117 118 119 120

	/* Mount options to be ignored */
	Opt_ignore,

	/* Options which could be blank */
	Opt_blank_pass,
121 122
	Opt_blank_user,
	Opt_blank_ip,
123 124 125 126 127 128 129 130 131 132

	Opt_err
};

static const match_table_t cifs_mount_option_tokens = {

	{ Opt_user_xattr, "user_xattr" },
	{ Opt_nouser_xattr, "nouser_xattr" },
	{ Opt_forceuid, "forceuid" },
	{ Opt_noforceuid, "noforceuid" },
133 134
	{ Opt_forcegid, "forcegid" },
	{ Opt_noforcegid, "noforcegid" },
135 136 137 138 139 140
	{ Opt_noblocksend, "noblocksend" },
	{ Opt_noautotune, "noautotune" },
	{ Opt_hard, "hard" },
	{ Opt_soft, "soft" },
	{ Opt_perm, "perm" },
	{ Opt_noperm, "noperm" },
141
	{ Opt_mapchars, "mapchars" }, /* SFU style */
142
	{ Opt_nomapchars, "nomapchars" },
143 144
	{ Opt_mapposix, "mapposix" }, /* SFM style */
	{ Opt_nomapposix, "nomapposix" },
145 146 147 148 149 150 151
	{ Opt_sfu, "sfu" },
	{ Opt_nosfu, "nosfu" },
	{ Opt_nodfs, "nodfs" },
	{ Opt_posixpaths, "posixpaths" },
	{ Opt_noposixpaths, "noposixpaths" },
	{ Opt_nounix, "nounix" },
	{ Opt_nounix, "nolinux" },
152 153 154 155
	{ Opt_nounix, "noposix" },
	{ Opt_unix, "unix" },
	{ Opt_unix, "linux" },
	{ Opt_unix, "posix" },
156 157 158 159
	{ Opt_nocase, "nocase" },
	{ Opt_nocase, "ignorecase" },
	{ Opt_brl, "brl" },
	{ Opt_nobrl, "nobrl" },
160 161
	{ Opt_handlecache, "handlecache" },
	{ Opt_nohandlecache, "nohandlecache" },
162 163
	{ Opt_nobrl, "nolock" },
	{ Opt_forcemandatorylock, "forcemandatorylock" },
164
	{ Opt_forcemandatorylock, "forcemand" },
165 166
	{ Opt_setuids, "setuids" },
	{ Opt_nosetuids, "nosetuids" },
167
	{ Opt_setuidfromacl, "idsfromsid" },
168 169 170 171 172 173 174 175 176 177 178
	{ Opt_dynperm, "dynperm" },
	{ Opt_nodynperm, "nodynperm" },
	{ Opt_nohard, "nohard" },
	{ Opt_nosoft, "nosoft" },
	{ Opt_nointr, "nointr" },
	{ Opt_intr, "intr" },
	{ Opt_nostrictsync, "nostrictsync" },
	{ Opt_strictsync, "strictsync" },
	{ Opt_serverino, "serverino" },
	{ Opt_noserverino, "noserverino" },
	{ Opt_rwpidforward, "rwpidforward" },
179
	{ Opt_modesid, "modefromsid" },
180 181 182 183 184 185 186 187 188 189 190
	{ Opt_cifsacl, "cifsacl" },
	{ Opt_nocifsacl, "nocifsacl" },
	{ Opt_acl, "acl" },
	{ Opt_noacl, "noacl" },
	{ Opt_locallease, "locallease" },
	{ Opt_sign, "sign" },
	{ Opt_seal, "seal" },
	{ Opt_noac, "noac" },
	{ Opt_fsc, "fsc" },
	{ Opt_mfsymlinks, "mfsymlinks" },
	{ Opt_multiuser, "multiuser" },
191
	{ Opt_sloppy, "sloppy" },
192
	{ Opt_nosharesock, "nosharesock" },
193 194
	{ Opt_persistent, "persistenthandles"},
	{ Opt_nopersistent, "nopersistenthandles"},
Steve French's avatar
Steve French committed
195 196
	{ Opt_resilient, "resilienthandles"},
	{ Opt_noresilient, "noresilienthandles"},
197
	{ Opt_domainauto, "domainauto"},
Long Li's avatar
Long Li committed
198
	{ Opt_rdma, "rdma"},
199 200 201 202 203 204 205 206 207 208

	{ Opt_backupuid, "backupuid=%s" },
	{ Opt_backupgid, "backupgid=%s" },
	{ Opt_uid, "uid=%s" },
	{ Opt_cruid, "cruid=%s" },
	{ Opt_gid, "gid=%s" },
	{ Opt_file_mode, "file_mode=%s" },
	{ Opt_dirmode, "dirmode=%s" },
	{ Opt_dirmode, "dir_mode=%s" },
	{ Opt_port, "port=%s" },
209
	{ Opt_blocksize, "bsize=%s" },
210 211 212
	{ Opt_rsize, "rsize=%s" },
	{ Opt_wsize, "wsize=%s" },
	{ Opt_actimeo, "actimeo=%s" },
213
	{ Opt_handletimeout, "handletimeout=%s" },
214
	{ Opt_echo_interval, "echo_interval=%s" },
215
	{ Opt_max_credits, "max_credits=%s" },
216
	{ Opt_snapshot, "snapshot=%s" },
217
	{ Opt_compress, "compress=%s" },
218

219 220
	{ Opt_blank_user, "user=" },
	{ Opt_blank_user, "username=" },
221 222 223
	{ Opt_user, "user=%s" },
	{ Opt_user, "username=%s" },
	{ Opt_blank_pass, "pass=" },
224
	{ Opt_blank_pass, "password=" },
225 226
	{ Opt_pass, "pass=%s" },
	{ Opt_pass, "password=%s" },
227 228
	{ Opt_blank_ip, "ip=" },
	{ Opt_blank_ip, "addr=" },
229 230
	{ Opt_ip, "ip=%s" },
	{ Opt_ip, "addr=%s" },
231 232 233
	{ Opt_ignore, "unc=%s" },
	{ Opt_ignore, "target=%s" },
	{ Opt_ignore, "path=%s" },
234 235 236 237
	{ Opt_domain, "dom=%s" },
	{ Opt_domain, "domain=%s" },
	{ Opt_domain, "workgroup=%s" },
	{ Opt_srcaddr, "srcaddr=%s" },
238
	{ Opt_ignore, "prefixpath=%s" },
239 240 241 242
	{ Opt_iocharset, "iocharset=%s" },
	{ Opt_netbiosname, "netbiosname=%s" },
	{ Opt_servern, "servern=%s" },
	{ Opt_ver, "ver=%s" },
243
	{ Opt_vers, "vers=%s" },
244
	{ Opt_sec, "sec=%s" },
245
	{ Opt_cache, "cache=%s" },
246 247 248

	{ Opt_ignore, "cred" },
	{ Opt_ignore, "credentials" },
249 250
	{ Opt_ignore, "cred=%s" },
	{ Opt_ignore, "credentials=%s" },
251 252 253 254 255 256 257 258 259 260 261 262
	{ Opt_ignore, "guest" },
	{ Opt_ignore, "rw" },
	{ Opt_ignore, "ro" },
	{ Opt_ignore, "suid" },
	{ Opt_ignore, "nosuid" },
	{ Opt_ignore, "exec" },
	{ Opt_ignore, "noexec" },
	{ Opt_ignore, "nodev" },
	{ Opt_ignore, "noauto" },
	{ Opt_ignore, "dev" },
	{ Opt_ignore, "mand" },
	{ Opt_ignore, "nomand" },
263
	{ Opt_ignore, "relatime" },
264 265 266 267 268 269 270 271
	{ Opt_ignore, "_netdev" },

	{ Opt_err, NULL }
};

enum {
	Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p,
	Opt_sec_ntlmsspi, Opt_sec_ntlmssp,
272 273
	Opt_ntlm, Opt_sec_ntlmi, Opt_sec_ntlmv2,
	Opt_sec_ntlmv2i, Opt_sec_lanman,
274 275 276 277 278 279 280 281 282 283 284 285 286
	Opt_sec_none,

	Opt_sec_err
};

static const match_table_t cifs_secflavor_tokens = {
	{ Opt_sec_krb5, "krb5" },
	{ Opt_sec_krb5i, "krb5i" },
	{ Opt_sec_krb5p, "krb5p" },
	{ Opt_sec_ntlmsspi, "ntlmsspi" },
	{ Opt_sec_ntlmssp, "ntlmssp" },
	{ Opt_ntlm, "ntlm" },
	{ Opt_sec_ntlmi, "ntlmi" },
287 288
	{ Opt_sec_ntlmv2, "nontlm" },
	{ Opt_sec_ntlmv2, "ntlmv2" },
289 290 291 292 293 294 295
	{ Opt_sec_ntlmv2i, "ntlmv2i" },
	{ Opt_sec_lanman, "lanman" },
	{ Opt_sec_none, "none" },

	{ Opt_sec_err, NULL }
};

296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
/* cache flavors */
enum {
	Opt_cache_loose,
	Opt_cache_strict,
	Opt_cache_none,
	Opt_cache_err
};

static const match_table_t cifs_cacheflavor_tokens = {
	{ Opt_cache_loose, "loose" },
	{ Opt_cache_strict, "strict" },
	{ Opt_cache_none, "none" },
	{ Opt_cache_err, NULL }
};

311 312
static const match_table_t cifs_smb_version_tokens = {
	{ Smb_1, SMB1_VERSION_STRING },
Steve French's avatar
Steve French committed
313
	{ Smb_20, SMB20_VERSION_STRING},
314
	{ Smb_21, SMB21_VERSION_STRING },
315
	{ Smb_30, SMB30_VERSION_STRING },
Steve French's avatar
Steve French committed
316
	{ Smb_302, SMB302_VERSION_STRING },
317
	{ Smb_302, ALT_SMB302_VERSION_STRING },
318
	{ Smb_311, SMB311_VERSION_STRING },
319
	{ Smb_311, ALT_SMB311_VERSION_STRING },
320 321
	{ Smb_3any, SMB3ANY_VERSION_STRING },
	{ Smb_default, SMBDEFAULT_VERSION_STRING },
322
	{ Smb_version_err, NULL }
323 324
};

325 326
static int ip_connect(struct TCP_Server_Info *server);
static int generic_ip_connect(struct TCP_Server_Info *server);
327
static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
328
static void cifs_prune_tlinks(struct work_struct *work);
329 330
static char *extract_hostname(const char *unc);

331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
/*
 * 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.
 */
#ifdef CONFIG_CIFS_DFS_UPCALL
static int reconn_set_ipaddr(struct TCP_Server_Info *server)
{
	int rc;
	int len;
	char *unc, *ipaddr = NULL;

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

	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;
	}
354
	scnprintf(unc, len, "\\\\%s", server->hostname);
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377

	rc = dns_resolve_server_name_to_ip(unc, &ipaddr);
	kfree(unc);

	if (rc < 0) {
		cifs_dbg(FYI, "%s: failed to resolve server part of %s to IP: %d\n",
			 __func__, server->hostname, rc);
		return rc;
	}

	rc = cifs_convert_address((struct sockaddr *)&server->dstaddr, ipaddr,
				  strlen(ipaddr));
	kfree(ipaddr);

	return !rc ? -1 : 0;
}
#else
static inline int reconn_set_ipaddr(struct TCP_Server_Info *server)
{
	return 0;
}
#endif

378 379 380 381 382 383 384 385 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
#ifdef CONFIG_CIFS_DFS_UPCALL
struct super_cb_data {
	struct TCP_Server_Info *server;
	struct cifs_sb_info *cifs_sb;
};

/* These functions must be called with server->srv_mutex held */

static void super_cb(struct super_block *sb, void *arg)
{
	struct super_cb_data *d = arg;
	struct cifs_sb_info *cifs_sb;
	struct cifs_tcon *tcon;

	if (d->cifs_sb)
		return;

	cifs_sb = CIFS_SB(sb);
	tcon = cifs_sb_master_tcon(cifs_sb);
	if (tcon->ses->server == d->server)
		d->cifs_sb = cifs_sb;
}

static inline struct cifs_sb_info *
find_super_by_tcp(struct TCP_Server_Info *server)
{
	struct super_cb_data d = {
		.server = server,
		.cifs_sb = NULL,
	};

	iterate_supers_type(&cifs_fs_type, super_cb, &d);
	return d.cifs_sb ? d.cifs_sb : ERR_PTR(-ENOENT);
}

static void reconn_inval_dfs_target(struct TCP_Server_Info *server,
				    struct cifs_sb_info *cifs_sb,
				    struct dfs_cache_tgt_list *tgt_list,
				    struct dfs_cache_tgt_iterator **tgt_it)
{
	const char *name;

	if (!cifs_sb || !cifs_sb->origin_fullpath || !tgt_list ||
	    !server->nr_targets)
		return;

	if (!*tgt_it) {
		*tgt_it = dfs_cache_get_tgt_iterator(tgt_list);
	} else {
		*tgt_it = dfs_cache_get_next_tgt(tgt_list, *tgt_it);
		if (!*tgt_it)
			*tgt_it = dfs_cache_get_tgt_iterator(tgt_list);
	}

	cifs_dbg(FYI, "%s: UNC: %s\n", __func__, cifs_sb->origin_fullpath);

	name = dfs_cache_get_tgt_name(*tgt_it);

	kfree(server->hostname);

	server->hostname = extract_hostname(name);
Dan Carpenter's avatar
Dan Carpenter committed
439 440 441 442
	if (IS_ERR(server->hostname)) {
		cifs_dbg(FYI,
			 "%s: failed to extract hostname from target: %ld\n",
			 __func__, PTR_ERR(server->hostname));
443 444 445 446 447 448 449 450 451 452 453 454
	}
}

static inline int reconn_setup_dfs_targets(struct cifs_sb_info *cifs_sb,
					   struct dfs_cache_tgt_list *tl,
					   struct dfs_cache_tgt_iterator **it)
{
	if (!cifs_sb->origin_fullpath)
		return -EOPNOTSUPP;
	return dfs_cache_noreq_find(cifs_sb->origin_fullpath + 1, NULL, tl);
}
#endif
Linus Torvalds's avatar
Linus Torvalds committed
455

456 457 458 459 460 461 462 463
/*
 * 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)
 */
464
int
Linus Torvalds's avatar
Linus Torvalds committed
465 466 467
cifs_reconnect(struct TCP_Server_Info *server)
{
	int rc = 0;
468
	struct list_head *tmp, *tmp2;
469 470
	struct cifs_ses *ses;
	struct cifs_tcon *tcon;
Steve French's avatar
Steve French committed
471
	struct mid_q_entry *mid_entry;
472
	struct list_head retry_list;
473
#ifdef CONFIG_CIFS_DFS_UPCALL
474 475
	struct cifs_sb_info *cifs_sb = NULL;
	struct dfs_cache_tgt_list tgt_list = {0};
476 477
	struct dfs_cache_tgt_iterator *tgt_it = NULL;
#endif
478

Linus Torvalds's avatar
Linus Torvalds committed
479
	spin_lock(&GlobalMid_Lock);
480 481
	server->nr_targets = 1;
#ifdef CONFIG_CIFS_DFS_UPCALL
482
	spin_unlock(&GlobalMid_Lock);
483 484 485 486 487 488 489 490
	cifs_sb = find_super_by_tcp(server);
	if (IS_ERR(cifs_sb)) {
		rc = PTR_ERR(cifs_sb);
		cifs_dbg(FYI, "%s: will not do DFS failover: rc = %d\n",
			 __func__, rc);
		cifs_sb = NULL;
	} else {
		rc = reconn_setup_dfs_targets(cifs_sb, &tgt_list, &tgt_it);
491
		if (rc && (rc != -EOPNOTSUPP)) {
492 493 494 495 496 497 498 499
			cifs_dbg(VFS, "%s: no target servers for DFS failover\n",
				 __func__);
		} else {
			server->nr_targets = dfs_cache_get_nr_tgts(&tgt_list);
		}
	}
	cifs_dbg(FYI, "%s: will retry %d target(s)\n", __func__,
		 server->nr_targets);
500
	spin_lock(&GlobalMid_Lock);
501
#endif
502
	if (server->tcpStatus == CifsExiting) {
Steve French's avatar
Steve French committed
503
		/* the demux thread will exit normally
Linus Torvalds's avatar
Linus Torvalds committed
504 505 506 507 508 509 510
		next time through the loop */
		spin_unlock(&GlobalMid_Lock);
		return rc;
	} else
		server->tcpStatus = CifsNeedReconnect;
	spin_unlock(&GlobalMid_Lock);
	server->maxBuf = 0;
511
	server->max_read = 0;
Linus Torvalds's avatar
Linus Torvalds committed
512

513
	cifs_dbg(FYI, "Mark tcp session as need reconnect\n");
Steve French's avatar
Steve French committed
514
	trace_smb3_reconnect(server->CurrentMid, server->hostname);
Linus Torvalds's avatar
Linus Torvalds committed
515 516 517

	/* before reconnecting the tcp session, mark the smb session (uid)
		and the tid bad so they are not used until reconnected */
518 519
	cifs_dbg(FYI, "%s: marking sessions and tcons for reconnect\n",
		 __func__);
520
	spin_lock(&cifs_tcp_ses_lock);
521
	list_for_each(tmp, &server->smb_ses_list) {
522
		ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
523
		ses->need_reconnect = true;
524
		list_for_each(tmp2, &ses->tcon_list) {
525
			tcon = list_entry(tmp2, struct cifs_tcon, tcon_list);
526
			tcon->need_reconnect = true;
Linus Torvalds's avatar
Linus Torvalds committed
527
		}
Aurelien Aptel's avatar
Aurelien Aptel committed
528 529
		if (ses->tcon_ipc)
			ses->tcon_ipc->need_reconnect = true;
Linus Torvalds's avatar
Linus Torvalds committed
530
	}
531
	spin_unlock(&cifs_tcp_ses_lock);
532

Linus Torvalds's avatar
Linus Torvalds committed
533
	/* do not want to be sending data on a socket we are freeing */
534
	cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
Jeff Layton's avatar
Jeff Layton committed
535
	mutex_lock(&server->srv_mutex);
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
	if (server->ssocket) {
		cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n",
			 server->ssocket->state, server->ssocket->flags);
		kernel_sock_shutdown(server->ssocket, SHUT_WR);
		cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n",
			 server->ssocket->state, server->ssocket->flags);
		sock_release(server->ssocket);
		server->ssocket = NULL;
	}
	server->sequence_number = 0;
	server->session_estab = false;
	kfree(server->session_key.response);
	server->session_key.response = NULL;
	server->session_key.len = 0;
	server->lstrp = jiffies;
Linus Torvalds's avatar
Linus Torvalds committed
551

552
	/* mark submitted MIDs for retry and issue callback */
553
	INIT_LIST_HEAD(&retry_list);
554
	cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
Linus Torvalds's avatar
Linus Torvalds committed
555
	spin_lock(&GlobalMid_Lock);
556 557
	list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
		mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
558 559
		if (mid_entry->mid_state == MID_REQUEST_SUBMITTED)
			mid_entry->mid_state = MID_RETRY_NEEDED;
560 561 562
		list_move(&mid_entry->qhead, &retry_list);
	}
	spin_unlock(&GlobalMid_Lock);
563
	mutex_unlock(&server->srv_mutex);
564

565
	cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
566 567
	list_for_each_safe(tmp, tmp2, &retry_list) {
		mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
568 569
		list_del_init(&mid_entry->qhead);
		mid_entry->callback(mid_entry);
Linus Torvalds's avatar
Linus Torvalds committed
570 571
	}

572 573
	if (cifs_rdma_enabled(server)) {
		mutex_lock(&server->srv_mutex);
574
		smbd_destroy(server);
575 576
		mutex_unlock(&server->srv_mutex);
	}
577

578
	do {
579
		try_to_freeze();
580

581
		mutex_lock(&server->srv_mutex);
582 583 584 585 586
		/*
		 * Set up next DFS target server (if any) for reconnect. If DFS
		 * feature is disabled, then we will retry last server we
		 * connected to before.
		 */
587 588 589 590
		if (cifs_rdma_enabled(server))
			rc = smbd_reconnect(server);
		else
			rc = generic_ip_connect(server);
Steve French's avatar
Steve French committed
591
		if (rc) {
592
			cifs_dbg(FYI, "reconnect error %d\n", rc);
593 594 595 596
#ifdef CONFIG_CIFS_DFS_UPCALL
			reconn_inval_dfs_target(server, cifs_sb, &tgt_list,
						&tgt_it);
#endif
597 598 599 600 601
			rc = reconn_set_ipaddr(server);
			if (rc) {
				cifs_dbg(FYI, "%s: failed to resolve hostname: %d\n",
					 __func__, rc);
			}
602
			mutex_unlock(&server->srv_mutex);
603
			msleep(3000);
Linus Torvalds's avatar
Linus Torvalds committed
604 605
		} else {
			atomic_inc(&tcpSesReconnectCount);
606
			set_credits(server, 1);
Linus Torvalds's avatar
Linus Torvalds committed
607
			spin_lock(&GlobalMid_Lock);
608
			if (server->tcpStatus != CifsExiting)
609
				server->tcpStatus = CifsNeedNegotiate;
Steve French's avatar
Steve French committed
610
			spin_unlock(&GlobalMid_Lock);
611
			mutex_unlock(&server->srv_mutex);
Linus Torvalds's avatar
Linus Torvalds committed
612
		}
613
	} while (server->tcpStatus == CifsNeedReconnect);
614

615 616 617 618 619 620 621 622 623 624 625 626 627
#ifdef CONFIG_CIFS_DFS_UPCALL
	if (tgt_it) {
		rc = dfs_cache_noreq_update_tgthint(cifs_sb->origin_fullpath + 1,
						    tgt_it);
		if (rc) {
			cifs_dbg(VFS, "%s: failed to update DFS target hint: rc = %d\n",
				 __func__, rc);
		}
		rc = dfs_cache_update_vol(cifs_sb->origin_fullpath, server);
		if (rc) {
			cifs_dbg(VFS, "%s: failed to update vol info in DFS cache: rc = %d\n",
				 __func__, rc);
		}
628
		dfs_cache_free_tgts(&tgt_list);
629 630
	}
#endif
631 632 633
	if (server->tcpStatus == CifsNeedNegotiate)
		mod_delayed_work(cifsiod_wq, &server->echo, 0);

Linus Torvalds's avatar
Linus Torvalds committed
634 635 636
	return rc;
}

637 638 639 640 641 642
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);
643 644 645 646 647 648 649 650 651 652
	unsigned long echo_interval;

	/*
	 * If we need to renegotiate, set echo interval to zero to
	 * immediately call echo service where we can renegotiate.
	 */
	if (server->tcpStatus == CifsNeedNegotiate)
		echo_interval = 0;
	else
		echo_interval = server->echo_interval;
653

654
	/*
655 656
	 * We cannot send an echo if it is disabled.
	 * Also, no need to ping if we got a response recently.
657
	 */
658 659

	if (server->tcpStatus == CifsNeedReconnect ||
660 661
	    server->tcpStatus == CifsExiting ||
	    server->tcpStatus == CifsNew ||
662
	    (server->ops->can_echo && !server->ops->can_echo(server)) ||
663
	    time_before(jiffies, server->lstrp + echo_interval - HZ))
664 665
		goto requeue_echo;

666
	rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS;
667
	if (rc)
668 669
		cifs_dbg(FYI, "Unable to send echo request to server: %s\n",
			 server->hostname);
670 671

requeue_echo:
672
	queue_delayed_work(cifsiod_wq, &server->echo, server->echo_interval);
673 674
}

675
static bool
676
allocate_buffers(struct TCP_Server_Info *server)
677
{
678 679 680
	if (!server->bigbuf) {
		server->bigbuf = (char *)cifs_buf_get();
		if (!server->bigbuf) {
681
			cifs_dbg(VFS, "No memory for large SMB response\n");
682 683 684 685
			msleep(3000);
			/* retry will check if exiting */
			return false;
		}
686
	} else if (server->large_buf) {
687
		/* we are reusing a dirty large buf, clear its start */
688
		memset(server->bigbuf, 0, HEADER_SIZE(server));
689 690
	}

691 692 693
	if (!server->smallbuf) {
		server->smallbuf = (char *)cifs_small_buf_get();
		if (!server->smallbuf) {
694
			cifs_dbg(VFS, "No memory for SMB response\n");
695 696 697 698 699 700 701
			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 */
702
		memset(server->smallbuf, 0, HEADER_SIZE(server));
703 704 705 706 707
	}

	return true;
}

708 709 710
static bool
server_unresponsive(struct TCP_Server_Info *server)
{
711
	/*
712
	 * We need to wait 3 echo intervals to make sure we handle such
713 714
	 * situations right:
	 * 1s  client sends a normal SMB request
715
	 * 3s  client gets a response
716 717 718 719 720 721
	 * 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.
	 */
722 723
	if ((server->tcpStatus == CifsGood ||
	    server->tcpStatus == CifsNeedNegotiate) &&
724
	    time_after(jiffies, server->lstrp + 3 * server->echo_interval)) {
725
		cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n",
726
			 server->hostname, (3 * server->echo_interval) / HZ);
727 728 729 730 731 732 733 734
		cifs_reconnect(server);
		wake_up(&server->response_q);
		return true;
	}

	return false;
}

735 736 737 738 739 740 741 742 743 744 745 746 747 748 749
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;
}

750 751
static int
cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
752
{
Jeff Layton's avatar
Jeff Layton committed
753 754
	int length = 0;
	int total_read;
755

756 757
	smb_msg->msg_control = NULL;
	smb_msg->msg_controllen = 0;
758

759
	for (total_read = 0; msg_data_left(smb_msg); total_read += length) {
760 761
		try_to_freeze();

762 763 764 765 766 767
		/* reconnect if no credits and no requests in flight */
		if (zero_credits(server)) {
			cifs_reconnect(server);
			return -ECONNABORTED;
		}

768 769
		if (server_unresponsive(server))
			return -ECONNABORTED;
770 771 772 773
		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);
774

775 776
		if (server->tcpStatus == CifsExiting)
			return -ESHUTDOWN;
777

778
		if (server->tcpStatus == CifsNeedReconnect) {
779
			cifs_reconnect(server);
780 781 782 783 784 785
			return -ECONNABORTED;
		}

		if (length == -ERESTARTSYS ||
		    length == -EAGAIN ||
		    length == -EINTR) {
786 787 788 789 790 791 792
			/*
			 * 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;
Jeff Layton's avatar
Jeff Layton committed
793
			continue;
794 795 796
		}

		if (length <= 0) {
797
			cifs_dbg(FYI, "Received no data or error: %d\n", length);
798
			cifs_reconnect(server);
799
			return -ECONNABORTED;
800 801
		}
	}
Jeff Layton's avatar
Jeff Layton committed
802
	return total_read;
803 804
}

Jeff Layton's avatar
Jeff Layton committed
805 806 807
int
cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
		      unsigned int to_read)
808
{
809 810
	struct msghdr smb_msg;
	struct kvec iov = {.iov_base = buf, .iov_len = to_read};
811
	iov_iter_kvec(&smb_msg.msg_iter, READ, &iov, 1, to_read);
812

813 814
	return cifs_readv_from_socket(server, &smb_msg);
}
815

816 817
int
cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page,
Long Li's avatar
Long Li committed
818
	unsigned int page_offset, unsigned int to_read)
819 820
{
	struct msghdr smb_msg;
Long Li's avatar
Long Li committed
821 822
	struct bio_vec bv = {
		.bv_page = page, .bv_len = to_read, .bv_offset = page_offset};
823
	iov_iter_bvec(&smb_msg.msg_iter, READ, &bv, 1, to_read);
824
	return cifs_readv_from_socket(server, &smb_msg);
825 826
}

827
static bool
828
is_smb_response(struct TCP_Server_Info *server, unsigned char type)
829 830 831 832 833 834
{
	/*
	 * 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.
	 */
835 836 837 838 839
	switch (type) {
	case RFC1002_SESSION_MESSAGE:
		/* Regular SMB response */
		return true;
	case RFC1002_SESSION_KEEP_ALIVE:
840
		cifs_dbg(FYI, "RFC 1002 session keep alive\n");
841 842
		break;
	case RFC1002_POSITIVE_SESSION_RESPONSE:
843
		cifs_dbg(FYI, "RFC 1002 positive session response\n");
844 845
		break;
	case RFC1002_NEGATIVE_SESSION_RESPONSE:
846 847 848 849
		/*
		 * We get this from Windows 98 instead of an error on
		 * SMB negprot response.
		 */
850
		cifs_dbg(FYI, "RFC 1002 negative session response\n");
851 852 853 854 855 856 857 858
		/* 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).
		 */
859
		cifs_set_port((struct sockaddr *)&server->dstaddr, CIFS_PORT);
860 861
		cifs_reconnect(server);
		wake_up(&server->response_q);
862 863
		break;
	default:
864
		cifs_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", type);
865 866 867
		cifs_reconnect(server);
	}

868
	return false;
869 870
}

Jeff Layton's avatar
Jeff Layton committed
871 872
void
dequeue_mid(struct mid_q_entry *mid, bool malformed)
873
{
874
#ifdef CONFIG_CIFS_STATS2
875
	mid->when_received = jiffies;
876
#endif
877 878
	spin_lock(&GlobalMid_Lock);
	if (!malformed)
879
		mid->mid_state = MID_RESPONSE_RECEIVED;
880
	else
881
		mid->mid_state = MID_RESPONSE_MALFORMED;
882 883 884 885 886 887 888 889 890
	/*
	 * Trying to handle/dequeue a mid after the send_recv()
	 * function has finished processing it is a bug.
	 */
	if (mid->mid_flags & MID_DELETED)
		printk_once(KERN_WARNING
			    "trying to dequeue a deleted mid\n");
	else
		list_del_init(&mid->qhead);
891
	spin_unlock(&GlobalMid_Lock);
892
}
893

894 895
static void
handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server,
896
	   char *buf, int malformed)
897
{
898 899
	if (server->ops->check_trans2 &&
	    server->ops->check_trans2(mid, server, buf, malformed))
900
		return;
901
	mid->resp_buf = buf;
902
	mid->large_buf = server->large_buf;
903 904 905 906 907 908 909 910
	/* 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;
	}
911
	dequeue_mid(mid, malformed);
912 913
}

914 915 916 917 918 919 920 921 922 923 924 925 926 927
static void clean_demultiplex_info(struct TCP_Server_Info *server)
{
	int length;

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

	spin_lock(&GlobalMid_Lock);
	server->tcpStatus = CifsExiting;
	spin_unlock(&GlobalMid_Lock);
	wake_up_all(&server->response_q);

928
	/* check if we have blocked requests that need to free */
929
	spin_lock(&server->req_lock);
930 931
	if (server->credits <= 0)
		server->credits = 1;
932
	spin_unlock(&server->req_lock);
933 934 935 936 937 938 939 940 941 942
	/*
	 * 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);
943 944
	if (cifs_rdma_enabled(server))
		smbd_destroy(server);
945 946 947 948 949 950 951 952 953 954 955 956 957 958
	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);
		spin_lock(&GlobalMid_Lock);
		list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
959
			cifs_dbg(FYI, "Clearing mid 0x%llx\n", mid_entry->mid);
960
			mid_entry->mid_state = MID_SHUTDOWN;
961 962 963 964 965 966 967
			list_move(&mid_entry->qhead, &dispose_list);
		}
		spin_unlock(&GlobalMid_Lock);

		/* 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);
968
			cifs_dbg(FYI, "Callback mid 0x%llx\n", mid_entry->mid);
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984
			list_del_init(&mid_entry->qhead);
			mid_entry->callback(mid_entry);
		}
		/* 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.
		 */