smb2ops.c revision 1a500f010fb2d121c58f77ddfde2eca1bde3bfcd
11080ef758fb87f286b25277d8373e680a9e73363Steve French/*
21080ef758fb87f286b25277d8373e680a9e73363Steve French *  SMB2 version specific operations
31080ef758fb87f286b25277d8373e680a9e73363Steve French *
41080ef758fb87f286b25277d8373e680a9e73363Steve French *  Copyright (c) 2012, Jeff Layton <jlayton@redhat.com>
51080ef758fb87f286b25277d8373e680a9e73363Steve French *
61080ef758fb87f286b25277d8373e680a9e73363Steve French *  This library is free software; you can redistribute it and/or modify
71080ef758fb87f286b25277d8373e680a9e73363Steve French *  it under the terms of the GNU General Public License v2 as published
81080ef758fb87f286b25277d8373e680a9e73363Steve French *  by the Free Software Foundation.
91080ef758fb87f286b25277d8373e680a9e73363Steve French *
101080ef758fb87f286b25277d8373e680a9e73363Steve French *  This library is distributed in the hope that it will be useful,
111080ef758fb87f286b25277d8373e680a9e73363Steve French *  but WITHOUT ANY WARRANTY; without even the implied warranty of
121080ef758fb87f286b25277d8373e680a9e73363Steve French *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
131080ef758fb87f286b25277d8373e680a9e73363Steve French *  the GNU Lesser General Public License for more details.
141080ef758fb87f286b25277d8373e680a9e73363Steve French *
151080ef758fb87f286b25277d8373e680a9e73363Steve French *  You should have received a copy of the GNU Lesser General Public License
161080ef758fb87f286b25277d8373e680a9e73363Steve French *  along with this library; if not, write to the Free Software
171080ef758fb87f286b25277d8373e680a9e73363Steve French *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
181080ef758fb87f286b25277d8373e680a9e73363Steve French */
191080ef758fb87f286b25277d8373e680a9e73363Steve French
201080ef758fb87f286b25277d8373e680a9e73363Steve French#include "cifsglob.h"
212dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky#include "smb2pdu.h"
222dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky#include "smb2proto.h"
2328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky#include "cifsproto.h"
2428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky#include "cifs_debug.h"
2528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
2628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic int
2728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskychange_conf(struct TCP_Server_Info *server)
2828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
2928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->credits += server->echo_credits + server->oplock_credits;
3028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->oplock_credits = server->echo_credits = 0;
3128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	switch (server->credits) {
3228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case 0:
3328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		return -1;
3428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case 1:
3528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echoes = false;
3628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->oplocks = false;
3728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		cERROR(1, "disabling echoes and oplocks");
3828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		break;
3928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case 2:
4028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echoes = true;
4128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->oplocks = false;
4228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echo_credits = 1;
4328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		cFYI(1, "disabling oplocks");
4428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		break;
4528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	default:
4628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echoes = true;
4728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->oplocks = true;
4828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echo_credits = 1;
4928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->oplock_credits = 1;
5028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	}
5128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->credits -= server->echo_credits + server->oplock_credits;
5228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	return 0;
5328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
5428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
5528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic void
5628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
5728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		 const int optype)
5828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
5928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	int *val, rc = 0;
6028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	spin_lock(&server->req_lock);
6128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	val = server->ops->get_credits_field(server, optype);
6228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	*val += add;
6328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->in_flight--;
64ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP)
6528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		rc = change_conf(server);
6628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	spin_unlock(&server->req_lock);
6728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	wake_up(&server->request_q);
6828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	if (rc)
6928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		cifs_reconnect(server);
7028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
7128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
7228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic void
7328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_set_credits(struct TCP_Server_Info *server, const int val)
7428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
7528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	spin_lock(&server->req_lock);
7628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->credits = val;
7728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	spin_unlock(&server->req_lock);
7828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
7928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
8028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic int *
8128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_get_credits_field(struct TCP_Server_Info *server, const int optype)
8228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
8328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	switch (optype) {
8428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case CIFS_ECHO_OP:
8528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		return &server->echo_credits;
8628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case CIFS_OBREAK_OP:
8728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		return &server->oplock_credits;
8828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	default:
8928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		return &server->credits;
9028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	}
9128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
9228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
9328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic unsigned int
9428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_get_credits(struct mid_q_entry *mid)
9528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
9628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	return le16_to_cpu(((struct smb2_hdr *)mid->resp_buf)->CreditRequest);
9728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
982dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky
992dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovskystatic __u64
1002dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovskysmb2_get_next_mid(struct TCP_Server_Info *server)
1012dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky{
1022dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	__u64 mid;
1032dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	/* for SMB2 we need the current value */
1042dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	spin_lock(&GlobalMid_Lock);
1052dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	mid = server->CurrentMid++;
1062dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	spin_unlock(&GlobalMid_Lock);
1072dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	return mid;
1082dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky}
1091080ef758fb87f286b25277d8373e680a9e73363Steve French
110093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskystatic struct mid_q_entry *
111093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskysmb2_find_mid(struct TCP_Server_Info *server, char *buf)
112093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky{
113093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	struct mid_q_entry *mid;
114093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
115093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky
116093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	spin_lock(&GlobalMid_Lock);
117093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	list_for_each_entry(mid, &server->pending_mid_q, qhead) {
118093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		if ((mid->mid == hdr->MessageId) &&
119093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		    (mid->mid_state == MID_REQUEST_SUBMITTED) &&
120093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		    (mid->command == hdr->Command)) {
121093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky			spin_unlock(&GlobalMid_Lock);
122093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky			return mid;
123093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		}
124093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	}
125093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	spin_unlock(&GlobalMid_Lock);
126093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	return NULL;
127093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky}
128093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky
129093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskystatic void
130093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskysmb2_dump_detail(void *buf)
131093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky{
132093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky#ifdef CONFIG_CIFS_DEBUG2
133093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	struct smb2_hdr *smb = (struct smb2_hdr *)buf;
134093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky
135093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	cERROR(1, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d",
136093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		  smb->Command, smb->Status, smb->Flags, smb->MessageId,
137093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		  smb->ProcessId);
138093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	cERROR(1, "smb buf %p len %u", smb, smb2_calc_size(smb));
139093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky#endif
140093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky}
141093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky
142ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskystatic bool
143ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskysmb2_need_neg(struct TCP_Server_Info *server)
144ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky{
145ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	return server->max_read == 0;
146ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky}
147ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky
148ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskystatic int
149ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskysmb2_negotiate(const unsigned int xid, struct cifs_ses *ses)
150ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky{
151ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	int rc;
152ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	ses->server->CurrentMid = 0;
153ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	rc = SMB2_negotiate(xid, ses);
154ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	/* BB we probably don't need to retry with modern servers */
155ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	if (rc == -EAGAIN)
156ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky		rc = -EHOSTDOWN;
157ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	return rc;
158ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky}
159ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky
1602503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovskystatic int
1612503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovskysmb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
1622503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky			struct cifs_sb_info *cifs_sb, const char *full_path)
1632503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky{
1642503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	int rc;
1652503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	__u64 persistent_fid, volatile_fid;
1662503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	__le16 *utf16_path;
1672503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky
1682503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
1692503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	if (!utf16_path)
1702503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky		return -ENOMEM;
1712503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky
1722503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
1732503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky		       FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0);
1742503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	if (rc) {
1752503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky		kfree(utf16_path);
1762503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky		return rc;
1772503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	}
1782503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky
1792503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	rc = SMB2_close(xid, tcon, persistent_fid, volatile_fid);
1802503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	kfree(utf16_path);
1812503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	return rc;
1822503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky}
1832503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky
184be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovskystatic int
185be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovskysmb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
186be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky		  struct cifs_sb_info *cifs_sb, const char *full_path,
187be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky		  u64 *uniqueid, FILE_ALL_INFO *data)
188be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky{
189be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky	*uniqueid = le64_to_cpu(data->IndexNumber);
190be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky	return 0;
191be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky}
192be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky
19325e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovskystatic char *
19425e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovskysmb2_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
19525e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky			struct cifs_tcon *tcon)
19625e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky{
19725e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	int pplen = vol->prepath ? strlen(vol->prepath) : 0;
19825e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	char *full_path = NULL;
19925e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky
20025e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	/* if no prefix path, simply set path to the root of share to "" */
20125e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	if (pplen == 0) {
20225e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky		full_path = kzalloc(2, GFP_KERNEL);
20325e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky		return full_path;
20425e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	}
20525e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky
20625e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	cERROR(1, "prefixpath is not supported for SMB2 now");
20725e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	return NULL;
20825e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky}
20925e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky
2109094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovskystatic bool
2119094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovskysmb2_can_echo(struct TCP_Server_Info *server)
2129094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky{
2139094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky	return server->echoes;
2149094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky}
2159094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky
216d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskystatic void
217d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskysmb2_clear_stats(struct cifs_tcon *tcon)
218d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky{
219d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#ifdef CONFIG_CIFS_STATS
220d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	int i;
221d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
222d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0);
223d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0);
224d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	}
225d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#endif
226d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky}
227d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky
228d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskystatic void
229d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskysmb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
230d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky{
231d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#ifdef CONFIG_CIFS_STATS
232d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	atomic_t *sent = tcon->stats.smb2_stats.smb2_com_sent;
233d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	atomic_t *failed = tcon->stats.smb2_stats.smb2_com_failed;
234d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nNegotiates: %d sent %d failed",
235d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_NEGOTIATE_HE]),
236d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_NEGOTIATE_HE]));
237d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nSessionSetups: %d sent %d failed",
238d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_SESSION_SETUP_HE]),
239d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_SESSION_SETUP_HE]));
240d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#define SMB2LOGOFF		0x0002 /* trivial request/resp */
241d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nLogoffs: %d sent %d failed",
242d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_LOGOFF_HE]),
243d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_LOGOFF_HE]));
244d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nTreeConnects: %d sent %d failed",
245d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_TREE_CONNECT_HE]),
246d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_TREE_CONNECT_HE]));
247d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nTreeDisconnects: %d sent %d failed",
248d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_TREE_DISCONNECT_HE]),
249d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_TREE_DISCONNECT_HE]));
250d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nCreates: %d sent %d failed",
251d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_CREATE_HE]),
252d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_CREATE_HE]));
253d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nCloses: %d sent %d failed",
254d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_CLOSE_HE]),
255d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_CLOSE_HE]));
256d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nFlushes: %d sent %d failed",
257d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_FLUSH_HE]),
258d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_FLUSH_HE]));
259d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nReads: %d sent %d failed",
260d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_READ_HE]),
261d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_READ_HE]));
262d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nWrites: %d sent %d failed",
263d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_WRITE_HE]),
264d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_WRITE_HE]));
265d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nLocks: %d sent %d failed",
266d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_LOCK_HE]),
267d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_LOCK_HE]));
268d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nIOCTLs: %d sent %d failed",
269d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_IOCTL_HE]),
270d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_IOCTL_HE]));
271d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nCancels: %d sent %d failed",
272d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_CANCEL_HE]),
273d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_CANCEL_HE]));
274d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nEchos: %d sent %d failed",
275d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_ECHO_HE]),
276d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_ECHO_HE]));
277d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nQueryDirectories: %d sent %d failed",
278d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_QUERY_DIRECTORY_HE]),
279d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_QUERY_DIRECTORY_HE]));
280d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nChangeNotifies: %d sent %d failed",
281d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_CHANGE_NOTIFY_HE]),
282d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_CHANGE_NOTIFY_HE]));
283d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nQueryInfos: %d sent %d failed",
284d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_QUERY_INFO_HE]),
285d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_QUERY_INFO_HE]));
286d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nSetInfos: %d sent %d failed",
287d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_SET_INFO_HE]),
288d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_SET_INFO_HE]));
289d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nOplockBreaks: %d sent %d failed",
290d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_OPLOCK_BREAK_HE]),
291d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_OPLOCK_BREAK_HE]));
292d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#endif
293d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky}
294d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky
2951080ef758fb87f286b25277d8373e680a9e73363Steve Frenchstruct smb_version_operations smb21_operations = {
2962dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	.setup_request = smb2_setup_request,
297c95b8eeda3efcb419ea0a3f864cf99e32c038c21Pavel Shilovsky	.setup_async_request = smb2_setup_async_request,
2982dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	.check_receive = smb2_check_receive,
29928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	.add_credits = smb2_add_credits,
30028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	.set_credits = smb2_set_credits,
30128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	.get_credits_field = smb2_get_credits_field,
30228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	.get_credits = smb2_get_credits,
3032dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	.get_next_mid = smb2_get_next_mid,
304093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.find_mid = smb2_find_mid,
305093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.check_message = smb2_check_message,
306093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.dump_detail = smb2_dump_detail,
307d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	.clear_stats = smb2_clear_stats,
308d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	.print_stats = smb2_print_stats,
309ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	.need_neg = smb2_need_neg,
310ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	.negotiate = smb2_negotiate,
3115478f9ba9a34d660eb3227dcd16314689c51f946Pavel Shilovsky	.sess_setup = SMB2_sess_setup,
3125478f9ba9a34d660eb3227dcd16314689c51f946Pavel Shilovsky	.logoff = SMB2_logoff,
313faaf946a7d5b79194358437150f34ab4c66bfe21Pavel Shilovsky	.tree_connect = SMB2_tcon,
314faaf946a7d5b79194358437150f34ab4c66bfe21Pavel Shilovsky	.tree_disconnect = SMB2_tdis,
3152503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	.is_path_accessible = smb2_is_path_accessible,
3169094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky	.can_echo = smb2_can_echo,
3179094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky	.echo = SMB2_echo,
318be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky	.query_path_info = smb2_query_path_info,
319be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky	.get_srv_inum = smb2_get_srv_inum,
32025e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	.build_path_to_root = smb2_build_path_to_root,
321a0e731839dd461eee0fe2dc026e0965e961e2730Pavel Shilovsky	.mkdir = smb2_mkdir,
322a0e731839dd461eee0fe2dc026e0965e961e2730Pavel Shilovsky	.mkdir_setinfo = smb2_mkdir_setinfo,
3231a500f010fb2d121c58f77ddfde2eca1bde3bfcdPavel Shilovsky	.rmdir = smb2_rmdir,
3241080ef758fb87f286b25277d8373e680a9e73363Steve French};
3251080ef758fb87f286b25277d8373e680a9e73363Steve French
3261080ef758fb87f286b25277d8373e680a9e73363Steve Frenchstruct smb_version_values smb21_values = {
3271080ef758fb87f286b25277d8373e680a9e73363Steve French	.version_string = SMB21_VERSION_STRING,
328093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.header_size = sizeof(struct smb2_hdr),
329093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.max_header_size = MAX_SMB2_HDR_SIZE,
3302dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	.lock_cmd = SMB2_LOCK,
33129e20f9c65fae245d6fd4fce31cc5d01cde3d93fPavel Shilovsky	.cap_unix = 0,
33229e20f9c65fae245d6fd4fce31cc5d01cde3d93fPavel Shilovsky	.cap_nt_find = SMB2_NT_FIND,
33329e20f9c65fae245d6fd4fce31cc5d01cde3d93fPavel Shilovsky	.cap_large_files = SMB2_LARGE_FILES,
3341080ef758fb87f286b25277d8373e680a9e73363Steve French};
335