public inbox for linux-cifs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/9] smb: client: block non-reconfigurable option changes on remount
@ 2026-04-09  9:59 rajasimandalos
  2026-04-09  9:59 ` [PATCH 2/9] smb: client: allow both 'lease' and 'nolease' mount options rajasimandalos
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: rajasimandalos @ 2026-04-09  9:59 UTC (permalink / raw)
  To: sfrench, linux-cifs
  Cc: pc, ronniesahlberg, sprasad, tom, metze, bharathsm,
	samba-technical, linux-kernel, Rajasi Mandal

From: Rajasi Mandal <rajasimandal@microsoft.com>

Options like seal, sign, vers, ip, rdma and others require tearing
down the connection to take effect, so they cannot be changed on
remount.  Previously they were silently accepted and ignored.

Add checks in smb3_verify_reconfigure_ctx() to reject changes to
these options on remount.  Options shown in /proc/mounts use a bare
!= comparison since libmount feeds them back automatically.  Options
not shown in /proc/mounts use an 'if (new && new != old)' guard so
their init default does not cause a false mismatch.

Introduce smb3_preserve_non_reconfig_opts() to copy hidden option
values from the old context into the new one before
smb3_fs_context_dup() overwrites them with init defaults.  Without
this, a bare remount silently corrupts the stored mount context by
replacing live values with zero/init defaults for every option not
shown in /proc/mounts.

Introduce smb3_sync_ctx_from_negotiated() to sync the stored mount
context with runtime state (persistenthandles, unix, nosharesock,
resilienthandles, domainname, ops/vals) before the verify step, since
cifs_show_options() reads these from tcon/server and they can diverge
from ctx when the server auto-enables a feature or negotiates a
different dialect than what was parsed (e.g. default -> SMB 3.1.1).
Without this sync, the fed-back /proc/mounts values mismatch the
stale ctx and the verify step incorrectly rejects a bare remount.

Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
---
 fs/smb/client/fs_context.c | 232 +++++++++++++++++++++++++++++++++++++
 1 file changed, 232 insertions(+)

diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 3f0faae99ed5..0f6c1eb8e274 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1021,10 +1021,238 @@ static int smb3_verify_reconfigure_ctx(struct fs_context *fc,
 		cifs_errorf(fc, "can not change nbsessinit during remount\n");
 		return -EINVAL;
 	}
+	/* init default: compress = false */
+	if (new_ctx->compress &&
+	    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;
+	}
+	/* init default: port = 0 */
+	if (new_ctx->port &&
+	    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;
+	}
+	/* source_rfc1001_name: both init from same nodename, safe to compare */
+	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;
+	}
+	/* init default: target_rfc1001_name[0] = 0 */
+	if (new_ctx->target_rfc1001_name[0] &&
+	    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;
+	}
+	/* init default: rootfs = false */
+	if (new_ctx->rootfs &&
+	    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;
+	}
+	/* init default: intr = false */
+	if (new_ctx->intr &&
+	    new_ctx->intr != old_ctx->intr) {
+		cifs_errorf(fc, "can not change intr during remount\n");
+		return -EINVAL;
+	}
+	/* init default: no_psx_acl = 0 */
+	if (new_ctx->no_psx_acl &&
+	    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;
+	}
+	/*
+	 * persistent is shown in /proc/mounts (bare !=).
+	 * nopersistent is NOT shown, so guard with init default check.
+	 */
+	if (new_ctx->persistent != old_ctx->persistent ||
+	    (new_ctx->nopersistent &&
+	     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;
+	}
+	/* init default: domainauto = false */
+	if (new_ctx->domainauto &&
+	    new_ctx->domainauto != old_ctx->domainauto) {
+		cifs_errorf(fc, "can not change domainauto during remount\n");
+		return -EINVAL;
+	}
+	/* init default: rdma = false */
+	if (new_ctx->rdma &&
+	    new_ctx->rdma != old_ctx->rdma) {
+		cifs_errorf(fc, "can not change rdma during remount\n");
+		return -EINVAL;
+	}
 
 	return 0;
 }
 
+/*
+ * Sync cifs_sb->ctx with negotiated runtime values for fields that
+ * cifs_show_options() reads from tcon/server rather than from ctx.
+ * The mount.cifs helper reads /proc/mounts and feeds these values back
+ * on remount, so ctx must match the runtime state to avoid false
+ * rejection by smb3_verify_reconfigure_ctx().
+ */
+static void smb3_sync_ctx_from_negotiated(struct cifs_sb_info *cifs_sb)
+{
+	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+	struct TCP_Server_Info *server = tcon->ses->server;
+	struct smb3_fs_context *ctx = cifs_sb->ctx;
+
+	/* /proc/mounts shows persistenthandles from tcon->use_persistent */
+	if (tcon->use_persistent && !ctx->persistent) {
+		ctx->persistent = true;
+		ctx->nopersistent = false;
+	}
+	/* /proc/mounts shows resilienthandles from tcon->use_resilient */
+	ctx->resilient = tcon->use_resilient;
+	/* /proc/mounts shows nounix/unix/posix from tcon */
+	if (tcon->posix_extensions) {
+		ctx->linux_ext = 1;
+		ctx->no_linux_ext = 0;
+	} else if (!tcon->unix_ext) {
+		ctx->linux_ext = 0;
+		ctx->no_linux_ext = 1;
+	}
+	/* /proc/mounts shows nosharesock from server->nosharesock */
+	if (server->nosharesock)
+		ctx->nosharesock = true;
+	/*
+	 * /proc/mounts shows vers= from server->vals->version_string,
+	 * which reflects the negotiated dialect. When mounted without
+	 * an explicit vers=, ctx stores smbdefault ops/vals while the
+	 * server may have negotiated e.g. SMB 3.1.1. Sync so the
+	 * verify check does not reject the fed-back vers= on remount.
+	 */
+	ctx->ops = server->ops;
+	ctx->vals = server->vals;
+}
+
+/*
+ * Carry forward non-reconfigurable mount options that are NOT
+ * displayed by cifs_show_options() into the new remount context
+ * before smb3_fs_context_dup() overwrites cifs_sb->ctx.
+ *
+ * Options that cifs_show_options() outputs are automatically
+ * re-fed by libmount (which reads /proc/mounts) on remount,
+ * so they do not need to be preserved here.
+ *
+ * Without this, a bare remount would silently reset these hidden
+ * fields to their init defaults.
+ */
+static void smb3_preserve_non_reconfig_opts(struct smb3_fs_context *new_ctx,
+					    struct smb3_fs_context *old_ctx)
+{
+	new_ctx->compress = old_ctx->compress;
+	new_ctx->port = old_ctx->port;
+	new_ctx->rootfs = old_ctx->rootfs;
+	new_ctx->intr = old_ctx->intr;
+	new_ctx->no_psx_acl = old_ctx->no_psx_acl;
+	new_ctx->domainauto = old_ctx->domainauto;
+	new_ctx->rdma = old_ctx->rdma;
+	new_ctx->nopersistent = old_ctx->nopersistent;
+	memcpy(new_ctx->target_rfc1001_name, old_ctx->target_rfc1001_name,
+	       RFC1001_NAME_LEN_WITH_NULL);
+}
+
 #define STEAL_STRING(cifs_sb, ctx, field)				\
 do {									\
 	kfree(ctx->field);						\
@@ -1093,6 +1321,8 @@ static int smb3_reconfigure(struct fs_context *fc)
 	if (ses->expired_pwd)
 		need_recon = true;
 
+	smb3_sync_ctx_from_negotiated(cifs_sb);
+
 	rc = smb3_verify_reconfigure_ctx(fc, ctx, cifs_sb->ctx, need_recon);
 	if (rc)
 		return rc;
@@ -1205,6 +1435,8 @@ static int smb3_reconfigure(struct fs_context *fc)
 	ctx->rsize = rsize ? CIFS_ALIGN_RSIZE(fc, rsize) : cifs_sb->ctx->rsize;
 	ctx->wsize = wsize ? CIFS_ALIGN_WSIZE(fc, wsize) : cifs_sb->ctx->wsize;
 
+	smb3_preserve_non_reconfig_opts(ctx, cifs_sb->ctx);
+
 	smb3_cleanup_fs_context_contents(cifs_sb->ctx);
 	rc = smb3_fs_context_dup(cifs_sb->ctx, ctx);
 	smb3_update_mnt_flags(cifs_sb);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/9] smb: client: allow both 'lease' and 'nolease' mount options
  2026-04-09  9:59 [PATCH 1/9] smb: client: block non-reconfigurable option changes on remount rajasimandalos
@ 2026-04-09  9:59 ` rajasimandalos
  2026-04-09  9:59 ` [PATCH 3/9] smb: client: sync tcon-level options on remount rajasimandalos
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: rajasimandalos @ 2026-04-09  9:59 UTC (permalink / raw)
  To: sfrench, linux-cifs
  Cc: pc, ronniesahlberg, sprasad, tom, metze, bharathsm,
	samba-technical, linux-kernel, Rajasi Mandal

From: Rajasi Mandal <rajasimandal@microsoft.com>

Change the nolease mount option from fsparam_flag() to fsparam_flag_no()
so that both 'lease' and 'nolease' are accepted as valid mount options.

Previously, only 'nolease' was recognized. Passing 'lease' would fail
with an unknown parameter error (or be silently ignored with 'sloppy').

With this change:
  - 'nolease' disables lease requests (same behavior as before)
  - 'lease' explicitly enables lease requests

This also renames the enum value from Opt_nolease to Opt_lease and uses
result.negated to set ctx->no_lease, which is the standard pattern used
by other flag_no options in the cifs mount option parser.

Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
---
 fs/smb/client/fs_context.c | 6 +++---
 fs/smb/client/fs_context.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 0f6c1eb8e274..e1bf7bad5be6 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -80,7 +80,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {
 	fsparam_flag_no("forcegid", Opt_forcegid),
 	fsparam_flag("noblocksend", Opt_noblocksend),
 	fsparam_flag("noautotune", Opt_noautotune),
-	fsparam_flag("nolease", Opt_nolease),
+	fsparam_flag_no("lease", Opt_lease),
 	fsparam_flag_no("hard", Opt_hard),
 	fsparam_flag_no("soft", Opt_soft),
 	fsparam_flag_no("perm", Opt_perm),
@@ -1572,8 +1572,8 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
 	case Opt_noautotune:
 		ctx->noautotune = 1;
 		break;
-	case Opt_nolease:
-		ctx->no_lease = 1;
+	case Opt_lease:
+		ctx->no_lease = result.negated;
 		break;
 	case Opt_nosparse:
 		ctx->no_sparse = 1;
diff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h
index 0b64fcb5d302..a80a5caff23c 100644
--- a/fs/smb/client/fs_context.h
+++ b/fs/smb/client/fs_context.h
@@ -102,7 +102,7 @@ enum cifs_param {
 	Opt_forcegid,
 	Opt_noblocksend,
 	Opt_noautotune,
-	Opt_nolease,
+	Opt_lease,
 	Opt_nosparse,
 	Opt_hard,
 	Opt_soft,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/9] smb: client: sync tcon-level options on remount
  2026-04-09  9:59 [PATCH 1/9] smb: client: block non-reconfigurable option changes on remount rajasimandalos
  2026-04-09  9:59 ` [PATCH 2/9] smb: client: allow both 'lease' and 'nolease' mount options rajasimandalos
@ 2026-04-09  9:59 ` rajasimandalos
  2026-04-09  9:59 ` [PATCH 4/9] smb: client: sync retrans " rajasimandalos
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: rajasimandalos @ 2026-04-09  9:59 UTC (permalink / raw)
  To: sfrench, linux-cifs
  Cc: pc, ronniesahlberg, sprasad, tom, metze, bharathsm,
	samba-technical, linux-kernel, Rajasi Mandal

From: Rajasi Mandal <rajasimandal@microsoft.com>

Several mount options are stored on each cifs_tcon at mount time but
smb3_reconfigure() only updates cifs_sb->ctx. A remount that changes
any of these options silently has no effect because the runtime code
reads from the tcon fields, not from the superblock context.

The affected options and their tcon fields are:
  retry           -> tcon->retry
  max_cached_dirs -> tcon->max_cached_dirs

Add smb3_sync_tcon_opts() which walks the tlink_tree under
tlink_tree_lock and propagates these values from ctx to every tcon
under tc_lock. Call it from smb3_reconfigure() after the context has
been updated.

Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
---
 fs/smb/client/fs_context.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index e1bf7bad5be6..90e83f07c870 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1307,6 +1307,35 @@ static void smb3_sync_ses_chan_max(struct cifs_ses *ses, unsigned int max_channe
 	spin_unlock(&ses->chan_lock);
 }
 
+/*
+ * Synchronize tcon options that are derived from ctx across all tcons
+ * associated with this superblock.  These fields are consulted at runtime
+ * (reconnect, I/O, unlink/rmdir) so remount needs to update the live
+ * tcons in addition to cifs_sb->ctx.
+ */
+static void smb3_sync_tcon_opts(struct cifs_sb_info *cifs_sb,
+				struct smb3_fs_context *ctx)
+{
+	struct rb_node *node;
+
+	spin_lock(&cifs_sb->tlink_tree_lock);
+	for (node = rb_first(&cifs_sb->tlink_tree); node; node = rb_next(node)) {
+		struct tcon_link *tlink;
+		struct cifs_tcon *tcon;
+
+		tlink = rb_entry(node, struct tcon_link, tl_rbnode);
+		tcon = tlink_tcon(tlink);
+		if (IS_ERR_OR_NULL(tcon))
+			continue;
+
+		spin_lock(&tcon->tc_lock);
+		tcon->retry = ctx->retry;
+		tcon->max_cached_dirs = ctx->max_cached_dirs;
+		spin_unlock(&tcon->tc_lock);
+	}
+	spin_unlock(&cifs_sb->tlink_tree_lock);
+}
+
 static int smb3_reconfigure(struct fs_context *fc)
 {
 	struct smb3_fs_context *ctx = smb3_fc2context(fc);
@@ -1444,6 +1473,8 @@ static int smb3_reconfigure(struct fs_context *fc)
 	if (!rc)
 		rc = dfs_cache_remount_fs(cifs_sb);
 #endif
+	if (!rc)
+		smb3_sync_tcon_opts(cifs_sb, cifs_sb->ctx);
 
 	return rc;
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/9] smb: client: sync retrans on remount
  2026-04-09  9:59 [PATCH 1/9] smb: client: block non-reconfigurable option changes on remount rajasimandalos
  2026-04-09  9:59 ` [PATCH 2/9] smb: client: allow both 'lease' and 'nolease' mount options rajasimandalos
  2026-04-09  9:59 ` [PATCH 3/9] smb: client: sync tcon-level options on remount rajasimandalos
@ 2026-04-09  9:59 ` rajasimandalos
  2026-04-09  9:59 ` [PATCH 5/9] smb: client: sync echo_interval " rajasimandalos
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: rajasimandalos @ 2026-04-09  9:59 UTC (permalink / raw)
  To: sfrench, linux-cifs
  Cc: pc, ronniesahlberg, sprasad, tom, metze, bharathsm,
	samba-technical, linux-kernel, Rajasi Mandal

From: Rajasi Mandal <rajasimandal@microsoft.com>

The retrans mount option controls how many times the client retries
sending a request before giving up.  Although remount already stored
the new value in cifs_sb->ctx, it was never propagated to
server->retrans, so the running connection kept using the old count.

Introduce smb3_sync_server_opts() to push ctx options that live on
TCP_Server_Info into the live server struct after a successful
remount.  For now it handles retrans; subsequent patches will extend
it to other server-level knobs.

The assignment is guarded (if ctx->retrans) so that a bare
'mount -o remount' (which re-parses /proc/mounts and gets
retrans=0 because cifs_show_options does not print it) does not
accidentally reset the value to zero.

Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
---
 fs/smb/client/fs_context.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 90e83f07c870..31b82f8f7ead 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1336,6 +1336,21 @@ static void smb3_sync_tcon_opts(struct cifs_sb_info *cifs_sb,
 	spin_unlock(&cifs_sb->tlink_tree_lock);
 }
 
+/*
+ * Synchronize server-level options that are stored on TCP_Server_Info
+ * at mount time.  These fields are consulted at runtime (retry logic)
+ * so remount needs to update the live server struct in addition to
+ * cifs_sb->ctx.
+ */
+static void smb3_sync_server_opts(struct cifs_sb_info *cifs_sb)
+{
+	struct TCP_Server_Info *server = cifs_sb_master_tcon(cifs_sb)->ses->server;
+	struct smb3_fs_context *ctx = cifs_sb->ctx;
+
+	if (ctx->retrans)
+		server->retrans = ctx->retrans;
+}
+
 static int smb3_reconfigure(struct fs_context *fc)
 {
 	struct smb3_fs_context *ctx = smb3_fc2context(fc);
@@ -1475,6 +1490,8 @@ static int smb3_reconfigure(struct fs_context *fc)
 #endif
 	if (!rc)
 		smb3_sync_tcon_opts(cifs_sb, cifs_sb->ctx);
+	if (!rc)
+		smb3_sync_server_opts(cifs_sb);
 
 	return rc;
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/9] smb: client: sync echo_interval on remount
  2026-04-09  9:59 [PATCH 1/9] smb: client: block non-reconfigurable option changes on remount rajasimandalos
                   ` (2 preceding siblings ...)
  2026-04-09  9:59 ` [PATCH 4/9] smb: client: sync retrans " rajasimandalos
@ 2026-04-09  9:59 ` rajasimandalos
  2026-04-09  9:59 ` [PATCH 6/9] smb: client: allow nolease option to be reconfigured " rajasimandalos
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: rajasimandalos @ 2026-04-09  9:59 UTC (permalink / raw)
  To: sfrench, linux-cifs
  Cc: pc, ronniesahlberg, sprasad, tom, metze, bharathsm,
	samba-technical, linux-kernel, Rajasi Mandal

From: Rajasi Mandal <rajasimandal@microsoft.com>

Add echo_interval handling to smb3_sync_server_opts() so that
changing echo_interval via remount actually takes effect on the
running connection.

The server echo worker fires every server->echo_interval jiffies,
but that field was never updated from cifs_sb->ctx on remount.
Convert the user-supplied seconds value to jiffies and reschedule
the echo worker with mod_delayed_work() so the new interval is
picked up immediately.

The assignment is guarded (if ctx->echo_interval) so that an
explicit echo_interval=0 does not accidentally reset the interval.

Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
---
 fs/smb/client/fs_context.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 31b82f8f7ead..5f0637035172 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1338,9 +1338,9 @@ static void smb3_sync_tcon_opts(struct cifs_sb_info *cifs_sb,
 
 /*
  * Synchronize server-level options that are stored on TCP_Server_Info
- * at mount time.  These fields are consulted at runtime (retry logic)
- * so remount needs to update the live server struct in addition to
- * cifs_sb->ctx.
+ * at mount time.  These fields are consulted at runtime (echo work,
+ * retry logic) so remount needs to update the live server struct in
+ * addition to cifs_sb->ctx.
  */
 static void smb3_sync_server_opts(struct cifs_sb_info *cifs_sb)
 {
@@ -1349,6 +1349,11 @@ static void smb3_sync_server_opts(struct cifs_sb_info *cifs_sb)
 
 	if (ctx->retrans)
 		server->retrans = ctx->retrans;
+	if (ctx->echo_interval) {
+		server->echo_interval = ctx->echo_interval * HZ;
+		mod_delayed_work(cifsiod_wq, &server->echo,
+				 server->echo_interval);
+	}
 }
 
 static int smb3_reconfigure(struct fs_context *fc)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 6/9] smb: client: allow nolease option to be reconfigured on remount
  2026-04-09  9:59 [PATCH 1/9] smb: client: block non-reconfigurable option changes on remount rajasimandalos
                   ` (3 preceding siblings ...)
  2026-04-09  9:59 ` [PATCH 5/9] smb: client: sync echo_interval " rajasimandalos
@ 2026-04-09  9:59 ` rajasimandalos
  2026-04-09  9:59 ` [PATCH 7/9] smb: client: block cache=ro and cache=singleclient " rajasimandalos
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: rajasimandalos @ 2026-04-09  9:59 UTC (permalink / raw)
  To: sfrench, linux-cifs
  Cc: pc, ronniesahlberg, sprasad, tom, metze, bharathsm,
	samba-technical, linux-kernel, Rajasi Mandal

From: Rajasi Mandal <rajasimandal@microsoft.com>

The nolease mount option (tcon->no_lease) controls whether the client
requests oplocks/leases from the server during SMB2 opens.  Previously,
changing this option via remount was silently accepted but had no effect
because the value was never synced from the updated ctx to the live tcon.

Add no_lease to smb3_sync_tcon_opts() so the flag is propagated to all
tcons on remount, matching the pattern used by retry, nodelete, and
max_cached_dirs.

When switching to nolease, also close all deferred file handles via
cifs_close_all_deferred_files(). Deferred handles retain their
original lease from the previous open; without closing them, a
subsequent open would reuse the cached handle and inherit the stale
lease, preventing nolease from taking effect.

Both transitions are safe:
 - lease -> nolease: deferred handles are force-closed, and future
   opens get OPLOCK_LEVEL_NONE.
 - nolease -> lease: future opens will request leases; existing
   uncached files remain uncached until reopened.

On reconnect, cifs_reopen_file() reads the current tcon->no_lease and
the server grants (or not) accordingly, so the per-inode cache state
is naturally updated.

Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
---
 fs/smb/client/fs_context.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 5f0637035172..ce4842e778c4 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1330,8 +1330,12 @@ static void smb3_sync_tcon_opts(struct cifs_sb_info *cifs_sb,
 
 		spin_lock(&tcon->tc_lock);
 		tcon->retry = ctx->retry;
+		tcon->no_lease = ctx->no_lease;
 		tcon->max_cached_dirs = ctx->max_cached_dirs;
 		spin_unlock(&tcon->tc_lock);
+
+		if (ctx->no_lease)
+			cifs_close_all_deferred_files(tcon);
 	}
 	spin_unlock(&cifs_sb->tlink_tree_lock);
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 7/9] smb: client: block cache=ro and cache=singleclient on remount
  2026-04-09  9:59 [PATCH 1/9] smb: client: block non-reconfigurable option changes on remount rajasimandalos
                   ` (4 preceding siblings ...)
  2026-04-09  9:59 ` [PATCH 6/9] smb: client: allow nolease option to be reconfigured " rajasimandalos
@ 2026-04-09  9:59 ` rajasimandalos
  2026-04-09  9:59 ` [PATCH 8/9] smb: client: fix domainauto remount by syncing domainname from session rajasimandalos
  2026-04-09  9:59 ` [PATCH 9/9] smb: client: apply rasize on remount rajasimandalos
  7 siblings, 0 replies; 9+ messages in thread
From: rajasimandalos @ 2026-04-09  9:59 UTC (permalink / raw)
  To: sfrench, linux-cifs
  Cc: pc, ronniesahlberg, sprasad, tom, metze, bharathsm,
	samba-technical, linux-kernel, Rajasi Mandal

From: Rajasi Mandal <rajasimandal@microsoft.com>

cache=ro and cache=singleclient are mount-time environment declarations
where the admin promises that the share is read-only or exclusively
accessed.  The client bypasses server-based coherency (oplocks/leases)
and caches aggressively based on this promise.

These modes were intentionally excluded from smb3_update_mnt_flags()
when it was introduced in commit 2d39f50c2b15 ("cifs: move update of
flags into a separate function") — only cache=strict, cache=none and
cache=loose were made reconfigurable.  However, remount currently
silently accepts cache=ro and cache=singleclient without actually
applying them, which is confusing.

Add explicit checks in smb3_verify_reconfigure_ctx() to reject
attempts to change these options during remount with a clear error
message.

Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
---
 fs/smb/client/fs_context.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index ce4842e778c4..2be72733ef2e 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1180,6 +1180,14 @@ static int smb3_verify_reconfigure_ctx(struct fs_context *fc,
 		cifs_errorf(fc, "can not change rdma during remount\n");
 		return -EINVAL;
 	}
+	if (new_ctx->cache_ro != old_ctx->cache_ro) {
+		cifs_errorf(fc, "can not change cache=ro during remount\n");
+		return -EINVAL;
+	}
+	if (new_ctx->cache_rw != old_ctx->cache_rw) {
+		cifs_errorf(fc, "can not change cache=singleclient during remount\n");
+		return -EINVAL;
+	}
 
 	return 0;
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 8/9] smb: client: fix domainauto remount by syncing domainname from session
  2026-04-09  9:59 [PATCH 1/9] smb: client: block non-reconfigurable option changes on remount rajasimandalos
                   ` (5 preceding siblings ...)
  2026-04-09  9:59 ` [PATCH 7/9] smb: client: block cache=ro and cache=singleclient " rajasimandalos
@ 2026-04-09  9:59 ` rajasimandalos
  2026-04-09  9:59 ` [PATCH 9/9] smb: client: apply rasize on remount rajasimandalos
  7 siblings, 0 replies; 9+ messages in thread
From: rajasimandalos @ 2026-04-09  9:59 UTC (permalink / raw)
  To: sfrench, linux-cifs
  Cc: pc, ronniesahlberg, sprasad, tom, metze, bharathsm,
	samba-technical, linux-kernel, Rajasi Mandal

From: Rajasi Mandal <rajasimandal@microsoft.com>

When domainauto is used at mount time, ctx->domainname stays NULL
while the server negotiates the actual domain into ses->domainName.
cifs_show_options() reads ses->domainName and outputs domain=X in
/proc/mounts.  On remount, libmount re-feeds domain=X, but the
verify check compares against old ctx->domainname (NULL) and rejects
the remount with "can not change domainname during remount".

Steps to reproduce:

  1. Mount with domainauto (no explicit domain= option):
       mount -t cifs //server/share /mnt \
         -o username=u,password=p,domainauto
     At this point ctx->domainname is NULL, but the server populates
     ses->domainName (e.g. "CORP") during session setup.

  2. Bare remount (or any remount):
       mount -o remount /mnt
     libmount reads /proc/mounts, sees domain=CORP (output by
     cifs_show_options() from ses->domainName), and feeds it back
     to the kernel.  The kernel parses domain=CORP into
     new_ctx->domainname="CORP", but old ctx->domainname is still
     NULL.  smb3_verify_reconfigure_ctx() sees the mismatch and
     rejects the remount.

This affects any server that populates ses->domainName during session
setup (Active Directory domain controllers, Azure Files) when the
admin uses domainauto instead of an explicit domain= option.

Fix this by syncing ctx->domainname from ses->domainName in
smb3_sync_ctx_from_negotiated() before the verify check runs.

Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
---
 fs/smb/client/fs_context.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 2be72733ef2e..d804e5da578e 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1232,6 +1232,9 @@ static void smb3_sync_ctx_from_negotiated(struct cifs_sb_info *cifs_sb)
 	 */
 	ctx->ops = server->ops;
 	ctx->vals = server->vals;
+	/* /proc/mounts shows domain= from ses->domainName */
+	if (tcon->ses->domainName && !ctx->domainname)
+		ctx->domainname = kstrdup(tcon->ses->domainName, GFP_KERNEL);
 }
 
 /*
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 9/9] smb: client: apply rasize on remount
  2026-04-09  9:59 [PATCH 1/9] smb: client: block non-reconfigurable option changes on remount rajasimandalos
                   ` (6 preceding siblings ...)
  2026-04-09  9:59 ` [PATCH 8/9] smb: client: fix domainauto remount by syncing domainname from session rajasimandalos
@ 2026-04-09  9:59 ` rajasimandalos
  7 siblings, 0 replies; 9+ messages in thread
From: rajasimandalos @ 2026-04-09  9:59 UTC (permalink / raw)
  To: sfrench, linux-cifs
  Cc: pc, ronniesahlberg, sprasad, tom, metze, bharathsm,
	samba-technical, linux-kernel, Rajasi Mandal

From: Rajasi Mandal <rajasimandal@microsoft.com>

rasize is accepted during remount parsing but sb->s_bdi->ra_pages is
only set in cifs_read_super() at mount time. A remount with a new
rasize value silently has no effect on the readahead window.

Update ra_pages in smb3_reconfigure() after the context has been
duplicated, using the same logic as cifs_read_super(): if rasize is
set, use it directly; otherwise fall back to 2 * rsize.

Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
---
 fs/smb/client/fs_context.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index d804e5da578e..bba642442ae3 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1504,6 +1504,12 @@ static int smb3_reconfigure(struct fs_context *fc)
 	smb3_cleanup_fs_context_contents(cifs_sb->ctx);
 	rc = smb3_fs_context_dup(cifs_sb->ctx, ctx);
 	smb3_update_mnt_flags(cifs_sb);
+
+	if (cifs_sb->ctx->rasize)
+		root->d_sb->s_bdi->ra_pages = cifs_sb->ctx->rasize / PAGE_SIZE;
+	else
+		root->d_sb->s_bdi->ra_pages = 2 * (cifs_sb->ctx->rsize / PAGE_SIZE);
+
 #ifdef CONFIG_CIFS_DFS_UPCALL
 	if (!rc)
 		rc = dfs_cache_remount_fs(cifs_sb);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-04-09 10:00 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-09  9:59 [PATCH 1/9] smb: client: block non-reconfigurable option changes on remount rajasimandalos
2026-04-09  9:59 ` [PATCH 2/9] smb: client: allow both 'lease' and 'nolease' mount options rajasimandalos
2026-04-09  9:59 ` [PATCH 3/9] smb: client: sync tcon-level options on remount rajasimandalos
2026-04-09  9:59 ` [PATCH 4/9] smb: client: sync retrans " rajasimandalos
2026-04-09  9:59 ` [PATCH 5/9] smb: client: sync echo_interval " rajasimandalos
2026-04-09  9:59 ` [PATCH 6/9] smb: client: allow nolease option to be reconfigured " rajasimandalos
2026-04-09  9:59 ` [PATCH 7/9] smb: client: block cache=ro and cache=singleclient " rajasimandalos
2026-04-09  9:59 ` [PATCH 8/9] smb: client: fix domainauto remount by syncing domainname from session rajasimandalos
2026-04-09  9:59 ` [PATCH 9/9] smb: client: apply rasize on remount rajasimandalos

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox