smb2ops.c revision 027e8eec31d8141a6231f772e10ccae60c9d5c13
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
203a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky#include <linux/pagemap.h>
216fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky#include <linux/vfs.h>
221080ef758fb87f286b25277d8373e680a9e73363Steve French#include "cifsglob.h"
232dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky#include "smb2pdu.h"
242dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky#include "smb2proto.h"
2528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky#include "cifsproto.h"
2628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky#include "cifs_debug.h"
272e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky#include "smb2status.h"
286fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky#include "smb2glob.h"
2928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
3028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic int
3128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskychange_conf(struct TCP_Server_Info *server)
3228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
3328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->credits += server->echo_credits + server->oplock_credits;
3428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->oplock_credits = server->echo_credits = 0;
3528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	switch (server->credits) {
3628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case 0:
3728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		return -1;
3828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case 1:
3928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echoes = false;
4028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->oplocks = false;
4128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		cERROR(1, "disabling echoes and oplocks");
4228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		break;
4328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case 2:
4428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echoes = true;
4528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->oplocks = false;
4628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echo_credits = 1;
4728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		cFYI(1, "disabling oplocks");
4828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		break;
4928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	default:
5028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echoes = true;
5128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->oplocks = true;
5228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echo_credits = 1;
5328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->oplock_credits = 1;
5428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	}
5528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->credits -= server->echo_credits + server->oplock_credits;
5628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	return 0;
5728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
5828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
5928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic void
6028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
6128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		 const int optype)
6228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
6328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	int *val, rc = 0;
6428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	spin_lock(&server->req_lock);
6528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	val = server->ops->get_credits_field(server, optype);
6628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	*val += add;
6728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->in_flight--;
68ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP)
6928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		rc = change_conf(server);
70983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	/*
71983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	 * Sometimes server returns 0 credits on oplock break ack - we need to
72983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	 * rebalance credits in this case.
73983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	 */
74983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	else if (server->in_flight > 0 && server->oplock_credits == 0 &&
75983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky		 server->oplocks) {
76983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky		if (server->credits > 1) {
77983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky			server->credits--;
78983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky			server->oplock_credits++;
79983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky		}
80983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	}
8128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	spin_unlock(&server->req_lock);
8228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	wake_up(&server->request_q);
8328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	if (rc)
8428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		cifs_reconnect(server);
8528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
8628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
8728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic void
8828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_set_credits(struct TCP_Server_Info *server, const int val)
8928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
9028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	spin_lock(&server->req_lock);
9128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->credits = val;
9228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	spin_unlock(&server->req_lock);
9328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
9428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
9528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic int *
9628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_get_credits_field(struct TCP_Server_Info *server, const int optype)
9728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
9828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	switch (optype) {
9928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case CIFS_ECHO_OP:
10028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		return &server->echo_credits;
10128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case CIFS_OBREAK_OP:
10228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		return &server->oplock_credits;
10328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	default:
10428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		return &server->credits;
10528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	}
10628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
10728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
10828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic unsigned int
10928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_get_credits(struct mid_q_entry *mid)
11028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
11128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	return le16_to_cpu(((struct smb2_hdr *)mid->resp_buf)->CreditRequest);
11228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
1132dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky
1142dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovskystatic __u64
1152dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovskysmb2_get_next_mid(struct TCP_Server_Info *server)
1162dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky{
1172dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	__u64 mid;
1182dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	/* for SMB2 we need the current value */
1192dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	spin_lock(&GlobalMid_Lock);
1202dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	mid = server->CurrentMid++;
1212dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	spin_unlock(&GlobalMid_Lock);
1222dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	return mid;
1232dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky}
1241080ef758fb87f286b25277d8373e680a9e73363Steve French
125093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskystatic struct mid_q_entry *
126093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskysmb2_find_mid(struct TCP_Server_Info *server, char *buf)
127093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky{
128093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	struct mid_q_entry *mid;
129093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
130093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky
131093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	spin_lock(&GlobalMid_Lock);
132093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	list_for_each_entry(mid, &server->pending_mid_q, qhead) {
133093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		if ((mid->mid == hdr->MessageId) &&
134093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		    (mid->mid_state == MID_REQUEST_SUBMITTED) &&
135093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		    (mid->command == hdr->Command)) {
136093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky			spin_unlock(&GlobalMid_Lock);
137093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky			return mid;
138093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		}
139093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	}
140093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	spin_unlock(&GlobalMid_Lock);
141093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	return NULL;
142093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky}
143093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky
144093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskystatic void
145093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskysmb2_dump_detail(void *buf)
146093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky{
147093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky#ifdef CONFIG_CIFS_DEBUG2
148093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	struct smb2_hdr *smb = (struct smb2_hdr *)buf;
149093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky
150093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	cERROR(1, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d",
151093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		  smb->Command, smb->Status, smb->Flags, smb->MessageId,
152093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		  smb->ProcessId);
153093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	cERROR(1, "smb buf %p len %u", smb, smb2_calc_size(smb));
154093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky#endif
155093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky}
156093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky
157ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskystatic bool
158ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskysmb2_need_neg(struct TCP_Server_Info *server)
159ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky{
160ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	return server->max_read == 0;
161ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky}
162ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky
163ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskystatic int
164ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskysmb2_negotiate(const unsigned int xid, struct cifs_ses *ses)
165ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky{
166ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	int rc;
167ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	ses->server->CurrentMid = 0;
168ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	rc = SMB2_negotiate(xid, ses);
169ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	/* BB we probably don't need to retry with modern servers */
170ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	if (rc == -EAGAIN)
171ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky		rc = -EHOSTDOWN;
172ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	return rc;
173ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky}
174ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky
1753a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovskystatic unsigned int
1763a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovskysmb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
1773a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky{
1783a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	struct TCP_Server_Info *server = tcon->ses->server;
1793a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	unsigned int wsize;
1803a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky
1813a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	/* start with specified wsize, or default */
1823a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE;
1833a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	wsize = min_t(unsigned int, wsize, server->max_write);
1843a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	/*
1853a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	 * limit write size to 2 ** 16, because we don't support multicredit
1863a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	 * requests now.
1873a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	 */
1883a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	wsize = min_t(unsigned int, wsize, 2 << 15);
1893a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky
1903a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	return wsize;
1913a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky}
1923a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky
1933a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovskystatic unsigned int
1943a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovskysmb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
1953a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky{
1963a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	struct TCP_Server_Info *server = tcon->ses->server;
1973a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	unsigned int rsize;
1983a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky
1993a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	/* start with specified rsize, or default */
2003a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE;
2013a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	rsize = min_t(unsigned int, rsize, server->max_read);
2023a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	/*
2033a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	 * limit write size to 2 ** 16, because we don't support multicredit
2043a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	 * requests now.
2053a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	 */
2063a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	rsize = min_t(unsigned int, rsize, 2 << 15);
2073a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky
2083a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	return rsize;
2093a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky}
2103a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky
2112503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovskystatic int
2122503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovskysmb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
2132503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky			struct cifs_sb_info *cifs_sb, const char *full_path)
2142503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky{
2152503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	int rc;
2162503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	__u64 persistent_fid, volatile_fid;
2172503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	__le16 *utf16_path;
2182e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
2192503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky
2202503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
2212503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	if (!utf16_path)
2222503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky		return -ENOMEM;
2232503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky
2242503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
2252e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky		       FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0, &oplock, NULL);
2262503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	if (rc) {
2272503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky		kfree(utf16_path);
2282503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky		return rc;
2292503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	}
2302503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky
2312503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	rc = SMB2_close(xid, tcon, persistent_fid, volatile_fid);
2322503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	kfree(utf16_path);
2332503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	return rc;
2342503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky}
2352503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky
236be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovskystatic int
237be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovskysmb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
238be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky		  struct cifs_sb_info *cifs_sb, const char *full_path,
239be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky		  u64 *uniqueid, FILE_ALL_INFO *data)
240be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky{
241be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky	*uniqueid = le64_to_cpu(data->IndexNumber);
242be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky	return 0;
243be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky}
244be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky
245b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovskystatic int
246b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovskysmb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
247b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky		     struct cifs_fid *fid, FILE_ALL_INFO *data)
248b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky{
249b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	int rc;
250b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	struct smb2_file_all_info *smb2_data;
251b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky
252b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + MAX_NAME * 2,
253b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky			    GFP_KERNEL);
254b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	if (smb2_data == NULL)
255b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky		return -ENOMEM;
256b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky
257b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	rc = SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid,
258b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky			     smb2_data);
259b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	if (!rc)
260b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky		move_smb2_info_to_cifs(data, smb2_data);
261b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	kfree(smb2_data);
262b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	return rc;
263b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky}
264b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky
26525e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovskystatic char *
26625e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovskysmb2_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
26725e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky			struct cifs_tcon *tcon)
26825e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky{
26925e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	int pplen = vol->prepath ? strlen(vol->prepath) : 0;
27025e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	char *full_path = NULL;
27125e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky
27225e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	/* if no prefix path, simply set path to the root of share to "" */
27325e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	if (pplen == 0) {
27425e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky		full_path = kzalloc(2, GFP_KERNEL);
27525e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky		return full_path;
27625e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	}
27725e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky
27825e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	cERROR(1, "prefixpath is not supported for SMB2 now");
27925e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	return NULL;
28025e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky}
28125e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky
2829094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovskystatic bool
2839094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovskysmb2_can_echo(struct TCP_Server_Info *server)
2849094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky{
2859094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky	return server->echoes;
2869094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky}
2879094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky
288d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskystatic void
289d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskysmb2_clear_stats(struct cifs_tcon *tcon)
290d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky{
291d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#ifdef CONFIG_CIFS_STATS
292d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	int i;
293d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
294d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0);
295d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0);
296d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	}
297d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#endif
298d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky}
299d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky
300d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskystatic void
301d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskysmb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
302d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky{
303d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#ifdef CONFIG_CIFS_STATS
304d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	atomic_t *sent = tcon->stats.smb2_stats.smb2_com_sent;
305d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	atomic_t *failed = tcon->stats.smb2_stats.smb2_com_failed;
306d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nNegotiates: %d sent %d failed",
307d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_NEGOTIATE_HE]),
308d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_NEGOTIATE_HE]));
309d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nSessionSetups: %d sent %d failed",
310d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_SESSION_SETUP_HE]),
311d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_SESSION_SETUP_HE]));
312d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#define SMB2LOGOFF		0x0002 /* trivial request/resp */
313d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nLogoffs: %d sent %d failed",
314d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_LOGOFF_HE]),
315d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_LOGOFF_HE]));
316d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nTreeConnects: %d sent %d failed",
317d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_TREE_CONNECT_HE]),
318d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_TREE_CONNECT_HE]));
319d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nTreeDisconnects: %d sent %d failed",
320d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_TREE_DISCONNECT_HE]),
321d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_TREE_DISCONNECT_HE]));
322d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nCreates: %d sent %d failed",
323d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_CREATE_HE]),
324d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_CREATE_HE]));
325d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nCloses: %d sent %d failed",
326d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_CLOSE_HE]),
327d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_CLOSE_HE]));
328d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nFlushes: %d sent %d failed",
329d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_FLUSH_HE]),
330d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_FLUSH_HE]));
331d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nReads: %d sent %d failed",
332d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_READ_HE]),
333d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_READ_HE]));
334d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nWrites: %d sent %d failed",
335d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_WRITE_HE]),
336d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_WRITE_HE]));
337d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nLocks: %d sent %d failed",
338d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_LOCK_HE]),
339d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_LOCK_HE]));
340d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nIOCTLs: %d sent %d failed",
341d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_IOCTL_HE]),
342d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_IOCTL_HE]));
343d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nCancels: %d sent %d failed",
344d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_CANCEL_HE]),
345d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_CANCEL_HE]));
346d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nEchos: %d sent %d failed",
347d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_ECHO_HE]),
348d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_ECHO_HE]));
349d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nQueryDirectories: %d sent %d failed",
350d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_QUERY_DIRECTORY_HE]),
351d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_QUERY_DIRECTORY_HE]));
352d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nChangeNotifies: %d sent %d failed",
353d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_CHANGE_NOTIFY_HE]),
354d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_CHANGE_NOTIFY_HE]));
355d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nQueryInfos: %d sent %d failed",
356d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_QUERY_INFO_HE]),
357d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_QUERY_INFO_HE]));
358d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nSetInfos: %d sent %d failed",
359d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_SET_INFO_HE]),
360d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_SET_INFO_HE]));
361d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nOplockBreaks: %d sent %d failed",
362d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_OPLOCK_BREAK_HE]),
363d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_OPLOCK_BREAK_HE]));
364d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#endif
365d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky}
366d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky
367f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovskystatic void
368f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovskysmb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
369f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky{
3702e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
371f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky	cfile->fid.persistent_fid = fid->persistent_fid;
372f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky	cfile->fid.volatile_fid = fid->volatile_fid;
3732e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	smb2_set_oplock_level(cinode, oplock);
374f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky	/* cinode->can_cache_brlcks = cinode->clientCanCacheAll; */
375f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky}
376f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky
377f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovskystatic int
378f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovskysmb2_close_file(const unsigned int xid, struct cifs_tcon *tcon,
379f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky		struct cifs_fid *fid)
380f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky{
381f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky	return SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
382f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky}
383f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky
3847a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovskystatic int
3857a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovskysmb2_flush_file(const unsigned int xid, struct cifs_tcon *tcon,
3867a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky		struct cifs_fid *fid)
3877a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky{
3887a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky	return SMB2_flush(xid, tcon, fid->persistent_fid, fid->volatile_fid);
3897a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky}
3907a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky
39109a4707e7638247302c6d798061aed117141fb74Pavel Shilovskystatic unsigned int
39209a4707e7638247302c6d798061aed117141fb74Pavel Shilovskysmb2_read_data_offset(char *buf)
39309a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky{
39409a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
39509a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	return rsp->DataOffset;
39609a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky}
39709a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky
39809a4707e7638247302c6d798061aed117141fb74Pavel Shilovskystatic unsigned int
39909a4707e7638247302c6d798061aed117141fb74Pavel Shilovskysmb2_read_data_length(char *buf)
40009a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky{
40109a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
40209a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	return le32_to_cpu(rsp->DataLength);
40309a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky}
40409a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky
405d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky
406d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovskystatic int
407d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovskysmb2_sync_read(const unsigned int xid, struct cifsFileInfo *cfile,
408d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky	       struct cifs_io_parms *parms, unsigned int *bytes_read,
409d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky	       char **buf, int *buf_type)
410d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky{
411d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky	parms->persistent_fid = cfile->fid.persistent_fid;
412d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky	parms->volatile_fid = cfile->fid.volatile_fid;
413d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky	return SMB2_read(xid, parms, bytes_read, buf, buf_type);
414d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky}
415d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky
416009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovskystatic int
417009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovskysmb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile,
418009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky		struct cifs_io_parms *parms, unsigned int *written,
419009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky		struct kvec *iov, unsigned long nr_segs)
420009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky{
421009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky
422009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky	parms->persistent_fid = cfile->fid.persistent_fid;
423009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky	parms->volatile_fid = cfile->fid.volatile_fid;
424009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky	return SMB2_write(xid, parms, written, iov, nr_segs);
425009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky}
426009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky
427c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovskystatic int
428c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovskysmb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
429c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky		   struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
430c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky{
431c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky	__le64 eof = cpu_to_le64(size);
432c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky	return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
433c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky			    cfile->fid.volatile_fid, cfile->pid, &eof);
434c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky}
435c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky
436d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskystatic int
437d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskysmb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
438d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		     const char *path, struct cifs_sb_info *cifs_sb,
439d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		     struct cifs_fid *fid, __u16 search_flags,
440d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		     struct cifs_search_info *srch_inf)
441d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky{
442d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	__le16 *utf16_path;
443d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	int rc;
4442e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
445d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	__u64 persistent_fid, volatile_fid;
446d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
447d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
448d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	if (!utf16_path)
449d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		return -ENOMEM;
450d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
451d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid,
452d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		       FILE_READ_ATTRIBUTES | FILE_READ_DATA, FILE_OPEN, 0, 0,
4532e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky		       &oplock, NULL);
454d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	kfree(utf16_path);
455d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	if (rc) {
456d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		cERROR(1, "open dir failed");
457d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		return rc;
458d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	}
459d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
460d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	srch_inf->entries_in_buffer = 0;
461d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	srch_inf->index_of_last_entry = 0;
462d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	fid->persistent_fid = persistent_fid;
463d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	fid->volatile_fid = volatile_fid;
464d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
465d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	rc = SMB2_query_directory(xid, tcon, persistent_fid, volatile_fid, 0,
466d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky				  srch_inf);
467d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	if (rc) {
468d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		cERROR(1, "query directory failed");
469d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		SMB2_close(xid, tcon, persistent_fid, volatile_fid);
470d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	}
471d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	return rc;
472d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky}
473d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
474d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskystatic int
475d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskysmb2_query_dir_next(const unsigned int xid, struct cifs_tcon *tcon,
476d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		    struct cifs_fid *fid, __u16 search_flags,
477d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		    struct cifs_search_info *srch_inf)
478d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky{
479d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	return SMB2_query_directory(xid, tcon, fid->persistent_fid,
480d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky				    fid->volatile_fid, 0, srch_inf);
481d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky}
482d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
483d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskystatic int
484d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskysmb2_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
485d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	       struct cifs_fid *fid)
486d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky{
487d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	return SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
488d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky}
489d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
4902e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky/*
4912e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky* If we negotiate SMB2 protocol and get STATUS_PENDING - update
4922e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky* the number of credits and return true. Otherwise - return false.
4932e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky*/
4942e44b2887882134abf353b28867b82645e9f0856Pavel Shilovskystatic bool
4952e44b2887882134abf353b28867b82645e9f0856Pavel Shilovskysmb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length)
4962e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky{
4972e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
4982e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky
4992e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	if (le32_to_cpu(hdr->Status) != STATUS_PENDING)
5002e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky		return false;
5012e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky
5022e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	if (!length) {
5032e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky		spin_lock(&server->req_lock);
5042e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky		server->credits += le16_to_cpu(hdr->CreditRequest);
5052e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky		spin_unlock(&server->req_lock);
5062e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky		wake_up(&server->request_q);
5072e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	}
5082e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky
5092e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	return true;
5102e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky}
5112e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky
512983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovskystatic int
513983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovskysmb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
514983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky		     struct cifsInodeInfo *cinode)
515983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky{
516983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	return SMB2_oplock_break(0, tcon, fid->persistent_fid,
517983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky				 fid->volatile_fid,
518983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky				 cinode->clientCanCacheRead ? 1 : 0);
519983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky}
520983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky
5216fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovskystatic int
5226fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovskysmb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
5236fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	     struct kstatfs *buf)
5246fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky{
5256fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	int rc;
5266fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	u64 persistent_fid, volatile_fid;
5276fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	__le16 srch_path = 0; /* Null - open root of share */
5286fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
5296fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky
5306fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	rc = SMB2_open(xid, tcon, &srch_path, &persistent_fid, &volatile_fid,
5316fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky		       FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0, &oplock, NULL);
5326fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	if (rc)
5336fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky		return rc;
5346fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	buf->f_type = SMB2_MAGIC_NUMBER;
5356fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	rc = SMB2_QFS_info(xid, tcon, persistent_fid, volatile_fid, buf);
5366fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	SMB2_close(xid, tcon, persistent_fid, volatile_fid);
5376fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	return rc;
5386fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky}
5396fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky
540027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovskystatic bool
541027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovskysmb2_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
542027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky{
543027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	return ob1->fid.persistent_fid == ob2->fid.persistent_fid &&
544027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	       ob1->fid.volatile_fid == ob2->fid.volatile_fid;
545027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky}
546027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky
5471080ef758fb87f286b25277d8373e680a9e73363Steve Frenchstruct smb_version_operations smb21_operations = {
548027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	.compare_fids = smb2_compare_fids,
5492dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	.setup_request = smb2_setup_request,
550c95b8eeda3efcb419ea0a3f864cf99e32c038c21Pavel Shilovsky	.setup_async_request = smb2_setup_async_request,
5512dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	.check_receive = smb2_check_receive,
55228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	.add_credits = smb2_add_credits,
55328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	.set_credits = smb2_set_credits,
55428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	.get_credits_field = smb2_get_credits_field,
55528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	.get_credits = smb2_get_credits,
5562dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	.get_next_mid = smb2_get_next_mid,
55709a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	.read_data_offset = smb2_read_data_offset,
55809a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	.read_data_length = smb2_read_data_length,
55909a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	.map_error = map_smb2_to_linux_error,
560093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.find_mid = smb2_find_mid,
561093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.check_message = smb2_check_message,
562093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.dump_detail = smb2_dump_detail,
563d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	.clear_stats = smb2_clear_stats,
564d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	.print_stats = smb2_print_stats,
565983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	.is_oplock_break = smb2_is_valid_oplock_break,
566ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	.need_neg = smb2_need_neg,
567ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	.negotiate = smb2_negotiate,
5683a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	.negotiate_wsize = smb2_negotiate_wsize,
5693a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	.negotiate_rsize = smb2_negotiate_rsize,
5705478f9ba9a34d660eb3227dcd16314689c51f946Pavel Shilovsky	.sess_setup = SMB2_sess_setup,
5715478f9ba9a34d660eb3227dcd16314689c51f946Pavel Shilovsky	.logoff = SMB2_logoff,
572faaf946a7d5b79194358437150f34ab4c66bfe21Pavel Shilovsky	.tree_connect = SMB2_tcon,
573faaf946a7d5b79194358437150f34ab4c66bfe21Pavel Shilovsky	.tree_disconnect = SMB2_tdis,
5742503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	.is_path_accessible = smb2_is_path_accessible,
5759094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky	.can_echo = smb2_can_echo,
5769094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky	.echo = SMB2_echo,
577be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky	.query_path_info = smb2_query_path_info,
578be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky	.get_srv_inum = smb2_get_srv_inum,
579b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	.query_file_info = smb2_query_file_info,
580c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky	.set_path_size = smb2_set_path_size,
581c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky	.set_file_size = smb2_set_file_size,
5821feeaac753e0a9b3864740556b7840643642abdbPavel Shilovsky	.set_file_info = smb2_set_file_info,
58325e266320caca88a4463385b6f4ef696111d2c9aPavel Shilovsky	.build_path_to_root = smb2_build_path_to_root,
584a0e731839dd461eee0fe2dc026e0965e961e2730Pavel Shilovsky	.mkdir = smb2_mkdir,
585a0e731839dd461eee0fe2dc026e0965e961e2730Pavel Shilovsky	.mkdir_setinfo = smb2_mkdir_setinfo,
5861a500f010fb2d121c58f77ddfde2eca1bde3bfcdPavel Shilovsky	.rmdir = smb2_rmdir,
587cbe6f439f5762c7fb4d2dd9293f5fdbfc4cd68f8Pavel Shilovsky	.unlink = smb2_unlink,
58835143eb5c2e3ae6c91b29144449d23f05f573796Pavel Shilovsky	.rename = smb2_rename_path,
589568798cc6211553e2494a6876fa19d064c822e79Pavel Shilovsky	.create_hardlink = smb2_create_hardlink,
590f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky	.open = smb2_open_file,
591f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky	.set_fid = smb2_set_fid,
592f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky	.close = smb2_close_file,
5937a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky	.flush = smb2_flush_file,
59409a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	.async_readv = smb2_async_readv,
59533319141252fd14b58cf13685156c23dcaac2527Pavel Shilovsky	.async_writev = smb2_async_writev,
596d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky	.sync_read = smb2_sync_read,
597009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky	.sync_write = smb2_sync_write,
598d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	.query_dir_first = smb2_query_dir_first,
599d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	.query_dir_next = smb2_query_dir_next,
600d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	.close_dir = smb2_close_dir,
601d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	.calc_smb_size = smb2_calc_size,
6022e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	.is_status_pending = smb2_is_status_pending,
603983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	.oplock_response = smb2_oplock_response,
6046fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	.queryfs = smb2_queryfs,
6051080ef758fb87f286b25277d8373e680a9e73363Steve French};
6061080ef758fb87f286b25277d8373e680a9e73363Steve French
6071080ef758fb87f286b25277d8373e680a9e73363Steve Frenchstruct smb_version_values smb21_values = {
6081080ef758fb87f286b25277d8373e680a9e73363Steve French	.version_string = SMB21_VERSION_STRING,
609027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	.large_lock_type = 0,
610027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
611027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
612027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
613093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.header_size = sizeof(struct smb2_hdr),
614093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.max_header_size = MAX_SMB2_HDR_SIZE,
61509a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
6162dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	.lock_cmd = SMB2_LOCK,
61729e20f9c65fae245d6fd4fce31cc5d01cde3d93fPavel Shilovsky	.cap_unix = 0,
61829e20f9c65fae245d6fd4fce31cc5d01cde3d93fPavel Shilovsky	.cap_nt_find = SMB2_NT_FIND,
61929e20f9c65fae245d6fd4fce31cc5d01cde3d93fPavel Shilovsky	.cap_large_files = SMB2_LARGE_FILES,
6201080ef758fb87f286b25277d8373e680a9e73363Steve French};
621