smb2ops.c revision 42873b0a282ac84a56e0e48c408beb62d0ad2917
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"
27b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky#include "cifs_unicode.h"
282e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky#include "smb2status.h"
296fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky#include "smb2glob.h"
3028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
3128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic int
3228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskychange_conf(struct TCP_Server_Info *server)
3328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
3428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->credits += server->echo_credits + server->oplock_credits;
3528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->oplock_credits = server->echo_credits = 0;
3628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	switch (server->credits) {
3728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case 0:
3828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		return -1;
3928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case 1:
4028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echoes = false;
4128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->oplocks = false;
42f96637be081141d6f8813429499f164260b49d70Joe Perches		cifs_dbg(VFS, "disabling echoes and oplocks\n");
4328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		break;
4428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case 2:
4528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echoes = true;
4628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->oplocks = false;
4728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echo_credits = 1;
48f96637be081141d6f8813429499f164260b49d70Joe Perches		cifs_dbg(FYI, "disabling oplocks\n");
4928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		break;
5028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	default:
5128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echoes = true;
5228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->oplocks = true;
5328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->echo_credits = 1;
5428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		server->oplock_credits = 1;
5528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	}
5628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->credits -= server->echo_credits + server->oplock_credits;
5728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	return 0;
5828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
5928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
6028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic void
6128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
6228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		 const int optype)
6328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
6428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	int *val, rc = 0;
6528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	spin_lock(&server->req_lock);
6628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	val = server->ops->get_credits_field(server, optype);
6728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	*val += add;
6828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->in_flight--;
69ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP)
7028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		rc = change_conf(server);
71983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	/*
72983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	 * Sometimes server returns 0 credits on oplock break ack - we need to
73983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	 * rebalance credits in this case.
74983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	 */
75983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	else if (server->in_flight > 0 && server->oplock_credits == 0 &&
76983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky		 server->oplocks) {
77983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky		if (server->credits > 1) {
78983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky			server->credits--;
79983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky			server->oplock_credits++;
80983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky		}
81983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	}
8228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	spin_unlock(&server->req_lock);
8328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	wake_up(&server->request_q);
8428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	if (rc)
8528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		cifs_reconnect(server);
8628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
8728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
8828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic void
8928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_set_credits(struct TCP_Server_Info *server, const int val)
9028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
9128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	spin_lock(&server->req_lock);
9228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	server->credits = val;
9328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	spin_unlock(&server->req_lock);
9428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
9528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
9628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic int *
9728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_get_credits_field(struct TCP_Server_Info *server, const int optype)
9828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
9928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	switch (optype) {
10028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case CIFS_ECHO_OP:
10128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		return &server->echo_credits;
10228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	case CIFS_OBREAK_OP:
10328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		return &server->oplock_credits;
10428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	default:
10528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky		return &server->credits;
10628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	}
10728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
10828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky
10928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic unsigned int
11028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_get_credits(struct mid_q_entry *mid)
11128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{
11228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	return le16_to_cpu(((struct smb2_hdr *)mid->resp_buf)->CreditRequest);
11328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky}
1142dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky
1152dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovskystatic __u64
1162dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovskysmb2_get_next_mid(struct TCP_Server_Info *server)
1172dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky{
1182dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	__u64 mid;
1192dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	/* for SMB2 we need the current value */
1202dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	spin_lock(&GlobalMid_Lock);
1212dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	mid = server->CurrentMid++;
1222dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	spin_unlock(&GlobalMid_Lock);
1232dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	return mid;
1242dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky}
1251080ef758fb87f286b25277d8373e680a9e73363Steve French
126093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskystatic struct mid_q_entry *
127093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskysmb2_find_mid(struct TCP_Server_Info *server, char *buf)
128093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky{
129093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	struct mid_q_entry *mid;
130093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
131093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky
132093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	spin_lock(&GlobalMid_Lock);
133093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	list_for_each_entry(mid, &server->pending_mid_q, qhead) {
134093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		if ((mid->mid == hdr->MessageId) &&
135093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		    (mid->mid_state == MID_REQUEST_SUBMITTED) &&
136093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		    (mid->command == hdr->Command)) {
137093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky			spin_unlock(&GlobalMid_Lock);
138093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky			return mid;
139093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky		}
140093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	}
141093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	spin_unlock(&GlobalMid_Lock);
142093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	return NULL;
143093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky}
144093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky
145093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskystatic void
146093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskysmb2_dump_detail(void *buf)
147093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky{
148093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky#ifdef CONFIG_CIFS_DEBUG2
149093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	struct smb2_hdr *smb = (struct smb2_hdr *)buf;
150093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky
151f96637be081141d6f8813429499f164260b49d70Joe Perches	cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n",
152f96637be081141d6f8813429499f164260b49d70Joe Perches		 smb->Command, smb->Status, smb->Flags, smb->MessageId,
153f96637be081141d6f8813429499f164260b49d70Joe Perches		 smb->ProcessId);
154f96637be081141d6f8813429499f164260b49d70Joe Perches	cifs_dbg(VFS, "smb buf %p len %u\n", smb, smb2_calc_size(smb));
155093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky#endif
156093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky}
157093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky
158ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskystatic bool
159ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskysmb2_need_neg(struct TCP_Server_Info *server)
160ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky{
161ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	return server->max_read == 0;
162ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky}
163ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky
164ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskystatic int
165ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskysmb2_negotiate(const unsigned int xid, struct cifs_ses *ses)
166ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky{
167ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	int rc;
168ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	ses->server->CurrentMid = 0;
169ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	rc = SMB2_negotiate(xid, ses);
170ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	/* BB we probably don't need to retry with modern servers */
171ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	if (rc == -EAGAIN)
172ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky		rc = -EHOSTDOWN;
173ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	return rc;
174ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky}
175ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky
1763a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovskystatic unsigned int
1773a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovskysmb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
1783a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky{
1793a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	struct TCP_Server_Info *server = tcon->ses->server;
1803a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	unsigned int wsize;
1813a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky
1823a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	/* start with specified wsize, or default */
1833a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE;
1843a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	wsize = min_t(unsigned int, wsize, server->max_write);
1853a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	/*
1863a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	 * limit write size to 2 ** 16, because we don't support multicredit
1873a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	 * requests now.
1883a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	 */
1893a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	wsize = min_t(unsigned int, wsize, 2 << 15);
1903a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky
1913a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	return wsize;
1923a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky}
1933a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky
1943a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovskystatic unsigned int
1953a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovskysmb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
1963a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky{
1973a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	struct TCP_Server_Info *server = tcon->ses->server;
1983a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	unsigned int rsize;
1993a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky
2003a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	/* start with specified rsize, or default */
2013a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE;
2023a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	rsize = min_t(unsigned int, rsize, server->max_read);
2033a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	/*
2043a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	 * limit write size to 2 ** 16, because we don't support multicredit
2053a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	 * requests now.
2063a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	 */
2073a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	rsize = min_t(unsigned int, rsize, 2 << 15);
2083a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky
2093a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	return rsize;
2103a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky}
2113a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky
2122503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovskystatic int
2132503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovskysmb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
2142503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky			struct cifs_sb_info *cifs_sb, const char *full_path)
2152503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky{
2162503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	int rc;
2172503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	__le16 *utf16_path;
2182e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
219064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	struct cifs_open_parms oparms;
220064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	struct cifs_fid fid;
2212503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky
2222503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
2232503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	if (!utf16_path)
2242503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky		return -ENOMEM;
2252503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky
226064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.tcon = tcon;
227064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.desired_access = FILE_READ_ATTRIBUTES;
228064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.disposition = FILE_OPEN;
229064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.create_options = 0;
230064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.fid = &fid;
2319cbc0b7339b0542a1d13922d2745a2636ce44853Pavel Shilovsky	oparms.reconnect = false;
232064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky
233b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
2342503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	if (rc) {
2352503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky		kfree(utf16_path);
2362503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky		return rc;
2372503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	}
2382503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky
239064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
2402503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	kfree(utf16_path);
2412503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	return rc;
2422503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky}
2432503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky
244be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovskystatic int
245be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovskysmb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
246be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky		  struct cifs_sb_info *cifs_sb, const char *full_path,
247be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky		  u64 *uniqueid, FILE_ALL_INFO *data)
248be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky{
249be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky	*uniqueid = le64_to_cpu(data->IndexNumber);
250be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky	return 0;
251be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky}
252be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky
253b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovskystatic int
254b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovskysmb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
255b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky		     struct cifs_fid *fid, FILE_ALL_INFO *data)
256b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky{
257b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	int rc;
258b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	struct smb2_file_all_info *smb2_data;
259b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky
260b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + MAX_NAME * 2,
261b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky			    GFP_KERNEL);
262b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	if (smb2_data == NULL)
263b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky		return -ENOMEM;
264b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky
265b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	rc = SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid,
266b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky			     smb2_data);
267b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	if (!rc)
268b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky		move_smb2_info_to_cifs(data, smb2_data);
269b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	kfree(smb2_data);
270b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	return rc;
271b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky}
272b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky
2739094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovskystatic bool
2749094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovskysmb2_can_echo(struct TCP_Server_Info *server)
2759094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky{
2769094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky	return server->echoes;
2779094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky}
2789094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky
279d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskystatic void
280d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskysmb2_clear_stats(struct cifs_tcon *tcon)
281d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky{
282d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#ifdef CONFIG_CIFS_STATS
283d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	int i;
284d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
285d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0);
286d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0);
287d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	}
288d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#endif
289d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky}
290d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky
291d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskystatic void
292769ee6a4024434d1960acafd7adde38538bbe3daSteve Frenchsmb2_dump_share_caps(struct seq_file *m, struct cifs_tcon *tcon)
293769ee6a4024434d1960acafd7adde38538bbe3daSteve French{
294769ee6a4024434d1960acafd7adde38538bbe3daSteve French	seq_puts(m, "\n\tShare Capabilities:");
295769ee6a4024434d1960acafd7adde38538bbe3daSteve French	if (tcon->capabilities & SMB2_SHARE_CAP_DFS)
296769ee6a4024434d1960acafd7adde38538bbe3daSteve French		seq_puts(m, " DFS,");
297769ee6a4024434d1960acafd7adde38538bbe3daSteve French	if (tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
298769ee6a4024434d1960acafd7adde38538bbe3daSteve French		seq_puts(m, " CONTINUOUS AVAILABILITY,");
299769ee6a4024434d1960acafd7adde38538bbe3daSteve French	if (tcon->capabilities & SMB2_SHARE_CAP_SCALEOUT)
300769ee6a4024434d1960acafd7adde38538bbe3daSteve French		seq_puts(m, " SCALEOUT,");
301769ee6a4024434d1960acafd7adde38538bbe3daSteve French	if (tcon->capabilities & SMB2_SHARE_CAP_CLUSTER)
302769ee6a4024434d1960acafd7adde38538bbe3daSteve French		seq_puts(m, " CLUSTER,");
303769ee6a4024434d1960acafd7adde38538bbe3daSteve French	if (tcon->capabilities & SMB2_SHARE_CAP_ASYMMETRIC)
304769ee6a4024434d1960acafd7adde38538bbe3daSteve French		seq_puts(m, " ASYMMETRIC,");
305769ee6a4024434d1960acafd7adde38538bbe3daSteve French	if (tcon->capabilities == 0)
306769ee6a4024434d1960acafd7adde38538bbe3daSteve French		seq_puts(m, " None");
307769ee6a4024434d1960acafd7adde38538bbe3daSteve French	seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags);
308769ee6a4024434d1960acafd7adde38538bbe3daSteve French}
309769ee6a4024434d1960acafd7adde38538bbe3daSteve French
310769ee6a4024434d1960acafd7adde38538bbe3daSteve Frenchstatic void
311d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskysmb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
312d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky{
313d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#ifdef CONFIG_CIFS_STATS
314d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	atomic_t *sent = tcon->stats.smb2_stats.smb2_com_sent;
315d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	atomic_t *failed = tcon->stats.smb2_stats.smb2_com_failed;
316d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nNegotiates: %d sent %d failed",
317d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_NEGOTIATE_HE]),
318d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_NEGOTIATE_HE]));
319d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nSessionSetups: %d sent %d failed",
320d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_SESSION_SETUP_HE]),
321d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_SESSION_SETUP_HE]));
322d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nLogoffs: %d sent %d failed",
323d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_LOGOFF_HE]),
324d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_LOGOFF_HE]));
325d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nTreeConnects: %d sent %d failed",
326d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_TREE_CONNECT_HE]),
327d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_TREE_CONNECT_HE]));
328d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nTreeDisconnects: %d sent %d failed",
329d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_TREE_DISCONNECT_HE]),
330d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_TREE_DISCONNECT_HE]));
331d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nCreates: %d sent %d failed",
332d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_CREATE_HE]),
333d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_CREATE_HE]));
334d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nCloses: %d sent %d failed",
335d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_CLOSE_HE]),
336d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_CLOSE_HE]));
337d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nFlushes: %d sent %d failed",
338d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_FLUSH_HE]),
339d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_FLUSH_HE]));
340d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nReads: %d sent %d failed",
341d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_READ_HE]),
342d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_READ_HE]));
343d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nWrites: %d sent %d failed",
344d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_WRITE_HE]),
345d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_WRITE_HE]));
346d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nLocks: %d sent %d failed",
347d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_LOCK_HE]),
348d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_LOCK_HE]));
349d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nIOCTLs: %d sent %d failed",
350d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_IOCTL_HE]),
351d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_IOCTL_HE]));
352d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nCancels: %d sent %d failed",
353d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_CANCEL_HE]),
354d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_CANCEL_HE]));
355d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nEchos: %d sent %d failed",
356d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_ECHO_HE]),
357d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_ECHO_HE]));
358d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nQueryDirectories: %d sent %d failed",
359d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_QUERY_DIRECTORY_HE]),
360d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_QUERY_DIRECTORY_HE]));
361d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nChangeNotifies: %d sent %d failed",
362d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_CHANGE_NOTIFY_HE]),
363d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_CHANGE_NOTIFY_HE]));
364d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nQueryInfos: %d sent %d failed",
365d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_QUERY_INFO_HE]),
366d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_QUERY_INFO_HE]));
367d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nSetInfos: %d sent %d failed",
368d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_SET_INFO_HE]),
369d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_SET_INFO_HE]));
370d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	seq_printf(m, "\nOplockBreaks: %d sent %d failed",
371d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&sent[SMB2_OPLOCK_BREAK_HE]),
372d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky		   atomic_read(&failed[SMB2_OPLOCK_BREAK_HE]));
373d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#endif
374d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky}
375d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky
376f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovskystatic void
377f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovskysmb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
378f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky{
3792e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
38053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
38153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky
382f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky	cfile->fid.persistent_fid = fid->persistent_fid;
383f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky	cfile->fid.volatile_fid = fid->volatile_fid;
38442873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky	server->ops->set_oplock_level(cinode, oplock, fid->epoch,
38542873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky				      &fid->purge_cache);
38618cceb6a78f46b65df654e8348fa2093b91b30f6Pavel Shilovsky	cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode);
387f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky}
388f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky
389760ad0cac198356c1148cad7531c1a6138322493Pavel Shilovskystatic void
390f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovskysmb2_close_file(const unsigned int xid, struct cifs_tcon *tcon,
391f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky		struct cifs_fid *fid)
392f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky{
393760ad0cac198356c1148cad7531c1a6138322493Pavel Shilovsky	SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
394f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky}
395f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky
3967a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovskystatic int
3977a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovskysmb2_flush_file(const unsigned int xid, struct cifs_tcon *tcon,
3987a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky		struct cifs_fid *fid)
3997a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky{
4007a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky	return SMB2_flush(xid, tcon, fid->persistent_fid, fid->volatile_fid);
4017a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky}
4027a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky
40309a4707e7638247302c6d798061aed117141fb74Pavel Shilovskystatic unsigned int
40409a4707e7638247302c6d798061aed117141fb74Pavel Shilovskysmb2_read_data_offset(char *buf)
40509a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky{
40609a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
40709a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	return rsp->DataOffset;
40809a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky}
40909a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky
41009a4707e7638247302c6d798061aed117141fb74Pavel Shilovskystatic unsigned int
41109a4707e7638247302c6d798061aed117141fb74Pavel Shilovskysmb2_read_data_length(char *buf)
41209a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky{
41309a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
41409a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	return le32_to_cpu(rsp->DataLength);
41509a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky}
41609a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky
417d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky
418d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovskystatic int
419d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovskysmb2_sync_read(const unsigned int xid, struct cifsFileInfo *cfile,
420d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky	       struct cifs_io_parms *parms, unsigned int *bytes_read,
421d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky	       char **buf, int *buf_type)
422d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky{
423d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky	parms->persistent_fid = cfile->fid.persistent_fid;
424d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky	parms->volatile_fid = cfile->fid.volatile_fid;
425d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky	return SMB2_read(xid, parms, bytes_read, buf, buf_type);
426d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky}
427d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky
428009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovskystatic int
429009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovskysmb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile,
430009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky		struct cifs_io_parms *parms, unsigned int *written,
431009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky		struct kvec *iov, unsigned long nr_segs)
432009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky{
433009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky
434009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky	parms->persistent_fid = cfile->fid.persistent_fid;
435009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky	parms->volatile_fid = cfile->fid.volatile_fid;
436009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky	return SMB2_write(xid, parms, written, iov, nr_segs);
437009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky}
438009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky
439c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovskystatic int
440c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovskysmb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
441c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky		   struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
442c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky{
443c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky	__le64 eof = cpu_to_le64(size);
444c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky	return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
445c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky			    cfile->fid.volatile_fid, cfile->pid, &eof);
446c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky}
447c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky
448d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskystatic int
449d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskysmb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
450d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		     const char *path, struct cifs_sb_info *cifs_sb,
451d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		     struct cifs_fid *fid, __u16 search_flags,
452d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		     struct cifs_search_info *srch_inf)
453d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky{
454d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	__le16 *utf16_path;
455d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	int rc;
4562e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
457064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	struct cifs_open_parms oparms;
458d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
459d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
460d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	if (!utf16_path)
461d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		return -ENOMEM;
462d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
463064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.tcon = tcon;
464064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
465064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.disposition = FILE_OPEN;
466064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.create_options = 0;
467064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.fid = fid;
4689cbc0b7339b0542a1d13922d2745a2636ce44853Pavel Shilovsky	oparms.reconnect = false;
469064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky
470b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
471d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	kfree(utf16_path);
472d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	if (rc) {
473f96637be081141d6f8813429499f164260b49d70Joe Perches		cifs_dbg(VFS, "open dir failed\n");
474d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		return rc;
475d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	}
476d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
477d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	srch_inf->entries_in_buffer = 0;
478d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	srch_inf->index_of_last_entry = 0;
479d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
480064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	rc = SMB2_query_directory(xid, tcon, fid->persistent_fid,
481064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky				  fid->volatile_fid, 0, srch_inf);
482d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	if (rc) {
483f96637be081141d6f8813429499f164260b49d70Joe Perches		cifs_dbg(VFS, "query directory failed\n");
484064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky		SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
485d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	}
486d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	return rc;
487d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky}
488d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
489d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskystatic int
490d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskysmb2_query_dir_next(const unsigned int xid, struct cifs_tcon *tcon,
491d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		    struct cifs_fid *fid, __u16 search_flags,
492d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky		    struct cifs_search_info *srch_inf)
493d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky{
494d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	return SMB2_query_directory(xid, tcon, fid->persistent_fid,
495d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky				    fid->volatile_fid, 0, srch_inf);
496d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky}
497d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
498d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskystatic int
499d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskysmb2_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
500d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	       struct cifs_fid *fid)
501d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky{
502d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	return SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
503d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky}
504d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky
5052e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky/*
5062e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky* If we negotiate SMB2 protocol and get STATUS_PENDING - update
5072e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky* the number of credits and return true. Otherwise - return false.
5082e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky*/
5092e44b2887882134abf353b28867b82645e9f0856Pavel Shilovskystatic bool
5102e44b2887882134abf353b28867b82645e9f0856Pavel Shilovskysmb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length)
5112e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky{
5122e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
5132e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky
51412e8a20824677fbc24e921d7aebfda6a47cc25b1Steve French	if (hdr->Status != STATUS_PENDING)
5152e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky		return false;
5162e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky
5172e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	if (!length) {
5182e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky		spin_lock(&server->req_lock);
5192e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky		server->credits += le16_to_cpu(hdr->CreditRequest);
5202e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky		spin_unlock(&server->req_lock);
5212e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky		wake_up(&server->request_q);
5222e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	}
5232e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky
5242e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	return true;
5252e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky}
5262e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky
527983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovskystatic int
528983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovskysmb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
529983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky		     struct cifsInodeInfo *cinode)
530983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky{
5310822f51426b51bd599b3a7e972b14aacaa045a92Pavel Shilovsky	if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
5320822f51426b51bd599b3a7e972b14aacaa045a92Pavel Shilovsky		return SMB2_lease_break(0, tcon, cinode->lease_key,
5330822f51426b51bd599b3a7e972b14aacaa045a92Pavel Shilovsky					smb2_get_lease_state(cinode));
5340822f51426b51bd599b3a7e972b14aacaa045a92Pavel Shilovsky
535983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	return SMB2_oplock_break(0, tcon, fid->persistent_fid,
536983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky				 fid->volatile_fid,
53718cceb6a78f46b65df654e8348fa2093b91b30f6Pavel Shilovsky				 CIFS_CACHE_READ(cinode) ? 1 : 0);
538983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky}
539983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky
5406fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovskystatic int
5416fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovskysmb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
5426fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	     struct kstatfs *buf)
5436fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky{
5446fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	int rc;
5456fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	__le16 srch_path = 0; /* Null - open root of share */
5466fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
547064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	struct cifs_open_parms oparms;
548064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	struct cifs_fid fid;
549064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky
550064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.tcon = tcon;
551064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.desired_access = FILE_READ_ATTRIBUTES;
552064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.disposition = FILE_OPEN;
553064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.create_options = 0;
554064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	oparms.fid = &fid;
5559cbc0b7339b0542a1d13922d2745a2636ce44853Pavel Shilovsky	oparms.reconnect = false;
5566fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky
557b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
5586fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	if (rc)
5596fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky		return rc;
5606fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	buf->f_type = SMB2_MAGIC_NUMBER;
561064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	rc = SMB2_QFS_info(xid, tcon, fid.persistent_fid, fid.volatile_fid,
562064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky			   buf);
563064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky	SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
5646fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	return rc;
5656fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky}
5666fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky
567027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovskystatic bool
568027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovskysmb2_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
569027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky{
570027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	return ob1->fid.persistent_fid == ob2->fid.persistent_fid &&
571027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	       ob1->fid.volatile_fid == ob2->fid.volatile_fid;
572027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky}
573027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky
574f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovskystatic int
575f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovskysmb2_mand_lock(const unsigned int xid, struct cifsFileInfo *cfile, __u64 offset,
576f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky	       __u64 length, __u32 type, int lock, int unlock, bool wait)
577f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky{
578f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky	if (unlock && !lock)
579f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky		type = SMB2_LOCKFLAG_UNLOCK;
580f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky	return SMB2_lock(xid, tlink_tcon(cfile->tlink),
581f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky			 cfile->fid.persistent_fid, cfile->fid.volatile_fid,
582f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky			 current->tgid, length, offset, type, wait);
583f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky}
584f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky
585b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovskystatic void
586b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovskysmb2_get_lease_key(struct inode *inode, struct cifs_fid *fid)
587b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky{
588b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky	memcpy(fid->lease_key, CIFS_I(inode)->lease_key, SMB2_LEASE_KEY_SIZE);
589b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky}
590b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky
591b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovskystatic void
592b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovskysmb2_set_lease_key(struct inode *inode, struct cifs_fid *fid)
593b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky{
594b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky	memcpy(CIFS_I(inode)->lease_key, fid->lease_key, SMB2_LEASE_KEY_SIZE);
595b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky}
596b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky
597b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovskystatic void
598b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovskysmb2_new_lease_key(struct cifs_fid *fid)
599b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky{
600b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky	get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE);
601b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky}
602b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky
603b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovskystatic int
604b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovskysmb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
605b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky		   const char *full_path, char **target_path,
606b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky		   struct cifs_sb_info *cifs_sb)
607b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky{
608b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	int rc;
609b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	__le16 *utf16_path;
610b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
611b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	struct cifs_open_parms oparms;
612b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	struct cifs_fid fid;
613b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	struct smb2_err_rsp *err_buf = NULL;
614b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	struct smb2_symlink_err_rsp *symlink;
615b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	unsigned int sub_len, sub_offset;
616b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky
617b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
618b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky
619b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
620b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	if (!utf16_path)
621b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky		return -ENOMEM;
622b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky
623b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	oparms.tcon = tcon;
624b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	oparms.desired_access = FILE_READ_ATTRIBUTES;
625b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	oparms.disposition = FILE_OPEN;
626b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	oparms.create_options = 0;
627b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	oparms.fid = &fid;
628b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	oparms.reconnect = false;
629b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky
630b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, &err_buf);
631b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky
632b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	if (!rc || !err_buf) {
633b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky		kfree(utf16_path);
634b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky		return -ENOENT;
635b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	}
636b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	/* open must fail on symlink - reset rc */
637b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	rc = 0;
638b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
639b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	sub_len = le16_to_cpu(symlink->SubstituteNameLength);
640b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	sub_offset = le16_to_cpu(symlink->SubstituteNameOffset);
641b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	*target_path = cifs_strndup_from_utf16(
642b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky				(char *)symlink->PathBuffer + sub_offset,
643b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky				sub_len, true, cifs_sb->local_nls);
644b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	if (!(*target_path)) {
645b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky		kfree(utf16_path);
646b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky		return -ENOMEM;
647b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	}
648b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	convert_delimiter(*target_path, '/');
649b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
650b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	kfree(utf16_path);
651b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	return rc;
652b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky}
653b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky
65453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskystatic void
65542873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovskysmb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
65642873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky		      unsigned int epoch, bool *purge_cache)
65753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky{
65853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	oplock &= 0xFF;
65953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
66053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		return;
66153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	if (oplock == SMB2_OPLOCK_LEVEL_BATCH) {
66242873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky		cinode->oplock = CIFS_CACHE_RHW_FLG;
66353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		cifs_dbg(FYI, "Batch Oplock granted on inode %p\n",
66453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky			 &cinode->vfs_inode);
66553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	} else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
66642873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky		cinode->oplock = CIFS_CACHE_RW_FLG;
66753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n",
66853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky			 &cinode->vfs_inode);
66953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	} else if (oplock == SMB2_OPLOCK_LEVEL_II) {
67053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		cinode->oplock = CIFS_CACHE_READ_FLG;
67153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		cifs_dbg(FYI, "Level II Oplock granted on inode %p\n",
67253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky			 &cinode->vfs_inode);
67353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	} else
67453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		cinode->oplock = 0;
67553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky}
67653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky
67753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskystatic void
67842873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovskysmb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
67942873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky		       unsigned int epoch, bool *purge_cache)
68053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky{
68153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	char message[5] = {0};
68253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky
68353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	oplock &= 0xFF;
68453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
68553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		return;
68653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky
68753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	cinode->oplock = 0;
68853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	if (oplock & SMB2_LEASE_READ_CACHING_HE) {
68953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		cinode->oplock |= CIFS_CACHE_READ_FLG;
69053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		strcat(message, "R");
69153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	}
69253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	if (oplock & SMB2_LEASE_HANDLE_CACHING_HE) {
69353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		cinode->oplock |= CIFS_CACHE_HANDLE_FLG;
69453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		strcat(message, "H");
69553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	}
69653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	if (oplock & SMB2_LEASE_WRITE_CACHING_HE) {
69753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		cinode->oplock |= CIFS_CACHE_WRITE_FLG;
69853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		strcat(message, "W");
69953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	}
70053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	if (!cinode->oplock)
70153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		strcat(message, "None");
70253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	cifs_dbg(FYI, "%s Lease granted on inode %p\n", message,
70353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky		 &cinode->vfs_inode);
70453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky}
70553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky
70642873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovskystatic void
70742873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovskysmb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
70842873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky		      unsigned int epoch, bool *purge_cache)
70942873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky{
71042873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky	unsigned int old_oplock = cinode->oplock;
71142873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky
71242873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky	smb21_set_oplock_level(cinode, oplock, epoch, purge_cache);
71342873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky
71442873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky	if (purge_cache) {
71542873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky		*purge_cache = false;
71642873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky		if (old_oplock == CIFS_CACHE_READ_FLG) {
71742873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky			if (cinode->oplock == CIFS_CACHE_READ_FLG &&
71842873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky			    (epoch - cinode->epoch > 0))
71942873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky				*purge_cache = true;
72042873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky			else if (cinode->oplock == CIFS_CACHE_RH_FLG &&
72142873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky				 (epoch - cinode->epoch > 1))
72242873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky				*purge_cache = true;
72342873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky			else if (cinode->oplock == CIFS_CACHE_RHW_FLG &&
72442873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky				 (epoch - cinode->epoch > 1))
72542873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky				*purge_cache = true;
72642873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky			else if (cinode->oplock == 0 &&
72742873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky				 (epoch - cinode->epoch > 0))
72842873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky				*purge_cache = true;
72942873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky		} else if (old_oplock == CIFS_CACHE_RH_FLG) {
73042873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky			if (cinode->oplock == CIFS_CACHE_RH_FLG &&
73142873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky			    (epoch - cinode->epoch > 0))
73242873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky				*purge_cache = true;
73342873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky			else if (cinode->oplock == CIFS_CACHE_RHW_FLG &&
73442873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky				 (epoch - cinode->epoch > 1))
73542873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky				*purge_cache = true;
73642873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky		}
73742873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky		cinode->epoch = epoch;
73842873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky	}
73942873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky}
74042873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky
74153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskystatic bool
74253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskysmb2_is_read_op(__u32 oplock)
74353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky{
74453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	return oplock == SMB2_OPLOCK_LEVEL_II;
74553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky}
74653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky
74753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskystatic bool
74853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskysmb21_is_read_op(__u32 oplock)
74953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky{
75053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	return (oplock & SMB2_LEASE_READ_CACHING_HE) &&
75153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	       !(oplock & SMB2_LEASE_WRITE_CACHING_HE);
75253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky}
75353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky
754f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovskystatic __le32
755f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovskymap_oplock_to_lease(u8 oplock)
756f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky{
757f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE)
758f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky		return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING;
759f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	else if (oplock == SMB2_OPLOCK_LEVEL_II)
760f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky		return SMB2_LEASE_READ_CACHING;
761f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	else if (oplock == SMB2_OPLOCK_LEVEL_BATCH)
762f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky		return SMB2_LEASE_HANDLE_CACHING | SMB2_LEASE_READ_CACHING |
763f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky		       SMB2_LEASE_WRITE_CACHING;
764f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	return 0;
765f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky}
766f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky
767a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovskystatic char *
768a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovskysmb2_create_lease_buf(u8 *lease_key, u8 oplock)
769a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky{
770a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	struct create_lease *buf;
771a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky
772a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	buf = kzalloc(sizeof(struct create_lease), GFP_KERNEL);
773a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	if (!buf)
774a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky		return NULL;
775a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky
776a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key));
777a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8)));
778f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
779a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky
780a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	buf->ccontext.DataOffset = cpu_to_le16(offsetof
781a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky					(struct create_lease, lcontext));
782a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context));
783a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	buf->ccontext.NameOffset = cpu_to_le16(offsetof
784a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky				(struct create_lease, Name));
785a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	buf->ccontext.NameLength = cpu_to_le16(4);
786a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	buf->Name[0] = 'R';
787a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	buf->Name[1] = 'q';
788a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	buf->Name[2] = 'L';
789a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	buf->Name[3] = 's';
790a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	return (char *)buf;
791a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky}
792a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky
793f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovskystatic char *
794f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovskysmb3_create_lease_buf(u8 *lease_key, u8 oplock)
795f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky{
796f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	struct create_lease_v2 *buf;
797f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky
798f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf = kzalloc(sizeof(struct create_lease_v2), GFP_KERNEL);
799f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	if (!buf)
800f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky		return NULL;
801f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky
802f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key));
803f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8)));
804f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
805f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky
806f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf->ccontext.DataOffset = cpu_to_le16(offsetof
807f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky					(struct create_lease_v2, lcontext));
808f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2));
809f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf->ccontext.NameOffset = cpu_to_le16(offsetof
810f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky				(struct create_lease_v2, Name));
811f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf->ccontext.NameLength = cpu_to_le16(4);
812f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf->Name[0] = 'R';
813f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf->Name[1] = 'q';
814f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf->Name[2] = 'L';
815f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	buf->Name[3] = 's';
816f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	return (char *)buf;
817f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky}
818f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky
819b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovskystatic __u8
82042873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovskysmb2_parse_lease_buf(void *buf, unsigned int *epoch)
821b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky{
822b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky	struct create_lease *lc = (struct create_lease *)buf;
823b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky
82442873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky	*epoch = 0; /* not used */
825b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky	if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
826b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky		return SMB2_OPLOCK_LEVEL_NOCHANGE;
827b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky	return le32_to_cpu(lc->lcontext.LeaseState);
828b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky}
829b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky
830f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovskystatic __u8
83142873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovskysmb3_parse_lease_buf(void *buf, unsigned int *epoch)
832f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky{
833f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;
834f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky
83542873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky	*epoch = le16_to_cpu(lc->lcontext.Epoch);
836f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
837f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky		return SMB2_OPLOCK_LEVEL_NOCHANGE;
838f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	return le32_to_cpu(lc->lcontext.LeaseState);
839f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky}
840f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky
84153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskystruct smb_version_operations smb20_operations = {
842027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	.compare_fids = smb2_compare_fids,
8432dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	.setup_request = smb2_setup_request,
844c95b8eeda3efcb419ea0a3f864cf99e32c038c21Pavel Shilovsky	.setup_async_request = smb2_setup_async_request,
8452dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	.check_receive = smb2_check_receive,
84628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	.add_credits = smb2_add_credits,
84728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	.set_credits = smb2_set_credits,
84828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	.get_credits_field = smb2_get_credits_field,
84928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky	.get_credits = smb2_get_credits,
8502dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	.get_next_mid = smb2_get_next_mid,
85109a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	.read_data_offset = smb2_read_data_offset,
85209a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	.read_data_length = smb2_read_data_length,
85309a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	.map_error = map_smb2_to_linux_error,
854093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.find_mid = smb2_find_mid,
855093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.check_message = smb2_check_message,
856093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.dump_detail = smb2_dump_detail,
857d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	.clear_stats = smb2_clear_stats,
858d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky	.print_stats = smb2_print_stats,
859983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	.is_oplock_break = smb2_is_valid_oplock_break,
860ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	.need_neg = smb2_need_neg,
861ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky	.negotiate = smb2_negotiate,
8623a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	.negotiate_wsize = smb2_negotiate_wsize,
8633a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky	.negotiate_rsize = smb2_negotiate_rsize,
8645478f9ba9a34d660eb3227dcd16314689c51f946Pavel Shilovsky	.sess_setup = SMB2_sess_setup,
8655478f9ba9a34d660eb3227dcd16314689c51f946Pavel Shilovsky	.logoff = SMB2_logoff,
866faaf946a7d5b79194358437150f34ab4c66bfe21Pavel Shilovsky	.tree_connect = SMB2_tcon,
867faaf946a7d5b79194358437150f34ab4c66bfe21Pavel Shilovsky	.tree_disconnect = SMB2_tdis,
8682503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky	.is_path_accessible = smb2_is_path_accessible,
8699094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky	.can_echo = smb2_can_echo,
8709094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky	.echo = SMB2_echo,
871be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky	.query_path_info = smb2_query_path_info,
872be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky	.get_srv_inum = smb2_get_srv_inum,
873b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky	.query_file_info = smb2_query_file_info,
874c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky	.set_path_size = smb2_set_path_size,
875c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky	.set_file_size = smb2_set_file_size,
8761feeaac753e0a9b3864740556b7840643642abdbPavel Shilovsky	.set_file_info = smb2_set_file_info,
877a0e731839dd461eee0fe2dc026e0965e961e2730Pavel Shilovsky	.mkdir = smb2_mkdir,
878a0e731839dd461eee0fe2dc026e0965e961e2730Pavel Shilovsky	.mkdir_setinfo = smb2_mkdir_setinfo,
8791a500f010fb2d121c58f77ddfde2eca1bde3bfcdPavel Shilovsky	.rmdir = smb2_rmdir,
880cbe6f439f5762c7fb4d2dd9293f5fdbfc4cd68f8Pavel Shilovsky	.unlink = smb2_unlink,
88135143eb5c2e3ae6c91b29144449d23f05f573796Pavel Shilovsky	.rename = smb2_rename_path,
882568798cc6211553e2494a6876fa19d064c822e79Pavel Shilovsky	.create_hardlink = smb2_create_hardlink,
883b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	.query_symlink = smb2_query_symlink,
884f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky	.open = smb2_open_file,
885f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky	.set_fid = smb2_set_fid,
886f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky	.close = smb2_close_file,
8877a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky	.flush = smb2_flush_file,
88809a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	.async_readv = smb2_async_readv,
88933319141252fd14b58cf13685156c23dcaac2527Pavel Shilovsky	.async_writev = smb2_async_writev,
890d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky	.sync_read = smb2_sync_read,
891009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky	.sync_write = smb2_sync_write,
892d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	.query_dir_first = smb2_query_dir_first,
893d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	.query_dir_next = smb2_query_dir_next,
894d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	.close_dir = smb2_close_dir,
895d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky	.calc_smb_size = smb2_calc_size,
8962e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky	.is_status_pending = smb2_is_status_pending,
897983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky	.oplock_response = smb2_oplock_response,
8986fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky	.queryfs = smb2_queryfs,
899f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky	.mand_lock = smb2_mand_lock,
900f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky	.mand_unlock_range = smb2_unlock_range,
901b140799a11adb6023d5f96712874c37b71dab290Pavel Shilovsky	.push_mand_locks = smb2_push_mandatory_locks,
902b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky	.get_lease_key = smb2_get_lease_key,
903b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky	.set_lease_key = smb2_set_lease_key,
904b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky	.new_lease_key = smb2_new_lease_key,
90538107d45cf452761a74fe512190e23f36834d6ddSteve French	.calc_signature = smb2_calc_signature,
90653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.is_read_op = smb2_is_read_op,
90753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.set_oplock_level = smb2_set_oplock_level,
908a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	.create_lease_buf = smb2_create_lease_buf,
909b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky	.parse_lease_buf = smb2_parse_lease_buf,
91038107d45cf452761a74fe512190e23f36834d6ddSteve French};
91138107d45cf452761a74fe512190e23f36834d6ddSteve French
91253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskystruct smb_version_operations smb21_operations = {
91353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.compare_fids = smb2_compare_fids,
91453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.setup_request = smb2_setup_request,
91553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.setup_async_request = smb2_setup_async_request,
91653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.check_receive = smb2_check_receive,
91753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.add_credits = smb2_add_credits,
91853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.set_credits = smb2_set_credits,
91953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.get_credits_field = smb2_get_credits_field,
92053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.get_credits = smb2_get_credits,
92153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.get_next_mid = smb2_get_next_mid,
92253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.read_data_offset = smb2_read_data_offset,
92353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.read_data_length = smb2_read_data_length,
92453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.map_error = map_smb2_to_linux_error,
92553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.find_mid = smb2_find_mid,
92653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.check_message = smb2_check_message,
92753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.dump_detail = smb2_dump_detail,
92853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.clear_stats = smb2_clear_stats,
92953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.print_stats = smb2_print_stats,
93053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.is_oplock_break = smb2_is_valid_oplock_break,
93153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.need_neg = smb2_need_neg,
93253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.negotiate = smb2_negotiate,
93353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.negotiate_wsize = smb2_negotiate_wsize,
93453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.negotiate_rsize = smb2_negotiate_rsize,
93553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.sess_setup = SMB2_sess_setup,
93653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.logoff = SMB2_logoff,
93753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.tree_connect = SMB2_tcon,
93853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.tree_disconnect = SMB2_tdis,
93953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.is_path_accessible = smb2_is_path_accessible,
94053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.can_echo = smb2_can_echo,
94153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.echo = SMB2_echo,
94253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.query_path_info = smb2_query_path_info,
94353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.get_srv_inum = smb2_get_srv_inum,
94453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.query_file_info = smb2_query_file_info,
94553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.set_path_size = smb2_set_path_size,
94653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.set_file_size = smb2_set_file_size,
94753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.set_file_info = smb2_set_file_info,
94853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.mkdir = smb2_mkdir,
94953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.mkdir_setinfo = smb2_mkdir_setinfo,
95053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.rmdir = smb2_rmdir,
95153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.unlink = smb2_unlink,
95253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.rename = smb2_rename_path,
95353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.create_hardlink = smb2_create_hardlink,
95453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.query_symlink = smb2_query_symlink,
95553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.open = smb2_open_file,
95653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.set_fid = smb2_set_fid,
95753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.close = smb2_close_file,
95853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.flush = smb2_flush_file,
95953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.async_readv = smb2_async_readv,
96053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.async_writev = smb2_async_writev,
96153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.sync_read = smb2_sync_read,
96253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.sync_write = smb2_sync_write,
96353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.query_dir_first = smb2_query_dir_first,
96453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.query_dir_next = smb2_query_dir_next,
96553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.close_dir = smb2_close_dir,
96653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.calc_smb_size = smb2_calc_size,
96753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.is_status_pending = smb2_is_status_pending,
96853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.oplock_response = smb2_oplock_response,
96953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.queryfs = smb2_queryfs,
97053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.mand_lock = smb2_mand_lock,
97153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.mand_unlock_range = smb2_unlock_range,
97253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.push_mand_locks = smb2_push_mandatory_locks,
97353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.get_lease_key = smb2_get_lease_key,
97453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.set_lease_key = smb2_set_lease_key,
97553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.new_lease_key = smb2_new_lease_key,
97653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.calc_signature = smb2_calc_signature,
97753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.is_read_op = smb21_is_read_op,
97853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.set_oplock_level = smb21_set_oplock_level,
979a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	.create_lease_buf = smb2_create_lease_buf,
980b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky	.parse_lease_buf = smb2_parse_lease_buf,
98153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky};
98238107d45cf452761a74fe512190e23f36834d6ddSteve French
98338107d45cf452761a74fe512190e23f36834d6ddSteve Frenchstruct smb_version_operations smb30_operations = {
98438107d45cf452761a74fe512190e23f36834d6ddSteve French	.compare_fids = smb2_compare_fids,
98538107d45cf452761a74fe512190e23f36834d6ddSteve French	.setup_request = smb2_setup_request,
98638107d45cf452761a74fe512190e23f36834d6ddSteve French	.setup_async_request = smb2_setup_async_request,
98738107d45cf452761a74fe512190e23f36834d6ddSteve French	.check_receive = smb2_check_receive,
98838107d45cf452761a74fe512190e23f36834d6ddSteve French	.add_credits = smb2_add_credits,
98938107d45cf452761a74fe512190e23f36834d6ddSteve French	.set_credits = smb2_set_credits,
99038107d45cf452761a74fe512190e23f36834d6ddSteve French	.get_credits_field = smb2_get_credits_field,
99138107d45cf452761a74fe512190e23f36834d6ddSteve French	.get_credits = smb2_get_credits,
99238107d45cf452761a74fe512190e23f36834d6ddSteve French	.get_next_mid = smb2_get_next_mid,
99338107d45cf452761a74fe512190e23f36834d6ddSteve French	.read_data_offset = smb2_read_data_offset,
99438107d45cf452761a74fe512190e23f36834d6ddSteve French	.read_data_length = smb2_read_data_length,
99538107d45cf452761a74fe512190e23f36834d6ddSteve French	.map_error = map_smb2_to_linux_error,
99638107d45cf452761a74fe512190e23f36834d6ddSteve French	.find_mid = smb2_find_mid,
99738107d45cf452761a74fe512190e23f36834d6ddSteve French	.check_message = smb2_check_message,
99838107d45cf452761a74fe512190e23f36834d6ddSteve French	.dump_detail = smb2_dump_detail,
99938107d45cf452761a74fe512190e23f36834d6ddSteve French	.clear_stats = smb2_clear_stats,
100038107d45cf452761a74fe512190e23f36834d6ddSteve French	.print_stats = smb2_print_stats,
1001769ee6a4024434d1960acafd7adde38538bbe3daSteve French	.dump_share_caps = smb2_dump_share_caps,
100238107d45cf452761a74fe512190e23f36834d6ddSteve French	.is_oplock_break = smb2_is_valid_oplock_break,
100338107d45cf452761a74fe512190e23f36834d6ddSteve French	.need_neg = smb2_need_neg,
100438107d45cf452761a74fe512190e23f36834d6ddSteve French	.negotiate = smb2_negotiate,
100538107d45cf452761a74fe512190e23f36834d6ddSteve French	.negotiate_wsize = smb2_negotiate_wsize,
100638107d45cf452761a74fe512190e23f36834d6ddSteve French	.negotiate_rsize = smb2_negotiate_rsize,
100738107d45cf452761a74fe512190e23f36834d6ddSteve French	.sess_setup = SMB2_sess_setup,
100838107d45cf452761a74fe512190e23f36834d6ddSteve French	.logoff = SMB2_logoff,
100938107d45cf452761a74fe512190e23f36834d6ddSteve French	.tree_connect = SMB2_tcon,
101038107d45cf452761a74fe512190e23f36834d6ddSteve French	.tree_disconnect = SMB2_tdis,
101138107d45cf452761a74fe512190e23f36834d6ddSteve French	.is_path_accessible = smb2_is_path_accessible,
101238107d45cf452761a74fe512190e23f36834d6ddSteve French	.can_echo = smb2_can_echo,
101338107d45cf452761a74fe512190e23f36834d6ddSteve French	.echo = SMB2_echo,
101438107d45cf452761a74fe512190e23f36834d6ddSteve French	.query_path_info = smb2_query_path_info,
101538107d45cf452761a74fe512190e23f36834d6ddSteve French	.get_srv_inum = smb2_get_srv_inum,
101638107d45cf452761a74fe512190e23f36834d6ddSteve French	.query_file_info = smb2_query_file_info,
101738107d45cf452761a74fe512190e23f36834d6ddSteve French	.set_path_size = smb2_set_path_size,
101838107d45cf452761a74fe512190e23f36834d6ddSteve French	.set_file_size = smb2_set_file_size,
101938107d45cf452761a74fe512190e23f36834d6ddSteve French	.set_file_info = smb2_set_file_info,
102038107d45cf452761a74fe512190e23f36834d6ddSteve French	.mkdir = smb2_mkdir,
102138107d45cf452761a74fe512190e23f36834d6ddSteve French	.mkdir_setinfo = smb2_mkdir_setinfo,
102238107d45cf452761a74fe512190e23f36834d6ddSteve French	.rmdir = smb2_rmdir,
102338107d45cf452761a74fe512190e23f36834d6ddSteve French	.unlink = smb2_unlink,
102438107d45cf452761a74fe512190e23f36834d6ddSteve French	.rename = smb2_rename_path,
102538107d45cf452761a74fe512190e23f36834d6ddSteve French	.create_hardlink = smb2_create_hardlink,
1026b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky	.query_symlink = smb2_query_symlink,
102738107d45cf452761a74fe512190e23f36834d6ddSteve French	.open = smb2_open_file,
102838107d45cf452761a74fe512190e23f36834d6ddSteve French	.set_fid = smb2_set_fid,
102938107d45cf452761a74fe512190e23f36834d6ddSteve French	.close = smb2_close_file,
103038107d45cf452761a74fe512190e23f36834d6ddSteve French	.flush = smb2_flush_file,
103138107d45cf452761a74fe512190e23f36834d6ddSteve French	.async_readv = smb2_async_readv,
103238107d45cf452761a74fe512190e23f36834d6ddSteve French	.async_writev = smb2_async_writev,
103338107d45cf452761a74fe512190e23f36834d6ddSteve French	.sync_read = smb2_sync_read,
103438107d45cf452761a74fe512190e23f36834d6ddSteve French	.sync_write = smb2_sync_write,
103538107d45cf452761a74fe512190e23f36834d6ddSteve French	.query_dir_first = smb2_query_dir_first,
103638107d45cf452761a74fe512190e23f36834d6ddSteve French	.query_dir_next = smb2_query_dir_next,
103738107d45cf452761a74fe512190e23f36834d6ddSteve French	.close_dir = smb2_close_dir,
103838107d45cf452761a74fe512190e23f36834d6ddSteve French	.calc_smb_size = smb2_calc_size,
103938107d45cf452761a74fe512190e23f36834d6ddSteve French	.is_status_pending = smb2_is_status_pending,
104038107d45cf452761a74fe512190e23f36834d6ddSteve French	.oplock_response = smb2_oplock_response,
104138107d45cf452761a74fe512190e23f36834d6ddSteve French	.queryfs = smb2_queryfs,
104238107d45cf452761a74fe512190e23f36834d6ddSteve French	.mand_lock = smb2_mand_lock,
104338107d45cf452761a74fe512190e23f36834d6ddSteve French	.mand_unlock_range = smb2_unlock_range,
104438107d45cf452761a74fe512190e23f36834d6ddSteve French	.push_mand_locks = smb2_push_mandatory_locks,
104538107d45cf452761a74fe512190e23f36834d6ddSteve French	.get_lease_key = smb2_get_lease_key,
104638107d45cf452761a74fe512190e23f36834d6ddSteve French	.set_lease_key = smb2_set_lease_key,
104738107d45cf452761a74fe512190e23f36834d6ddSteve French	.new_lease_key = smb2_new_lease_key,
1048e65a5cb41718e0eb17a470bc3acf2c3b2f00f1d0Steve French	.generate_signingkey = generate_smb3signingkey,
104938107d45cf452761a74fe512190e23f36834d6ddSteve French	.calc_signature = smb3_calc_signature,
105053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky	.is_read_op = smb21_is_read_op,
105142873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky	.set_oplock_level = smb3_set_oplock_level,
1052f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	.create_lease_buf = smb3_create_lease_buf,
1053f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	.parse_lease_buf = smb3_parse_lease_buf,
10541080ef758fb87f286b25277d8373e680a9e73363Steve French};
10551080ef758fb87f286b25277d8373e680a9e73363Steve French
1056dd446b16edd74ca525208d924d426f786dd973f8Steve Frenchstruct smb_version_values smb20_values = {
1057dd446b16edd74ca525208d924d426f786dd973f8Steve French	.version_string = SMB20_VERSION_STRING,
1058dd446b16edd74ca525208d924d426f786dd973f8Steve French	.protocol_id = SMB20_PROT_ID,
1059dd446b16edd74ca525208d924d426f786dd973f8Steve French	.req_capabilities = 0, /* MBZ */
1060dd446b16edd74ca525208d924d426f786dd973f8Steve French	.large_lock_type = 0,
1061dd446b16edd74ca525208d924d426f786dd973f8Steve French	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1062dd446b16edd74ca525208d924d426f786dd973f8Steve French	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1063dd446b16edd74ca525208d924d426f786dd973f8Steve French	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1064dd446b16edd74ca525208d924d426f786dd973f8Steve French	.header_size = sizeof(struct smb2_hdr),
1065dd446b16edd74ca525208d924d426f786dd973f8Steve French	.max_header_size = MAX_SMB2_HDR_SIZE,
1066dd446b16edd74ca525208d924d426f786dd973f8Steve French	.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1067dd446b16edd74ca525208d924d426f786dd973f8Steve French	.lock_cmd = SMB2_LOCK,
1068dd446b16edd74ca525208d924d426f786dd973f8Steve French	.cap_unix = 0,
1069dd446b16edd74ca525208d924d426f786dd973f8Steve French	.cap_nt_find = SMB2_NT_FIND,
1070dd446b16edd74ca525208d924d426f786dd973f8Steve French	.cap_large_files = SMB2_LARGE_FILES,
107150285882fdd919e2b9617fc844b4816b7833f115Jeff Layton	.signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
107250285882fdd919e2b9617fc844b4816b7833f115Jeff Layton	.signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1073a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	.create_lease_size = sizeof(struct create_lease),
1074dd446b16edd74ca525208d924d426f786dd973f8Steve French};
1075dd446b16edd74ca525208d924d426f786dd973f8Steve French
10761080ef758fb87f286b25277d8373e680a9e73363Steve Frenchstruct smb_version_values smb21_values = {
10771080ef758fb87f286b25277d8373e680a9e73363Steve French	.version_string = SMB21_VERSION_STRING,
1078e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.protocol_id = SMB21_PROT_ID,
1079e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.req_capabilities = 0, /* MBZ on negotiate req until SMB3 dialect */
1080e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.large_lock_type = 0,
1081e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1082e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1083e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1084e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.header_size = sizeof(struct smb2_hdr),
1085e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.max_header_size = MAX_SMB2_HDR_SIZE,
1086e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1087e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.lock_cmd = SMB2_LOCK,
1088e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.cap_unix = 0,
1089e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.cap_nt_find = SMB2_NT_FIND,
1090e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.cap_large_files = SMB2_LARGE_FILES,
109150285882fdd919e2b9617fc844b4816b7833f115Jeff Layton	.signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
109250285882fdd919e2b9617fc844b4816b7833f115Jeff Layton	.signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1093a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky	.create_lease_size = sizeof(struct create_lease),
1094e4aa25e7801163df058f62c617b859e9d3d4b148Steve French};
1095e4aa25e7801163df058f62c617b859e9d3d4b148Steve French
1096e4aa25e7801163df058f62c617b859e9d3d4b148Steve Frenchstruct smb_version_values smb30_values = {
1097e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.version_string = SMB30_VERSION_STRING,
1098e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.protocol_id = SMB30_PROT_ID,
1099e4aa25e7801163df058f62c617b859e9d3d4b148Steve French	.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
1100027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	.large_lock_type = 0,
1101027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1102027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1103027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1104093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.header_size = sizeof(struct smb2_hdr),
1105093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky	.max_header_size = MAX_SMB2_HDR_SIZE,
110609a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky	.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
11072dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky	.lock_cmd = SMB2_LOCK,
110829e20f9c65fae245d6fd4fce31cc5d01cde3d93fPavel Shilovsky	.cap_unix = 0,
110929e20f9c65fae245d6fd4fce31cc5d01cde3d93fPavel Shilovsky	.cap_nt_find = SMB2_NT_FIND,
111029e20f9c65fae245d6fd4fce31cc5d01cde3d93fPavel Shilovsky	.cap_large_files = SMB2_LARGE_FILES,
111150285882fdd919e2b9617fc844b4816b7833f115Jeff Layton	.signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
111250285882fdd919e2b9617fc844b4816b7833f115Jeff Layton	.signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1113f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	.create_lease_size = sizeof(struct create_lease_v2),
11141080ef758fb87f286b25277d8373e680a9e73363Steve French};
111520b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French
111620b6d8b42e7e7c9af5046fe525d6709e10d14992Steve Frenchstruct smb_version_values smb302_values = {
111720b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.version_string = SMB302_VERSION_STRING,
111820b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.protocol_id = SMB302_PROT_ID,
111920b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
112020b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.large_lock_type = 0,
112120b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
112220b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
112320b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
112420b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.header_size = sizeof(struct smb2_hdr),
112520b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.max_header_size = MAX_SMB2_HDR_SIZE,
112620b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
112720b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.lock_cmd = SMB2_LOCK,
112820b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.cap_unix = 0,
112920b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.cap_nt_find = SMB2_NT_FIND,
113020b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French	.cap_large_files = SMB2_LARGE_FILES,
113150285882fdd919e2b9617fc844b4816b7833f115Jeff Layton	.signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
113250285882fdd919e2b9617fc844b4816b7833f115Jeff Layton	.signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1133f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky	.create_lease_size = sizeof(struct create_lease_v2),
113420b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French};
1135