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