Commit cfaf773b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
  ...
parents 471025c9 dfe6f14a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -32,6 +32,6 @@ cifs-$(CONFIG_CIFS_SMB_DIRECT) += smbdirect.o

cifs-$(CONFIG_CIFS_ROOT) += cifsroot.o

cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += smb1ops.o cifssmb.o
cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += smb1ops.o cifssmb.o cifstransport.o

cifs-$(CONFIG_CIFS_COMPRESSION) += compress.o compress/lz77.o
+11 −13
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
		return;

	cifs_dbg(VFS, "Dump pending requests:\n");
	spin_lock(&server->mid_lock);
	spin_lock(&server->mid_queue_lock);
	list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
		cifs_dbg(VFS, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n",
			 mid_entry->mid_state,
@@ -83,7 +83,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
				mid_entry->resp_buf, 62);
		}
	}
	spin_unlock(&server->mid_lock);
	spin_unlock(&server->mid_queue_lock);
#endif /* CONFIG_CIFS_DEBUG2 */
}

@@ -412,6 +412,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
	spin_lock(&cifs_tcp_ses_lock);
	list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
#ifdef CONFIG_CIFS_SMB_DIRECT
		struct smbdirect_socket *sc;
		struct smbdirect_socket_parameters *sp;
#endif

@@ -436,7 +437,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
			seq_printf(m, "\nSMBDirect transport not available");
			goto skip_rdma;
		}
		sp = &server->smbd_conn->socket.parameters;
		sc = &server->smbd_conn->socket;
		sp = &sc->parameters;

		seq_printf(m, "\nSMBDirect (in hex) protocol version: %x "
			"transport status: %x",
@@ -465,15 +467,13 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
		seq_printf(m, "\nRead Queue count_reassembly_queue: %x "
			"count_enqueue_reassembly_queue: %x "
			"count_dequeue_reassembly_queue: %x "
			"fragment_reassembly_remaining: %x "
			"reassembly_data_length: %x "
			"reassembly_queue_length: %x",
			server->smbd_conn->count_reassembly_queue,
			server->smbd_conn->count_enqueue_reassembly_queue,
			server->smbd_conn->count_dequeue_reassembly_queue,
			server->smbd_conn->fragment_reassembly_remaining,
			server->smbd_conn->reassembly_data_length,
			server->smbd_conn->reassembly_queue_length);
			sc->recv_io.reassembly.data_length,
			sc->recv_io.reassembly.queue_length);
		seq_printf(m, "\nCurrent Credits send_credits: %x "
			"receive_credits: %x receive_credit_target: %x",
			atomic_read(&server->smbd_conn->send_credits),
@@ -481,10 +481,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
			server->smbd_conn->receive_credit_target);
		seq_printf(m, "\nPending send_pending: %x ",
			atomic_read(&server->smbd_conn->send_pending));
		seq_printf(m, "\nReceive buffers count_receive_queue: %x "
			"count_empty_packet_queue: %x",
			server->smbd_conn->count_receive_queue,
			server->smbd_conn->count_empty_packet_queue);
		seq_printf(m, "\nReceive buffers count_receive_queue: %x ",
			server->smbd_conn->count_receive_queue);
		seq_printf(m, "\nMR responder_resources: %x "
			"max_frmr_depth: %x mr_type: %x",
			server->smbd_conn->responder_resources,
@@ -672,7 +670,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)

				seq_printf(m, "\n\tServer ConnectionId: 0x%llx",
					   chan_server->conn_id);
				spin_lock(&chan_server->mid_lock);
				spin_lock(&chan_server->mid_queue_lock);
				list_for_each_entry(mid_entry, &chan_server->pending_mid_q, qhead) {
					seq_printf(m, "\n\t\tState: %d com: %d pid: %d cbdata: %p mid %llu",
						   mid_entry->mid_state,
@@ -681,7 +679,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
						   mid_entry->callback_data,
						   mid_entry->mid);
				}
				spin_unlock(&chan_server->mid_lock);
				spin_unlock(&chan_server->mid_queue_lock);
			}
			spin_unlock(&ses->chan_lock);
			seq_puts(m, "\n--\n");
+3 −5
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ unsigned int global_secflags = CIFSSEC_DEF;
unsigned int GlobalCurrentXid;	/* protected by GlobalMid_Lock */
unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Lock */
unsigned int GlobalMaxActiveXid;	/* prot by GlobalMid_Lock */
spinlock_t GlobalMid_Lock; /* protects above & list operations on midQ entries */
DEFINE_SPINLOCK(GlobalMid_Lock); /* protects above & list operations on midQ entries */

/*
 *  Global counters, updated atomically
@@ -97,7 +97,7 @@ atomic_t total_buf_alloc_count;
atomic_t total_small_buf_alloc_count;
#endif/* STATS2 */
struct list_head	cifs_tcp_ses_list;
spinlock_t		cifs_tcp_ses_lock;
DEFINE_SPINLOCK(cifs_tcp_ses_lock);
static const struct super_operations cifs_super_ops;
unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
module_param(CIFSMaxBufSize, uint, 0444);
@@ -723,7 +723,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
	else
		seq_puts(s, ",nativesocket");
	seq_show_option(s, "symlink",
			cifs_symlink_type_str(get_cifs_symlink_type(cifs_sb)));
			cifs_symlink_type_str(cifs_symlink_type(cifs_sb)));

	seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize);
	seq_printf(s, ",wsize=%u", cifs_sb->ctx->wsize);
@@ -1863,8 +1863,6 @@ init_cifs(void)
	GlobalCurrentXid = 0;
	GlobalTotalActiveXid = 0;
	GlobalMaxActiveXid = 0;
	spin_lock_init(&cifs_tcp_ses_lock);
	spin_lock_init(&GlobalMid_Lock);

	cifs_lock_secret = get_random_u32();

+13 −10
Original line number Diff line number Diff line
@@ -732,7 +732,8 @@ struct TCP_Server_Info {
#endif
	wait_queue_head_t response_q;
	wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
	spinlock_t mid_lock;  /* protect mid queue and it's entries */
	spinlock_t mid_queue_lock;  /* protect mid queue */
	spinlock_t mid_counter_lock;
	struct list_head pending_mid_q;
	bool noblocksnd;		/* use blocking sendmsg */
	bool noautotune;		/* do not autotune send buf sizes */
@@ -770,7 +771,7 @@ struct TCP_Server_Info {
	/* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */
	unsigned int capabilities; /* selective disabling of caps by smb sess */
	int timeAdj;  /* Adjust for difference in server time zone in sec */
	__u64 CurrentMid;         /* multiplex id - rotating counter, protected by GlobalMid_Lock */
	__u64 current_mid;	/* multiplex id - rotating counter, protected by mid_counter_lock */
	char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */
	/* 16th byte of RFC1001 workstation name is always null */
	char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
@@ -1729,9 +1730,10 @@ struct mid_q_entry {
	unsigned int resp_buf_size;
	int mid_state;	/* wish this were enum but can not pass to wait_event */
	int mid_rc;		/* rc for MID_RC */
	unsigned int mid_flags;
	__le16 command;		/* smb command code */
	unsigned int optype;	/* operation type */
	bool wait_cancelled:1;  /* Cancelled while waiting for response */
	bool deleted_from_q:1;  /* Whether Mid has been dequeued frem pending_mid_q */
	bool large_buf:1;	/* if valid response, is pointer to large buf */
	bool multiRsp:1;	/* multiple trans2 responses for one request  */
	bool multiEnd:1;	/* both received */
@@ -1893,10 +1895,6 @@ static inline bool is_replayable_error(int error)
#define   MID_RESPONSE_READY 0x40 /* ready for other process handle the rsp */
#define   MID_RC             0x80 /* mid_rc contains custom rc */

/* Flags */
#define   MID_WAIT_CANCELLED	 1 /* Cancelled while waiting for response */
#define   MID_DELETED            2 /* Mid has been dequeued/deleted */

/* Types of response buffer returned from SendReceive2 */
#define   CIFS_NO_BUFFER        0    /* Response buffer not returned */
#define   CIFS_SMALL_BUFFER     1
@@ -2007,9 +2005,9 @@ require use of the stronger protocol */
 *				GlobalCurrentXid
 *				GlobalTotalActiveXid
 * TCP_Server_Info->srv_lock	(anything in struct not protected by another lock and can change)
 * TCP_Server_Info->mid_lock	TCP_Server_Info->pending_mid_q	cifs_get_tcp_session
 *				->CurrentMid
 *				(any changes in mid_q_entry fields)
 * TCP_Server_Info->mid_queue_lock	TCP_Server_Info->pending_mid_q	cifs_get_tcp_session
 *				mid_q_entry->deleted_from_q
 * TCP_Server_Info->mid_counter_lock    TCP_Server_Info->current_mid    cifs_get_tcp_session
 * TCP_Server_Info->req_lock	TCP_Server_Info->in_flight	cifs_get_tcp_session
 *				->credits
 *				->echo_credits
@@ -2377,4 +2375,9 @@ static inline bool cifs_netbios_name(const char *name, size_t namelen)
	return ret;
}

#define CIFS_REPARSE_SUPPORT(tcon) \
	((tcon)->posix_extensions || \
	 (le32_to_cpu((tcon)->fsAttrInfo.Attributes) & \
	  FILE_SUPPORTS_REPARSE_POINTS))

#endif	/* _CIFS_GLOB_H */
+15 −0
Original line number Diff line number Diff line
@@ -116,16 +116,31 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
			int * /* bytes returned */ , const int);
extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
			    char *in_buf, int flags);
int cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server);
extern struct mid_q_entry *cifs_setup_request(struct cifs_ses *,
				struct TCP_Server_Info *,
				struct smb_rqst *);
extern struct mid_q_entry *cifs_setup_async_request(struct TCP_Server_Info *,
						struct smb_rqst *);
int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
		    struct smb_rqst *rqst);
extern int cifs_check_receive(struct mid_q_entry *mid,
			struct TCP_Server_Info *server, bool log_error);
int wait_for_free_request(struct TCP_Server_Info *server, const int flags,
			  unsigned int *instance);
extern int cifs_wait_mtu_credits(struct TCP_Server_Info *server,
				 size_t size, size_t *num,
				 struct cifs_credits *credits);

static inline int
send_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
	    struct mid_q_entry *mid)
{
	return server->ops->send_cancel ?
				server->ops->send_cancel(server, rqst, mid) : 0;
}

int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ);
extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
			struct kvec *, int /* nvec to send */,
			int * /* type of buf returned */, const int flags,
Loading