^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * SMB1 (CIFS) 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 "cifsglob.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "cifsproto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "cifs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "cifspdu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "cifs_unicode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * An NT cancel request header looks just like the original request except:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * The Command is SMB_COM_NT_CANCEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * The WordCount is zeroed out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * The ByteCount is zeroed out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * This function mangles an existing request buffer into a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * SMB_COM_NT_CANCEL request and then sends it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct mid_q_entry *mid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct smb_hdr *in_buf = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* -4 for RFC1001 length and +2 for BCC field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) in_buf->smb_buf_length = cpu_to_be32(sizeof(struct smb_hdr) - 4 + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) in_buf->Command = SMB_COM_NT_CANCEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) in_buf->WordCount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) put_bcc(0, in_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) mutex_lock(&server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) rc = cifs_sign_smb(in_buf, server, &mid->sequence_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) mutex_unlock(&server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * The response to this call was already factored into the sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * number when the call went out, so we must adjust it back downward
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * after signing here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) --server->sequence_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) server->sequence_number--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) mutex_unlock(&server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) cifs_dbg(FYI, "issued NT_CANCEL for mid %u, rc = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) get_mid(in_buf), rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) cifs_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return ob1->fid.netfid == ob2->fid.netfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) cifs_read_data_offset(char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) READ_RSP *rsp = (READ_RSP *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return le16_to_cpu(rsp->DataOffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) cifs_read_data_length(char *buf, bool in_remaining)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) READ_RSP *rsp = (READ_RSP *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* It's a bug reading remaining data for SMB1 packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) WARN_ON(in_remaining);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return (le16_to_cpu(rsp->DataLengthHigh) << 16) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) le16_to_cpu(rsp->DataLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static struct mid_q_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) cifs_find_mid(struct TCP_Server_Info *server, char *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct smb_hdr *buf = (struct smb_hdr *)buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct mid_q_entry *mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) list_for_each_entry(mid, &server->pending_mid_q, qhead) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (compare_mid(mid->mid, buf) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) mid->mid_state == MID_REQUEST_SUBMITTED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) le16_to_cpu(mid->command) == buf->Command) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) kref_get(&mid->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) cifs_add_credits(struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) const struct cifs_credits *credits, const int optype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) spin_lock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) server->credits += credits->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) server->in_flight--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) wake_up(&server->request_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) cifs_set_credits(struct TCP_Server_Info *server, const int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) spin_lock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) server->credits = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) server->oplocks = val > 1 ? enable_oplocks : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) cifs_get_credits_field(struct TCP_Server_Info *server, const int optype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return &server->credits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) cifs_get_credits(struct mid_q_entry *mid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Find a free multiplex id (SMB mid). Otherwise there could be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * mid collisions which might cause problems, demultiplexing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * wrong response to this request. Multiplex ids could collide if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * one of a series requests takes much longer than the others, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * if a very large number of long lived requests (byte range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * locks or FindNotify requests) are pending. No more than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * 64K-1 requests can be outstanding at one time. If no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * mids are available, return zero. A future optimization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * could make the combination of mids and uid the key we use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * to demultiplex on (rather than mid alone).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * In addition to the above check, the cifs demultiplex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * code already used the command code as a secondary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * check of the frame and if signing is negotiated the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * response would be discarded if the mid were the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * but the signature was wrong. Since the mid is not put in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * pending queue until later (when it is about to be dispatched)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * we do have to limit the number of outstanding requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * to somewhat less than 64K-1 although it is hard to imagine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * so many threads being in the vfs at one time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static __u64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) cifs_get_next_mid(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) __u64 mid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) __u16 last_mid, cur_mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) bool collision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* mid is 16 bit only for CIFS/SMB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) cur_mid = (__u16)((server->CurrentMid) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* we do not want to loop forever */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) last_mid = cur_mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) cur_mid++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* avoid 0xFFFF MID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (cur_mid == 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) cur_mid++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * This nested loop looks more expensive than it is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * In practice the list of pending requests is short,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * fewer than 50, and the mids are likely to be unique
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * on the first pass through the loop unless some request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * takes longer than the 64 thousand requests before it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * (and it would also have to have been a request that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * did not time out).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) while (cur_mid != last_mid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct mid_q_entry *mid_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) unsigned int num_mids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) collision = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (cur_mid == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) cur_mid++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) num_mids = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ++num_mids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (mid_entry->mid == cur_mid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) mid_entry->mid_state == MID_REQUEST_SUBMITTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* This mid is in use, try a different one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) collision = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * if we have more than 32k mids in the list, then something
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * is very wrong. Possibly a local user is trying to DoS the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * box by issuing long-running calls and SIGKILL'ing them. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * we get to 2^16 mids then we're in big trouble as this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * function could loop forever.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * Go ahead and assign out the mid in this situation, but force
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * an eventual reconnect to clean out the pending_mid_q.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (num_mids > 32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) server->tcpStatus = CifsNeedReconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!collision) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) mid = (__u64)cur_mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) server->CurrentMid = mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) cur_mid++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return mid;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return codes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 0 not a transact2, or all data present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) >0 transact2 with that much data missing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) -EINVAL invalid transact2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) check2ndT2(char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct smb_hdr *pSMB = (struct smb_hdr *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct smb_t2_rsp *pSMBt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) int remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) __u16 total_data_size, data_in_this_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (pSMB->Command != SMB_COM_TRANSACTION2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* check for plausible wct, bcc and t2 data and parm sizes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* check for parm and data offset going beyond end of smb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) cifs_dbg(FYI, "Invalid transact2 word count\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) pSMBt = (struct smb_t2_rsp *)pSMB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) data_in_this_rsp = get_unaligned_le16(&pSMBt->t2_rsp.DataCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (total_data_size == data_in_this_rsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) else if (total_data_size < data_in_this_rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) cifs_dbg(FYI, "total data %d smaller than data in frame %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) total_data_size, data_in_this_rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) remaining = total_data_size - data_in_this_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) cifs_dbg(FYI, "missing %d bytes from transact2, check next response\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) remaining);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (total_data_size > CIFSMaxBufSize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) cifs_dbg(VFS, "TotalDataSize %d is over maximum buffer %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) total_data_size, CIFSMaxBufSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) coalesce_t2(char *second_buf, struct smb_hdr *target_hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct smb_t2_rsp *pSMBs = (struct smb_t2_rsp *)second_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)target_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) char *data_area_of_tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) char *data_area_of_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) unsigned int byte_count, total_in_tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) __u16 tgt_total_cnt, src_total_cnt, total_in_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) src_total_cnt = get_unaligned_le16(&pSMBs->t2_rsp.TotalDataCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) tgt_total_cnt = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (tgt_total_cnt != src_total_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) cifs_dbg(FYI, "total data count of primary and secondary t2 differ source=%hu target=%hu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) src_total_cnt, tgt_total_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) total_in_tgt = get_unaligned_le16(&pSMBt->t2_rsp.DataCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) remaining = tgt_total_cnt - total_in_tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (remaining < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) cifs_dbg(FYI, "Server sent too much data. tgt_total_cnt=%hu total_in_tgt=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) tgt_total_cnt, total_in_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (remaining == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* nothing to do, ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) cifs_dbg(FYI, "no more data remains\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) total_in_src = get_unaligned_le16(&pSMBs->t2_rsp.DataCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (remaining < total_in_src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) cifs_dbg(FYI, "transact2 2nd response contains too much data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* find end of first SMB data area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) data_area_of_tgt = (char *)&pSMBt->hdr.Protocol +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) get_unaligned_le16(&pSMBt->t2_rsp.DataOffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* validate target area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) data_area_of_src = (char *)&pSMBs->hdr.Protocol +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) get_unaligned_le16(&pSMBs->t2_rsp.DataOffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) data_area_of_tgt += total_in_tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) total_in_tgt += total_in_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* is the result too big for the field? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (total_in_tgt > USHRT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) cifs_dbg(FYI, "coalesced DataCount too large (%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) total_in_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) put_unaligned_le16(total_in_tgt, &pSMBt->t2_rsp.DataCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* fix up the BCC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) byte_count = get_bcc(target_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) byte_count += total_in_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* is the result too big for the field? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (byte_count > USHRT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) cifs_dbg(FYI, "coalesced BCC too large (%u)\n", byte_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) put_bcc(byte_count, target_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) byte_count = be32_to_cpu(target_hdr->smb_buf_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) byte_count += total_in_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /* don't allow buffer to overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (byte_count > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) cifs_dbg(FYI, "coalesced BCC exceeds buffer size (%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) byte_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) target_hdr->smb_buf_length = cpu_to_be32(byte_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* copy second buffer into end of first buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) memcpy(data_area_of_tgt, data_area_of_src, total_in_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (remaining != total_in_src) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* more responses to go */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) cifs_dbg(FYI, "waiting for more secondary responses\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* we are done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) cifs_dbg(FYI, "found the last secondary response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) cifs_downgrade_oplock(struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct cifsInodeInfo *cinode, __u32 oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) unsigned int epoch, bool *purge_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) cifs_set_oplock_level(cinode, oplock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) char *buf, int malformed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (malformed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (check2ndT2(buf) <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) mid->multiRsp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (mid->resp_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* merge response - fix up 1st*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) malformed = coalesce_t2(buf, mid->resp_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (malformed > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* All parts received or packet is malformed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) mid->multiEnd = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dequeue_mid(mid, malformed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (!server->large_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /*FIXME: switch to already allocated largebuf?*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) cifs_dbg(VFS, "1st trans2 resp needs bigbuf\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* Have first buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) mid->resp_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mid->large_buf = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) server->bigbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) cifs_need_neg(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return server->maxBuf == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) cifs_negotiate(const unsigned int xid, struct cifs_ses *ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) rc = CIFSSMBNegotiate(xid, ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (rc == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* retry only once on 1st time connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) set_credits(ses->server, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) rc = CIFSSMBNegotiate(xid, ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (rc == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) rc = -EHOSTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct TCP_Server_Info *server = tcon->ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) unsigned int wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* start with specified wsize, or default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (volume_info->wsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) wsize = volume_info->wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) else if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) wsize = CIFS_DEFAULT_IOSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) wsize = CIFS_DEFAULT_NON_POSIX_WSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /* can server support 24-bit write sizes? (via UNIX extensions) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1002_WSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * no CAP_LARGE_WRITE_X or is signing enabled without CAP_UNIX set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * Limit it to max buffer offered by the server, minus the size of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * WRITEX header, not including the 4 byte RFC1001 length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!(server->capabilities & CAP_LARGE_WRITE_X) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) (!(server->capabilities & CAP_UNIX) && server->sign))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) wsize = min_t(unsigned int, wsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) server->maxBuf - sizeof(WRITE_REQ) + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* hard limit of CIFS_MAX_WSIZE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct TCP_Server_Info *server = tcon->ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) unsigned int rsize, defsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * Set default value...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * HACK alert! Ancient servers have very small buffers. Even though
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * MS-CIFS indicates that servers are only limited by the client's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * bufsize for reads, testing against win98se shows that it throws
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * INVALID_PARAMETER errors if you try to request too large a read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * OS/2 just sends back short reads.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * If the server doesn't advertise CAP_LARGE_READ_X, then assume that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * it can't handle a read request larger than its MaxBufferSize either.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) defsize = CIFS_DEFAULT_IOSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) else if (server->capabilities & CAP_LARGE_READ_X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) defsize = CIFS_DEFAULT_NON_POSIX_RSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) defsize = server->maxBuf - sizeof(READ_RSP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) rsize = volume_info->rsize ? volume_info->rsize : defsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * no CAP_LARGE_READ_X? Then MS-CIFS states that we must limit this to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * the client's MaxBufferSize.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (!(server->capabilities & CAP_LARGE_READ_X))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) rsize = min_t(unsigned int, CIFSMaxBufSize, rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /* hard limit of CIFS_MAX_RSIZE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) cifs_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) CIFSSMBQFSDeviceInfo(xid, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) CIFSSMBQFSAttributeInfo(xid, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) cifs_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct cifs_sb_info *cifs_sb, const char *full_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) FILE_ALL_INFO *file_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) file_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (file_info == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) rc = CIFSSMBQPathInfo(xid, tcon, full_path, file_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 0 /* not legacy */, cifs_sb->local_nls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) cifs_remap(cifs_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (rc == -EOPNOTSUPP || rc == -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) rc = SMBQueryInformation(xid, tcon, full_path, file_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) cifs_sb->local_nls, cifs_remap(cifs_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) kfree(file_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct cifs_sb_info *cifs_sb, const char *full_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) FILE_ALL_INFO *data, bool *adjustTZ, bool *symlink)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) *symlink = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /* could do find first instead but this returns more info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) rc = CIFSSMBQPathInfo(xid, tcon, full_path, data, 0 /* not legacy */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) cifs_sb->local_nls, cifs_remap(cifs_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * BB optimize code so we do not make the above call when server claims
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * no NT SMB support and the above call failed at least once - set flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * in tcon or mount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) rc = SMBQueryInformation(xid, tcon, full_path, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) cifs_sb->local_nls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) cifs_remap(cifs_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) *adjustTZ = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (!rc && (le32_to_cpu(data->Attributes) & ATTR_REPARSE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) int tmprc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) int oplock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) oparms.cifs_sb = cifs_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) oparms.desired_access = FILE_READ_ATTRIBUTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) oparms.create_options = cifs_create_options(cifs_sb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) oparms.path = full_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /* Need to check if this is a symbolic link or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) tmprc = CIFS_open(xid, &oparms, &oplock, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (tmprc == -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) *symlink = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) else if (tmprc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) CIFSSMBClose(xid, tcon, fid.netfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) cifs_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct cifs_sb_info *cifs_sb, const char *full_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) u64 *uniqueid, FILE_ALL_INFO *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * We can not use the IndexNumber field by default from Windows or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * CIFS spec claims that this value is unique within the scope of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * share, and the windows docs hint that it's actually unique
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * per-machine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * There may be higher info levels that work but are there Windows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * server or network appliances for which IndexNumber field is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * guaranteed unique?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return CIFSGetSrvInodeNumber(xid, tcon, full_path, uniqueid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) cifs_sb->local_nls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) cifs_remap(cifs_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct cifs_fid *fid, FILE_ALL_INFO *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return CIFSSMBQFileInfo(xid, tcon, fid->netfid, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) cifs_clear_stats(struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) atomic_set(&tcon->stats.cifs_stats.num_writes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) atomic_set(&tcon->stats.cifs_stats.num_reads, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) atomic_set(&tcon->stats.cifs_stats.num_flushes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) atomic_set(&tcon->stats.cifs_stats.num_oplock_brks, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) atomic_set(&tcon->stats.cifs_stats.num_opens, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) atomic_set(&tcon->stats.cifs_stats.num_posixopens, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) atomic_set(&tcon->stats.cifs_stats.num_posixmkdirs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) atomic_set(&tcon->stats.cifs_stats.num_closes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) atomic_set(&tcon->stats.cifs_stats.num_deletes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) atomic_set(&tcon->stats.cifs_stats.num_mkdirs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) atomic_set(&tcon->stats.cifs_stats.num_rmdirs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) atomic_set(&tcon->stats.cifs_stats.num_renames, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) atomic_set(&tcon->stats.cifs_stats.num_t2renames, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) atomic_set(&tcon->stats.cifs_stats.num_ffirst, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) atomic_set(&tcon->stats.cifs_stats.num_fnext, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) atomic_set(&tcon->stats.cifs_stats.num_fclose, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) atomic_set(&tcon->stats.cifs_stats.num_hardlinks, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) atomic_set(&tcon->stats.cifs_stats.num_symlinks, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) atomic_set(&tcon->stats.cifs_stats.num_locks, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) atomic_set(&tcon->stats.cifs_stats.num_acl_get, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) atomic_set(&tcon->stats.cifs_stats.num_acl_set, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) cifs_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) seq_printf(m, " Oplocks breaks: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) atomic_read(&tcon->stats.cifs_stats.num_oplock_brks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) seq_printf(m, "\nReads: %d Bytes: %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) atomic_read(&tcon->stats.cifs_stats.num_reads),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) (long long)(tcon->bytes_read));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) seq_printf(m, "\nWrites: %d Bytes: %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) atomic_read(&tcon->stats.cifs_stats.num_writes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) (long long)(tcon->bytes_written));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) seq_printf(m, "\nFlushes: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) atomic_read(&tcon->stats.cifs_stats.num_flushes));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) seq_printf(m, "\nLocks: %d HardLinks: %d Symlinks: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) atomic_read(&tcon->stats.cifs_stats.num_locks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) atomic_read(&tcon->stats.cifs_stats.num_hardlinks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) atomic_read(&tcon->stats.cifs_stats.num_symlinks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) seq_printf(m, "\nOpens: %d Closes: %d Deletes: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) atomic_read(&tcon->stats.cifs_stats.num_opens),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) atomic_read(&tcon->stats.cifs_stats.num_closes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) atomic_read(&tcon->stats.cifs_stats.num_deletes));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) seq_printf(m, "\nPosix Opens: %d Posix Mkdirs: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) atomic_read(&tcon->stats.cifs_stats.num_posixopens),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) atomic_read(&tcon->stats.cifs_stats.num_posixmkdirs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) seq_printf(m, "\nMkdirs: %d Rmdirs: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) atomic_read(&tcon->stats.cifs_stats.num_mkdirs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) atomic_read(&tcon->stats.cifs_stats.num_rmdirs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) seq_printf(m, "\nRenames: %d T2 Renames %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) atomic_read(&tcon->stats.cifs_stats.num_renames),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) atomic_read(&tcon->stats.cifs_stats.num_t2renames));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) seq_printf(m, "\nFindFirst: %d FNext %d FClose %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) atomic_read(&tcon->stats.cifs_stats.num_ffirst),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) atomic_read(&tcon->stats.cifs_stats.num_fnext),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) atomic_read(&tcon->stats.cifs_stats.num_fclose));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) cifs_mkdir_setinfo(struct inode *inode, const char *full_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) const unsigned int xid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) FILE_BASIC_INFO info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct cifsInodeInfo *cifsInode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) u32 dosattrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) memset(&info, 0, sizeof(info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) cifsInode = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) info.Attributes = cpu_to_le32(dosattrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) rc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, cifs_sb->local_nls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) cifsInode->cifsAttrs = dosattrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) __u32 *oplock, FILE_ALL_INFO *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (!(oparms->tcon->ses->capabilities & CAP_NT_SMBS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return SMBLegacyOpen(xid, oparms->tcon, oparms->path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) oparms->disposition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) oparms->desired_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) oparms->create_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) &oparms->fid->netfid, oplock, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) oparms->cifs_sb->local_nls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) cifs_remap(oparms->cifs_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return CIFS_open(xid, oparms, oplock, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) cifs_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) cfile->fid.netfid = fid->netfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) cifs_set_oplock_level(cinode, oplock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) cifs_close_file(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct cifs_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) CIFSSMBClose(xid, tcon, fid->netfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) cifs_flush_file(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) struct cifs_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return CIFSSMBFlush(xid, tcon, fid->netfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) cifs_sync_read(const unsigned int xid, struct cifs_fid *pfid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) struct cifs_io_parms *parms, unsigned int *bytes_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) char **buf, int *buf_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) parms->netfid = pfid->netfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return CIFSSMBRead(xid, parms, bytes_read, buf, buf_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) cifs_sync_write(const unsigned int xid, struct cifs_fid *pfid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct cifs_io_parms *parms, unsigned int *written,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct kvec *iov, unsigned long nr_segs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) parms->netfid = pfid->netfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return CIFSSMBWrite2(xid, parms, written, iov, nr_segs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) smb_set_file_info(struct inode *inode, const char *full_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) FILE_BASIC_INFO *buf, const unsigned int xid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int oplock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) __u32 netpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct cifsFileInfo *open_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct cifsInodeInfo *cinode = CIFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct tcon_link *tlink = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* if the file is already open for write, just use that fileid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) open_file = find_writable_file(cinode, FIND_WR_FSUID_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (open_file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) fid.netfid = open_file->fid.netfid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) netpid = open_file->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) tcon = tlink_tcon(open_file->tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) goto set_via_filehandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) tlink = cifs_sb_tlink(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (IS_ERR(tlink)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) rc = PTR_ERR(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) tlink = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) tcon = tlink_tcon(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) rc = CIFSSMBSetPathInfo(xid, tcon, full_path, buf, cifs_sb->local_nls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) cinode->cifsAttrs = le32_to_cpu(buf->Attributes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) } else if (rc != -EOPNOTSUPP && rc != -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) oparms.cifs_sb = cifs_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) oparms.desired_access = SYNCHRONIZE | FILE_WRITE_ATTRIBUTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) oparms.path = full_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) cifs_dbg(FYI, "calling SetFileInfo since SetPathInfo for times not supported by this server\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) rc = CIFS_open(xid, &oparms, &oplock, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (rc == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) netpid = current->tgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) set_via_filehandle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) rc = CIFSSMBSetFileInfo(xid, tcon, buf, fid.netfid, netpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) cinode->cifsAttrs = le32_to_cpu(buf->Attributes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (open_file == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) CIFSSMBClose(xid, tcon, fid.netfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) cifsFileInfo_put(open_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (tlink != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) cifs_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct cifsFileInfo *cfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return CIFSSMB_set_compression(xid, tcon, cfile->fid.netfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) cifs_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) const char *path, struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct cifs_fid *fid, __u16 search_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) struct cifs_search_info *srch_inf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) rc = CIFSFindFirst(xid, tcon, path, cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) &fid->netfid, search_flags, srch_inf, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) cifs_dbg(FYI, "find first failed=%d\n", rc);
^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 int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) cifs_query_dir_next(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct cifs_fid *fid, __u16 search_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct cifs_search_info *srch_inf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return CIFSFindNext(xid, tcon, fid->netfid, search_flags, srch_inf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) cifs_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) struct cifs_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return CIFSFindClose(xid, tcon, fid->netfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) cifs_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) struct cifsInodeInfo *cinode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return CIFSSMBLock(0, tcon, fid->netfid, current->tgid, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) LOCKING_ANDX_OPLOCK_RELEASE, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) CIFS_CACHE_READ(cinode) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) cifs_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) int rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) buf->f_type = CIFS_MAGIC_NUMBER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) * We could add a second check for a QFS Unix capability bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if ((tcon->ses->capabilities & CAP_UNIX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) (CIFS_POSIX_EXTENSIONS & le64_to_cpu(tcon->fsUnixInfo.Capability)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) rc = CIFSSMBQFSPosixInfo(xid, tcon, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * Only need to call the old QFSInfo if failed on newer one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * e.g. by OS/2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (rc && (tcon->ses->capabilities & CAP_NT_SMBS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) rc = CIFSSMBQFSInfo(xid, tcon, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * Some old Windows servers also do not support level 103, retry with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * older level one if old server failed the previous call or we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * bypassed it because we detected that this was an older LANMAN sess
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) rc = SMBOldQFSInfo(xid, tcon, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) cifs_mand_lock(const unsigned int xid, struct cifsFileInfo *cfile, __u64 offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) __u64 length, __u32 type, int lock, int unlock, bool wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return CIFSSMBLock(xid, tlink_tcon(cfile->tlink), cfile->fid.netfid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) current->tgid, length, offset, unlock, lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) (__u8)type, wait, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) cifs_unix_dfs_readlink(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) const unsigned char *searchName, char **symlinkinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) const struct nls_table *nls_codepage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct dfs_info3_param referral = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) rc = get_dfs_path(xid, tcon->ses, searchName, nls_codepage, &referral,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) *symlinkinfo = kstrndup(referral.node_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) strlen(referral.node_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) free_dfs_info_param(&referral);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (!*symlinkinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) #else /* No DFS support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return -EREMOTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) cifs_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) struct cifs_sb_info *cifs_sb, const char *full_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) char **target_path, bool is_reparse_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) int oplock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (is_reparse_point) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) cifs_dbg(VFS, "reparse points not handled for SMB1 symlinks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) /* Check for unix extensions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (cap_unix(tcon->ses)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, target_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) cifs_sb->local_nls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) cifs_remap(cifs_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (rc == -EREMOTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) rc = cifs_unix_dfs_readlink(xid, tcon, full_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) target_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) cifs_sb->local_nls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) oparms.cifs_sb = cifs_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) oparms.desired_access = FILE_READ_ATTRIBUTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) oparms.create_options = cifs_create_options(cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) OPEN_REPARSE_POINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) oparms.disposition = FILE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) oparms.path = full_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) rc = CIFS_open(xid, &oparms, &oplock, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) rc = CIFSSMBQuerySymLink(xid, tcon, fid.netfid, target_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) cifs_sb->local_nls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) convert_delimiter(*target_path, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) out_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) CIFSSMBClose(xid, tcon, fid.netfid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) cifs_is_read_op(__u32 oplock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return oplock == OPLOCK_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) cifs_wp_retry_size(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return CIFS_SB(inode->i_sb)->wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) cifs_dir_needs_close(struct cifsFileInfo *cfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return !cfile->srch_inf.endOfSearch && !cfile->invalidHandle;
^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) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) cifs_can_echo(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (server->tcpStatus == CifsGood)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) cifs_make_node(unsigned int xid, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct dentry *dentry, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) char *full_path, umode_t mode, dev_t dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) struct inode *newinode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) int rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) FILE_ALL_INFO *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) struct cifs_io_parms io_parms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) __u32 oplock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) struct cifs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) struct cifs_open_parms oparms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) unsigned int bytes_written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) struct win_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) struct kvec iov[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (tcon->unix_ext) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * SMB1 Unix Extensions: requires server support but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * works with all special files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) struct cifs_unix_set_info_args args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) .mode = mode & ~current_umask(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) .ctime = NO_CHANGE_64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) .atime = NO_CHANGE_64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .mtime = NO_CHANGE_64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) .device = dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) args.uid = current_fsuid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) args.gid = current_fsgid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) args.uid = INVALID_UID; /* no change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) args.gid = INVALID_GID; /* no change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) rc = CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) cifs_sb->local_nls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) cifs_remap(cifs_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) rc = cifs_get_inode_info_unix(&newinode, full_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) inode->i_sb, xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) d_instantiate(dentry, newinode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) * SMB1 SFU emulation: should work with all servers, but only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) * support block and char device (no socket & fifo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (!S_ISCHR(mode) && !S_ISBLK(mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) cifs_dbg(FYI, "sfu compat create special file\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (buf == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) oparms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) oparms.cifs_sb = cifs_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) oparms.desired_access = GENERIC_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) CREATE_OPTION_SPECIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) oparms.disposition = FILE_CREATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) oparms.path = full_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) oparms.fid = &fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) oparms.reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (tcon->ses->server->oplocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) oplock = REQ_OPLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) oplock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * BB Do not bother to decode buf since no local inode yet to put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) * timestamps in, but we can reuse it safely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) pdev = (struct win_dev *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) io_parms.pid = current->tgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) io_parms.tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) io_parms.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) io_parms.length = sizeof(struct win_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) iov[1].iov_base = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) iov[1].iov_len = sizeof(struct win_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (S_ISCHR(mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) memcpy(pdev->type, "IntxCHR", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) pdev->major = cpu_to_le64(MAJOR(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) pdev->minor = cpu_to_le64(MINOR(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) &bytes_written, iov, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) } else if (S_ISBLK(mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) memcpy(pdev->type, "IntxBLK", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) pdev->major = cpu_to_le64(MAJOR(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) pdev->minor = cpu_to_le64(MINOR(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) &bytes_written, iov, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) tcon->ses->server->ops->close(xid, tcon, &fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) /* FIXME: add code here to set EAs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) struct smb_version_operations smb1_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) .send_cancel = send_nt_cancel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) .compare_fids = cifs_compare_fids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) .setup_request = cifs_setup_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) .setup_async_request = cifs_setup_async_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) .check_receive = cifs_check_receive,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) .add_credits = cifs_add_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) .set_credits = cifs_set_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) .get_credits_field = cifs_get_credits_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) .get_credits = cifs_get_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) .wait_mtu_credits = cifs_wait_mtu_credits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) .get_next_mid = cifs_get_next_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) .read_data_offset = cifs_read_data_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) .read_data_length = cifs_read_data_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) .map_error = map_smb_to_linux_error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) .find_mid = cifs_find_mid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) .check_message = checkSMB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) .dump_detail = cifs_dump_detail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) .clear_stats = cifs_clear_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) .print_stats = cifs_print_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) .is_oplock_break = is_valid_oplock_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) .downgrade_oplock = cifs_downgrade_oplock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) .check_trans2 = cifs_check_trans2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) .need_neg = cifs_need_neg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) .negotiate = cifs_negotiate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) .negotiate_wsize = cifs_negotiate_wsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) .negotiate_rsize = cifs_negotiate_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) .sess_setup = CIFS_SessSetup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) .logoff = CIFSSMBLogoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) .tree_connect = CIFSTCon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) .tree_disconnect = CIFSSMBTDis,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) .get_dfs_refer = CIFSGetDFSRefer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) .qfs_tcon = cifs_qfs_tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) .is_path_accessible = cifs_is_path_accessible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) .can_echo = cifs_can_echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) .query_path_info = cifs_query_path_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) .query_file_info = cifs_query_file_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) .get_srv_inum = cifs_get_srv_inum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) .set_path_size = CIFSSMBSetEOF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) .set_file_size = CIFSSMBSetFileSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) .set_file_info = smb_set_file_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) .set_compression = cifs_set_compression,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) .echo = CIFSSMBEcho,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) .mkdir = CIFSSMBMkDir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) .mkdir_setinfo = cifs_mkdir_setinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) .rmdir = CIFSSMBRmDir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) .unlink = CIFSSMBDelFile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) .rename_pending_delete = cifs_rename_pending_delete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) .rename = CIFSSMBRename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) .create_hardlink = CIFSCreateHardLink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) .query_symlink = cifs_query_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) .open = cifs_open_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) .set_fid = cifs_set_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) .close = cifs_close_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) .flush = cifs_flush_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) .async_readv = cifs_async_readv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) .async_writev = cifs_async_writev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) .sync_read = cifs_sync_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) .sync_write = cifs_sync_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) .query_dir_first = cifs_query_dir_first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) .query_dir_next = cifs_query_dir_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) .close_dir = cifs_close_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) .calc_smb_size = smbCalcSize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) .oplock_response = cifs_oplock_response,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) .queryfs = cifs_queryfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) .mand_lock = cifs_mand_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) .mand_unlock_range = cifs_unlock_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) .push_mand_locks = cifs_push_mandatory_locks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) .query_mf_symlink = cifs_query_mf_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) .create_mf_symlink = cifs_create_mf_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) .is_read_op = cifs_is_read_op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) .wp_retry_size = cifs_wp_retry_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) .dir_needs_close = cifs_dir_needs_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) .select_sectype = cifs_select_sectype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) #ifdef CONFIG_CIFS_XATTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) .query_all_EAs = CIFSSMBQAllEAs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) .set_EA = CIFSSMBSetEA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) #endif /* CIFS_XATTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) .get_acl = get_cifs_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) .get_acl_by_fid = get_cifs_acl_by_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) .set_acl = set_cifs_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) .make_node = cifs_make_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) struct smb_version_values smb1_values = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) .version_string = SMB1_VERSION_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) .protocol_id = SMB10_PROT_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) .large_lock_type = LOCKING_ANDX_LARGE_FILES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) .exclusive_lock_type = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) .shared_lock_type = LOCKING_ANDX_SHARED_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) .unlock_lock_type = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) .header_preamble_size = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) .header_size = sizeof(struct smb_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) .max_header_size = MAX_CIFS_HDR_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) .read_rsp_size = sizeof(READ_RSP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) .lock_cmd = cpu_to_le16(SMB_COM_LOCKING_ANDX),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) .cap_unix = CAP_UNIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) .cap_nt_find = CAP_NT_SMBS | CAP_NT_FIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) .cap_large_files = CAP_LARGE_FILES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) .signing_enabled = SECMODE_SIGN_ENABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) .signing_required = SECMODE_SIGN_REQUIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) };