^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * SMB2 version specific operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2012, Jeff Layton <jlayton@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/vfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/falloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/scatterlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/uuid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/sort.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <crypto/aead.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/fiemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "cifsfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "cifsglob.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "smb2pdu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "smb2proto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "cifsproto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "cifs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "cifs_unicode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "smb2status.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "smb2glob.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "cifs_ioctl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "smbdirect.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* Change credits for different ops and return the total number of credits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) change_conf(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) server->credits += server->echo_credits + server->oplock_credits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) server->oplock_credits = server->echo_credits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) switch (server->credits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) server->echoes = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) server->oplocks = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) server->echoes = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) server->oplocks = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) server->echo_credits = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) server->echoes = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (enable_oplocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) server->oplocks = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) server->oplock_credits = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) server->oplocks = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) server->echo_credits = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) server->credits -= server->echo_credits + server->oplock_credits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return server->credits + server->echo_credits + server->oplock_credits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) smb2_add_credits(struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) const struct cifs_credits *credits, const int optype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int *val, rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned int add = credits->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned int instance = credits->instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) bool reconnect_detected = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) spin_lock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) val = server->ops->get_credits_field(server, optype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* eg found case where write overlapping reconnect messed up credits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (((optype & CIFS_OP_MASK) == CIFS_NEG_OP) && (*val != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) trace_smb3_reconnect_with_invalid_credits(server->CurrentMid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) server->hostname, *val, add);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if ((instance == 0) || (instance == server->reconnect_instance))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *val += add;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) reconnect_detected = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (*val > 65000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) *val = 65000; /* Don't get near 64K credits, avoid srv bugs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) pr_warn_once("server overflowed SMB3 credits\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) server->in_flight--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) rc = change_conf(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * Sometimes server returns 0 credits on oplock break ack - we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * rebalance credits in this case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) else if (server->in_flight > 0 && server->oplock_credits == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) server->oplocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (server->credits > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) server->credits--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) server->oplock_credits++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) wake_up(&server->request_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (reconnect_detected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) cifs_dbg(FYI, "trying to put %d credits from the old server instance %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) add, instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (server->tcpStatus == CifsNeedReconnect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) || server->tcpStatus == CifsExiting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) switch (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* change_conf hasn't been executed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) cifs_server_dbg(VFS, "Possible client or server bug - zero credits\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) cifs_server_dbg(VFS, "disabling echoes and oplocks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) cifs_dbg(FYI, "disabling oplocks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) trace_smb3_add_credits(server->CurrentMid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) server->hostname, rc, add);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) cifs_dbg(FYI, "add %u credits total=%d\n", add, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) smb2_set_credits(struct TCP_Server_Info *server, const int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) spin_lock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) server->credits = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (val == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) server->reconnect_instance++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* don't log while holding the lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (val == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) cifs_dbg(FYI, "set credits to 1 due to smb2 reconnect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static int *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) smb2_get_credits_field(struct TCP_Server_Info *server, const int optype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) switch (optype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case CIFS_ECHO_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return &server->echo_credits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) case CIFS_OBREAK_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return &server->oplock_credits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return &server->credits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) smb2_get_credits(struct mid_q_entry *mid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return mid->credits_received;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) unsigned int *num, struct cifs_credits *credits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) unsigned int scredits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) spin_lock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (server->credits <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) cifs_num_waiters_inc(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) rc = wait_event_killable(server->request_q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) has_credits(server, &server->credits, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) cifs_num_waiters_dec(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) spin_lock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (server->tcpStatus == CifsExiting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) scredits = server->credits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* can deadlock with reopen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (scredits <= 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *num = SMB2_MAX_BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) credits->value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) credits->instance = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* leave some credits for reopen and other ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) scredits -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) *num = min_t(unsigned int, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) scredits * SMB2_MAX_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) credits->value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) DIV_ROUND_UP(*num, SMB2_MAX_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) credits->instance = server->reconnect_instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) server->credits -= credits->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) server->in_flight++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (server->in_flight > server->max_in_flight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) server->max_in_flight = server->in_flight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) smb2_adjust_credits(struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct cifs_credits *credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) const unsigned int payload_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int new_val = DIV_ROUND_UP(payload_size, SMB2_MAX_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (!credits->value || credits->value == new_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (credits->value < new_val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) WARN_ONCE(1, "request has less credits (%d) than required (%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) credits->value, new_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) spin_lock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (server->reconnect_instance != credits->instance) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) cifs_server_dbg(VFS, "trying to return %d credits to old session\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) credits->value - new_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) server->credits += credits->value - new_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) wake_up(&server->request_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) credits->value = new_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static __u64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) smb2_get_next_mid(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) __u64 mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* for SMB2 we need the current value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mid = server->CurrentMid++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) smb2_revert_current_mid(struct TCP_Server_Info *server, const unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (server->CurrentMid >= val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) server->CurrentMid -= val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static struct mid_q_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct mid_q_entry *mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) __u64 wire_mid = le64_to_cpu(shdr->MessageId);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) cifs_server_dbg(VFS, "Encrypted frame parsing not supported yet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) list_for_each_entry(mid, &server->pending_mid_q, qhead) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if ((mid->mid == wire_mid) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) (mid->mid_state == MID_REQUEST_SUBMITTED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) (mid->command == shdr->Command)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) kref_get(&mid->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (dequeue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) list_del_init(&mid->qhead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) mid->mid_flags |= MID_DELETED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static struct mid_q_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) smb2_find_mid(struct TCP_Server_Info *server, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return __smb2_find_mid(server, buf, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static struct mid_q_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) smb2_find_dequeue_mid(struct TCP_Server_Info *server, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return __smb2_find_mid(server, buf, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) smb2_dump_detail(void *buf, struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) #ifdef CONFIG_CIFS_DEBUG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) cifs_server_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) shdr->ProcessId);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) cifs_server_dbg(VFS, "smb buf %p len %u\n", buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) server->ops->calc_smb_size(buf, server));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) smb2_need_neg(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return server->max_read == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) smb2_negotiate(const unsigned int xid, struct cifs_ses *ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) cifs_ses_server(ses)->CurrentMid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) rc = SMB2_negotiate(xid, ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* BB we probably don't need to retry with modern servers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (rc == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) rc = -EHOSTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct TCP_Server_Info *server = tcon->ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) unsigned int wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* start with specified wsize, or default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) wsize = min_t(unsigned int, wsize, server->max_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) smb3_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct TCP_Server_Info *server = tcon->ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) unsigned int wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* start with specified wsize, or default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) wsize = volume_info->wsize ? volume_info->wsize : SMB3_DEFAULT_IOSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) wsize = min_t(unsigned int, wsize, server->max_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) #ifdef CONFIG_CIFS_SMB_DIRECT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (server->rdma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (server->sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * Account for SMB2 data transfer packet header and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * possible encryption header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) wsize = min_t(unsigned int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) wsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) server->smbd_conn->max_fragmented_send_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) SMB2_READWRITE_PDU_HEADER_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) sizeof(struct smb2_transform_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) wsize = min_t(unsigned int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) wsize, server->smbd_conn->max_readwrite_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct TCP_Server_Info *server = tcon->ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) unsigned int rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /* start with specified rsize, or default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) rsize = min_t(unsigned int, rsize, server->max_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) rsize = min_t(unsigned int, rsize, SMB2_MAX_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct TCP_Server_Info *server = tcon->ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) unsigned int rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* start with specified rsize, or default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) rsize = volume_info->rsize ? volume_info->rsize : SMB3_DEFAULT_IOSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) rsize = min_t(unsigned int, rsize, server->max_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) #ifdef CONFIG_CIFS_SMB_DIRECT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (server->rdma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (server->sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * Account for SMB2 data transfer packet header and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * possible encryption header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) rsize = min_t(unsigned int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) server->smbd_conn->max_fragmented_recv_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) SMB2_READWRITE_PDU_HEADER_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) sizeof(struct smb2_transform_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) rsize = min_t(unsigned int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) rsize, server->smbd_conn->max_readwrite_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) rsize = min_t(unsigned int, rsize, SMB2_MAX_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) size_t buf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct cifs_server_iface **iface_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) size_t *iface_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct network_interface_info_ioctl_rsp *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct sockaddr_in *addr4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct sockaddr_in6 *addr6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct iface_info_ipv4 *p4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct iface_info_ipv6 *p6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct cifs_server_iface *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) ssize_t bytes_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) size_t next = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int nb_iface = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) *iface_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) *iface_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * Fist pass: count and sanity check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) bytes_left = buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) p = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) while (bytes_left >= sizeof(*p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) nb_iface++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) next = le32_to_cpu(p->Next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (!next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) bytes_left -= sizeof(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) p = (struct network_interface_info_ioctl_rsp *)((u8 *)p+next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) bytes_left -= next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (!nb_iface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) cifs_dbg(VFS, "%s: malformed interface info\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* Azure rounds the buffer size up 8, to a 16 byte boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if ((bytes_left > 8) || p->Next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) cifs_dbg(VFS, "%s: incomplete interface info\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * Second pass: extract info to internal structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) *iface_list = kcalloc(nb_iface, sizeof(**iface_list), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (!*iface_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) info = *iface_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) bytes_left = buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) p = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) while (bytes_left >= sizeof(*p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) info->speed = le64_to_cpu(p->LinkSpeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) info->rdma_capable = le32_to_cpu(p->Capability & RDMA_CAPABLE) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) info->rss_capable = le32_to_cpu(p->Capability & RSS_CAPABLE) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) cifs_dbg(FYI, "%s: adding iface %zu\n", __func__, *iface_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) cifs_dbg(FYI, "%s: speed %zu bps\n", __func__, info->speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) cifs_dbg(FYI, "%s: capabilities 0x%08x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) le32_to_cpu(p->Capability));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) switch (p->Family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * The kernel and wire socket structures have the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * layout and use network byte order but make the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * conversion explicit in case either one changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) case INTERNETWORK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) addr4 = (struct sockaddr_in *)&info->sockaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) p4 = (struct iface_info_ipv4 *)p->Buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) addr4->sin_family = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) memcpy(&addr4->sin_addr, &p4->IPv4Address, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* [MS-SMB2] 2.2.32.5.1.1 Clients MUST ignore these */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) addr4->sin_port = cpu_to_be16(CIFS_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) cifs_dbg(FYI, "%s: ipv4 %pI4\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) &addr4->sin_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) case INTERNETWORKV6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) addr6 = (struct sockaddr_in6 *)&info->sockaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) p6 = (struct iface_info_ipv6 *)p->Buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) addr6->sin6_family = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) memcpy(&addr6->sin6_addr, &p6->IPv6Address, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /* [MS-SMB2] 2.2.32.5.1.2 Clients MUST ignore these */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) addr6->sin6_flowinfo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) addr6->sin6_scope_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) addr6->sin6_port = cpu_to_be16(CIFS_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) cifs_dbg(FYI, "%s: ipv6 %pI6\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) &addr6->sin6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) "%s: skipping unsupported socket family\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) goto next_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) (*iface_count)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) info++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) next_iface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) next = le32_to_cpu(p->Next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (!next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) p = (struct network_interface_info_ioctl_rsp *)((u8 *)p+next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) bytes_left -= next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (!*iface_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) kfree(*iface_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) *iface_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) *iface_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static int compare_iface(const void *ia, const void *ib)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) const struct cifs_server_iface *a = (struct cifs_server_iface *)ia;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) const struct cifs_server_iface *b = (struct cifs_server_iface *)ib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return a->speed == b->speed ? 0 : (a->speed > b->speed ? -1 : 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) unsigned int ret_data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct network_interface_info_ioctl_rsp *out_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct cifs_server_iface *iface_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) size_t iface_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct cifs_ses *ses = tcon->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) FSCTL_QUERY_NETWORK_INTERFACE_INFO, true /* is_fsctl */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) NULL /* no data input */, 0 /* no data input */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) CIFSMaxBufSize, (char **)&out_buf, &ret_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (rc == -EOPNOTSUPP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) cifs_dbg(FYI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) "server does not support query network interfaces\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) } else if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) cifs_tcon_dbg(VFS, "error %d on ioctl to get interface list\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) rc = parse_server_interfaces(out_buf, ret_data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) &iface_list, &iface_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* sort interfaces from fastest to slowest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) sort(iface_list, iface_count, sizeof(*iface_list), compare_iface, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) spin_lock(&ses->iface_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) kfree(ses->iface_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) ses->iface_list = iface_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) ses->iface_count = iface_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) ses->iface_last_update = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) spin_unlock(&ses->iface_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) kfree(out_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) smb2_close_cached_fid(struct kref *ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct cached_fid *cfid = container_of(ref, struct cached_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (cfid->is_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) cifs_dbg(FYI, "clear cached root file handle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) SMB2_close(0, cfid->tcon, cfid->fid->persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) cfid->fid->volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) cfid->is_valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) cfid->file_all_info_is_valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) cfid->has_lease = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) void close_shroot(struct cached_fid *cfid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) mutex_lock(&cfid->fid_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) kref_put(&cfid->refcount, smb2_close_cached_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) mutex_unlock(&cfid->fid_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) void close_shroot_lease_locked(struct cached_fid *cfid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (cfid->has_lease) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) cfid->has_lease = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) kref_put(&cfid->refcount, smb2_close_cached_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) void close_shroot_lease(struct cached_fid *cfid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) mutex_lock(&cfid->fid_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) close_shroot_lease_locked(cfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) mutex_unlock(&cfid->fid_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) smb2_cached_lease_break(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct cached_fid *cfid = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct cached_fid, lease_break);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) close_shroot_lease(cfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * Open the directory at the root of a share
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct cached_fid **cfid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct cifs_ses *ses = tcon->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct TCP_Server_Info *server = ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct smb2_create_rsp *o_rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct smb2_query_info_rsp *qi_rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) int resp_buftype[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct smb_rqst rqst[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct kvec rsp_iov[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) struct kvec qi_iov[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) int rc, flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) __le16 utf16_path = 0; /* Null - since an open of top of share */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) u8 oplock = SMB2_OPLOCK_LEVEL_II;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct cifs_fid *pfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) mutex_lock(&tcon->crfid.fid_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (tcon->crfid.is_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) cifs_dbg(FYI, "found a cached root file handle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) *cfid = &tcon->crfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) kref_get(&tcon->crfid.refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) mutex_unlock(&tcon->crfid.fid_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * We do not hold the lock for the open because in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * SMB2_open needs to reconnect, it will end up calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * cifs_mark_open_files_invalid() which takes the lock again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * thus causing a deadlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) mutex_unlock(&tcon->crfid.fid_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (smb3_encryption_required(tcon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) flags |= CIFS_TRANSFORM_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (!server->ops->new_lease_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) pfid = tcon->crfid.fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) server->ops->new_lease_key(pfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) memset(rqst, 0, sizeof(rqst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) resp_buftype[0] = resp_buftype[1] = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) memset(rsp_iov, 0, sizeof(rsp_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /* Open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) memset(&open_iov, 0, sizeof(open_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) rqst[0].rq_iov = open_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) oparms.desired_access = FILE_READ_ATTRIBUTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) oparms.fid = pfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) rc = SMB2_open_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) &rqst[0], &oplock, &oparms, &utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) goto oshr_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) smb2_set_next_command(tcon, &rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) memset(&qi_iov, 0, sizeof(qi_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) rqst[1].rq_iov = qi_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) rqst[1].rq_nvec = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) rc = SMB2_query_info_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) &rqst[1], COMPOUND_FID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) COMPOUND_FID, FILE_ALL_INFORMATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) SMB2_O_INFO_FILE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) sizeof(struct smb2_file_all_info) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) PATH_MAX * 2, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) goto oshr_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) smb2_set_related(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) rc = compound_send_recv(xid, ses, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) flags, 2, rqst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) resp_buftype, rsp_iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) mutex_lock(&tcon->crfid.fid_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * Now we need to check again as the cached root might have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * been successfully re-opened from a concurrent process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (tcon->crfid.is_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /* work was already done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* stash fids for close() later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) struct cifs_fid fid = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .persistent_fid = pfid->persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) .volatile_fid = pfid->volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * caller expects this func to set pfid to a valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * cached root, so we copy the existing one and get a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) memcpy(pfid, tcon->crfid.fid, sizeof(*pfid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) kref_get(&tcon->crfid.refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) mutex_unlock(&tcon->crfid.fid_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /* close extra handle outside of crit sec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) goto oshr_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) /* Cached root is still invalid, continue normaly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (rc == -EREMCHG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) tcon->need_reconnect = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) pr_warn_once("server share %s deleted\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) tcon->treeName);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) goto oshr_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) atomic_inc(&tcon->num_remote_opens);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) oparms.fid->persistent_fid = o_rsp->PersistentFileId;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) oparms.fid->volatile_fid = o_rsp->VolatileFileId;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) #ifdef CONFIG_CIFS_DEBUG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) oparms.fid->mid = le64_to_cpu(o_rsp->sync_hdr.MessageId);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) #endif /* CIFS_DEBUG2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) memcpy(tcon->crfid.fid, pfid, sizeof(struct cifs_fid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) tcon->crfid.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) tcon->crfid.is_valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) kref_init(&tcon->crfid.refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /* BB TBD check to see if oplock level check can be removed below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (o_rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) kref_get(&tcon->crfid.refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) tcon->crfid.has_lease = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) smb2_parse_contexts(server, o_rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) &oparms.fid->epoch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) oparms.fid->lease_key, &oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) goto oshr_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) goto oshr_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (!smb2_validate_and_copy_iov(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) le16_to_cpu(qi_rsp->OutputBufferOffset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) sizeof(struct smb2_file_all_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) &rsp_iov[1], sizeof(struct smb2_file_all_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) (char *)&tcon->crfid.file_all_info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) tcon->crfid.file_all_info_is_valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) oshr_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) mutex_unlock(&tcon->crfid.fid_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) oshr_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) SMB2_open_free(&rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) SMB2_query_info_free(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) *cfid = &tcon->crfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) __le16 srch_path = 0; /* Null - open root of share */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) bool no_cached_open = tcon->nohandlecache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) struct cached_fid *cfid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) oparms.desired_access = FILE_READ_ATTRIBUTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (no_cached_open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) rc = open_shroot(xid, tcon, cifs_sb, &cfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) memcpy(&fid, cfid->fid, sizeof(struct cifs_fid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) SMB3_request_interfaces(xid, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) FS_ATTRIBUTE_INFORMATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) FS_DEVICE_INFORMATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) FS_VOLUME_INFORMATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (no_cached_open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) close_shroot(cfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) __le16 srch_path = 0; /* Null - open root of share */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) oparms.desired_access = FILE_READ_ATTRIBUTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) FS_ATTRIBUTE_INFORMATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) FS_DEVICE_INFORMATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) struct cifs_sb_info *cifs_sb, const char *full_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) __le16 *utf16_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if ((*full_path == 0) && tcon->crfid.is_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (!utf16_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) oparms.desired_access = FILE_READ_ATTRIBUTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) kfree(utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) kfree(utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) struct cifs_sb_info *cifs_sb, const char *full_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) u64 *uniqueid, FILE_ALL_INFO *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) *uniqueid = le64_to_cpu(data->IndexNumber);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct cifs_fid *fid, FILE_ALL_INFO *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) struct smb2_file_all_info *smb2_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (smb2_data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) rc = SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) smb2_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) move_smb2_info_to_cifs(data, smb2_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) kfree(smb2_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) #ifdef CONFIG_CIFS_XATTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) move_smb2_ea_to_cifs(char *dst, size_t dst_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct smb2_file_full_ea_info *src, size_t src_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) const unsigned char *ea_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) char *name, *value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) size_t buf_size = dst_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) size_t name_len, value_len, user_name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) while (src_size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) name = &src->ea_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) name_len = (size_t)src->ea_name_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) value = &src->ea_data[src->ea_name_length + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) value_len = (size_t)le16_to_cpu(src->ea_value_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (name_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (src_size < 8 + name_len + 1 + value_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) cifs_dbg(FYI, "EA entry goes beyond length of list\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (ea_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (ea_name_len == name_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) memcmp(ea_name, name, name_len) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) rc = value_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (dst_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (dst_size < value_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) rc = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) memcpy(dst, value, value_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) /* 'user.' plus a terminating null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) user_name_len = 5 + 1 + name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (buf_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /* skip copy - calc size only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) rc += user_name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) } else if (dst_size >= user_name_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) dst_size -= user_name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) memcpy(dst, "user.", 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) dst += 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) memcpy(dst, src->ea_data, name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) dst += name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) *dst = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) ++dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) rc += user_name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /* stop before overrun buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) rc = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (!src->next_entry_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (src_size < le32_to_cpu(src->next_entry_offset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) /* stop before overrun buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) rc = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) src_size -= le32_to_cpu(src->next_entry_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) src = (void *)((char *)src +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) le32_to_cpu(src->next_entry_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /* didn't find the named attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (ea_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) rc = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) return (ssize_t)rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) const unsigned char *path, const unsigned char *ea_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) char *ea_data, size_t buf_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) __le16 *utf16_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) struct kvec rsp_iov = {NULL, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) int buftype = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) struct smb2_query_info_rsp *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) struct smb2_file_full_ea_info *info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (!utf16_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) rc = smb2_query_info_compound(xid, tcon, utf16_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) FILE_READ_EA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) FILE_FULL_EA_INFORMATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) SMB2_O_INFO_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) CIFSMaxBufSize -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) MAX_SMB2_CREATE_RESPONSE_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) MAX_SMB2_CLOSE_RESPONSE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) &rsp_iov, &buftype, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * If ea_name is NULL (listxattr) and there are no EAs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * return 0 as it's not an error. Otherwise, the specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * ea_name was not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (!ea_name && rc == -ENODATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) goto qeas_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) le32_to_cpu(rsp->OutputBufferLength),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) &rsp_iov,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) sizeof(struct smb2_file_full_ea_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) goto qeas_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) info = (struct smb2_file_full_ea_info *)(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) le16_to_cpu(rsp->OutputBufferOffset) + (char *)rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) rc = move_smb2_ea_to_cifs(ea_data, buf_size, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) le32_to_cpu(rsp->OutputBufferLength), ea_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) qeas_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) kfree(utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) free_rsp_buf(buftype, rsp_iov.iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) const char *path, const char *ea_name, const void *ea_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) const __u16 ea_value_len, const struct nls_table *nls_codepage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) struct cifs_ses *ses = tcon->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct TCP_Server_Info *server = cifs_pick_channel(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) __le16 *utf16_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) int ea_name_len = strlen(ea_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) int flags = CIFS_CP_CREATE_CLOSE_OP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) struct smb_rqst rqst[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) int resp_buftype[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) struct kvec rsp_iov[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) unsigned int size[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) void *data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) struct smb2_file_full_ea_info *ea = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) struct kvec close_iov[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) struct smb2_query_info_rsp *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) int rc, used_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (smb3_encryption_required(tcon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) flags |= CIFS_TRANSFORM_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) if (ea_name_len > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (!utf16_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) memset(rqst, 0, sizeof(rqst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) memset(rsp_iov, 0, sizeof(rsp_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (ses->server->ops->query_all_EAs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (!ea_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) rc = ses->server->ops->query_all_EAs(xid, tcon, path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) ea_name, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (rc == -ENODATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) goto sea_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) /* If we are adding a attribute we should first check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) * if there will be enough space available to store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) * the new EA. If not we should not add it since we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) * would not be able to even read the EAs back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) rc = smb2_query_info_compound(xid, tcon, utf16_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) FILE_READ_EA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) FILE_FULL_EA_INFORMATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) SMB2_O_INFO_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) CIFSMaxBufSize -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) MAX_SMB2_CREATE_RESPONSE_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) MAX_SMB2_CLOSE_RESPONSE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) &rsp_iov[1], &resp_buftype[1], cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) used_len = le32_to_cpu(rsp->OutputBufferLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) resp_buftype[1] = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) memset(&rsp_iov[1], 0, sizeof(rsp_iov[1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) /* Use a fudge factor of 256 bytes in case we collide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) * with a different set_EAs command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if(CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) MAX_SMB2_CLOSE_RESPONSE_SIZE - 256 <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) used_len + ea_name_len + ea_value_len + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) rc = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) goto sea_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) /* Open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) memset(&open_iov, 0, sizeof(open_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) rqst[0].rq_iov = open_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) memset(&oparms, 0, sizeof(oparms));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) oparms.desired_access = FILE_WRITE_EA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) rc = SMB2_open_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) &rqst[0], &oplock, &oparms, utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) goto sea_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) smb2_set_next_command(tcon, &rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) /* Set Info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) memset(&si_iov, 0, sizeof(si_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) rqst[1].rq_iov = si_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) rqst[1].rq_nvec = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) len = sizeof(*ea) + ea_name_len + ea_value_len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) ea = kzalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (ea == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) goto sea_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) ea->ea_name_length = ea_name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) ea->ea_value_length = cpu_to_le16(ea_value_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) memcpy(ea->ea_data, ea_name, ea_name_len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) memcpy(ea->ea_data + ea_name_len + 1, ea_value, ea_value_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) size[0] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) data[0] = ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) rc = SMB2_set_info_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) &rqst[1], COMPOUND_FID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) COMPOUND_FID, current->tgid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) FILE_FULL_EA_INFORMATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) SMB2_O_INFO_FILE, 0, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) smb2_set_next_command(tcon, &rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) smb2_set_related(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) /* Close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) memset(&close_iov, 0, sizeof(close_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) rqst[2].rq_iov = close_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) rqst[2].rq_nvec = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) rc = SMB2_close_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) smb2_set_related(&rqst[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) rc = compound_send_recv(xid, ses, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) flags, 3, rqst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) resp_buftype, rsp_iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) /* no need to bump num_remote_opens because handle immediately closed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) sea_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) kfree(ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) kfree(utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) SMB2_open_free(&rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) SMB2_set_info_free(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) SMB2_close_free(&rqst[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) smb2_can_echo(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) return server->echoes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) smb2_clear_stats(struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) smb2_dump_share_caps(struct seq_file *m, struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) seq_puts(m, "\n\tShare Capabilities:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (tcon->capabilities & SMB2_SHARE_CAP_DFS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) seq_puts(m, " DFS,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) seq_puts(m, " CONTINUOUS AVAILABILITY,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (tcon->capabilities & SMB2_SHARE_CAP_SCALEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) seq_puts(m, " SCALEOUT,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (tcon->capabilities & SMB2_SHARE_CAP_CLUSTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) seq_puts(m, " CLUSTER,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (tcon->capabilities & SMB2_SHARE_CAP_ASYMMETRIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) seq_puts(m, " ASYMMETRIC,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (tcon->capabilities == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) seq_puts(m, " None");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) if (tcon->ss_flags & SSINFO_FLAGS_ALIGNED_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) seq_puts(m, " Aligned,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (tcon->ss_flags & SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) seq_puts(m, " Partition Aligned,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (tcon->ss_flags & SSINFO_FLAGS_NO_SEEK_PENALTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) seq_puts(m, " SSD,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) if (tcon->ss_flags & SSINFO_FLAGS_TRIM_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) seq_puts(m, " TRIM-support,");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) seq_printf(m, "\n\ttid: 0x%x", tcon->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) if (tcon->perf_sector_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) seq_printf(m, "\tOptimal sector size: 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) tcon->perf_sector_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) seq_printf(m, "\tMaximal Access: 0x%x", tcon->maximal_access);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) smb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) atomic_t *sent = tcon->stats.smb2_stats.smb2_com_sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) atomic_t *failed = tcon->stats.smb2_stats.smb2_com_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) * Can't display SMB2_NEGOTIATE, SESSION_SETUP, LOGOFF, CANCEL and ECHO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) * totals (requests sent) since those SMBs are per-session not per tcon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) seq_printf(m, "\nBytes read: %llu Bytes written: %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) (long long)(tcon->bytes_read),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) (long long)(tcon->bytes_written));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) seq_printf(m, "\nOpen files: %d total (local), %d open on server",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) atomic_read(&tcon->num_local_opens),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) atomic_read(&tcon->num_remote_opens));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) seq_printf(m, "\nTreeConnects: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) atomic_read(&sent[SMB2_TREE_CONNECT_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) atomic_read(&failed[SMB2_TREE_CONNECT_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) seq_printf(m, "\nTreeDisconnects: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) atomic_read(&sent[SMB2_TREE_DISCONNECT_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) atomic_read(&failed[SMB2_TREE_DISCONNECT_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) seq_printf(m, "\nCreates: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) atomic_read(&sent[SMB2_CREATE_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) atomic_read(&failed[SMB2_CREATE_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) seq_printf(m, "\nCloses: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) atomic_read(&sent[SMB2_CLOSE_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) atomic_read(&failed[SMB2_CLOSE_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) seq_printf(m, "\nFlushes: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) atomic_read(&sent[SMB2_FLUSH_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) atomic_read(&failed[SMB2_FLUSH_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) seq_printf(m, "\nReads: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) atomic_read(&sent[SMB2_READ_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) atomic_read(&failed[SMB2_READ_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) seq_printf(m, "\nWrites: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) atomic_read(&sent[SMB2_WRITE_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) atomic_read(&failed[SMB2_WRITE_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) seq_printf(m, "\nLocks: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) atomic_read(&sent[SMB2_LOCK_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) atomic_read(&failed[SMB2_LOCK_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) seq_printf(m, "\nIOCTLs: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) atomic_read(&sent[SMB2_IOCTL_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) atomic_read(&failed[SMB2_IOCTL_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) seq_printf(m, "\nQueryDirectories: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) atomic_read(&sent[SMB2_QUERY_DIRECTORY_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) atomic_read(&failed[SMB2_QUERY_DIRECTORY_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) seq_printf(m, "\nChangeNotifies: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) atomic_read(&sent[SMB2_CHANGE_NOTIFY_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) atomic_read(&failed[SMB2_CHANGE_NOTIFY_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) seq_printf(m, "\nQueryInfos: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) atomic_read(&sent[SMB2_QUERY_INFO_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) atomic_read(&failed[SMB2_QUERY_INFO_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) seq_printf(m, "\nSetInfos: %d total %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) atomic_read(&sent[SMB2_SET_INFO_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) atomic_read(&failed[SMB2_SET_INFO_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) seq_printf(m, "\nOplockBreaks: %d sent %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) atomic_read(&sent[SMB2_OPLOCK_BREAK_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) atomic_read(&failed[SMB2_OPLOCK_BREAK_HE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) cfile->fid.persistent_fid = fid->persistent_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) cfile->fid.volatile_fid = fid->volatile_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) cfile->fid.access = fid->access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) #ifdef CONFIG_CIFS_DEBUG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) cfile->fid.mid = fid->mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) #endif /* CIFS_DEBUG2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) server->ops->set_oplock_level(cinode, oplock, fid->epoch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) &fid->purge_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) memcpy(cfile->fid.create_guid, fid->create_guid, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) smb2_close_file(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) struct cifs_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) smb2_close_getattr(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) struct cifsFileInfo *cfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) struct smb2_file_network_open_info file_inf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) rc = __SMB2_close(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) cfile->fid.volatile_fid, &file_inf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) inode = d_inode(cfile->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) CIFS_I(inode)->time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) /* Creation time should not need to be updated on close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) if (file_inf.LastWriteTime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) inode->i_mtime = cifs_NTtimeToUnix(file_inf.LastWriteTime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (file_inf.ChangeTime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) inode->i_ctime = cifs_NTtimeToUnix(file_inf.ChangeTime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (file_inf.LastAccessTime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) inode->i_atime = cifs_NTtimeToUnix(file_inf.LastAccessTime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) * i_blocks is not related to (i_size / i_blksize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) * but instead 512 byte (2**9) size is required for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) * calculating num blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) if (le64_to_cpu(file_inf.AllocationSize) > 4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) inode->i_blocks =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) (512 - 1 + le64_to_cpu(file_inf.AllocationSize)) >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) /* End of file and Attributes should not have to be updated on close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) u64 persistent_fid, u64 volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) struct copychunk_ioctl *pcchunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) unsigned int ret_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) struct resume_key_req *res_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) FSCTL_SRV_REQUEST_RESUME_KEY, true /* is_fsctl */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) NULL, 0 /* no input */, CIFSMaxBufSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) (char **)&res_key, &ret_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) cifs_tcon_dbg(VFS, "refcpy ioctl error %d getting resume key\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) goto req_res_key_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (ret_data_len < sizeof(struct resume_key_req)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) cifs_tcon_dbg(VFS, "Invalid refcopy resume key length\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) goto req_res_key_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) memcpy(pcchunk->SourceKey, res_key->ResumeKey, COPY_CHUNK_RES_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) req_res_key_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) kfree(res_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) struct iqi_vars {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) struct smb_rqst rqst[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) struct kvec rsp_iov[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) struct kvec qi_iov[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) struct kvec close_iov[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) smb2_ioctl_query_info(const unsigned int xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) __le16 *path, int is_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) unsigned long p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) struct iqi_vars *vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) struct smb_rqst *rqst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) struct kvec *rsp_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) struct cifs_ses *ses = tcon->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) struct TCP_Server_Info *server = cifs_pick_channel(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) char __user *arg = (char __user *)p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) struct smb_query_info qi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) struct smb_query_info __user *pqi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) int flags = CIFS_CP_CREATE_CLOSE_OP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) struct smb2_query_info_rsp *qi_rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) struct smb2_ioctl_rsp *io_rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) void *buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) int resp_buftype[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) unsigned int size[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) void *data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) int create_options = is_dir ? CREATE_NOT_FILE : CREATE_NOT_DIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) void (*free_req1_func)(struct smb_rqst *r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) vars = kzalloc(sizeof(*vars), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) if (vars == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) rqst = &vars->rqst[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) rsp_iov = &vars->rsp_iov[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) if (copy_from_user(&qi, arg, sizeof(struct smb_query_info))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) goto free_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) if (qi.output_buffer_length > 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) goto free_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) if (!ses || !server) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) goto free_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (smb3_encryption_required(tcon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) flags |= CIFS_TRANSFORM_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (qi.output_buffer_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) buffer = memdup_user(arg + sizeof(struct smb_query_info), qi.output_buffer_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) if (IS_ERR(buffer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) rc = PTR_ERR(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) goto free_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) /* Open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) rqst[0].rq_iov = &vars->open_iov[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) memset(&oparms, 0, sizeof(oparms));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) oparms.create_options = cifs_create_options(cifs_sb, create_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) if (qi.flags & PASSTHRU_FSCTL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) switch (qi.info_type & FSCTL_DEVICE_ACCESS_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) case FSCTL_DEVICE_ACCESS_FILE_READ_WRITE_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) oparms.desired_access = FILE_READ_DATA | FILE_WRITE_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) case FSCTL_DEVICE_ACCESS_FILE_ANY_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) oparms.desired_access = GENERIC_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) case FSCTL_DEVICE_ACCESS_FILE_READ_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) oparms.desired_access = GENERIC_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) case FSCTL_DEVICE_ACCESS_FILE_WRITE_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) oparms.desired_access = GENERIC_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) } else if (qi.flags & PASSTHRU_SET_INFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) oparms.desired_access = GENERIC_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) oparms.desired_access = FILE_READ_ATTRIBUTES | READ_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) rc = SMB2_open_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) &rqst[0], &oplock, &oparms, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) goto free_output_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) smb2_set_next_command(tcon, &rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) /* Query */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) if (qi.flags & PASSTHRU_FSCTL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) /* Can eventually relax perm check since server enforces too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (!capable(CAP_SYS_ADMIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) goto free_open_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) rqst[1].rq_iov = &vars->io_iov[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) rc = SMB2_ioctl_init(tcon, server, &rqst[1], COMPOUND_FID, COMPOUND_FID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) qi.info_type, true, buffer, qi.output_buffer_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) MAX_SMB2_CLOSE_RESPONSE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) free_req1_func = SMB2_ioctl_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) } else if (qi.flags == PASSTHRU_SET_INFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) /* Can eventually relax perm check since server enforces too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) if (!capable(CAP_SYS_ADMIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) goto free_open_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (qi.output_buffer_length < 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) goto free_open_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) rqst[1].rq_iov = &vars->si_iov[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) rqst[1].rq_nvec = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) /* MS-FSCC 2.4.13 FileEndOfFileInformation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) size[0] = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) data[0] = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) rc = SMB2_set_info_init(tcon, server, &rqst[1], COMPOUND_FID, COMPOUND_FID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) current->tgid, FILE_END_OF_FILE_INFORMATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) SMB2_O_INFO_FILE, 0, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) free_req1_func = SMB2_set_info_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) } else if (qi.flags == PASSTHRU_QUERY_INFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) rqst[1].rq_iov = &vars->qi_iov[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) rqst[1].rq_nvec = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) rc = SMB2_query_info_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) &rqst[1], COMPOUND_FID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) COMPOUND_FID, qi.file_info_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) qi.info_type, qi.additional_information,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) qi.input_buffer_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) qi.output_buffer_length, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) free_req1_func = SMB2_query_info_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) } else { /* unknown flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) cifs_tcon_dbg(VFS, "Invalid passthru query flags: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) qi.flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) goto free_open_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) smb2_set_next_command(tcon, &rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) smb2_set_related(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) /* Close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) rqst[2].rq_iov = &vars->close_iov[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) rqst[2].rq_nvec = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) rc = SMB2_close_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) goto free_req_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) smb2_set_related(&rqst[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) rc = compound_send_recv(xid, ses, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) flags, 3, rqst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) resp_buftype, rsp_iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) /* No need to bump num_remote_opens since handle immediately closed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) if (qi.flags & PASSTHRU_FSCTL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) pqi = (struct smb_query_info __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) io_rsp = (struct smb2_ioctl_rsp *)rsp_iov[1].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) if (le32_to_cpu(io_rsp->OutputCount) < qi.input_buffer_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) qi.input_buffer_length = le32_to_cpu(io_rsp->OutputCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) if (qi.input_buffer_length > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) le32_to_cpu(io_rsp->OutputOffset) + qi.input_buffer_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) > rsp_iov[1].iov_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) if (copy_to_user(&pqi->input_buffer_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) &qi.input_buffer_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) sizeof(qi.input_buffer_length))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) if (copy_to_user((void __user *)pqi + sizeof(struct smb_query_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) (const void *)io_rsp + le32_to_cpu(io_rsp->OutputOffset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) qi.input_buffer_length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) pqi = (struct smb_query_info __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if (le32_to_cpu(qi_rsp->OutputBufferLength) < qi.input_buffer_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) qi.input_buffer_length = le32_to_cpu(qi_rsp->OutputBufferLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) if (copy_to_user(&pqi->input_buffer_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) &qi.input_buffer_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) sizeof(qi.input_buffer_length))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (copy_to_user(pqi + 1, qi_rsp->Buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) qi.input_buffer_length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) SMB2_close_free(&rqst[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) free_req_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) free_req1_func(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) free_open_req:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) SMB2_open_free(&rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) free_output_buffer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) free_vars:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) kfree(vars);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) smb2_copychunk_range(const unsigned int xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) struct cifsFileInfo *srcfile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) struct cifsFileInfo *trgtfile, u64 src_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) u64 len, u64 dest_off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) unsigned int ret_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) struct copychunk_ioctl *pcchunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) struct copychunk_ioctl_rsp *retbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) int chunks_copied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) bool chunk_sizes_updated = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) ssize_t bytes_written, total_bytes_written = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) pcchunk = kmalloc(sizeof(struct copychunk_ioctl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (pcchunk == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) cifs_dbg(FYI, "%s: about to call request res key\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) /* Request a key from the server to identify the source of the copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) rc = SMB2_request_res_key(xid, tlink_tcon(srcfile->tlink),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) srcfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) srcfile->fid.volatile_fid, pcchunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) /* Note: request_res_key sets res_key null only if rc !=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) goto cchunk_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) /* For now array only one chunk long, will make more flexible later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) pcchunk->ChunkCount = cpu_to_le32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) pcchunk->Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) pcchunk->Reserved2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) tcon = tlink_tcon(trgtfile->tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) while (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) pcchunk->SourceOffset = cpu_to_le64(src_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) pcchunk->TargetOffset = cpu_to_le64(dest_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) pcchunk->Length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) /* Request server copy to target from src identified by key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) kfree(retbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) retbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) trgtfile->fid.volatile_fid, FSCTL_SRV_COPYCHUNK_WRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) true /* is_fsctl */, (char *)pcchunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) sizeof(struct copychunk_ioctl), CIFSMaxBufSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) (char **)&retbuf, &ret_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) if (ret_data_len !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) sizeof(struct copychunk_ioctl_rsp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) cifs_tcon_dbg(VFS, "Invalid cchunk response size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) goto cchunk_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) if (retbuf->TotalBytesWritten == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) cifs_dbg(FYI, "no bytes copied\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) goto cchunk_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) * Check if server claimed to write more than we asked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) if (le32_to_cpu(retbuf->TotalBytesWritten) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) le32_to_cpu(pcchunk->Length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) cifs_tcon_dbg(VFS, "Invalid copy chunk response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) goto cchunk_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if (le32_to_cpu(retbuf->ChunksWritten) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) cifs_tcon_dbg(VFS, "Invalid num chunks written\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) goto cchunk_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) chunks_copied++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) bytes_written = le32_to_cpu(retbuf->TotalBytesWritten);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) src_off += bytes_written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) dest_off += bytes_written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) len -= bytes_written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) total_bytes_written += bytes_written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) cifs_dbg(FYI, "Chunks %d PartialChunk %d Total %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) le32_to_cpu(retbuf->ChunksWritten),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) le32_to_cpu(retbuf->ChunkBytesWritten),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) bytes_written);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) } else if (rc == -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) if (ret_data_len != sizeof(struct copychunk_ioctl_rsp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) goto cchunk_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) cifs_dbg(FYI, "MaxChunks %d BytesChunk %d MaxCopy %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) le32_to_cpu(retbuf->ChunksWritten),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) le32_to_cpu(retbuf->ChunkBytesWritten),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) le32_to_cpu(retbuf->TotalBytesWritten));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) * Check if this is the first request using these sizes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) * (ie check if copy succeed once with original sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) * and check if the server gave us different sizes after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) * we already updated max sizes on previous request).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) * if not then why is the server returning an error now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if ((chunks_copied != 0) || chunk_sizes_updated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) goto cchunk_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) /* Check that server is not asking us to grow size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) if (le32_to_cpu(retbuf->ChunkBytesWritten) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) tcon->max_bytes_chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) tcon->max_bytes_chunk =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) le32_to_cpu(retbuf->ChunkBytesWritten);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) goto cchunk_out; /* server gave us bogus size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) /* No need to change MaxChunks since already set to 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) chunk_sizes_updated = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) goto cchunk_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) cchunk_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) kfree(pcchunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) kfree(retbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) return total_bytes_written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) smb2_flush_file(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) struct cifs_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) return SMB2_flush(xid, tcon, fid->persistent_fid, fid->volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) smb2_read_data_offset(char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) return rsp->DataOffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) smb2_read_data_length(char *buf, bool in_remaining)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) if (in_remaining)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) return le32_to_cpu(rsp->DataRemaining);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) return le32_to_cpu(rsp->DataLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) smb2_sync_read(const unsigned int xid, struct cifs_fid *pfid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) struct cifs_io_parms *parms, unsigned int *bytes_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) char **buf, int *buf_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) parms->persistent_fid = pfid->persistent_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) parms->volatile_fid = pfid->volatile_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) return SMB2_read(xid, parms, bytes_read, buf, buf_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) smb2_sync_write(const unsigned int xid, struct cifs_fid *pfid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) struct cifs_io_parms *parms, unsigned int *written,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) struct kvec *iov, unsigned long nr_segs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) parms->persistent_fid = pfid->persistent_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) parms->volatile_fid = pfid->volatile_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) return SMB2_write(xid, parms, written, iov, nr_segs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) /* Set or clear the SPARSE_FILE attribute based on value passed in setsparse */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) static bool smb2_set_sparse(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) struct cifsFileInfo *cfile, struct inode *inode, __u8 setsparse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) struct cifsInodeInfo *cifsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) cifsi = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) /* if file already sparse don't bother setting sparse again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) && setsparse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) return true; /* already sparse */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) && !setsparse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) return true; /* already not sparse */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) * Can't check for sparse support on share the usual way via the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) * FS attribute info (FILE_SUPPORTS_SPARSE_FILES) on the share
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) * since Samba server doesn't set the flag on the share, yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) * supports the set sparse FSCTL and returns sparse correctly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) * in the file attributes. If we fail setting sparse though we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) * mark that server does not support sparse files for this share
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) * to avoid repeatedly sending the unsupported fsctl to server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) * if the file is repeatedly extended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) if (tcon->broken_sparse_sup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) cfile->fid.volatile_fid, FSCTL_SET_SPARSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) true /* is_fctl */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) &setsparse, 1, CIFSMaxBufSize, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) tcon->broken_sparse_sup = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) cifs_dbg(FYI, "set sparse rc = %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) if (setsparse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) cifsi->cifsAttrs |= FILE_ATTRIBUTE_SPARSE_FILE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) cifsi->cifsAttrs &= (~FILE_ATTRIBUTE_SPARSE_FILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) __le64 eof = cpu_to_le64(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) * If extending file more than one page make sparse. Many Linux fs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) * make files sparse by default when extending via ftruncate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) inode = d_inode(cfile->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) if (!set_alloc && (size > inode->i_size + 8192)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) __u8 set_sparse = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) /* whether set sparse succeeds or not, extend the file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) smb2_set_sparse(xid, tcon, cfile, inode, set_sparse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) cfile->fid.volatile_fid, cfile->pid, &eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) smb2_duplicate_extents(const unsigned int xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) struct cifsFileInfo *srcfile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) struct cifsFileInfo *trgtfile, u64 src_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) u64 len, u64 dest_off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) unsigned int ret_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) struct duplicate_extents_to_file dup_ext_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) struct cifs_tcon *tcon = tlink_tcon(trgtfile->tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) /* server fileays advertise duplicate extent support with this flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) if ((le32_to_cpu(tcon->fsAttrInfo.Attributes) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) FILE_SUPPORTS_BLOCK_REFCOUNTING) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) dup_ext_buf.VolatileFileHandle = srcfile->fid.volatile_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) dup_ext_buf.PersistentFileHandle = srcfile->fid.persistent_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) dup_ext_buf.SourceFileOffset = cpu_to_le64(src_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) dup_ext_buf.TargetFileOffset = cpu_to_le64(dest_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) dup_ext_buf.ByteCount = cpu_to_le64(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) cifs_dbg(FYI, "Duplicate extents: src off %lld dst off %lld len %lld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) src_off, dest_off, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) inode = d_inode(trgtfile->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) if (inode->i_size < dest_off + len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) goto duplicate_extents_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) * Although also could set plausible allocation size (i_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) * here in addition to setting the file size, in reflink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) * it is likely that the target file is sparse. Its allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) * size will be queried on next revalidate, but it is important
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) * to make sure that file's cached size is updated immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) cifs_setsize(inode, dest_off + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) trgtfile->fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) FSCTL_DUPLICATE_EXTENTS_TO_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) true /* is_fsctl */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) (char *)&dup_ext_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) sizeof(struct duplicate_extents_to_file),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) CIFSMaxBufSize, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) &ret_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) if (ret_data_len > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) cifs_dbg(FYI, "Non-zero response length in duplicate extents\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) duplicate_extents_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) smb2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) struct cifsFileInfo *cfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) return SMB2_set_compression(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) cfile->fid.volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) struct cifsFileInfo *cfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) struct fsctl_set_integrity_information_req integr_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) unsigned int ret_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) integr_info.ChecksumAlgorithm = cpu_to_le16(CHECKSUM_TYPE_UNCHANGED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) integr_info.Flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) integr_info.Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) return SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) cfile->fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) FSCTL_SET_INTEGRITY_INFORMATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) true /* is_fsctl */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) (char *)&integr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) sizeof(struct fsctl_set_integrity_information_req),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) CIFSMaxBufSize, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) &ret_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) /* GMT Token is @GMT-YYYY.MM.DD-HH.MM.SS Unicode which is 48 bytes + null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) #define GMT_TOKEN_SIZE 50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) #define MIN_SNAPSHOT_ARRAY_SIZE 16 /* See MS-SMB2 section 3.3.5.15.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) * Input buffer contains (empty) struct smb_snapshot array with size filled in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) * For output see struct SRV_SNAPSHOT_ARRAY in MS-SMB2 section 2.2.32.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) struct cifsFileInfo *cfile, void __user *ioc_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) char *retbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) unsigned int ret_data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) u32 max_response_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) struct smb_snapshot_array snapshot_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) * On the first query to enumerate the list of snapshots available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) * for this volume the buffer begins with 0 (number of snapshots
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) * which can be returned is zero since at that point we do not know
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) * how big the buffer needs to be). On the second query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) * it (ret_data_len) is set to number of snapshots so we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) * know to set the maximum response size larger (see below).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) if (get_user(ret_data_len, (unsigned int __user *)ioc_buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) * Note that for snapshot queries that servers like Azure expect that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) * the first query be minimal size (and just used to get the number/size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) * of previous versions) so response size must be specified as EXACTLY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) * sizeof(struct snapshot_array) which is 16 when rounded up to multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) * of eight bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) if (ret_data_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) max_response_size = MIN_SNAPSHOT_ARRAY_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) max_response_size = CIFSMaxBufSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) cfile->fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) FSCTL_SRV_ENUMERATE_SNAPSHOTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) true /* is_fsctl */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) NULL, 0 /* no input data */, max_response_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) (char **)&retbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) &ret_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) cifs_dbg(FYI, "enum snaphots ioctl returned %d and ret buflen is %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) rc, ret_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) if (ret_data_len && (ioc_buf != NULL) && (retbuf != NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) /* Fixup buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) if (copy_from_user(&snapshot_in, ioc_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) sizeof(struct smb_snapshot_array))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) kfree(retbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) * Check for min size, ie not large enough to fit even one GMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) * token (snapshot). On the first ioctl some users may pass in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) * smaller size (or zero) to simply get the size of the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) * so the user space caller can allocate sufficient memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) * and retry the ioctl again with larger array size sufficient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) * to hold all of the snapshot GMT tokens on the second try.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) if (snapshot_in.snapshot_array_size < GMT_TOKEN_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) ret_data_len = sizeof(struct smb_snapshot_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) * We return struct SRV_SNAPSHOT_ARRAY, followed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) * the snapshot array (of 50 byte GMT tokens) each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) * representing an available previous version of the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) if (ret_data_len > (snapshot_in.snapshot_array_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) sizeof(struct smb_snapshot_array)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) ret_data_len = snapshot_in.snapshot_array_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) sizeof(struct smb_snapshot_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) if (copy_to_user(ioc_buf, retbuf, ret_data_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) kfree(retbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) smb3_notify(const unsigned int xid, struct file *pfile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) void __user *ioc_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) struct smb3_notify notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) struct dentry *dentry = pfile->f_path.dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) struct inode *inode = file_inode(pfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) struct cifs_sb_info *cifs_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) unsigned char *path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) __le16 *utf16_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) path = build_path_from_dentry(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) if (path == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) cifs_sb = CIFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) if (utf16_path == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) goto notify_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) if (copy_from_user(¬ify, ioc_buf, sizeof(struct smb3_notify))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) goto notify_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) tcon = cifs_sb_master_tcon(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) goto notify_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) rc = SMB2_change_notify(xid, tcon, fid.persistent_fid, fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) notify.watch_tree, notify.completion_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) cifs_dbg(FYI, "change notify for path %s rc %d\n", path, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) notify_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) kfree(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) kfree(utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) const char *path, struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) struct cifs_fid *fid, __u16 search_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) struct cifs_search_info *srch_inf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) __le16 *utf16_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) struct smb_rqst rqst[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) struct kvec rsp_iov[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) int resp_buftype[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) struct kvec qd_iov[SMB2_QUERY_DIRECTORY_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) int rc, flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) struct smb2_query_directory_rsp *qd_rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) struct smb2_create_rsp *op_rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) if (!utf16_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) if (smb3_encryption_required(tcon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) flags |= CIFS_TRANSFORM_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) memset(rqst, 0, sizeof(rqst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) resp_buftype[0] = resp_buftype[1] = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) memset(rsp_iov, 0, sizeof(rsp_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) /* Open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) memset(&open_iov, 0, sizeof(open_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) rqst[0].rq_iov = open_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) oparms.fid = fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) rc = SMB2_open_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) &rqst[0], &oplock, &oparms, utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) goto qdf_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) smb2_set_next_command(tcon, &rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) /* Query directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) srch_inf->entries_in_buffer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) srch_inf->index_of_last_entry = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) memset(&qd_iov, 0, sizeof(qd_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) rqst[1].rq_iov = qd_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) rqst[1].rq_nvec = SMB2_QUERY_DIRECTORY_IOV_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) rc = SMB2_query_directory_init(xid, tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) &rqst[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) COMPOUND_FID, COMPOUND_FID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 0, srch_inf->info_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) goto qdf_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) smb2_set_related(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) rc = compound_send_recv(xid, tcon->ses, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) flags, 2, rqst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) resp_buftype, rsp_iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) /* If the open failed there is nothing to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) op_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) if (op_rsp == NULL || op_rsp->sync_hdr.Status != STATUS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) cifs_dbg(FYI, "query_dir_first: open failed rc=%d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) goto qdf_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) fid->persistent_fid = op_rsp->PersistentFileId;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) fid->volatile_fid = op_rsp->VolatileFileId;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) /* Anything else than ENODATA means a genuine error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) if (rc && rc != -ENODATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) cifs_dbg(FYI, "query_dir_first: query directory failed rc=%d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) trace_smb3_query_dir_err(xid, fid->persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) tcon->tid, tcon->ses->Suid, 0, 0, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) goto qdf_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) atomic_inc(&tcon->num_remote_opens);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) qd_rsp = (struct smb2_query_directory_rsp *)rsp_iov[1].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) if (qd_rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) trace_smb3_query_dir_done(xid, fid->persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) tcon->tid, tcon->ses->Suid, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) srch_inf->endOfSearch = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) goto qdf_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) rc = smb2_parse_query_directory(tcon, &rsp_iov[1], resp_buftype[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) srch_inf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) trace_smb3_query_dir_err(xid, fid->persistent_fid, tcon->tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) tcon->ses->Suid, 0, 0, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) goto qdf_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) resp_buftype[1] = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) trace_smb3_query_dir_done(xid, fid->persistent_fid, tcon->tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) tcon->ses->Suid, 0, srch_inf->entries_in_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) qdf_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) kfree(utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) SMB2_open_free(&rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) SMB2_query_directory_free(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) smb2_query_dir_next(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) struct cifs_fid *fid, __u16 search_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) struct cifs_search_info *srch_inf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) return SMB2_query_directory(xid, tcon, fid->persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) fid->volatile_fid, 0, srch_inf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) smb2_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) struct cifs_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) return SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) * If we negotiate SMB2 protocol and get STATUS_PENDING - update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) * the number of credits and return true. Otherwise - return false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) smb2_is_status_pending(char *buf, struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) if (shdr->Status != STATUS_PENDING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) if (shdr->CreditRequest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) spin_lock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) server->credits += le16_to_cpu(shdr->CreditRequest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) wake_up(&server->request_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) smb2_is_session_expired(char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) if (shdr->Status != STATUS_NETWORK_SESSION_EXPIRED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) shdr->Status != STATUS_USER_SESSION_DELETED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) trace_smb3_ses_expired(shdr->TreeId, shdr->SessionId,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) le16_to_cpu(shdr->Command),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) le64_to_cpu(shdr->MessageId));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) cifs_dbg(FYI, "Session expired or deleted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) smb2_is_status_io_timeout(char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) if (shdr->Status == STATUS_IO_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) struct cifsInodeInfo *cinode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) return SMB2_lease_break(0, tcon, cinode->lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) smb2_get_lease_state(cinode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) return SMB2_oplock_break(0, tcon, fid->persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) fid->volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) CIFS_CACHE_READ(cinode) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) smb2_set_related(struct smb_rqst *rqst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) struct smb2_sync_hdr *shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) if (shdr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) cifs_dbg(FYI, "shdr NULL in smb2_set_related\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) shdr->Flags |= SMB2_FLAGS_RELATED_OPERATIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) char smb2_padding[7] = {0, 0, 0, 0, 0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) struct smb2_sync_hdr *shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) struct cifs_ses *ses = tcon->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) struct TCP_Server_Info *server = ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) unsigned long len = smb_rqst_len(server, rqst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) int i, num_padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) if (shdr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) cifs_dbg(FYI, "shdr NULL in smb2_set_next_command\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) /* SMB headers in a compound are 8 byte aligned. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) /* No padding needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) if (!(len & 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) goto finished;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) num_padding = 8 - (len & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) if (!smb3_encryption_required(tcon)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) * If we do not have encryption then we can just add an extra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) * iov for the padding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) rqst->rq_iov[rqst->rq_nvec].iov_base = smb2_padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) rqst->rq_iov[rqst->rq_nvec].iov_len = num_padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) rqst->rq_nvec++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) len += num_padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) * We can not add a small padding iov for the encryption case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) * because the encryption framework can not handle the padding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) * iovs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) * We have to flatten this into a single buffer and add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) * the padding to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) for (i = 1; i < rqst->rq_nvec; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) memcpy(rqst->rq_iov[0].iov_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) rqst->rq_iov[0].iov_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) rqst->rq_iov[i].iov_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) rqst->rq_iov[i].iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) rqst->rq_iov[0].iov_len += rqst->rq_iov[i].iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) memset(rqst->rq_iov[0].iov_base + rqst->rq_iov[0].iov_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 0, num_padding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) rqst->rq_iov[0].iov_len += num_padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) len += num_padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) rqst->rq_nvec = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) finished:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) shdr->NextCommand = cpu_to_le32(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) * Passes the query info response back to the caller on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) * Caller need to free this with free_rsp_buf().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) __le16 *utf16_path, u32 desired_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) u32 class, u32 type, u32 output_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) struct kvec *rsp, int *buftype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) struct cifs_ses *ses = tcon->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) struct TCP_Server_Info *server = cifs_pick_channel(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) int flags = CIFS_CP_CREATE_CLOSE_OP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) struct smb_rqst rqst[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) int resp_buftype[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) struct kvec rsp_iov[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) struct kvec qi_iov[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) struct kvec close_iov[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) if (smb3_encryption_required(tcon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) flags |= CIFS_TRANSFORM_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) memset(rqst, 0, sizeof(rqst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) memset(rsp_iov, 0, sizeof(rsp_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) memset(&open_iov, 0, sizeof(open_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) rqst[0].rq_iov = open_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) oparms.desired_access = desired_access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) rc = SMB2_open_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) &rqst[0], &oplock, &oparms, utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) goto qic_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) smb2_set_next_command(tcon, &rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) memset(&qi_iov, 0, sizeof(qi_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) rqst[1].rq_iov = qi_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) rqst[1].rq_nvec = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) rc = SMB2_query_info_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) &rqst[1], COMPOUND_FID, COMPOUND_FID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) class, type, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) output_len, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) goto qic_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) smb2_set_next_command(tcon, &rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) smb2_set_related(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) memset(&close_iov, 0, sizeof(close_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) rqst[2].rq_iov = close_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) rqst[2].rq_nvec = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) rc = SMB2_close_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) goto qic_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) smb2_set_related(&rqst[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) rc = compound_send_recv(xid, ses, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) flags, 3, rqst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) resp_buftype, rsp_iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) if (rc == -EREMCHG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) tcon->need_reconnect = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) pr_warn_once("server share %s deleted\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) tcon->treeName);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) goto qic_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) *rsp = rsp_iov[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) *buftype = resp_buftype[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) qic_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) SMB2_open_free(&rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) SMB2_query_info_free(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) SMB2_close_free(&rqst[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) struct smb2_query_info_rsp *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) struct smb2_fs_full_size_info *info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) __le16 utf16_path = 0; /* Null - open root of share */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) struct kvec rsp_iov = {NULL, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) int buftype = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) rc = smb2_query_info_compound(xid, tcon, &utf16_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) FILE_READ_ATTRIBUTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) FS_FULL_SIZE_INFORMATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) SMB2_O_INFO_FILESYSTEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) sizeof(struct smb2_fs_full_size_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) &rsp_iov, &buftype, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) goto qfs_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) buf->f_type = SMB2_MAGIC_NUMBER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) info = (struct smb2_fs_full_size_info *)(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) le16_to_cpu(rsp->OutputBufferOffset) + (char *)rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) le32_to_cpu(rsp->OutputBufferLength),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) &rsp_iov,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) sizeof(struct smb2_fs_full_size_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) smb2_copy_fs_info_to_kstatfs(info, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) qfs_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) free_rsp_buf(buftype, rsp_iov.iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) __le16 srch_path = 0; /* Null - open root of share */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) if (!tcon->posix_extensions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) return smb2_queryfs(xid, tcon, cifs_sb, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) oparms.desired_access = FILE_READ_ATTRIBUTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) rc = SMB311_posix_qfs_info(xid, tcon, fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) fid.volatile_fid, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) buf->f_type = SMB2_MAGIC_NUMBER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) smb2_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) return ob1->fid.persistent_fid == ob2->fid.persistent_fid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) ob1->fid.volatile_fid == ob2->fid.volatile_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) smb2_mand_lock(const unsigned int xid, struct cifsFileInfo *cfile, __u64 offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) __u64 length, __u32 type, int lock, int unlock, bool wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) if (unlock && !lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) type = SMB2_LOCKFLAG_UNLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) return SMB2_lock(xid, tlink_tcon(cfile->tlink),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) cfile->fid.persistent_fid, cfile->fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) current->tgid, length, offset, type, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) smb2_get_lease_key(struct inode *inode, struct cifs_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) memcpy(fid->lease_key, CIFS_I(inode)->lease_key, SMB2_LEASE_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) smb2_set_lease_key(struct inode *inode, struct cifs_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) memcpy(CIFS_I(inode)->lease_key, fid->lease_key, SMB2_LEASE_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) smb2_new_lease_key(struct cifs_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) generate_random_uuid(fid->lease_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) const char *search_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) struct dfs_info3_param **target_nodes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) unsigned int *num_of_nodes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) const struct nls_table *nls_codepage, int remap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) __le16 *utf16_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) int utf16_path_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) struct fsctl_get_dfs_referral_req *dfs_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) struct get_dfs_referral_rsp *dfs_rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) u32 dfs_req_size = 0, dfs_rsp_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) cifs_dbg(FYI, "%s: path: %s\n", __func__, search_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) * Try to use the IPC tcon, otherwise just use any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) tcon = ses->tcon_ipc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) if (tcon == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) tcon = list_first_entry_or_null(&ses->tcon_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) struct cifs_tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) tcon_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) if (tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) tcon->tc_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) if (tcon == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) cifs_dbg(VFS, "session %p has no tcon available for a dfs referral request\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) rc = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) utf16_path = cifs_strndup_to_utf16(search_name, PATH_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) &utf16_path_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) nls_codepage, remap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) if (!utf16_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) dfs_req_size = sizeof(*dfs_req) + utf16_path_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) dfs_req = kzalloc(dfs_req_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) if (!dfs_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) /* Highest DFS referral version understood */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) dfs_req->MaxReferralLevel = DFS_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) /* Path to resolve in an UTF-16 null-terminated string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) memcpy(dfs_req->RequestFileName, utf16_path, utf16_path_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) FSCTL_DFS_GET_REFERRALS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) true /* is_fsctl */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) (char *)dfs_req, dfs_req_size, CIFSMaxBufSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) (char **)&dfs_rsp, &dfs_rsp_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) } while (rc == -EAGAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) if ((rc != -ENOENT) && (rc != -EOPNOTSUPP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) cifs_tcon_dbg(VFS, "ioctl error in %s rc=%d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) rc = parse_dfs_referrals(dfs_rsp, dfs_rsp_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) num_of_nodes, target_nodes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) nls_codepage, remap, search_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) true /* is_unicode */);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) cifs_tcon_dbg(VFS, "parse error in %s rc=%d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) if (tcon && !tcon->ipc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) /* ipc tcons are not refcounted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) tcon->tc_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) kfree(utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) kfree(dfs_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) kfree(dfs_rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) parse_reparse_posix(struct reparse_posix_data *symlink_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) u32 plen, char **target_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) /* See MS-FSCC 2.1.2.6 for the 'NFS' style reparse tags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) len = le16_to_cpu(symlink_buf->ReparseDataLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) if (le64_to_cpu(symlink_buf->InodeType) != NFS_SPECFILE_LNK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) cifs_dbg(VFS, "%lld not a supported symlink type\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) le64_to_cpu(symlink_buf->InodeType));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) *target_path = cifs_strndup_from_utf16(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) symlink_buf->PathBuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) len, true, cifs_sb->local_nls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) if (!(*target_path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) convert_delimiter(*target_path, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) parse_reparse_symlink(struct reparse_symlink_data_buffer *symlink_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) u32 plen, char **target_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) unsigned int sub_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) unsigned int sub_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) /* We handle Symbolic Link reparse tag here. See: MS-FSCC 2.1.2.4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) sub_offset = le16_to_cpu(symlink_buf->SubstituteNameOffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) sub_len = le16_to_cpu(symlink_buf->SubstituteNameLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) if (sub_offset + 20 > plen ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) sub_offset + sub_len + 20 > plen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) cifs_dbg(VFS, "srv returned malformed symlink buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) *target_path = cifs_strndup_from_utf16(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) symlink_buf->PathBuffer + sub_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) sub_len, true, cifs_sb->local_nls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) if (!(*target_path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) convert_delimiter(*target_path, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) parse_reparse_point(struct reparse_data_buffer *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) u32 plen, char **target_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) if (plen < sizeof(struct reparse_data_buffer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) cifs_dbg(VFS, "reparse buffer is too small. Must be at least 8 bytes but was %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) if (plen < le16_to_cpu(buf->ReparseDataLength) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) sizeof(struct reparse_data_buffer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) cifs_dbg(VFS, "srv returned invalid reparse buf length: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) /* See MS-FSCC 2.1.2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) switch (le32_to_cpu(buf->ReparseTag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) case IO_REPARSE_TAG_NFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) return parse_reparse_posix(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) (struct reparse_posix_data *)buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) plen, target_path, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) case IO_REPARSE_TAG_SYMLINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) return parse_reparse_symlink(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) (struct reparse_symlink_data_buffer *)buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) plen, target_path, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) cifs_dbg(VFS, "srv returned unknown symlink buffer tag:0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) le32_to_cpu(buf->ReparseTag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) #define SMB2_SYMLINK_STRUCT_SIZE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) struct cifs_sb_info *cifs_sb, const char *full_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) char **target_path, bool is_reparse_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) __le16 *utf16_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) struct kvec err_iov = {NULL, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) struct smb2_err_rsp *err_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) struct smb2_symlink_err_rsp *symlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) unsigned int sub_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) unsigned int sub_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) unsigned int print_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) unsigned int print_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) int flags = CIFS_CP_CREATE_CLOSE_OP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) struct smb_rqst rqst[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) int resp_buftype[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) struct kvec rsp_iov[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) struct kvec close_iov[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) struct smb2_create_rsp *create_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) struct smb2_ioctl_rsp *ioctl_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) struct reparse_data_buffer *reparse_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) int create_options = is_reparse_point ? OPEN_REPARSE_POINT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) u32 plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) *target_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) if (smb3_encryption_required(tcon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) flags |= CIFS_TRANSFORM_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) memset(rqst, 0, sizeof(rqst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) memset(rsp_iov, 0, sizeof(rsp_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) if (!utf16_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) /* Open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) memset(&open_iov, 0, sizeof(open_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) rqst[0].rq_iov = open_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) memset(&oparms, 0, sizeof(oparms));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) oparms.desired_access = FILE_READ_ATTRIBUTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) oparms.create_options = cifs_create_options(cifs_sb, create_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) rc = SMB2_open_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) &rqst[0], &oplock, &oparms, utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) goto querty_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) smb2_set_next_command(tcon, &rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) /* IOCTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) memset(&io_iov, 0, sizeof(io_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) rqst[1].rq_iov = io_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) rc = SMB2_ioctl_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) &rqst[1], fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) fid.volatile_fid, FSCTL_GET_REPARSE_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) true /* is_fctl */, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) CIFSMaxBufSize -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) MAX_SMB2_CREATE_RESPONSE_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) MAX_SMB2_CLOSE_RESPONSE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) goto querty_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) smb2_set_next_command(tcon, &rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) smb2_set_related(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) /* Close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) memset(&close_iov, 0, sizeof(close_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) rqst[2].rq_iov = close_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) rqst[2].rq_nvec = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) rc = SMB2_close_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) goto querty_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) smb2_set_related(&rqst[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) rc = compound_send_recv(xid, tcon->ses, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) flags, 3, rqst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) resp_buftype, rsp_iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) create_rsp = rsp_iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) if (create_rsp && create_rsp->sync_hdr.Status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) err_iov = rsp_iov[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) ioctl_rsp = rsp_iov[1].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) * Open was successful and we got an ioctl response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) if ((rc == 0) && (is_reparse_point)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) /* See MS-FSCC 2.3.23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) reparse_buf = (struct reparse_data_buffer *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) ((char *)ioctl_rsp +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) le32_to_cpu(ioctl_rsp->OutputOffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) plen = le32_to_cpu(ioctl_rsp->OutputCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) if (plen + le32_to_cpu(ioctl_rsp->OutputOffset) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) rsp_iov[1].iov_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) cifs_tcon_dbg(VFS, "srv returned invalid ioctl len: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) goto querty_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) rc = parse_reparse_point(reparse_buf, plen, target_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) goto querty_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) if (!rc || !err_iov.iov_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) goto querty_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) err_buf = err_iov.iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) goto querty_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) if (le32_to_cpu(symlink->SymLinkErrorTag) != SYMLINK_ERROR_TAG ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) le32_to_cpu(symlink->ReparseTag) != IO_REPARSE_TAG_SYMLINK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) goto querty_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) /* open must fail on symlink - reset rc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) sub_len = le16_to_cpu(symlink->SubstituteNameLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) sub_offset = le16_to_cpu(symlink->SubstituteNameOffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) print_len = le16_to_cpu(symlink->PrintNameLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) print_offset = le16_to_cpu(symlink->PrintNameOffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) if (err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) goto querty_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) if (err_iov.iov_len <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) goto querty_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) *target_path = cifs_strndup_from_utf16(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) (char *)symlink->PathBuffer + sub_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) sub_len, true, cifs_sb->local_nls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) if (!(*target_path)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) goto querty_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) convert_delimiter(*target_path, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) querty_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) cifs_dbg(FYI, "query symlink rc %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) kfree(utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) SMB2_open_free(&rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) SMB2_ioctl_free(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) SMB2_close_free(&rqst[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) struct cifs_sb_info *cifs_sb, const char *full_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) __u32 *tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) __le16 *utf16_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) int flags = CIFS_CP_CREATE_CLOSE_OP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) struct smb_rqst rqst[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) int resp_buftype[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) struct kvec rsp_iov[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) struct kvec close_iov[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) struct smb2_ioctl_rsp *ioctl_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) struct reparse_data_buffer *reparse_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) u32 plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) if (smb3_encryption_required(tcon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) flags |= CIFS_TRANSFORM_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) memset(rqst, 0, sizeof(rqst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) memset(rsp_iov, 0, sizeof(rsp_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) if (!utf16_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) * setup smb2open - TODO add optimization to call cifs_get_readable_path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) * to see if there is a handle already open that we can use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) memset(&open_iov, 0, sizeof(open_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) rqst[0].rq_iov = open_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) memset(&oparms, 0, sizeof(oparms));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) oparms.desired_access = FILE_READ_ATTRIBUTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) oparms.create_options = cifs_create_options(cifs_sb, OPEN_REPARSE_POINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) rc = SMB2_open_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) &rqst[0], &oplock, &oparms, utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) goto query_rp_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) smb2_set_next_command(tcon, &rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) /* IOCTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) memset(&io_iov, 0, sizeof(io_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) rqst[1].rq_iov = io_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) rc = SMB2_ioctl_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) &rqst[1], COMPOUND_FID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) COMPOUND_FID, FSCTL_GET_REPARSE_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) true /* is_fctl */, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) CIFSMaxBufSize -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) MAX_SMB2_CREATE_RESPONSE_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) MAX_SMB2_CLOSE_RESPONSE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) goto query_rp_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) smb2_set_next_command(tcon, &rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) smb2_set_related(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) /* Close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) memset(&close_iov, 0, sizeof(close_iov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) rqst[2].rq_iov = close_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) rqst[2].rq_nvec = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) rc = SMB2_close_init(tcon, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) goto query_rp_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) smb2_set_related(&rqst[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) rc = compound_send_recv(xid, tcon->ses, server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) flags, 3, rqst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) resp_buftype, rsp_iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) ioctl_rsp = rsp_iov[1].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) * Open was successful and we got an ioctl response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) /* See MS-FSCC 2.3.23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) reparse_buf = (struct reparse_data_buffer *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) ((char *)ioctl_rsp +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) le32_to_cpu(ioctl_rsp->OutputOffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) plen = le32_to_cpu(ioctl_rsp->OutputCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) if (plen + le32_to_cpu(ioctl_rsp->OutputOffset) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) rsp_iov[1].iov_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) cifs_tcon_dbg(FYI, "srv returned invalid ioctl len: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) goto query_rp_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) *tag = le32_to_cpu(reparse_buf->ReparseTag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) query_rp_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) kfree(utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) SMB2_open_free(&rqst[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) SMB2_ioctl_free(&rqst[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) SMB2_close_free(&rqst[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) static struct cifs_ntsd *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) get_smb2_acl_by_fid(struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) const struct cifs_fid *cifsfid, u32 *pacllen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) struct cifs_ntsd *pntsd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) int rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) if (IS_ERR(tlink))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) return ERR_CAST(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) cifs_dbg(FYI, "trying to get acl\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) rc = SMB2_query_acl(xid, tlink_tcon(tlink), cifsfid->persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) cifsfid->volatile_fid, (void **)&pntsd, pacllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) return pntsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) static struct cifs_ntsd *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) const char *path, u32 *pacllen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) struct cifs_ntsd *pntsd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) __le16 *utf16_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) cifs_dbg(FYI, "get smb3 acl for path %s\n", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) if (IS_ERR(tlink))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) return ERR_CAST(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) tcon = tlink_tcon(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) if (!utf16_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) oparms.desired_access = READ_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) * When querying an ACL, even if the file is a symlink we want to open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) * the source not the target, and so the protocol requires that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) * client specify this flag when opening a reparse point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) oparms.create_options = cifs_create_options(cifs_sb, 0) | OPEN_REPARSE_POINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) kfree(utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) rc = SMB2_query_acl(xid, tlink_tcon(tlink), fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) fid.volatile_fid, (void **)&pntsd, pacllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) return pntsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) struct inode *inode, const char *path, int aclflag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) int rc, access_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) __le16 *utf16_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) cifs_dbg(FYI, "set smb3 acl for path %s\n", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) if (IS_ERR(tlink))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) return PTR_ERR(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) tcon = tlink_tcon(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) access_flags = WRITE_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) access_flags = WRITE_DAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) if (!utf16_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) oparms.desired_access = access_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) oparms.path = path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) kfree(utf16_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) rc = SMB2_set_acl(xid, tlink_tcon(tlink), fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) fid.volatile_fid, pnntsd, acllen, aclflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) /* Retrieve an ACL from the server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) static struct cifs_ntsd *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) get_smb2_acl(struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) struct inode *inode, const char *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) u32 *pacllen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) struct cifs_ntsd *pntsd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) struct cifsFileInfo *open_file = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) if (inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) open_file = find_readable_file(CIFS_I(inode), true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) if (!open_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) return get_smb2_acl_by_path(cifs_sb, path, pacllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) pntsd = get_smb2_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) cifsFileInfo_put(open_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) return pntsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) loff_t offset, loff_t len, bool keep_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) struct cifs_ses *ses = tcon->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) struct cifsInodeInfo *cifsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) struct cifsFileInfo *cfile = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) struct file_zero_data_information fsctl_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) long rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) __le64 eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) inode = d_inode(cfile->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) cifsi = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) trace_smb3_zero_enter(xid, cfile->fid.persistent_fid, tcon->tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) ses->Suid, offset, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) * We zero the range through ioctl, so we need remove the page caches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) * first, otherwise the data may be inconsistent with the server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) truncate_pagecache_range(inode, offset, offset + len - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) /* if file not oplocked can't be sure whether asking to extend size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) if (!CIFS_CACHE_READ(cifsi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) if (keep_size == false) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) trace_smb3_zero_err(xid, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) tcon->tid, ses->Suid, offset, len, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) cifs_dbg(FYI, "Offset %lld len %lld\n", offset, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) fsctl_buf.FileOffset = cpu_to_le64(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) cfile->fid.volatile_fid, FSCTL_SET_ZERO_DATA, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) (char *)&fsctl_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) sizeof(struct file_zero_data_information),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 0, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) goto zero_range_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) * do we also need to change the size of the file?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) if (keep_size == false && i_size_read(inode) < offset + len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) eof = cpu_to_le64(offset + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) cfile->fid.volatile_fid, cfile->pid, &eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) zero_range_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) trace_smb3_zero_err(xid, cfile->fid.persistent_fid, tcon->tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) ses->Suid, offset, len, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) trace_smb3_zero_done(xid, cfile->fid.persistent_fid, tcon->tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) ses->Suid, offset, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) loff_t offset, loff_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) struct cifsFileInfo *cfile = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) struct file_zero_data_information fsctl_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) long rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) __u8 set_sparse = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) inode = d_inode(cfile->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) /* Need to make file sparse, if not already, before freeing range. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) /* Consider adding equivalent for compressed since it could also work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) if (!smb2_set_sparse(xid, tcon, cfile, inode, set_sparse)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) * We implement the punch hole through ioctl, so we need remove the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) * caches first, otherwise the data may be inconsistent with the server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) truncate_pagecache_range(inode, offset, offset + len - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) cifs_dbg(FYI, "Offset %lld len %lld\n", offset, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) fsctl_buf.FileOffset = cpu_to_le64(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) cfile->fid.volatile_fid, FSCTL_SET_ZERO_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) true /* is_fctl */, (char *)&fsctl_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) sizeof(struct file_zero_data_information),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) CIFSMaxBufSize, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) static int smb3_simple_fallocate_write_range(unsigned int xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) struct cifsFileInfo *cfile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) loff_t off, loff_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) struct cifs_io_parms io_parms = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) int nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) struct kvec iov[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) io_parms.netfid = cfile->fid.netfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) io_parms.pid = current->tgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) io_parms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) io_parms.persistent_fid = cfile->fid.persistent_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) io_parms.volatile_fid = cfile->fid.volatile_fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) while (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) io_parms.offset = off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) io_parms.length = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) if (io_parms.length > SMB2_MAX_BUFFER_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) io_parms.length = SMB2_MAX_BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) /* iov[0] is reserved for smb header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) iov[1].iov_base = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) iov[1].iov_len = io_parms.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) rc = SMB2_write(xid, &io_parms, &nbytes, iov, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) if (nbytes > len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) buf += nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) off += nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) len -= nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) static int smb3_simple_fallocate_range(unsigned int xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) struct cifsFileInfo *cfile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) loff_t off, loff_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) struct file_allocated_range_buffer in_data, *out_data = NULL, *tmp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) u32 out_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) char *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) loff_t l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) in_data.file_offset = cpu_to_le64(off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) in_data.length = cpu_to_le64(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) cfile->fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) FSCTL_QUERY_ALLOCATED_RANGES, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) (char *)&in_data, sizeof(in_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 1024 * sizeof(struct file_allocated_range_buffer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) (char **)&out_data, &out_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) buf = kzalloc(1024 * 1024, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) if (buf == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) tmp_data = out_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) while (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) * The rest of the region is unmapped so write it all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) if (out_data_len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) rc = smb3_simple_fallocate_write_range(xid, tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) cfile, off, len, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) if (out_data_len < sizeof(struct file_allocated_range_buffer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) if (off < le64_to_cpu(tmp_data->file_offset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) * We are at a hole. Write until the end of the region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) * or until the next allocated data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) * whichever comes next.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) l = le64_to_cpu(tmp_data->file_offset) - off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) if (len < l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) l = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) rc = smb3_simple_fallocate_write_range(xid, tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) cfile, off, l, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) off = off + l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) len = len - l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) * We are at a section of allocated data, just skip forward
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) * until the end of the data or the end of the region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) * we are supposed to fallocate, whichever comes first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) l = le64_to_cpu(tmp_data->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) if (len < l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) l = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) off += l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) len -= l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) tmp_data = &tmp_data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) out_data_len -= sizeof(struct file_allocated_range_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) kfree(out_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) loff_t off, loff_t len, bool keep_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) struct cifsInodeInfo *cifsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) struct cifsFileInfo *cfile = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) long rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) __le64 eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) inode = d_inode(cfile->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) cifsi = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) trace_smb3_falloc_enter(xid, cfile->fid.persistent_fid, tcon->tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) tcon->ses->Suid, off, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) /* if file not oplocked can't be sure whether asking to extend size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) if (!CIFS_CACHE_READ(cifsi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) if (keep_size == false) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) trace_smb3_falloc_err(xid, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) tcon->tid, tcon->ses->Suid, off, len, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) * Extending the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) if ((keep_size == false) && i_size_read(inode) < off + len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) rc = inode_newsize_ok(inode, off + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) smb2_set_sparse(xid, tcon, cfile, inode, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) eof = cpu_to_le64(off + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) cfile->fid.volatile_fid, cfile->pid, &eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) cifsi->server_eof = off + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) cifs_setsize(inode, off + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) cifs_truncate_page(inode->i_mapping, inode->i_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) truncate_setsize(inode, off + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) * Files are non-sparse by default so falloc may be a no-op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) * Must check if file sparse. If not sparse, and since we are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) * extending then no need to do anything since file already allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) if (keep_size == true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) * We can not preallocate pages beyond the end of the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) * in SMB2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) if (off >= i_size_read(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) * For fallocates that are partially beyond the end of file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) * clamp len so we only fallocate up to the end of file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) if (off + len > i_size_read(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) len = i_size_read(inode) - off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) if ((keep_size == true) || (i_size_read(inode) >= off + len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) * At this point, we are trying to fallocate an internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) * regions of a sparse file. Since smb2 does not have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) * fallocate command we have two otions on how to emulate this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) * We can either turn the entire file to become non-sparse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) * which we only do if the fallocate is for virtually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) * the whole file, or we can overwrite the region with zeroes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) * using SMB2_write, which could be prohibitevly expensive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) * if len is large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) * We are only trying to fallocate a small region so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) * just write it with zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) if (len <= 1024 * 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) rc = smb3_simple_fallocate_range(xid, tcon, cfile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) off, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) * Check if falloc starts within first few pages of file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) * and ends within a few pages of the end of file to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) * ensure that most of file is being forced to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) * fallocated now. If so then setting whole file sparse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) * ie potentially making a few extra pages at the beginning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) * or end of the file non-sparse via set_sparse is harmless.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) if ((off > 8192) || (off + len + 8192 < i_size_read(inode))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) smb2_set_sparse(xid, tcon, cfile, inode, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) trace_smb3_falloc_err(xid, cfile->fid.persistent_fid, tcon->tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) tcon->ses->Suid, off, len, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) trace_smb3_falloc_done(xid, cfile->fid.persistent_fid, tcon->tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) tcon->ses->Suid, off, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) static loff_t smb3_llseek(struct file *file, struct cifs_tcon *tcon, loff_t offset, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) struct cifsFileInfo *wrcfile, *cfile = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) struct cifsInodeInfo *cifsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) struct file_allocated_range_buffer in_data, *out_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) u32 out_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) if (whence != SEEK_HOLE && whence != SEEK_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) return generic_file_llseek(file, offset, whence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) inode = d_inode(cfile->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) cifsi = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) if (offset < 0 || offset >= i_size_read(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) * We need to be sure that all dirty pages are written as they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) * might fill holes on the server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) * Note that we also MUST flush any written pages since at least
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) * some servers (Windows2016) will not reflect recent writes in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) * QUERY_ALLOCATED_RANGES until SMB2_flush is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) wrcfile = find_writable_file(cifsi, FIND_WR_ANY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) if (wrcfile) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) filemap_write_and_wait(inode->i_mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) smb2_flush_file(xid, tcon, &wrcfile->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) cifsFileInfo_put(wrcfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) if (whence == SEEK_HOLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) offset = i_size_read(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) goto lseek_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) in_data.file_offset = cpu_to_le64(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) in_data.length = cpu_to_le64(i_size_read(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) cfile->fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) FSCTL_QUERY_ALLOCATED_RANGES, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) (char *)&in_data, sizeof(in_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) sizeof(struct file_allocated_range_buffer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) (char **)&out_data, &out_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) if (rc == -E2BIG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) goto lseek_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) if (whence == SEEK_HOLE && out_data_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) goto lseek_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) if (whence == SEEK_DATA && out_data_len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) rc = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) goto lseek_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) if (out_data_len < sizeof(struct file_allocated_range_buffer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) goto lseek_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) if (whence == SEEK_DATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) offset = le64_to_cpu(out_data->file_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) goto lseek_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) if (offset < le64_to_cpu(out_data->file_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) goto lseek_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) offset = le64_to_cpu(out_data->file_offset) + le64_to_cpu(out_data->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) lseek_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) kfree(out_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) return vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) static int smb3_fiemap(struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) struct cifsFileInfo *cfile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) struct fiemap_extent_info *fei, u64 start, u64 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) struct file_allocated_range_buffer in_data, *out_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) u32 out_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) int i, num, rc, flags, last_blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) u64 next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) rc = fiemap_prep(d_inode(cfile->dentry), fei, start, &len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) in_data.file_offset = cpu_to_le64(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) in_data.length = cpu_to_le64(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) cfile->fid.volatile_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) FSCTL_QUERY_ALLOCATED_RANGES, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) (char *)&in_data, sizeof(in_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 1024 * sizeof(struct file_allocated_range_buffer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) (char **)&out_data, &out_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) if (rc == -E2BIG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) last_blob = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) last_blob = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) if (out_data_len && out_data_len < sizeof(struct file_allocated_range_buffer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) if (out_data_len % sizeof(struct file_allocated_range_buffer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) num = out_data_len / sizeof(struct file_allocated_range_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) if (i == num - 1 && last_blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) flags |= FIEMAP_EXTENT_LAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) rc = fiemap_fill_next_extent(fei,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) le64_to_cpu(out_data[i].file_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) le64_to_cpu(out_data[i].file_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) le64_to_cpu(out_data[i].length),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) if (rc == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) if (!last_blob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) next = le64_to_cpu(out_data[num - 1].file_offset) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) le64_to_cpu(out_data[num - 1].length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) len = len - (next - start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) start = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) kfree(out_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) static long smb3_fallocate(struct file *file, struct cifs_tcon *tcon, int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) loff_t off, loff_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) /* KEEP_SIZE already checked for by do_fallocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) if (mode & FALLOC_FL_PUNCH_HOLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) return smb3_punch_hole(file, tcon, off, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) else if (mode & FALLOC_FL_ZERO_RANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) if (mode & FALLOC_FL_KEEP_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) return smb3_zero_range(file, tcon, off, len, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) return smb3_zero_range(file, tcon, off, len, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) } else if (mode == FALLOC_FL_KEEP_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) return smb3_simple_falloc(file, tcon, off, len, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) else if (mode == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) return smb3_simple_falloc(file, tcon, off, len, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) smb2_downgrade_oplock(struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) struct cifsInodeInfo *cinode, __u32 oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) unsigned int epoch, bool *purge_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) server->ops->set_oplock_level(cinode, oplock, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) unsigned int epoch, bool *purge_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) smb3_downgrade_oplock(struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) struct cifsInodeInfo *cinode, __u32 oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) unsigned int epoch, bool *purge_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) unsigned int old_state = cinode->oplock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) unsigned int old_epoch = cinode->epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) unsigned int new_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) if (epoch > old_epoch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) smb21_set_oplock_level(cinode, oplock, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) cinode->epoch = epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) new_state = cinode->oplock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) *purge_cache = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) if ((old_state & CIFS_CACHE_READ_FLG) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) (new_state & CIFS_CACHE_READ_FLG) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) *purge_cache = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) else if (old_state == new_state && (epoch - old_epoch > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) *purge_cache = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) unsigned int epoch, bool *purge_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) oplock &= 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) if (oplock == SMB2_OPLOCK_LEVEL_BATCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) cinode->oplock = CIFS_CACHE_RHW_FLG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) cifs_dbg(FYI, "Batch Oplock granted on inode %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) &cinode->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) } else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) cinode->oplock = CIFS_CACHE_RW_FLG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) &cinode->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) } else if (oplock == SMB2_OPLOCK_LEVEL_II) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) cinode->oplock = CIFS_CACHE_READ_FLG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) cifs_dbg(FYI, "Level II Oplock granted on inode %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) &cinode->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) cinode->oplock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) unsigned int epoch, bool *purge_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) char message[5] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) unsigned int new_oplock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) oplock &= 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) /* Check if the server granted an oplock rather than a lease */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) if (oplock & SMB2_OPLOCK_LEVEL_EXCLUSIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) return smb2_set_oplock_level(cinode, oplock, epoch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) purge_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) if (oplock & SMB2_LEASE_READ_CACHING_HE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) new_oplock |= CIFS_CACHE_READ_FLG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) strcat(message, "R");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) if (oplock & SMB2_LEASE_HANDLE_CACHING_HE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) new_oplock |= CIFS_CACHE_HANDLE_FLG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) strcat(message, "H");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) if (oplock & SMB2_LEASE_WRITE_CACHING_HE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) new_oplock |= CIFS_CACHE_WRITE_FLG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) strcat(message, "W");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) if (!new_oplock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) strncpy(message, "None", sizeof(message));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) cinode->oplock = new_oplock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) cifs_dbg(FYI, "%s Lease granted on inode %p\n", message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) &cinode->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) unsigned int epoch, bool *purge_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) unsigned int old_oplock = cinode->oplock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) smb21_set_oplock_level(cinode, oplock, epoch, purge_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) if (purge_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) *purge_cache = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) if (old_oplock == CIFS_CACHE_READ_FLG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) if (cinode->oplock == CIFS_CACHE_READ_FLG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) (epoch - cinode->epoch > 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) *purge_cache = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) else if (cinode->oplock == CIFS_CACHE_RH_FLG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) (epoch - cinode->epoch > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) *purge_cache = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) else if (cinode->oplock == CIFS_CACHE_RHW_FLG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) (epoch - cinode->epoch > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) *purge_cache = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) else if (cinode->oplock == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) (epoch - cinode->epoch > 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) *purge_cache = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) } else if (old_oplock == CIFS_CACHE_RH_FLG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) if (cinode->oplock == CIFS_CACHE_RH_FLG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) (epoch - cinode->epoch > 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) *purge_cache = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) else if (cinode->oplock == CIFS_CACHE_RHW_FLG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) (epoch - cinode->epoch > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) *purge_cache = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) cinode->epoch = epoch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) smb2_is_read_op(__u32 oplock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) return oplock == SMB2_OPLOCK_LEVEL_II;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) smb21_is_read_op(__u32 oplock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) return (oplock & SMB2_LEASE_READ_CACHING_HE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) !(oplock & SMB2_LEASE_WRITE_CACHING_HE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) static __le32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) map_oplock_to_lease(u8 oplock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) else if (oplock == SMB2_OPLOCK_LEVEL_II)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) return SMB2_LEASE_READ_CACHING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) else if (oplock == SMB2_OPLOCK_LEVEL_BATCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) return SMB2_LEASE_HANDLE_CACHING | SMB2_LEASE_READ_CACHING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) SMB2_LEASE_WRITE_CACHING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) static char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) smb2_create_lease_buf(u8 *lease_key, u8 oplock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) struct create_lease *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) buf = kzalloc(sizeof(struct create_lease), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) memcpy(&buf->lcontext.LeaseKey, lease_key, SMB2_LEASE_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) buf->ccontext.DataOffset = cpu_to_le16(offsetof
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) (struct create_lease, lcontext));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) buf->ccontext.NameOffset = cpu_to_le16(offsetof
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) (struct create_lease, Name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) buf->ccontext.NameLength = cpu_to_le16(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) /* SMB2_CREATE_REQUEST_LEASE is "RqLs" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) buf->Name[0] = 'R';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) buf->Name[1] = 'q';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) buf->Name[2] = 'L';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) buf->Name[3] = 's';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) return (char *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) static char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) smb3_create_lease_buf(u8 *lease_key, u8 oplock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) struct create_lease_v2 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) buf = kzalloc(sizeof(struct create_lease_v2), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) memcpy(&buf->lcontext.LeaseKey, lease_key, SMB2_LEASE_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) buf->ccontext.DataOffset = cpu_to_le16(offsetof
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) (struct create_lease_v2, lcontext));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) buf->ccontext.NameOffset = cpu_to_le16(offsetof
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) (struct create_lease_v2, Name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) buf->ccontext.NameLength = cpu_to_le16(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) /* SMB2_CREATE_REQUEST_LEASE is "RqLs" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) buf->Name[0] = 'R';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) buf->Name[1] = 'q';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) buf->Name[2] = 'L';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) buf->Name[3] = 's';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) return (char *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) static __u8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) smb2_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) struct create_lease *lc = (struct create_lease *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) *epoch = 0; /* not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) return SMB2_OPLOCK_LEVEL_NOCHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) return le32_to_cpu(lc->lcontext.LeaseState);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) static __u8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) smb3_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) *epoch = le16_to_cpu(lc->lcontext.Epoch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) return SMB2_OPLOCK_LEVEL_NOCHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) if (lease_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) memcpy(lease_key, &lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) return le32_to_cpu(lc->lcontext.LeaseState);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) smb2_wp_retry_size(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) return min_t(unsigned int, CIFS_SB(inode->i_sb)->wsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) SMB2_MAX_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) smb2_dir_needs_close(struct cifsFileInfo *cfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) return !cfile->invalidHandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) struct smb_rqst *old_rq, __le16 cipher_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) struct smb2_sync_hdr *shdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) (struct smb2_sync_hdr *)old_rq->rq_iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) memset(tr_hdr, 0, sizeof(struct smb2_transform_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) tr_hdr->ProtocolId = SMB2_TRANSFORM_PROTO_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) tr_hdr->OriginalMessageSize = cpu_to_le32(orig_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) tr_hdr->Flags = cpu_to_le16(0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) if ((cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) (cipher_type == SMB2_ENCRYPTION_AES256_GCM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) get_random_bytes(&tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) get_random_bytes(&tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) /* We can not use the normal sg_set_buf() as we will sometimes pass a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) * stack object as buf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) unsigned int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) void *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) * VMAP_STACK (at least) puts stack into the vmalloc address space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) if (is_vmalloc_addr(buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) addr = vmalloc_to_page(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) addr = virt_to_page(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) sg_set_page(sg, addr, buflen, offset_in_page(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) /* Assumes the first rqst has a transform header as the first iov.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) * I.e.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) * rqst[0].rq_iov[0] is transform header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) * rqst[0].rq_iov[1+] data to be encrypted/decrypted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) static struct scatterlist *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) init_sg(int num_rqst, struct smb_rqst *rqst, u8 *sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) unsigned int sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) unsigned int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) unsigned int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) int skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) sg_len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) for (i = 0; i < num_rqst; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) sg_len += rqst[i].rq_nvec + rqst[i].rq_npages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) sg = kmalloc_array(sg_len, sizeof(struct scatterlist), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) if (!sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) sg_init_table(sg, sg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) for (i = 0; i < num_rqst; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) for (j = 0; j < rqst[i].rq_nvec; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) * The first rqst has a transform header where the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) * first 20 bytes are not part of the encrypted blob
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) skip = (i == 0) && (j == 0) ? 20 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) smb2_sg_set_buf(&sg[idx++],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) rqst[i].rq_iov[j].iov_base + skip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) rqst[i].rq_iov[j].iov_len - skip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) for (j = 0; j < rqst[i].rq_npages; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) unsigned int len, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) rqst_page_get_length(&rqst[i], j, &len, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) sg_set_page(&sg[idx++], rqst[i].rq_pages[j], len, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) smb2_sg_set_buf(&sg[idx], sign, SMB2_SIGNATURE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) return sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) struct cifs_ses *ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) u8 *ses_enc_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) if (ses->Suid == ses_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) ses_enc_key = enc ? ses->smb3encryptionkey :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) ses->smb3decryptionkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) * Encrypt or decrypt @rqst message. @rqst[0] has the following format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) * iov[0] - transform header (associate data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) * iov[1-N] - SMB2 header and pages - data to encrypt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) * On success return encrypted data in iov[1-N] and pages, leave iov[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) * untouched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) crypt_message(struct TCP_Server_Info *server, int num_rqst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) struct smb_rqst *rqst, int enc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) struct smb2_transform_hdr *tr_hdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) (struct smb2_transform_hdr *)rqst[0].rq_iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) u8 sign[SMB2_SIGNATURE_SIZE] = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) u8 key[SMB3_ENC_DEC_KEY_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) struct aead_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) char *iv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) unsigned int iv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) DECLARE_CRYPTO_WAIT(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) struct crypto_aead *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) rc = smb2_get_enc_key(server, tr_hdr->SessionId, enc, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) cifs_server_dbg(VFS, "%s: Could not get %scryption key\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) enc ? "en" : "de");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) rc = smb3_crypto_aead_allocate(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) tfm = enc ? server->secmech.ccmaesencrypt :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) server->secmech.ccmaesdecrypt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) cifs_server_dbg(VFS, "%s: Failed to set aead key %d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) cifs_server_dbg(VFS, "%s: Failed to set authsize %d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) req = aead_request_alloc(tfm, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) if (!req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) cifs_server_dbg(VFS, "%s: Failed to alloc aead request\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) if (!enc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) crypt_len += SMB2_SIGNATURE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) sg = init_sg(num_rqst, rqst, sign);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) if (!sg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) cifs_server_dbg(VFS, "%s: Failed to init sg\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) goto free_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) iv_len = crypto_aead_ivsize(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) iv = kzalloc(iv_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) if (!iv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) cifs_server_dbg(VFS, "%s: Failed to alloc iv\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) goto free_sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) iv[0] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) aead_request_set_crypt(req, sg, sg, crypt_len, iv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) aead_request_set_ad(req, assoc_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) crypto_req_done, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) rc = crypto_wait_req(enc ? crypto_aead_encrypt(req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) : crypto_aead_decrypt(req), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) if (!rc && enc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) kfree(iv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) free_sg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) kfree(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) free_req:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) kfree(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) smb3_free_compound_rqst(int num_rqst, struct smb_rqst *rqst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) for (i = 0; i < num_rqst; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) if (rqst[i].rq_pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) for (j = rqst[i].rq_npages - 1; j >= 0; j--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) put_page(rqst[i].rq_pages[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) kfree(rqst[i].rq_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) * This function will initialize new_rq and encrypt the content.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) * The first entry, new_rq[0], only contains a single iov which contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) * a smb2_transform_hdr and is pre-allocated by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) * This function then populates new_rq[1+] with the content from olq_rq[0+].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) * The end result is an array of smb_rqst structures where the first structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) * only contains a single iov for the transform header which we then can pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) * to crypt_message().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) * new_rq[0].rq_iov[0] : smb2_transform_hdr pre-allocated by the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) * new_rq[1+].rq_iov[*] == old_rq[0+].rq_iov[*] : SMB2/3 requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) struct smb_rqst *new_rq, struct smb_rqst *old_rq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) struct smb2_transform_hdr *tr_hdr = new_rq[0].rq_iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) unsigned int npages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) unsigned int orig_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) int rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) for (i = 1; i < num_rqst; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) npages = old_rq[i - 1].rq_npages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) pages = kmalloc_array(npages, sizeof(struct page *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) if (!pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) new_rq[i].rq_pages = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) new_rq[i].rq_npages = npages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) new_rq[i].rq_offset = old_rq[i - 1].rq_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) new_rq[i].rq_pagesz = old_rq[i - 1].rq_pagesz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) new_rq[i].rq_tailsz = old_rq[i - 1].rq_tailsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) new_rq[i].rq_iov = old_rq[i - 1].rq_iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) new_rq[i].rq_nvec = old_rq[i - 1].rq_nvec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) orig_len += smb_rqst_len(server, &old_rq[i - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) for (j = 0; j < npages; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) pages[j] = alloc_page(GFP_KERNEL|__GFP_HIGHMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) if (!pages[j])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) /* copy pages form the old */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) for (j = 0; j < npages; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) char *dst, *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) unsigned int offset, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) rqst_page_get_length(&new_rq[i], j, &len, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) dst = (char *) kmap(new_rq[i].rq_pages[j]) + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) src = (char *) kmap(old_rq[i - 1].rq_pages[j]) + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) memcpy(dst, src, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) kunmap(new_rq[i].rq_pages[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) kunmap(old_rq[i - 1].rq_pages[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) /* fill the 1st iov with a transform header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) fill_transform_hdr(tr_hdr, orig_len, old_rq, server->cipher_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) rc = crypt_message(server, num_rqst, new_rq, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) cifs_dbg(FYI, "Encrypt message returned %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) smb3_free_compound_rqst(num_rqst - 1, &new_rq[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) smb3_is_transform_hdr(void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) struct smb2_transform_hdr *trhdr = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) return trhdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) unsigned int buf_data_size, struct page **pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) unsigned int npages, unsigned int page_data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) bool is_offloaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) struct kvec iov[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) struct smb_rqst rqst = {NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) iov[0].iov_base = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) iov[0].iov_len = sizeof(struct smb2_transform_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) iov[1].iov_base = buf + sizeof(struct smb2_transform_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) iov[1].iov_len = buf_data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) rqst.rq_iov = iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) rqst.rq_nvec = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) rqst.rq_pages = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) rqst.rq_npages = npages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) rqst.rq_pagesz = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) rqst.rq_tailsz = (page_data_size % PAGE_SIZE) ? : PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) rc = crypt_message(server, 1, &rqst, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) cifs_dbg(FYI, "Decrypt message returned %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) memmove(buf, iov[1].iov_base, buf_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) if (!is_offloaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) server->total_read = buf_data_size + page_data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) read_data_into_pages(struct TCP_Server_Info *server, struct page **pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) unsigned int npages, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) for (i = 0; i < npages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) struct page *page = pages[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) size_t n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) n = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) if (len >= PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) /* enough data to fill the page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) n = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) len -= n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) zero_user(page, len, PAGE_SIZE - len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) length = cifs_read_page_from_socket(server, page, 0, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) if (length < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) return length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) server->total_read += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) init_read_bvec(struct page **pages, unsigned int npages, unsigned int data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) unsigned int cur_off, struct bio_vec **page_vec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) struct bio_vec *bvec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) bvec = kcalloc(npages, sizeof(struct bio_vec), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) if (!bvec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) for (i = 0; i < npages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) bvec[i].bv_page = pages[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) bvec[i].bv_offset = (i == 0) ? cur_off : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) bvec[i].bv_len = min_t(unsigned int, PAGE_SIZE, data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) data_size -= bvec[i].bv_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) if (data_size != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) cifs_dbg(VFS, "%s: something went wrong\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) kfree(bvec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) *page_vec = bvec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) char *buf, unsigned int buf_len, struct page **pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) unsigned int npages, unsigned int page_data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) bool is_offloaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) unsigned int data_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) unsigned int data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) unsigned int cur_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) unsigned int cur_page_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) unsigned int pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) struct cifs_readdata *rdata = mid->callback_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) struct bio_vec *bvec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) struct iov_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) struct kvec iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) bool use_rdma_mr = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) if (shdr->Command != SMB2_READ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) cifs_server_dbg(VFS, "only big read responses are supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) if (server->ops->is_session_expired &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) server->ops->is_session_expired(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) if (!is_offloaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) if (server->ops->is_status_pending &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) server->ops->is_status_pending(buf, server))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) /* set up first two iov to get credits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) rdata->iov[0].iov_base = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) rdata->iov[0].iov_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) rdata->iov[1].iov_base = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) rdata->iov[1].iov_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) min_t(unsigned int, buf_len, server->vals->read_rsp_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) rdata->iov[0].iov_base, rdata->iov[0].iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) rdata->iov[1].iov_base, rdata->iov[1].iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) rdata->result = server->ops->map_error(buf, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) if (rdata->result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) cifs_dbg(FYI, "%s: server returned error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) __func__, rdata->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) /* normal error on read response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) if (is_offloaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) mid->mid_state = MID_RESPONSE_RECEIVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) dequeue_mid(mid, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) data_offset = server->ops->read_data_offset(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) #ifdef CONFIG_CIFS_SMB_DIRECT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) use_rdma_mr = rdata->mr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) data_len = server->ops->read_data_length(buf, use_rdma_mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) if (data_offset < server->vals->read_rsp_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) * win2k8 sometimes sends an offset of 0 when the read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) * is beyond the EOF. Treat it as if the data starts just after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) * the header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) __func__, data_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) data_offset = server->vals->read_rsp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) /* data_offset is beyond the end of smallbuf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) __func__, data_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) rdata->result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) if (is_offloaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) mid->mid_state = MID_RESPONSE_MALFORMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) dequeue_mid(mid, rdata->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) pad_len = data_offset - server->vals->read_rsp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) if (buf_len <= data_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) /* read response payload is in pages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) cur_page_idx = pad_len / PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) cur_off = pad_len % PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) if (cur_page_idx != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) /* data offset is beyond the 1st page of response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) cifs_dbg(FYI, "%s: data offset (%u) beyond 1st page of response\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) __func__, data_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) rdata->result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) if (is_offloaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) mid->mid_state = MID_RESPONSE_MALFORMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) dequeue_mid(mid, rdata->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) if (data_len > page_data_size - pad_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) /* data_len is corrupt -- discard frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) rdata->result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) if (is_offloaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) mid->mid_state = MID_RESPONSE_MALFORMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) dequeue_mid(mid, rdata->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) rdata->result = init_read_bvec(pages, npages, page_data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) cur_off, &bvec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) if (rdata->result != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) if (is_offloaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) mid->mid_state = MID_RESPONSE_MALFORMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) dequeue_mid(mid, rdata->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) iov_iter_bvec(&iter, WRITE, bvec, npages, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) } else if (buf_len >= data_offset + data_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) /* read response payload is in buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) WARN_ONCE(npages > 0, "read data can be either in buf or in pages");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) iov.iov_base = buf + data_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) iov.iov_len = data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) iov_iter_kvec(&iter, WRITE, &iov, 1, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) /* read response payload cannot be in both buf and pages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) WARN_ONCE(1, "buf can not contain only a part of read data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) rdata->result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) if (is_offloaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) mid->mid_state = MID_RESPONSE_MALFORMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) dequeue_mid(mid, rdata->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) length = rdata->copy_into_pages(server, rdata, &iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) kfree(bvec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) if (length < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) return length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) if (is_offloaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) mid->mid_state = MID_RESPONSE_RECEIVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) dequeue_mid(mid, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) return length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) struct smb2_decrypt_work {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) struct work_struct decrypt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) struct TCP_Server_Info *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) struct page **ppages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) unsigned int npages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) static void smb2_decrypt_offload(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) struct smb2_decrypt_work *dw = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) struct smb2_decrypt_work, decrypt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) struct mid_q_entry *mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) rc = decrypt_raw_data(dw->server, dw->buf, dw->server->vals->read_rsp_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) dw->ppages, dw->npages, dw->len, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) cifs_dbg(VFS, "error decrypting rc=%d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) goto free_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) dw->server->lstrp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) mid = smb2_find_dequeue_mid(dw->server, dw->buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) if (mid == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) cifs_dbg(FYI, "mid not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) mid->decrypted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) rc = handle_read_data(dw->server, mid, dw->buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) dw->server->vals->read_rsp_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) dw->ppages, dw->npages, dw->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) if (rc >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) #ifdef CONFIG_CIFS_STATS2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) mid->when_received = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) mid->callback(mid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) if (dw->server->tcpStatus == CifsNeedReconnect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) mid->mid_state = MID_RETRY_NEEDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) mid->callback(mid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) mid->mid_state = MID_REQUEST_SUBMITTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) mid->mid_flags &= ~(MID_DELETED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) list_add_tail(&mid->qhead,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) &dw->server->pending_mid_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) cifs_mid_q_entry_release(mid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) free_pages:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) for (i = dw->npages-1; i >= 0; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) put_page(dw->ppages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) kfree(dw->ppages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) cifs_small_buf_release(dw->buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) kfree(dw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) int *num_mids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) char *buf = server->smallbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) unsigned int npages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) unsigned int buflen = server->pdu_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) struct smb2_decrypt_work *dw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) *num_mids = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) len = min_t(unsigned int, buflen, server->vals->read_rsp_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) sizeof(struct smb2_transform_hdr)) - HEADER_SIZE(server) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) rc = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) server->total_read += rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) len = le32_to_cpu(tr_hdr->OriginalMessageSize) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) server->vals->read_rsp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) npages = DIV_ROUND_UP(len, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) if (!pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) goto discard_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) for (; i < npages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) pages[i] = alloc_page(GFP_KERNEL|__GFP_HIGHMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) if (!pages[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) goto discard_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) /* read read data into pages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) rc = read_data_into_pages(server, pages, npages, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) goto free_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) rc = cifs_discard_remaining_data(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) goto free_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) * For large reads, offload to different thread for better performance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) * use more cores decrypting which can be expensive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) if ((server->min_offload) && (server->in_flight > 1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) (server->pdu_size >= server->min_offload)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) dw = kmalloc(sizeof(struct smb2_decrypt_work), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) if (dw == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) goto non_offloaded_decrypt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) dw->buf = server->smallbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) server->smallbuf = (char *)cifs_small_buf_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) INIT_WORK(&dw->decrypt, smb2_decrypt_offload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) dw->npages = npages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) dw->server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) dw->ppages = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) dw->len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) queue_work(decrypt_wq, &dw->decrypt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) *num_mids = 0; /* worker thread takes care of finding mid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) non_offloaded_decrypt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) rc = decrypt_raw_data(server, buf, server->vals->read_rsp_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) pages, npages, len, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) goto free_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) *mid = smb2_find_mid(server, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) if (*mid == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) cifs_dbg(FYI, "mid not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) cifs_dbg(FYI, "mid found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) (*mid)->decrypted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) rc = handle_read_data(server, *mid, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) server->vals->read_rsp_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) pages, npages, len, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) free_pages:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) for (i = i - 1; i >= 0; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) put_page(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) kfree(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) discard_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) cifs_discard_remaining_data(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) goto free_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) receive_encrypted_standard(struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) struct mid_q_entry **mids, char **bufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) int *num_mids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) int ret, length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) char *buf = server->smallbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) struct smb2_sync_hdr *shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) unsigned int pdu_length = server->pdu_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) unsigned int buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) struct mid_q_entry *mid_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) int next_is_large;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) char *next_buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) *num_mids = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) /* switch to large buffer if too big for a small one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) server->large_buf = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) memcpy(server->bigbuf, buf, server->total_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) buf = server->bigbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) /* now read the rest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) pdu_length - HEADER_SIZE(server) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) if (length < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) return length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) server->total_read += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) buf_size = pdu_length - sizeof(struct smb2_transform_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) length = decrypt_raw_data(server, buf, buf_size, NULL, 0, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) if (length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) return length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) next_is_large = server->large_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) one_more:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) shdr = (struct smb2_sync_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) if (shdr->NextCommand) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) if (next_is_large)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) next_buffer = (char *)cifs_buf_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) next_buffer = (char *)cifs_small_buf_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) memcpy(next_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) buf + le32_to_cpu(shdr->NextCommand),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) pdu_length - le32_to_cpu(shdr->NextCommand));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) mid_entry = smb2_find_mid(server, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) if (mid_entry == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) cifs_dbg(FYI, "mid not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) cifs_dbg(FYI, "mid found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) mid_entry->decrypted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) mid_entry->resp_buf_size = server->pdu_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) if (*num_mids >= MAX_COMPOUND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) cifs_server_dbg(VFS, "too many PDUs in compound\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) bufs[*num_mids] = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) mids[(*num_mids)++] = mid_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) if (mid_entry && mid_entry->handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) ret = mid_entry->handle(server, mid_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) ret = cifs_handle_standard(server, mid_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) if (ret == 0 && shdr->NextCommand) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) pdu_length -= le32_to_cpu(shdr->NextCommand);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) server->large_buf = next_is_large;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) if (next_is_large)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) server->bigbuf = buf = next_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) server->smallbuf = buf = next_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) goto one_more;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) } else if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) * ret != 0 here means that we didn't get to handle_mid() thus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) * server->smallbuf and server->bigbuf are still valid. We need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) * to free next_buffer because it is not going to be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) * anywhere.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) if (next_is_large)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) free_rsp_buf(CIFS_LARGE_BUFFER, next_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) free_rsp_buf(CIFS_SMALL_BUFFER, next_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) smb3_receive_transform(struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) struct mid_q_entry **mids, char **bufs, int *num_mids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) char *buf = server->smallbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) unsigned int pdu_length = server->pdu_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) unsigned int orig_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) if (pdu_length < sizeof(struct smb2_transform_hdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) sizeof(struct smb2_sync_hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) cifs_server_dbg(VFS, "Transform message is too small (%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) pdu_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) return -ECONNABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) if (pdu_length < orig_len + sizeof(struct smb2_transform_hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) cifs_server_dbg(VFS, "Transform message is broken\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) return -ECONNABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) /* TODO: add support for compounds containing READ. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) return receive_encrypted_read(server, &mids[0], num_mids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) return receive_encrypted_standard(server, mids, bufs, num_mids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) smb3_handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) char *buf = server->large_buf ? server->bigbuf : server->smallbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) return handle_read_data(server, mid, buf, server->pdu_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) NULL, 0, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) smb2_next_header(char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) struct smb2_sync_hdr *hdr = (struct smb2_sync_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) struct smb2_transform_hdr *t_hdr = (struct smb2_transform_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) return sizeof(struct smb2_transform_hdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) le32_to_cpu(t_hdr->OriginalMessageSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) return le32_to_cpu(hdr->NextCommand);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) smb2_make_node(unsigned int xid, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) struct dentry *dentry, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) char *full_path, umode_t mode, dev_t dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) int rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) FILE_ALL_INFO *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) struct cifs_io_parms io_parms = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) __u32 oplock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) unsigned int bytes_written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) struct win_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) struct kvec iov[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) * Check if mounted with mount parm 'sfu' mount parm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) * SFU emulation should work with all servers, but only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) * supports block and char device (no socket & fifo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) * and was used by default in earlier versions of Windows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) * TODO: Add ability to create instead via reparse point. Windows (e.g.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) * their current NFS server) uses this approach to expose special files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) * over SMB2/SMB3 and Samba will do this with SMB3.1.1 POSIX Extensions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) if (!S_ISCHR(mode) && !S_ISBLK(mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) cifs_dbg(FYI, "sfu compat create special file\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) if (buf == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) oparms.cifs_sb = cifs_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) oparms.desired_access = GENERIC_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) CREATE_OPTION_SPECIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) oparms.disposition = FILE_CREATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) oparms.path = full_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) if (tcon->ses->server->oplocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) oplock = REQ_OPLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) oplock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) * BB Do not bother to decode buf since no local inode yet to put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) * timestamps in, but we can reuse it safely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) pdev = (struct win_dev *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) io_parms.pid = current->tgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) io_parms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) io_parms.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) io_parms.length = sizeof(struct win_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) iov[1].iov_base = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) iov[1].iov_len = sizeof(struct win_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) if (S_ISCHR(mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) memcpy(pdev->type, "IntxCHR", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) pdev->major = cpu_to_le64(MAJOR(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) pdev->minor = cpu_to_le64(MINOR(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) &bytes_written, iov, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) } else if (S_ISBLK(mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) memcpy(pdev->type, "IntxBLK", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) pdev->major = cpu_to_le64(MAJOR(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) pdev->minor = cpu_to_le64(MINOR(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) &bytes_written, iov, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) tcon->ses->server->ops->close(xid, tcon, &fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) /* FIXME: add code here to set EAs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) struct smb_version_operations smb20_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) .compare_fids = smb2_compare_fids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) .setup_request = smb2_setup_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) .setup_async_request = smb2_setup_async_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) .check_receive = smb2_check_receive,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) .add_credits = smb2_add_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) .set_credits = smb2_set_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) .get_credits_field = smb2_get_credits_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) .get_credits = smb2_get_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) .wait_mtu_credits = cifs_wait_mtu_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) .get_next_mid = smb2_get_next_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) .revert_current_mid = smb2_revert_current_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) .read_data_offset = smb2_read_data_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) .read_data_length = smb2_read_data_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) .map_error = map_smb2_to_linux_error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) .find_mid = smb2_find_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) .check_message = smb2_check_message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) .dump_detail = smb2_dump_detail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) .clear_stats = smb2_clear_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) .print_stats = smb2_print_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) .is_oplock_break = smb2_is_valid_oplock_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) .handle_cancelled_mid = smb2_handle_cancelled_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) .downgrade_oplock = smb2_downgrade_oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) .need_neg = smb2_need_neg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) .negotiate = smb2_negotiate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) .negotiate_wsize = smb2_negotiate_wsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) .negotiate_rsize = smb2_negotiate_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) .sess_setup = SMB2_sess_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) .logoff = SMB2_logoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) .tree_connect = SMB2_tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) .tree_disconnect = SMB2_tdis,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) .qfs_tcon = smb2_qfs_tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) .is_path_accessible = smb2_is_path_accessible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) .can_echo = smb2_can_echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) .echo = SMB2_echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) .query_path_info = smb2_query_path_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) .get_srv_inum = smb2_get_srv_inum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) .query_file_info = smb2_query_file_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) .set_path_size = smb2_set_path_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) .set_file_size = smb2_set_file_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) .set_file_info = smb2_set_file_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) .set_compression = smb2_set_compression,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) .mkdir = smb2_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) .mkdir_setinfo = smb2_mkdir_setinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) .rmdir = smb2_rmdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) .unlink = smb2_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) .rename = smb2_rename_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) .create_hardlink = smb2_create_hardlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) .query_symlink = smb2_query_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) .query_mf_symlink = smb3_query_mf_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) .create_mf_symlink = smb3_create_mf_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) .open = smb2_open_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) .set_fid = smb2_set_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) .close = smb2_close_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) .flush = smb2_flush_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) .async_readv = smb2_async_readv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) .async_writev = smb2_async_writev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) .sync_read = smb2_sync_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) .sync_write = smb2_sync_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) .query_dir_first = smb2_query_dir_first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) .query_dir_next = smb2_query_dir_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) .close_dir = smb2_close_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) .calc_smb_size = smb2_calc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) .is_status_pending = smb2_is_status_pending,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) .is_session_expired = smb2_is_session_expired,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) .oplock_response = smb2_oplock_response,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) .queryfs = smb2_queryfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) .mand_lock = smb2_mand_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) .mand_unlock_range = smb2_unlock_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) .push_mand_locks = smb2_push_mandatory_locks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) .get_lease_key = smb2_get_lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) .set_lease_key = smb2_set_lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) .new_lease_key = smb2_new_lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) .calc_signature = smb2_calc_signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) .is_read_op = smb2_is_read_op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) .set_oplock_level = smb2_set_oplock_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) .create_lease_buf = smb2_create_lease_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) .parse_lease_buf = smb2_parse_lease_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) .copychunk_range = smb2_copychunk_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) .wp_retry_size = smb2_wp_retry_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) .dir_needs_close = smb2_dir_needs_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) .get_dfs_refer = smb2_get_dfs_refer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) .select_sectype = smb2_select_sectype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) #ifdef CONFIG_CIFS_XATTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) .query_all_EAs = smb2_query_eas,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) .set_EA = smb2_set_ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) #endif /* CIFS_XATTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) .get_acl = get_smb2_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) .get_acl_by_fid = get_smb2_acl_by_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) .set_acl = set_smb2_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) .next_header = smb2_next_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) .ioctl_query_info = smb2_ioctl_query_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) .make_node = smb2_make_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) .fiemap = smb3_fiemap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) .llseek = smb3_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) .is_status_io_timeout = smb2_is_status_io_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) struct smb_version_operations smb21_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) .compare_fids = smb2_compare_fids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) .setup_request = smb2_setup_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) .setup_async_request = smb2_setup_async_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) .check_receive = smb2_check_receive,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) .add_credits = smb2_add_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) .set_credits = smb2_set_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) .get_credits_field = smb2_get_credits_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) .get_credits = smb2_get_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) .wait_mtu_credits = smb2_wait_mtu_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) .adjust_credits = smb2_adjust_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) .get_next_mid = smb2_get_next_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) .revert_current_mid = smb2_revert_current_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) .read_data_offset = smb2_read_data_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) .read_data_length = smb2_read_data_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) .map_error = map_smb2_to_linux_error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) .find_mid = smb2_find_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) .check_message = smb2_check_message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) .dump_detail = smb2_dump_detail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) .clear_stats = smb2_clear_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) .print_stats = smb2_print_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) .is_oplock_break = smb2_is_valid_oplock_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) .handle_cancelled_mid = smb2_handle_cancelled_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) .downgrade_oplock = smb2_downgrade_oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) .need_neg = smb2_need_neg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) .negotiate = smb2_negotiate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) .negotiate_wsize = smb2_negotiate_wsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) .negotiate_rsize = smb2_negotiate_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) .sess_setup = SMB2_sess_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) .logoff = SMB2_logoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) .tree_connect = SMB2_tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) .tree_disconnect = SMB2_tdis,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) .qfs_tcon = smb2_qfs_tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) .is_path_accessible = smb2_is_path_accessible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) .can_echo = smb2_can_echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) .echo = SMB2_echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) .query_path_info = smb2_query_path_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) .get_srv_inum = smb2_get_srv_inum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) .query_file_info = smb2_query_file_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) .set_path_size = smb2_set_path_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) .set_file_size = smb2_set_file_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) .set_file_info = smb2_set_file_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) .set_compression = smb2_set_compression,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) .mkdir = smb2_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) .mkdir_setinfo = smb2_mkdir_setinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) .rmdir = smb2_rmdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) .unlink = smb2_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) .rename = smb2_rename_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) .create_hardlink = smb2_create_hardlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) .query_symlink = smb2_query_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) .query_mf_symlink = smb3_query_mf_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) .create_mf_symlink = smb3_create_mf_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) .open = smb2_open_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) .set_fid = smb2_set_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) .close = smb2_close_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) .flush = smb2_flush_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) .async_readv = smb2_async_readv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) .async_writev = smb2_async_writev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) .sync_read = smb2_sync_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) .sync_write = smb2_sync_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) .query_dir_first = smb2_query_dir_first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) .query_dir_next = smb2_query_dir_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) .close_dir = smb2_close_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) .calc_smb_size = smb2_calc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) .is_status_pending = smb2_is_status_pending,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) .is_session_expired = smb2_is_session_expired,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) .oplock_response = smb2_oplock_response,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) .queryfs = smb2_queryfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) .mand_lock = smb2_mand_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) .mand_unlock_range = smb2_unlock_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) .push_mand_locks = smb2_push_mandatory_locks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) .get_lease_key = smb2_get_lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) .set_lease_key = smb2_set_lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) .new_lease_key = smb2_new_lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) .calc_signature = smb2_calc_signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) .is_read_op = smb21_is_read_op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) .set_oplock_level = smb21_set_oplock_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) .create_lease_buf = smb2_create_lease_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) .parse_lease_buf = smb2_parse_lease_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) .copychunk_range = smb2_copychunk_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) .wp_retry_size = smb2_wp_retry_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) .dir_needs_close = smb2_dir_needs_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) .enum_snapshots = smb3_enum_snapshots,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) .notify = smb3_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) .get_dfs_refer = smb2_get_dfs_refer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) .select_sectype = smb2_select_sectype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) #ifdef CONFIG_CIFS_XATTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) .query_all_EAs = smb2_query_eas,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) .set_EA = smb2_set_ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) #endif /* CIFS_XATTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) .get_acl = get_smb2_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) .get_acl_by_fid = get_smb2_acl_by_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) .set_acl = set_smb2_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) .next_header = smb2_next_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) .ioctl_query_info = smb2_ioctl_query_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) .make_node = smb2_make_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) .fiemap = smb3_fiemap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) .llseek = smb3_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) .is_status_io_timeout = smb2_is_status_io_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) struct smb_version_operations smb30_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) .compare_fids = smb2_compare_fids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) .setup_request = smb2_setup_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) .setup_async_request = smb2_setup_async_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) .check_receive = smb2_check_receive,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) .add_credits = smb2_add_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) .set_credits = smb2_set_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) .get_credits_field = smb2_get_credits_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) .get_credits = smb2_get_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) .wait_mtu_credits = smb2_wait_mtu_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) .adjust_credits = smb2_adjust_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) .get_next_mid = smb2_get_next_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) .revert_current_mid = smb2_revert_current_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) .read_data_offset = smb2_read_data_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) .read_data_length = smb2_read_data_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) .map_error = map_smb2_to_linux_error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) .find_mid = smb2_find_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) .check_message = smb2_check_message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) .dump_detail = smb2_dump_detail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) .clear_stats = smb2_clear_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) .print_stats = smb2_print_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) .dump_share_caps = smb2_dump_share_caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) .is_oplock_break = smb2_is_valid_oplock_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) .handle_cancelled_mid = smb2_handle_cancelled_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) .downgrade_oplock = smb3_downgrade_oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) .need_neg = smb2_need_neg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) .negotiate = smb2_negotiate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) .negotiate_wsize = smb3_negotiate_wsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) .negotiate_rsize = smb3_negotiate_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) .sess_setup = SMB2_sess_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) .logoff = SMB2_logoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) .tree_connect = SMB2_tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) .tree_disconnect = SMB2_tdis,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) .qfs_tcon = smb3_qfs_tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) .is_path_accessible = smb2_is_path_accessible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) .can_echo = smb2_can_echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) .echo = SMB2_echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) .query_path_info = smb2_query_path_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) /* WSL tags introduced long after smb2.1, enable for SMB3, 3.11 only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) .query_reparse_tag = smb2_query_reparse_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) .get_srv_inum = smb2_get_srv_inum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) .query_file_info = smb2_query_file_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) .set_path_size = smb2_set_path_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) .set_file_size = smb2_set_file_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) .set_file_info = smb2_set_file_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) .set_compression = smb2_set_compression,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) .mkdir = smb2_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) .mkdir_setinfo = smb2_mkdir_setinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) .rmdir = smb2_rmdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) .unlink = smb2_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) .rename = smb2_rename_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) .create_hardlink = smb2_create_hardlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) .query_symlink = smb2_query_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) .query_mf_symlink = smb3_query_mf_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) .create_mf_symlink = smb3_create_mf_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) .open = smb2_open_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) .set_fid = smb2_set_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) .close = smb2_close_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) .close_getattr = smb2_close_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) .flush = smb2_flush_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) .async_readv = smb2_async_readv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) .async_writev = smb2_async_writev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) .sync_read = smb2_sync_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) .sync_write = smb2_sync_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) .query_dir_first = smb2_query_dir_first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) .query_dir_next = smb2_query_dir_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) .close_dir = smb2_close_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) .calc_smb_size = smb2_calc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) .is_status_pending = smb2_is_status_pending,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) .is_session_expired = smb2_is_session_expired,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) .oplock_response = smb2_oplock_response,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) .queryfs = smb2_queryfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) .mand_lock = smb2_mand_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) .mand_unlock_range = smb2_unlock_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) .push_mand_locks = smb2_push_mandatory_locks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) .get_lease_key = smb2_get_lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) .set_lease_key = smb2_set_lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) .new_lease_key = smb2_new_lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) .generate_signingkey = generate_smb30signingkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) .calc_signature = smb3_calc_signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) .set_integrity = smb3_set_integrity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) .is_read_op = smb21_is_read_op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) .set_oplock_level = smb3_set_oplock_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) .create_lease_buf = smb3_create_lease_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) .parse_lease_buf = smb3_parse_lease_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) .copychunk_range = smb2_copychunk_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) .duplicate_extents = smb2_duplicate_extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) .validate_negotiate = smb3_validate_negotiate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) .wp_retry_size = smb2_wp_retry_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) .dir_needs_close = smb2_dir_needs_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) .fallocate = smb3_fallocate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) .enum_snapshots = smb3_enum_snapshots,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) .notify = smb3_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) .init_transform_rq = smb3_init_transform_rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) .is_transform_hdr = smb3_is_transform_hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) .receive_transform = smb3_receive_transform,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) .get_dfs_refer = smb2_get_dfs_refer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) .select_sectype = smb2_select_sectype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) #ifdef CONFIG_CIFS_XATTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) .query_all_EAs = smb2_query_eas,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) .set_EA = smb2_set_ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) #endif /* CIFS_XATTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) .get_acl = get_smb2_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) .get_acl_by_fid = get_smb2_acl_by_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) .set_acl = set_smb2_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) .next_header = smb2_next_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) .ioctl_query_info = smb2_ioctl_query_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) .make_node = smb2_make_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) .fiemap = smb3_fiemap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) .llseek = smb3_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) .is_status_io_timeout = smb2_is_status_io_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) struct smb_version_operations smb311_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) .compare_fids = smb2_compare_fids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) .setup_request = smb2_setup_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) .setup_async_request = smb2_setup_async_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) .check_receive = smb2_check_receive,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) .add_credits = smb2_add_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) .set_credits = smb2_set_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) .get_credits_field = smb2_get_credits_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) .get_credits = smb2_get_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) .wait_mtu_credits = smb2_wait_mtu_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) .adjust_credits = smb2_adjust_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) .get_next_mid = smb2_get_next_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) .revert_current_mid = smb2_revert_current_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) .read_data_offset = smb2_read_data_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) .read_data_length = smb2_read_data_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) .map_error = map_smb2_to_linux_error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) .find_mid = smb2_find_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) .check_message = smb2_check_message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) .dump_detail = smb2_dump_detail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) .clear_stats = smb2_clear_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) .print_stats = smb2_print_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) .dump_share_caps = smb2_dump_share_caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) .is_oplock_break = smb2_is_valid_oplock_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) .handle_cancelled_mid = smb2_handle_cancelled_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) .downgrade_oplock = smb3_downgrade_oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) .need_neg = smb2_need_neg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) .negotiate = smb2_negotiate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) .negotiate_wsize = smb3_negotiate_wsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) .negotiate_rsize = smb3_negotiate_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) .sess_setup = SMB2_sess_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) .logoff = SMB2_logoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) .tree_connect = SMB2_tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) .tree_disconnect = SMB2_tdis,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) .qfs_tcon = smb3_qfs_tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) .is_path_accessible = smb2_is_path_accessible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) .can_echo = smb2_can_echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) .echo = SMB2_echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) .query_path_info = smb2_query_path_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) .query_reparse_tag = smb2_query_reparse_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) .get_srv_inum = smb2_get_srv_inum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) .query_file_info = smb2_query_file_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) .set_path_size = smb2_set_path_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) .set_file_size = smb2_set_file_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) .set_file_info = smb2_set_file_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) .set_compression = smb2_set_compression,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) .mkdir = smb2_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) .mkdir_setinfo = smb2_mkdir_setinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) .posix_mkdir = smb311_posix_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) .rmdir = smb2_rmdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) .unlink = smb2_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) .rename = smb2_rename_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) .create_hardlink = smb2_create_hardlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) .query_symlink = smb2_query_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) .query_mf_symlink = smb3_query_mf_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) .create_mf_symlink = smb3_create_mf_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) .open = smb2_open_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) .set_fid = smb2_set_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) .close = smb2_close_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) .close_getattr = smb2_close_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) .flush = smb2_flush_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) .async_readv = smb2_async_readv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) .async_writev = smb2_async_writev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) .sync_read = smb2_sync_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) .sync_write = smb2_sync_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) .query_dir_first = smb2_query_dir_first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) .query_dir_next = smb2_query_dir_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) .close_dir = smb2_close_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) .calc_smb_size = smb2_calc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) .is_status_pending = smb2_is_status_pending,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) .is_session_expired = smb2_is_session_expired,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500) .oplock_response = smb2_oplock_response,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) .queryfs = smb311_queryfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) .mand_lock = smb2_mand_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) .mand_unlock_range = smb2_unlock_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) .push_mand_locks = smb2_push_mandatory_locks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) .get_lease_key = smb2_get_lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) .set_lease_key = smb2_set_lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) .new_lease_key = smb2_new_lease_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) .generate_signingkey = generate_smb311signingkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) .calc_signature = smb3_calc_signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) .set_integrity = smb3_set_integrity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) .is_read_op = smb21_is_read_op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) .set_oplock_level = smb3_set_oplock_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) .create_lease_buf = smb3_create_lease_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) .parse_lease_buf = smb3_parse_lease_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) .copychunk_range = smb2_copychunk_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) .duplicate_extents = smb2_duplicate_extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) /* .validate_negotiate = smb3_validate_negotiate, */ /* not used in 3.11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) .wp_retry_size = smb2_wp_retry_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) .dir_needs_close = smb2_dir_needs_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) .fallocate = smb3_fallocate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) .enum_snapshots = smb3_enum_snapshots,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) .notify = smb3_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) .init_transform_rq = smb3_init_transform_rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) .is_transform_hdr = smb3_is_transform_hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) .receive_transform = smb3_receive_transform,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) .get_dfs_refer = smb2_get_dfs_refer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) .select_sectype = smb2_select_sectype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) #ifdef CONFIG_CIFS_XATTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) .query_all_EAs = smb2_query_eas,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) .set_EA = smb2_set_ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) #endif /* CIFS_XATTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) .get_acl = get_smb2_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) .get_acl_by_fid = get_smb2_acl_by_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) .set_acl = set_smb2_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) .next_header = smb2_next_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) .ioctl_query_info = smb2_ioctl_query_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) .make_node = smb2_make_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) .fiemap = smb3_fiemap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) .llseek = smb3_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) .is_status_io_timeout = smb2_is_status_io_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) struct smb_version_values smb20_values = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) .version_string = SMB20_VERSION_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) .protocol_id = SMB20_PROT_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) .req_capabilities = 0, /* MBZ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) .large_lock_type = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) .header_size = sizeof(struct smb2_sync_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) .header_preamble_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) .max_header_size = MAX_SMB2_HDR_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) .lock_cmd = SMB2_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) .cap_unix = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) .cap_nt_find = SMB2_NT_FIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) .cap_large_files = SMB2_LARGE_FILES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) .create_lease_size = sizeof(struct create_lease),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) struct smb_version_values smb21_values = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) .version_string = SMB21_VERSION_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) .protocol_id = SMB21_PROT_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) .req_capabilities = 0, /* MBZ on negotiate req until SMB3 dialect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) .large_lock_type = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) .header_size = sizeof(struct smb2_sync_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) .header_preamble_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) .max_header_size = MAX_SMB2_HDR_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) .lock_cmd = SMB2_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) .cap_unix = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) .cap_nt_find = SMB2_NT_FIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) .cap_large_files = SMB2_LARGE_FILES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) .create_lease_size = sizeof(struct create_lease),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) struct smb_version_values smb3any_values = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) .version_string = SMB3ANY_VERSION_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587) .protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) .large_lock_type = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) .header_size = sizeof(struct smb2_sync_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) .header_preamble_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) .max_header_size = MAX_SMB2_HDR_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) .lock_cmd = SMB2_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) .cap_unix = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599) .cap_nt_find = SMB2_NT_FIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) .cap_large_files = SMB2_LARGE_FILES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) .create_lease_size = sizeof(struct create_lease_v2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) struct smb_version_values smbdefault_values = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) .version_string = SMBDEFAULT_VERSION_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) .protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) .large_lock_type = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) .header_size = sizeof(struct smb2_sync_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) .header_preamble_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) .max_header_size = MAX_SMB2_HDR_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) .lock_cmd = SMB2_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) .cap_unix = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) .cap_nt_find = SMB2_NT_FIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) .cap_large_files = SMB2_LARGE_FILES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) .create_lease_size = sizeof(struct create_lease_v2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627) struct smb_version_values smb30_values = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) .version_string = SMB30_VERSION_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) .protocol_id = SMB30_PROT_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) .large_lock_type = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) .header_size = sizeof(struct smb2_sync_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) .header_preamble_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) .max_header_size = MAX_SMB2_HDR_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) .lock_cmd = SMB2_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) .cap_unix = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) .cap_nt_find = SMB2_NT_FIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) .cap_large_files = SMB2_LARGE_FILES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) .create_lease_size = sizeof(struct create_lease_v2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) struct smb_version_values smb302_values = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) .version_string = SMB302_VERSION_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) .protocol_id = SMB302_PROT_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) .large_lock_type = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) .header_size = sizeof(struct smb2_sync_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657) .header_preamble_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) .max_header_size = MAX_SMB2_HDR_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660) .lock_cmd = SMB2_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) .cap_unix = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662) .cap_nt_find = SMB2_NT_FIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) .cap_large_files = SMB2_LARGE_FILES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664) .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) .create_lease_size = sizeof(struct create_lease_v2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) struct smb_version_values smb311_values = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) .version_string = SMB311_VERSION_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) .protocol_id = SMB311_PROT_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) .large_lock_type = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) .header_size = sizeof(struct smb2_sync_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) .header_preamble_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) .max_header_size = MAX_SMB2_HDR_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) .lock_cmd = SMB2_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) .cap_unix = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683) .cap_nt_find = SMB2_NT_FIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) .cap_large_files = SMB2_LARGE_FILES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685) .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687) .create_lease_size = sizeof(struct create_lease_v2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688) };