diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 891c8d8c2bb53b187837e4683c5e9d26b7730b90..313d252bbbe9df63aafc84012aa9f3feda0da789 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -598,9 +598,7 @@ extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page, unsigned int *len, unsigned int *offset); struct cifs_chan * cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server); -int cifs_try_adding_channels(struct cifs_ses *ses); -int cifs_ses_add_channel(struct cifs_ses *ses, - struct cifs_server_iface *iface); +int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses); bool is_server_using_iface(struct TCP_Server_Info *server, struct cifs_server_iface *iface); bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index eb036cf0f6310a9b49ed48cb09c116df15a6e92b..2d43c313f13da9e887878f48a159d014b414ac54 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2717,7 +2717,19 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx, cifs_dbg(FYI, "file mode: %04ho dir mode: %04ho\n", cifs_sb->ctx->file_mode, cifs_sb->ctx->dir_mode); - cifs_sb->local_nls = ctx->local_nls; + /* this is needed for ASCII cp to Unicode converts */ + if (ctx->iocharset == NULL) { + /* load_nls_default cannot return null */ + cifs_sb->local_nls = load_nls_default(); + } else { + cifs_sb->local_nls = load_nls(ctx->iocharset); + if (cifs_sb->local_nls == NULL) { + cifs_dbg(VFS, "CIFS mount error: iocharset %s not found\n", + ctx->iocharset); + return -ELIBACC; + } + } + ctx->local_nls = cifs_sb->local_nls; if (ctx->nodfs) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS; @@ -3187,19 +3199,6 @@ cifs_setup_volume_info(struct smb3_fs_context *ctx) return -EINVAL; } - /* this is needed for ASCII cp to Unicode converts */ - if (ctx->iocharset == NULL) { - /* load_nls_default cannot return null */ - ctx->local_nls = load_nls_default(); - } else { - ctx->local_nls = load_nls(ctx->iocharset); - if (ctx->local_nls == NULL) { - cifs_dbg(VFS, "CIFS mount error: iocharset %s not found\n", - ctx->iocharset); - return -ELIBACC; - } - } - return rc; } @@ -3521,7 +3520,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) out: free_xid(xid); - cifs_try_adding_channels(ses); + cifs_try_adding_channels(cifs_sb, ses); return mount_setup_tlink(cifs_sb, ses, tcon); error: diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c index b807f8a78adc8b8b80cca1ba7a9445fe68f840d1..c3c6d0cd291ba8dc9a38e278310bf08507794ce7 100644 --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -304,7 +304,6 @@ smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx memcpy(new_ctx, ctx, sizeof(*ctx)); new_ctx->prepath = NULL; new_ctx->mount_options = NULL; - new_ctx->local_nls = NULL; new_ctx->nodename = NULL; new_ctx->username = NULL; new_ctx->password = NULL; @@ -1350,9 +1349,6 @@ smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx) ctx->iocharset = NULL; kfree(ctx->prepath); ctx->prepath = NULL; - - unload_nls(ctx->local_nls); - ctx->local_nls = NULL; } void diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h index 1680d0ceed38cc5eb6437042a773ae513eabbca3..2519108eeb29f7e71b2835cce008fda095f27700 100644 --- a/fs/cifs/fs_context.h +++ b/fs/cifs/fs_context.h @@ -237,7 +237,7 @@ struct smb3_fs_context { char *prepath; struct sockaddr_storage dstaddr; /* destination address */ struct sockaddr_storage srcaddr; /* allow binding to a local IP */ - struct nls_table *local_nls; + struct nls_table *local_nls; /* This is a copy of the pointer in cifs_sb */ unsigned int echo_interval; /* echo interval in secs */ __u64 snapshot_time; /* needed for timewarp tokens */ __u32 handle_timeout; /* persistent and durable handle timeout in ms */ diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 00ca687a17dda5dbcc3c5cc453fc66425e9c852c..213465718fa89d7005e01f05bd718157b9540af2 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -34,6 +34,10 @@ #include "smb2proto.h" #include "fs_context.h" +static int +cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, + struct cifs_server_iface *iface); + bool is_server_using_iface(struct TCP_Server_Info *server, struct cifs_server_iface *iface) @@ -71,7 +75,7 @@ bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface) } /* returns number of channels added */ -int cifs_try_adding_channels(struct cifs_ses *ses) +int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) { int old_chan_count = ses->chan_count; int left = ses->chan_max - ses->chan_count; @@ -134,7 +138,7 @@ int cifs_try_adding_channels(struct cifs_ses *ses) continue; } - rc = cifs_ses_add_channel(ses, iface); + rc = cifs_ses_add_channel(cifs_sb, ses, iface); if (rc) { cifs_dbg(FYI, "failed to open extra channel on iface#%d rc=%d\n", i, rc); @@ -167,8 +171,9 @@ cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server) return NULL; } -int -cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) +static int +cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, + struct cifs_server_iface *iface) { struct cifs_chan *chan; struct smb3_fs_context ctx = {NULL}; @@ -229,13 +234,8 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) /* * This will be used for encoding/decoding user/domain/pw * during sess setup auth. - * - * XXX: We use the default for simplicity but the proper way - * would be to use the one that ses used, which is not - * stored. This might break when dealing with non-ascii - * strings. */ - ctx.local_nls = load_nls_default(); + ctx.local_nls = cifs_sb->local_nls; /* Use RDMA if possible */ ctx.rdma = iface->rdma_capable; @@ -275,7 +275,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) if (rc) goto out; - rc = cifs_setup_session(xid, ses, ctx.local_nls); + rc = cifs_setup_session(xid, ses, cifs_sb->local_nls); if (rc) goto out; @@ -298,7 +298,6 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) if (rc && chan->server) cifs_put_tcp_session(chan->server, 0); - unload_nls(ctx.local_nls); return rc; }