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>
This commit is contained in:
parent
7c06514afd
commit
352d96f3ac
|
@ -1335,6 +1335,7 @@ struct cifs_io_parms {
|
|||
__u64 offset;
|
||||
unsigned int length;
|
||||
struct cifs_tcon *tcon;
|
||||
struct TCP_Server_Info *server;
|
||||
};
|
||||
|
||||
struct cifs_aio_ctx {
|
||||
|
@ -1382,6 +1383,7 @@ struct cifs_readdata {
|
|||
struct cifs_readdata *rdata,
|
||||
struct iov_iter *iter);
|
||||
struct kvec iov[2];
|
||||
struct TCP_Server_Info *server;
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
struct smbd_mr *mr;
|
||||
#endif
|
||||
|
@ -1408,6 +1410,7 @@ struct cifs_writedata {
|
|||
pid_t pid;
|
||||
unsigned int bytes;
|
||||
int result;
|
||||
struct TCP_Server_Info *server;
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
struct smbd_mr *mr;
|
||||
#endif
|
||||
|
|
|
@ -98,9 +98,11 @@ extern int cifs_call_async(struct TCP_Server_Info *server,
|
|||
const struct cifs_credits *exist_credits);
|
||||
extern struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses);
|
||||
extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
|
||||
struct TCP_Server_Info *server,
|
||||
struct smb_rqst *rqst, int *resp_buf_type,
|
||||
const int flags, struct kvec *resp_iov);
|
||||
extern int compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
|
||||
struct TCP_Server_Info *server,
|
||||
const int flags, const int num_rqst,
|
||||
struct smb_rqst *rqst, int *resp_buf_type,
|
||||
struct kvec *resp_iov);
|
||||
|
|
|
@ -2292,8 +2292,6 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
|
|||
struct address_space *mapping, struct writeback_control *wbc)
|
||||
{
|
||||
int rc;
|
||||
struct TCP_Server_Info *server =
|
||||
tlink_tcon(wdata->cfile->tlink)->ses->server;
|
||||
|
||||
wdata->sync_mode = wbc->sync_mode;
|
||||
wdata->nr_pages = nr_pages;
|
||||
|
@ -2305,14 +2303,15 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
|
|||
wdata->bytes = ((nr_pages - 1) * PAGE_SIZE) + wdata->tailsz;
|
||||
wdata->pid = wdata->cfile->pid;
|
||||
|
||||
rc = adjust_credits(server, &wdata->credits, wdata->bytes);
|
||||
rc = adjust_credits(wdata->server, &wdata->credits, wdata->bytes);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (wdata->cfile->invalidHandle)
|
||||
rc = -EAGAIN;
|
||||
else
|
||||
rc = server->ops->async_writev(wdata, cifs_writedata_release);
|
||||
rc = wdata->server->ops->async_writev(wdata,
|
||||
cifs_writedata_release);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -2349,7 +2348,8 @@ static int cifs_writepages(struct address_space *mapping,
|
|||
range_whole = true;
|
||||
scanned = true;
|
||||
}
|
||||
server = cifs_sb_master_tcon(cifs_sb)->ses->server;
|
||||
server = cifs_pick_channel(cifs_sb_master_tcon(cifs_sb)->ses);
|
||||
|
||||
retry:
|
||||
while (!done && index <= end) {
|
||||
unsigned int i, nr_pages, found_pages, wsize;
|
||||
|
@ -2403,6 +2403,7 @@ retry:
|
|||
|
||||
wdata->credits = credits_on_stack;
|
||||
wdata->cfile = cfile;
|
||||
wdata->server = server;
|
||||
cfile = NULL;
|
||||
|
||||
if (!wdata->cfile) {
|
||||
|
@ -2806,8 +2807,7 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
|
|||
unsigned int wsize;
|
||||
struct cifs_credits credits;
|
||||
int rc;
|
||||
struct TCP_Server_Info *server =
|
||||
tlink_tcon(wdata->cfile->tlink)->ses->server;
|
||||
struct TCP_Server_Info *server = wdata->server;
|
||||
|
||||
do {
|
||||
if (wdata->cfile->invalidHandle) {
|
||||
|
@ -2893,7 +2893,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
|
|||
else
|
||||
pid = current->tgid;
|
||||
|
||||
server = tlink_tcon(open_file->tlink)->ses->server;
|
||||
server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
|
||||
xid = get_xid();
|
||||
|
||||
do {
|
||||
|
@ -2997,6 +2997,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
|
|||
wdata->nr_pages = nr_pages;
|
||||
wdata->offset = (__u64)offset;
|
||||
wdata->cfile = cifsFileInfo_get(open_file);
|
||||
wdata->server = server;
|
||||
wdata->pid = pid;
|
||||
wdata->bytes = cur_len;
|
||||
wdata->pagesz = PAGE_SIZE;
|
||||
|
@ -3538,8 +3539,10 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
|
|||
unsigned int rsize;
|
||||
struct cifs_credits credits;
|
||||
int rc;
|
||||
struct TCP_Server_Info *server =
|
||||
tlink_tcon(rdata->cfile->tlink)->ses->server;
|
||||
struct TCP_Server_Info *server;
|
||||
|
||||
/* XXX: should we pick a new channel here? */
|
||||
server = rdata->server;
|
||||
|
||||
do {
|
||||
if (rdata->cfile->invalidHandle) {
|
||||
|
@ -3618,7 +3621,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
|
|||
size_t start;
|
||||
struct iov_iter direct_iov = ctx->iter;
|
||||
|
||||
server = tlink_tcon(open_file->tlink)->ses->server;
|
||||
server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
|
||||
pid = open_file->pid;
|
||||
|
@ -3702,6 +3705,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
|
|||
rdata->tailsz = PAGE_SIZE;
|
||||
}
|
||||
|
||||
rdata->server = server;
|
||||
rdata->cfile = cifsFileInfo_get(open_file);
|
||||
rdata->nr_pages = npages;
|
||||
rdata->offset = offset;
|
||||
|
@ -4031,7 +4035,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
|
|||
}
|
||||
open_file = file->private_data;
|
||||
tcon = tlink_tcon(open_file->tlink);
|
||||
server = tcon->ses->server;
|
||||
server = cifs_pick_channel(tcon->ses);
|
||||
|
||||
if (!server->ops->sync_read) {
|
||||
free_xid(xid);
|
||||
|
@ -4070,6 +4074,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
|
|||
io_parms.tcon = tcon;
|
||||
io_parms.offset = *offset;
|
||||
io_parms.length = current_read_size;
|
||||
io_parms.server = server;
|
||||
rc = server->ops->sync_read(xid, &open_file->fid, &io_parms,
|
||||
&bytes_read, &cur_offset,
|
||||
&buf_type);
|
||||
|
@ -4372,7 +4377,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
|
|||
pid = current->tgid;
|
||||
|
||||
rc = 0;
|
||||
server = tlink_tcon(open_file->tlink)->ses->server;
|
||||
server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
|
||||
|
||||
cifs_dbg(FYI, "%s: file=%p mapping=%p num_pages=%u\n",
|
||||
__func__, file, mapping, num_pages);
|
||||
|
@ -4443,6 +4448,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
|
|||
}
|
||||
|
||||
rdata->cfile = cifsFileInfo_get(open_file);
|
||||
rdata->server = server;
|
||||
rdata->mapping = mapping;
|
||||
rdata->offset = offset;
|
||||
rdata->bytes = bytes;
|
||||
|
|
|
@ -450,7 +450,7 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
|||
int rc;
|
||||
struct cifs_fid fid;
|
||||
struct cifs_open_parms oparms;
|
||||
struct cifs_io_parms io_parms;
|
||||
struct cifs_io_parms io_parms = {0};
|
||||
__le16 *utf16_path;
|
||||
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
|
||||
struct kvec iov[2];
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -708,7 +708,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.fid = pfid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, &utf16_path);
|
||||
rc = SMB2_open_init(tcon, server,
|
||||
&rqst[0], &oplock, &oparms, &utf16_path);
|
||||
if (rc)
|
||||
goto oshr_free;
|
||||
smb2_set_next_command(tcon, &rqst[0]);
|
||||
|
@ -717,7 +718,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
|
|||
rqst[1].rq_iov = qi_iov;
|
||||
rqst[1].rq_nvec = 1;
|
||||
|
||||
rc = SMB2_query_info_init(tcon, &rqst[1], COMPOUND_FID,
|
||||
rc = SMB2_query_info_init(tcon, server,
|
||||
&rqst[1], COMPOUND_FID,
|
||||
COMPOUND_FID, FILE_ALL_INFORMATION,
|
||||
SMB2_O_INFO_FILE, 0,
|
||||
sizeof(struct smb2_file_all_info) +
|
||||
|
@ -727,7 +729,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
|
|||
|
||||
smb2_set_related(&rqst[1]);
|
||||
|
||||
rc = compound_send_recv(xid, ses, flags, 2, rqst,
|
||||
rc = compound_send_recv(xid, ses, server,
|
||||
flags, 2, rqst,
|
||||
resp_buftype, rsp_iov);
|
||||
mutex_lock(&tcon->crfid.fid_mutex);
|
||||
|
||||
|
@ -1102,6 +1105,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
struct cifs_ses *ses = tcon->ses;
|
||||
struct TCP_Server_Info *server = cifs_pick_channel(ses);
|
||||
__le16 *utf16_path = NULL;
|
||||
int ea_name_len = strlen(ea_name);
|
||||
int flags = 0;
|
||||
|
@ -1190,7 +1194,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path);
|
||||
rc = SMB2_open_init(tcon, server,
|
||||
&rqst[0], &oplock, &oparms, utf16_path);
|
||||
if (rc)
|
||||
goto sea_exit;
|
||||
smb2_set_next_command(tcon, &rqst[0]);
|
||||
|
@ -1216,7 +1221,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
size[0] = len;
|
||||
data[0] = ea;
|
||||
|
||||
rc = SMB2_set_info_init(tcon, &rqst[1], COMPOUND_FID,
|
||||
rc = SMB2_set_info_init(tcon, server,
|
||||
&rqst[1], COMPOUND_FID,
|
||||
COMPOUND_FID, current->tgid,
|
||||
FILE_FULL_EA_INFORMATION,
|
||||
SMB2_O_INFO_FILE, 0, data, size);
|
||||
|
@ -1228,10 +1234,12 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
memset(&close_iov, 0, sizeof(close_iov));
|
||||
rqst[2].rq_iov = close_iov;
|
||||
rqst[2].rq_nvec = 1;
|
||||
rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
|
||||
rc = SMB2_close_init(tcon, server,
|
||||
&rqst[2], COMPOUND_FID, COMPOUND_FID, false);
|
||||
smb2_set_related(&rqst[2]);
|
||||
|
||||
rc = compound_send_recv(xid, ses, flags, 3, rqst,
|
||||
rc = compound_send_recv(xid, ses, server,
|
||||
flags, 3, rqst,
|
||||
resp_buftype, rsp_iov);
|
||||
/* no need to bump num_remote_opens because handle immediately closed */
|
||||
|
||||
|
@ -1473,6 +1481,7 @@ smb2_ioctl_query_info(const unsigned int xid,
|
|||
struct smb_rqst *rqst;
|
||||
struct kvec *rsp_iov;
|
||||
struct cifs_ses *ses = tcon->ses;
|
||||
struct TCP_Server_Info *server = cifs_pick_channel(ses);
|
||||
char __user *arg = (char __user *)p;
|
||||
struct smb_query_info qi;
|
||||
struct smb_query_info __user *pqi;
|
||||
|
@ -1505,7 +1514,7 @@ smb2_ioctl_query_info(const unsigned int xid,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!ses || !(ses->server)) {
|
||||
if (!ses || !server) {
|
||||
kfree(vars);
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -1552,7 +1561,8 @@ smb2_ioctl_query_info(const unsigned int xid,
|
|||
oparms.desired_access = FILE_READ_ATTRIBUTES | READ_CONTROL;
|
||||
}
|
||||
|
||||
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, path);
|
||||
rc = SMB2_open_init(tcon, server,
|
||||
&rqst[0], &oplock, &oparms, path);
|
||||
if (rc)
|
||||
goto iqinf_exit;
|
||||
smb2_set_next_command(tcon, &rqst[0]);
|
||||
|
@ -1566,7 +1576,8 @@ smb2_ioctl_query_info(const unsigned int xid,
|
|||
rqst[1].rq_iov = &vars->io_iov[0];
|
||||
rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
|
||||
|
||||
rc = SMB2_ioctl_init(tcon, &rqst[1],
|
||||
rc = SMB2_ioctl_init(tcon, server,
|
||||
&rqst[1],
|
||||
COMPOUND_FID, COMPOUND_FID,
|
||||
qi.info_type, true, buffer,
|
||||
qi.output_buffer_length,
|
||||
|
@ -1585,7 +1596,8 @@ smb2_ioctl_query_info(const unsigned int xid,
|
|||
size[0] = 8;
|
||||
data[0] = buffer;
|
||||
|
||||
rc = SMB2_set_info_init(tcon, &rqst[1],
|
||||
rc = SMB2_set_info_init(tcon, server,
|
||||
&rqst[1],
|
||||
COMPOUND_FID, COMPOUND_FID,
|
||||
current->tgid,
|
||||
FILE_END_OF_FILE_INFORMATION,
|
||||
|
@ -1595,7 +1607,8 @@ smb2_ioctl_query_info(const unsigned int xid,
|
|||
rqst[1].rq_iov = &vars->qi_iov[0];
|
||||
rqst[1].rq_nvec = 1;
|
||||
|
||||
rc = SMB2_query_info_init(tcon, &rqst[1], COMPOUND_FID,
|
||||
rc = SMB2_query_info_init(tcon, server,
|
||||
&rqst[1], COMPOUND_FID,
|
||||
COMPOUND_FID, qi.file_info_class,
|
||||
qi.info_type, qi.additional_information,
|
||||
qi.input_buffer_length,
|
||||
|
@ -1615,12 +1628,14 @@ smb2_ioctl_query_info(const unsigned int xid,
|
|||
rqst[2].rq_iov = &vars->close_iov[0];
|
||||
rqst[2].rq_nvec = 1;
|
||||
|
||||
rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
|
||||
rc = SMB2_close_init(tcon, server,
|
||||
&rqst[2], COMPOUND_FID, COMPOUND_FID, false);
|
||||
if (rc)
|
||||
goto iqinf_exit;
|
||||
smb2_set_related(&rqst[2]);
|
||||
|
||||
rc = compound_send_recv(xid, ses, flags, 3, rqst,
|
||||
rc = compound_send_recv(xid, ses, server,
|
||||
flags, 3, rqst,
|
||||
resp_buftype, rsp_iov);
|
||||
if (rc)
|
||||
goto iqinf_exit;
|
||||
|
@ -2172,6 +2187,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
struct cifs_open_parms oparms;
|
||||
struct smb2_query_directory_rsp *qd_rsp = NULL;
|
||||
struct smb2_create_rsp *op_rsp = NULL;
|
||||
struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
|
||||
|
||||
utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
|
||||
if (!utf16_path)
|
||||
|
@ -2196,7 +2212,8 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.fid = fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path);
|
||||
rc = SMB2_open_init(tcon, server,
|
||||
&rqst[0], &oplock, &oparms, utf16_path);
|
||||
if (rc)
|
||||
goto qdf_free;
|
||||
smb2_set_next_command(tcon, &rqst[0]);
|
||||
|
@ -2209,7 +2226,8 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
rqst[1].rq_iov = qd_iov;
|
||||
rqst[1].rq_nvec = SMB2_QUERY_DIRECTORY_IOV_SIZE;
|
||||
|
||||
rc = SMB2_query_directory_init(xid, tcon, &rqst[1],
|
||||
rc = SMB2_query_directory_init(xid, tcon, server,
|
||||
&rqst[1],
|
||||
COMPOUND_FID, COMPOUND_FID,
|
||||
0, srch_inf->info_level);
|
||||
if (rc)
|
||||
|
@ -2217,7 +2235,8 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
|
||||
smb2_set_related(&rqst[1]);
|
||||
|
||||
rc = compound_send_recv(xid, tcon->ses, flags, 2, rqst,
|
||||
rc = compound_send_recv(xid, tcon->ses, server,
|
||||
flags, 2, rqst,
|
||||
resp_buftype, rsp_iov);
|
||||
|
||||
/* If the open failed there is nothing to do */
|
||||
|
@ -2422,6 +2441,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
struct cifs_ses *ses = tcon->ses;
|
||||
struct TCP_Server_Info *server = cifs_pick_channel(ses);
|
||||
int flags = 0;
|
||||
struct smb_rqst rqst[3];
|
||||
int resp_buftype[3];
|
||||
|
@ -2452,7 +2472,8 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path);
|
||||
rc = SMB2_open_init(tcon, server,
|
||||
&rqst[0], &oplock, &oparms, utf16_path);
|
||||
if (rc)
|
||||
goto qic_exit;
|
||||
smb2_set_next_command(tcon, &rqst[0]);
|
||||
|
@ -2461,7 +2482,8 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
rqst[1].rq_iov = qi_iov;
|
||||
rqst[1].rq_nvec = 1;
|
||||
|
||||
rc = SMB2_query_info_init(tcon, &rqst[1], COMPOUND_FID, COMPOUND_FID,
|
||||
rc = SMB2_query_info_init(tcon, server,
|
||||
&rqst[1], COMPOUND_FID, COMPOUND_FID,
|
||||
class, type, 0,
|
||||
output_len, 0,
|
||||
NULL);
|
||||
|
@ -2474,12 +2496,14 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
rqst[2].rq_iov = close_iov;
|
||||
rqst[2].rq_nvec = 1;
|
||||
|
||||
rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
|
||||
rc = SMB2_close_init(tcon, server,
|
||||
&rqst[2], COMPOUND_FID, COMPOUND_FID, false);
|
||||
if (rc)
|
||||
goto qic_exit;
|
||||
smb2_set_related(&rqst[2]);
|
||||
|
||||
rc = compound_send_recv(xid, ses, flags, 3, rqst,
|
||||
rc = compound_send_recv(xid, ses, server,
|
||||
flags, 3, rqst,
|
||||
resp_buftype, rsp_iov);
|
||||
if (rc) {
|
||||
free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
|
||||
|
@ -2811,6 +2835,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
struct kvec err_iov = {NULL, 0};
|
||||
struct smb2_err_rsp *err_buf = NULL;
|
||||
struct smb2_symlink_err_rsp *symlink;
|
||||
struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
|
||||
unsigned int sub_len;
|
||||
unsigned int sub_offset;
|
||||
unsigned int print_len;
|
||||
|
@ -2856,7 +2881,8 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path);
|
||||
rc = SMB2_open_init(tcon, server,
|
||||
&rqst[0], &oplock, &oparms, utf16_path);
|
||||
if (rc)
|
||||
goto querty_exit;
|
||||
smb2_set_next_command(tcon, &rqst[0]);
|
||||
|
@ -2867,7 +2893,8 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
rqst[1].rq_iov = io_iov;
|
||||
rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
|
||||
|
||||
rc = SMB2_ioctl_init(tcon, &rqst[1], fid.persistent_fid,
|
||||
rc = SMB2_ioctl_init(tcon, server,
|
||||
&rqst[1], fid.persistent_fid,
|
||||
fid.volatile_fid, FSCTL_GET_REPARSE_POINT,
|
||||
true /* is_fctl */, NULL, 0,
|
||||
CIFSMaxBufSize -
|
||||
|
@ -2885,13 +2912,15 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
rqst[2].rq_iov = close_iov;
|
||||
rqst[2].rq_nvec = 1;
|
||||
|
||||
rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
|
||||
rc = SMB2_close_init(tcon, server,
|
||||
&rqst[2], COMPOUND_FID, COMPOUND_FID, false);
|
||||
if (rc)
|
||||
goto querty_exit;
|
||||
|
||||
smb2_set_related(&rqst[2]);
|
||||
|
||||
rc = compound_send_recv(xid, tcon->ses, flags, 3, rqst,
|
||||
rc = compound_send_recv(xid, tcon->ses, server,
|
||||
flags, 3, rqst,
|
||||
resp_buftype, rsp_iov);
|
||||
|
||||
create_rsp = rsp_iov[0].iov_base;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -143,7 +143,9 @@ extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms,
|
|||
struct smb2_file_all_info *buf,
|
||||
struct create_posix_rsp *posix,
|
||||
struct kvec *err_iov, int *resp_buftype);
|
||||
extern int SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
|
||||
extern int SMB2_open_init(struct cifs_tcon *tcon,
|
||||
struct TCP_Server_Info *server,
|
||||
struct smb_rqst *rqst,
|
||||
__u8 *oplock, struct cifs_open_parms *oparms,
|
||||
__le16 *path);
|
||||
extern void SMB2_open_free(struct smb_rqst *rqst);
|
||||
|
@ -151,7 +153,9 @@ extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
u64 persistent_fid, u64 volatile_fid, u32 opcode,
|
||||
bool is_fsctl, char *in_data, u32 indatalen, u32 maxoutlen,
|
||||
char **out_data, u32 *plen /* returned data len */);
|
||||
extern int SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
|
||||
extern int SMB2_ioctl_init(struct cifs_tcon *tcon,
|
||||
struct TCP_Server_Info *server,
|
||||
struct smb_rqst *rqst,
|
||||
u64 persistent_fid, u64 volatile_fid, u32 opcode,
|
||||
bool is_fsctl, char *in_data, u32 indatalen,
|
||||
__u32 max_response_size);
|
||||
|
@ -165,19 +169,25 @@ extern int __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
struct smb2_file_network_open_info *pbuf);
|
||||
extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
u64 persistent_file_id, u64 volatile_file_id);
|
||||
extern int SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
|
||||
u64 persistent_fid, u64 volatile_fid, bool query_attrs);
|
||||
extern int SMB2_close_init(struct cifs_tcon *tcon,
|
||||
struct TCP_Server_Info *server,
|
||||
struct smb_rqst *rqst,
|
||||
u64 persistent_fid, u64 volatile_fid,
|
||||
bool query_attrs);
|
||||
extern void SMB2_close_free(struct smb_rqst *rqst);
|
||||
extern int SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
u64 persistent_file_id, u64 volatile_file_id);
|
||||
extern int SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst,
|
||||
struct cifs_tcon *tcon,
|
||||
struct TCP_Server_Info *server,
|
||||
u64 persistent_file_id, u64 volatile_file_id);
|
||||
extern void SMB2_flush_free(struct smb_rqst *rqst);
|
||||
extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
u64 persistent_file_id, u64 volatile_file_id,
|
||||
struct smb2_file_all_info *data);
|
||||
extern int SMB2_query_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
|
||||
extern int SMB2_query_info_init(struct cifs_tcon *tcon,
|
||||
struct TCP_Server_Info *server,
|
||||
struct smb_rqst *rqst,
|
||||
u64 persistent_fid, u64 volatile_fid,
|
||||
u8 info_class, u8 info_type,
|
||||
u32 additional_info, size_t output_len,
|
||||
|
@ -201,6 +211,7 @@ extern int SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
u64 persistent_fid, u64 volatile_fid, int index,
|
||||
struct cifs_search_info *srch_inf);
|
||||
extern int SMB2_query_directory_init(unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct TCP_Server_Info *server,
|
||||
struct smb_rqst *rqst,
|
||||
u64 persistent_fid, u64 volatile_fid,
|
||||
int index, int info_level);
|
||||
|
@ -208,7 +219,9 @@ extern void SMB2_query_directory_free(struct smb_rqst *rqst);
|
|||
extern int SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
u64 persistent_fid, u64 volatile_fid, u32 pid,
|
||||
__le64 *eof);
|
||||
extern int SMB2_set_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
|
||||
extern int SMB2_set_info_init(struct cifs_tcon *tcon,
|
||||
struct TCP_Server_Info *server,
|
||||
struct smb_rqst *rqst,
|
||||
u64 persistent_fid, u64 volatile_fid, u32 pid,
|
||||
u8 info_class, u8 info_type, u32 additional_info,
|
||||
void **data, unsigned int *size);
|
||||
|
|
|
@ -1020,6 +1020,7 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
|
|||
|
||||
int
|
||||
compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
|
||||
struct TCP_Server_Info *server,
|
||||
const int flags, const int num_rqst, struct smb_rqst *rqst,
|
||||
int *resp_buf_type, struct kvec *resp_iov)
|
||||
{
|
||||
|
@ -1031,20 +1032,17 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
|
|||
};
|
||||
unsigned int instance;
|
||||
char *buf;
|
||||
struct TCP_Server_Info *server;
|
||||
|
||||
optype = flags & CIFS_OP_MASK;
|
||||
|
||||
for (i = 0; i < num_rqst; i++)
|
||||
resp_buf_type[i] = CIFS_NO_BUFFER; /* no response buf yet */
|
||||
|
||||
if ((ses == NULL) || (ses->server == NULL)) {
|
||||
if (!ses || !ses->server || !server) {
|
||||
cifs_dbg(VFS, "Null session\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
server = cifs_pick_channel(ses);
|
||||
|
||||
if (server->tcpStatus == CifsExiting)
|
||||
return -ENOENT;
|
||||
|
||||
|
@ -1239,11 +1237,12 @@ out:
|
|||
|
||||
int
|
||||
cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
|
||||
struct TCP_Server_Info *server,
|
||||
struct smb_rqst *rqst, int *resp_buf_type, const int flags,
|
||||
struct kvec *resp_iov)
|
||||
{
|
||||
return compound_send_recv(xid, ses, flags, 1, rqst, resp_buf_type,
|
||||
resp_iov);
|
||||
return compound_send_recv(xid, ses, server, flags, 1,
|
||||
rqst, resp_buf_type, resp_iov);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1278,7 +1277,8 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
|
|||
rqst.rq_iov = new_iov;
|
||||
rqst.rq_nvec = n_vec + 1;
|
||||
|
||||
rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov);
|
||||
rc = cifs_send_recv(xid, ses, ses->server,
|
||||
&rqst, resp_buf_type, flags, resp_iov);
|
||||
if (n_vec + 1 > CIFS_MAX_IOV_SIZE)
|
||||
kfree(new_iov);
|
||||
return rc;
|
||||
|
|
Loading…
Reference in New Issue