Re: [PATCH v3 2/9] smb: client: block non-reconfigurable option changes on remount
From: Meetakshi Setiya
Date: Thu Jun 04 2026 - 10:51:17 EST
Reviewed-by: Meetakshi Setiya <msetiya@xxxxxxxxxxxxx>
On Thu, May 21, 2026 at 7:24 PM <rajasimandalos@xxxxxxxxx> wrote:
>
> From: Rajasi Mandal <rajasimandal@xxxxxxxxxxxxx>
>
> Several mount options (seal, sign, vers, ip, rdma, nosharesock,
> persistent/resilient handles, etc.) require tearing down the
> connection to take effect, but smb3_verify_reconfigure_ctx() does
> not reject them. A remount that changes any of these silently
> ignores the new value, confusing users.
>
> Now that smb3_init_fs_context() duplicates the live context (with
> runtime state synced in) on reconfigure, simple != checks in
> smb3_verify_reconfigure_ctx() are sound -- a difference between
> new_ctx and old_ctx represents a real, intentional change by the
> user rather than a spurious mismatch against init defaults.
>
> Add comprehensive checks for connection-tied options with clear
> error messages so the user sees why the remount failed.
>
> Signed-off-by: Rajasi Mandal <rajasimandal@xxxxxxxxxxxxx>
> ---
> fs/smb/client/fs_context.c | 137 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 137 insertions(+)
>
> diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
> index b93d6ef13463..0677aad237e8 100644
> --- a/fs/smb/client/fs_context.c
> +++ b/fs/smb/client/fs_context.c
> @@ -1069,6 +1069,143 @@ static int smb3_verify_reconfigure_ctx(struct fs_context *fc,
> cifs_errorf(fc, "can not change nbsessinit during remount\n");
> return -EINVAL;
> }
> + if (new_ctx->compress != old_ctx->compress) {
> + cifs_errorf(fc, "can not change compress during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->noblocksnd != old_ctx->noblocksnd) {
> + cifs_errorf(fc, "can not change noblocksend during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->noautotune != old_ctx->noautotune) {
> + cifs_errorf(fc, "can not change noautotune during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->no_sparse != old_ctx->no_sparse) {
> + cifs_errorf(fc, "can not change nosparse during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->nodelete != old_ctx->nodelete) {
> + cifs_errorf(fc, "can not change nodelete during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->cruid_specified &&
> + !uid_eq(new_ctx->cred_uid, old_ctx->cred_uid)) {
> + cifs_errorf(fc, "can not change cruid during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->port != old_ctx->port) {
> + cifs_errorf(fc, "can not change port during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->min_offload != old_ctx->min_offload) {
> + cifs_errorf(fc, "can not change min_enc_offload during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->snapshot_time != old_ctx->snapshot_time) {
> + cifs_errorf(fc, "can not change snapshot during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->max_credits != old_ctx->max_credits) {
> + cifs_errorf(fc, "can not change max_credits during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->handle_timeout != old_ctx->handle_timeout) {
> + cifs_errorf(fc, "can not change handletimeout during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->got_ip &&
> + !cifs_match_ipaddr((struct sockaddr *)&new_ctx->dstaddr,
> + (struct sockaddr *)&old_ctx->dstaddr)) {
> + cifs_errorf(fc, "can not change ip during remount\n");
> + return -EINVAL;
> + }
> + if (((struct sockaddr *)&new_ctx->srcaddr)->sa_family != AF_UNSPEC &&
> + memcmp(&new_ctx->srcaddr, &old_ctx->srcaddr, sizeof(new_ctx->srcaddr))) {
> + cifs_errorf(fc, "can not change srcaddr during remount\n");
> + return -EINVAL;
> + }
> + if (memcmp(new_ctx->source_rfc1001_name, old_ctx->source_rfc1001_name,
> + RFC1001_NAME_LEN)) {
> + cifs_errorf(fc, "can not change netbiosname during remount\n");
> + return -EINVAL;
> + }
> + if (memcmp(new_ctx->target_rfc1001_name, old_ctx->target_rfc1001_name,
> + RFC1001_NAME_LEN)) {
> + cifs_errorf(fc, "can not change servern during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->got_version &&
> + (new_ctx->ops != old_ctx->ops || new_ctx->vals != old_ctx->vals)) {
> + cifs_errorf(fc, "can not change vers during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->witness != old_ctx->witness) {
> + cifs_errorf(fc, "can not change witness during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->rootfs != old_ctx->rootfs) {
> + cifs_errorf(fc, "can not change rootfs during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->linux_ext != old_ctx->linux_ext ||
> + new_ctx->no_linux_ext != old_ctx->no_linux_ext) {
> + cifs_errorf(fc, "can not change unix during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->nocase != old_ctx->nocase) {
> + cifs_errorf(fc, "can not change nocase during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->intr != old_ctx->intr) {
> + cifs_errorf(fc, "can not change intr during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->no_psx_acl != old_ctx->no_psx_acl) {
> + cifs_errorf(fc, "can not change acl during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->local_lease != old_ctx->local_lease) {
> + cifs_errorf(fc, "can not change locallease during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->sign != old_ctx->sign) {
> + cifs_errorf(fc, "can not change sign during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->ignore_signature != old_ctx->ignore_signature) {
> + cifs_errorf(fc, "can not change ignore_signature during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->seal != old_ctx->seal) {
> + cifs_errorf(fc, "can not change seal during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->nosharesock != old_ctx->nosharesock) {
> + cifs_errorf(fc, "can not change nosharesock during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->persistent != old_ctx->persistent ||
> + new_ctx->nopersistent != old_ctx->nopersistent) {
> + cifs_errorf(fc, "can not change persistenthandles during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->resilient != old_ctx->resilient) {
> + cifs_errorf(fc, "can not change resilienthandles during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->sockopt_tcp_nodelay != old_ctx->sockopt_tcp_nodelay) {
> + cifs_errorf(fc, "can not change tcpnodelay during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->domainauto != old_ctx->domainauto) {
> + cifs_errorf(fc, "can not change domainauto during remount\n");
> + return -EINVAL;
> + }
> + if (new_ctx->rdma != old_ctx->rdma) {
> + cifs_errorf(fc, "can not change rdma during remount\n");
> + return -EINVAL;
> + }
>
> return 0;
> }
> --
> 2.43.0
>