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> 22f29ebb47d5bb59ef246966b047356c03629a9705Steve French#include <linux/falloc.h> 231080ef758fb87f286b25277d8373e680a9e73363Steve French#include "cifsglob.h" 242dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky#include "smb2pdu.h" 252dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky#include "smb2proto.h" 2628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky#include "cifsproto.h" 2728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky#include "cifs_debug.h" 28b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky#include "cifs_unicode.h" 292e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky#include "smb2status.h" 306fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky#include "smb2glob.h" 3128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky 3228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic int 3328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskychange_conf(struct TCP_Server_Info *server) 3428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{ 3528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->credits += server->echo_credits + server->oplock_credits; 3628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->oplock_credits = server->echo_credits = 0; 3728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky switch (server->credits) { 3828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky case 0: 3928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky return -1; 4028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky case 1: 4128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->echoes = false; 4228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->oplocks = false; 43f96637be081141d6f8813429499f164260b49d70Joe Perches cifs_dbg(VFS, "disabling echoes and oplocks\n"); 4428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky break; 4528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky case 2: 4628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->echoes = true; 4728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->oplocks = false; 4828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->echo_credits = 1; 49f96637be081141d6f8813429499f164260b49d70Joe Perches cifs_dbg(FYI, "disabling oplocks\n"); 5028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky break; 5128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky default: 5228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->echoes = true; 5328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->oplocks = true; 5428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->echo_credits = 1; 5528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->oplock_credits = 1; 5628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky } 5728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->credits -= server->echo_credits + server->oplock_credits; 5828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky return 0; 5928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky} 6028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky 6128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic void 6228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_add_credits(struct TCP_Server_Info *server, const unsigned int add, 6328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky const int optype) 6428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{ 6528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky int *val, rc = 0; 6628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky spin_lock(&server->req_lock); 6728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky val = server->ops->get_credits_field(server, optype); 6828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky *val += add; 6928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->in_flight--; 70ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP) 7128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky rc = change_conf(server); 72983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky /* 73983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky * Sometimes server returns 0 credits on oplock break ack - we need to 74983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky * rebalance credits in this case. 75983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky */ 76983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky else if (server->in_flight > 0 && server->oplock_credits == 0 && 77983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky server->oplocks) { 78983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky if (server->credits > 1) { 79983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky server->credits--; 80983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky server->oplock_credits++; 81983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky } 82983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky } 8328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky spin_unlock(&server->req_lock); 8428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky wake_up(&server->request_q); 8528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky if (rc) 8628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky cifs_reconnect(server); 8728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky} 8828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky 8928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic void 9028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_set_credits(struct TCP_Server_Info *server, const int val) 9128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{ 9228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky spin_lock(&server->req_lock); 9328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky server->credits = val; 9428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky spin_unlock(&server->req_lock); 9528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky} 9628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky 9728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic int * 9828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_get_credits_field(struct TCP_Server_Info *server, const int optype) 9928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{ 10028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky switch (optype) { 10128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky case CIFS_ECHO_OP: 10228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky return &server->echo_credits; 10328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky case CIFS_OBREAK_OP: 10428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky return &server->oplock_credits; 10528ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky default: 10628ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky return &server->credits; 10728ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky } 10828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky} 10928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky 11028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskystatic unsigned int 11128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovskysmb2_get_credits(struct mid_q_entry *mid) 11228ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky{ 11328ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky return le16_to_cpu(((struct smb2_hdr *)mid->resp_buf)->CreditRequest); 11428ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky} 1152dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky 116cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovskystatic int 117cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovskysmb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, 118cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky unsigned int *num, unsigned int *credits) 119cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky{ 120cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky int rc = 0; 121cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky unsigned int scredits; 122cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky 123cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky spin_lock(&server->req_lock); 124cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky while (1) { 125cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky if (server->credits <= 0) { 126cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky spin_unlock(&server->req_lock); 127cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky cifs_num_waiters_inc(server); 128cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky rc = wait_event_killable(server->request_q, 129cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky has_credits(server, &server->credits)); 130cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky cifs_num_waiters_dec(server); 131cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky if (rc) 132cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky return rc; 133cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky spin_lock(&server->req_lock); 134cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky } else { 135cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky if (server->tcpStatus == CifsExiting) { 136cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky spin_unlock(&server->req_lock); 137cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky return -ENOENT; 138cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky } 139cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky 140cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky scredits = server->credits; 141cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky /* can deadlock with reopen */ 142cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky if (scredits == 1) { 143cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky *num = SMB2_MAX_BUFFER_SIZE; 144cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky *credits = 0; 145cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky break; 146cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky } 147cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky 148cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky /* leave one credit for a possible reopen */ 149cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky scredits--; 150cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky *num = min_t(unsigned int, size, 151cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky scredits * SMB2_MAX_BUFFER_SIZE); 152cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky 153cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky *credits = DIV_ROUND_UP(*num, SMB2_MAX_BUFFER_SIZE); 154cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky server->credits -= *credits; 155cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky server->in_flight++; 156cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky break; 157cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky } 158cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky } 159cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky spin_unlock(&server->req_lock); 160cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky return rc; 161cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky} 162cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky 1632dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovskystatic __u64 1642dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovskysmb2_get_next_mid(struct TCP_Server_Info *server) 1652dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky{ 1662dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky __u64 mid; 1672dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky /* for SMB2 we need the current value */ 1682dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky spin_lock(&GlobalMid_Lock); 1692dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky mid = server->CurrentMid++; 1702dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky spin_unlock(&GlobalMid_Lock); 1712dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky return mid; 1722dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky} 1731080ef758fb87f286b25277d8373e680a9e73363Steve French 174093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskystatic struct mid_q_entry * 175093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskysmb2_find_mid(struct TCP_Server_Info *server, char *buf) 176093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky{ 177093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky struct mid_q_entry *mid; 178093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky struct smb2_hdr *hdr = (struct smb2_hdr *)buf; 179093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky 180093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky spin_lock(&GlobalMid_Lock); 181093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky list_for_each_entry(mid, &server->pending_mid_q, qhead) { 182093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky if ((mid->mid == hdr->MessageId) && 183093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky (mid->mid_state == MID_REQUEST_SUBMITTED) && 184093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky (mid->command == hdr->Command)) { 185093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky spin_unlock(&GlobalMid_Lock); 186093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky return mid; 187093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky } 188093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky } 189093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky spin_unlock(&GlobalMid_Lock); 190093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky return NULL; 191093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky} 192093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky 193093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskystatic void 194093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovskysmb2_dump_detail(void *buf) 195093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky{ 196093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky#ifdef CONFIG_CIFS_DEBUG2 197093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky struct smb2_hdr *smb = (struct smb2_hdr *)buf; 198093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky 199f96637be081141d6f8813429499f164260b49d70Joe Perches cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n", 200f96637be081141d6f8813429499f164260b49d70Joe Perches smb->Command, smb->Status, smb->Flags, smb->MessageId, 201f96637be081141d6f8813429499f164260b49d70Joe Perches smb->ProcessId); 202f96637be081141d6f8813429499f164260b49d70Joe Perches cifs_dbg(VFS, "smb buf %p len %u\n", smb, smb2_calc_size(smb)); 203093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky#endif 204093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky} 205093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky 206ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskystatic bool 207ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskysmb2_need_neg(struct TCP_Server_Info *server) 208ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky{ 209ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky return server->max_read == 0; 210ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky} 211ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky 212ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskystatic int 213ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovskysmb2_negotiate(const unsigned int xid, struct cifs_ses *ses) 214ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky{ 215ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky int rc; 216ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky ses->server->CurrentMid = 0; 217ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky rc = SMB2_negotiate(xid, ses); 218ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky /* BB we probably don't need to retry with modern servers */ 219ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky if (rc == -EAGAIN) 220ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky rc = -EHOSTDOWN; 221ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky return rc; 222ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky} 223ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky 2243a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovskystatic unsigned int 2253a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovskysmb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) 2263a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky{ 2273a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky struct TCP_Server_Info *server = tcon->ses->server; 2283a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky unsigned int wsize; 2293a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky 2303a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky /* start with specified wsize, or default */ 2313a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE; 2323a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky wsize = min_t(unsigned int, wsize, server->max_write); 233cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky 234cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU)) 235cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE); 2363a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky 2373a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky return wsize; 2383a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky} 2393a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky 2403a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovskystatic unsigned int 2413a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovskysmb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) 2423a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky{ 2433a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky struct TCP_Server_Info *server = tcon->ses->server; 2443a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky unsigned int rsize; 2453a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky 2463a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky /* start with specified rsize, or default */ 2473a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE; 2483a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky rsize = min_t(unsigned int, rsize, server->max_read); 249bed9da0213f2174719b68012bd60735a11cfe244Pavel Shilovsky 250bed9da0213f2174719b68012bd60735a11cfe244Pavel Shilovsky if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU)) 251bed9da0213f2174719b68012bd60735a11cfe244Pavel Shilovsky rsize = min_t(unsigned int, rsize, SMB2_MAX_BUFFER_SIZE); 2523a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky 2533a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky return rsize; 2543a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky} 2553a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky 256c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French#ifdef CONFIG_CIFS_STATS2 257c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve Frenchstatic int 258c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve FrenchSMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon) 259c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French{ 260c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French int rc; 261c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French unsigned int ret_data_len = 0; 262c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French struct network_interface_info_ioctl_rsp *out_buf; 263c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French 264c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, 265c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French FSCTL_QUERY_NETWORK_INTERFACE_INFO, true /* is_fsctl */, 266c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French NULL /* no data input */, 0 /* no data input */, 267c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French (char **)&out_buf, &ret_data_len); 2689ffc5412964d5b276227684124efb702ec387c19Steve French if (rc != 0) 2699ffc5412964d5b276227684124efb702ec387c19Steve French cifs_dbg(VFS, "error %d on ioctl to get interface list\n", rc); 2709ffc5412964d5b276227684124efb702ec387c19Steve French else if (ret_data_len < sizeof(struct network_interface_info_ioctl_rsp)) { 2719ffc5412964d5b276227684124efb702ec387c19Steve French cifs_dbg(VFS, "server returned bad net interface info buf\n"); 2729ffc5412964d5b276227684124efb702ec387c19Steve French rc = -EINVAL; 2739ffc5412964d5b276227684124efb702ec387c19Steve French } else { 274c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French /* Dump info on first interface */ 275c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French cifs_dbg(FYI, "Adapter Capability 0x%x\t", 276c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French le32_to_cpu(out_buf->Capability)); 277c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French cifs_dbg(FYI, "Link Speed %lld\n", 278c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French le64_to_cpu(out_buf->LinkSpeed)); 2799ffc5412964d5b276227684124efb702ec387c19Steve French } 280c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French 281c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French return rc; 282c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French} 283c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French#endif /* STATS2 */ 284c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French 28534f626406c09dd45878ce75170abab342985ec24Steve Frenchstatic void 286af6a12ea8d4bb39a87527835b943bde4215897e5Steven Frenchsmb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon) 287af6a12ea8d4bb39a87527835b943bde4215897e5Steven French{ 288af6a12ea8d4bb39a87527835b943bde4215897e5Steven French int rc; 289af6a12ea8d4bb39a87527835b943bde4215897e5Steven French __le16 srch_path = 0; /* Null - open root of share */ 290af6a12ea8d4bb39a87527835b943bde4215897e5Steven French u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 291af6a12ea8d4bb39a87527835b943bde4215897e5Steven French struct cifs_open_parms oparms; 292af6a12ea8d4bb39a87527835b943bde4215897e5Steven French struct cifs_fid fid; 293af6a12ea8d4bb39a87527835b943bde4215897e5Steven French 294af6a12ea8d4bb39a87527835b943bde4215897e5Steven French oparms.tcon = tcon; 295af6a12ea8d4bb39a87527835b943bde4215897e5Steven French oparms.desired_access = FILE_READ_ATTRIBUTES; 296af6a12ea8d4bb39a87527835b943bde4215897e5Steven French oparms.disposition = FILE_OPEN; 297af6a12ea8d4bb39a87527835b943bde4215897e5Steven French oparms.create_options = 0; 298af6a12ea8d4bb39a87527835b943bde4215897e5Steven French oparms.fid = &fid; 299af6a12ea8d4bb39a87527835b943bde4215897e5Steven French oparms.reconnect = false; 300af6a12ea8d4bb39a87527835b943bde4215897e5Steven French 301af6a12ea8d4bb39a87527835b943bde4215897e5Steven French rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL); 302af6a12ea8d4bb39a87527835b943bde4215897e5Steven French if (rc) 303af6a12ea8d4bb39a87527835b943bde4215897e5Steven French return; 304af6a12ea8d4bb39a87527835b943bde4215897e5Steven French 305c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French#ifdef CONFIG_CIFS_STATS2 306c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French SMB3_request_interfaces(xid, tcon); 307c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French#endif /* STATS2 */ 308c481e9feee78c6ce1ba0a1c8c892049f6514f6cfSteve French 309af6a12ea8d4bb39a87527835b943bde4215897e5Steven French SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, 310af6a12ea8d4bb39a87527835b943bde4215897e5Steven French FS_ATTRIBUTE_INFORMATION); 311af6a12ea8d4bb39a87527835b943bde4215897e5Steven French SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, 312af6a12ea8d4bb39a87527835b943bde4215897e5Steven French FS_DEVICE_INFORMATION); 313af6a12ea8d4bb39a87527835b943bde4215897e5Steven French SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, 314af6a12ea8d4bb39a87527835b943bde4215897e5Steven French FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */ 315af6a12ea8d4bb39a87527835b943bde4215897e5Steven French SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 316af6a12ea8d4bb39a87527835b943bde4215897e5Steven French return; 317af6a12ea8d4bb39a87527835b943bde4215897e5Steven French} 318af6a12ea8d4bb39a87527835b943bde4215897e5Steven French 319af6a12ea8d4bb39a87527835b943bde4215897e5Steven Frenchstatic void 32034f626406c09dd45878ce75170abab342985ec24Steve Frenchsmb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon) 32134f626406c09dd45878ce75170abab342985ec24Steve French{ 32234f626406c09dd45878ce75170abab342985ec24Steve French int rc; 32334f626406c09dd45878ce75170abab342985ec24Steve French __le16 srch_path = 0; /* Null - open root of share */ 32434f626406c09dd45878ce75170abab342985ec24Steve French u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 32534f626406c09dd45878ce75170abab342985ec24Steve French struct cifs_open_parms oparms; 32634f626406c09dd45878ce75170abab342985ec24Steve French struct cifs_fid fid; 32734f626406c09dd45878ce75170abab342985ec24Steve French 32834f626406c09dd45878ce75170abab342985ec24Steve French oparms.tcon = tcon; 32934f626406c09dd45878ce75170abab342985ec24Steve French oparms.desired_access = FILE_READ_ATTRIBUTES; 33034f626406c09dd45878ce75170abab342985ec24Steve French oparms.disposition = FILE_OPEN; 33134f626406c09dd45878ce75170abab342985ec24Steve French oparms.create_options = 0; 33234f626406c09dd45878ce75170abab342985ec24Steve French oparms.fid = &fid; 33334f626406c09dd45878ce75170abab342985ec24Steve French oparms.reconnect = false; 33434f626406c09dd45878ce75170abab342985ec24Steve French 33534f626406c09dd45878ce75170abab342985ec24Steve French rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL); 33634f626406c09dd45878ce75170abab342985ec24Steve French if (rc) 33734f626406c09dd45878ce75170abab342985ec24Steve French return; 33834f626406c09dd45878ce75170abab342985ec24Steve French 3392167114c6ea6e76fd84e368bae5389d37dd156aaSteven French SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, 3402167114c6ea6e76fd84e368bae5389d37dd156aaSteven French FS_ATTRIBUTE_INFORMATION); 3412167114c6ea6e76fd84e368bae5389d37dd156aaSteven French SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, 3422167114c6ea6e76fd84e368bae5389d37dd156aaSteven French FS_DEVICE_INFORMATION); 34334f626406c09dd45878ce75170abab342985ec24Steve French SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 34434f626406c09dd45878ce75170abab342985ec24Steve French return; 34534f626406c09dd45878ce75170abab342985ec24Steve French} 34634f626406c09dd45878ce75170abab342985ec24Steve French 3472503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovskystatic int 3482503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovskysmb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, 3492503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky struct cifs_sb_info *cifs_sb, const char *full_path) 3502503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky{ 3512503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky int rc; 3522503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky __le16 *utf16_path; 3532e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 354064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky struct cifs_open_parms oparms; 355064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky struct cifs_fid fid; 3562503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky 3572503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); 3582503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky if (!utf16_path) 3592503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky return -ENOMEM; 3602503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky 361064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.tcon = tcon; 362064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.desired_access = FILE_READ_ATTRIBUTES; 363064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.disposition = FILE_OPEN; 364064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.create_options = 0; 365064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.fid = &fid; 3669cbc0b7339b0542a1d13922d2745a2636ce44853Pavel Shilovsky oparms.reconnect = false; 367064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky 368b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL); 3692503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky if (rc) { 3702503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky kfree(utf16_path); 3712503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky return rc; 3722503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky } 3732503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky 374064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 3752503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky kfree(utf16_path); 3762503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky return rc; 3772503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky} 3782503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky 379be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovskystatic int 380be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovskysmb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon, 381be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky struct cifs_sb_info *cifs_sb, const char *full_path, 382be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky u64 *uniqueid, FILE_ALL_INFO *data) 383be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky{ 384be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky *uniqueid = le64_to_cpu(data->IndexNumber); 385be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky return 0; 386be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky} 387be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky 388b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovskystatic int 389b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovskysmb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon, 390b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky struct cifs_fid *fid, FILE_ALL_INFO *data) 391b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky{ 392b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky int rc; 393b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky struct smb2_file_all_info *smb2_data; 394b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky 3951bbe4997b13de903c421c1cc78440e544b5f9064Pavel Shilovsky smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2, 396b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky GFP_KERNEL); 397b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky if (smb2_data == NULL) 398b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky return -ENOMEM; 399b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky 400b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky rc = SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid, 401b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky smb2_data); 402b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky if (!rc) 403b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky move_smb2_info_to_cifs(data, smb2_data); 404b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky kfree(smb2_data); 405b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky return rc; 406b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky} 407b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky 4089094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovskystatic bool 4099094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovskysmb2_can_echo(struct TCP_Server_Info *server) 4109094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky{ 4119094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky return server->echoes; 4129094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky} 4139094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky 414d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskystatic void 415d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskysmb2_clear_stats(struct cifs_tcon *tcon) 416d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky{ 417d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#ifdef CONFIG_CIFS_STATS 418d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky int i; 419d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) { 420d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0); 421d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0); 422d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky } 423d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#endif 424d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky} 425d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky 426d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskystatic void 427769ee6a4024434d1960acafd7adde38538bbe3daSteve Frenchsmb2_dump_share_caps(struct seq_file *m, struct cifs_tcon *tcon) 428769ee6a4024434d1960acafd7adde38538bbe3daSteve French{ 429769ee6a4024434d1960acafd7adde38538bbe3daSteve French seq_puts(m, "\n\tShare Capabilities:"); 430769ee6a4024434d1960acafd7adde38538bbe3daSteve French if (tcon->capabilities & SMB2_SHARE_CAP_DFS) 431769ee6a4024434d1960acafd7adde38538bbe3daSteve French seq_puts(m, " DFS,"); 432769ee6a4024434d1960acafd7adde38538bbe3daSteve French if (tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY) 433769ee6a4024434d1960acafd7adde38538bbe3daSteve French seq_puts(m, " CONTINUOUS AVAILABILITY,"); 434769ee6a4024434d1960acafd7adde38538bbe3daSteve French if (tcon->capabilities & SMB2_SHARE_CAP_SCALEOUT) 435769ee6a4024434d1960acafd7adde38538bbe3daSteve French seq_puts(m, " SCALEOUT,"); 436769ee6a4024434d1960acafd7adde38538bbe3daSteve French if (tcon->capabilities & SMB2_SHARE_CAP_CLUSTER) 437769ee6a4024434d1960acafd7adde38538bbe3daSteve French seq_puts(m, " CLUSTER,"); 438769ee6a4024434d1960acafd7adde38538bbe3daSteve French if (tcon->capabilities & SMB2_SHARE_CAP_ASYMMETRIC) 439769ee6a4024434d1960acafd7adde38538bbe3daSteve French seq_puts(m, " ASYMMETRIC,"); 440769ee6a4024434d1960acafd7adde38538bbe3daSteve French if (tcon->capabilities == 0) 441769ee6a4024434d1960acafd7adde38538bbe3daSteve French seq_puts(m, " None"); 442af6a12ea8d4bb39a87527835b943bde4215897e5Steven French if (tcon->ss_flags & SSINFO_FLAGS_ALIGNED_DEVICE) 443af6a12ea8d4bb39a87527835b943bde4215897e5Steven French seq_puts(m, " Aligned,"); 444af6a12ea8d4bb39a87527835b943bde4215897e5Steven French if (tcon->ss_flags & SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE) 445af6a12ea8d4bb39a87527835b943bde4215897e5Steven French seq_puts(m, " Partition Aligned,"); 446af6a12ea8d4bb39a87527835b943bde4215897e5Steven French if (tcon->ss_flags & SSINFO_FLAGS_NO_SEEK_PENALTY) 447af6a12ea8d4bb39a87527835b943bde4215897e5Steven French seq_puts(m, " SSD,"); 448af6a12ea8d4bb39a87527835b943bde4215897e5Steven French if (tcon->ss_flags & SSINFO_FLAGS_TRIM_ENABLED) 449af6a12ea8d4bb39a87527835b943bde4215897e5Steven French seq_puts(m, " TRIM-support,"); 450af6a12ea8d4bb39a87527835b943bde4215897e5Steven French 451769ee6a4024434d1960acafd7adde38538bbe3daSteve French seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags); 452af6a12ea8d4bb39a87527835b943bde4215897e5Steven French if (tcon->perf_sector_size) 453af6a12ea8d4bb39a87527835b943bde4215897e5Steven French seq_printf(m, "\tOptimal sector size: 0x%x", 454af6a12ea8d4bb39a87527835b943bde4215897e5Steven French tcon->perf_sector_size); 455769ee6a4024434d1960acafd7adde38538bbe3daSteve French} 456769ee6a4024434d1960acafd7adde38538bbe3daSteve French 457769ee6a4024434d1960acafd7adde38538bbe3daSteve Frenchstatic void 458d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovskysmb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon) 459d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky{ 460d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#ifdef CONFIG_CIFS_STATS 461d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_t *sent = tcon->stats.smb2_stats.smb2_com_sent; 462d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_t *failed = tcon->stats.smb2_stats.smb2_com_failed; 463d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nNegotiates: %d sent %d failed", 464d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_NEGOTIATE_HE]), 465d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_NEGOTIATE_HE])); 466d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nSessionSetups: %d sent %d failed", 467d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_SESSION_SETUP_HE]), 468d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_SESSION_SETUP_HE])); 469d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nLogoffs: %d sent %d failed", 470d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_LOGOFF_HE]), 471d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_LOGOFF_HE])); 472d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nTreeConnects: %d sent %d failed", 473d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_TREE_CONNECT_HE]), 474d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_TREE_CONNECT_HE])); 475d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nTreeDisconnects: %d sent %d failed", 476d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_TREE_DISCONNECT_HE]), 477d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_TREE_DISCONNECT_HE])); 478d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nCreates: %d sent %d failed", 479d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_CREATE_HE]), 480d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_CREATE_HE])); 481d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nCloses: %d sent %d failed", 482d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_CLOSE_HE]), 483d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_CLOSE_HE])); 484d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nFlushes: %d sent %d failed", 485d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_FLUSH_HE]), 486d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_FLUSH_HE])); 487d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nReads: %d sent %d failed", 488d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_READ_HE]), 489d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_READ_HE])); 490d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nWrites: %d sent %d failed", 491d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_WRITE_HE]), 492d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_WRITE_HE])); 493d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nLocks: %d sent %d failed", 494d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_LOCK_HE]), 495d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_LOCK_HE])); 496d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nIOCTLs: %d sent %d failed", 497d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_IOCTL_HE]), 498d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_IOCTL_HE])); 499d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nCancels: %d sent %d failed", 500d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_CANCEL_HE]), 501d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_CANCEL_HE])); 502d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nEchos: %d sent %d failed", 503d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_ECHO_HE]), 504d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_ECHO_HE])); 505d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nQueryDirectories: %d sent %d failed", 506d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_QUERY_DIRECTORY_HE]), 507d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_QUERY_DIRECTORY_HE])); 508d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nChangeNotifies: %d sent %d failed", 509d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_CHANGE_NOTIFY_HE]), 510d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_CHANGE_NOTIFY_HE])); 511d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nQueryInfos: %d sent %d failed", 512d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_QUERY_INFO_HE]), 513d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_QUERY_INFO_HE])); 514d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nSetInfos: %d sent %d failed", 515d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_SET_INFO_HE]), 516d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_SET_INFO_HE])); 517d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky seq_printf(m, "\nOplockBreaks: %d sent %d failed", 518d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&sent[SMB2_OPLOCK_BREAK_HE]), 519d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky atomic_read(&failed[SMB2_OPLOCK_BREAK_HE])); 520d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky#endif 521d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky} 522d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky 523f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovskystatic void 524f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovskysmb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock) 525f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky{ 5262e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); 52753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; 52853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky 529f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky cfile->fid.persistent_fid = fid->persistent_fid; 530f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky cfile->fid.volatile_fid = fid->volatile_fid; 53142873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky server->ops->set_oplock_level(cinode, oplock, fid->epoch, 53242873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky &fid->purge_cache); 53318cceb6a78f46b65df654e8348fa2093b91b30f6Pavel Shilovsky cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode); 534f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky} 535f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky 536760ad0cac198356c1148cad7531c1a6138322493Pavel Shilovskystatic void 537f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovskysmb2_close_file(const unsigned int xid, struct cifs_tcon *tcon, 538f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky struct cifs_fid *fid) 539f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky{ 540760ad0cac198356c1148cad7531c1a6138322493Pavel Shilovsky SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid); 541f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky} 542f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky 5437a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovskystatic int 54441c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve FrenchSMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon, 54541c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French u64 persistent_fid, u64 volatile_fid, 54641c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French struct copychunk_ioctl *pcchunk) 54741c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French{ 54841c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French int rc; 54941c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French unsigned int ret_data_len; 55041c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French struct resume_key_req *res_key; 55141c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 55241c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid, 55341c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French FSCTL_SRV_REQUEST_RESUME_KEY, true /* is_fsctl */, 55441c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French NULL, 0 /* no input */, 55541c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French (char **)&res_key, &ret_data_len); 55641c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 55741c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French if (rc) { 55841c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French cifs_dbg(VFS, "refcpy ioctl error %d getting resume key\n", rc); 55941c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French goto req_res_key_exit; 56041c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French } 56141c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French if (ret_data_len < sizeof(struct resume_key_req)) { 56241c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French cifs_dbg(VFS, "Invalid refcopy resume key length\n"); 56341c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French rc = -EINVAL; 56441c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French goto req_res_key_exit; 56541c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French } 56641c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French memcpy(pcchunk->SourceKey, res_key->ResumeKey, COPY_CHUNK_RES_KEY_SIZE); 56741c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 56841c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve Frenchreq_res_key_exit: 56941c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French kfree(res_key); 57041c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French return rc; 57141c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French} 57241c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 57341c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve Frenchstatic int 57441c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve Frenchsmb2_clone_range(const unsigned int xid, 57541c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French struct cifsFileInfo *srcfile, 57641c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French struct cifsFileInfo *trgtfile, u64 src_off, 57741c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French u64 len, u64 dest_off) 57841c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French{ 57941c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French int rc; 58041c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French unsigned int ret_data_len; 58141c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French struct copychunk_ioctl *pcchunk; 5829bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French struct copychunk_ioctl_rsp *retbuf = NULL; 5839bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French struct cifs_tcon *tcon; 5849bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French int chunks_copied = 0; 5859bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French bool chunk_sizes_updated = false; 58641c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 58741c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French pcchunk = kmalloc(sizeof(struct copychunk_ioctl), GFP_KERNEL); 58841c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 58941c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French if (pcchunk == NULL) 59041c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French return -ENOMEM; 59141c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 59241c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French cifs_dbg(FYI, "in smb2_clone_range - about to call request res key\n"); 59341c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French /* Request a key from the server to identify the source of the copy */ 59441c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French rc = SMB2_request_res_key(xid, tlink_tcon(srcfile->tlink), 59541c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French srcfile->fid.persistent_fid, 59641c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French srcfile->fid.volatile_fid, pcchunk); 59741c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 59841c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French /* Note: request_res_key sets res_key null only if rc !=0 */ 59941c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French if (rc) 6009bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French goto cchunk_out; 60141c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 60241c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French /* For now array only one chunk long, will make more flexible later */ 60341c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French pcchunk->ChunkCount = __constant_cpu_to_le32(1); 60441c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French pcchunk->Reserved = 0; 60541c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French pcchunk->Reserved2 = 0; 60641c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 6079bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French tcon = tlink_tcon(trgtfile->tlink); 60841c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 6099bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French while (len > 0) { 6109bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French pcchunk->SourceOffset = cpu_to_le64(src_off); 6119bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French pcchunk->TargetOffset = cpu_to_le64(dest_off); 6129bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French pcchunk->Length = 6139bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk)); 61441c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 6159bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French /* Request server copy to target from src identified by key */ 6169bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid, 6179bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French trgtfile->fid.volatile_fid, FSCTL_SRV_COPYCHUNK_WRITE, 6189bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French true /* is_fsctl */, (char *)pcchunk, 6199bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French sizeof(struct copychunk_ioctl), (char **)&retbuf, 6209bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French &ret_data_len); 6219bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French if (rc == 0) { 6229bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French if (ret_data_len != 6239bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French sizeof(struct copychunk_ioctl_rsp)) { 6249bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French cifs_dbg(VFS, "invalid cchunk response size\n"); 6259bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French rc = -EIO; 6269bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French goto cchunk_out; 6279bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French } 6289bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French if (retbuf->TotalBytesWritten == 0) { 6299bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French cifs_dbg(FYI, "no bytes copied\n"); 6309bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French rc = -EIO; 6319bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French goto cchunk_out; 6329bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French } 6339bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French /* 6349bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French * Check if server claimed to write more than we asked 6359bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French */ 6369bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French if (le32_to_cpu(retbuf->TotalBytesWritten) > 6379bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French le32_to_cpu(pcchunk->Length)) { 6389bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French cifs_dbg(VFS, "invalid copy chunk response\n"); 6399bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French rc = -EIO; 6409bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French goto cchunk_out; 6419bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French } 6429bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French if (le32_to_cpu(retbuf->ChunksWritten) != 1) { 6439bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French cifs_dbg(VFS, "invalid num chunks written\n"); 6449bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French rc = -EIO; 6459bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French goto cchunk_out; 6469bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French } 6479bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French chunks_copied++; 6489bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French 6499bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French src_off += le32_to_cpu(retbuf->TotalBytesWritten); 6509bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French dest_off += le32_to_cpu(retbuf->TotalBytesWritten); 6519bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French len -= le32_to_cpu(retbuf->TotalBytesWritten); 6529bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French 6539bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French cifs_dbg(FYI, "Chunks %d PartialChunk %d Total %d\n", 6549bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French le32_to_cpu(retbuf->ChunksWritten), 6559bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French le32_to_cpu(retbuf->ChunkBytesWritten), 6569bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French le32_to_cpu(retbuf->TotalBytesWritten)); 6579bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French } else if (rc == -EINVAL) { 6589bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French if (ret_data_len != sizeof(struct copychunk_ioctl_rsp)) 6599bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French goto cchunk_out; 6609bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French 6619bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French cifs_dbg(FYI, "MaxChunks %d BytesChunk %d MaxCopy %d\n", 6629bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French le32_to_cpu(retbuf->ChunksWritten), 6639bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French le32_to_cpu(retbuf->ChunkBytesWritten), 6649bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French le32_to_cpu(retbuf->TotalBytesWritten)); 6659bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French 6669bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French /* 6679bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French * Check if this is the first request using these sizes, 6689bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French * (ie check if copy succeed once with original sizes 6699bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French * and check if the server gave us different sizes after 6709bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French * we already updated max sizes on previous request). 6719bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French * if not then why is the server returning an error now 6729bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French */ 6739bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French if ((chunks_copied != 0) || chunk_sizes_updated) 6749bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French goto cchunk_out; 6759bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French 6769bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French /* Check that server is not asking us to grow size */ 6779bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French if (le32_to_cpu(retbuf->ChunkBytesWritten) < 6789bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French tcon->max_bytes_chunk) 6799bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French tcon->max_bytes_chunk = 6809bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French le32_to_cpu(retbuf->ChunkBytesWritten); 6819bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French else 6829bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French goto cchunk_out; /* server gave us bogus size */ 6839bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French 6849bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French /* No need to change MaxChunks since already set to 1 */ 6859bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French chunk_sizes_updated = true; 6869bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French } 6879bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve French } 68841c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 6899bf0c9cd431440a831e60c0a0fd0bc4f0e083e7fSteve Frenchcchunk_out: 69041c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French kfree(pcchunk); 69141c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French return rc; 69241c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French} 69341c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French 69441c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve Frenchstatic int 6957a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovskysmb2_flush_file(const unsigned int xid, struct cifs_tcon *tcon, 6967a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky struct cifs_fid *fid) 6977a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky{ 6987a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky return SMB2_flush(xid, tcon, fid->persistent_fid, fid->volatile_fid); 6997a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky} 7007a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky 70109a4707e7638247302c6d798061aed117141fb74Pavel Shilovskystatic unsigned int 70209a4707e7638247302c6d798061aed117141fb74Pavel Shilovskysmb2_read_data_offset(char *buf) 70309a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky{ 70409a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf; 70509a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky return rsp->DataOffset; 70609a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky} 70709a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky 70809a4707e7638247302c6d798061aed117141fb74Pavel Shilovskystatic unsigned int 70909a4707e7638247302c6d798061aed117141fb74Pavel Shilovskysmb2_read_data_length(char *buf) 71009a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky{ 71109a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf; 71209a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky return le32_to_cpu(rsp->DataLength); 71309a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky} 71409a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky 715d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky 716d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovskystatic int 717db8b631d4bc4eaa9f7e13a6b0a287306cac0cb72Steve Frenchsmb2_sync_read(const unsigned int xid, struct cifs_fid *pfid, 718d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky struct cifs_io_parms *parms, unsigned int *bytes_read, 719d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky char **buf, int *buf_type) 720d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky{ 721db8b631d4bc4eaa9f7e13a6b0a287306cac0cb72Steve French parms->persistent_fid = pfid->persistent_fid; 722db8b631d4bc4eaa9f7e13a6b0a287306cac0cb72Steve French parms->volatile_fid = pfid->volatile_fid; 723d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky return SMB2_read(xid, parms, bytes_read, buf, buf_type); 724d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky} 725d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky 726009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovskystatic int 727db8b631d4bc4eaa9f7e13a6b0a287306cac0cb72Steve Frenchsmb2_sync_write(const unsigned int xid, struct cifs_fid *pfid, 728009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky struct cifs_io_parms *parms, unsigned int *written, 729009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky struct kvec *iov, unsigned long nr_segs) 730009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky{ 731009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky 732db8b631d4bc4eaa9f7e13a6b0a287306cac0cb72Steve French parms->persistent_fid = pfid->persistent_fid; 733db8b631d4bc4eaa9f7e13a6b0a287306cac0cb72Steve French parms->volatile_fid = pfid->volatile_fid; 734009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky return SMB2_write(xid, parms, written, iov, nr_segs); 735009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky} 736009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky 737d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French/* Set or clear the SPARSE_FILE attribute based on value passed in setsparse */ 738d43cc79343dfabf9f168531d3f5cff313205c8fbSteve Frenchstatic bool smb2_set_sparse(const unsigned int xid, struct cifs_tcon *tcon, 739d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French struct cifsFileInfo *cfile, struct inode *inode, __u8 setsparse) 740d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French{ 741d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French struct cifsInodeInfo *cifsi; 742d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French int rc; 743d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French 744d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French cifsi = CIFS_I(inode); 745d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French 746d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French /* if file already sparse don't bother setting sparse again */ 747d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) && setsparse) 748d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French return true; /* already sparse */ 749d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French 750d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) && !setsparse) 751d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French return true; /* already not sparse */ 752d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French 753d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French /* 754d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French * Can't check for sparse support on share the usual way via the 755d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French * FS attribute info (FILE_SUPPORTS_SPARSE_FILES) on the share 756d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French * since Samba server doesn't set the flag on the share, yet 757d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French * supports the set sparse FSCTL and returns sparse correctly 758d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French * in the file attributes. If we fail setting sparse though we 759d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French * mark that server does not support sparse files for this share 760d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French * to avoid repeatedly sending the unsupported fsctl to server 761d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French * if the file is repeatedly extended. 762d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French */ 763d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French if (tcon->broken_sparse_sup) 764d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French return false; 765d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French 766d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid, 767d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French cfile->fid.volatile_fid, FSCTL_SET_SPARSE, 768d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French true /* is_fctl */, &setsparse, 1, NULL, NULL); 769d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French if (rc) { 770d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French tcon->broken_sparse_sup = true; 771d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French cifs_dbg(FYI, "set sparse rc = %d\n", rc); 772d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French return false; 773d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French } 774d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French 775d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French if (setsparse) 776d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French cifsi->cifsAttrs |= FILE_ATTRIBUTE_SPARSE_FILE; 777d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French else 778d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French cifsi->cifsAttrs &= (~FILE_ATTRIBUTE_SPARSE_FILE); 779d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French 780d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French return true; 781d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French} 782d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French 783c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovskystatic int 784c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovskysmb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon, 785c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky struct cifsFileInfo *cfile, __u64 size, bool set_alloc) 786c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky{ 787c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky __le64 eof = cpu_to_le64(size); 7883d1a3745d8ca7ccdf00905b01fd5ab42ff523a94Steve French struct inode *inode; 7893d1a3745d8ca7ccdf00905b01fd5ab42ff523a94Steve French 7903d1a3745d8ca7ccdf00905b01fd5ab42ff523a94Steve French /* 7913d1a3745d8ca7ccdf00905b01fd5ab42ff523a94Steve French * If extending file more than one page make sparse. Many Linux fs 7923d1a3745d8ca7ccdf00905b01fd5ab42ff523a94Steve French * make files sparse by default when extending via ftruncate 7933d1a3745d8ca7ccdf00905b01fd5ab42ff523a94Steve French */ 7943d1a3745d8ca7ccdf00905b01fd5ab42ff523a94Steve French inode = cfile->dentry->d_inode; 7953d1a3745d8ca7ccdf00905b01fd5ab42ff523a94Steve French 7963d1a3745d8ca7ccdf00905b01fd5ab42ff523a94Steve French if (!set_alloc && (size > inode->i_size + 8192)) { 7973d1a3745d8ca7ccdf00905b01fd5ab42ff523a94Steve French __u8 set_sparse = 1; 798d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French 799d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French /* whether set sparse succeeds or not, extend the file */ 800d43cc79343dfabf9f168531d3f5cff313205c8fbSteve French smb2_set_sparse(xid, tcon, cfile, inode, set_sparse); 8013d1a3745d8ca7ccdf00905b01fd5ab42ff523a94Steve French } 8023d1a3745d8ca7ccdf00905b01fd5ab42ff523a94Steve French 803c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid, 804f29ebb47d5bb59ef246966b047356c03629a9705Steve French cfile->fid.volatile_fid, cfile->pid, &eof, false); 805c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky} 806c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky 807d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskystatic int 80864a5cfa6db94c5abba2cafe77aca077dd1e3283bSteve Frenchsmb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, 80964a5cfa6db94c5abba2cafe77aca077dd1e3283bSteve French struct cifsFileInfo *cfile) 81064a5cfa6db94c5abba2cafe77aca077dd1e3283bSteve French{ 81164a5cfa6db94c5abba2cafe77aca077dd1e3283bSteve French return SMB2_set_compression(xid, tcon, cfile->fid.persistent_fid, 81264a5cfa6db94c5abba2cafe77aca077dd1e3283bSteve French cfile->fid.volatile_fid); 81364a5cfa6db94c5abba2cafe77aca077dd1e3283bSteve French} 81464a5cfa6db94c5abba2cafe77aca077dd1e3283bSteve French 81564a5cfa6db94c5abba2cafe77aca077dd1e3283bSteve Frenchstatic int 816d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskysmb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, 817d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky const char *path, struct cifs_sb_info *cifs_sb, 818d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky struct cifs_fid *fid, __u16 search_flags, 819d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky struct cifs_search_info *srch_inf) 820d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky{ 821d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky __le16 *utf16_path; 822d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky int rc; 8232e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 824064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky struct cifs_open_parms oparms; 825d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky 826d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); 827d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky if (!utf16_path) 828d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky return -ENOMEM; 829d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky 830064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.tcon = tcon; 831064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA; 832064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.disposition = FILE_OPEN; 833064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.create_options = 0; 834064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.fid = fid; 8359cbc0b7339b0542a1d13922d2745a2636ce44853Pavel Shilovsky oparms.reconnect = false; 836064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky 837b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL); 838d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky kfree(utf16_path); 839d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky if (rc) { 840f96637be081141d6f8813429499f164260b49d70Joe Perches cifs_dbg(VFS, "open dir failed\n"); 841d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky return rc; 842d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky } 843d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky 844d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky srch_inf->entries_in_buffer = 0; 845d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky srch_inf->index_of_last_entry = 0; 846d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky 847064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky rc = SMB2_query_directory(xid, tcon, fid->persistent_fid, 848064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky fid->volatile_fid, 0, srch_inf); 849d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky if (rc) { 850f96637be081141d6f8813429499f164260b49d70Joe Perches cifs_dbg(VFS, "query directory failed\n"); 851064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid); 852d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky } 853d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky return rc; 854d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky} 855d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky 856d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskystatic int 857d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskysmb2_query_dir_next(const unsigned int xid, struct cifs_tcon *tcon, 858d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky struct cifs_fid *fid, __u16 search_flags, 859d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky struct cifs_search_info *srch_inf) 860d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky{ 861d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky return SMB2_query_directory(xid, tcon, fid->persistent_fid, 862d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky fid->volatile_fid, 0, srch_inf); 863d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky} 864d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky 865d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskystatic int 866d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovskysmb2_close_dir(const unsigned int xid, struct cifs_tcon *tcon, 867d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky struct cifs_fid *fid) 868d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky{ 869d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky return SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid); 870d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky} 871d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky 8722e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky/* 8732e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky* If we negotiate SMB2 protocol and get STATUS_PENDING - update 8742e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky* the number of credits and return true. Otherwise - return false. 8752e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky*/ 8762e44b2887882134abf353b28867b82645e9f0856Pavel Shilovskystatic bool 8772e44b2887882134abf353b28867b82645e9f0856Pavel Shilovskysmb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length) 8782e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky{ 8792e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky struct smb2_hdr *hdr = (struct smb2_hdr *)buf; 8802e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky 88112e8a20824677fbc24e921d7aebfda6a47cc25b1Steve French if (hdr->Status != STATUS_PENDING) 8822e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky return false; 8832e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky 8842e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky if (!length) { 8852e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky spin_lock(&server->req_lock); 8862e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky server->credits += le16_to_cpu(hdr->CreditRequest); 8872e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky spin_unlock(&server->req_lock); 8882e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky wake_up(&server->request_q); 8892e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky } 8902e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky 8912e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky return true; 8922e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky} 8932e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky 894983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovskystatic int 895983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovskysmb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid, 896983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky struct cifsInodeInfo *cinode) 897983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky{ 8980822f51426b51bd599b3a7e972b14aacaa045a92Pavel Shilovsky if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) 8990822f51426b51bd599b3a7e972b14aacaa045a92Pavel Shilovsky return SMB2_lease_break(0, tcon, cinode->lease_key, 9000822f51426b51bd599b3a7e972b14aacaa045a92Pavel Shilovsky smb2_get_lease_state(cinode)); 9010822f51426b51bd599b3a7e972b14aacaa045a92Pavel Shilovsky 902983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky return SMB2_oplock_break(0, tcon, fid->persistent_fid, 903983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky fid->volatile_fid, 90418cceb6a78f46b65df654e8348fa2093b91b30f6Pavel Shilovsky CIFS_CACHE_READ(cinode) ? 1 : 0); 905983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky} 906983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky 9076fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovskystatic int 9086fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovskysmb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, 9096fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky struct kstatfs *buf) 9106fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky{ 9116fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky int rc; 9126fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky __le16 srch_path = 0; /* Null - open root of share */ 9136fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 914064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky struct cifs_open_parms oparms; 915064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky struct cifs_fid fid; 916064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky 917064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.tcon = tcon; 918064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.desired_access = FILE_READ_ATTRIBUTES; 919064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.disposition = FILE_OPEN; 920064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.create_options = 0; 921064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky oparms.fid = &fid; 9229cbc0b7339b0542a1d13922d2745a2636ce44853Pavel Shilovsky oparms.reconnect = false; 9236fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky 924b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL); 9256fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky if (rc) 9266fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky return rc; 9276fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky buf->f_type = SMB2_MAGIC_NUMBER; 928064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky rc = SMB2_QFS_info(xid, tcon, fid.persistent_fid, fid.volatile_fid, 929064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky buf); 930064f6047a123d61dd52bb44605c999cd8ef727d9Pavel Shilovsky SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 9316fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky return rc; 9326fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky} 9336fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky 934027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovskystatic bool 935027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovskysmb2_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2) 936027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky{ 937027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky return ob1->fid.persistent_fid == ob2->fid.persistent_fid && 938027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky ob1->fid.volatile_fid == ob2->fid.volatile_fid; 939027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky} 940027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky 941f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovskystatic int 942f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovskysmb2_mand_lock(const unsigned int xid, struct cifsFileInfo *cfile, __u64 offset, 943f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky __u64 length, __u32 type, int lock, int unlock, bool wait) 944f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky{ 945f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky if (unlock && !lock) 946f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky type = SMB2_LOCKFLAG_UNLOCK; 947f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky return SMB2_lock(xid, tlink_tcon(cfile->tlink), 948f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky cfile->fid.persistent_fid, cfile->fid.volatile_fid, 949f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky current->tgid, length, offset, type, wait); 950f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky} 951f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky 952b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovskystatic void 953b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovskysmb2_get_lease_key(struct inode *inode, struct cifs_fid *fid) 954b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky{ 955b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky memcpy(fid->lease_key, CIFS_I(inode)->lease_key, SMB2_LEASE_KEY_SIZE); 956b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky} 957b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky 958b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovskystatic void 959b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovskysmb2_set_lease_key(struct inode *inode, struct cifs_fid *fid) 960b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky{ 961b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky memcpy(CIFS_I(inode)->lease_key, fid->lease_key, SMB2_LEASE_KEY_SIZE); 962b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky} 963b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky 964b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovskystatic void 965b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovskysmb2_new_lease_key(struct cifs_fid *fid) 966b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky{ 967b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE); 968b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky} 969b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky 970b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovskystatic int 971b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovskysmb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, 972b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky const char *full_path, char **target_path, 973b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky struct cifs_sb_info *cifs_sb) 974b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky{ 975b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky int rc; 976b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky __le16 *utf16_path; 977b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 978b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky struct cifs_open_parms oparms; 979b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky struct cifs_fid fid; 980b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky struct smb2_err_rsp *err_buf = NULL; 981b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky struct smb2_symlink_err_rsp *symlink; 982b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky unsigned int sub_len, sub_offset; 983b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky 984b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); 985b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky 986b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); 987b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky if (!utf16_path) 988b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky return -ENOMEM; 989b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky 990b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky oparms.tcon = tcon; 991b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky oparms.desired_access = FILE_READ_ATTRIBUTES; 992b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky oparms.disposition = FILE_OPEN; 993b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky oparms.create_options = 0; 994b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky oparms.fid = &fid; 995b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky oparms.reconnect = false; 996b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky 997b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, &err_buf); 998b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky 999b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky if (!rc || !err_buf) { 1000b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky kfree(utf16_path); 1001b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky return -ENOENT; 1002b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky } 1003b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky /* open must fail on symlink - reset rc */ 1004b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky rc = 0; 1005b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData; 1006b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky sub_len = le16_to_cpu(symlink->SubstituteNameLength); 1007b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky sub_offset = le16_to_cpu(symlink->SubstituteNameOffset); 1008b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky *target_path = cifs_strndup_from_utf16( 1009b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky (char *)symlink->PathBuffer + sub_offset, 1010b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky sub_len, true, cifs_sb->local_nls); 1011b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky if (!(*target_path)) { 1012b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky kfree(utf16_path); 1013b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky return -ENOMEM; 1014b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky } 1015b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky convert_delimiter(*target_path, '/'); 1016b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path); 1017b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky kfree(utf16_path); 1018b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky return rc; 1019b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky} 1020b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky 102130175628bf7f521e9ee31ac98fa6d6fe7441a556Steve Frenchstatic long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, 102230175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French loff_t offset, loff_t len, bool keep_size) 102330175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French{ 102430175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French struct inode *inode; 102530175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French struct cifsInodeInfo *cifsi; 102630175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French struct cifsFileInfo *cfile = file->private_data; 102730175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French struct file_zero_data_information fsctl_buf; 102830175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French long rc; 102930175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French unsigned int xid; 103030175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French 103130175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French xid = get_xid(); 103230175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French 103330175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French inode = cfile->dentry->d_inode; 103430175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French cifsi = CIFS_I(inode); 103530175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French 103630175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French /* if file not oplocked can't be sure whether asking to extend size */ 103730175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French if (!CIFS_CACHE_READ(cifsi)) 103830175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French if (keep_size == false) 103930175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French return -EOPNOTSUPP; 104030175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French 10412bb93d244157b6dfa4964d4088be4680b3169701Steve French /* 104230175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French * Must check if file sparse since fallocate -z (zero range) assumes 104330175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French * non-sparse allocation 104430175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French */ 104530175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE)) 104630175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French return -EOPNOTSUPP; 104730175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French 104830175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French /* 104930175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French * need to make sure we are not asked to extend the file since the SMB3 105030175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French * fsctl does not change the file size. In the future we could change 105130175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French * this to zero the first part of the range then set the file size 105230175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French * which for a non sparse file would zero the newly extended range 105330175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French */ 105430175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French if (keep_size == false) 105530175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French if (i_size_read(inode) < offset + len) 105630175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French return -EOPNOTSUPP; 105730175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French 105830175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French cifs_dbg(FYI, "offset %lld len %lld", offset, len); 105930175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French 106030175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French fsctl_buf.FileOffset = cpu_to_le64(offset); 106130175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len); 106230175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French 106330175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid, 106430175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French cfile->fid.volatile_fid, FSCTL_SET_ZERO_DATA, 106530175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French true /* is_fctl */, (char *)&fsctl_buf, 106630175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French sizeof(struct file_zero_data_information), NULL, NULL); 106730175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French free_xid(xid); 106830175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French return rc; 106930175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French} 107030175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French 107131742c5a331766bc7df6b0d525df00c6cd20d5a6Steve Frenchstatic long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon, 107231742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French loff_t offset, loff_t len) 107331742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French{ 107431742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French struct inode *inode; 107531742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French struct cifsInodeInfo *cifsi; 107631742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French struct cifsFileInfo *cfile = file->private_data; 107731742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French struct file_zero_data_information fsctl_buf; 107831742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French long rc; 107931742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French unsigned int xid; 108031742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French __u8 set_sparse = 1; 108131742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French 108231742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French xid = get_xid(); 108331742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French 108431742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French inode = cfile->dentry->d_inode; 108531742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French cifsi = CIFS_I(inode); 108631742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French 108731742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French /* Need to make file sparse, if not already, before freeing range. */ 108831742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French /* Consider adding equivalent for compressed since it could also work */ 108931742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French if (!smb2_set_sparse(xid, tcon, cfile, inode, set_sparse)) 109031742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French return -EOPNOTSUPP; 109131742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French 109231742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French cifs_dbg(FYI, "offset %lld len %lld", offset, len); 109331742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French 109431742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French fsctl_buf.FileOffset = cpu_to_le64(offset); 109531742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len); 109631742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French 109731742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid, 109831742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French cfile->fid.volatile_fid, FSCTL_SET_ZERO_DATA, 109931742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French true /* is_fctl */, (char *)&fsctl_buf, 110031742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French sizeof(struct file_zero_data_information), NULL, NULL); 110131742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French free_xid(xid); 110231742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French return rc; 110331742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French} 110431742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French 110531742c5a331766bc7df6b0d525df00c6cd20d5a6Steve Frenchstatic long smb3_fallocate(struct file *file, struct cifs_tcon *tcon, int mode, 110631742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French loff_t off, loff_t len) 110731742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French{ 110831742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French /* KEEP_SIZE already checked for by do_fallocate */ 110931742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French if (mode & FALLOC_FL_PUNCH_HOLE) 111031742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French return smb3_punch_hole(file, tcon, off, len); 111130175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French else if (mode & FALLOC_FL_ZERO_RANGE) { 111230175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French if (mode & FALLOC_FL_KEEP_SIZE) 111330175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French return smb3_zero_range(file, tcon, off, len, true); 111430175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French return smb3_zero_range(file, tcon, off, len, false); 111530175628bf7f521e9ee31ac98fa6d6fe7441a556Steve French } 111631742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French 111731742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French return -EOPNOTSUPP; 111831742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French} 111931742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French 112053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskystatic void 1121c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhusmb2_downgrade_oplock(struct TCP_Server_Info *server, 1122c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhu struct cifsInodeInfo *cinode, bool set_level2) 1123c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhu{ 1124c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhu if (set_level2) 1125c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhu server->ops->set_oplock_level(cinode, SMB2_OPLOCK_LEVEL_II, 1126c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhu 0, NULL); 1127c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhu else 1128c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhu server->ops->set_oplock_level(cinode, 0, 0, NULL); 1129c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhu} 1130c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhu 1131c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhustatic void 113242873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovskysmb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, 113342873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky unsigned int epoch, bool *purge_cache) 113453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky{ 113553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky oplock &= 0xFF; 113653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE) 113753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky return; 113853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky if (oplock == SMB2_OPLOCK_LEVEL_BATCH) { 113942873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky cinode->oplock = CIFS_CACHE_RHW_FLG; 114053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky cifs_dbg(FYI, "Batch Oplock granted on inode %p\n", 114153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky &cinode->vfs_inode); 114253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky } else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) { 114342873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky cinode->oplock = CIFS_CACHE_RW_FLG; 114453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n", 114553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky &cinode->vfs_inode); 114653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky } else if (oplock == SMB2_OPLOCK_LEVEL_II) { 114753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky cinode->oplock = CIFS_CACHE_READ_FLG; 114853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky cifs_dbg(FYI, "Level II Oplock granted on inode %p\n", 114953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky &cinode->vfs_inode); 115053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky } else 115153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky cinode->oplock = 0; 115253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky} 115353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky 115453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskystatic void 115542873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovskysmb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, 115642873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky unsigned int epoch, bool *purge_cache) 115753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky{ 115853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky char message[5] = {0}; 115953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky 116053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky oplock &= 0xFF; 116153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE) 116253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky return; 116353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky 116453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky cinode->oplock = 0; 116553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky if (oplock & SMB2_LEASE_READ_CACHING_HE) { 116653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky cinode->oplock |= CIFS_CACHE_READ_FLG; 116753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky strcat(message, "R"); 116853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky } 116953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky if (oplock & SMB2_LEASE_HANDLE_CACHING_HE) { 117053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky cinode->oplock |= CIFS_CACHE_HANDLE_FLG; 117153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky strcat(message, "H"); 117253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky } 117353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky if (oplock & SMB2_LEASE_WRITE_CACHING_HE) { 117453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky cinode->oplock |= CIFS_CACHE_WRITE_FLG; 117553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky strcat(message, "W"); 117653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky } 117753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky if (!cinode->oplock) 117853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky strcat(message, "None"); 117953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky cifs_dbg(FYI, "%s Lease granted on inode %p\n", message, 118053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky &cinode->vfs_inode); 118153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky} 118253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky 118342873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovskystatic void 118442873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovskysmb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, 118542873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky unsigned int epoch, bool *purge_cache) 118642873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky{ 118742873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky unsigned int old_oplock = cinode->oplock; 118842873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky 118942873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky smb21_set_oplock_level(cinode, oplock, epoch, purge_cache); 119042873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky 119142873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky if (purge_cache) { 119242873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky *purge_cache = false; 119342873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky if (old_oplock == CIFS_CACHE_READ_FLG) { 119442873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky if (cinode->oplock == CIFS_CACHE_READ_FLG && 119542873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky (epoch - cinode->epoch > 0)) 119642873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky *purge_cache = true; 119742873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky else if (cinode->oplock == CIFS_CACHE_RH_FLG && 119842873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky (epoch - cinode->epoch > 1)) 119942873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky *purge_cache = true; 120042873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky else if (cinode->oplock == CIFS_CACHE_RHW_FLG && 120142873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky (epoch - cinode->epoch > 1)) 120242873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky *purge_cache = true; 120342873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky else if (cinode->oplock == 0 && 120442873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky (epoch - cinode->epoch > 0)) 120542873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky *purge_cache = true; 120642873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky } else if (old_oplock == CIFS_CACHE_RH_FLG) { 120742873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky if (cinode->oplock == CIFS_CACHE_RH_FLG && 120842873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky (epoch - cinode->epoch > 0)) 120942873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky *purge_cache = true; 121042873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky else if (cinode->oplock == CIFS_CACHE_RHW_FLG && 121142873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky (epoch - cinode->epoch > 1)) 121242873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky *purge_cache = true; 121342873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky } 121442873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky cinode->epoch = epoch; 121542873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky } 121642873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky} 121742873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky 121853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskystatic bool 121953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskysmb2_is_read_op(__u32 oplock) 122053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky{ 122153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky return oplock == SMB2_OPLOCK_LEVEL_II; 122253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky} 122353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky 122453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskystatic bool 122553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskysmb21_is_read_op(__u32 oplock) 122653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky{ 122753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky return (oplock & SMB2_LEASE_READ_CACHING_HE) && 122853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky !(oplock & SMB2_LEASE_WRITE_CACHING_HE); 122953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky} 123053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky 1231f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovskystatic __le32 1232f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovskymap_oplock_to_lease(u8 oplock) 1233f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky{ 1234f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) 1235f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING; 1236f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky else if (oplock == SMB2_OPLOCK_LEVEL_II) 1237f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky return SMB2_LEASE_READ_CACHING; 1238f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky else if (oplock == SMB2_OPLOCK_LEVEL_BATCH) 1239f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky return SMB2_LEASE_HANDLE_CACHING | SMB2_LEASE_READ_CACHING | 1240f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky SMB2_LEASE_WRITE_CACHING; 1241f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky return 0; 1242f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky} 1243f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky 1244a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovskystatic char * 1245a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovskysmb2_create_lease_buf(u8 *lease_key, u8 oplock) 1246a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky{ 1247a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky struct create_lease *buf; 1248a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky 1249a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky buf = kzalloc(sizeof(struct create_lease), GFP_KERNEL); 1250a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky if (!buf) 1251a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky return NULL; 1252a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky 1253a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key)); 1254a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8))); 1255f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf->lcontext.LeaseState = map_oplock_to_lease(oplock); 1256a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky 1257a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky buf->ccontext.DataOffset = cpu_to_le16(offsetof 1258a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky (struct create_lease, lcontext)); 1259a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context)); 1260a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky buf->ccontext.NameOffset = cpu_to_le16(offsetof 1261a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky (struct create_lease, Name)); 1262a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky buf->ccontext.NameLength = cpu_to_le16(4); 126312197a7fdda9f7db18657f907e531318fefc4a68Steve French /* SMB2_CREATE_REQUEST_LEASE is "RqLs" */ 1264a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky buf->Name[0] = 'R'; 1265a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky buf->Name[1] = 'q'; 1266a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky buf->Name[2] = 'L'; 1267a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky buf->Name[3] = 's'; 1268a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky return (char *)buf; 1269a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky} 1270a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky 1271f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovskystatic char * 1272f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovskysmb3_create_lease_buf(u8 *lease_key, u8 oplock) 1273f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky{ 1274f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky struct create_lease_v2 *buf; 1275f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky 1276f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf = kzalloc(sizeof(struct create_lease_v2), GFP_KERNEL); 1277f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky if (!buf) 1278f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky return NULL; 1279f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky 1280f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key)); 1281f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8))); 1282f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf->lcontext.LeaseState = map_oplock_to_lease(oplock); 1283f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky 1284f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf->ccontext.DataOffset = cpu_to_le16(offsetof 1285f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky (struct create_lease_v2, lcontext)); 1286f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2)); 1287f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf->ccontext.NameOffset = cpu_to_le16(offsetof 1288f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky (struct create_lease_v2, Name)); 1289f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf->ccontext.NameLength = cpu_to_le16(4); 129012197a7fdda9f7db18657f907e531318fefc4a68Steve French /* SMB2_CREATE_REQUEST_LEASE is "RqLs" */ 1291f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf->Name[0] = 'R'; 1292f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf->Name[1] = 'q'; 1293f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf->Name[2] = 'L'; 1294f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky buf->Name[3] = 's'; 1295f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky return (char *)buf; 1296f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky} 1297f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky 1298b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovskystatic __u8 129942873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovskysmb2_parse_lease_buf(void *buf, unsigned int *epoch) 1300b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky{ 1301b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky struct create_lease *lc = (struct create_lease *)buf; 1302b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky 130342873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky *epoch = 0; /* not used */ 1304b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS) 1305b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky return SMB2_OPLOCK_LEVEL_NOCHANGE; 1306b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky return le32_to_cpu(lc->lcontext.LeaseState); 1307b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky} 1308b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky 1309f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovskystatic __u8 131042873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovskysmb3_parse_lease_buf(void *buf, unsigned int *epoch) 1311f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky{ 1312f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky struct create_lease_v2 *lc = (struct create_lease_v2 *)buf; 1313f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky 131442873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky *epoch = le16_to_cpu(lc->lcontext.Epoch); 1315f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS) 1316f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky return SMB2_OPLOCK_LEVEL_NOCHANGE; 1317f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky return le32_to_cpu(lc->lcontext.LeaseState); 1318f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky} 1319f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky 13207f6c50086a6f5bc0fee46548afc836070a439313Pavel Shilovskystatic unsigned int 13217f6c50086a6f5bc0fee46548afc836070a439313Pavel Shilovskysmb2_wp_retry_size(struct inode *inode) 13227f6c50086a6f5bc0fee46548afc836070a439313Pavel Shilovsky{ 13237f6c50086a6f5bc0fee46548afc836070a439313Pavel Shilovsky return min_t(unsigned int, CIFS_SB(inode->i_sb)->wsize, 13247f6c50086a6f5bc0fee46548afc836070a439313Pavel Shilovsky SMB2_MAX_BUFFER_SIZE); 13257f6c50086a6f5bc0fee46548afc836070a439313Pavel Shilovsky} 13267f6c50086a6f5bc0fee46548afc836070a439313Pavel Shilovsky 132752755808d4525f4d5b86d112d36ffc7a46f3fb48Pavel Shilovskystatic bool 132852755808d4525f4d5b86d112d36ffc7a46f3fb48Pavel Shilovskysmb2_dir_needs_close(struct cifsFileInfo *cfile) 132952755808d4525f4d5b86d112d36ffc7a46f3fb48Pavel Shilovsky{ 133052755808d4525f4d5b86d112d36ffc7a46f3fb48Pavel Shilovsky return !cfile->invalidHandle; 133152755808d4525f4d5b86d112d36ffc7a46f3fb48Pavel Shilovsky} 133252755808d4525f4d5b86d112d36ffc7a46f3fb48Pavel Shilovsky 133353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskystruct smb_version_operations smb20_operations = { 1334027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky .compare_fids = smb2_compare_fids, 13352dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky .setup_request = smb2_setup_request, 1336c95b8eeda3efcb419ea0a3f864cf99e32c038c21Pavel Shilovsky .setup_async_request = smb2_setup_async_request, 13372dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky .check_receive = smb2_check_receive, 133828ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky .add_credits = smb2_add_credits, 133928ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky .set_credits = smb2_set_credits, 134028ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky .get_credits_field = smb2_get_credits_field, 134128ea5290d78a7fc87a4b4f7cedcaa662f5b8d977Pavel Shilovsky .get_credits = smb2_get_credits, 1342cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky .wait_mtu_credits = cifs_wait_mtu_credits, 13432dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky .get_next_mid = smb2_get_next_mid, 134409a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky .read_data_offset = smb2_read_data_offset, 134509a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky .read_data_length = smb2_read_data_length, 134609a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky .map_error = map_smb2_to_linux_error, 1347093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky .find_mid = smb2_find_mid, 1348093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky .check_message = smb2_check_message, 1349093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky .dump_detail = smb2_dump_detail, 1350d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky .clear_stats = smb2_clear_stats, 1351d60622eb5a23904facf4a4efac60f5bfa810d7d4Pavel Shilovsky .print_stats = smb2_print_stats, 1352983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky .is_oplock_break = smb2_is_valid_oplock_break, 1353c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhu .downgrade_oplock = smb2_downgrade_oplock, 1354ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky .need_neg = smb2_need_neg, 1355ec2e4523fdba88317e06d0c7a88af3a0860447fcPavel Shilovsky .negotiate = smb2_negotiate, 13563a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky .negotiate_wsize = smb2_negotiate_wsize, 13573a3bab509f3f0e7295caab24e9102ce303edb50bPavel Shilovsky .negotiate_rsize = smb2_negotiate_rsize, 13585478f9ba9a34d660eb3227dcd16314689c51f946Pavel Shilovsky .sess_setup = SMB2_sess_setup, 13595478f9ba9a34d660eb3227dcd16314689c51f946Pavel Shilovsky .logoff = SMB2_logoff, 1360faaf946a7d5b79194358437150f34ab4c66bfe21Pavel Shilovsky .tree_connect = SMB2_tcon, 1361faaf946a7d5b79194358437150f34ab4c66bfe21Pavel Shilovsky .tree_disconnect = SMB2_tdis, 136234f626406c09dd45878ce75170abab342985ec24Steve French .qfs_tcon = smb2_qfs_tcon, 13632503a0dba989486c59523a947a1dcb50ad90fee9Pavel Shilovsky .is_path_accessible = smb2_is_path_accessible, 13649094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky .can_echo = smb2_can_echo, 13659094fad1ed90caebd25b1bdec3c8982d079356eePavel Shilovsky .echo = SMB2_echo, 1366be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky .query_path_info = smb2_query_path_info, 1367be4cb9e3d4ef7af1aaf66cebab1391ff91b48bebPavel Shilovsky .get_srv_inum = smb2_get_srv_inum, 1368b7546bc54c4acf1a79c83030fa0591cd24875125Pavel Shilovsky .query_file_info = smb2_query_file_info, 1369c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky .set_path_size = smb2_set_path_size, 1370c839ff244ba2d54d0933596e29a4b03e3c846a9aPavel Shilovsky .set_file_size = smb2_set_file_size, 13711feeaac753e0a9b3864740556b7840643642abdbPavel Shilovsky .set_file_info = smb2_set_file_info, 137264a5cfa6db94c5abba2cafe77aca077dd1e3283bSteve French .set_compression = smb2_set_compression, 1373a0e731839dd461eee0fe2dc026e0965e961e2730Pavel Shilovsky .mkdir = smb2_mkdir, 1374a0e731839dd461eee0fe2dc026e0965e961e2730Pavel Shilovsky .mkdir_setinfo = smb2_mkdir_setinfo, 13751a500f010fb2d121c58f77ddfde2eca1bde3bfcdPavel Shilovsky .rmdir = smb2_rmdir, 1376cbe6f439f5762c7fb4d2dd9293f5fdbfc4cd68f8Pavel Shilovsky .unlink = smb2_unlink, 137735143eb5c2e3ae6c91b29144449d23f05f573796Pavel Shilovsky .rename = smb2_rename_path, 1378568798cc6211553e2494a6876fa19d064c822e79Pavel Shilovsky .create_hardlink = smb2_create_hardlink, 1379b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky .query_symlink = smb2_query_symlink, 1380f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky .open = smb2_open_file, 1381f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky .set_fid = smb2_set_fid, 1382f0df737ee820ec62055baf2b28e24db4fb1ad71dPavel Shilovsky .close = smb2_close_file, 13837a5cfb1965854132f2f382eade8c6ce2eeb6f692Pavel Shilovsky .flush = smb2_flush_file, 138409a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky .async_readv = smb2_async_readv, 138533319141252fd14b58cf13685156c23dcaac2527Pavel Shilovsky .async_writev = smb2_async_writev, 1386d8e050398d23ef7c019c96200b80d73f4e5cec0cPavel Shilovsky .sync_read = smb2_sync_read, 1387009d344398bb3e844b31eb9e6a7860748c6f6dd3Pavel Shilovsky .sync_write = smb2_sync_write, 1388d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky .query_dir_first = smb2_query_dir_first, 1389d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky .query_dir_next = smb2_query_dir_next, 1390d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky .close_dir = smb2_close_dir, 1391d324f08d6a87149597817f4496ef0f7ac185e8daPavel Shilovsky .calc_smb_size = smb2_calc_size, 13922e44b2887882134abf353b28867b82645e9f0856Pavel Shilovsky .is_status_pending = smb2_is_status_pending, 1393983c88a497914d60c91f431b05a8449ddda19167Pavel Shilovsky .oplock_response = smb2_oplock_response, 13946fc05c25ca35e65ee1759dd803f23576a268f5ecPavel Shilovsky .queryfs = smb2_queryfs, 1395f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky .mand_lock = smb2_mand_lock, 1396f7ba7fe685bc3ed8fd0687870e68b2567d17357fPavel Shilovsky .mand_unlock_range = smb2_unlock_range, 1397b140799a11adb6023d5f96712874c37b71dab290Pavel Shilovsky .push_mand_locks = smb2_push_mandatory_locks, 1398b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky .get_lease_key = smb2_get_lease_key, 1399b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky .set_lease_key = smb2_set_lease_key, 1400b8c32dbb0deb287a5fcb78251e4eae6c7275760dPavel Shilovsky .new_lease_key = smb2_new_lease_key, 140138107d45cf452761a74fe512190e23f36834d6ddSteve French .calc_signature = smb2_calc_signature, 140253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .is_read_op = smb2_is_read_op, 140353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .set_oplock_level = smb2_set_oplock_level, 1404a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky .create_lease_buf = smb2_create_lease_buf, 1405b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky .parse_lease_buf = smb2_parse_lease_buf, 140641c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French .clone_range = smb2_clone_range, 14077f6c50086a6f5bc0fee46548afc836070a439313Pavel Shilovsky .wp_retry_size = smb2_wp_retry_size, 140852755808d4525f4d5b86d112d36ffc7a46f3fb48Pavel Shilovsky .dir_needs_close = smb2_dir_needs_close, 140938107d45cf452761a74fe512190e23f36834d6ddSteve French}; 141038107d45cf452761a74fe512190e23f36834d6ddSteve French 141153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovskystruct smb_version_operations smb21_operations = { 141253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .compare_fids = smb2_compare_fids, 141353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .setup_request = smb2_setup_request, 141453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .setup_async_request = smb2_setup_async_request, 141553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .check_receive = smb2_check_receive, 141653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .add_credits = smb2_add_credits, 141753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .set_credits = smb2_set_credits, 141853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .get_credits_field = smb2_get_credits_field, 141953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .get_credits = smb2_get_credits, 1420cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky .wait_mtu_credits = smb2_wait_mtu_credits, 142153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .get_next_mid = smb2_get_next_mid, 142253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .read_data_offset = smb2_read_data_offset, 142353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .read_data_length = smb2_read_data_length, 142453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .map_error = map_smb2_to_linux_error, 142553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .find_mid = smb2_find_mid, 142653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .check_message = smb2_check_message, 142753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .dump_detail = smb2_dump_detail, 142853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .clear_stats = smb2_clear_stats, 142953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .print_stats = smb2_print_stats, 143053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .is_oplock_break = smb2_is_valid_oplock_break, 1431c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhu .downgrade_oplock = smb2_downgrade_oplock, 143253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .need_neg = smb2_need_neg, 143353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .negotiate = smb2_negotiate, 143453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .negotiate_wsize = smb2_negotiate_wsize, 143553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .negotiate_rsize = smb2_negotiate_rsize, 143653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .sess_setup = SMB2_sess_setup, 143753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .logoff = SMB2_logoff, 143853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .tree_connect = SMB2_tcon, 143953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .tree_disconnect = SMB2_tdis, 144034f626406c09dd45878ce75170abab342985ec24Steve French .qfs_tcon = smb2_qfs_tcon, 144153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .is_path_accessible = smb2_is_path_accessible, 144253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .can_echo = smb2_can_echo, 144353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .echo = SMB2_echo, 144453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .query_path_info = smb2_query_path_info, 144553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .get_srv_inum = smb2_get_srv_inum, 144653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .query_file_info = smb2_query_file_info, 144753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .set_path_size = smb2_set_path_size, 144853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .set_file_size = smb2_set_file_size, 144953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .set_file_info = smb2_set_file_info, 145064a5cfa6db94c5abba2cafe77aca077dd1e3283bSteve French .set_compression = smb2_set_compression, 145153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .mkdir = smb2_mkdir, 145253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .mkdir_setinfo = smb2_mkdir_setinfo, 145353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .rmdir = smb2_rmdir, 145453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .unlink = smb2_unlink, 145553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .rename = smb2_rename_path, 145653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .create_hardlink = smb2_create_hardlink, 145753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .query_symlink = smb2_query_symlink, 1458c22870ea2deb2841402133909cfa707a2c0b12edSteve French .query_mf_symlink = smb3_query_mf_symlink, 14595ab97578cbb3bf9a28dec4534cb86fbc35e600bbSteve French .create_mf_symlink = smb3_create_mf_symlink, 146053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .open = smb2_open_file, 146153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .set_fid = smb2_set_fid, 146253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .close = smb2_close_file, 146353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .flush = smb2_flush_file, 146453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .async_readv = smb2_async_readv, 146553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .async_writev = smb2_async_writev, 146653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .sync_read = smb2_sync_read, 146753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .sync_write = smb2_sync_write, 146853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .query_dir_first = smb2_query_dir_first, 146953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .query_dir_next = smb2_query_dir_next, 147053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .close_dir = smb2_close_dir, 147153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .calc_smb_size = smb2_calc_size, 147253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .is_status_pending = smb2_is_status_pending, 147353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .oplock_response = smb2_oplock_response, 147453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .queryfs = smb2_queryfs, 147553ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .mand_lock = smb2_mand_lock, 147653ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .mand_unlock_range = smb2_unlock_range, 147753ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .push_mand_locks = smb2_push_mandatory_locks, 147853ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .get_lease_key = smb2_get_lease_key, 147953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .set_lease_key = smb2_set_lease_key, 148053ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .new_lease_key = smb2_new_lease_key, 148153ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .calc_signature = smb2_calc_signature, 148253ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .is_read_op = smb21_is_read_op, 148353ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .set_oplock_level = smb21_set_oplock_level, 1484a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky .create_lease_buf = smb2_create_lease_buf, 1485b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2Pavel Shilovsky .parse_lease_buf = smb2_parse_lease_buf, 148641c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French .clone_range = smb2_clone_range, 14877f6c50086a6f5bc0fee46548afc836070a439313Pavel Shilovsky .wp_retry_size = smb2_wp_retry_size, 148852755808d4525f4d5b86d112d36ffc7a46f3fb48Pavel Shilovsky .dir_needs_close = smb2_dir_needs_close, 148953ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky}; 149038107d45cf452761a74fe512190e23f36834d6ddSteve French 149138107d45cf452761a74fe512190e23f36834d6ddSteve Frenchstruct smb_version_operations smb30_operations = { 149238107d45cf452761a74fe512190e23f36834d6ddSteve French .compare_fids = smb2_compare_fids, 149338107d45cf452761a74fe512190e23f36834d6ddSteve French .setup_request = smb2_setup_request, 149438107d45cf452761a74fe512190e23f36834d6ddSteve French .setup_async_request = smb2_setup_async_request, 149538107d45cf452761a74fe512190e23f36834d6ddSteve French .check_receive = smb2_check_receive, 149638107d45cf452761a74fe512190e23f36834d6ddSteve French .add_credits = smb2_add_credits, 149738107d45cf452761a74fe512190e23f36834d6ddSteve French .set_credits = smb2_set_credits, 149838107d45cf452761a74fe512190e23f36834d6ddSteve French .get_credits_field = smb2_get_credits_field, 149938107d45cf452761a74fe512190e23f36834d6ddSteve French .get_credits = smb2_get_credits, 1500cb7e9eabb2b584884db0d11ae0376d31ac1cfdc1Pavel Shilovsky .wait_mtu_credits = smb2_wait_mtu_credits, 150138107d45cf452761a74fe512190e23f36834d6ddSteve French .get_next_mid = smb2_get_next_mid, 150238107d45cf452761a74fe512190e23f36834d6ddSteve French .read_data_offset = smb2_read_data_offset, 150338107d45cf452761a74fe512190e23f36834d6ddSteve French .read_data_length = smb2_read_data_length, 150438107d45cf452761a74fe512190e23f36834d6ddSteve French .map_error = map_smb2_to_linux_error, 150538107d45cf452761a74fe512190e23f36834d6ddSteve French .find_mid = smb2_find_mid, 150638107d45cf452761a74fe512190e23f36834d6ddSteve French .check_message = smb2_check_message, 150738107d45cf452761a74fe512190e23f36834d6ddSteve French .dump_detail = smb2_dump_detail, 150838107d45cf452761a74fe512190e23f36834d6ddSteve French .clear_stats = smb2_clear_stats, 150938107d45cf452761a74fe512190e23f36834d6ddSteve French .print_stats = smb2_print_stats, 1510769ee6a4024434d1960acafd7adde38538bbe3daSteve French .dump_share_caps = smb2_dump_share_caps, 151138107d45cf452761a74fe512190e23f36834d6ddSteve French .is_oplock_break = smb2_is_valid_oplock_break, 1512c11f1df5003d534fd067f0168bfad7befffb3b5cSachin Prabhu .downgrade_oplock = smb2_downgrade_oplock, 151338107d45cf452761a74fe512190e23f36834d6ddSteve French .need_neg = smb2_need_neg, 151438107d45cf452761a74fe512190e23f36834d6ddSteve French .negotiate = smb2_negotiate, 151538107d45cf452761a74fe512190e23f36834d6ddSteve French .negotiate_wsize = smb2_negotiate_wsize, 151638107d45cf452761a74fe512190e23f36834d6ddSteve French .negotiate_rsize = smb2_negotiate_rsize, 151738107d45cf452761a74fe512190e23f36834d6ddSteve French .sess_setup = SMB2_sess_setup, 151838107d45cf452761a74fe512190e23f36834d6ddSteve French .logoff = SMB2_logoff, 151938107d45cf452761a74fe512190e23f36834d6ddSteve French .tree_connect = SMB2_tcon, 152038107d45cf452761a74fe512190e23f36834d6ddSteve French .tree_disconnect = SMB2_tdis, 1521af6a12ea8d4bb39a87527835b943bde4215897e5Steven French .qfs_tcon = smb3_qfs_tcon, 152238107d45cf452761a74fe512190e23f36834d6ddSteve French .is_path_accessible = smb2_is_path_accessible, 152338107d45cf452761a74fe512190e23f36834d6ddSteve French .can_echo = smb2_can_echo, 152438107d45cf452761a74fe512190e23f36834d6ddSteve French .echo = SMB2_echo, 152538107d45cf452761a74fe512190e23f36834d6ddSteve French .query_path_info = smb2_query_path_info, 152638107d45cf452761a74fe512190e23f36834d6ddSteve French .get_srv_inum = smb2_get_srv_inum, 152738107d45cf452761a74fe512190e23f36834d6ddSteve French .query_file_info = smb2_query_file_info, 152838107d45cf452761a74fe512190e23f36834d6ddSteve French .set_path_size = smb2_set_path_size, 152938107d45cf452761a74fe512190e23f36834d6ddSteve French .set_file_size = smb2_set_file_size, 153038107d45cf452761a74fe512190e23f36834d6ddSteve French .set_file_info = smb2_set_file_info, 153164a5cfa6db94c5abba2cafe77aca077dd1e3283bSteve French .set_compression = smb2_set_compression, 153238107d45cf452761a74fe512190e23f36834d6ddSteve French .mkdir = smb2_mkdir, 153338107d45cf452761a74fe512190e23f36834d6ddSteve French .mkdir_setinfo = smb2_mkdir_setinfo, 153438107d45cf452761a74fe512190e23f36834d6ddSteve French .rmdir = smb2_rmdir, 153538107d45cf452761a74fe512190e23f36834d6ddSteve French .unlink = smb2_unlink, 153638107d45cf452761a74fe512190e23f36834d6ddSteve French .rename = smb2_rename_path, 153738107d45cf452761a74fe512190e23f36834d6ddSteve French .create_hardlink = smb2_create_hardlink, 1538b42bf88828cde60772dc08201d0a4f1a0663d7bcPavel Shilovsky .query_symlink = smb2_query_symlink, 1539c22870ea2deb2841402133909cfa707a2c0b12edSteve French .query_mf_symlink = smb3_query_mf_symlink, 15405ab97578cbb3bf9a28dec4534cb86fbc35e600bbSteve French .create_mf_symlink = smb3_create_mf_symlink, 154138107d45cf452761a74fe512190e23f36834d6ddSteve French .open = smb2_open_file, 154238107d45cf452761a74fe512190e23f36834d6ddSteve French .set_fid = smb2_set_fid, 154338107d45cf452761a74fe512190e23f36834d6ddSteve French .close = smb2_close_file, 154438107d45cf452761a74fe512190e23f36834d6ddSteve French .flush = smb2_flush_file, 154538107d45cf452761a74fe512190e23f36834d6ddSteve French .async_readv = smb2_async_readv, 154638107d45cf452761a74fe512190e23f36834d6ddSteve French .async_writev = smb2_async_writev, 154738107d45cf452761a74fe512190e23f36834d6ddSteve French .sync_read = smb2_sync_read, 154838107d45cf452761a74fe512190e23f36834d6ddSteve French .sync_write = smb2_sync_write, 154938107d45cf452761a74fe512190e23f36834d6ddSteve French .query_dir_first = smb2_query_dir_first, 155038107d45cf452761a74fe512190e23f36834d6ddSteve French .query_dir_next = smb2_query_dir_next, 155138107d45cf452761a74fe512190e23f36834d6ddSteve French .close_dir = smb2_close_dir, 155238107d45cf452761a74fe512190e23f36834d6ddSteve French .calc_smb_size = smb2_calc_size, 155338107d45cf452761a74fe512190e23f36834d6ddSteve French .is_status_pending = smb2_is_status_pending, 155438107d45cf452761a74fe512190e23f36834d6ddSteve French .oplock_response = smb2_oplock_response, 155538107d45cf452761a74fe512190e23f36834d6ddSteve French .queryfs = smb2_queryfs, 155638107d45cf452761a74fe512190e23f36834d6ddSteve French .mand_lock = smb2_mand_lock, 155738107d45cf452761a74fe512190e23f36834d6ddSteve French .mand_unlock_range = smb2_unlock_range, 155838107d45cf452761a74fe512190e23f36834d6ddSteve French .push_mand_locks = smb2_push_mandatory_locks, 155938107d45cf452761a74fe512190e23f36834d6ddSteve French .get_lease_key = smb2_get_lease_key, 156038107d45cf452761a74fe512190e23f36834d6ddSteve French .set_lease_key = smb2_set_lease_key, 156138107d45cf452761a74fe512190e23f36834d6ddSteve French .new_lease_key = smb2_new_lease_key, 1562e65a5cb41718e0eb17a470bc3acf2c3b2f00f1d0Steve French .generate_signingkey = generate_smb3signingkey, 156338107d45cf452761a74fe512190e23f36834d6ddSteve French .calc_signature = smb3_calc_signature, 156453ef1016fd0e4bab128a24f7fe06b9cdb2afdc31Pavel Shilovsky .is_read_op = smb21_is_read_op, 156542873b0a282ac84a56e0e48c408beb62d0ad2917Pavel Shilovsky .set_oplock_level = smb3_set_oplock_level, 1566f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky .create_lease_buf = smb3_create_lease_buf, 1567f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky .parse_lease_buf = smb3_parse_lease_buf, 156841c1358e9181ab1ebd773905b3fa8039b61aa0e9Steve French .clone_range = smb2_clone_range, 1569ff1c038addc4f205d5f1ede449426c7d316c0eedSteve French .validate_negotiate = smb3_validate_negotiate, 15707f6c50086a6f5bc0fee46548afc836070a439313Pavel Shilovsky .wp_retry_size = smb2_wp_retry_size, 157152755808d4525f4d5b86d112d36ffc7a46f3fb48Pavel Shilovsky .dir_needs_close = smb2_dir_needs_close, 157231742c5a331766bc7df6b0d525df00c6cd20d5a6Steve French .fallocate = smb3_fallocate, 15731080ef758fb87f286b25277d8373e680a9e73363Steve French}; 15741080ef758fb87f286b25277d8373e680a9e73363Steve French 1575dd446b16edd74ca525208d924d426f786dd973f8Steve Frenchstruct smb_version_values smb20_values = { 1576dd446b16edd74ca525208d924d426f786dd973f8Steve French .version_string = SMB20_VERSION_STRING, 1577dd446b16edd74ca525208d924d426f786dd973f8Steve French .protocol_id = SMB20_PROT_ID, 1578dd446b16edd74ca525208d924d426f786dd973f8Steve French .req_capabilities = 0, /* MBZ */ 1579dd446b16edd74ca525208d924d426f786dd973f8Steve French .large_lock_type = 0, 1580dd446b16edd74ca525208d924d426f786dd973f8Steve French .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, 1581dd446b16edd74ca525208d924d426f786dd973f8Steve French .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, 1582dd446b16edd74ca525208d924d426f786dd973f8Steve French .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, 1583dd446b16edd74ca525208d924d426f786dd973f8Steve French .header_size = sizeof(struct smb2_hdr), 1584dd446b16edd74ca525208d924d426f786dd973f8Steve French .max_header_size = MAX_SMB2_HDR_SIZE, 1585dd446b16edd74ca525208d924d426f786dd973f8Steve French .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, 1586dd446b16edd74ca525208d924d426f786dd973f8Steve French .lock_cmd = SMB2_LOCK, 1587dd446b16edd74ca525208d924d426f786dd973f8Steve French .cap_unix = 0, 1588dd446b16edd74ca525208d924d426f786dd973f8Steve French .cap_nt_find = SMB2_NT_FIND, 1589dd446b16edd74ca525208d924d426f786dd973f8Steve French .cap_large_files = SMB2_LARGE_FILES, 159050285882fdd919e2b9617fc844b4816b7833f115Jeff Layton .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, 159150285882fdd919e2b9617fc844b4816b7833f115Jeff Layton .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, 1592a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky .create_lease_size = sizeof(struct create_lease), 1593dd446b16edd74ca525208d924d426f786dd973f8Steve French}; 1594dd446b16edd74ca525208d924d426f786dd973f8Steve French 15951080ef758fb87f286b25277d8373e680a9e73363Steve Frenchstruct smb_version_values smb21_values = { 15961080ef758fb87f286b25277d8373e680a9e73363Steve French .version_string = SMB21_VERSION_STRING, 1597e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .protocol_id = SMB21_PROT_ID, 1598e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .req_capabilities = 0, /* MBZ on negotiate req until SMB3 dialect */ 1599e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .large_lock_type = 0, 1600e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, 1601e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, 1602e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, 1603e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .header_size = sizeof(struct smb2_hdr), 1604e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .max_header_size = MAX_SMB2_HDR_SIZE, 1605e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, 1606e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .lock_cmd = SMB2_LOCK, 1607e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .cap_unix = 0, 1608e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .cap_nt_find = SMB2_NT_FIND, 1609e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .cap_large_files = SMB2_LARGE_FILES, 161050285882fdd919e2b9617fc844b4816b7833f115Jeff Layton .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, 161150285882fdd919e2b9617fc844b4816b7833f115Jeff Layton .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, 1612a41a28bda936ea627afbfe94a7f5cd63f23cf727Pavel Shilovsky .create_lease_size = sizeof(struct create_lease), 1613e4aa25e7801163df058f62c617b859e9d3d4b148Steve French}; 1614e4aa25e7801163df058f62c617b859e9d3d4b148Steve French 1615e4aa25e7801163df058f62c617b859e9d3d4b148Steve Frenchstruct smb_version_values smb30_values = { 1616e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .version_string = SMB30_VERSION_STRING, 1617e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .protocol_id = SMB30_PROT_ID, 1618e4aa25e7801163df058f62c617b859e9d3d4b148Steve French .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU, 1619027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky .large_lock_type = 0, 1620027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, 1621027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, 1622027e8eec31d8141a6231f772e10ccae60c9d5c13Pavel Shilovsky .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, 1623093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky .header_size = sizeof(struct smb2_hdr), 1624093b2bdad3221e3fae3c26d89387e7297a157664Pavel Shilovsky .max_header_size = MAX_SMB2_HDR_SIZE, 162509a4707e7638247302c6d798061aed117141fb74Pavel Shilovsky .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, 16262dc7e1c03316940dec899fa3206a595de000e99bPavel Shilovsky .lock_cmd = SMB2_LOCK, 162729e20f9c65fae245d6fd4fce31cc5d01cde3d93fPavel Shilovsky .cap_unix = 0, 162829e20f9c65fae245d6fd4fce31cc5d01cde3d93fPavel Shilovsky .cap_nt_find = SMB2_NT_FIND, 162929e20f9c65fae245d6fd4fce31cc5d01cde3d93fPavel Shilovsky .cap_large_files = SMB2_LARGE_FILES, 163050285882fdd919e2b9617fc844b4816b7833f115Jeff Layton .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, 163150285882fdd919e2b9617fc844b4816b7833f115Jeff Layton .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, 1632f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky .create_lease_size = sizeof(struct create_lease_v2), 16331080ef758fb87f286b25277d8373e680a9e73363Steve French}; 163420b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French 163520b6d8b42e7e7c9af5046fe525d6709e10d14992Steve Frenchstruct smb_version_values smb302_values = { 163620b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .version_string = SMB302_VERSION_STRING, 163720b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .protocol_id = SMB302_PROT_ID, 163820b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU, 163920b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .large_lock_type = 0, 164020b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, 164120b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, 164220b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, 164320b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .header_size = sizeof(struct smb2_hdr), 164420b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .max_header_size = MAX_SMB2_HDR_SIZE, 164520b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, 164620b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .lock_cmd = SMB2_LOCK, 164720b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .cap_unix = 0, 164820b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .cap_nt_find = SMB2_NT_FIND, 164920b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French .cap_large_files = SMB2_LARGE_FILES, 165050285882fdd919e2b9617fc844b4816b7833f115Jeff Layton .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, 165150285882fdd919e2b9617fc844b4816b7833f115Jeff Layton .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, 1652f047390a097e907ccccf8aa894dec49890578a1aPavel Shilovsky .create_lease_size = sizeof(struct create_lease_v2), 165320b6d8b42e7e7c9af5046fe525d6709e10d14992Steve French}; 1654