Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
   1/*
   2 *  SMB2 version specific operations
   3 *
   4 *  Copyright (c) 2012, Jeff Layton <jlayton@redhat.com>
   5 *
   6 *  This library is free software; you can redistribute it and/or modify
   7 *  it under the terms of the GNU General Public License v2 as published
   8 *  by the Free Software Foundation.
   9 *
  10 *  This library is distributed in the hope that it will be useful,
  11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  13 *  the GNU Lesser General Public License for more details.
  14 *
  15 *  You should have received a copy of the GNU Lesser General Public License
  16 *  along with this library; if not, write to the Free Software
  17 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18 */
  19
  20#include <linux/pagemap.h>
  21#include <linux/vfs.h>
  22#include "cifsglob.h"
  23#include "smb2pdu.h"
  24#include "smb2proto.h"
  25#include "cifsproto.h"
  26#include "cifs_debug.h"
  27#include "cifs_unicode.h"
  28#include "smb2status.h"
  29#include "smb2glob.h"
  30
  31static int
  32change_conf(struct TCP_Server_Info *server)
  33{
  34	server->credits += server->echo_credits + server->oplock_credits;
  35	server->oplock_credits = server->echo_credits = 0;
  36	switch (server->credits) {
  37	case 0:
  38		return -1;
  39	case 1:
  40		server->echoes = false;
  41		server->oplocks = false;
  42		cifs_dbg(VFS, "disabling echoes and oplocks\n");
  43		break;
  44	case 2:
  45		server->echoes = true;
  46		server->oplocks = false;
  47		server->echo_credits = 1;
  48		cifs_dbg(FYI, "disabling oplocks\n");
  49		break;
  50	default:
  51		server->echoes = true;
  52		server->oplocks = true;
  53		server->echo_credits = 1;
  54		server->oplock_credits = 1;
  55	}
  56	server->credits -= server->echo_credits + server->oplock_credits;
  57	return 0;
  58}
  59
  60static void
  61smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
  62		 const int optype)
  63{
  64	int *val, rc = 0;
  65	spin_lock(&server->req_lock);
  66	val = server->ops->get_credits_field(server, optype);
  67	*val += add;
  68	server->in_flight--;
  69	if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP)
  70		rc = change_conf(server);
  71	/*
  72	 * Sometimes server returns 0 credits on oplock break ack - we need to
  73	 * rebalance credits in this case.
  74	 */
  75	else if (server->in_flight > 0 && server->oplock_credits == 0 &&
  76		 server->oplocks) {
  77		if (server->credits > 1) {
  78			server->credits--;
  79			server->oplock_credits++;
  80		}
  81	}
  82	spin_unlock(&server->req_lock);
  83	wake_up(&server->request_q);
  84	if (rc)
  85		cifs_reconnect(server);
  86}
  87
  88static void
  89smb2_set_credits(struct TCP_Server_Info *server, const int val)
  90{
  91	spin_lock(&server->req_lock);
  92	server->credits = val;
  93	spin_unlock(&server->req_lock);
  94}
  95
  96static int *
  97smb2_get_credits_field(struct TCP_Server_Info *server, const int optype)
  98{
  99	switch (optype) {
 100	case CIFS_ECHO_OP:
 101		return &server->echo_credits;
 102	case CIFS_OBREAK_OP:
 103		return &server->oplock_credits;
 104	default:
 105		return &server->credits;
 106	}
 107}
 108
 109static unsigned int
 110smb2_get_credits(struct mid_q_entry *mid)
 111{
 112	return le16_to_cpu(((struct smb2_hdr *)mid->resp_buf)->CreditRequest);
 113}
 114
 115static __u64
 116smb2_get_next_mid(struct TCP_Server_Info *server)
 117{
 118	__u64 mid;
 119	/* for SMB2 we need the current value */
 120	spin_lock(&GlobalMid_Lock);
 121	mid = server->CurrentMid++;
 122	spin_unlock(&GlobalMid_Lock);
 123	return mid;
 124}
 125
 126static struct mid_q_entry *
 127smb2_find_mid(struct TCP_Server_Info *server, char *buf)
 128{
 129	struct mid_q_entry *mid;
 130	struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
 131
 132	spin_lock(&GlobalMid_Lock);
 133	list_for_each_entry(mid, &server->pending_mid_q, qhead) {
 134		if ((mid->mid == hdr->MessageId) &&
 135		    (mid->mid_state == MID_REQUEST_SUBMITTED) &&
 136		    (mid->command == hdr->Command)) {
 137			spin_unlock(&GlobalMid_Lock);
 138			return mid;
 139		}
 140	}
 141	spin_unlock(&GlobalMid_Lock);
 142	return NULL;
 143}
 144
 145static void
 146smb2_dump_detail(void *buf)
 147{
 148#ifdef CONFIG_CIFS_DEBUG2
 149	struct smb2_hdr *smb = (struct smb2_hdr *)buf;
 150
 151	cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n",
 152		 smb->Command, smb->Status, smb->Flags, smb->MessageId,
 153		 smb->ProcessId);
 154	cifs_dbg(VFS, "smb buf %p len %u\n", smb, smb2_calc_size(smb));
 155#endif
 156}
 157
 158static bool
 159smb2_need_neg(struct TCP_Server_Info *server)
 160{
 161	return server->max_read == 0;
 162}
 163
 164static int
 165smb2_negotiate(const unsigned int xid, struct cifs_ses *ses)
 166{
 167	int rc;
 168	ses->server->CurrentMid = 0;
 169	rc = SMB2_negotiate(xid, ses);
 170	/* BB we probably don't need to retry with modern servers */
 171	if (rc == -EAGAIN)
 172		rc = -EHOSTDOWN;
 173	return rc;
 174}
 175
 176static unsigned int
 177smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
 178{
 179	struct TCP_Server_Info *server = tcon->ses->server;
 180	unsigned int wsize;
 181
 182	/* start with specified wsize, or default */
 183	wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE;
 184	wsize = min_t(unsigned int, wsize, server->max_write);
 185	/* set it to the maximum buffer size value we can send with 1 credit */
 186	wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE);
 187
 188	return wsize;
 189}
 190
 191static unsigned int
 192smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
 193{
 194	struct TCP_Server_Info *server = tcon->ses->server;
 195	unsigned int rsize;
 196
 197	/* start with specified rsize, or default */
 198	rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE;
 199	rsize = min_t(unsigned int, rsize, server->max_read);
 200	/* set it to the maximum buffer size value we can send with 1 credit */
 201	rsize = min_t(unsigned int, rsize, SMB2_MAX_BUFFER_SIZE);
 202
 203	return rsize;
 204}
 205
 206#ifdef CONFIG_CIFS_STATS2
 207static int
 208SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
 209{
 210	int rc;
 211	unsigned int ret_data_len = 0;
 212	struct network_interface_info_ioctl_rsp *out_buf;
 213
 214	rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
 215			FSCTL_QUERY_NETWORK_INTERFACE_INFO, true /* is_fsctl */,
 216			NULL /* no data input */, 0 /* no data input */,
 217			(char **)&out_buf, &ret_data_len);
 218
 219	if ((rc == 0)  && (ret_data_len > 0)) {
 220		/* Dump info on first interface */
 221		cifs_dbg(FYI, "Adapter Capability 0x%x\t",
 222			le32_to_cpu(out_buf->Capability));
 223		cifs_dbg(FYI, "Link Speed %lld\n",
 224			le64_to_cpu(out_buf->LinkSpeed));
 225	} else
 226		cifs_dbg(VFS, "error %d on ioctl to get interface list\n", rc);
 227
 228	return rc;
 229}
 230#endif /* STATS2 */
 231
 232static void
 233smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
 234{
 235	int rc;
 236	__le16 srch_path = 0; /* Null - open root of share */
 237	u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 238	struct cifs_open_parms oparms;
 239	struct cifs_fid fid;
 240
 241	oparms.tcon = tcon;
 242	oparms.desired_access = FILE_READ_ATTRIBUTES;
 243	oparms.disposition = FILE_OPEN;
 244	oparms.create_options = 0;
 245	oparms.fid = &fid;
 246	oparms.reconnect = false;
 247
 248	rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
 249	if (rc)
 250		return;
 251
 252#ifdef CONFIG_CIFS_STATS2
 253	SMB3_request_interfaces(xid, tcon);
 254#endif /* STATS2 */
 255
 256	SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
 257			FS_ATTRIBUTE_INFORMATION);
 258	SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
 259			FS_DEVICE_INFORMATION);
 260	SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
 261			FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */
 262	SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
 263	return;
 264}
 265
 266static void
 267smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
 268{
 269	int rc;
 270	__le16 srch_path = 0; /* Null - open root of share */
 271	u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 272	struct cifs_open_parms oparms;
 273	struct cifs_fid fid;
 274
 275	oparms.tcon = tcon;
 276	oparms.desired_access = FILE_READ_ATTRIBUTES;
 277	oparms.disposition = FILE_OPEN;
 278	oparms.create_options = 0;
 279	oparms.fid = &fid;
 280	oparms.reconnect = false;
 281
 282	rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
 283	if (rc)
 284		return;
 285
 286	SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
 287			FS_ATTRIBUTE_INFORMATION);
 288	SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
 289			FS_DEVICE_INFORMATION);
 290	SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
 291	return;
 292}
 293
 294static int
 295smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
 296			struct cifs_sb_info *cifs_sb, const char *full_path)
 297{
 298	int rc;
 299	__le16 *utf16_path;
 300	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 301	struct cifs_open_parms oparms;
 302	struct cifs_fid fid;
 303
 304	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
 305	if (!utf16_path)
 306		return -ENOMEM;
 307
 308	oparms.tcon = tcon;
 309	oparms.desired_access = FILE_READ_ATTRIBUTES;
 310	oparms.disposition = FILE_OPEN;
 311	oparms.create_options = 0;
 312	oparms.fid = &fid;
 313	oparms.reconnect = false;
 314
 315	rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
 316	if (rc) {
 317		kfree(utf16_path);
 318		return rc;
 319	}
 320
 321	rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
 322	kfree(utf16_path);
 323	return rc;
 324}
 325
 326static int
 327smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
 328		  struct cifs_sb_info *cifs_sb, const char *full_path,
 329		  u64 *uniqueid, FILE_ALL_INFO *data)
 330{
 331	*uniqueid = le64_to_cpu(data->IndexNumber);
 332	return 0;
 333}
 334
 335static int
 336smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
 337		     struct cifs_fid *fid, FILE_ALL_INFO *data)
 338{
 339	int rc;
 340	struct smb2_file_all_info *smb2_data;
 341
 342	smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + MAX_NAME * 2,
 343			    GFP_KERNEL);
 344	if (smb2_data == NULL)
 345		return -ENOMEM;
 346
 347	rc = SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid,
 348			     smb2_data);
 349	if (!rc)
 350		move_smb2_info_to_cifs(data, smb2_data);
 351	kfree(smb2_data);
 352	return rc;
 353}
 354
 355static bool
 356smb2_can_echo(struct TCP_Server_Info *server)
 357{
 358	return server->echoes;
 359}
 360
 361static void
 362smb2_clear_stats(struct cifs_tcon *tcon)
 363{
 364#ifdef CONFIG_CIFS_STATS
 365	int i;
 366	for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
 367		atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0);
 368		atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0);
 369	}
 370#endif
 371}
 372
 373static void
 374smb2_dump_share_caps(struct seq_file *m, struct cifs_tcon *tcon)
 375{
 376	seq_puts(m, "\n\tShare Capabilities:");
 377	if (tcon->capabilities & SMB2_SHARE_CAP_DFS)
 378		seq_puts(m, " DFS,");
 379	if (tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
 380		seq_puts(m, " CONTINUOUS AVAILABILITY,");
 381	if (tcon->capabilities & SMB2_SHARE_CAP_SCALEOUT)
 382		seq_puts(m, " SCALEOUT,");
 383	if (tcon->capabilities & SMB2_SHARE_CAP_CLUSTER)
 384		seq_puts(m, " CLUSTER,");
 385	if (tcon->capabilities & SMB2_SHARE_CAP_ASYMMETRIC)
 386		seq_puts(m, " ASYMMETRIC,");
 387	if (tcon->capabilities == 0)
 388		seq_puts(m, " None");
 389	if (tcon->ss_flags & SSINFO_FLAGS_ALIGNED_DEVICE)
 390		seq_puts(m, " Aligned,");
 391	if (tcon->ss_flags & SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE)
 392		seq_puts(m, " Partition Aligned,");
 393	if (tcon->ss_flags & SSINFO_FLAGS_NO_SEEK_PENALTY)
 394		seq_puts(m, " SSD,");
 395	if (tcon->ss_flags & SSINFO_FLAGS_TRIM_ENABLED)
 396		seq_puts(m, " TRIM-support,");
 397
 398	seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags);
 399	if (tcon->perf_sector_size)
 400		seq_printf(m, "\tOptimal sector size: 0x%x",
 401			   tcon->perf_sector_size);
 402}
 403
 404static void
 405smb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
 406{
 407#ifdef CONFIG_CIFS_STATS
 408	atomic_t *sent = tcon->stats.smb2_stats.smb2_com_sent;
 409	atomic_t *failed = tcon->stats.smb2_stats.smb2_com_failed;
 410	seq_printf(m, "\nNegotiates: %d sent %d failed",
 411		   atomic_read(&sent[SMB2_NEGOTIATE_HE]),
 412		   atomic_read(&failed[SMB2_NEGOTIATE_HE]));
 413	seq_printf(m, "\nSessionSetups: %d sent %d failed",
 414		   atomic_read(&sent[SMB2_SESSION_SETUP_HE]),
 415		   atomic_read(&failed[SMB2_SESSION_SETUP_HE]));
 416	seq_printf(m, "\nLogoffs: %d sent %d failed",
 417		   atomic_read(&sent[SMB2_LOGOFF_HE]),
 418		   atomic_read(&failed[SMB2_LOGOFF_HE]));
 419	seq_printf(m, "\nTreeConnects: %d sent %d failed",
 420		   atomic_read(&sent[SMB2_TREE_CONNECT_HE]),
 421		   atomic_read(&failed[SMB2_TREE_CONNECT_HE]));
 422	seq_printf(m, "\nTreeDisconnects: %d sent %d failed",
 423		   atomic_read(&sent[SMB2_TREE_DISCONNECT_HE]),
 424		   atomic_read(&failed[SMB2_TREE_DISCONNECT_HE]));
 425	seq_printf(m, "\nCreates: %d sent %d failed",
 426		   atomic_read(&sent[SMB2_CREATE_HE]),
 427		   atomic_read(&failed[SMB2_CREATE_HE]));
 428	seq_printf(m, "\nCloses: %d sent %d failed",
 429		   atomic_read(&sent[SMB2_CLOSE_HE]),
 430		   atomic_read(&failed[SMB2_CLOSE_HE]));
 431	seq_printf(m, "\nFlushes: %d sent %d failed",
 432		   atomic_read(&sent[SMB2_FLUSH_HE]),
 433		   atomic_read(&failed[SMB2_FLUSH_HE]));
 434	seq_printf(m, "\nReads: %d sent %d failed",
 435		   atomic_read(&sent[SMB2_READ_HE]),
 436		   atomic_read(&failed[SMB2_READ_HE]));
 437	seq_printf(m, "\nWrites: %d sent %d failed",
 438		   atomic_read(&sent[SMB2_WRITE_HE]),
 439		   atomic_read(&failed[SMB2_WRITE_HE]));
 440	seq_printf(m, "\nLocks: %d sent %d failed",
 441		   atomic_read(&sent[SMB2_LOCK_HE]),
 442		   atomic_read(&failed[SMB2_LOCK_HE]));
 443	seq_printf(m, "\nIOCTLs: %d sent %d failed",
 444		   atomic_read(&sent[SMB2_IOCTL_HE]),
 445		   atomic_read(&failed[SMB2_IOCTL_HE]));
 446	seq_printf(m, "\nCancels: %d sent %d failed",
 447		   atomic_read(&sent[SMB2_CANCEL_HE]),
 448		   atomic_read(&failed[SMB2_CANCEL_HE]));
 449	seq_printf(m, "\nEchos: %d sent %d failed",
 450		   atomic_read(&sent[SMB2_ECHO_HE]),
 451		   atomic_read(&failed[SMB2_ECHO_HE]));
 452	seq_printf(m, "\nQueryDirectories: %d sent %d failed",
 453		   atomic_read(&sent[SMB2_QUERY_DIRECTORY_HE]),
 454		   atomic_read(&failed[SMB2_QUERY_DIRECTORY_HE]));
 455	seq_printf(m, "\nChangeNotifies: %d sent %d failed",
 456		   atomic_read(&sent[SMB2_CHANGE_NOTIFY_HE]),
 457		   atomic_read(&failed[SMB2_CHANGE_NOTIFY_HE]));
 458	seq_printf(m, "\nQueryInfos: %d sent %d failed",
 459		   atomic_read(&sent[SMB2_QUERY_INFO_HE]),
 460		   atomic_read(&failed[SMB2_QUERY_INFO_HE]));
 461	seq_printf(m, "\nSetInfos: %d sent %d failed",
 462		   atomic_read(&sent[SMB2_SET_INFO_HE]),
 463		   atomic_read(&failed[SMB2_SET_INFO_HE]));
 464	seq_printf(m, "\nOplockBreaks: %d sent %d failed",
 465		   atomic_read(&sent[SMB2_OPLOCK_BREAK_HE]),
 466		   atomic_read(&failed[SMB2_OPLOCK_BREAK_HE]));
 467#endif
 468}
 469
 470static void
 471smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
 472{
 473	struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
 474	struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
 475
 476	cfile->fid.persistent_fid = fid->persistent_fid;
 477	cfile->fid.volatile_fid = fid->volatile_fid;
 478	server->ops->set_oplock_level(cinode, oplock, fid->epoch,
 479				      &fid->purge_cache);
 480	cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode);
 481}
 482
 483static void
 484smb2_close_file(const unsigned int xid, struct cifs_tcon *tcon,
 485		struct cifs_fid *fid)
 486{
 487	SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
 488}
 489
 490static int
 491SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon,
 492		     u64 persistent_fid, u64 volatile_fid,
 493		     struct copychunk_ioctl *pcchunk)
 494{
 495	int rc;
 496	unsigned int ret_data_len;
 497	struct resume_key_req *res_key;
 498
 499	rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid,
 500			FSCTL_SRV_REQUEST_RESUME_KEY, true /* is_fsctl */,
 501			NULL, 0 /* no input */,
 502			(char **)&res_key, &ret_data_len);
 503
 504	if (rc) {
 505		cifs_dbg(VFS, "refcpy ioctl error %d getting resume key\n", rc);
 506		goto req_res_key_exit;
 507	}
 508	if (ret_data_len < sizeof(struct resume_key_req)) {
 509		cifs_dbg(VFS, "Invalid refcopy resume key length\n");
 510		rc = -EINVAL;
 511		goto req_res_key_exit;
 512	}
 513	memcpy(pcchunk->SourceKey, res_key->ResumeKey, COPY_CHUNK_RES_KEY_SIZE);
 514
 515req_res_key_exit:
 516	kfree(res_key);
 517	return rc;
 518}
 519
 520static int
 521smb2_clone_range(const unsigned int xid,
 522			struct cifsFileInfo *srcfile,
 523			struct cifsFileInfo *trgtfile, u64 src_off,
 524			u64 len, u64 dest_off)
 525{
 526	int rc;
 527	unsigned int ret_data_len;
 528	struct copychunk_ioctl *pcchunk;
 529	struct copychunk_ioctl_rsp *retbuf = NULL;
 530	struct cifs_tcon *tcon;
 531	int chunks_copied = 0;
 532	bool chunk_sizes_updated = false;
 533
 534	pcchunk = kmalloc(sizeof(struct copychunk_ioctl), GFP_KERNEL);
 535
 536	if (pcchunk == NULL)
 537		return -ENOMEM;
 538
 539	cifs_dbg(FYI, "in smb2_clone_range - about to call request res key\n");
 540	/* Request a key from the server to identify the source of the copy */
 541	rc = SMB2_request_res_key(xid, tlink_tcon(srcfile->tlink),
 542				srcfile->fid.persistent_fid,
 543				srcfile->fid.volatile_fid, pcchunk);
 544
 545	/* Note: request_res_key sets res_key null only if rc !=0 */
 546	if (rc)
 547		goto cchunk_out;
 548
 549	/* For now array only one chunk long, will make more flexible later */
 550	pcchunk->ChunkCount = __constant_cpu_to_le32(1);
 551	pcchunk->Reserved = 0;
 552	pcchunk->Reserved2 = 0;
 553
 554	tcon = tlink_tcon(trgtfile->tlink);
 555
 556	while (len > 0) {
 557		pcchunk->SourceOffset = cpu_to_le64(src_off);
 558		pcchunk->TargetOffset = cpu_to_le64(dest_off);
 559		pcchunk->Length =
 560			cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk));
 561
 562		/* Request server copy to target from src identified by key */
 563		rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
 564			trgtfile->fid.volatile_fid, FSCTL_SRV_COPYCHUNK_WRITE,
 565			true /* is_fsctl */, (char *)pcchunk,
 566			sizeof(struct copychunk_ioctl),	(char **)&retbuf,
 567			&ret_data_len);
 568		if (rc == 0) {
 569			if (ret_data_len !=
 570					sizeof(struct copychunk_ioctl_rsp)) {
 571				cifs_dbg(VFS, "invalid cchunk response size\n");
 572				rc = -EIO;
 573				goto cchunk_out;
 574			}
 575			if (retbuf->TotalBytesWritten == 0) {
 576				cifs_dbg(FYI, "no bytes copied\n");
 577				rc = -EIO;
 578				goto cchunk_out;
 579			}
 580			/*
 581			 * Check if server claimed to write more than we asked
 582			 */
 583			if (le32_to_cpu(retbuf->TotalBytesWritten) >
 584			    le32_to_cpu(pcchunk->Length)) {
 585				cifs_dbg(VFS, "invalid copy chunk response\n");
 586				rc = -EIO;
 587				goto cchunk_out;
 588			}
 589			if (le32_to_cpu(retbuf->ChunksWritten) != 1) {
 590				cifs_dbg(VFS, "invalid num chunks written\n");
 591				rc = -EIO;
 592				goto cchunk_out;
 593			}
 594			chunks_copied++;
 595
 596			src_off += le32_to_cpu(retbuf->TotalBytesWritten);
 597			dest_off += le32_to_cpu(retbuf->TotalBytesWritten);
 598			len -= le32_to_cpu(retbuf->TotalBytesWritten);
 599
 600			cifs_dbg(FYI, "Chunks %d PartialChunk %d Total %d\n",
 601				le32_to_cpu(retbuf->ChunksWritten),
 602				le32_to_cpu(retbuf->ChunkBytesWritten),
 603				le32_to_cpu(retbuf->TotalBytesWritten));
 604		} else if (rc == -EINVAL) {
 605			if (ret_data_len != sizeof(struct copychunk_ioctl_rsp))
 606				goto cchunk_out;
 607
 608			cifs_dbg(FYI, "MaxChunks %d BytesChunk %d MaxCopy %d\n",
 609				le32_to_cpu(retbuf->ChunksWritten),
 610				le32_to_cpu(retbuf->ChunkBytesWritten),
 611				le32_to_cpu(retbuf->TotalBytesWritten));
 612
 613			/*
 614			 * Check if this is the first request using these sizes,
 615			 * (ie check if copy succeed once with original sizes
 616			 * and check if the server gave us different sizes after
 617			 * we already updated max sizes on previous request).
 618			 * if not then why is the server returning an error now
 619			 */
 620			if ((chunks_copied != 0) || chunk_sizes_updated)
 621				goto cchunk_out;
 622
 623			/* Check that server is not asking us to grow size */
 624			if (le32_to_cpu(retbuf->ChunkBytesWritten) <
 625					tcon->max_bytes_chunk)
 626				tcon->max_bytes_chunk =
 627					le32_to_cpu(retbuf->ChunkBytesWritten);
 628			else
 629				goto cchunk_out; /* server gave us bogus size */
 630
 631			/* No need to change MaxChunks since already set to 1 */
 632			chunk_sizes_updated = true;
 633		}
 634	}
 635
 636cchunk_out:
 637	kfree(pcchunk);
 638	return rc;
 639}
 640
 641static int
 642smb2_flush_file(const unsigned int xid, struct cifs_tcon *tcon,
 643		struct cifs_fid *fid)
 644{
 645	return SMB2_flush(xid, tcon, fid->persistent_fid, fid->volatile_fid);
 646}
 647
 648static unsigned int
 649smb2_read_data_offset(char *buf)
 650{
 651	struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
 652	return rsp->DataOffset;
 653}
 654
 655static unsigned int
 656smb2_read_data_length(char *buf)
 657{
 658	struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
 659	return le32_to_cpu(rsp->DataLength);
 660}
 661
 662
 663static int
 664smb2_sync_read(const unsigned int xid, struct cifsFileInfo *cfile,
 665	       struct cifs_io_parms *parms, unsigned int *bytes_read,
 666	       char **buf, int *buf_type)
 667{
 668	parms->persistent_fid = cfile->fid.persistent_fid;
 669	parms->volatile_fid = cfile->fid.volatile_fid;
 670	return SMB2_read(xid, parms, bytes_read, buf, buf_type);
 671}
 672
 673static int
 674smb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile,
 675		struct cifs_io_parms *parms, unsigned int *written,
 676		struct kvec *iov, unsigned long nr_segs)
 677{
 678
 679	parms->persistent_fid = cfile->fid.persistent_fid;
 680	parms->volatile_fid = cfile->fid.volatile_fid;
 681	return SMB2_write(xid, parms, written, iov, nr_segs);
 682}
 683
 684static int
 685smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
 686		   struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
 687{
 688	__le64 eof = cpu_to_le64(size);
 689	return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
 690			    cfile->fid.volatile_fid, cfile->pid, &eof);
 691}
 692
 693static int
 694smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
 695		   struct cifsFileInfo *cfile)
 696{
 697	return SMB2_set_compression(xid, tcon, cfile->fid.persistent_fid,
 698			    cfile->fid.volatile_fid);
 699}
 700
 701static int
 702smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
 703		     const char *path, struct cifs_sb_info *cifs_sb,
 704		     struct cifs_fid *fid, __u16 search_flags,
 705		     struct cifs_search_info *srch_inf)
 706{
 707	__le16 *utf16_path;
 708	int rc;
 709	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 710	struct cifs_open_parms oparms;
 711
 712	utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
 713	if (!utf16_path)
 714		return -ENOMEM;
 715
 716	oparms.tcon = tcon;
 717	oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
 718	oparms.disposition = FILE_OPEN;
 719	oparms.create_options = 0;
 720	oparms.fid = fid;
 721	oparms.reconnect = false;
 722
 723	rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
 724	kfree(utf16_path);
 725	if (rc) {
 726		cifs_dbg(VFS, "open dir failed\n");
 727		return rc;
 728	}
 729
 730	srch_inf->entries_in_buffer = 0;
 731	srch_inf->index_of_last_entry = 0;
 732
 733	rc = SMB2_query_directory(xid, tcon, fid->persistent_fid,
 734				  fid->volatile_fid, 0, srch_inf);
 735	if (rc) {
 736		cifs_dbg(VFS, "query directory failed\n");
 737		SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
 738	}
 739	return rc;
 740}
 741
 742static int
 743smb2_query_dir_next(const unsigned int xid, struct cifs_tcon *tcon,
 744		    struct cifs_fid *fid, __u16 search_flags,
 745		    struct cifs_search_info *srch_inf)
 746{
 747	return SMB2_query_directory(xid, tcon, fid->persistent_fid,
 748				    fid->volatile_fid, 0, srch_inf);
 749}
 750
 751static int
 752smb2_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
 753	       struct cifs_fid *fid)
 754{
 755	return SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
 756}
 757
 758/*
 759* If we negotiate SMB2 protocol and get STATUS_PENDING - update
 760* the number of credits and return true. Otherwise - return false.
 761*/
 762static bool
 763smb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length)
 764{
 765	struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
 766
 767	if (hdr->Status != STATUS_PENDING)
 768		return false;
 769
 770	if (!length) {
 771		spin_lock(&server->req_lock);
 772		server->credits += le16_to_cpu(hdr->CreditRequest);
 773		spin_unlock(&server->req_lock);
 774		wake_up(&server->request_q);
 775	}
 776
 777	return true;
 778}
 779
 780static int
 781smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
 782		     struct cifsInodeInfo *cinode)
 783{
 784	if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
 785		return SMB2_lease_break(0, tcon, cinode->lease_key,
 786					smb2_get_lease_state(cinode));
 787
 788	return SMB2_oplock_break(0, tcon, fid->persistent_fid,
 789				 fid->volatile_fid,
 790				 CIFS_CACHE_READ(cinode) ? 1 : 0);
 791}
 792
 793static int
 794smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
 795	     struct kstatfs *buf)
 796{
 797	int rc;
 798	__le16 srch_path = 0; /* Null - open root of share */
 799	u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 800	struct cifs_open_parms oparms;
 801	struct cifs_fid fid;
 802
 803	oparms.tcon = tcon;
 804	oparms.desired_access = FILE_READ_ATTRIBUTES;
 805	oparms.disposition = FILE_OPEN;
 806	oparms.create_options = 0;
 807	oparms.fid = &fid;
 808	oparms.reconnect = false;
 809
 810	rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
 811	if (rc)
 812		return rc;
 813	buf->f_type = SMB2_MAGIC_NUMBER;
 814	rc = SMB2_QFS_info(xid, tcon, fid.persistent_fid, fid.volatile_fid,
 815			   buf);
 816	SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
 817	return rc;
 818}
 819
 820static bool
 821smb2_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
 822{
 823	return ob1->fid.persistent_fid == ob2->fid.persistent_fid &&
 824	       ob1->fid.volatile_fid == ob2->fid.volatile_fid;
 825}
 826
 827static int
 828smb2_mand_lock(const unsigned int xid, struct cifsFileInfo *cfile, __u64 offset,
 829	       __u64 length, __u32 type, int lock, int unlock, bool wait)
 830{
 831	if (unlock && !lock)
 832		type = SMB2_LOCKFLAG_UNLOCK;
 833	return SMB2_lock(xid, tlink_tcon(cfile->tlink),
 834			 cfile->fid.persistent_fid, cfile->fid.volatile_fid,
 835			 current->tgid, length, offset, type, wait);
 836}
 837
 838static void
 839smb2_get_lease_key(struct inode *inode, struct cifs_fid *fid)
 840{
 841	memcpy(fid->lease_key, CIFS_I(inode)->lease_key, SMB2_LEASE_KEY_SIZE);
 842}
 843
 844static void
 845smb2_set_lease_key(struct inode *inode, struct cifs_fid *fid)
 846{
 847	memcpy(CIFS_I(inode)->lease_key, fid->lease_key, SMB2_LEASE_KEY_SIZE);
 848}
 849
 850static void
 851smb2_new_lease_key(struct cifs_fid *fid)
 852{
 853	get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE);
 854}
 855
 856static int
 857smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 858		   const char *full_path, char **target_path,
 859		   struct cifs_sb_info *cifs_sb)
 860{
 861	int rc;
 862	__le16 *utf16_path;
 863	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 864	struct cifs_open_parms oparms;
 865	struct cifs_fid fid;
 866	struct smb2_err_rsp *err_buf = NULL;
 867	struct smb2_symlink_err_rsp *symlink;
 868	unsigned int sub_len, sub_offset;
 869
 870	cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
 871
 872	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
 873	if (!utf16_path)
 874		return -ENOMEM;
 875
 876	oparms.tcon = tcon;
 877	oparms.desired_access = FILE_READ_ATTRIBUTES;
 878	oparms.disposition = FILE_OPEN;
 879	oparms.create_options = 0;
 880	oparms.fid = &fid;
 881	oparms.reconnect = false;
 882
 883	rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, &err_buf);
 884
 885	if (!rc || !err_buf) {
 886		kfree(utf16_path);
 887		return -ENOENT;
 888	}
 889	/* open must fail on symlink - reset rc */
 890	rc = 0;
 891	symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
 892	sub_len = le16_to_cpu(symlink->SubstituteNameLength);
 893	sub_offset = le16_to_cpu(symlink->SubstituteNameOffset);
 894	*target_path = cifs_strndup_from_utf16(
 895				(char *)symlink->PathBuffer + sub_offset,
 896				sub_len, true, cifs_sb->local_nls);
 897	if (!(*target_path)) {
 898		kfree(utf16_path);
 899		return -ENOMEM;
 900	}
 901	convert_delimiter(*target_path, '/');
 902	cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
 903	kfree(utf16_path);
 904	return rc;
 905}
 906
 907static void
 908smb2_downgrade_oplock(struct TCP_Server_Info *server,
 909			struct cifsInodeInfo *cinode, bool set_level2)
 910{
 911	if (set_level2)
 912		server->ops->set_oplock_level(cinode, SMB2_OPLOCK_LEVEL_II,
 913						0, NULL);
 914	else
 915		server->ops->set_oplock_level(cinode, 0, 0, NULL);
 916}
 917
 918static void
 919smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
 920		      unsigned int epoch, bool *purge_cache)
 921{
 922	oplock &= 0xFF;
 923	if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
 924		return;
 925	if (oplock == SMB2_OPLOCK_LEVEL_BATCH) {
 926		cinode->oplock = CIFS_CACHE_RHW_FLG;
 927		cifs_dbg(FYI, "Batch Oplock granted on inode %p\n",
 928			 &cinode->vfs_inode);
 929	} else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
 930		cinode->oplock = CIFS_CACHE_RW_FLG;
 931		cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n",
 932			 &cinode->vfs_inode);
 933	} else if (oplock == SMB2_OPLOCK_LEVEL_II) {
 934		cinode->oplock = CIFS_CACHE_READ_FLG;
 935		cifs_dbg(FYI, "Level II Oplock granted on inode %p\n",
 936			 &cinode->vfs_inode);
 937	} else
 938		cinode->oplock = 0;
 939}
 940
 941static void
 942smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
 943		       unsigned int epoch, bool *purge_cache)
 944{
 945	char message[5] = {0};
 946
 947	oplock &= 0xFF;
 948	if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
 949		return;
 950
 951	cinode->oplock = 0;
 952	if (oplock & SMB2_LEASE_READ_CACHING_HE) {
 953		cinode->oplock |= CIFS_CACHE_READ_FLG;
 954		strcat(message, "R");
 955	}
 956	if (oplock & SMB2_LEASE_HANDLE_CACHING_HE) {
 957		cinode->oplock |= CIFS_CACHE_HANDLE_FLG;
 958		strcat(message, "H");
 959	}
 960	if (oplock & SMB2_LEASE_WRITE_CACHING_HE) {
 961		cinode->oplock |= CIFS_CACHE_WRITE_FLG;
 962		strcat(message, "W");
 963	}
 964	if (!cinode->oplock)
 965		strcat(message, "None");
 966	cifs_dbg(FYI, "%s Lease granted on inode %p\n", message,
 967		 &cinode->vfs_inode);
 968}
 969
 970static void
 971smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
 972		      unsigned int epoch, bool *purge_cache)
 973{
 974	unsigned int old_oplock = cinode->oplock;
 975
 976	smb21_set_oplock_level(cinode, oplock, epoch, purge_cache);
 977
 978	if (purge_cache) {
 979		*purge_cache = false;
 980		if (old_oplock == CIFS_CACHE_READ_FLG) {
 981			if (cinode->oplock == CIFS_CACHE_READ_FLG &&
 982			    (epoch - cinode->epoch > 0))
 983				*purge_cache = true;
 984			else if (cinode->oplock == CIFS_CACHE_RH_FLG &&
 985				 (epoch - cinode->epoch > 1))
 986				*purge_cache = true;
 987			else if (cinode->oplock == CIFS_CACHE_RHW_FLG &&
 988				 (epoch - cinode->epoch > 1))
 989				*purge_cache = true;
 990			else if (cinode->oplock == 0 &&
 991				 (epoch - cinode->epoch > 0))
 992				*purge_cache = true;
 993		} else if (old_oplock == CIFS_CACHE_RH_FLG) {
 994			if (cinode->oplock == CIFS_CACHE_RH_FLG &&
 995			    (epoch - cinode->epoch > 0))
 996				*purge_cache = true;
 997			else if (cinode->oplock == CIFS_CACHE_RHW_FLG &&
 998				 (epoch - cinode->epoch > 1))
 999				*purge_cache = true;
1000		}
1001		cinode->epoch = epoch;
1002	}
1003}
1004
1005static bool
1006smb2_is_read_op(__u32 oplock)
1007{
1008	return oplock == SMB2_OPLOCK_LEVEL_II;
1009}
1010
1011static bool
1012smb21_is_read_op(__u32 oplock)
1013{
1014	return (oplock & SMB2_LEASE_READ_CACHING_HE) &&
1015	       !(oplock & SMB2_LEASE_WRITE_CACHING_HE);
1016}
1017
1018static __le32
1019map_oplock_to_lease(u8 oplock)
1020{
1021	if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE)
1022		return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING;
1023	else if (oplock == SMB2_OPLOCK_LEVEL_II)
1024		return SMB2_LEASE_READ_CACHING;
1025	else if (oplock == SMB2_OPLOCK_LEVEL_BATCH)
1026		return SMB2_LEASE_HANDLE_CACHING | SMB2_LEASE_READ_CACHING |
1027		       SMB2_LEASE_WRITE_CACHING;
1028	return 0;
1029}
1030
1031static char *
1032smb2_create_lease_buf(u8 *lease_key, u8 oplock)
1033{
1034	struct create_lease *buf;
1035
1036	buf = kzalloc(sizeof(struct create_lease), GFP_KERNEL);
1037	if (!buf)
1038		return NULL;
1039
1040	buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key));
1041	buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8)));
1042	buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
1043
1044	buf->ccontext.DataOffset = cpu_to_le16(offsetof
1045					(struct create_lease, lcontext));
1046	buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context));
1047	buf->ccontext.NameOffset = cpu_to_le16(offsetof
1048				(struct create_lease, Name));
1049	buf->ccontext.NameLength = cpu_to_le16(4);
1050	buf->Name[0] = 'R';
1051	buf->Name[1] = 'q';
1052	buf->Name[2] = 'L';
1053	buf->Name[3] = 's';
1054	return (char *)buf;
1055}
1056
1057static char *
1058smb3_create_lease_buf(u8 *lease_key, u8 oplock)
1059{
1060	struct create_lease_v2 *buf;
1061
1062	buf = kzalloc(sizeof(struct create_lease_v2), GFP_KERNEL);
1063	if (!buf)
1064		return NULL;
1065
1066	buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key));
1067	buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8)));
1068	buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
1069
1070	buf->ccontext.DataOffset = cpu_to_le16(offsetof
1071					(struct create_lease_v2, lcontext));
1072	buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2));
1073	buf->ccontext.NameOffset = cpu_to_le16(offsetof
1074				(struct create_lease_v2, Name));
1075	buf->ccontext.NameLength = cpu_to_le16(4);
1076	buf->Name[0] = 'R';
1077	buf->Name[1] = 'q';
1078	buf->Name[2] = 'L';
1079	buf->Name[3] = 's';
1080	return (char *)buf;
1081}
1082
1083static __u8
1084smb2_parse_lease_buf(void *buf, unsigned int *epoch)
1085{
1086	struct create_lease *lc = (struct create_lease *)buf;
1087
1088	*epoch = 0; /* not used */
1089	if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
1090		return SMB2_OPLOCK_LEVEL_NOCHANGE;
1091	return le32_to_cpu(lc->lcontext.LeaseState);
1092}
1093
1094static __u8
1095smb3_parse_lease_buf(void *buf, unsigned int *epoch)
1096{
1097	struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;
1098
1099	*epoch = le16_to_cpu(lc->lcontext.Epoch);
1100	if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
1101		return SMB2_OPLOCK_LEVEL_NOCHANGE;
1102	return le32_to_cpu(lc->lcontext.LeaseState);
1103}
1104
1105struct smb_version_operations smb20_operations = {
1106	.compare_fids = smb2_compare_fids,
1107	.setup_request = smb2_setup_request,
1108	.setup_async_request = smb2_setup_async_request,
1109	.check_receive = smb2_check_receive,
1110	.add_credits = smb2_add_credits,
1111	.set_credits = smb2_set_credits,
1112	.get_credits_field = smb2_get_credits_field,
1113	.get_credits = smb2_get_credits,
1114	.get_next_mid = smb2_get_next_mid,
1115	.read_data_offset = smb2_read_data_offset,
1116	.read_data_length = smb2_read_data_length,
1117	.map_error = map_smb2_to_linux_error,
1118	.find_mid = smb2_find_mid,
1119	.check_message = smb2_check_message,
1120	.dump_detail = smb2_dump_detail,
1121	.clear_stats = smb2_clear_stats,
1122	.print_stats = smb2_print_stats,
1123	.is_oplock_break = smb2_is_valid_oplock_break,
1124	.downgrade_oplock = smb2_downgrade_oplock,
1125	.need_neg = smb2_need_neg,
1126	.negotiate = smb2_negotiate,
1127	.negotiate_wsize = smb2_negotiate_wsize,
1128	.negotiate_rsize = smb2_negotiate_rsize,
1129	.sess_setup = SMB2_sess_setup,
1130	.logoff = SMB2_logoff,
1131	.tree_connect = SMB2_tcon,
1132	.tree_disconnect = SMB2_tdis,
1133	.qfs_tcon = smb2_qfs_tcon,
1134	.is_path_accessible = smb2_is_path_accessible,
1135	.can_echo = smb2_can_echo,
1136	.echo = SMB2_echo,
1137	.query_path_info = smb2_query_path_info,
1138	.get_srv_inum = smb2_get_srv_inum,
1139	.query_file_info = smb2_query_file_info,
1140	.set_path_size = smb2_set_path_size,
1141	.set_file_size = smb2_set_file_size,
1142	.set_file_info = smb2_set_file_info,
1143	.set_compression = smb2_set_compression,
1144	.mkdir = smb2_mkdir,
1145	.mkdir_setinfo = smb2_mkdir_setinfo,
1146	.rmdir = smb2_rmdir,
1147	.unlink = smb2_unlink,
1148	.rename = smb2_rename_path,
1149	.create_hardlink = smb2_create_hardlink,
1150	.query_symlink = smb2_query_symlink,
1151	.open = smb2_open_file,
1152	.set_fid = smb2_set_fid,
1153	.close = smb2_close_file,
1154	.flush = smb2_flush_file,
1155	.async_readv = smb2_async_readv,
1156	.async_writev = smb2_async_writev,
1157	.sync_read = smb2_sync_read,
1158	.sync_write = smb2_sync_write,
1159	.query_dir_first = smb2_query_dir_first,
1160	.query_dir_next = smb2_query_dir_next,
1161	.close_dir = smb2_close_dir,
1162	.calc_smb_size = smb2_calc_size,
1163	.is_status_pending = smb2_is_status_pending,
1164	.oplock_response = smb2_oplock_response,
1165	.queryfs = smb2_queryfs,
1166	.mand_lock = smb2_mand_lock,
1167	.mand_unlock_range = smb2_unlock_range,
1168	.push_mand_locks = smb2_push_mandatory_locks,
1169	.get_lease_key = smb2_get_lease_key,
1170	.set_lease_key = smb2_set_lease_key,
1171	.new_lease_key = smb2_new_lease_key,
1172	.calc_signature = smb2_calc_signature,
1173	.is_read_op = smb2_is_read_op,
1174	.set_oplock_level = smb2_set_oplock_level,
1175	.create_lease_buf = smb2_create_lease_buf,
1176	.parse_lease_buf = smb2_parse_lease_buf,
1177	.clone_range = smb2_clone_range,
1178};
1179
1180struct smb_version_operations smb21_operations = {
1181	.compare_fids = smb2_compare_fids,
1182	.setup_request = smb2_setup_request,
1183	.setup_async_request = smb2_setup_async_request,
1184	.check_receive = smb2_check_receive,
1185	.add_credits = smb2_add_credits,
1186	.set_credits = smb2_set_credits,
1187	.get_credits_field = smb2_get_credits_field,
1188	.get_credits = smb2_get_credits,
1189	.get_next_mid = smb2_get_next_mid,
1190	.read_data_offset = smb2_read_data_offset,
1191	.read_data_length = smb2_read_data_length,
1192	.map_error = map_smb2_to_linux_error,
1193	.find_mid = smb2_find_mid,
1194	.check_message = smb2_check_message,
1195	.dump_detail = smb2_dump_detail,
1196	.clear_stats = smb2_clear_stats,
1197	.print_stats = smb2_print_stats,
1198	.is_oplock_break = smb2_is_valid_oplock_break,
1199	.downgrade_oplock = smb2_downgrade_oplock,
1200	.need_neg = smb2_need_neg,
1201	.negotiate = smb2_negotiate,
1202	.negotiate_wsize = smb2_negotiate_wsize,
1203	.negotiate_rsize = smb2_negotiate_rsize,
1204	.sess_setup = SMB2_sess_setup,
1205	.logoff = SMB2_logoff,
1206	.tree_connect = SMB2_tcon,
1207	.tree_disconnect = SMB2_tdis,
1208	.qfs_tcon = smb2_qfs_tcon,
1209	.is_path_accessible = smb2_is_path_accessible,
1210	.can_echo = smb2_can_echo,
1211	.echo = SMB2_echo,
1212	.query_path_info = smb2_query_path_info,
1213	.get_srv_inum = smb2_get_srv_inum,
1214	.query_file_info = smb2_query_file_info,
1215	.set_path_size = smb2_set_path_size,
1216	.set_file_size = smb2_set_file_size,
1217	.set_file_info = smb2_set_file_info,
1218	.set_compression = smb2_set_compression,
1219	.mkdir = smb2_mkdir,
1220	.mkdir_setinfo = smb2_mkdir_setinfo,
1221	.rmdir = smb2_rmdir,
1222	.unlink = smb2_unlink,
1223	.rename = smb2_rename_path,
1224	.create_hardlink = smb2_create_hardlink,
1225	.query_symlink = smb2_query_symlink,
1226	.open = smb2_open_file,
1227	.set_fid = smb2_set_fid,
1228	.close = smb2_close_file,
1229	.flush = smb2_flush_file,
1230	.async_readv = smb2_async_readv,
1231	.async_writev = smb2_async_writev,
1232	.sync_read = smb2_sync_read,
1233	.sync_write = smb2_sync_write,
1234	.query_dir_first = smb2_query_dir_first,
1235	.query_dir_next = smb2_query_dir_next,
1236	.close_dir = smb2_close_dir,
1237	.calc_smb_size = smb2_calc_size,
1238	.is_status_pending = smb2_is_status_pending,
1239	.oplock_response = smb2_oplock_response,
1240	.queryfs = smb2_queryfs,
1241	.mand_lock = smb2_mand_lock,
1242	.mand_unlock_range = smb2_unlock_range,
1243	.push_mand_locks = smb2_push_mandatory_locks,
1244	.get_lease_key = smb2_get_lease_key,
1245	.set_lease_key = smb2_set_lease_key,
1246	.new_lease_key = smb2_new_lease_key,
1247	.calc_signature = smb2_calc_signature,
1248	.is_read_op = smb21_is_read_op,
1249	.set_oplock_level = smb21_set_oplock_level,
1250	.create_lease_buf = smb2_create_lease_buf,
1251	.parse_lease_buf = smb2_parse_lease_buf,
1252	.clone_range = smb2_clone_range,
1253};
1254
1255struct smb_version_operations smb30_operations = {
1256	.compare_fids = smb2_compare_fids,
1257	.setup_request = smb2_setup_request,
1258	.setup_async_request = smb2_setup_async_request,
1259	.check_receive = smb2_check_receive,
1260	.add_credits = smb2_add_credits,
1261	.set_credits = smb2_set_credits,
1262	.get_credits_field = smb2_get_credits_field,
1263	.get_credits = smb2_get_credits,
1264	.get_next_mid = smb2_get_next_mid,
1265	.read_data_offset = smb2_read_data_offset,
1266	.read_data_length = smb2_read_data_length,
1267	.map_error = map_smb2_to_linux_error,
1268	.find_mid = smb2_find_mid,
1269	.check_message = smb2_check_message,
1270	.dump_detail = smb2_dump_detail,
1271	.clear_stats = smb2_clear_stats,
1272	.print_stats = smb2_print_stats,
1273	.dump_share_caps = smb2_dump_share_caps,
1274	.is_oplock_break = smb2_is_valid_oplock_break,
1275	.downgrade_oplock = smb2_downgrade_oplock,
1276	.need_neg = smb2_need_neg,
1277	.negotiate = smb2_negotiate,
1278	.negotiate_wsize = smb2_negotiate_wsize,
1279	.negotiate_rsize = smb2_negotiate_rsize,
1280	.sess_setup = SMB2_sess_setup,
1281	.logoff = SMB2_logoff,
1282	.tree_connect = SMB2_tcon,
1283	.tree_disconnect = SMB2_tdis,
1284	.qfs_tcon = smb3_qfs_tcon,
1285	.is_path_accessible = smb2_is_path_accessible,
1286	.can_echo = smb2_can_echo,
1287	.echo = SMB2_echo,
1288	.query_path_info = smb2_query_path_info,
1289	.get_srv_inum = smb2_get_srv_inum,
1290	.query_file_info = smb2_query_file_info,
1291	.set_path_size = smb2_set_path_size,
1292	.set_file_size = smb2_set_file_size,
1293	.set_file_info = smb2_set_file_info,
1294	.set_compression = smb2_set_compression,
1295	.mkdir = smb2_mkdir,
1296	.mkdir_setinfo = smb2_mkdir_setinfo,
1297	.rmdir = smb2_rmdir,
1298	.unlink = smb2_unlink,
1299	.rename = smb2_rename_path,
1300	.create_hardlink = smb2_create_hardlink,
1301	.query_symlink = smb2_query_symlink,
1302	.open = smb2_open_file,
1303	.set_fid = smb2_set_fid,
1304	.close = smb2_close_file,
1305	.flush = smb2_flush_file,
1306	.async_readv = smb2_async_readv,
1307	.async_writev = smb2_async_writev,
1308	.sync_read = smb2_sync_read,
1309	.sync_write = smb2_sync_write,
1310	.query_dir_first = smb2_query_dir_first,
1311	.query_dir_next = smb2_query_dir_next,
1312	.close_dir = smb2_close_dir,
1313	.calc_smb_size = smb2_calc_size,
1314	.is_status_pending = smb2_is_status_pending,
1315	.oplock_response = smb2_oplock_response,
1316	.queryfs = smb2_queryfs,
1317	.mand_lock = smb2_mand_lock,
1318	.mand_unlock_range = smb2_unlock_range,
1319	.push_mand_locks = smb2_push_mandatory_locks,
1320	.get_lease_key = smb2_get_lease_key,
1321	.set_lease_key = smb2_set_lease_key,
1322	.new_lease_key = smb2_new_lease_key,
1323	.generate_signingkey = generate_smb3signingkey,
1324	.calc_signature = smb3_calc_signature,
1325	.is_read_op = smb21_is_read_op,
1326	.set_oplock_level = smb3_set_oplock_level,
1327	.create_lease_buf = smb3_create_lease_buf,
1328	.parse_lease_buf = smb3_parse_lease_buf,
1329	.clone_range = smb2_clone_range,
1330	.validate_negotiate = smb3_validate_negotiate,
1331};
1332
1333struct smb_version_values smb20_values = {
1334	.version_string = SMB20_VERSION_STRING,
1335	.protocol_id = SMB20_PROT_ID,
1336	.req_capabilities = 0, /* MBZ */
1337	.large_lock_type = 0,
1338	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1339	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1340	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1341	.header_size = sizeof(struct smb2_hdr),
1342	.max_header_size = MAX_SMB2_HDR_SIZE,
1343	.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1344	.lock_cmd = SMB2_LOCK,
1345	.cap_unix = 0,
1346	.cap_nt_find = SMB2_NT_FIND,
1347	.cap_large_files = SMB2_LARGE_FILES,
1348	.signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1349	.signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1350	.create_lease_size = sizeof(struct create_lease),
1351};
1352
1353struct smb_version_values smb21_values = {
1354	.version_string = SMB21_VERSION_STRING,
1355	.protocol_id = SMB21_PROT_ID,
1356	.req_capabilities = 0, /* MBZ on negotiate req until SMB3 dialect */
1357	.large_lock_type = 0,
1358	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1359	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1360	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1361	.header_size = sizeof(struct smb2_hdr),
1362	.max_header_size = MAX_SMB2_HDR_SIZE,
1363	.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1364	.lock_cmd = SMB2_LOCK,
1365	.cap_unix = 0,
1366	.cap_nt_find = SMB2_NT_FIND,
1367	.cap_large_files = SMB2_LARGE_FILES,
1368	.signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1369	.signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1370	.create_lease_size = sizeof(struct create_lease),
1371};
1372
1373struct smb_version_values smb30_values = {
1374	.version_string = SMB30_VERSION_STRING,
1375	.protocol_id = SMB30_PROT_ID,
1376	.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
1377	.large_lock_type = 0,
1378	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1379	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1380	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1381	.header_size = sizeof(struct smb2_hdr),
1382	.max_header_size = MAX_SMB2_HDR_SIZE,
1383	.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1384	.lock_cmd = SMB2_LOCK,
1385	.cap_unix = 0,
1386	.cap_nt_find = SMB2_NT_FIND,
1387	.cap_large_files = SMB2_LARGE_FILES,
1388	.signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1389	.signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1390	.create_lease_size = sizeof(struct create_lease_v2),
1391};
1392
1393struct smb_version_values smb302_values = {
1394	.version_string = SMB302_VERSION_STRING,
1395	.protocol_id = SMB302_PROT_ID,
1396	.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
1397	.large_lock_type = 0,
1398	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1399	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1400	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1401	.header_size = sizeof(struct smb2_hdr),
1402	.max_header_size = MAX_SMB2_HDR_SIZE,
1403	.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1404	.lock_cmd = SMB2_LOCK,
1405	.cap_unix = 0,
1406	.cap_nt_find = SMB2_NT_FIND,
1407	.cap_large_files = SMB2_LARGE_FILES,
1408	.signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1409	.signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1410	.create_lease_size = sizeof(struct create_lease_v2),
1411};