diff options
Diffstat (limited to 'fs/smb/client/smb2ops.c')
| -rw-r--r-- | fs/smb/client/smb2ops.c | 78 |
1 files changed, 40 insertions, 38 deletions
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 7ace6d4d305b..a16ded46b5a2 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -17,9 +17,9 @@ #include <uapi/linux/magic.h> #include "cifsfs.h" #include "cifsglob.h" -#include "smb2pdu.h" -#include "smb2proto.h" #include "cifsproto.h" +#include "smb2proto.h" +#include "smb2pdu.h" #include "cifs_debug.h" #include "cifs_unicode.h" #include "../common/smb2status.h" @@ -406,7 +406,7 @@ __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue) if ((mid->mid == wire_mid) && (mid->mid_state == MID_REQUEST_SUBMITTED) && (mid->command == shdr->Command)) { - kref_get(&mid->refcount); + smb_get_mid(mid); if (dequeue) { list_del_init(&mid->qhead); mid->deleted_from_q = true; @@ -432,7 +432,7 @@ smb2_find_dequeue_mid(struct TCP_Server_Info *server, char *buf) } static void -smb2_dump_detail(void *buf, struct TCP_Server_Info *server) +smb2_dump_detail(void *buf, size_t buf_len, struct TCP_Server_Info *server) { #ifdef CONFIG_CIFS_DEBUG2 struct smb2_hdr *shdr = (struct smb2_hdr *)buf; @@ -440,7 +440,7 @@ smb2_dump_detail(void *buf, struct TCP_Server_Info *server) cifs_server_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n", shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId, shdr->Id.SyncId.ProcessId); - if (!server->ops->check_message(buf, server->total_read, server)) { + if (!server->ops->check_message(buf, buf_len, server->total_read, server)) { cifs_server_dbg(VFS, "smb buf %p len %u\n", buf, server->ops->calc_smb_size(buf)); } @@ -1046,7 +1046,8 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size, if (src_size < 8 + name_len + 1 + value_len) { cifs_dbg(FYI, "EA entry goes beyond length of list\n"); - rc = -EIO; + rc = smb_EIO2(smb_eio_trace_ea_overrun, + src_size, 8 + name_len + 1 + value_len); goto out; } @@ -1607,7 +1608,7 @@ replay_again: } if (!ses || !server) { - rc = -EIO; + rc = smb_EIO(smb_eio_trace_null_pointers); goto free_vars; } @@ -1942,7 +1943,7 @@ retry: if (unlikely(ret_data_len != sizeof(*cc_rsp))) { cifs_tcon_dbg(VFS, "Copychunk invalid response: size %u/%zu\n", ret_data_len, sizeof(*cc_rsp)); - rc = -EIO; + rc = smb_EIO1(smb_eio_trace_copychunk_inv_rsp, ret_data_len); goto out; } @@ -1952,11 +1953,18 @@ retry: if (rc == 0) { /* Check if server claimed to write more than we asked */ - if (unlikely(!bytes_written || bytes_written > copy_bytes || - !chunks_written || chunks_written > chunks)) { - cifs_tcon_dbg(VFS, "Copychunk invalid response: bytes written %u/%u, chunks written %u/%u\n", - bytes_written, copy_bytes, chunks_written, chunks); - rc = -EIO; + if (unlikely(!bytes_written || bytes_written > copy_bytes)) { + cifs_tcon_dbg(VFS, "Copychunk invalid response: bytes written %u/%u\n", + bytes_written, copy_bytes); + rc = smb_EIO2(smb_eio_trace_copychunk_overcopy_b, + bytes_written, copy_bytes); + goto out; + } + if (unlikely(!chunks_written || chunks_written > chunks)) { + cifs_tcon_dbg(VFS, "Copychunk invalid response: chunks written %u/%u\n", + chunks_written, chunks); + rc = smb_EIO2(smb_eio_trace_copychunk_overcopy_c, + chunks_written, chunks); goto out; } @@ -3127,7 +3135,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, } if (!rc && !dfs_rsp) - rc = -EIO; + rc = smb_EIO(smb_eio_trace_dfsref_no_rsp); if (rc) { if (!is_retryable_error(rc) && rc != -ENOENT && rc != -EOPNOTSUPP) cifs_tcon_dbg(FYI, "%s: ioctl error: rc=%d\n", __func__, rc); @@ -4555,7 +4563,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst, buffer, 0, 0, size); if (!cifs_copy_iter_to_folioq(&old->rq_iter, size, buffer)) { - rc = -EIO; + rc = smb_EIO1(smb_eio_trace_tx_copy_iter_to_buf, size); goto err_free; } } @@ -4656,7 +4664,8 @@ cifs_copy_folioq_to_iter(struct folio_queue *folioq, size_t data_size, n = copy_folio_to_iter(folio, skip, len, iter); if (n != len) { cifs_dbg(VFS, "%s: something went wrong\n", __func__); - return -EIO; + return smb_EIO2(smb_eio_trace_rx_copy_to_iter, + n, len); } data_size -= n; skip = 0; @@ -4716,7 +4725,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, if (is_offloaded) mid->mid_state = MID_RESPONSE_RECEIVED; else - dequeue_mid(mid, false); + dequeue_mid(server, mid, false); return 0; } @@ -4739,11 +4748,11 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, /* data_offset is beyond the end of smallbuf */ cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n", __func__, data_offset); - rdata->result = -EIO; + rdata->result = smb_EIO1(smb_eio_trace_rx_overlong, data_offset); if (is_offloaded) mid->mid_state = MID_RESPONSE_MALFORMED; else - dequeue_mid(mid, rdata->result); + dequeue_mid(server, mid, rdata->result); return 0; } @@ -4758,21 +4767,21 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, /* data offset is beyond the 1st page of response */ cifs_dbg(FYI, "%s: data offset (%u) beyond 1st page of response\n", __func__, data_offset); - rdata->result = -EIO; + rdata->result = smb_EIO1(smb_eio_trace_rx_overpage, data_offset); if (is_offloaded) mid->mid_state = MID_RESPONSE_MALFORMED; else - dequeue_mid(mid, rdata->result); + dequeue_mid(server, mid, rdata->result); return 0; } if (data_len > buffer_len - pad_len) { /* data_len is corrupt -- discard frame */ - rdata->result = -EIO; + rdata->result = smb_EIO1(smb_eio_trace_rx_bad_datalen, data_len); if (is_offloaded) mid->mid_state = MID_RESPONSE_MALFORMED; else - dequeue_mid(mid, rdata->result); + dequeue_mid(server, mid, rdata->result); return 0; } @@ -4783,7 +4792,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, if (is_offloaded) mid->mid_state = MID_RESPONSE_MALFORMED; else - dequeue_mid(mid, rdata->result); + dequeue_mid(server, mid, rdata->result); return 0; } rdata->got_bytes = buffer_len; @@ -4793,23 +4802,23 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, WARN_ONCE(buffer, "read data can be either in buf or in buffer"); copied = copy_to_iter(buf + data_offset, data_len, &rdata->subreq.io_iter); if (copied == 0) - return -EIO; + return smb_EIO2(smb_eio_trace_rx_copy_to_iter, copied, data_len); rdata->got_bytes = copied; } else { /* read response payload cannot be in both buf and pages */ WARN_ONCE(1, "buf can not contain only a part of read data"); - rdata->result = -EIO; + rdata->result = smb_EIO(smb_eio_trace_rx_both_buf); if (is_offloaded) mid->mid_state = MID_RESPONSE_MALFORMED; else - dequeue_mid(mid, rdata->result); + dequeue_mid(server, mid, rdata->result); return 0; } if (is_offloaded) mid->mid_state = MID_RESPONSE_RECEIVED; else - dequeue_mid(mid, false); + dequeue_mid(server, mid, false); return 0; } @@ -4856,7 +4865,7 @@ static void smb2_decrypt_offload(struct work_struct *work) dw->server->ops->is_network_name_deleted(dw->buf, dw->server); - mid_execute_callback(mid); + mid_execute_callback(dw->server, mid); } else { spin_lock(&dw->server->srv_lock); if (dw->server->tcpStatus == CifsNeedReconnect) { @@ -4864,7 +4873,7 @@ static void smb2_decrypt_offload(struct work_struct *work) mid->mid_state = MID_RETRY_NEEDED; spin_unlock(&dw->server->mid_queue_lock); spin_unlock(&dw->server->srv_lock); - mid_execute_callback(mid); + mid_execute_callback(dw->server, mid); } else { spin_lock(&dw->server->mid_queue_lock); mid->mid_state = MID_REQUEST_SUBMITTED; @@ -4875,7 +4884,7 @@ static void smb2_decrypt_offload(struct work_struct *work) spin_unlock(&dw->server->srv_lock); } } - release_mid(mid); + release_mid(dw->server, mid); } free_pages: @@ -5767,7 +5776,6 @@ struct smb_version_values smb20_values = { .shared_lock_type = SMB2_LOCKFLAG_SHARED, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, .max_header_size = MAX_SMB2_HDR_SIZE, .read_rsp_size = sizeof(struct smb2_read_rsp), .lock_cmd = SMB2_LOCK, @@ -5789,7 +5797,6 @@ struct smb_version_values smb21_values = { .shared_lock_type = SMB2_LOCKFLAG_SHARED, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, .max_header_size = MAX_SMB2_HDR_SIZE, .read_rsp_size = sizeof(struct smb2_read_rsp), .lock_cmd = SMB2_LOCK, @@ -5810,7 +5817,6 @@ struct smb_version_values smb3any_values = { .shared_lock_type = SMB2_LOCKFLAG_SHARED, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, .max_header_size = MAX_SMB2_HDR_SIZE, .read_rsp_size = sizeof(struct smb2_read_rsp), .lock_cmd = SMB2_LOCK, @@ -5831,7 +5837,6 @@ struct smb_version_values smbdefault_values = { .shared_lock_type = SMB2_LOCKFLAG_SHARED, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, .max_header_size = MAX_SMB2_HDR_SIZE, .read_rsp_size = sizeof(struct smb2_read_rsp), .lock_cmd = SMB2_LOCK, @@ -5852,7 +5857,6 @@ struct smb_version_values smb30_values = { .shared_lock_type = SMB2_LOCKFLAG_SHARED, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, .max_header_size = MAX_SMB2_HDR_SIZE, .read_rsp_size = sizeof(struct smb2_read_rsp), .lock_cmd = SMB2_LOCK, @@ -5873,7 +5877,6 @@ struct smb_version_values smb302_values = { .shared_lock_type = SMB2_LOCKFLAG_SHARED, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, .max_header_size = MAX_SMB2_HDR_SIZE, .read_rsp_size = sizeof(struct smb2_read_rsp), .lock_cmd = SMB2_LOCK, @@ -5894,7 +5897,6 @@ struct smb_version_values smb311_values = { .shared_lock_type = SMB2_LOCKFLAG_SHARED, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, .max_header_size = MAX_SMB2_HDR_SIZE, .read_rsp_size = sizeof(struct smb2_read_rsp), .lock_cmd = SMB2_LOCK, |
