cifs: multichannel: move channel selection above transport layer

Move the channel (TCP_Server_Info*) selection from the tranport
layer to higher in the call stack so that:

- credit handling is done with the server that will actually be used
  to send.
  * ->wait_mtu_credit
  * ->set_credits / set_credits
  * ->add_credits / add_credits
  * add_credits_and_wake_if

- potential reconnection (smb2_reconnect) done when initializing a
  request is checked and done with the server that will actually be
  used to send.

To do this:

- remove the cifs_pick_channel() call out of compound_send_recv()

- select channel and pass it down by adding a cifs_pick_channel(ses)
  call in:
  - smb311_posix_mkdir
  - SMB2_open
  - SMB2_ioctl
  - __SMB2_close
  - query_info
  - SMB2_change_notify
  - SMB2_flush
  - smb2_async_readv  (if none provided in context param)
  - SMB2_read         (if none provided in context param)
  - smb2_async_writev (if none provided in context param)
  - SMB2_write        (if none provided in context param)
  - SMB2_query_directory
  - send_set_info
  - SMB2_oplock_break
  - SMB311_posix_qfs_info
  - SMB2_QFS_info
  - SMB2_QFS_attr
  - smb2_lockv
  - SMB2_lease_break
    - smb2_compound_op
  - smb2_set_ea
  - smb2_ioctl_query_info
  - smb2_query_dir_first
  - smb2_query_info_comound
  - smb2_query_symlink
  - cifs_writepages
  - cifs_write_from_iter
  - cifs_send_async_read
  - cifs_read
  - cifs_readpages

- add TCP_Server_Info *server param argument to:
  - cifs_send_recv
  - compound_send_recv
  - SMB2_open_init
  - SMB2_query_info_init
  - SMB2_set_info_init
  - SMB2_close_init
  - SMB2_ioctl_init
  - smb2_iotcl_req_init
  - SMB2_query_directory_init
  - SMB2_notify_init
  - SMB2_flush_init
  - build_qfs_info_req
  - smb2_hdr_assemble
  - smb2_reconnect
  - fill_small_buf
  - smb2_plain_req_init
  - __smb2_plain_req_init

The read/write codepath is different than the rest as it is using
pages, io iterators and async calls. To deal with those we add a
server pointer in the cifs_writedata/cifs_readdata/cifs_io_parms
context struct and set it in:

- cifs_writepages      (wdata)
- cifs_write_from_iter (wdata)
- cifs_readpages       (rdata)
- cifs_send_async_read (rdata)

The [rw]data->server pointer is eventually copied to
cifs_io_parms->server to pass it down to SMB2_read/SMB2_write.
If SMB2_read/SMB2_write is called from a different place that doesn't
set the server field it will pick a channel.

Some places do not pick a channel and just use ses->server or
cifs_ses_server(ses). All cifs_ses_server(ses) calls are in codepaths
involving negprot/sess.setup.

- SMB2_negotiate         (binding channel)
- SMB2_sess_alloc_buffer (binding channel)
- SMB2_echo              (uses provided one)
- SMB2_logoff            (uses master)
- SMB2_tdis              (uses master)

(list not exhaustive)

Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index fa86c78..0a116fc 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -74,6 +74,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
 	struct cifs_fid fid;
 	struct cifs_ses *ses = tcon->ses;
+	struct TCP_Server_Info *server;
 	int num_rqst = 0;
 	int resp_buftype[3];
 	struct smb2_query_info_rsp *qi_rsp = NULL;
@@ -89,6 +90,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 	rqst = &vars->rqst[0];
 	rsp_iov = &vars->rsp_iov[0];
 
+	server = cifs_pick_channel(ses);
+
 	if (smb3_encryption_required(tcon))
 		flags |= CIFS_TRANSFORM_REQ;
 
@@ -115,7 +118,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 
 	rqst[num_rqst].rq_iov = &vars->open_iov[0];
 	rqst[num_rqst].rq_nvec = SMB2_CREATE_IOV_SIZE;
-	rc = SMB2_open_init(tcon, &rqst[num_rqst], &oplock, &vars->oparms,
+	rc = SMB2_open_init(tcon, server,
+			    &rqst[num_rqst], &oplock, &vars->oparms,
 			    utf16_path);
 	kfree(utf16_path);
 	if (rc)
@@ -133,7 +137,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 		rqst[num_rqst].rq_nvec = 1;
 
 		if (cfile)
-			rc = SMB2_query_info_init(tcon, &rqst[num_rqst],
+			rc = SMB2_query_info_init(tcon, server,
+				&rqst[num_rqst],
 				cfile->fid.persistent_fid,
 				cfile->fid.volatile_fid,
 				FILE_ALL_INFORMATION,
@@ -141,10 +146,11 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 				sizeof(struct smb2_file_all_info) +
 					  PATH_MAX * 2, 0, NULL);
 		else {
-			rc = SMB2_query_info_init(tcon, &rqst[num_rqst],
+			rc = SMB2_query_info_init(tcon, server,
+				&rqst[num_rqst],
 				COMPOUND_FID,
 				COMPOUND_FID,
-				 FILE_ALL_INFORMATION,
+				FILE_ALL_INFORMATION,
 				SMB2_O_INFO_FILE, 0,
 				sizeof(struct smb2_file_all_info) +
 					  PATH_MAX * 2, 0, NULL);
@@ -177,7 +183,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 		size[0] = 1; /* sizeof __u8 See MS-FSCC section 2.4.11 */
 		data[0] = &delete_pending[0];
 
-		rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
+		rc = SMB2_set_info_init(tcon, server,
+					&rqst[num_rqst], COMPOUND_FID,
 					COMPOUND_FID, current->tgid,
 					FILE_DISPOSITION_INFORMATION,
 					SMB2_O_INFO_FILE, 0, data, size);
@@ -194,7 +201,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 		size[0] = 8; /* sizeof __le64 */
 		data[0] = ptr;
 
-		rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
+		rc = SMB2_set_info_init(tcon, server,
+					&rqst[num_rqst], COMPOUND_FID,
 					COMPOUND_FID, current->tgid,
 					FILE_END_OF_FILE_INFORMATION,
 					SMB2_O_INFO_FILE, 0, data, size);
@@ -213,13 +221,15 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 		data[0] = ptr;
 
 		if (cfile)
-			rc = SMB2_set_info_init(tcon, &rqst[num_rqst],
+			rc = SMB2_set_info_init(tcon, server,
+				&rqst[num_rqst],
 				cfile->fid.persistent_fid,
 				cfile->fid.volatile_fid, current->tgid,
 				FILE_BASIC_INFORMATION,
 				SMB2_O_INFO_FILE, 0, data, size);
 		else {
-			rc = SMB2_set_info_init(tcon, &rqst[num_rqst],
+			rc = SMB2_set_info_init(tcon, server,
+				&rqst[num_rqst],
 				COMPOUND_FID,
 				COMPOUND_FID, current->tgid,
 				FILE_BASIC_INFORMATION,
@@ -253,13 +263,15 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 		data[1] = (__le16 *)ptr;
 
 		if (cfile)
-			rc = SMB2_set_info_init(tcon, &rqst[num_rqst],
+			rc = SMB2_set_info_init(tcon, server,
+						&rqst[num_rqst],
 						cfile->fid.persistent_fid,
 						cfile->fid.volatile_fid,
 					current->tgid, FILE_RENAME_INFORMATION,
 					SMB2_O_INFO_FILE, 0, data, size);
 		else {
-			rc = SMB2_set_info_init(tcon, &rqst[num_rqst],
+			rc = SMB2_set_info_init(tcon, server,
+					&rqst[num_rqst],
 					COMPOUND_FID, COMPOUND_FID,
 					current->tgid, FILE_RENAME_INFORMATION,
 					SMB2_O_INFO_FILE, 0, data, size);
@@ -289,7 +301,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 		size[1] = len + 2 /* null */;
 		data[1] = (__le16 *)ptr;
 
-		rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
+		rc = SMB2_set_info_init(tcon, server,
+					&rqst[num_rqst], COMPOUND_FID,
 					COMPOUND_FID, current->tgid,
 					FILE_LINK_INFORMATION,
 					SMB2_O_INFO_FILE, 0, data, size);
@@ -312,7 +325,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 	/* Close */
 	rqst[num_rqst].rq_iov = &vars->close_iov[0];
 	rqst[num_rqst].rq_nvec = 1;
-	rc = SMB2_close_init(tcon, &rqst[num_rqst], COMPOUND_FID,
+	rc = SMB2_close_init(tcon, server,
+			     &rqst[num_rqst], COMPOUND_FID,
 			     COMPOUND_FID, false);
 	smb2_set_related(&rqst[num_rqst]);
 	if (rc)
@@ -323,11 +337,13 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
 	if (cfile) {
 		cifsFileInfo_put(cfile);
 		cfile = NULL;
-		rc = compound_send_recv(xid, ses, flags, num_rqst - 2,
+		rc = compound_send_recv(xid, ses, server,
+					flags, num_rqst - 2,
 					&rqst[1], &resp_buftype[1],
 					&rsp_iov[1]);
 	} else
-		rc = compound_send_recv(xid, ses, flags, num_rqst,
+		rc = compound_send_recv(xid, ses, server,
+					flags, num_rqst,
 					rqst, resp_buftype,
 					rsp_iov);