Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'v6.17rc-part2-SMB3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull more smb client updates from Steve French:
"Non-smbdirect:
- Fix null ptr deref caused by delay in global spinlock
initialization
- Two fixes for native symlink creation with SMB3.1.1 POSIX
Extensions
- Fix for socket special file creation with SMB3.1.1 POSIX Exensions
- Reduce lock contention by splitting out mid_counter_lock
- move SMB1 transport code to separate file to reduce module size
when support for legacy servers is disabled
- Two cleanup patches: rename mid_lock to make it clearer what it
protects and one to convert mid flags to bool to make clearer

Smbdirect/RDMA restructuring and fixes:
- Fix for error handling in send done
- Remove unneeded empty packet queue
- Fix put_receive_buffer error path
- Two fixes to recv_done error paths
- Remove unused variable
- Improve response and recvmsg type handling
- Fix handling of incoming message type
- Two cleanup fixes for better handling smbdirect recv io
- Two cleanup fixes for socket spinlock
- Two patches that add socket reassembly struct
- Remove unused connection_status enum
- Use flag in common header for SMBDIRECT_RECV_IO_MAX_SGE
- Two cleanup patches to introduce and use smbdirect send io
- Two cleanup patches to introduce and use smbdirect send_io struct
- Fix to return error if rdma connect takes longer than 5 seconds
- Error logging improvements
- Fix redundand call to init_waitqueue_head
- Remove unneeded wait queue"

* tag 'v6.17rc-part2-SMB3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: (33 commits)
smb: client: only use a single wait_queue to monitor smbdirect connection status
smb: client: don't call init_waitqueue_head(&info->conn_wait) twice in _smbd_get_connection
smb: client: improve logging in smbd_conn_upcall()
smb: client: return an error if rdma_connect does not return within 5 seconds
smb: client: make use of smbdirect_socket.{send,recv}_io.mem.{cache,pool}
smb: smbdirect: add smbdirect_socket.{send,recv}_io.mem.{cache,pool}
smb: client: make use of struct smbdirect_send_io
smb: smbdirect: introduce struct smbdirect_send_io
smb: client: make use of SMBDIRECT_RECV_IO_MAX_SGE
smb: smbdirect: add SMBDIRECT_RECV_IO_MAX_SGE
smb: client: remove unused enum smbd_connection_status
smb: client: make use of smbdirect_socket.recv_io.reassembly.*
smb: smbdirect: introduce smbdirect_socket.recv_io.reassembly.*
smb: client: make use of smb: smbdirect_socket.recv_io.free.{list,lock}
smb: smbdirect: introduce smbdirect_socket.recv_io.free.{list,lock}
smb: client: make use of struct smbdirect_recv_io
smb: smbdirect: introduce struct smbdirect_recv_io
smb: client: make use of smbdirect_socket->recv_io.expected
smb: smbdirect: introduce smbdirect_socket.recv_io.expected
smb: client: remove unused smbd_connection->fragment_reassembly_remaining
...

+1066 -1031
+1 -1
fs/smb/client/Makefile
··· 32 32 33 33 cifs-$(CONFIG_CIFS_ROOT) += cifsroot.o 34 34 35 - cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += smb1ops.o cifssmb.o 35 + cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += smb1ops.o cifssmb.o cifstransport.o 36 36 37 37 cifs-$(CONFIG_CIFS_COMPRESSION) += compress.o compress/lz77.o
+11 -13
fs/smb/client/cifs_debug.c
··· 60 60 return; 61 61 62 62 cifs_dbg(VFS, "Dump pending requests:\n"); 63 - spin_lock(&server->mid_lock); 63 + spin_lock(&server->mid_queue_lock); 64 64 list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) { 65 65 cifs_dbg(VFS, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n", 66 66 mid_entry->mid_state, ··· 83 83 mid_entry->resp_buf, 62); 84 84 } 85 85 } 86 - spin_unlock(&server->mid_lock); 86 + spin_unlock(&server->mid_queue_lock); 87 87 #endif /* CONFIG_CIFS_DEBUG2 */ 88 88 } 89 89 ··· 412 412 spin_lock(&cifs_tcp_ses_lock); 413 413 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 414 414 #ifdef CONFIG_CIFS_SMB_DIRECT 415 + struct smbdirect_socket *sc; 415 416 struct smbdirect_socket_parameters *sp; 416 417 #endif 417 418 ··· 437 436 seq_printf(m, "\nSMBDirect transport not available"); 438 437 goto skip_rdma; 439 438 } 440 - sp = &server->smbd_conn->socket.parameters; 439 + sc = &server->smbd_conn->socket; 440 + sp = &sc->parameters; 441 441 442 442 seq_printf(m, "\nSMBDirect (in hex) protocol version: %x " 443 443 "transport status: %x", ··· 467 465 seq_printf(m, "\nRead Queue count_reassembly_queue: %x " 468 466 "count_enqueue_reassembly_queue: %x " 469 467 "count_dequeue_reassembly_queue: %x " 470 - "fragment_reassembly_remaining: %x " 471 468 "reassembly_data_length: %x " 472 469 "reassembly_queue_length: %x", 473 470 server->smbd_conn->count_reassembly_queue, 474 471 server->smbd_conn->count_enqueue_reassembly_queue, 475 472 server->smbd_conn->count_dequeue_reassembly_queue, 476 - server->smbd_conn->fragment_reassembly_remaining, 477 - server->smbd_conn->reassembly_data_length, 478 - server->smbd_conn->reassembly_queue_length); 473 + sc->recv_io.reassembly.data_length, 474 + sc->recv_io.reassembly.queue_length); 479 475 seq_printf(m, "\nCurrent Credits send_credits: %x " 480 476 "receive_credits: %x receive_credit_target: %x", 481 477 atomic_read(&server->smbd_conn->send_credits), ··· 481 481 server->smbd_conn->receive_credit_target); 482 482 seq_printf(m, "\nPending send_pending: %x ", 483 483 atomic_read(&server->smbd_conn->send_pending)); 484 - seq_printf(m, "\nReceive buffers count_receive_queue: %x " 485 - "count_empty_packet_queue: %x", 486 - server->smbd_conn->count_receive_queue, 487 - server->smbd_conn->count_empty_packet_queue); 484 + seq_printf(m, "\nReceive buffers count_receive_queue: %x ", 485 + server->smbd_conn->count_receive_queue); 488 486 seq_printf(m, "\nMR responder_resources: %x " 489 487 "max_frmr_depth: %x mr_type: %x", 490 488 server->smbd_conn->responder_resources, ··· 670 672 671 673 seq_printf(m, "\n\tServer ConnectionId: 0x%llx", 672 674 chan_server->conn_id); 673 - spin_lock(&chan_server->mid_lock); 675 + spin_lock(&chan_server->mid_queue_lock); 674 676 list_for_each_entry(mid_entry, &chan_server->pending_mid_q, qhead) { 675 677 seq_printf(m, "\n\t\tState: %d com: %d pid: %d cbdata: %p mid %llu", 676 678 mid_entry->mid_state, ··· 679 681 mid_entry->callback_data, 680 682 mid_entry->mid); 681 683 } 682 - spin_unlock(&chan_server->mid_lock); 684 + spin_unlock(&chan_server->mid_queue_lock); 683 685 } 684 686 spin_unlock(&ses->chan_lock); 685 687 seq_puts(m, "\n--\n");
+3 -5
fs/smb/client/cifsfs.c
··· 77 77 unsigned int GlobalCurrentXid; /* protected by GlobalMid_Lock */ 78 78 unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Lock */ 79 79 unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Lock */ 80 - spinlock_t GlobalMid_Lock; /* protects above & list operations on midQ entries */ 80 + DEFINE_SPINLOCK(GlobalMid_Lock); /* protects above & list operations on midQ entries */ 81 81 82 82 /* 83 83 * Global counters, updated atomically ··· 97 97 atomic_t total_small_buf_alloc_count; 98 98 #endif/* STATS2 */ 99 99 struct list_head cifs_tcp_ses_list; 100 - spinlock_t cifs_tcp_ses_lock; 100 + DEFINE_SPINLOCK(cifs_tcp_ses_lock); 101 101 static const struct super_operations cifs_super_ops; 102 102 unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; 103 103 module_param(CIFSMaxBufSize, uint, 0444); ··· 723 723 else 724 724 seq_puts(s, ",nativesocket"); 725 725 seq_show_option(s, "symlink", 726 - cifs_symlink_type_str(get_cifs_symlink_type(cifs_sb))); 726 + cifs_symlink_type_str(cifs_symlink_type(cifs_sb))); 727 727 728 728 seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize); 729 729 seq_printf(s, ",wsize=%u", cifs_sb->ctx->wsize); ··· 1863 1863 GlobalCurrentXid = 0; 1864 1864 GlobalTotalActiveXid = 0; 1865 1865 GlobalMaxActiveXid = 0; 1866 - spin_lock_init(&cifs_tcp_ses_lock); 1867 - spin_lock_init(&GlobalMid_Lock); 1868 1866 1869 1867 cifs_lock_secret = get_random_u32(); 1870 1868
+13 -10
fs/smb/client/cifsglob.h
··· 732 732 #endif 733 733 wait_queue_head_t response_q; 734 734 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/ 735 - spinlock_t mid_lock; /* protect mid queue and it's entries */ 735 + spinlock_t mid_queue_lock; /* protect mid queue */ 736 + spinlock_t mid_counter_lock; 736 737 struct list_head pending_mid_q; 737 738 bool noblocksnd; /* use blocking sendmsg */ 738 739 bool noautotune; /* do not autotune send buf sizes */ ··· 771 770 /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ 772 771 unsigned int capabilities; /* selective disabling of caps by smb sess */ 773 772 int timeAdj; /* Adjust for difference in server time zone in sec */ 774 - __u64 CurrentMid; /* multiplex id - rotating counter, protected by GlobalMid_Lock */ 773 + __u64 current_mid; /* multiplex id - rotating counter, protected by mid_counter_lock */ 775 774 char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */ 776 775 /* 16th byte of RFC1001 workstation name is always null */ 777 776 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; ··· 1730 1729 unsigned int resp_buf_size; 1731 1730 int mid_state; /* wish this were enum but can not pass to wait_event */ 1732 1731 int mid_rc; /* rc for MID_RC */ 1733 - unsigned int mid_flags; 1734 1732 __le16 command; /* smb command code */ 1735 1733 unsigned int optype; /* operation type */ 1734 + bool wait_cancelled:1; /* Cancelled while waiting for response */ 1735 + bool deleted_from_q:1; /* Whether Mid has been dequeued frem pending_mid_q */ 1736 1736 bool large_buf:1; /* if valid response, is pointer to large buf */ 1737 1737 bool multiRsp:1; /* multiple trans2 responses for one request */ 1738 1738 bool multiEnd:1; /* both received */ ··· 1895 1893 #define MID_RESPONSE_READY 0x40 /* ready for other process handle the rsp */ 1896 1894 #define MID_RC 0x80 /* mid_rc contains custom rc */ 1897 1895 1898 - /* Flags */ 1899 - #define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ 1900 - #define MID_DELETED 2 /* Mid has been dequeued/deleted */ 1901 - 1902 1896 /* Types of response buffer returned from SendReceive2 */ 1903 1897 #define CIFS_NO_BUFFER 0 /* Response buffer not returned */ 1904 1898 #define CIFS_SMALL_BUFFER 1 ··· 2005 2007 * GlobalCurrentXid 2006 2008 * GlobalTotalActiveXid 2007 2009 * TCP_Server_Info->srv_lock (anything in struct not protected by another lock and can change) 2008 - * TCP_Server_Info->mid_lock TCP_Server_Info->pending_mid_q cifs_get_tcp_session 2009 - * ->CurrentMid 2010 - * (any changes in mid_q_entry fields) 2010 + * TCP_Server_Info->mid_queue_lock TCP_Server_Info->pending_mid_q cifs_get_tcp_session 2011 + * mid_q_entry->deleted_from_q 2012 + * TCP_Server_Info->mid_counter_lock TCP_Server_Info->current_mid cifs_get_tcp_session 2011 2013 * TCP_Server_Info->req_lock TCP_Server_Info->in_flight cifs_get_tcp_session 2012 2014 * ->credits 2013 2015 * ->echo_credits ··· 2374 2376 } 2375 2377 return ret; 2376 2378 } 2379 + 2380 + #define CIFS_REPARSE_SUPPORT(tcon) \ 2381 + ((tcon)->posix_extensions || \ 2382 + (le32_to_cpu((tcon)->fsAttrInfo.Attributes) & \ 2383 + FILE_SUPPORTS_REPARSE_POINTS)) 2377 2384 2378 2385 #endif /* _CIFS_GLOB_H */
+15
fs/smb/client/cifsproto.h
··· 116 116 int * /* bytes returned */ , const int); 117 117 extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, 118 118 char *in_buf, int flags); 119 + int cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server); 119 120 extern struct mid_q_entry *cifs_setup_request(struct cifs_ses *, 120 121 struct TCP_Server_Info *, 121 122 struct smb_rqst *); 122 123 extern struct mid_q_entry *cifs_setup_async_request(struct TCP_Server_Info *, 123 124 struct smb_rqst *); 125 + int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, 126 + struct smb_rqst *rqst); 124 127 extern int cifs_check_receive(struct mid_q_entry *mid, 125 128 struct TCP_Server_Info *server, bool log_error); 129 + int wait_for_free_request(struct TCP_Server_Info *server, const int flags, 130 + unsigned int *instance); 126 131 extern int cifs_wait_mtu_credits(struct TCP_Server_Info *server, 127 132 size_t size, size_t *num, 128 133 struct cifs_credits *credits); 134 + 135 + static inline int 136 + send_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst, 137 + struct mid_q_entry *mid) 138 + { 139 + return server->ops->send_cancel ? 140 + server->ops->send_cancel(server, rqst, mid) : 0; 141 + } 142 + 143 + int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ); 129 144 extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *, 130 145 struct kvec *, int /* nvec to send */, 131 146 int * /* type of buf returned */, const int flags,
+2 -2
fs/smb/client/cifssmb.c
··· 2751 2751 if (cap_unix(tcon->ses)) 2752 2752 return -EOPNOTSUPP; 2753 2753 2754 - if (!(le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS)) 2754 + if (!CIFS_REPARSE_SUPPORT(tcon)) 2755 2755 return -EOPNOTSUPP; 2756 2756 2757 2757 oparms = (struct cifs_open_parms) { ··· 2879 2879 * attempt to create reparse point. This will prevent creating unusable 2880 2880 * empty object on the server. 2881 2881 */ 2882 - if (!(le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS)) 2882 + if (!CIFS_REPARSE_SUPPORT(tcon)) 2883 2883 return ERR_PTR(-EOPNOTSUPP); 2884 2884 2885 2885 #ifndef CONFIG_CIFS_XATTR
+566
fs/smb/client/cifstransport.c
··· 1 + // SPDX-License-Identifier: LGPL-2.1 2 + /* 3 + * 4 + * Copyright (C) International Business Machines Corp., 2002,2008 5 + * Author(s): Steve French (sfrench@us.ibm.com) 6 + * Jeremy Allison (jra@samba.org) 2006. 7 + * 8 + */ 9 + 10 + #include <linux/fs.h> 11 + #include <linux/list.h> 12 + #include <linux/gfp.h> 13 + #include <linux/wait.h> 14 + #include <linux/net.h> 15 + #include <linux/delay.h> 16 + #include <linux/freezer.h> 17 + #include <linux/tcp.h> 18 + #include <linux/bvec.h> 19 + #include <linux/highmem.h> 20 + #include <linux/uaccess.h> 21 + #include <linux/processor.h> 22 + #include <linux/mempool.h> 23 + #include <linux/sched/signal.h> 24 + #include <linux/task_io_accounting_ops.h> 25 + #include "cifspdu.h" 26 + #include "cifsglob.h" 27 + #include "cifsproto.h" 28 + #include "cifs_debug.h" 29 + #include "smb2proto.h" 30 + #include "smbdirect.h" 31 + #include "compress.h" 32 + 33 + /* Max number of iovectors we can use off the stack when sending requests. */ 34 + #define CIFS_MAX_IOV_SIZE 8 35 + 36 + static struct mid_q_entry * 37 + alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server) 38 + { 39 + struct mid_q_entry *temp; 40 + 41 + if (server == NULL) { 42 + cifs_dbg(VFS, "%s: null TCP session\n", __func__); 43 + return NULL; 44 + } 45 + 46 + temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS); 47 + memset(temp, 0, sizeof(struct mid_q_entry)); 48 + kref_init(&temp->refcount); 49 + temp->mid = get_mid(smb_buffer); 50 + temp->pid = current->pid; 51 + temp->command = cpu_to_le16(smb_buffer->Command); 52 + cifs_dbg(FYI, "For smb_command %d\n", smb_buffer->Command); 53 + /* easier to use jiffies */ 54 + /* when mid allocated can be before when sent */ 55 + temp->when_alloc = jiffies; 56 + temp->server = server; 57 + 58 + /* 59 + * The default is for the mid to be synchronous, so the 60 + * default callback just wakes up the current task. 61 + */ 62 + get_task_struct(current); 63 + temp->creator = current; 64 + temp->callback = cifs_wake_up_task; 65 + temp->callback_data = current; 66 + 67 + atomic_inc(&mid_count); 68 + temp->mid_state = MID_REQUEST_ALLOCATED; 69 + return temp; 70 + } 71 + 72 + int 73 + smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, 74 + unsigned int smb_buf_length) 75 + { 76 + struct kvec iov[2]; 77 + struct smb_rqst rqst = { .rq_iov = iov, 78 + .rq_nvec = 2 }; 79 + 80 + iov[0].iov_base = smb_buffer; 81 + iov[0].iov_len = 4; 82 + iov[1].iov_base = (char *)smb_buffer + 4; 83 + iov[1].iov_len = smb_buf_length; 84 + 85 + return __smb_send_rqst(server, 1, &rqst); 86 + } 87 + 88 + static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf, 89 + struct mid_q_entry **ppmidQ) 90 + { 91 + spin_lock(&ses->ses_lock); 92 + if (ses->ses_status == SES_NEW) { 93 + if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 94 + (in_buf->Command != SMB_COM_NEGOTIATE)) { 95 + spin_unlock(&ses->ses_lock); 96 + return -EAGAIN; 97 + } 98 + /* else ok - we are setting up session */ 99 + } 100 + 101 + if (ses->ses_status == SES_EXITING) { 102 + /* check if SMB session is bad because we are setting it up */ 103 + if (in_buf->Command != SMB_COM_LOGOFF_ANDX) { 104 + spin_unlock(&ses->ses_lock); 105 + return -EAGAIN; 106 + } 107 + /* else ok - we are shutting down session */ 108 + } 109 + spin_unlock(&ses->ses_lock); 110 + 111 + *ppmidQ = alloc_mid(in_buf, ses->server); 112 + if (*ppmidQ == NULL) 113 + return -ENOMEM; 114 + spin_lock(&ses->server->mid_queue_lock); 115 + list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q); 116 + spin_unlock(&ses->server->mid_queue_lock); 117 + return 0; 118 + } 119 + 120 + struct mid_q_entry * 121 + cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst) 122 + { 123 + int rc; 124 + struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base; 125 + struct mid_q_entry *mid; 126 + 127 + if (rqst->rq_iov[0].iov_len != 4 || 128 + rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base) 129 + return ERR_PTR(-EIO); 130 + 131 + /* enable signing if server requires it */ 132 + if (server->sign) 133 + hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 134 + 135 + mid = alloc_mid(hdr, server); 136 + if (mid == NULL) 137 + return ERR_PTR(-ENOMEM); 138 + 139 + rc = cifs_sign_rqst(rqst, server, &mid->sequence_number); 140 + if (rc) { 141 + release_mid(mid); 142 + return ERR_PTR(rc); 143 + } 144 + 145 + return mid; 146 + } 147 + 148 + /* 149 + * 150 + * Send an SMB Request. No response info (other than return code) 151 + * needs to be parsed. 152 + * 153 + * flags indicate the type of request buffer and how long to wait 154 + * and whether to log NT STATUS code (error) before mapping it to POSIX error 155 + * 156 + */ 157 + int 158 + SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, 159 + char *in_buf, int flags) 160 + { 161 + int rc; 162 + struct kvec iov[1]; 163 + struct kvec rsp_iov; 164 + int resp_buf_type; 165 + 166 + iov[0].iov_base = in_buf; 167 + iov[0].iov_len = get_rfc1002_length(in_buf) + 4; 168 + flags |= CIFS_NO_RSP_BUF; 169 + rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov); 170 + cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc); 171 + 172 + return rc; 173 + } 174 + 175 + int 176 + cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, 177 + bool log_error) 178 + { 179 + unsigned int len = get_rfc1002_length(mid->resp_buf) + 4; 180 + 181 + dump_smb(mid->resp_buf, min_t(u32, 92, len)); 182 + 183 + /* convert the length into a more usable form */ 184 + if (server->sign) { 185 + struct kvec iov[2]; 186 + int rc = 0; 187 + struct smb_rqst rqst = { .rq_iov = iov, 188 + .rq_nvec = 2 }; 189 + 190 + iov[0].iov_base = mid->resp_buf; 191 + iov[0].iov_len = 4; 192 + iov[1].iov_base = (char *)mid->resp_buf + 4; 193 + iov[1].iov_len = len - 4; 194 + /* FIXME: add code to kill session */ 195 + rc = cifs_verify_signature(&rqst, server, 196 + mid->sequence_number); 197 + if (rc) 198 + cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n", 199 + rc); 200 + } 201 + 202 + /* BB special case reconnect tid and uid here? */ 203 + return map_and_check_smb_error(mid, log_error); 204 + } 205 + 206 + struct mid_q_entry * 207 + cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored, 208 + struct smb_rqst *rqst) 209 + { 210 + int rc; 211 + struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base; 212 + struct mid_q_entry *mid; 213 + 214 + if (rqst->rq_iov[0].iov_len != 4 || 215 + rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base) 216 + return ERR_PTR(-EIO); 217 + 218 + rc = allocate_mid(ses, hdr, &mid); 219 + if (rc) 220 + return ERR_PTR(rc); 221 + rc = cifs_sign_rqst(rqst, ses->server, &mid->sequence_number); 222 + if (rc) { 223 + delete_mid(mid); 224 + return ERR_PTR(rc); 225 + } 226 + return mid; 227 + } 228 + 229 + int 230 + SendReceive2(const unsigned int xid, struct cifs_ses *ses, 231 + struct kvec *iov, int n_vec, int *resp_buf_type /* ret */, 232 + const int flags, struct kvec *resp_iov) 233 + { 234 + struct smb_rqst rqst; 235 + struct kvec s_iov[CIFS_MAX_IOV_SIZE], *new_iov; 236 + int rc; 237 + 238 + if (n_vec + 1 > CIFS_MAX_IOV_SIZE) { 239 + new_iov = kmalloc_array(n_vec + 1, sizeof(struct kvec), 240 + GFP_KERNEL); 241 + if (!new_iov) { 242 + /* otherwise cifs_send_recv below sets resp_buf_type */ 243 + *resp_buf_type = CIFS_NO_BUFFER; 244 + return -ENOMEM; 245 + } 246 + } else 247 + new_iov = s_iov; 248 + 249 + /* 1st iov is a RFC1001 length followed by the rest of the packet */ 250 + memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec)); 251 + 252 + new_iov[0].iov_base = new_iov[1].iov_base; 253 + new_iov[0].iov_len = 4; 254 + new_iov[1].iov_base += 4; 255 + new_iov[1].iov_len -= 4; 256 + 257 + memset(&rqst, 0, sizeof(struct smb_rqst)); 258 + rqst.rq_iov = new_iov; 259 + rqst.rq_nvec = n_vec + 1; 260 + 261 + rc = cifs_send_recv(xid, ses, ses->server, 262 + &rqst, resp_buf_type, flags, resp_iov); 263 + if (n_vec + 1 > CIFS_MAX_IOV_SIZE) 264 + kfree(new_iov); 265 + return rc; 266 + } 267 + 268 + int 269 + SendReceive(const unsigned int xid, struct cifs_ses *ses, 270 + struct smb_hdr *in_buf, struct smb_hdr *out_buf, 271 + int *pbytes_returned, const int flags) 272 + { 273 + int rc = 0; 274 + struct mid_q_entry *midQ; 275 + unsigned int len = be32_to_cpu(in_buf->smb_buf_length); 276 + struct kvec iov = { .iov_base = in_buf, .iov_len = len }; 277 + struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; 278 + struct cifs_credits credits = { .value = 1, .instance = 0 }; 279 + struct TCP_Server_Info *server; 280 + 281 + if (ses == NULL) { 282 + cifs_dbg(VFS, "Null smb session\n"); 283 + return -EIO; 284 + } 285 + server = ses->server; 286 + if (server == NULL) { 287 + cifs_dbg(VFS, "Null tcp session\n"); 288 + return -EIO; 289 + } 290 + 291 + spin_lock(&server->srv_lock); 292 + if (server->tcpStatus == CifsExiting) { 293 + spin_unlock(&server->srv_lock); 294 + return -ENOENT; 295 + } 296 + spin_unlock(&server->srv_lock); 297 + 298 + /* Ensure that we do not send more than 50 overlapping requests 299 + to the same server. We may make this configurable later or 300 + use ses->maxReq */ 301 + 302 + if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 303 + cifs_server_dbg(VFS, "Invalid length, greater than maximum frame, %d\n", 304 + len); 305 + return -EIO; 306 + } 307 + 308 + rc = wait_for_free_request(server, flags, &credits.instance); 309 + if (rc) 310 + return rc; 311 + 312 + /* make sure that we sign in the same order that we send on this socket 313 + and avoid races inside tcp sendmsg code that could cause corruption 314 + of smb data */ 315 + 316 + cifs_server_lock(server); 317 + 318 + rc = allocate_mid(ses, in_buf, &midQ); 319 + if (rc) { 320 + cifs_server_unlock(server); 321 + /* Update # of requests on wire to server */ 322 + add_credits(server, &credits, 0); 323 + return rc; 324 + } 325 + 326 + rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number); 327 + if (rc) { 328 + cifs_server_unlock(server); 329 + goto out; 330 + } 331 + 332 + midQ->mid_state = MID_REQUEST_SUBMITTED; 333 + 334 + rc = smb_send(server, in_buf, len); 335 + cifs_save_when_sent(midQ); 336 + 337 + if (rc < 0) 338 + server->sequence_number -= 2; 339 + 340 + cifs_server_unlock(server); 341 + 342 + if (rc < 0) 343 + goto out; 344 + 345 + rc = wait_for_response(server, midQ); 346 + if (rc != 0) { 347 + send_cancel(server, &rqst, midQ); 348 + spin_lock(&server->mid_queue_lock); 349 + if (midQ->mid_state == MID_REQUEST_SUBMITTED || 350 + midQ->mid_state == MID_RESPONSE_RECEIVED) { 351 + /* no longer considered to be "in-flight" */ 352 + midQ->callback = release_mid; 353 + spin_unlock(&server->mid_queue_lock); 354 + add_credits(server, &credits, 0); 355 + return rc; 356 + } 357 + spin_unlock(&server->mid_queue_lock); 358 + } 359 + 360 + rc = cifs_sync_mid_result(midQ, server); 361 + if (rc != 0) { 362 + add_credits(server, &credits, 0); 363 + return rc; 364 + } 365 + 366 + if (!midQ->resp_buf || !out_buf || 367 + midQ->mid_state != MID_RESPONSE_READY) { 368 + rc = -EIO; 369 + cifs_server_dbg(VFS, "Bad MID state?\n"); 370 + goto out; 371 + } 372 + 373 + *pbytes_returned = get_rfc1002_length(midQ->resp_buf); 374 + memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4); 375 + rc = cifs_check_receive(midQ, server, 0); 376 + out: 377 + delete_mid(midQ); 378 + add_credits(server, &credits, 0); 379 + 380 + return rc; 381 + } 382 + 383 + /* We send a LOCKINGX_CANCEL_LOCK to cause the Windows 384 + blocking lock to return. */ 385 + 386 + static int 387 + send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon, 388 + struct smb_hdr *in_buf, 389 + struct smb_hdr *out_buf) 390 + { 391 + int bytes_returned; 392 + struct cifs_ses *ses = tcon->ses; 393 + LOCK_REQ *pSMB = (LOCK_REQ *)in_buf; 394 + 395 + /* We just modify the current in_buf to change 396 + the type of lock from LOCKING_ANDX_SHARED_LOCK 397 + or LOCKING_ANDX_EXCLUSIVE_LOCK to 398 + LOCKING_ANDX_CANCEL_LOCK. */ 399 + 400 + pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES; 401 + pSMB->Timeout = 0; 402 + pSMB->hdr.Mid = get_next_mid(ses->server); 403 + 404 + return SendReceive(xid, ses, in_buf, out_buf, 405 + &bytes_returned, 0); 406 + } 407 + 408 + int 409 + SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, 410 + struct smb_hdr *in_buf, struct smb_hdr *out_buf, 411 + int *pbytes_returned) 412 + { 413 + int rc = 0; 414 + int rstart = 0; 415 + struct mid_q_entry *midQ; 416 + struct cifs_ses *ses; 417 + unsigned int len = be32_to_cpu(in_buf->smb_buf_length); 418 + struct kvec iov = { .iov_base = in_buf, .iov_len = len }; 419 + struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; 420 + unsigned int instance; 421 + struct TCP_Server_Info *server; 422 + 423 + if (tcon == NULL || tcon->ses == NULL) { 424 + cifs_dbg(VFS, "Null smb session\n"); 425 + return -EIO; 426 + } 427 + ses = tcon->ses; 428 + server = ses->server; 429 + 430 + if (server == NULL) { 431 + cifs_dbg(VFS, "Null tcp session\n"); 432 + return -EIO; 433 + } 434 + 435 + spin_lock(&server->srv_lock); 436 + if (server->tcpStatus == CifsExiting) { 437 + spin_unlock(&server->srv_lock); 438 + return -ENOENT; 439 + } 440 + spin_unlock(&server->srv_lock); 441 + 442 + /* Ensure that we do not send more than 50 overlapping requests 443 + to the same server. We may make this configurable later or 444 + use ses->maxReq */ 445 + 446 + if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 447 + cifs_tcon_dbg(VFS, "Invalid length, greater than maximum frame, %d\n", 448 + len); 449 + return -EIO; 450 + } 451 + 452 + rc = wait_for_free_request(server, CIFS_BLOCKING_OP, &instance); 453 + if (rc) 454 + return rc; 455 + 456 + /* make sure that we sign in the same order that we send on this socket 457 + and avoid races inside tcp sendmsg code that could cause corruption 458 + of smb data */ 459 + 460 + cifs_server_lock(server); 461 + 462 + rc = allocate_mid(ses, in_buf, &midQ); 463 + if (rc) { 464 + cifs_server_unlock(server); 465 + return rc; 466 + } 467 + 468 + rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number); 469 + if (rc) { 470 + delete_mid(midQ); 471 + cifs_server_unlock(server); 472 + return rc; 473 + } 474 + 475 + midQ->mid_state = MID_REQUEST_SUBMITTED; 476 + rc = smb_send(server, in_buf, len); 477 + cifs_save_when_sent(midQ); 478 + 479 + if (rc < 0) 480 + server->sequence_number -= 2; 481 + 482 + cifs_server_unlock(server); 483 + 484 + if (rc < 0) { 485 + delete_mid(midQ); 486 + return rc; 487 + } 488 + 489 + /* Wait for a reply - allow signals to interrupt. */ 490 + rc = wait_event_interruptible(server->response_q, 491 + (!(midQ->mid_state == MID_REQUEST_SUBMITTED || 492 + midQ->mid_state == MID_RESPONSE_RECEIVED)) || 493 + ((server->tcpStatus != CifsGood) && 494 + (server->tcpStatus != CifsNew))); 495 + 496 + /* Were we interrupted by a signal ? */ 497 + spin_lock(&server->srv_lock); 498 + if ((rc == -ERESTARTSYS) && 499 + (midQ->mid_state == MID_REQUEST_SUBMITTED || 500 + midQ->mid_state == MID_RESPONSE_RECEIVED) && 501 + ((server->tcpStatus == CifsGood) || 502 + (server->tcpStatus == CifsNew))) { 503 + spin_unlock(&server->srv_lock); 504 + 505 + if (in_buf->Command == SMB_COM_TRANSACTION2) { 506 + /* POSIX lock. We send a NT_CANCEL SMB to cause the 507 + blocking lock to return. */ 508 + rc = send_cancel(server, &rqst, midQ); 509 + if (rc) { 510 + delete_mid(midQ); 511 + return rc; 512 + } 513 + } else { 514 + /* Windows lock. We send a LOCKINGX_CANCEL_LOCK 515 + to cause the blocking lock to return. */ 516 + 517 + rc = send_lock_cancel(xid, tcon, in_buf, out_buf); 518 + 519 + /* If we get -ENOLCK back the lock may have 520 + already been removed. Don't exit in this case. */ 521 + if (rc && rc != -ENOLCK) { 522 + delete_mid(midQ); 523 + return rc; 524 + } 525 + } 526 + 527 + rc = wait_for_response(server, midQ); 528 + if (rc) { 529 + send_cancel(server, &rqst, midQ); 530 + spin_lock(&server->mid_queue_lock); 531 + if (midQ->mid_state == MID_REQUEST_SUBMITTED || 532 + midQ->mid_state == MID_RESPONSE_RECEIVED) { 533 + /* no longer considered to be "in-flight" */ 534 + midQ->callback = release_mid; 535 + spin_unlock(&server->mid_queue_lock); 536 + return rc; 537 + } 538 + spin_unlock(&server->mid_queue_lock); 539 + } 540 + 541 + /* We got the response - restart system call. */ 542 + rstart = 1; 543 + spin_lock(&server->srv_lock); 544 + } 545 + spin_unlock(&server->srv_lock); 546 + 547 + rc = cifs_sync_mid_result(midQ, server); 548 + if (rc != 0) 549 + return rc; 550 + 551 + /* rcvd frame is ok */ 552 + if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_READY) { 553 + rc = -EIO; 554 + cifs_tcon_dbg(VFS, "Bad MID state?\n"); 555 + goto out; 556 + } 557 + 558 + *pbytes_returned = get_rfc1002_length(midQ->resp_buf); 559 + memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4); 560 + rc = cifs_check_receive(midQ, server, 0); 561 + out: 562 + delete_mid(midQ); 563 + if (rstart && rc == -EACCES) 564 + return -ERESTARTSYS; 565 + return rc; 566 + }
+18 -17
fs/smb/client/connect.c
··· 321 321 /* mark submitted MIDs for retry and issue callback */ 322 322 INIT_LIST_HEAD(&retry_list); 323 323 cifs_dbg(FYI, "%s: moving mids to private list\n", __func__); 324 - spin_lock(&server->mid_lock); 324 + spin_lock(&server->mid_queue_lock); 325 325 list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) { 326 326 kref_get(&mid->refcount); 327 327 if (mid->mid_state == MID_REQUEST_SUBMITTED) 328 328 mid->mid_state = MID_RETRY_NEEDED; 329 329 list_move(&mid->qhead, &retry_list); 330 - mid->mid_flags |= MID_DELETED; 330 + mid->deleted_from_q = true; 331 331 } 332 - spin_unlock(&server->mid_lock); 332 + spin_unlock(&server->mid_queue_lock); 333 333 cifs_server_unlock(server); 334 334 335 335 cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__); ··· 358 358 } 359 359 360 360 cifs_dbg(FYI, "Mark tcp session as need reconnect\n"); 361 - trace_smb3_reconnect(server->CurrentMid, server->conn_id, 361 + trace_smb3_reconnect(server->current_mid, server->conn_id, 362 362 server->hostname); 363 363 server->tcpStatus = CifsNeedReconnect; 364 364 ··· 884 884 * server there should be exactly one pending mid 885 885 * corresponding to SMB1/SMB2 Negotiate packet. 886 886 */ 887 - spin_lock(&server->mid_lock); 887 + spin_lock(&server->mid_queue_lock); 888 888 list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) { 889 889 kref_get(&mid->refcount); 890 890 list_move(&mid->qhead, &dispose_list); 891 - mid->mid_flags |= MID_DELETED; 891 + mid->deleted_from_q = true; 892 892 } 893 - spin_unlock(&server->mid_lock); 893 + spin_unlock(&server->mid_queue_lock); 894 894 895 895 /* Now try to reconnect once with NetBIOS session. */ 896 896 server->with_rfc1001 = true; ··· 957 957 #ifdef CONFIG_CIFS_STATS2 958 958 mid->when_received = jiffies; 959 959 #endif 960 - spin_lock(&mid->server->mid_lock); 960 + spin_lock(&mid->server->mid_queue_lock); 961 961 if (!malformed) 962 962 mid->mid_state = MID_RESPONSE_RECEIVED; 963 963 else ··· 966 966 * Trying to handle/dequeue a mid after the send_recv() 967 967 * function has finished processing it is a bug. 968 968 */ 969 - if (mid->mid_flags & MID_DELETED) { 970 - spin_unlock(&mid->server->mid_lock); 969 + if (mid->deleted_from_q == true) { 970 + spin_unlock(&mid->server->mid_queue_lock); 971 971 pr_warn_once("trying to dequeue a deleted mid\n"); 972 972 } else { 973 973 list_del_init(&mid->qhead); 974 - mid->mid_flags |= MID_DELETED; 975 - spin_unlock(&mid->server->mid_lock); 974 + mid->deleted_from_q = true; 975 + spin_unlock(&mid->server->mid_queue_lock); 976 976 } 977 977 } 978 978 ··· 1101 1101 struct list_head *tmp, *tmp2; 1102 1102 LIST_HEAD(dispose_list); 1103 1103 1104 - spin_lock(&server->mid_lock); 1104 + spin_lock(&server->mid_queue_lock); 1105 1105 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { 1106 1106 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 1107 1107 cifs_dbg(FYI, "Clearing mid %llu\n", mid_entry->mid); 1108 1108 kref_get(&mid_entry->refcount); 1109 1109 mid_entry->mid_state = MID_SHUTDOWN; 1110 1110 list_move(&mid_entry->qhead, &dispose_list); 1111 - mid_entry->mid_flags |= MID_DELETED; 1111 + mid_entry->deleted_from_q = true; 1112 1112 } 1113 - spin_unlock(&server->mid_lock); 1113 + spin_unlock(&server->mid_queue_lock); 1114 1114 1115 1115 /* now walk dispose list and issue callbacks */ 1116 1116 list_for_each_safe(tmp, tmp2, &dispose_list) { ··· 1242 1242 spin_unlock(&server->req_lock); 1243 1243 wake_up(&server->request_q); 1244 1244 1245 - trace_smb3_hdr_credits(server->CurrentMid, 1245 + trace_smb3_hdr_credits(server->current_mid, 1246 1246 server->conn_id, server->hostname, scredits, 1247 1247 le16_to_cpu(shdr->CreditRequest), in_flight); 1248 1248 cifs_server_dbg(FYI, "%s: added %u credits total=%d\n", ··· 1822 1822 tcp_ses->compression.requested = ctx->compress; 1823 1823 spin_lock_init(&tcp_ses->req_lock); 1824 1824 spin_lock_init(&tcp_ses->srv_lock); 1825 - spin_lock_init(&tcp_ses->mid_lock); 1825 + spin_lock_init(&tcp_ses->mid_queue_lock); 1826 + spin_lock_init(&tcp_ses->mid_counter_lock); 1826 1827 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); 1827 1828 INIT_LIST_HEAD(&tcp_ses->smb_ses_list); 1828 1829 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
+1 -18
fs/smb/client/fs_context.c
··· 1652 1652 pr_warn_once("conflicting posix mount options specified\n"); 1653 1653 ctx->linux_ext = 1; 1654 1654 ctx->no_linux_ext = 0; 1655 + ctx->nonativesocket = 1; /* POSIX mounts use NFS style reparse points */ 1655 1656 } 1656 1657 break; 1657 1658 case Opt_nocase: ··· 1828 1827 kfree_sensitive(ctx->password2); 1829 1828 ctx->password2 = NULL; 1830 1829 return -EINVAL; 1831 - } 1832 - 1833 - enum cifs_symlink_type get_cifs_symlink_type(struct cifs_sb_info *cifs_sb) 1834 - { 1835 - if (cifs_sb->ctx->symlink_type == CIFS_SYMLINK_TYPE_DEFAULT) { 1836 - if (cifs_sb->ctx->mfsymlinks) 1837 - return CIFS_SYMLINK_TYPE_MFSYMLINKS; 1838 - else if (cifs_sb->ctx->sfu_emul) 1839 - return CIFS_SYMLINK_TYPE_SFU; 1840 - else if (cifs_sb->ctx->linux_ext && !cifs_sb->ctx->no_linux_ext) 1841 - return CIFS_SYMLINK_TYPE_UNIX; 1842 - else if (cifs_sb->ctx->reparse_type != CIFS_REPARSE_TYPE_NONE) 1843 - return CIFS_SYMLINK_TYPE_NATIVE; 1844 - else 1845 - return CIFS_SYMLINK_TYPE_NONE; 1846 - } else { 1847 - return cifs_sb->ctx->symlink_type; 1848 - } 1849 1830 } 1850 1831 1851 1832 int smb3_init_fs_context(struct fs_context *fc)
+17 -1
fs/smb/client/fs_context.h
··· 341 341 342 342 extern const struct fs_parameter_spec smb3_fs_parameters[]; 343 343 344 - extern enum cifs_symlink_type get_cifs_symlink_type(struct cifs_sb_info *cifs_sb); 344 + static inline enum cifs_symlink_type cifs_symlink_type(struct cifs_sb_info *cifs_sb) 345 + { 346 + bool posix = cifs_sb_master_tcon(cifs_sb)->posix_extensions; 347 + 348 + if (cifs_sb->ctx->symlink_type != CIFS_SYMLINK_TYPE_DEFAULT) 349 + return cifs_sb->ctx->symlink_type; 350 + 351 + if (cifs_sb->ctx->mfsymlinks) 352 + return CIFS_SYMLINK_TYPE_MFSYMLINKS; 353 + else if (cifs_sb->ctx->sfu_emul) 354 + return CIFS_SYMLINK_TYPE_SFU; 355 + else if (cifs_sb->ctx->linux_ext && !cifs_sb->ctx->no_linux_ext) 356 + return posix ? CIFS_SYMLINK_TYPE_NATIVE : CIFS_SYMLINK_TYPE_UNIX; 357 + else if (cifs_sb->ctx->reparse_type != CIFS_REPARSE_TYPE_NONE) 358 + return CIFS_SYMLINK_TYPE_NATIVE; 359 + return CIFS_SYMLINK_TYPE_NONE; 360 + } 345 361 346 362 extern int smb3_init_fs_context(struct fs_context *fc); 347 363 extern void smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx);
+4 -9
fs/smb/client/link.c
··· 605 605 606 606 /* BB what if DFS and this volume is on different share? BB */ 607 607 rc = -EOPNOTSUPP; 608 - switch (get_cifs_symlink_type(cifs_sb)) { 609 - case CIFS_SYMLINK_TYPE_DEFAULT: 610 - /* should not happen, get_cifs_symlink_type() resolves the default */ 611 - break; 612 - 613 - case CIFS_SYMLINK_TYPE_NONE: 614 - break; 615 - 608 + switch (cifs_symlink_type(cifs_sb)) { 616 609 case CIFS_SYMLINK_TYPE_UNIX: 617 610 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 618 611 if (pTcon->unix_ext) { ··· 635 642 case CIFS_SYMLINK_TYPE_NATIVE: 636 643 case CIFS_SYMLINK_TYPE_NFS: 637 644 case CIFS_SYMLINK_TYPE_WSL: 638 - if (le32_to_cpu(pTcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS) { 645 + if (CIFS_REPARSE_SUPPORT(pTcon)) { 639 646 rc = create_reparse_symlink(xid, inode, direntry, pTcon, 640 647 full_path, symname); 641 648 goto symlink_exit; 642 649 } 650 + break; 651 + default: 643 652 break; 644 653 } 645 654
+1 -1
fs/smb/client/reparse.c
··· 38 38 struct dentry *dentry, struct cifs_tcon *tcon, 39 39 const char *full_path, const char *symname) 40 40 { 41 - switch (get_cifs_symlink_type(CIFS_SB(inode->i_sb))) { 41 + switch (cifs_symlink_type(CIFS_SB(inode->i_sb))) { 42 42 case CIFS_SYMLINK_TYPE_NATIVE: 43 43 return create_native_symlink(xid, inode, dentry, tcon, full_path, symname); 44 44 case CIFS_SYMLINK_TYPE_NFS:
+10 -9
fs/smb/client/smb1ops.c
··· 95 95 struct smb_hdr *buf = (struct smb_hdr *)buffer; 96 96 struct mid_q_entry *mid; 97 97 98 - spin_lock(&server->mid_lock); 98 + spin_lock(&server->mid_queue_lock); 99 99 list_for_each_entry(mid, &server->pending_mid_q, qhead) { 100 100 if (compare_mid(mid->mid, buf) && 101 101 mid->mid_state == MID_REQUEST_SUBMITTED && 102 102 le16_to_cpu(mid->command) == buf->Command) { 103 103 kref_get(&mid->refcount); 104 - spin_unlock(&server->mid_lock); 104 + spin_unlock(&server->mid_queue_lock); 105 105 return mid; 106 106 } 107 107 } 108 - spin_unlock(&server->mid_lock); 108 + spin_unlock(&server->mid_queue_lock); 109 109 return NULL; 110 110 } 111 111 ··· 169 169 __u16 last_mid, cur_mid; 170 170 bool collision, reconnect = false; 171 171 172 - spin_lock(&server->mid_lock); 173 - 172 + spin_lock(&server->mid_counter_lock); 174 173 /* mid is 16 bit only for CIFS/SMB */ 175 - cur_mid = (__u16)((server->CurrentMid) & 0xffff); 174 + cur_mid = (__u16)((server->current_mid) & 0xffff); 176 175 /* we do not want to loop forever */ 177 176 last_mid = cur_mid; 178 177 cur_mid++; ··· 197 198 cur_mid++; 198 199 199 200 num_mids = 0; 201 + spin_lock(&server->mid_queue_lock); 200 202 list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) { 201 203 ++num_mids; 202 204 if (mid_entry->mid == cur_mid && ··· 207 207 break; 208 208 } 209 209 } 210 + spin_unlock(&server->mid_queue_lock); 210 211 211 212 /* 212 213 * if we have more than 32k mids in the list, then something ··· 224 223 225 224 if (!collision) { 226 225 mid = (__u64)cur_mid; 227 - server->CurrentMid = mid; 226 + server->current_mid = mid; 228 227 break; 229 228 } 230 229 cur_mid++; 231 230 } 232 - spin_unlock(&server->mid_lock); 231 + spin_unlock(&server->mid_counter_lock); 233 232 234 233 if (reconnect) { 235 234 cifs_signal_cifsd_for_reconnect(server, false); ··· 1273 1272 */ 1274 1273 return cifs_sfu_make_node(xid, inode, dentry, tcon, 1275 1274 full_path, mode, dev); 1276 - } else if (le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS) { 1275 + } else if (CIFS_REPARSE_SUPPORT(tcon)) { 1277 1276 /* 1278 1277 * mknod via reparse points requires server support for 1279 1278 * storing reparse points, which is available since
+2 -3
fs/smb/client/smb2inode.c
··· 1346 1346 * attempt to create reparse point. This will prevent creating unusable 1347 1347 * empty object on the server. 1348 1348 */ 1349 - if (!(le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS)) 1350 - if (!tcon->posix_extensions) 1351 - return ERR_PTR(-EOPNOTSUPP); 1349 + if (!CIFS_REPARSE_SUPPORT(tcon)) 1350 + return ERR_PTR(-EOPNOTSUPP); 1352 1351 1353 1352 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, 1354 1353 SYNCHRONIZE | DELETE |
+31 -32
fs/smb/client/smb2ops.c
··· 91 91 if (*val > 65000) { 92 92 *val = 65000; /* Don't get near 64K credits, avoid srv bugs */ 93 93 pr_warn_once("server overflowed SMB3 credits\n"); 94 - trace_smb3_overflow_credits(server->CurrentMid, 94 + trace_smb3_overflow_credits(server->current_mid, 95 95 server->conn_id, server->hostname, *val, 96 96 add, server->in_flight); 97 97 } ··· 136 136 wake_up(&server->request_q); 137 137 138 138 if (reconnect_detected) { 139 - trace_smb3_reconnect_detected(server->CurrentMid, 139 + trace_smb3_reconnect_detected(server->current_mid, 140 140 server->conn_id, server->hostname, scredits, add, in_flight); 141 141 142 142 cifs_dbg(FYI, "trying to put %d credits from the old server instance %d\n", ··· 144 144 } 145 145 146 146 if (reconnect_with_invalid_credits) { 147 - trace_smb3_reconnect_with_invalid_credits(server->CurrentMid, 147 + trace_smb3_reconnect_with_invalid_credits(server->current_mid, 148 148 server->conn_id, server->hostname, scredits, add, in_flight); 149 149 cifs_dbg(FYI, "Negotiate operation when server credits is non-zero. Optype: %d, server credits: %d, credits added: %d\n", 150 150 optype, scredits, add); ··· 176 176 break; 177 177 } 178 178 179 - trace_smb3_add_credits(server->CurrentMid, 179 + trace_smb3_add_credits(server->current_mid, 180 180 server->conn_id, server->hostname, scredits, add, in_flight); 181 181 cifs_dbg(FYI, "%s: added %u credits total=%d\n", __func__, add, scredits); 182 182 } ··· 203 203 in_flight = server->in_flight; 204 204 spin_unlock(&server->req_lock); 205 205 206 - trace_smb3_set_credits(server->CurrentMid, 206 + trace_smb3_set_credits(server->current_mid, 207 207 server->conn_id, server->hostname, scredits, val, in_flight); 208 208 cifs_dbg(FYI, "%s: set %u credits\n", __func__, val); 209 209 ··· 288 288 in_flight = server->in_flight; 289 289 spin_unlock(&server->req_lock); 290 290 291 - trace_smb3_wait_credits(server->CurrentMid, 291 + trace_smb3_wait_credits(server->current_mid, 292 292 server->conn_id, server->hostname, scredits, -(credits->value), in_flight); 293 293 cifs_dbg(FYI, "%s: removed %u credits total=%d\n", 294 294 __func__, credits->value, scredits); ··· 316 316 server->credits, server->in_flight, 317 317 new_val - credits->value, 318 318 cifs_trace_rw_credits_no_adjust_up); 319 - trace_smb3_too_many_credits(server->CurrentMid, 319 + trace_smb3_too_many_credits(server->current_mid, 320 320 server->conn_id, server->hostname, 0, credits->value - new_val, 0); 321 321 cifs_server_dbg(VFS, "R=%x[%x] request has less credits (%d) than required (%d)", 322 322 subreq->rreq->debug_id, subreq->subreq.debug_index, ··· 338 338 server->credits, server->in_flight, 339 339 new_val - credits->value, 340 340 cifs_trace_rw_credits_old_session); 341 - trace_smb3_reconnect_detected(server->CurrentMid, 341 + trace_smb3_reconnect_detected(server->current_mid, 342 342 server->conn_id, server->hostname, scredits, 343 343 credits->value - new_val, in_flight); 344 344 cifs_server_dbg(VFS, "R=%x[%x] trying to return %d credits to old session\n", ··· 358 358 spin_unlock(&server->req_lock); 359 359 wake_up(&server->request_q); 360 360 361 - trace_smb3_adj_credits(server->CurrentMid, 361 + trace_smb3_adj_credits(server->current_mid, 362 362 server->conn_id, server->hostname, scredits, 363 363 credits->value - new_val, in_flight); 364 364 cifs_dbg(FYI, "%s: adjust added %u credits total=%d\n", ··· 374 374 { 375 375 __u64 mid; 376 376 /* for SMB2 we need the current value */ 377 - spin_lock(&server->mid_lock); 378 - mid = server->CurrentMid++; 379 - spin_unlock(&server->mid_lock); 377 + spin_lock(&server->mid_counter_lock); 378 + mid = server->current_mid++; 379 + spin_unlock(&server->mid_counter_lock); 380 380 return mid; 381 381 } 382 382 383 383 static void 384 384 smb2_revert_current_mid(struct TCP_Server_Info *server, const unsigned int val) 385 385 { 386 - spin_lock(&server->mid_lock); 387 - if (server->CurrentMid >= val) 388 - server->CurrentMid -= val; 389 - spin_unlock(&server->mid_lock); 386 + spin_lock(&server->mid_counter_lock); 387 + if (server->current_mid >= val) 388 + server->current_mid -= val; 389 + spin_unlock(&server->mid_counter_lock); 390 390 } 391 391 392 392 static struct mid_q_entry * ··· 401 401 return NULL; 402 402 } 403 403 404 - spin_lock(&server->mid_lock); 404 + spin_lock(&server->mid_queue_lock); 405 405 list_for_each_entry(mid, &server->pending_mid_q, qhead) { 406 406 if ((mid->mid == wire_mid) && 407 407 (mid->mid_state == MID_REQUEST_SUBMITTED) && ··· 409 409 kref_get(&mid->refcount); 410 410 if (dequeue) { 411 411 list_del_init(&mid->qhead); 412 - mid->mid_flags |= MID_DELETED; 412 + mid->deleted_from_q = true; 413 413 } 414 - spin_unlock(&server->mid_lock); 414 + spin_unlock(&server->mid_queue_lock); 415 415 return mid; 416 416 } 417 417 } 418 - spin_unlock(&server->mid_lock); 418 + spin_unlock(&server->mid_queue_lock); 419 419 return NULL; 420 420 } 421 421 ··· 460 460 { 461 461 int rc; 462 462 463 - spin_lock(&server->mid_lock); 464 - server->CurrentMid = 0; 465 - spin_unlock(&server->mid_lock); 463 + spin_lock(&server->mid_counter_lock); 464 + server->current_mid = 0; 465 + spin_unlock(&server->mid_counter_lock); 466 466 rc = SMB2_negotiate(xid, ses, server); 467 467 return rc; 468 468 } ··· 2498 2498 spin_unlock(&server->req_lock); 2499 2499 wake_up(&server->request_q); 2500 2500 2501 - trace_smb3_pend_credits(server->CurrentMid, 2501 + trace_smb3_pend_credits(server->current_mid, 2502 2502 server->conn_id, server->hostname, scredits, 2503 2503 le16_to_cpu(shdr->CreditRequest), in_flight); 2504 2504 cifs_dbg(FYI, "%s: status pending add %u credits total=%d\n", ··· 4809 4809 } else { 4810 4810 spin_lock(&dw->server->srv_lock); 4811 4811 if (dw->server->tcpStatus == CifsNeedReconnect) { 4812 - spin_lock(&dw->server->mid_lock); 4812 + spin_lock(&dw->server->mid_queue_lock); 4813 4813 mid->mid_state = MID_RETRY_NEEDED; 4814 - spin_unlock(&dw->server->mid_lock); 4814 + spin_unlock(&dw->server->mid_queue_lock); 4815 4815 spin_unlock(&dw->server->srv_lock); 4816 4816 mid->callback(mid); 4817 4817 } else { 4818 - spin_lock(&dw->server->mid_lock); 4818 + spin_lock(&dw->server->mid_queue_lock); 4819 4819 mid->mid_state = MID_REQUEST_SUBMITTED; 4820 - mid->mid_flags &= ~(MID_DELETED); 4820 + mid->deleted_from_q = false; 4821 4821 list_add_tail(&mid->qhead, 4822 4822 &dw->server->pending_mid_q); 4823 - spin_unlock(&dw->server->mid_lock); 4823 + spin_unlock(&dw->server->mid_queue_lock); 4824 4824 spin_unlock(&dw->server->srv_lock); 4825 4825 } 4826 4826 } ··· 5260 5260 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 5261 5261 rc = cifs_sfu_make_node(xid, inode, dentry, tcon, 5262 5262 full_path, mode, dev); 5263 - } else if ((le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS) 5264 - || (tcon->posix_extensions)) { 5263 + } else if (CIFS_REPARSE_SUPPORT(tcon)) { 5265 5264 rc = mknod_reparse(xid, inode, dentry, tcon, 5266 - full_path, mode, dev); 5265 + full_path, mode, dev); 5267 5266 } 5268 5267 return rc; 5269 5268 }
+2 -2
fs/smb/client/smb2transport.c
··· 840 840 *mid = smb2_mid_entry_alloc(shdr, server); 841 841 if (*mid == NULL) 842 842 return -ENOMEM; 843 - spin_lock(&server->mid_lock); 843 + spin_lock(&server->mid_queue_lock); 844 844 list_add_tail(&(*mid)->qhead, &server->pending_mid_q); 845 - spin_unlock(&server->mid_lock); 845 + spin_unlock(&server->mid_queue_lock); 846 846 847 847 return 0; 848 848 }
+222 -243
fs/smb/client/smbdirect.c
··· 13 13 #include "cifsproto.h" 14 14 #include "smb2proto.h" 15 15 16 - static struct smbd_response *get_empty_queue_buffer( 17 - struct smbd_connection *info); 18 - static struct smbd_response *get_receive_buffer( 16 + static struct smbdirect_recv_io *get_receive_buffer( 19 17 struct smbd_connection *info); 20 18 static void put_receive_buffer( 21 19 struct smbd_connection *info, 22 - struct smbd_response *response); 20 + struct smbdirect_recv_io *response); 23 21 static int allocate_receive_buffers(struct smbd_connection *info, int num_buf); 24 22 static void destroy_receive_buffers(struct smbd_connection *info); 25 23 26 - static void put_empty_packet( 27 - struct smbd_connection *info, struct smbd_response *response); 28 24 static void enqueue_reassembly( 29 25 struct smbd_connection *info, 30 - struct smbd_response *response, int data_length); 31 - static struct smbd_response *_get_first_reassembly( 26 + struct smbdirect_recv_io *response, int data_length); 27 + static struct smbdirect_recv_io *_get_first_reassembly( 32 28 struct smbd_connection *info); 33 29 34 30 static int smbd_post_recv( 35 31 struct smbd_connection *info, 36 - struct smbd_response *response); 32 + struct smbdirect_recv_io *response); 37 33 38 34 static int smbd_post_send_empty(struct smbd_connection *info); 39 35 ··· 178 182 { 179 183 struct smbd_connection *info = id->context; 180 184 struct smbdirect_socket *sc = &info->socket; 185 + const char *event_name = rdma_event_msg(event->event); 181 186 182 - log_rdma_event(INFO, "event=%d status=%d\n", 183 - event->event, event->status); 187 + log_rdma_event(INFO, "event=%s status=%d\n", 188 + event_name, event->status); 184 189 185 190 switch (event->event) { 186 191 case RDMA_CM_EVENT_ADDR_RESOLVED: ··· 191 194 break; 192 195 193 196 case RDMA_CM_EVENT_ADDR_ERROR: 197 + log_rdma_event(ERR, "connecting failed event=%s\n", event_name); 194 198 info->ri_rc = -EHOSTUNREACH; 195 199 complete(&info->ri_done); 196 200 break; 197 201 198 202 case RDMA_CM_EVENT_ROUTE_ERROR: 203 + log_rdma_event(ERR, "connecting failed event=%s\n", event_name); 199 204 info->ri_rc = -ENETUNREACH; 200 205 complete(&info->ri_done); 201 206 break; 202 207 203 208 case RDMA_CM_EVENT_ESTABLISHED: 204 - log_rdma_event(INFO, "connected event=%d\n", event->event); 209 + log_rdma_event(INFO, "connected event=%s\n", event_name); 205 210 sc->status = SMBDIRECT_SOCKET_CONNECTED; 206 - wake_up_interruptible(&info->conn_wait); 211 + wake_up_interruptible(&info->status_wait); 207 212 break; 208 213 209 214 case RDMA_CM_EVENT_CONNECT_ERROR: 210 215 case RDMA_CM_EVENT_UNREACHABLE: 211 216 case RDMA_CM_EVENT_REJECTED: 212 - log_rdma_event(INFO, "connecting failed event=%d\n", event->event); 217 + log_rdma_event(ERR, "connecting failed event=%s\n", event_name); 213 218 sc->status = SMBDIRECT_SOCKET_DISCONNECTED; 214 - wake_up_interruptible(&info->conn_wait); 219 + wake_up_interruptible(&info->status_wait); 215 220 break; 216 221 217 222 case RDMA_CM_EVENT_DEVICE_REMOVAL: 218 223 case RDMA_CM_EVENT_DISCONNECTED: 219 224 /* This happens when we fail the negotiation */ 220 225 if (sc->status == SMBDIRECT_SOCKET_NEGOTIATE_FAILED) { 226 + log_rdma_event(ERR, "event=%s during negotiation\n", event_name); 221 227 sc->status = SMBDIRECT_SOCKET_DISCONNECTED; 222 - wake_up(&info->conn_wait); 228 + wake_up(&info->status_wait); 223 229 break; 224 230 } 225 231 226 232 sc->status = SMBDIRECT_SOCKET_DISCONNECTED; 227 - wake_up_interruptible(&info->disconn_wait); 228 - wake_up_interruptible(&info->wait_reassembly_queue); 233 + wake_up_interruptible(&info->status_wait); 234 + wake_up_interruptible(&sc->recv_io.reassembly.wait_queue); 229 235 wake_up_interruptible_all(&info->wait_send_queue); 230 236 break; 231 237 232 238 default: 239 + log_rdma_event(ERR, "unexpected event=%s status=%d\n", 240 + event_name, event->status); 233 241 break; 234 242 } 235 243 ··· 261 259 } 262 260 } 263 261 264 - static inline void *smbd_request_payload(struct smbd_request *request) 262 + static inline void *smbdirect_send_io_payload(struct smbdirect_send_io *request) 265 263 { 266 264 return (void *)request->packet; 267 265 } 268 266 269 - static inline void *smbd_response_payload(struct smbd_response *response) 267 + static inline void *smbdirect_recv_io_payload(struct smbdirect_recv_io *response) 270 268 { 271 269 return (void *)response->packet; 272 270 } ··· 275 273 static void send_done(struct ib_cq *cq, struct ib_wc *wc) 276 274 { 277 275 int i; 278 - struct smbd_request *request = 279 - container_of(wc->wr_cqe, struct smbd_request, cqe); 280 - struct smbd_connection *info = request->info; 281 - struct smbdirect_socket *sc = &info->socket; 276 + struct smbdirect_send_io *request = 277 + container_of(wc->wr_cqe, struct smbdirect_send_io, cqe); 278 + struct smbdirect_socket *sc = request->socket; 279 + struct smbd_connection *info = 280 + container_of(sc, struct smbd_connection, socket); 282 281 283 - log_rdma_send(INFO, "smbd_request 0x%p completed wc->status=%d\n", 282 + log_rdma_send(INFO, "smbdirect_send_io 0x%p completed wc->status=%d\n", 284 283 request, wc->status); 285 - 286 - if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) { 287 - log_rdma_send(ERR, "wc->status=%d wc->opcode=%d\n", 288 - wc->status, wc->opcode); 289 - smbd_disconnect_rdma_connection(request->info); 290 - } 291 284 292 285 for (i = 0; i < request->num_sge; i++) 293 286 ib_dma_unmap_single(sc->ib.dev, ··· 290 293 request->sge[i].length, 291 294 DMA_TO_DEVICE); 292 295 293 - if (atomic_dec_and_test(&request->info->send_pending)) 294 - wake_up(&request->info->wait_send_pending); 296 + if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) { 297 + log_rdma_send(ERR, "wc->status=%d wc->opcode=%d\n", 298 + wc->status, wc->opcode); 299 + mempool_free(request, sc->send_io.mem.pool); 300 + smbd_disconnect_rdma_connection(info); 301 + return; 302 + } 295 303 296 - wake_up(&request->info->wait_post_send); 304 + if (atomic_dec_and_test(&info->send_pending)) 305 + wake_up(&info->wait_send_pending); 297 306 298 - mempool_free(request, request->info->request_mempool); 307 + wake_up(&info->wait_post_send); 308 + 309 + mempool_free(request, sc->send_io.mem.pool); 299 310 } 300 311 301 312 static void dump_smbdirect_negotiate_resp(struct smbdirect_negotiate_resp *resp) ··· 322 317 * return value: true if negotiation is a success, false if failed 323 318 */ 324 319 static bool process_negotiation_response( 325 - struct smbd_response *response, int packet_length) 320 + struct smbdirect_recv_io *response, int packet_length) 326 321 { 327 - struct smbd_connection *info = response->info; 328 - struct smbdirect_socket *sc = &info->socket; 322 + struct smbdirect_socket *sc = response->socket; 323 + struct smbd_connection *info = 324 + container_of(sc, struct smbd_connection, socket); 329 325 struct smbdirect_socket_parameters *sp = &sc->parameters; 330 - struct smbdirect_negotiate_resp *packet = smbd_response_payload(response); 326 + struct smbdirect_negotiate_resp *packet = smbdirect_recv_io_payload(response); 331 327 332 328 if (packet_length < sizeof(struct smbdirect_negotiate_resp)) { 333 329 log_rdma_event(ERR, ··· 391 385 info->max_frmr_depth * PAGE_SIZE); 392 386 info->max_frmr_depth = sp->max_read_write_size / PAGE_SIZE; 393 387 388 + sc->recv_io.expected = SMBDIRECT_EXPECT_DATA_TRANSFER; 394 389 return true; 395 390 } 396 391 397 392 static void smbd_post_send_credits(struct work_struct *work) 398 393 { 399 394 int ret = 0; 400 - int use_receive_queue = 1; 401 395 int rc; 402 - struct smbd_response *response; 396 + struct smbdirect_recv_io *response; 403 397 struct smbd_connection *info = 404 398 container_of(work, struct smbd_connection, 405 399 post_send_credits_work); ··· 413 407 if (info->receive_credit_target > 414 408 atomic_read(&info->receive_credits)) { 415 409 while (true) { 416 - if (use_receive_queue) 417 - response = get_receive_buffer(info); 418 - else 419 - response = get_empty_queue_buffer(info); 420 - if (!response) { 421 - /* now switch to empty packet queue */ 422 - if (use_receive_queue) { 423 - use_receive_queue = 0; 424 - continue; 425 - } else 426 - break; 427 - } 410 + response = get_receive_buffer(info); 411 + if (!response) 412 + break; 428 413 429 - response->type = SMBD_TRANSFER_DATA; 430 414 response->first_segment = false; 431 415 rc = smbd_post_recv(info, response); 432 416 if (rc) { ··· 450 454 static void recv_done(struct ib_cq *cq, struct ib_wc *wc) 451 455 { 452 456 struct smbdirect_data_transfer *data_transfer; 453 - struct smbd_response *response = 454 - container_of(wc->wr_cqe, struct smbd_response, cqe); 455 - struct smbd_connection *info = response->info; 457 + struct smbdirect_recv_io *response = 458 + container_of(wc->wr_cqe, struct smbdirect_recv_io, cqe); 459 + struct smbdirect_socket *sc = response->socket; 460 + struct smbd_connection *info = 461 + container_of(sc, struct smbd_connection, socket); 456 462 int data_length = 0; 457 463 458 464 log_rdma_recv(INFO, "response=0x%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%u\n", 459 - response, response->type, wc->status, wc->opcode, 465 + response, sc->recv_io.expected, wc->status, wc->opcode, 460 466 wc->byte_len, wc->pkey_index); 461 467 462 468 if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) { 463 469 log_rdma_recv(INFO, "wc->status=%d opcode=%d\n", 464 470 wc->status, wc->opcode); 465 - smbd_disconnect_rdma_connection(info); 466 471 goto error; 467 472 } 468 473 ··· 473 476 response->sge.length, 474 477 DMA_FROM_DEVICE); 475 478 476 - switch (response->type) { 479 + switch (sc->recv_io.expected) { 477 480 /* SMBD negotiation response */ 478 - case SMBD_NEGOTIATE_RESP: 479 - dump_smbdirect_negotiate_resp(smbd_response_payload(response)); 480 - info->full_packet_received = true; 481 + case SMBDIRECT_EXPECT_NEGOTIATE_REP: 482 + dump_smbdirect_negotiate_resp(smbdirect_recv_io_payload(response)); 483 + sc->recv_io.reassembly.full_packet_received = true; 481 484 info->negotiate_done = 482 485 process_negotiation_response(response, wc->byte_len); 486 + put_receive_buffer(info, response); 483 487 complete(&info->negotiate_completion); 484 - break; 488 + return; 485 489 486 490 /* SMBD data transfer packet */ 487 - case SMBD_TRANSFER_DATA: 488 - data_transfer = smbd_response_payload(response); 491 + case SMBDIRECT_EXPECT_DATA_TRANSFER: 492 + data_transfer = smbdirect_recv_io_payload(response); 489 493 data_length = le32_to_cpu(data_transfer->data_length); 490 494 491 - /* 492 - * If this is a packet with data playload place the data in 493 - * reassembly queue and wake up the reading thread 494 - */ 495 495 if (data_length) { 496 - if (info->full_packet_received) 496 + if (sc->recv_io.reassembly.full_packet_received) 497 497 response->first_segment = true; 498 498 499 499 if (le32_to_cpu(data_transfer->remaining_data_length)) 500 - info->full_packet_received = false; 500 + sc->recv_io.reassembly.full_packet_received = false; 501 501 else 502 - info->full_packet_received = true; 503 - 504 - enqueue_reassembly( 505 - info, 506 - response, 507 - data_length); 508 - } else 509 - put_empty_packet(info, response); 510 - 511 - if (data_length) 512 - wake_up_interruptible(&info->wait_reassembly_queue); 502 + sc->recv_io.reassembly.full_packet_received = true; 503 + } 513 504 514 505 atomic_dec(&info->receive_credits); 515 506 info->receive_credit_target = ··· 525 540 info->keep_alive_requested = KEEP_ALIVE_PENDING; 526 541 } 527 542 543 + /* 544 + * If this is a packet with data playload place the data in 545 + * reassembly queue and wake up the reading thread 546 + */ 547 + if (data_length) { 548 + enqueue_reassembly(info, response, data_length); 549 + wake_up_interruptible(&sc->recv_io.reassembly.wait_queue); 550 + } else 551 + put_receive_buffer(info, response); 552 + 528 553 return; 529 554 530 - default: 531 - log_rdma_recv(ERR, 532 - "unexpected response type=%d\n", response->type); 555 + case SMBDIRECT_EXPECT_NEGOTIATE_REQ: 556 + /* Only server... */ 557 + break; 533 558 } 534 559 560 + /* 561 + * This is an internal error! 562 + */ 563 + log_rdma_recv(ERR, "unexpected response type=%d\n", sc->recv_io.expected); 564 + WARN_ON_ONCE(sc->recv_io.expected != SMBDIRECT_EXPECT_DATA_TRANSFER); 535 565 error: 536 566 put_receive_buffer(info, response); 567 + smbd_disconnect_rdma_connection(info); 537 568 } 538 569 539 570 static struct rdma_cm_id *smbd_create_id( ··· 695 694 struct smbdirect_socket_parameters *sp = &sc->parameters; 696 695 struct ib_send_wr send_wr; 697 696 int rc = -ENOMEM; 698 - struct smbd_request *request; 697 + struct smbdirect_send_io *request; 699 698 struct smbdirect_negotiate_req *packet; 700 699 701 - request = mempool_alloc(info->request_mempool, GFP_KERNEL); 700 + request = mempool_alloc(sc->send_io.mem.pool, GFP_KERNEL); 702 701 if (!request) 703 702 return rc; 704 703 705 - request->info = info; 704 + request->socket = sc; 706 705 707 - packet = smbd_request_payload(request); 706 + packet = smbdirect_send_io_payload(request); 708 707 packet->min_version = cpu_to_le16(SMBDIRECT_V1); 709 708 packet->max_version = cpu_to_le16(SMBDIRECT_V1); 710 709 packet->reserved = 0; ··· 757 756 smbd_disconnect_rdma_connection(info); 758 757 759 758 dma_mapping_failed: 760 - mempool_free(request, info->request_mempool); 759 + mempool_free(request, sc->send_io.mem.pool); 761 760 return rc; 762 761 } 763 762 ··· 801 800 802 801 /* Post the send request */ 803 802 static int smbd_post_send(struct smbd_connection *info, 804 - struct smbd_request *request) 803 + struct smbdirect_send_io *request) 805 804 { 806 805 struct smbdirect_socket *sc = &info->socket; 807 806 struct smbdirect_socket_parameters *sp = &sc->parameters; ··· 850 849 int i, rc; 851 850 int header_length; 852 851 int data_length; 853 - struct smbd_request *request; 852 + struct smbdirect_send_io *request; 854 853 struct smbdirect_data_transfer *packet; 855 854 int new_credits = 0; 856 855 ··· 889 888 goto wait_send_queue; 890 889 } 891 890 892 - request = mempool_alloc(info->request_mempool, GFP_KERNEL); 891 + request = mempool_alloc(sc->send_io.mem.pool, GFP_KERNEL); 893 892 if (!request) { 894 893 rc = -ENOMEM; 895 894 goto err_alloc; 896 895 } 897 896 898 - request->info = info; 897 + request->socket = sc; 899 898 memset(request->sge, 0, sizeof(request->sge)); 900 899 901 900 /* Fill in the data payload to find out how much data we can add */ 902 901 if (iter) { 903 902 struct smb_extract_to_rdma extract = { 904 903 .nr_sge = 1, 905 - .max_sge = SMBDIRECT_MAX_SEND_SGE, 904 + .max_sge = SMBDIRECT_SEND_IO_MAX_SGE, 906 905 .sge = request->sge, 907 906 .device = sc->ib.dev, 908 907 .local_dma_lkey = sc->ib.pd->local_dma_lkey, ··· 924 923 } 925 924 926 925 /* Fill in the packet header */ 927 - packet = smbd_request_payload(request); 926 + packet = smbdirect_send_io_payload(request); 928 927 packet->credits_requested = cpu_to_le16(sp->send_credit_target); 929 928 930 929 new_credits = manage_credits_prior_sending(info); ··· 983 982 request->sge[i].addr, 984 983 request->sge[i].length, 985 984 DMA_TO_DEVICE); 986 - mempool_free(request, info->request_mempool); 985 + mempool_free(request, sc->send_io.mem.pool); 987 986 988 987 /* roll back receive credits and credits to be offered */ 989 988 spin_lock(&info->lock_new_credits_offered); ··· 1043 1042 * The interaction is controlled by send/receive credit system 1044 1043 */ 1045 1044 static int smbd_post_recv( 1046 - struct smbd_connection *info, struct smbd_response *response) 1045 + struct smbd_connection *info, struct smbdirect_recv_io *response) 1047 1046 { 1048 1047 struct smbdirect_socket *sc = &info->socket; 1049 1048 struct smbdirect_socket_parameters *sp = &sc->parameters; ··· 1070 1069 if (rc) { 1071 1070 ib_dma_unmap_single(sc->ib.dev, response->sge.addr, 1072 1071 response->sge.length, DMA_FROM_DEVICE); 1072 + response->sge.length = 0; 1073 1073 smbd_disconnect_rdma_connection(info); 1074 1074 log_rdma_recv(ERR, "ib_post_recv failed rc=%d\n", rc); 1075 1075 } ··· 1081 1079 /* Perform SMBD negotiate according to [MS-SMBD] 3.1.5.2 */ 1082 1080 static int smbd_negotiate(struct smbd_connection *info) 1083 1081 { 1082 + struct smbdirect_socket *sc = &info->socket; 1084 1083 int rc; 1085 - struct smbd_response *response = get_receive_buffer(info); 1084 + struct smbdirect_recv_io *response = get_receive_buffer(info); 1086 1085 1087 - response->type = SMBD_NEGOTIATE_RESP; 1086 + sc->recv_io.expected = SMBDIRECT_EXPECT_NEGOTIATE_REP; 1088 1087 rc = smbd_post_recv(info, response); 1089 1088 log_rdma_event(INFO, "smbd_post_recv rc=%d iov.addr=0x%llx iov.length=%u iov.lkey=0x%x\n", 1090 1089 rc, response->sge.addr, ··· 1116 1113 return rc; 1117 1114 } 1118 1115 1119 - static void put_empty_packet( 1120 - struct smbd_connection *info, struct smbd_response *response) 1121 - { 1122 - spin_lock(&info->empty_packet_queue_lock); 1123 - list_add_tail(&response->list, &info->empty_packet_queue); 1124 - info->count_empty_packet_queue++; 1125 - spin_unlock(&info->empty_packet_queue_lock); 1126 - 1127 - queue_work(info->workqueue, &info->post_send_credits_work); 1128 - } 1129 - 1130 1116 /* 1131 1117 * Implement Connection.FragmentReassemblyBuffer defined in [MS-SMBD] 3.1.1.1 1132 1118 * This is a queue for reassembling upper layer payload and present to upper ··· 1128 1136 */ 1129 1137 static void enqueue_reassembly( 1130 1138 struct smbd_connection *info, 1131 - struct smbd_response *response, 1139 + struct smbdirect_recv_io *response, 1132 1140 int data_length) 1133 1141 { 1134 - spin_lock(&info->reassembly_queue_lock); 1135 - list_add_tail(&response->list, &info->reassembly_queue); 1136 - info->reassembly_queue_length++; 1142 + struct smbdirect_socket *sc = &info->socket; 1143 + 1144 + spin_lock(&sc->recv_io.reassembly.lock); 1145 + list_add_tail(&response->list, &sc->recv_io.reassembly.list); 1146 + sc->recv_io.reassembly.queue_length++; 1137 1147 /* 1138 1148 * Make sure reassembly_data_length is updated after list and 1139 1149 * reassembly_queue_length are updated. On the dequeue side ··· 1143 1149 * if reassembly_queue_length and list is up to date 1144 1150 */ 1145 1151 virt_wmb(); 1146 - info->reassembly_data_length += data_length; 1147 - spin_unlock(&info->reassembly_queue_lock); 1152 + sc->recv_io.reassembly.data_length += data_length; 1153 + spin_unlock(&sc->recv_io.reassembly.lock); 1148 1154 info->count_reassembly_queue++; 1149 1155 info->count_enqueue_reassembly_queue++; 1150 1156 } ··· 1154 1160 * Caller is responsible for locking 1155 1161 * return value: the first entry if any, NULL if queue is empty 1156 1162 */ 1157 - static struct smbd_response *_get_first_reassembly(struct smbd_connection *info) 1163 + static struct smbdirect_recv_io *_get_first_reassembly(struct smbd_connection *info) 1158 1164 { 1159 - struct smbd_response *ret = NULL; 1165 + struct smbdirect_socket *sc = &info->socket; 1166 + struct smbdirect_recv_io *ret = NULL; 1160 1167 1161 - if (!list_empty(&info->reassembly_queue)) { 1168 + if (!list_empty(&sc->recv_io.reassembly.list)) { 1162 1169 ret = list_first_entry( 1163 - &info->reassembly_queue, 1164 - struct smbd_response, list); 1170 + &sc->recv_io.reassembly.list, 1171 + struct smbdirect_recv_io, list); 1165 1172 } 1166 - return ret; 1167 - } 1168 - 1169 - static struct smbd_response *get_empty_queue_buffer( 1170 - struct smbd_connection *info) 1171 - { 1172 - struct smbd_response *ret = NULL; 1173 - unsigned long flags; 1174 - 1175 - spin_lock_irqsave(&info->empty_packet_queue_lock, flags); 1176 - if (!list_empty(&info->empty_packet_queue)) { 1177 - ret = list_first_entry( 1178 - &info->empty_packet_queue, 1179 - struct smbd_response, list); 1180 - list_del(&ret->list); 1181 - info->count_empty_packet_queue--; 1182 - } 1183 - spin_unlock_irqrestore(&info->empty_packet_queue_lock, flags); 1184 - 1185 1173 return ret; 1186 1174 } 1187 1175 ··· 1173 1197 * pre-allocated in advance. 1174 1198 * return value: the receive buffer, NULL if none is available 1175 1199 */ 1176 - static struct smbd_response *get_receive_buffer(struct smbd_connection *info) 1200 + static struct smbdirect_recv_io *get_receive_buffer(struct smbd_connection *info) 1177 1201 { 1178 - struct smbd_response *ret = NULL; 1202 + struct smbdirect_socket *sc = &info->socket; 1203 + struct smbdirect_recv_io *ret = NULL; 1179 1204 unsigned long flags; 1180 1205 1181 - spin_lock_irqsave(&info->receive_queue_lock, flags); 1182 - if (!list_empty(&info->receive_queue)) { 1206 + spin_lock_irqsave(&sc->recv_io.free.lock, flags); 1207 + if (!list_empty(&sc->recv_io.free.list)) { 1183 1208 ret = list_first_entry( 1184 - &info->receive_queue, 1185 - struct smbd_response, list); 1209 + &sc->recv_io.free.list, 1210 + struct smbdirect_recv_io, list); 1186 1211 list_del(&ret->list); 1187 1212 info->count_receive_queue--; 1188 1213 info->count_get_receive_buffer++; 1189 1214 } 1190 - spin_unlock_irqrestore(&info->receive_queue_lock, flags); 1215 + spin_unlock_irqrestore(&sc->recv_io.free.lock, flags); 1191 1216 1192 1217 return ret; 1193 1218 } ··· 1200 1223 * receive buffer is returned. 1201 1224 */ 1202 1225 static void put_receive_buffer( 1203 - struct smbd_connection *info, struct smbd_response *response) 1226 + struct smbd_connection *info, struct smbdirect_recv_io *response) 1204 1227 { 1205 1228 struct smbdirect_socket *sc = &info->socket; 1206 1229 unsigned long flags; 1207 1230 1208 - ib_dma_unmap_single(sc->ib.dev, response->sge.addr, 1209 - response->sge.length, DMA_FROM_DEVICE); 1231 + if (likely(response->sge.length != 0)) { 1232 + ib_dma_unmap_single(sc->ib.dev, 1233 + response->sge.addr, 1234 + response->sge.length, 1235 + DMA_FROM_DEVICE); 1236 + response->sge.length = 0; 1237 + } 1210 1238 1211 - spin_lock_irqsave(&info->receive_queue_lock, flags); 1212 - list_add_tail(&response->list, &info->receive_queue); 1239 + spin_lock_irqsave(&sc->recv_io.free.lock, flags); 1240 + list_add_tail(&response->list, &sc->recv_io.free.list); 1213 1241 info->count_receive_queue++; 1214 1242 info->count_put_receive_buffer++; 1215 - spin_unlock_irqrestore(&info->receive_queue_lock, flags); 1243 + spin_unlock_irqrestore(&sc->recv_io.free.lock, flags); 1216 1244 1217 1245 queue_work(info->workqueue, &info->post_send_credits_work); 1218 1246 } ··· 1225 1243 /* Preallocate all receive buffer on transport establishment */ 1226 1244 static int allocate_receive_buffers(struct smbd_connection *info, int num_buf) 1227 1245 { 1246 + struct smbdirect_socket *sc = &info->socket; 1247 + struct smbdirect_recv_io *response; 1228 1248 int i; 1229 - struct smbd_response *response; 1230 1249 1231 - INIT_LIST_HEAD(&info->reassembly_queue); 1232 - spin_lock_init(&info->reassembly_queue_lock); 1233 - info->reassembly_data_length = 0; 1234 - info->reassembly_queue_length = 0; 1250 + INIT_LIST_HEAD(&sc->recv_io.reassembly.list); 1251 + spin_lock_init(&sc->recv_io.reassembly.lock); 1252 + sc->recv_io.reassembly.data_length = 0; 1253 + sc->recv_io.reassembly.queue_length = 0; 1235 1254 1236 - INIT_LIST_HEAD(&info->receive_queue); 1237 - spin_lock_init(&info->receive_queue_lock); 1255 + INIT_LIST_HEAD(&sc->recv_io.free.list); 1256 + spin_lock_init(&sc->recv_io.free.lock); 1238 1257 info->count_receive_queue = 0; 1239 - 1240 - INIT_LIST_HEAD(&info->empty_packet_queue); 1241 - spin_lock_init(&info->empty_packet_queue_lock); 1242 - info->count_empty_packet_queue = 0; 1243 1258 1244 1259 init_waitqueue_head(&info->wait_receive_queues); 1245 1260 1246 1261 for (i = 0; i < num_buf; i++) { 1247 - response = mempool_alloc(info->response_mempool, GFP_KERNEL); 1262 + response = mempool_alloc(sc->recv_io.mem.pool, GFP_KERNEL); 1248 1263 if (!response) 1249 1264 goto allocate_failed; 1250 1265 1251 - response->info = info; 1252 - list_add_tail(&response->list, &info->receive_queue); 1266 + response->socket = sc; 1267 + response->sge.length = 0; 1268 + list_add_tail(&response->list, &sc->recv_io.free.list); 1253 1269 info->count_receive_queue++; 1254 1270 } 1255 1271 1256 1272 return 0; 1257 1273 1258 1274 allocate_failed: 1259 - while (!list_empty(&info->receive_queue)) { 1275 + while (!list_empty(&sc->recv_io.free.list)) { 1260 1276 response = list_first_entry( 1261 - &info->receive_queue, 1262 - struct smbd_response, list); 1277 + &sc->recv_io.free.list, 1278 + struct smbdirect_recv_io, list); 1263 1279 list_del(&response->list); 1264 1280 info->count_receive_queue--; 1265 1281 1266 - mempool_free(response, info->response_mempool); 1282 + mempool_free(response, sc->recv_io.mem.pool); 1267 1283 } 1268 1284 return -ENOMEM; 1269 1285 } 1270 1286 1271 1287 static void destroy_receive_buffers(struct smbd_connection *info) 1272 1288 { 1273 - struct smbd_response *response; 1289 + struct smbdirect_socket *sc = &info->socket; 1290 + struct smbdirect_recv_io *response; 1274 1291 1275 1292 while ((response = get_receive_buffer(info))) 1276 - mempool_free(response, info->response_mempool); 1277 - 1278 - while ((response = get_empty_queue_buffer(info))) 1279 - mempool_free(response, info->response_mempool); 1293 + mempool_free(response, sc->recv_io.mem.pool); 1280 1294 } 1281 1295 1282 1296 /* Implement idle connection timer [MS-SMBD] 3.1.6.2 */ ··· 1310 1332 struct smbd_connection *info = server->smbd_conn; 1311 1333 struct smbdirect_socket *sc; 1312 1334 struct smbdirect_socket_parameters *sp; 1313 - struct smbd_response *response; 1335 + struct smbdirect_recv_io *response; 1314 1336 unsigned long flags; 1315 1337 1316 1338 if (!info) { ··· 1325 1347 rdma_disconnect(sc->rdma.cm_id); 1326 1348 log_rdma_event(INFO, "wait for transport being disconnected\n"); 1327 1349 wait_event_interruptible( 1328 - info->disconn_wait, 1350 + info->status_wait, 1329 1351 sc->status == SMBDIRECT_SOCKET_DISCONNECTED); 1330 1352 } 1331 1353 ··· 1344 1366 /* It's not possible for upper layer to get to reassembly */ 1345 1367 log_rdma_event(INFO, "drain the reassembly queue\n"); 1346 1368 do { 1347 - spin_lock_irqsave(&info->reassembly_queue_lock, flags); 1369 + spin_lock_irqsave(&sc->recv_io.reassembly.lock, flags); 1348 1370 response = _get_first_reassembly(info); 1349 1371 if (response) { 1350 1372 list_del(&response->list); 1351 1373 spin_unlock_irqrestore( 1352 - &info->reassembly_queue_lock, flags); 1374 + &sc->recv_io.reassembly.lock, flags); 1353 1375 put_receive_buffer(info, response); 1354 1376 } else 1355 1377 spin_unlock_irqrestore( 1356 - &info->reassembly_queue_lock, flags); 1378 + &sc->recv_io.reassembly.lock, flags); 1357 1379 } while (response); 1358 - info->reassembly_data_length = 0; 1380 + sc->recv_io.reassembly.data_length = 0; 1359 1381 1360 1382 log_rdma_event(INFO, "free receive buffers\n"); 1361 1383 wait_event(info->wait_receive_queues, 1362 - info->count_receive_queue + info->count_empty_packet_queue 1363 - == sp->recv_credit_max); 1384 + info->count_receive_queue == sp->recv_credit_max); 1364 1385 destroy_receive_buffers(info); 1365 1386 1366 1387 /* ··· 1384 1407 rdma_destroy_id(sc->rdma.cm_id); 1385 1408 1386 1409 /* free mempools */ 1387 - mempool_destroy(info->request_mempool); 1388 - kmem_cache_destroy(info->request_cache); 1410 + mempool_destroy(sc->send_io.mem.pool); 1411 + kmem_cache_destroy(sc->send_io.mem.cache); 1389 1412 1390 - mempool_destroy(info->response_mempool); 1391 - kmem_cache_destroy(info->response_cache); 1413 + mempool_destroy(sc->recv_io.mem.pool); 1414 + kmem_cache_destroy(sc->recv_io.mem.cache); 1392 1415 1393 1416 sc->status = SMBDIRECT_SOCKET_DESTROYED; 1394 1417 ··· 1436 1459 1437 1460 static void destroy_caches_and_workqueue(struct smbd_connection *info) 1438 1461 { 1462 + struct smbdirect_socket *sc = &info->socket; 1463 + 1439 1464 destroy_receive_buffers(info); 1440 1465 destroy_workqueue(info->workqueue); 1441 - mempool_destroy(info->response_mempool); 1442 - kmem_cache_destroy(info->response_cache); 1443 - mempool_destroy(info->request_mempool); 1444 - kmem_cache_destroy(info->request_cache); 1466 + mempool_destroy(sc->recv_io.mem.pool); 1467 + kmem_cache_destroy(sc->recv_io.mem.cache); 1468 + mempool_destroy(sc->send_io.mem.pool); 1469 + kmem_cache_destroy(sc->send_io.mem.cache); 1445 1470 } 1446 1471 1447 1472 #define MAX_NAME_LEN 80 ··· 1457 1478 if (WARN_ON_ONCE(sp->max_recv_size < sizeof(struct smbdirect_data_transfer))) 1458 1479 return -ENOMEM; 1459 1480 1460 - scnprintf(name, MAX_NAME_LEN, "smbd_request_%p", info); 1461 - info->request_cache = 1481 + scnprintf(name, MAX_NAME_LEN, "smbdirect_send_io_%p", info); 1482 + sc->send_io.mem.cache = 1462 1483 kmem_cache_create( 1463 1484 name, 1464 - sizeof(struct smbd_request) + 1485 + sizeof(struct smbdirect_send_io) + 1465 1486 sizeof(struct smbdirect_data_transfer), 1466 1487 0, SLAB_HWCACHE_ALIGN, NULL); 1467 - if (!info->request_cache) 1488 + if (!sc->send_io.mem.cache) 1468 1489 return -ENOMEM; 1469 1490 1470 - info->request_mempool = 1491 + sc->send_io.mem.pool = 1471 1492 mempool_create(sp->send_credit_target, mempool_alloc_slab, 1472 - mempool_free_slab, info->request_cache); 1473 - if (!info->request_mempool) 1493 + mempool_free_slab, sc->send_io.mem.cache); 1494 + if (!sc->send_io.mem.pool) 1474 1495 goto out1; 1475 1496 1476 - scnprintf(name, MAX_NAME_LEN, "smbd_response_%p", info); 1497 + scnprintf(name, MAX_NAME_LEN, "smbdirect_recv_io_%p", info); 1477 1498 1478 1499 struct kmem_cache_args response_args = { 1479 - .align = __alignof__(struct smbd_response), 1480 - .useroffset = (offsetof(struct smbd_response, packet) + 1500 + .align = __alignof__(struct smbdirect_recv_io), 1501 + .useroffset = (offsetof(struct smbdirect_recv_io, packet) + 1481 1502 sizeof(struct smbdirect_data_transfer)), 1482 1503 .usersize = sp->max_recv_size - sizeof(struct smbdirect_data_transfer), 1483 1504 }; 1484 - info->response_cache = 1505 + sc->recv_io.mem.cache = 1485 1506 kmem_cache_create(name, 1486 - sizeof(struct smbd_response) + sp->max_recv_size, 1507 + sizeof(struct smbdirect_recv_io) + sp->max_recv_size, 1487 1508 &response_args, SLAB_HWCACHE_ALIGN); 1488 - if (!info->response_cache) 1509 + if (!sc->recv_io.mem.cache) 1489 1510 goto out2; 1490 1511 1491 - info->response_mempool = 1512 + sc->recv_io.mem.pool = 1492 1513 mempool_create(sp->recv_credit_max, mempool_alloc_slab, 1493 - mempool_free_slab, info->response_cache); 1494 - if (!info->response_mempool) 1514 + mempool_free_slab, sc->recv_io.mem.cache); 1515 + if (!sc->recv_io.mem.pool) 1495 1516 goto out3; 1496 1517 1497 1518 scnprintf(name, MAX_NAME_LEN, "smbd_%p", info); ··· 1510 1531 out5: 1511 1532 destroy_workqueue(info->workqueue); 1512 1533 out4: 1513 - mempool_destroy(info->response_mempool); 1534 + mempool_destroy(sc->recv_io.mem.pool); 1514 1535 out3: 1515 - kmem_cache_destroy(info->response_cache); 1536 + kmem_cache_destroy(sc->recv_io.mem.cache); 1516 1537 out2: 1517 - mempool_destroy(info->request_mempool); 1538 + mempool_destroy(sc->send_io.mem.pool); 1518 1539 out1: 1519 - kmem_cache_destroy(info->request_cache); 1540 + kmem_cache_destroy(sc->send_io.mem.cache); 1520 1541 return -ENOMEM; 1521 1542 } 1522 1543 ··· 1572 1593 sp->max_recv_size = smbd_max_receive_size; 1573 1594 sp->keepalive_interval_msec = smbd_keep_alive_interval * 1000; 1574 1595 1575 - if (sc->ib.dev->attrs.max_send_sge < SMBDIRECT_MAX_SEND_SGE || 1576 - sc->ib.dev->attrs.max_recv_sge < SMBDIRECT_MAX_RECV_SGE) { 1596 + if (sc->ib.dev->attrs.max_send_sge < SMBDIRECT_SEND_IO_MAX_SGE || 1597 + sc->ib.dev->attrs.max_recv_sge < SMBDIRECT_RECV_IO_MAX_SGE) { 1577 1598 log_rdma_event(ERR, 1578 1599 "device %.*s max_send_sge/max_recv_sge = %d/%d too small\n", 1579 1600 IB_DEVICE_NAME_MAX, ··· 1604 1625 qp_attr.qp_context = info; 1605 1626 qp_attr.cap.max_send_wr = sp->send_credit_target; 1606 1627 qp_attr.cap.max_recv_wr = sp->recv_credit_max; 1607 - qp_attr.cap.max_send_sge = SMBDIRECT_MAX_SEND_SGE; 1608 - qp_attr.cap.max_recv_sge = SMBDIRECT_MAX_RECV_SGE; 1628 + qp_attr.cap.max_send_sge = SMBDIRECT_SEND_IO_MAX_SGE; 1629 + qp_attr.cap.max_recv_sge = SMBDIRECT_RECV_IO_MAX_SGE; 1609 1630 qp_attr.cap.max_inline_data = 0; 1610 1631 qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR; 1611 1632 qp_attr.qp_type = IB_QPT_RC; ··· 1650 1671 log_rdma_event(INFO, "connecting to IP %pI4 port %d\n", 1651 1672 &addr_in->sin_addr, port); 1652 1673 1653 - init_waitqueue_head(&info->conn_wait); 1654 - init_waitqueue_head(&info->disconn_wait); 1655 - init_waitqueue_head(&info->wait_reassembly_queue); 1674 + init_waitqueue_head(&info->status_wait); 1675 + init_waitqueue_head(&sc->recv_io.reassembly.wait_queue); 1656 1676 rc = rdma_connect(sc->rdma.cm_id, &conn_param); 1657 1677 if (rc) { 1658 1678 log_rdma_event(ERR, "rdma_connect() failed with %i\n", rc); 1659 1679 goto rdma_connect_failed; 1660 1680 } 1661 1681 1662 - wait_event_interruptible( 1663 - info->conn_wait, sc->status != SMBDIRECT_SOCKET_CONNECTING); 1682 + wait_event_interruptible_timeout( 1683 + info->status_wait, 1684 + sc->status != SMBDIRECT_SOCKET_CONNECTING, 1685 + msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT)); 1664 1686 1665 1687 if (sc->status != SMBDIRECT_SOCKET_CONNECTED) { 1666 1688 log_rdma_event(ERR, "rdma_connect failed port=%d\n", port); ··· 1715 1735 cancel_delayed_work_sync(&info->idle_timer_work); 1716 1736 destroy_caches_and_workqueue(info); 1717 1737 sc->status = SMBDIRECT_SOCKET_NEGOTIATE_FAILED; 1718 - init_waitqueue_head(&info->conn_wait); 1719 1738 rdma_disconnect(sc->rdma.cm_id); 1720 - wait_event(info->conn_wait, 1739 + wait_event(info->status_wait, 1721 1740 sc->status == SMBDIRECT_SOCKET_DISCONNECTED); 1722 1741 1723 1742 allocate_cache_failed: ··· 1773 1794 int smbd_recv(struct smbd_connection *info, struct msghdr *msg) 1774 1795 { 1775 1796 struct smbdirect_socket *sc = &info->socket; 1776 - struct smbd_response *response; 1797 + struct smbdirect_recv_io *response; 1777 1798 struct smbdirect_data_transfer *data_transfer; 1778 1799 size_t size = iov_iter_count(&msg->msg_iter); 1779 1800 int to_copy, to_read, data_read, offset; ··· 1789 1810 * the only one reading from the front of the queue. The transport 1790 1811 * may add more entries to the back of the queue at the same time 1791 1812 */ 1792 - log_read(INFO, "size=%zd info->reassembly_data_length=%d\n", size, 1793 - info->reassembly_data_length); 1794 - if (info->reassembly_data_length >= size) { 1813 + log_read(INFO, "size=%zd sc->recv_io.reassembly.data_length=%d\n", size, 1814 + sc->recv_io.reassembly.data_length); 1815 + if (sc->recv_io.reassembly.data_length >= size) { 1795 1816 int queue_length; 1796 1817 int queue_removed = 0; 1797 1818 ··· 1803 1824 * updated in SOFTIRQ as more data is received 1804 1825 */ 1805 1826 virt_rmb(); 1806 - queue_length = info->reassembly_queue_length; 1827 + queue_length = sc->recv_io.reassembly.queue_length; 1807 1828 data_read = 0; 1808 1829 to_read = size; 1809 - offset = info->first_entry_offset; 1830 + offset = sc->recv_io.reassembly.first_entry_offset; 1810 1831 while (data_read < size) { 1811 1832 response = _get_first_reassembly(info); 1812 - data_transfer = smbd_response_payload(response); 1833 + data_transfer = smbdirect_recv_io_payload(response); 1813 1834 data_length = le32_to_cpu(data_transfer->data_length); 1814 1835 remaining_data_length = 1815 1836 le32_to_cpu( ··· 1854 1875 list_del(&response->list); 1855 1876 else { 1856 1877 spin_lock_irq( 1857 - &info->reassembly_queue_lock); 1878 + &sc->recv_io.reassembly.lock); 1858 1879 list_del(&response->list); 1859 1880 spin_unlock_irq( 1860 - &info->reassembly_queue_lock); 1881 + &sc->recv_io.reassembly.lock); 1861 1882 } 1862 1883 queue_removed++; 1863 1884 info->count_reassembly_queue--; ··· 1876 1897 to_read, data_read, offset); 1877 1898 } 1878 1899 1879 - spin_lock_irq(&info->reassembly_queue_lock); 1880 - info->reassembly_data_length -= data_read; 1881 - info->reassembly_queue_length -= queue_removed; 1882 - spin_unlock_irq(&info->reassembly_queue_lock); 1900 + spin_lock_irq(&sc->recv_io.reassembly.lock); 1901 + sc->recv_io.reassembly.data_length -= data_read; 1902 + sc->recv_io.reassembly.queue_length -= queue_removed; 1903 + spin_unlock_irq(&sc->recv_io.reassembly.lock); 1883 1904 1884 - info->first_entry_offset = offset; 1905 + sc->recv_io.reassembly.first_entry_offset = offset; 1885 1906 log_read(INFO, "returning to thread data_read=%d reassembly_data_length=%d first_entry_offset=%d\n", 1886 - data_read, info->reassembly_data_length, 1887 - info->first_entry_offset); 1907 + data_read, sc->recv_io.reassembly.data_length, 1908 + sc->recv_io.reassembly.first_entry_offset); 1888 1909 read_rfc1002_done: 1889 1910 return data_read; 1890 1911 } 1891 1912 1892 1913 log_read(INFO, "wait_event on more data\n"); 1893 1914 rc = wait_event_interruptible( 1894 - info->wait_reassembly_queue, 1895 - info->reassembly_data_length >= size || 1915 + sc->recv_io.reassembly.wait_queue, 1916 + sc->recv_io.reassembly.data_length >= size || 1896 1917 sc->status != SMBDIRECT_SOCKET_CONNECTED); 1897 1918 /* Don't return any data if interrupted */ 1898 1919 if (rc)
+1 -91
fs/smb/client/smbdirect.h
··· 33 33 KEEP_ALIVE_SENT, 34 34 }; 35 35 36 - enum smbd_connection_status { 37 - SMBD_CREATED, 38 - SMBD_CONNECTING, 39 - SMBD_CONNECTED, 40 - SMBD_NEGOTIATE_FAILED, 41 - SMBD_DISCONNECTING, 42 - SMBD_DISCONNECTED, 43 - SMBD_DESTROYED 44 - }; 45 - 46 36 /* 47 37 * The context for the SMBDirect transport 48 38 * Everything related to the transport is here. It has several logical parts ··· 47 57 48 58 int ri_rc; 49 59 struct completion ri_done; 50 - wait_queue_head_t conn_wait; 51 - wait_queue_head_t disconn_wait; 60 + wait_queue_head_t status_wait; 52 61 53 62 struct completion negotiate_completion; 54 63 bool negotiate_done; ··· 64 75 atomic_t send_credits; 65 76 atomic_t receive_credits; 66 77 int receive_credit_target; 67 - int fragment_reassembly_remaining; 68 78 69 79 /* Memory registrations */ 70 80 /* Maximum number of RDMA read/write outstanding on this connection */ ··· 94 106 wait_queue_head_t wait_post_send; 95 107 96 108 /* Receive queue */ 97 - struct list_head receive_queue; 98 109 int count_receive_queue; 99 - spinlock_t receive_queue_lock; 100 - 101 - struct list_head empty_packet_queue; 102 - int count_empty_packet_queue; 103 - spinlock_t empty_packet_queue_lock; 104 - 105 110 wait_queue_head_t wait_receive_queues; 106 - 107 - /* Reassembly queue */ 108 - struct list_head reassembly_queue; 109 - spinlock_t reassembly_queue_lock; 110 - wait_queue_head_t wait_reassembly_queue; 111 - 112 - /* total data length of reassembly queue */ 113 - int reassembly_data_length; 114 - int reassembly_queue_length; 115 - /* the offset to first buffer in reassembly queue */ 116 - int first_entry_offset; 117 111 118 112 bool send_immediate; 119 113 120 114 wait_queue_head_t wait_send_queue; 121 115 122 - /* 123 - * Indicate if we have received a full packet on the connection 124 - * This is used to identify the first SMBD packet of a assembled 125 - * payload (SMB packet) in reassembly queue so we can return a 126 - * RFC1002 length to upper layer to indicate the length of the SMB 127 - * packet received 128 - */ 129 - bool full_packet_received; 130 - 131 116 struct workqueue_struct *workqueue; 132 117 struct delayed_work idle_timer_work; 133 - 134 - /* Memory pool for preallocating buffers */ 135 - /* request pool for RDMA send */ 136 - struct kmem_cache *request_cache; 137 - mempool_t *request_mempool; 138 - 139 - /* response pool for RDMA receive */ 140 - struct kmem_cache *response_cache; 141 - mempool_t *response_mempool; 142 118 143 119 /* for debug purposes */ 144 120 unsigned int count_get_receive_buffer; ··· 111 159 unsigned int count_enqueue_reassembly_queue; 112 160 unsigned int count_dequeue_reassembly_queue; 113 161 unsigned int count_send_empty; 114 - }; 115 - 116 - enum smbd_message_type { 117 - SMBD_NEGOTIATE_RESP, 118 - SMBD_TRANSFER_DATA, 119 - }; 120 - 121 - /* Maximum number of SGEs used by smbdirect.c in any send work request */ 122 - #define SMBDIRECT_MAX_SEND_SGE 6 123 - 124 - /* The context for a SMBD request */ 125 - struct smbd_request { 126 - struct smbd_connection *info; 127 - struct ib_cqe cqe; 128 - 129 - /* the SGE entries for this work request */ 130 - struct ib_sge sge[SMBDIRECT_MAX_SEND_SGE]; 131 - int num_sge; 132 - 133 - /* SMBD packet header follows this structure */ 134 - u8 packet[]; 135 - }; 136 - 137 - /* Maximum number of SGEs used by smbdirect.c in any receive work request */ 138 - #define SMBDIRECT_MAX_RECV_SGE 1 139 - 140 - /* The context for a SMBD response */ 141 - struct smbd_response { 142 - struct smbd_connection *info; 143 - struct ib_cqe cqe; 144 - struct ib_sge sge; 145 - 146 - enum smbd_message_type type; 147 - 148 - /* Link to receive queue or reassembly queue */ 149 - struct list_head list; 150 - 151 - /* Indicate if this is the 1st packet of a payload */ 152 - bool first_segment; 153 - 154 - /* SMBD packet header and payload follows this structure */ 155 - u8 packet[]; 156 162 }; 157 163 158 164 /* Create a SMBDirect session */
+28 -574
fs/smb/client/transport.c
··· 30 30 #include "smbdirect.h" 31 31 #include "compress.h" 32 32 33 - /* Max number of iovectors we can use off the stack when sending requests. */ 34 - #define CIFS_MAX_IOV_SIZE 8 35 - 36 33 void 37 34 cifs_wake_up_task(struct mid_q_entry *mid) 38 35 { 39 36 if (mid->mid_state == MID_RESPONSE_RECEIVED) 40 37 mid->mid_state = MID_RESPONSE_READY; 41 38 wake_up_process(mid->callback_data); 42 - } 43 - 44 - static struct mid_q_entry * 45 - alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server) 46 - { 47 - struct mid_q_entry *temp; 48 - 49 - if (server == NULL) { 50 - cifs_dbg(VFS, "%s: null TCP session\n", __func__); 51 - return NULL; 52 - } 53 - 54 - temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS); 55 - memset(temp, 0, sizeof(struct mid_q_entry)); 56 - kref_init(&temp->refcount); 57 - temp->mid = get_mid(smb_buffer); 58 - temp->pid = current->pid; 59 - temp->command = cpu_to_le16(smb_buffer->Command); 60 - cifs_dbg(FYI, "For smb_command %d\n", smb_buffer->Command); 61 - /* easier to use jiffies */ 62 - /* when mid allocated can be before when sent */ 63 - temp->when_alloc = jiffies; 64 - temp->server = server; 65 - 66 - /* 67 - * The default is for the mid to be synchronous, so the 68 - * default callback just wakes up the current task. 69 - */ 70 - get_task_struct(current); 71 - temp->creator = current; 72 - temp->callback = cifs_wake_up_task; 73 - temp->callback_data = current; 74 - 75 - atomic_inc(&mid_count); 76 - temp->mid_state = MID_REQUEST_ALLOCATED; 77 - return temp; 78 39 } 79 40 80 41 void __release_mid(struct kref *refcount) ··· 50 89 #endif 51 90 struct TCP_Server_Info *server = midEntry->server; 52 91 53 - if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && 92 + if (midEntry->resp_buf && (midEntry->wait_cancelled) && 54 93 (midEntry->mid_state == MID_RESPONSE_RECEIVED || 55 94 midEntry->mid_state == MID_RESPONSE_READY) && 56 95 server->ops->handle_cancelled_mid) ··· 121 160 void 122 161 delete_mid(struct mid_q_entry *mid) 123 162 { 124 - spin_lock(&mid->server->mid_lock); 125 - if (!(mid->mid_flags & MID_DELETED)) { 163 + spin_lock(&mid->server->mid_queue_lock); 164 + if (mid->deleted_from_q == false) { 126 165 list_del_init(&mid->qhead); 127 - mid->mid_flags |= MID_DELETED; 166 + mid->deleted_from_q = true; 128 167 } 129 - spin_unlock(&mid->server->mid_lock); 168 + spin_unlock(&mid->server->mid_queue_lock); 130 169 131 170 release_mid(mid); 132 171 } ··· 230 269 return buflen; 231 270 } 232 271 233 - static int 234 - __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, 235 - struct smb_rqst *rqst) 272 + int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, 273 + struct smb_rqst *rqst) 236 274 { 237 275 int rc; 238 276 struct kvec *iov; ··· 357 397 * socket so the server throws away the partial SMB 358 398 */ 359 399 cifs_signal_cifsd_for_reconnect(server, false); 360 - trace_smb3_partial_send_reconnect(server->CurrentMid, 400 + trace_smb3_partial_send_reconnect(server->current_mid, 361 401 server->conn_id, server->hostname); 362 402 } 363 403 smbd_done: ··· 416 456 return rc; 417 457 } 418 458 419 - int 420 - smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, 421 - unsigned int smb_buf_length) 422 - { 423 - struct kvec iov[2]; 424 - struct smb_rqst rqst = { .rq_iov = iov, 425 - .rq_nvec = 2 }; 426 - 427 - iov[0].iov_base = smb_buffer; 428 - iov[0].iov_len = 4; 429 - iov[1].iov_base = (char *)smb_buffer + 4; 430 - iov[1].iov_len = smb_buf_length; 431 - 432 - return __smb_send_rqst(server, 1, &rqst); 433 - } 434 - 435 459 static int 436 460 wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, 437 461 const int timeout, const int flags, ··· 453 509 in_flight = server->in_flight; 454 510 spin_unlock(&server->req_lock); 455 511 456 - trace_smb3_nblk_credits(server->CurrentMid, 512 + trace_smb3_nblk_credits(server->current_mid, 457 513 server->conn_id, server->hostname, scredits, -1, in_flight); 458 514 cifs_dbg(FYI, "%s: remove %u credits total=%d\n", 459 515 __func__, 1, scredits); ··· 486 542 in_flight = server->in_flight; 487 543 spin_unlock(&server->req_lock); 488 544 489 - trace_smb3_credit_timeout(server->CurrentMid, 545 + trace_smb3_credit_timeout(server->current_mid, 490 546 server->conn_id, server->hostname, scredits, 491 547 num_credits, in_flight); 492 548 cifs_server_dbg(VFS, "wait timed out after %d ms\n", ··· 529 585 spin_unlock(&server->req_lock); 530 586 531 587 trace_smb3_credit_timeout( 532 - server->CurrentMid, 588 + server->current_mid, 533 589 server->conn_id, server->hostname, 534 590 scredits, num_credits, in_flight); 535 591 cifs_server_dbg(VFS, "wait timed out after %d ms\n", ··· 559 615 in_flight = server->in_flight; 560 616 spin_unlock(&server->req_lock); 561 617 562 - trace_smb3_waitff_credits(server->CurrentMid, 618 + trace_smb3_waitff_credits(server->current_mid, 563 619 server->conn_id, server->hostname, scredits, 564 620 -(num_credits), in_flight); 565 621 cifs_dbg(FYI, "%s: remove %u credits total=%d\n", ··· 570 626 return 0; 571 627 } 572 628 573 - static int 574 - wait_for_free_request(struct TCP_Server_Info *server, const int flags, 575 - unsigned int *instance) 629 + int wait_for_free_request(struct TCP_Server_Info *server, const int flags, 630 + unsigned int *instance) 576 631 { 577 632 return wait_for_free_credits(server, 1, -1, flags, 578 633 instance); ··· 609 666 */ 610 667 if (server->in_flight == 0) { 611 668 spin_unlock(&server->req_lock); 612 - trace_smb3_insufficient_credits(server->CurrentMid, 669 + trace_smb3_insufficient_credits(server->current_mid, 613 670 server->conn_id, server->hostname, scredits, 614 671 num, in_flight); 615 672 cifs_dbg(FYI, "%s: %d requests in flight, needed %d total=%d\n", ··· 633 690 return 0; 634 691 } 635 692 636 - static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf, 637 - struct mid_q_entry **ppmidQ) 638 - { 639 - spin_lock(&ses->ses_lock); 640 - if (ses->ses_status == SES_NEW) { 641 - if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 642 - (in_buf->Command != SMB_COM_NEGOTIATE)) { 643 - spin_unlock(&ses->ses_lock); 644 - return -EAGAIN; 645 - } 646 - /* else ok - we are setting up session */ 647 - } 648 - 649 - if (ses->ses_status == SES_EXITING) { 650 - /* check if SMB session is bad because we are setting it up */ 651 - if (in_buf->Command != SMB_COM_LOGOFF_ANDX) { 652 - spin_unlock(&ses->ses_lock); 653 - return -EAGAIN; 654 - } 655 - /* else ok - we are shutting down session */ 656 - } 657 - spin_unlock(&ses->ses_lock); 658 - 659 - *ppmidQ = alloc_mid(in_buf, ses->server); 660 - if (*ppmidQ == NULL) 661 - return -ENOMEM; 662 - spin_lock(&ses->server->mid_lock); 663 - list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q); 664 - spin_unlock(&ses->server->mid_lock); 665 - return 0; 666 - } 667 - 668 - static int 669 - wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ) 693 + int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ) 670 694 { 671 695 int error; 672 696 ··· 645 735 return -ERESTARTSYS; 646 736 647 737 return 0; 648 - } 649 - 650 - struct mid_q_entry * 651 - cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst) 652 - { 653 - int rc; 654 - struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base; 655 - struct mid_q_entry *mid; 656 - 657 - if (rqst->rq_iov[0].iov_len != 4 || 658 - rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base) 659 - return ERR_PTR(-EIO); 660 - 661 - /* enable signing if server requires it */ 662 - if (server->sign) 663 - hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 664 - 665 - mid = alloc_mid(hdr, server); 666 - if (mid == NULL) 667 - return ERR_PTR(-ENOMEM); 668 - 669 - rc = cifs_sign_rqst(rqst, server, &mid->sequence_number); 670 - if (rc) { 671 - release_mid(mid); 672 - return ERR_PTR(rc); 673 - } 674 - 675 - return mid; 676 738 } 677 739 678 740 /* ··· 701 819 mid->mid_state = MID_REQUEST_SUBMITTED; 702 820 703 821 /* put it on the pending_mid_q */ 704 - spin_lock(&server->mid_lock); 822 + spin_lock(&server->mid_queue_lock); 705 823 list_add_tail(&mid->qhead, &server->pending_mid_q); 706 - spin_unlock(&server->mid_lock); 824 + spin_unlock(&server->mid_queue_lock); 707 825 708 826 /* 709 827 * Need to store the time in mid before calling I/O. For call_async, ··· 727 845 return rc; 728 846 } 729 847 730 - /* 731 - * 732 - * Send an SMB Request. No response info (other than return code) 733 - * needs to be parsed. 734 - * 735 - * flags indicate the type of request buffer and how long to wait 736 - * and whether to log NT STATUS code (error) before mapping it to POSIX error 737 - * 738 - */ 739 - int 740 - SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, 741 - char *in_buf, int flags) 742 - { 743 - int rc; 744 - struct kvec iov[1]; 745 - struct kvec rsp_iov; 746 - int resp_buf_type; 747 - 748 - iov[0].iov_base = in_buf; 749 - iov[0].iov_len = get_rfc1002_length(in_buf) + 4; 750 - flags |= CIFS_NO_RSP_BUF; 751 - rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov); 752 - cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc); 753 - 754 - return rc; 755 - } 756 - 757 - static int 758 - cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) 848 + int cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) 759 849 { 760 850 int rc = 0; 761 851 762 852 cifs_dbg(FYI, "%s: cmd=%d mid=%llu state=%d\n", 763 853 __func__, le16_to_cpu(mid->command), mid->mid, mid->mid_state); 764 854 765 - spin_lock(&server->mid_lock); 855 + spin_lock(&server->mid_queue_lock); 766 856 switch (mid->mid_state) { 767 857 case MID_RESPONSE_READY: 768 - spin_unlock(&server->mid_lock); 858 + spin_unlock(&server->mid_queue_lock); 769 859 return rc; 770 860 case MID_RETRY_NEEDED: 771 861 rc = -EAGAIN; ··· 752 898 rc = mid->mid_rc; 753 899 break; 754 900 default: 755 - if (!(mid->mid_flags & MID_DELETED)) { 901 + if (mid->deleted_from_q == false) { 756 902 list_del_init(&mid->qhead); 757 - mid->mid_flags |= MID_DELETED; 903 + mid->deleted_from_q = true; 758 904 } 759 - spin_unlock(&server->mid_lock); 905 + spin_unlock(&server->mid_queue_lock); 760 906 cifs_server_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n", 761 907 __func__, mid->mid, mid->mid_state); 762 908 rc = -EIO; 763 909 goto sync_mid_done; 764 910 } 765 - spin_unlock(&server->mid_lock); 911 + spin_unlock(&server->mid_queue_lock); 766 912 767 913 sync_mid_done: 768 914 release_mid(mid); 769 915 return rc; 770 - } 771 - 772 - static inline int 773 - send_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst, 774 - struct mid_q_entry *mid) 775 - { 776 - return server->ops->send_cancel ? 777 - server->ops->send_cancel(server, rqst, mid) : 0; 778 - } 779 - 780 - int 781 - cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, 782 - bool log_error) 783 - { 784 - unsigned int len = get_rfc1002_length(mid->resp_buf) + 4; 785 - 786 - dump_smb(mid->resp_buf, min_t(u32, 92, len)); 787 - 788 - /* convert the length into a more usable form */ 789 - if (server->sign) { 790 - struct kvec iov[2]; 791 - int rc = 0; 792 - struct smb_rqst rqst = { .rq_iov = iov, 793 - .rq_nvec = 2 }; 794 - 795 - iov[0].iov_base = mid->resp_buf; 796 - iov[0].iov_len = 4; 797 - iov[1].iov_base = (char *)mid->resp_buf + 4; 798 - iov[1].iov_len = len - 4; 799 - /* FIXME: add code to kill session */ 800 - rc = cifs_verify_signature(&rqst, server, 801 - mid->sequence_number); 802 - if (rc) 803 - cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n", 804 - rc); 805 - } 806 - 807 - /* BB special case reconnect tid and uid here? */ 808 - return map_and_check_smb_error(mid, log_error); 809 - } 810 - 811 - struct mid_q_entry * 812 - cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored, 813 - struct smb_rqst *rqst) 814 - { 815 - int rc; 816 - struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base; 817 - struct mid_q_entry *mid; 818 - 819 - if (rqst->rq_iov[0].iov_len != 4 || 820 - rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base) 821 - return ERR_PTR(-EIO); 822 - 823 - rc = allocate_mid(ses, hdr, &mid); 824 - if (rc) 825 - return ERR_PTR(rc); 826 - rc = cifs_sign_rqst(rqst, ses->server, &mid->sequence_number); 827 - if (rc) { 828 - delete_mid(mid); 829 - return ERR_PTR(rc); 830 - } 831 - return mid; 832 916 } 833 917 834 918 static void ··· 1005 1213 cifs_server_dbg(FYI, "Cancelling wait for mid %llu cmd: %d\n", 1006 1214 midQ[i]->mid, le16_to_cpu(midQ[i]->command)); 1007 1215 send_cancel(server, &rqst[i], midQ[i]); 1008 - spin_lock(&server->mid_lock); 1009 - midQ[i]->mid_flags |= MID_WAIT_CANCELLED; 1216 + spin_lock(&server->mid_queue_lock); 1217 + midQ[i]->wait_cancelled = true; 1010 1218 if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED || 1011 1219 midQ[i]->mid_state == MID_RESPONSE_RECEIVED) { 1012 1220 midQ[i]->callback = cifs_cancelled_callback; 1013 1221 cancelled_mid[i] = true; 1014 1222 credits[i].value = 0; 1015 1223 } 1016 - spin_unlock(&server->mid_lock); 1224 + spin_unlock(&server->mid_queue_lock); 1017 1225 } 1018 1226 } 1019 1227 ··· 1096 1304 rqst, resp_buf_type, resp_iov); 1097 1305 } 1098 1306 1099 - int 1100 - SendReceive2(const unsigned int xid, struct cifs_ses *ses, 1101 - struct kvec *iov, int n_vec, int *resp_buf_type /* ret */, 1102 - const int flags, struct kvec *resp_iov) 1103 - { 1104 - struct smb_rqst rqst; 1105 - struct kvec s_iov[CIFS_MAX_IOV_SIZE], *new_iov; 1106 - int rc; 1107 - 1108 - if (n_vec + 1 > CIFS_MAX_IOV_SIZE) { 1109 - new_iov = kmalloc_array(n_vec + 1, sizeof(struct kvec), 1110 - GFP_KERNEL); 1111 - if (!new_iov) { 1112 - /* otherwise cifs_send_recv below sets resp_buf_type */ 1113 - *resp_buf_type = CIFS_NO_BUFFER; 1114 - return -ENOMEM; 1115 - } 1116 - } else 1117 - new_iov = s_iov; 1118 - 1119 - /* 1st iov is a RFC1001 length followed by the rest of the packet */ 1120 - memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec)); 1121 - 1122 - new_iov[0].iov_base = new_iov[1].iov_base; 1123 - new_iov[0].iov_len = 4; 1124 - new_iov[1].iov_base += 4; 1125 - new_iov[1].iov_len -= 4; 1126 - 1127 - memset(&rqst, 0, sizeof(struct smb_rqst)); 1128 - rqst.rq_iov = new_iov; 1129 - rqst.rq_nvec = n_vec + 1; 1130 - 1131 - rc = cifs_send_recv(xid, ses, ses->server, 1132 - &rqst, resp_buf_type, flags, resp_iov); 1133 - if (n_vec + 1 > CIFS_MAX_IOV_SIZE) 1134 - kfree(new_iov); 1135 - return rc; 1136 - } 1137 - 1138 - int 1139 - SendReceive(const unsigned int xid, struct cifs_ses *ses, 1140 - struct smb_hdr *in_buf, struct smb_hdr *out_buf, 1141 - int *pbytes_returned, const int flags) 1142 - { 1143 - int rc = 0; 1144 - struct mid_q_entry *midQ; 1145 - unsigned int len = be32_to_cpu(in_buf->smb_buf_length); 1146 - struct kvec iov = { .iov_base = in_buf, .iov_len = len }; 1147 - struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; 1148 - struct cifs_credits credits = { .value = 1, .instance = 0 }; 1149 - struct TCP_Server_Info *server; 1150 - 1151 - if (ses == NULL) { 1152 - cifs_dbg(VFS, "Null smb session\n"); 1153 - return -EIO; 1154 - } 1155 - server = ses->server; 1156 - if (server == NULL) { 1157 - cifs_dbg(VFS, "Null tcp session\n"); 1158 - return -EIO; 1159 - } 1160 - 1161 - spin_lock(&server->srv_lock); 1162 - if (server->tcpStatus == CifsExiting) { 1163 - spin_unlock(&server->srv_lock); 1164 - return -ENOENT; 1165 - } 1166 - spin_unlock(&server->srv_lock); 1167 - 1168 - /* Ensure that we do not send more than 50 overlapping requests 1169 - to the same server. We may make this configurable later or 1170 - use ses->maxReq */ 1171 - 1172 - if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 1173 - cifs_server_dbg(VFS, "Invalid length, greater than maximum frame, %d\n", 1174 - len); 1175 - return -EIO; 1176 - } 1177 - 1178 - rc = wait_for_free_request(server, flags, &credits.instance); 1179 - if (rc) 1180 - return rc; 1181 - 1182 - /* make sure that we sign in the same order that we send on this socket 1183 - and avoid races inside tcp sendmsg code that could cause corruption 1184 - of smb data */ 1185 - 1186 - cifs_server_lock(server); 1187 - 1188 - rc = allocate_mid(ses, in_buf, &midQ); 1189 - if (rc) { 1190 - cifs_server_unlock(server); 1191 - /* Update # of requests on wire to server */ 1192 - add_credits(server, &credits, 0); 1193 - return rc; 1194 - } 1195 - 1196 - rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number); 1197 - if (rc) { 1198 - cifs_server_unlock(server); 1199 - goto out; 1200 - } 1201 - 1202 - midQ->mid_state = MID_REQUEST_SUBMITTED; 1203 - 1204 - rc = smb_send(server, in_buf, len); 1205 - cifs_save_when_sent(midQ); 1206 - 1207 - if (rc < 0) 1208 - server->sequence_number -= 2; 1209 - 1210 - cifs_server_unlock(server); 1211 - 1212 - if (rc < 0) 1213 - goto out; 1214 - 1215 - rc = wait_for_response(server, midQ); 1216 - if (rc != 0) { 1217 - send_cancel(server, &rqst, midQ); 1218 - spin_lock(&server->mid_lock); 1219 - if (midQ->mid_state == MID_REQUEST_SUBMITTED || 1220 - midQ->mid_state == MID_RESPONSE_RECEIVED) { 1221 - /* no longer considered to be "in-flight" */ 1222 - midQ->callback = release_mid; 1223 - spin_unlock(&server->mid_lock); 1224 - add_credits(server, &credits, 0); 1225 - return rc; 1226 - } 1227 - spin_unlock(&server->mid_lock); 1228 - } 1229 - 1230 - rc = cifs_sync_mid_result(midQ, server); 1231 - if (rc != 0) { 1232 - add_credits(server, &credits, 0); 1233 - return rc; 1234 - } 1235 - 1236 - if (!midQ->resp_buf || !out_buf || 1237 - midQ->mid_state != MID_RESPONSE_READY) { 1238 - rc = -EIO; 1239 - cifs_server_dbg(VFS, "Bad MID state?\n"); 1240 - goto out; 1241 - } 1242 - 1243 - *pbytes_returned = get_rfc1002_length(midQ->resp_buf); 1244 - memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4); 1245 - rc = cifs_check_receive(midQ, server, 0); 1246 - out: 1247 - delete_mid(midQ); 1248 - add_credits(server, &credits, 0); 1249 - 1250 - return rc; 1251 - } 1252 - 1253 - /* We send a LOCKINGX_CANCEL_LOCK to cause the Windows 1254 - blocking lock to return. */ 1255 - 1256 - static int 1257 - send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon, 1258 - struct smb_hdr *in_buf, 1259 - struct smb_hdr *out_buf) 1260 - { 1261 - int bytes_returned; 1262 - struct cifs_ses *ses = tcon->ses; 1263 - LOCK_REQ *pSMB = (LOCK_REQ *)in_buf; 1264 - 1265 - /* We just modify the current in_buf to change 1266 - the type of lock from LOCKING_ANDX_SHARED_LOCK 1267 - or LOCKING_ANDX_EXCLUSIVE_LOCK to 1268 - LOCKING_ANDX_CANCEL_LOCK. */ 1269 - 1270 - pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES; 1271 - pSMB->Timeout = 0; 1272 - pSMB->hdr.Mid = get_next_mid(ses->server); 1273 - 1274 - return SendReceive(xid, ses, in_buf, out_buf, 1275 - &bytes_returned, 0); 1276 - } 1277 - 1278 - int 1279 - SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, 1280 - struct smb_hdr *in_buf, struct smb_hdr *out_buf, 1281 - int *pbytes_returned) 1282 - { 1283 - int rc = 0; 1284 - int rstart = 0; 1285 - struct mid_q_entry *midQ; 1286 - struct cifs_ses *ses; 1287 - unsigned int len = be32_to_cpu(in_buf->smb_buf_length); 1288 - struct kvec iov = { .iov_base = in_buf, .iov_len = len }; 1289 - struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; 1290 - unsigned int instance; 1291 - struct TCP_Server_Info *server; 1292 - 1293 - if (tcon == NULL || tcon->ses == NULL) { 1294 - cifs_dbg(VFS, "Null smb session\n"); 1295 - return -EIO; 1296 - } 1297 - ses = tcon->ses; 1298 - server = ses->server; 1299 - 1300 - if (server == NULL) { 1301 - cifs_dbg(VFS, "Null tcp session\n"); 1302 - return -EIO; 1303 - } 1304 - 1305 - spin_lock(&server->srv_lock); 1306 - if (server->tcpStatus == CifsExiting) { 1307 - spin_unlock(&server->srv_lock); 1308 - return -ENOENT; 1309 - } 1310 - spin_unlock(&server->srv_lock); 1311 - 1312 - /* Ensure that we do not send more than 50 overlapping requests 1313 - to the same server. We may make this configurable later or 1314 - use ses->maxReq */ 1315 - 1316 - if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 1317 - cifs_tcon_dbg(VFS, "Invalid length, greater than maximum frame, %d\n", 1318 - len); 1319 - return -EIO; 1320 - } 1321 - 1322 - rc = wait_for_free_request(server, CIFS_BLOCKING_OP, &instance); 1323 - if (rc) 1324 - return rc; 1325 - 1326 - /* make sure that we sign in the same order that we send on this socket 1327 - and avoid races inside tcp sendmsg code that could cause corruption 1328 - of smb data */ 1329 - 1330 - cifs_server_lock(server); 1331 - 1332 - rc = allocate_mid(ses, in_buf, &midQ); 1333 - if (rc) { 1334 - cifs_server_unlock(server); 1335 - return rc; 1336 - } 1337 - 1338 - rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number); 1339 - if (rc) { 1340 - delete_mid(midQ); 1341 - cifs_server_unlock(server); 1342 - return rc; 1343 - } 1344 - 1345 - midQ->mid_state = MID_REQUEST_SUBMITTED; 1346 - rc = smb_send(server, in_buf, len); 1347 - cifs_save_when_sent(midQ); 1348 - 1349 - if (rc < 0) 1350 - server->sequence_number -= 2; 1351 - 1352 - cifs_server_unlock(server); 1353 - 1354 - if (rc < 0) { 1355 - delete_mid(midQ); 1356 - return rc; 1357 - } 1358 - 1359 - /* Wait for a reply - allow signals to interrupt. */ 1360 - rc = wait_event_interruptible(server->response_q, 1361 - (!(midQ->mid_state == MID_REQUEST_SUBMITTED || 1362 - midQ->mid_state == MID_RESPONSE_RECEIVED)) || 1363 - ((server->tcpStatus != CifsGood) && 1364 - (server->tcpStatus != CifsNew))); 1365 - 1366 - /* Were we interrupted by a signal ? */ 1367 - spin_lock(&server->srv_lock); 1368 - if ((rc == -ERESTARTSYS) && 1369 - (midQ->mid_state == MID_REQUEST_SUBMITTED || 1370 - midQ->mid_state == MID_RESPONSE_RECEIVED) && 1371 - ((server->tcpStatus == CifsGood) || 1372 - (server->tcpStatus == CifsNew))) { 1373 - spin_unlock(&server->srv_lock); 1374 - 1375 - if (in_buf->Command == SMB_COM_TRANSACTION2) { 1376 - /* POSIX lock. We send a NT_CANCEL SMB to cause the 1377 - blocking lock to return. */ 1378 - rc = send_cancel(server, &rqst, midQ); 1379 - if (rc) { 1380 - delete_mid(midQ); 1381 - return rc; 1382 - } 1383 - } else { 1384 - /* Windows lock. We send a LOCKINGX_CANCEL_LOCK 1385 - to cause the blocking lock to return. */ 1386 - 1387 - rc = send_lock_cancel(xid, tcon, in_buf, out_buf); 1388 - 1389 - /* If we get -ENOLCK back the lock may have 1390 - already been removed. Don't exit in this case. */ 1391 - if (rc && rc != -ENOLCK) { 1392 - delete_mid(midQ); 1393 - return rc; 1394 - } 1395 - } 1396 - 1397 - rc = wait_for_response(server, midQ); 1398 - if (rc) { 1399 - send_cancel(server, &rqst, midQ); 1400 - spin_lock(&server->mid_lock); 1401 - if (midQ->mid_state == MID_REQUEST_SUBMITTED || 1402 - midQ->mid_state == MID_RESPONSE_RECEIVED) { 1403 - /* no longer considered to be "in-flight" */ 1404 - midQ->callback = release_mid; 1405 - spin_unlock(&server->mid_lock); 1406 - return rc; 1407 - } 1408 - spin_unlock(&server->mid_lock); 1409 - } 1410 - 1411 - /* We got the response - restart system call. */ 1412 - rstart = 1; 1413 - spin_lock(&server->srv_lock); 1414 - } 1415 - spin_unlock(&server->srv_lock); 1416 - 1417 - rc = cifs_sync_mid_result(midQ, server); 1418 - if (rc != 0) 1419 - return rc; 1420 - 1421 - /* rcvd frame is ok */ 1422 - if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_READY) { 1423 - rc = -EIO; 1424 - cifs_tcon_dbg(VFS, "Bad MID state?\n"); 1425 - goto out; 1426 - } 1427 - 1428 - *pbytes_returned = get_rfc1002_length(midQ->resp_buf); 1429 - memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4); 1430 - rc = cifs_check_receive(midQ, server, 0); 1431 - out: 1432 - delete_mid(midQ); 1433 - if (rstart && rc == -EACCES) 1434 - return -ERESTARTSYS; 1435 - return rc; 1436 - } 1437 1307 1438 1308 /* 1439 1309 * Discard any remaining data in the current SMB. To do this, we borrow the
+118
fs/smb/common/smbdirect/smbdirect_socket.h
··· 38 38 } ib; 39 39 40 40 struct smbdirect_socket_parameters parameters; 41 + 42 + /* 43 + * The state for posted send buffers 44 + */ 45 + struct { 46 + /* 47 + * Memory pools for preallocating 48 + * smbdirect_send_io buffers 49 + */ 50 + struct { 51 + struct kmem_cache *cache; 52 + mempool_t *pool; 53 + } mem; 54 + } send_io; 55 + 56 + /* 57 + * The state for posted receive buffers 58 + */ 59 + struct { 60 + /* 61 + * The type of PDU we are expecting 62 + */ 63 + enum { 64 + SMBDIRECT_EXPECT_NEGOTIATE_REQ = 1, 65 + SMBDIRECT_EXPECT_NEGOTIATE_REP = 2, 66 + SMBDIRECT_EXPECT_DATA_TRANSFER = 3, 67 + } expected; 68 + 69 + /* 70 + * Memory pools for preallocating 71 + * smbdirect_recv_io buffers 72 + */ 73 + struct { 74 + struct kmem_cache *cache; 75 + mempool_t *pool; 76 + } mem; 77 + 78 + /* 79 + * The list of free smbdirect_recv_io 80 + * structures 81 + */ 82 + struct { 83 + struct list_head list; 84 + spinlock_t lock; 85 + } free; 86 + 87 + /* 88 + * The list of arrived non-empty smbdirect_recv_io 89 + * structures 90 + * 91 + * This represents the reassembly queue. 92 + */ 93 + struct { 94 + struct list_head list; 95 + spinlock_t lock; 96 + wait_queue_head_t wait_queue; 97 + /* total data length of reassembly queue */ 98 + int data_length; 99 + int queue_length; 100 + /* the offset to first buffer in reassembly queue */ 101 + int first_entry_offset; 102 + /* 103 + * Indicate if we have received a full packet on the 104 + * connection This is used to identify the first SMBD 105 + * packet of a assembled payload (SMB packet) in 106 + * reassembly queue so we can return a RFC1002 length to 107 + * upper layer to indicate the length of the SMB packet 108 + * received 109 + */ 110 + bool full_packet_received; 111 + } reassembly; 112 + } recv_io; 113 + }; 114 + 115 + struct smbdirect_send_io { 116 + struct smbdirect_socket *socket; 117 + struct ib_cqe cqe; 118 + 119 + /* 120 + * The SGE entries for this work request 121 + * 122 + * The first points to the packet header 123 + */ 124 + #define SMBDIRECT_SEND_IO_MAX_SGE 6 125 + size_t num_sge; 126 + struct ib_sge sge[SMBDIRECT_SEND_IO_MAX_SGE]; 127 + 128 + /* 129 + * Link to the list of sibling smbdirect_send_io 130 + * messages. 131 + */ 132 + struct list_head sibling_list; 133 + struct ib_send_wr wr; 134 + 135 + /* SMBD packet header follows this structure */ 136 + u8 packet[]; 137 + }; 138 + 139 + struct smbdirect_recv_io { 140 + struct smbdirect_socket *socket; 141 + struct ib_cqe cqe; 142 + 143 + /* 144 + * For now we only use a single SGE 145 + * as we have just one large buffer 146 + * per posted recv. 147 + */ 148 + #define SMBDIRECT_RECV_IO_MAX_SGE 1 149 + struct ib_sge sge; 150 + 151 + /* Link to free or reassembly list */ 152 + struct list_head list; 153 + 154 + /* Indicate if this is the 1st packet of a payload */ 155 + bool first_segment; 156 + 157 + /* SMBD packet header and payload follows this structure */ 158 + u8 packet[]; 41 159 }; 42 160 43 161 #endif /* __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__ */