* [PATCH RESEND 0/9] smb: client: remount reconfigure option fixes
@ 2026-07-02 11:35 rajasimandalos
2026-07-02 11:35 ` [PATCH 1/9] smb: client: sync runtime state into ctx on reconfigure rajasimandalos
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: rajasimandalos @ 2026-07-02 11:35 UTC (permalink / raw)
To: linux-cifs; +Cc: bharathsm, msetiya, smfrench, sfrench, stfrench, Rajasi Mandal
From: Rajasi Mandal <rajasimandal@microsoft.com>
Resending the full remount reconfigure series with review fixes included.
This resend includes:
- review fixes for patches 1-4
- nolease remount follow-up fix (patch 7)
Cc: Steve French <smfrench@gmail.com>
Cc: Steve French <sfrench@samba.org>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: Meetakshi Setiya <msetiya@microsoft.com>
Rajasi Mandal (9):
smb: client: sync runtime state into ctx on reconfigure
smb: client: block non-reconfigurable option changes on remount
smb: client: sync retrans on remount
smb: client: block cache=ro and cache=singleclient on remount
smb: client: apply rasize on remount
smb: client: move struct tcon_list to cifsglob.h
smb: client: allow nolease option to be reconfigured on remount
smb: client: review fixes for remount ctx/retrans sync (patches 1-4)
smb: client: review fixes for nolease remount (patch 7)
fs/smb/client/cached_dir.c | 70 +++++-
fs/smb/client/cached_dir.h | 4 +-
fs/smb/client/cifs_debug.c | 2 +-
fs/smb/client/cifs_swn.h | 14 +-
fs/smb/client/cifsfs.c | 6 +-
fs/smb/client/cifsglob.h | 7 +-
fs/smb/client/connect.c | 4 +-
fs/smb/client/file.c | 2 +-
fs/smb/client/fs_context.c | 422 ++++++++++++++++++++++++++++++++++++-
fs/smb/client/misc.c | 5 -
fs/smb/client/smb1ops.c | 7 +-
fs/smb/client/smb2ops.c | 2 +-
fs/smb/client/smb2pdu.c | 13 +-
fs/smb/client/trace.h | 2 +
14 files changed, 530 insertions(+), 30 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/9] smb: client: sync runtime state into ctx on reconfigure
2026-07-02 11:35 [PATCH RESEND 0/9] smb: client: remount reconfigure option fixes rajasimandalos
@ 2026-07-02 11:35 ` rajasimandalos
2026-07-02 11:35 ` [PATCH 2/9] smb: client: block non-reconfigurable option changes on remount rajasimandalos
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: rajasimandalos @ 2026-07-02 11:35 UTC (permalink / raw)
To: linux-cifs; +Cc: bharathsm, msetiya, smfrench, sfrench, stfrench, Rajasi Mandal
From: Rajasi Mandal <rajasimandal@microsoft.com>
smb3_init_fs_context() builds a fresh context with init defaults on
every call, including reconfigure (remount). Many fields displayed
by cifs_show_options() are sourced from tcon/server/ses rather than
from ctx, so the init defaults do not reflect the live mount and
cannot be used as a baseline for comparing new vs old options on
remount.
Detect FS_CONTEXT_FOR_RECONFIGURE in smb3_init_fs_context() and
duplicate the existing cifs_sb->ctx instead. Before duplicating,
sync ctx with runtime state via a new helper
smb3_sync_ctx_from_runtime() so the baseline matches what
cifs_show_options() displays. Add srv_lock / tc_lock around the
relevant runtime writers (SMB2_negotiate, SMB2_tcon,
reset_cifs_unix_caps, cifs_swn_set_server_dstaddr) so the helper
can read them without torn-read races.
Also preserve inherited multichannel/max_channels values in
smb3_handle_conflicting_options() during reconfigure when neither
option is explicitly specified, since the dup'd context already
carries them.
This is preparatory plumbing for a subsequent commit that compares
new_ctx against old_ctx in smb3_verify_reconfigure_ctx() to reject
non-reconfigurable option changes.
Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
Reviewed-by: Meetakshi Setiya <msetiya@microsoft.com>
---
fs/smb/client/cifs_swn.h | 14 ++++-
fs/smb/client/fs_context.c | 111 +++++++++++++++++++++++++++++++++++++
fs/smb/client/smb1ops.c | 7 ++-
fs/smb/client/smb2pdu.c | 11 +++-
4 files changed, 139 insertions(+), 4 deletions(-)
diff --git a/fs/smb/client/cifs_swn.h b/fs/smb/client/cifs_swn.h
index 955d07b69450..caf0779d4d07 100644
--- a/fs/smb/client/cifs_swn.h
+++ b/fs/smb/client/cifs_swn.h
@@ -26,11 +26,21 @@ void cifs_swn_check(void);
static inline bool cifs_swn_set_server_dstaddr(struct TCP_Server_Info *server)
{
+ bool ret = false;
+
+ /*
+ * srv_lock serializes the 128-byte sockaddr_storage write against
+ * concurrent readers (e.g. cifs_show_address(), reconn_set_ipaddr_
+ * from_hostname() snapshot, smb3_sync_ctx_from_runtime()) and other
+ * writers like cifs_chan_update_iface() which already use srv_lock.
+ */
+ spin_lock(&server->srv_lock);
if (server->use_swn_dstaddr) {
server->dstaddr = server->swn_dstaddr;
- return true;
+ ret = true;
}
- return false;
+ spin_unlock(&server->srv_lock);
+ return ret;
}
static inline void cifs_swn_reset_server_dstaddr(struct TCP_Server_Info *server)
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 9addc74ce57e..576a78b6d0cb 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -926,6 +926,81 @@ static void smb3_fs_context_free(struct fs_context *fc)
smb3_cleanup_fs_context(ctx);
}
+/*
+ * Sync cifs_sb->ctx with runtime state from tcon/server/ses so the
+ * baseline matches what cifs_show_options() displays. Wide fields
+ * (dstaddr, ops/vals) are protected by the matching server/tcon lock;
+ * the remaining word-sized scalars rely on the same unsynchronized-read
+ * pattern already used by cifs_show_options().
+ */
+static int smb3_sync_ctx_from_runtime(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 cifs_ses *ses = tcon->ses;
+ struct smb3_fs_context *ctx = cifs_sb->ctx;
+ const char *domain;
+ int unicode;
+
+ /*
+ * Server fields that can drift from ctx after mount:
+ * - ops/vals: dialect renegotiation during reconnect (paired,
+ * so read under srv_lock to match the writer in SMB2_negotiate)
+ * - dstaddr: SWN witness failover updates server->dstaddr; the
+ * 128-byte sockaddr_storage is not atomic, so srv_lock is
+ * required against torn reads
+ * - nosharesock: can be flipped to true post-mount by SMB2_tcon
+ * on STATUS_BAD_NETWORK_NAME with ISOLATED_TRANSPORT, so read
+ * under srv_lock to pair with that writer
+ */
+ spin_lock(&server->srv_lock);
+ ctx->ops = server->ops;
+ ctx->vals = server->vals;
+ ctx->dstaddr = server->dstaddr;
+ ctx->nosharesock = server->nosharesock;
+ spin_unlock(&server->srv_lock);
+
+ /*
+ * tcon->unix_ext can be flipped post-mount by reset_cifs_unix_caps()
+ * on SMB1 reconnect (smb1_reconnect path). Read under tc_lock to pair
+ * with that writer. tcon->posix_extensions is only ever set at
+ * mount-time pre-publish, but read it under the same lock so the
+ * derived linux_ext/no_linux_ext pair is consistent.
+ */
+ spin_lock(&tcon->tc_lock);
+ if (tcon->posix_extensions || tcon->unix_ext) {
+ ctx->linux_ext = 1;
+ ctx->no_linux_ext = 0;
+ } else {
+ ctx->linux_ext = 0;
+ ctx->no_linux_ext = 1;
+ }
+ spin_unlock(&tcon->tc_lock);
+ ctx->seal = tcon->seal;
+ ctx->persistent = tcon->use_persistent;
+ ctx->nopersistent = !tcon->use_persistent;
+ ctx->resilient = tcon->use_resilient;
+ ctx->witness = tcon->use_witness;
+
+ /*
+ * Session fields: domainName and unicode are effectively
+ * write-once (set during session setup, never freed/replaced
+ * while the session exists), so plain reads are safe.
+ */
+ domain = ses->domainName;
+ unicode = ses->unicode;
+
+ if (domain && !ctx->domainname) {
+ ctx->domainname = kstrdup(domain, GFP_KERNEL);
+ if (!ctx->domainname)
+ return -ENOMEM;
+ }
+ if (unicode >= 0)
+ ctx->unicode = unicode;
+
+ return 0;
+}
+
/*
* Compare the old and new proposed context during reconfigure
* and check if the changes are compatible.
@@ -1961,6 +2036,42 @@ int smb3_init_fs_context(struct fs_context *fc)
char *nodename = utsname()->nodename;
int i;
+ /*
+ * For reconfigure (remount), duplicate the existing mount context
+ * instead of building one from scratch with init defaults.
+ *
+ * VFS sets fc->root before calling init_fs_context for reconfigure,
+ * so we can access the existing superblock's context. We first sync
+ * cifs_sb->ctx with runtime state (tcon/server/ses) so that ctx
+ * matches what cifs_show_options() displays. Then we dup old_ctx
+ * into new_ctx. The parser will overwrite only the options
+ * explicitly passed on remount, so any difference between new_ctx
+ * and old_ctx in smb3_verify_reconfigure_ctx() represents a real,
+ * intentional change by the user.
+ */
+ if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
+ struct cifs_sb_info *cifs_sb = CIFS_SB(fc->root->d_sb);
+ int rc;
+
+ rc = smb3_sync_ctx_from_runtime(cifs_sb);
+ if (rc)
+ return rc;
+
+ ctx = kzalloc_obj(struct smb3_fs_context);
+ if (!ctx)
+ return -ENOMEM;
+
+ rc = smb3_fs_context_dup(ctx, cifs_sb->ctx);
+ if (rc) {
+ kfree(ctx);
+ return rc;
+ }
+
+ fc->fs_private = ctx;
+ fc->ops = &smb3_fs_context_ops;
+ return 0;
+ }
+
ctx = kzalloc_obj(struct smb3_fs_context);
if (unlikely(!ctx))
return -ENOMEM;
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index d34b3d99f6ed..33c890e14988 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -36,11 +36,16 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
if (ctx && ctx->no_linux_ext) {
tcon->fsUnixInfo.Capability = 0;
+ spin_lock(&tcon->tc_lock);
tcon->unix_ext = 0; /* Unix Extensions disabled */
+ spin_unlock(&tcon->tc_lock);
cifs_dbg(FYI, "Linux protocol extensions disabled\n");
return;
- } else if (ctx)
+ } else if (ctx) {
+ spin_lock(&tcon->tc_lock);
tcon->unix_ext = 1; /* Unix Extensions supported */
+ spin_unlock(&tcon->tc_lock);
+ }
if (!tcon->unix_ext) {
cifs_dbg(FYI, "Unix extensions disabled so not set on reconnect\n");
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 4972cfe249f6..958ca0753774 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -1189,8 +1189,10 @@ SMB2_negotiate(const unsigned int xid,
goto neg_exit;
case SMB311_PROT_ID:
/* ops set to 3.0 by default for default so update */
+ spin_lock(&server->srv_lock);
server->ops = &smb311_operations;
server->vals = &smb311_values;
+ spin_unlock(&server->srv_lock);
break;
default:
break;
@@ -1205,12 +1207,16 @@ SMB2_negotiate(const unsigned int xid,
goto neg_exit;
case SMB21_PROT_ID:
/* ops set to 3.0 by default for default so update */
+ spin_lock(&server->srv_lock);
server->ops = &smb21_operations;
server->vals = &smb21_values;
+ spin_unlock(&server->srv_lock);
break;
case SMB311_PROT_ID:
+ spin_lock(&server->srv_lock);
server->ops = &smb311_operations;
server->vals = &smb311_values;
+ spin_unlock(&server->srv_lock);
break;
default:
break;
@@ -2226,8 +2232,11 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
if (server->ops->validate_negotiate)
rc = server->ops->validate_negotiate(xid, tcon);
if (rc == 0) /* See MS-SMB2 2.2.10 and 3.2.5.5 */
- if (tcon->share_flags & SMB2_SHAREFLAG_ISOLATED_TRANSPORT)
+ if (tcon->share_flags & SMB2_SHAREFLAG_ISOLATED_TRANSPORT) {
+ spin_lock(&server->srv_lock);
server->nosharesock = true;
+ spin_unlock(&server->srv_lock);
+ }
tcon_exit:
free_rsp_buf(resp_buftype, rsp);
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/9] smb: client: block non-reconfigurable option changes on remount
2026-07-02 11:35 [PATCH RESEND 0/9] smb: client: remount reconfigure option fixes rajasimandalos
2026-07-02 11:35 ` [PATCH 1/9] smb: client: sync runtime state into ctx on reconfigure rajasimandalos
@ 2026-07-02 11:35 ` rajasimandalos
2026-07-02 11:35 ` [PATCH 3/9] smb: client: sync retrans " rajasimandalos
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: rajasimandalos @ 2026-07-02 11:35 UTC (permalink / raw)
To: linux-cifs; +Cc: bharathsm, msetiya, smfrench, sfrench, stfrench, Rajasi Mandal
From: Rajasi Mandal <rajasimandal@microsoft.com>
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@microsoft.com>
Reviewed-by: Meetakshi Setiya <msetiya@microsoft.com>
---
fs/smb/client/fs_context.c | 141 +++++++++++++++++++++++++++++++++++++
1 file changed, 141 insertions(+)
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 576a78b6d0cb..d5a7d4dd402b 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1070,6 +1070,147 @@ 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->echo_interval != old_ctx->echo_interval) {
+ cifs_errorf(fc, "can not change echo_interval 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 (!cifs_match_ipaddr((struct sockaddr *)&new_ctx->srcaddr,
+ (struct sockaddr *)&old_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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/9] smb: client: sync retrans on remount
2026-07-02 11:35 [PATCH RESEND 0/9] smb: client: remount reconfigure option fixes rajasimandalos
2026-07-02 11:35 ` [PATCH 1/9] smb: client: sync runtime state into ctx on reconfigure rajasimandalos
2026-07-02 11:35 ` [PATCH 2/9] smb: client: block non-reconfigurable option changes on remount rajasimandalos
@ 2026-07-02 11:35 ` rajasimandalos
2026-07-02 11:35 ` [PATCH 4/9] smb: client: block cache=ro and cache=singleclient " rajasimandalos
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: rajasimandalos @ 2026-07-02 11:35 UTC (permalink / raw)
To: linux-cifs; +Cc: bharathsm, msetiya, smfrench, sfrench, stfrench, 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 previous patch in this series ("smb: client: sync runtime state
into ctx on reconfigure") duplicates the existing context on remount,
so a bare 'mount -o remount' carries the old retrans value forward and
the parser only overwrites it when the user explicitly passes
retrans=N. No special-casing for the bare-remount /proc/mounts replay
is therefore needed; in particular, an explicit retrans=0 from the
user now correctly resets the value to the compile-time default.
Writes to server->retrans are unsynchronized to match the existing
convention: every other reader of the field (smb2ops.c retry path,
cifs_show_options(), the original cifs_get_tcp_session() writer) does
not take server->srv_lock, and match_server() only reads it under
srv_lock as part of the larger match function.
Note that retrans lives on TCP_Server_Info and is therefore shared
across all mounts to the same server; reconfiguring one mount updates
the value seen by every other mount sharing the connection. This is
consistent with the existing semantics: cifs_show_options() already
reads server->retrans for /proc/mounts on every mount, and the
runtime retry path always uses the server's value rather than any
per-mount copy.
Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
Reviewed-by: Meetakshi Setiya <msetiya@microsoft.com>
---
fs/smb/client/fs_context.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index d5a7d4dd402b..bfbea0648f6a 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1278,6 +1278,24 @@ static void smb3_sync_ses_chan_max(struct cifs_ses *ses, size_t max_channels)
spin_unlock(&ses->chan_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. Note these live on TCP_Server_Info and are therefore
+ * shared across all mounts to the same server; reconfiguring one mount
+ * updates the value seen by every other mount sharing the connection,
+ * matching how cifs_show_options() and the runtime retry path already
+ * read them unsynchronized from the server struct.
+ */
+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;
+
+ server->retrans = ctx->retrans;
+}
+
static int smb3_reconfigure(struct fs_context *fc)
{
struct smb3_fs_context *ctx = smb3_fc2context(fc);
@@ -1447,6 +1465,8 @@ static int smb3_reconfigure(struct fs_context *fc)
if (!rc)
rc = dfs_cache_remount_fs(cifs_sb);
#endif
+ if (!rc)
+ smb3_sync_server_opts(cifs_sb);
return rc;
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/9] smb: client: block cache=ro and cache=singleclient on remount
2026-07-02 11:35 [PATCH RESEND 0/9] smb: client: remount reconfigure option fixes rajasimandalos
` (2 preceding siblings ...)
2026-07-02 11:35 ` [PATCH 3/9] smb: client: sync retrans " rajasimandalos
@ 2026-07-02 11:35 ` rajasimandalos
2026-07-02 11:35 ` [PATCH 5/9] smb: client: apply rasize " rajasimandalos
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: rajasimandalos @ 2026-07-02 11:35 UTC (permalink / raw)
To: linux-cifs; +Cc: bharathsm, msetiya, smfrench, sfrench, stfrench, 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>
Reviewed-by: Meetakshi Setiya <msetiya@microsoft.com>
---
fs/smb/client/fs_context.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index bfbea0648f6a..659fb0adb528 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1211,6 +1211,15 @@ static int smb3_verify_reconfigure_ctx(struct fs_context *fc,
cifs_errorf(fc, "can not change rdma during remount\n");
return -EINVAL;
}
+ /* init default: cache_ro = false, cache_rw = false (i.e. cache=strict) */
+ 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] 10+ messages in thread
* [PATCH 5/9] smb: client: apply rasize on remount
2026-07-02 11:35 [PATCH RESEND 0/9] smb: client: remount reconfigure option fixes rajasimandalos
` (3 preceding siblings ...)
2026-07-02 11:35 ` [PATCH 4/9] smb: client: block cache=ro and cache=singleclient " rajasimandalos
@ 2026-07-02 11:35 ` rajasimandalos
2026-07-02 11:35 ` [PATCH 6/9] smb: client: move struct tcon_list to cifsglob.h rajasimandalos
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: rajasimandalos @ 2026-07-02 11:35 UTC (permalink / raw)
To: linux-cifs; +Cc: bharathsm, msetiya, smfrench, sfrench, stfrench, 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>
Reviewed-by: Meetakshi Setiya <msetiya@microsoft.com>
---
fs/smb/client/fs_context.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 659fb0adb528..0a72e1089ff7 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1313,7 +1313,7 @@ static int smb3_reconfigure(struct fs_context *fc)
struct dentry *root = fc->root;
struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb);
struct cifs_ses *ses = cifs_sb_master_tcon(cifs_sb)->ses;
- unsigned int rsize = ctx->rsize, wsize = ctx->wsize;
+ unsigned int rsize = ctx->rsize, wsize = ctx->wsize, rasize = ctx->rasize;
char *new_password = NULL, *new_password2 = NULL;
bool need_recon = false;
bool need_mchan_update;
@@ -1379,9 +1379,10 @@ static int smb3_reconfigure(struct fs_context *fc)
STEAL_STRING_SENSITIVE(cifs_sb, ctx, password2);
}
- /* if rsize or wsize not passed in on remount, use previous values */
+ /* if rsize, wsize, or rasize not passed in on remount, use previous values */
ctx->rsize = rsize ? CIFS_ALIGN_RSIZE(fc, rsize) : cifs_sb->ctx->rsize;
ctx->wsize = wsize ? CIFS_ALIGN_WSIZE(fc, wsize) : cifs_sb->ctx->wsize;
+ ctx->rasize = rasize ? rasize : cifs_sb->ctx->rasize;
new_ctx = kzalloc_obj(*new_ctx);
if (!new_ctx) {
@@ -1470,6 +1471,12 @@ static int smb3_reconfigure(struct fs_context *fc)
smb3_cleanup_fs_context(old_ctx);
old_ctx = NULL;
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] 10+ messages in thread
* [PATCH 6/9] smb: client: move struct tcon_list to cifsglob.h
2026-07-02 11:35 [PATCH RESEND 0/9] smb: client: remount reconfigure option fixes rajasimandalos
` (4 preceding siblings ...)
2026-07-02 11:35 ` [PATCH 5/9] smb: client: apply rasize " rajasimandalos
@ 2026-07-02 11:35 ` rajasimandalos
2026-07-02 11:35 ` [PATCH 7/9] smb: client: allow nolease option to be reconfigured on remount rajasimandalos
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: rajasimandalos @ 2026-07-02 11:35 UTC (permalink / raw)
To: linux-cifs; +Cc: bharathsm, msetiya, smfrench, sfrench, stfrench, Rajasi Mandal
From: Rajasi Mandal <rajasimandal@microsoft.com>
struct tcon_list is a small list-node wrapper that pairs a list_head
with a cifs_tcon pointer, used to safely iterate tcons under a
superblock outside tlink_tree_lock.
It is currently file-static in misc.c, used only by
cifs_close_all_deferred_files_sb(). Move it next to the similar
struct file_list in cifsglob.h so that other _sb() iteration helpers
can reuse it instead of redefining the same shape locally.
No functional change.
Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
Reviewed-by: Bharath SM <bharathsm@microsoft.com>
---
fs/smb/client/cifsglob.h | 5 +++++
fs/smb/client/misc.c | 5 -----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index a462c1590a9e..38e27ba6d8f6 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -1807,6 +1807,11 @@ struct file_list {
struct cifsFileInfo *cfile;
};
+struct tcon_list {
+ struct list_head entry;
+ struct cifs_tcon *tcon;
+};
+
struct cifs_mount_ctx {
struct cifs_sb_info *cifs_sb;
struct smb3_fs_context *fs_ctx;
diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c
index 0c54b9b79a2c..7ef135dc8268 100644
--- a/fs/smb/client/misc.c
+++ b/fs/smb/client/misc.c
@@ -28,11 +28,6 @@
#include "fs_context.h"
#include "cached_dir.h"
-struct tcon_list {
- struct list_head entry;
- struct cifs_tcon *tcon;
-};
-
/* The xid serves as a useful identifier for each incoming vfs request,
in a similar way to the mid which is useful to track each sent smb,
and CurrentXid can also provide a running counter (although it
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/9] smb: client: allow nolease option to be reconfigured on remount
2026-07-02 11:35 [PATCH RESEND 0/9] smb: client: remount reconfigure option fixes rajasimandalos
` (5 preceding siblings ...)
2026-07-02 11:35 ` [PATCH 6/9] smb: client: move struct tcon_list to cifsglob.h rajasimandalos
@ 2026-07-02 11:35 ` rajasimandalos
2026-07-02 11:35 ` [PATCH 8/9] smb: client: review fixes for remount ctx/retrans sync (patches 1-4) rajasimandalos
2026-07-02 11:35 ` [PATCH 9/9] smb: client: review fixes for nolease remount (patch 7) rajasimandalos
8 siblings, 0 replies; 10+ messages in thread
From: rajasimandalos @ 2026-07-02 11:35 UTC (permalink / raw)
To: linux-cifs; +Cc: bharathsm, msetiya, smfrench, sfrench, stfrench, Rajasi Mandal
From: Rajasi Mandal <rajasimandal@microsoft.com>
Changing nolease via remount is silently accepted but has no effect:
the value is not propagated to the live tcons, and stale lease-bearing
state from before the switch keeps using the old behavior.
Make nolease take effect on remount:
- Add smb3_sync_tcon_opts() which walks the tlink_tree under
tlink_tree_lock and propagates ctx->no_lease to tcon->no_lease for
every tcon under this superblock so future opens honor the new
setting. Call it from smb3_reconfigure() after the context has
been updated.
- On switch to nolease, drop deferred file handles via
cifs_close_all_deferred_files_sb() (each holds an active lease).
- On switch to nolease, evict cached directory fids via the new
invalidate_all_cached_dirs_sb() helper (each holds a directory
lease).
invalidate_all_cached_dirs_sb() mirrors cifs_close_all_deferred_files_sb():
take tc_count refs on every tcon under tlink_tree_lock, drop the lock,
then call invalidate_all_cached_dirs() per tcon (it can sleep). Two
new tcon_ref trace tags are added for the audit trail.
Move tcon->no_lease out of the bitfield word into a plain bool. As a
runtime writer it now shares storage with need_reconnect/need_reopen_files,
which the reconnect/reopen paths update locklessly; a bitfield write is a
read-modify-write of the whole word and could clobber a concurrent
need_reconnect update. Its own memory location removes that race.
Existing open handles keep their leases until the server breaks them
or userspace closes the file -- nolease only governs new opens.
Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
Reviewed-by: Bharath SM <bharathsm@microsoft.com>
---
fs/smb/client/cached_dir.c | 44 ++++++++++++++++++++++++++++++++++++++
fs/smb/client/cached_dir.h | 1 +
fs/smb/client/cifsglob.h | 2 +-
fs/smb/client/fs_context.c | 40 ++++++++++++++++++++++++++++++++++
fs/smb/client/trace.h | 2 ++
5 files changed, 88 insertions(+), 1 deletion(-)
diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index 88d5e9a32f28..58d68a8f4d41 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -637,6 +637,50 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon, bool sync)
flush_delayed_work(&cfids->laundromat_work);
}
+/*
+ * Invalidate cached directory entries across all tcons under a
+ * superblock. Collect references on each tcon under tlink_tree_lock,
+ * then call invalidate_all_cached_dirs() outside the spinlock since it
+ * can sleep. Holding a tc_count reference prevents the tcon from being
+ * freed by tlink_expire_delayed() between dropping the spinlock and
+ * the call.
+ */
+void invalidate_all_cached_dirs_sb(struct cifs_sb_info *cifs_sb)
+{
+ struct rb_root *root = &cifs_sb->tlink_tree;
+ struct rb_node *node;
+ struct cifs_tcon *tcon;
+ struct tcon_link *tlink;
+ struct tcon_list *tmp_list, *q;
+ LIST_HEAD(tcon_head);
+
+ spin_lock(&cifs_sb->tlink_tree_lock);
+ for (node = rb_first(root); node; node = rb_next(node)) {
+ tlink = rb_entry(node, struct tcon_link, tl_rbnode);
+ tcon = tlink_tcon(tlink);
+ if (IS_ERR(tcon))
+ continue;
+ tmp_list = kmalloc_obj(struct tcon_list, GFP_ATOMIC);
+ if (!tmp_list)
+ break;
+ tmp_list->tcon = tcon;
+ spin_lock(&tcon->tc_lock);
+ ++tcon->tc_count;
+ trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
+ netfs_trace_tcon_ref_get_cached_inval_sb);
+ spin_unlock(&tcon->tc_lock);
+ list_add_tail(&tmp_list->entry, &tcon_head);
+ }
+ spin_unlock(&cifs_sb->tlink_tree_lock);
+
+ list_for_each_entry_safe(tmp_list, q, &tcon_head, entry) {
+ invalidate_all_cached_dirs(tmp_list->tcon, true);
+ list_del(&tmp_list->entry);
+ cifs_put_tcon(tmp_list->tcon, netfs_trace_tcon_ref_put_cached_inval_sb);
+ kfree(tmp_list);
+ }
+}
+
static void
cached_dir_offload_close(struct work_struct *work)
{
diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
index fc756836da95..606ba2a0b64f 100644
--- a/fs/smb/client/cached_dir.h
+++ b/fs/smb/client/cached_dir.h
@@ -90,6 +90,7 @@ void close_cached_dir(struct cached_fid *cfid);
void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon,
const char *name, struct cifs_sb_info *cifs_sb);
void close_all_cached_dirs(struct cifs_sb_info *cifs_sb);
+void invalidate_all_cached_dirs_sb(struct cifs_sb_info *cifs_sb);
void invalidate_all_cached_dirs(struct cifs_tcon *tcon, bool sync);
bool cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16]);
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index 38e27ba6d8f6..713ca152b0ea 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -1262,9 +1262,9 @@ struct cifs_tcon {
bool need_reopen_files:1; /* need to reopen tcon file handles */
bool use_resilient:1; /* use resilient instead of durable handles */
bool use_persistent:1; /* use persistent instead of durable handles */
- bool no_lease:1; /* Do not request leases on files or directories */
bool use_witness:1; /* use witness protocol */
bool dummy:1; /* dummy tcon used for reconnecting channels */
+ bool no_lease; /* Do not request leases on files or directories */
__le32 capabilities;
__u32 share_flags;
__u32 maximal_access;
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 0a72e1089ff7..53f986d8e9e0 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -35,6 +35,7 @@
#include "nterr.h"
#include "rfc1002pdu.h"
#include "fs_context.h"
+#include "cached_dir.h"
DEFINE_MUTEX(cifs_mount_mutex);
@@ -1287,6 +1288,43 @@ static void smb3_sync_ses_chan_max(struct cifs_ses *ses, size_t max_channels)
spin_unlock(&ses->chan_lock);
}
+/*
+ * Propagate ctx->no_lease to every tcon under this superblock so future
+ * opens honor the new setting after a remount. When switching to nolease,
+ * also drop deferred file handles and invalidate cached directory fids,
+ * since each holds an active lease from before the switch.
+ *
+ * Existing open handles keep their leases until the server breaks them
+ * or userspace closes the file -- nolease only governs new opens.
+ */
+static void smb3_sync_tcon_opts(struct cifs_sb_info *cifs_sb,
+ struct smb3_fs_context *ctx)
+{
+ struct tcon_link *tlink;
+ struct cifs_tcon *tcon;
+ struct rb_node *node;
+
+ spin_lock(&cifs_sb->tlink_tree_lock);
+ for (node = rb_first(&cifs_sb->tlink_tree); node; node = rb_next(node)) {
+ tlink = rb_entry(node, struct tcon_link, tl_rbnode);
+ tcon = tlink_tcon(tlink);
+ if (IS_ERR(tcon))
+ continue;
+ tcon->no_lease = ctx->no_lease;
+ }
+ spin_unlock(&cifs_sb->tlink_tree_lock);
+
+ /*
+ * Both _sb() helpers iterate all tcons internally and handle
+ * their own locking. They can sleep, so they must be called
+ * outside tlink_tree_lock.
+ */
+ if (ctx->no_lease) {
+ cifs_close_all_deferred_files_sb(cifs_sb);
+ invalidate_all_cached_dirs_sb(cifs_sb);
+ }
+}
+
/*
* Synchronize server-level options that are stored on TCP_Server_Info
* at mount time. These fields are consulted at runtime (retry logic)
@@ -1483,6 +1521,8 @@ static int smb3_reconfigure(struct fs_context *fc)
#endif
if (!rc)
smb3_sync_server_opts(cifs_sb);
+ if (!rc)
+ smb3_sync_tcon_opts(cifs_sb, cifs_sb->ctx);
return rc;
diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h
index 5b21ad3c15fb..1e61a36759ed 100644
--- a/fs/smb/client/trace.h
+++ b/fs/smb/client/trace.h
@@ -173,6 +173,7 @@
EM(netfs_trace_tcon_ref_free_ipc, "FRE Ipc ") \
EM(netfs_trace_tcon_ref_free_ipc_fail, "FRE Ipc-F ") \
EM(netfs_trace_tcon_ref_free_reconnect_server, "FRE Reconn") \
+ EM(netfs_trace_tcon_ref_get_cached_inval_sb, "GET Ch-IvS") \
EM(netfs_trace_tcon_ref_get_cached_laundromat, "GET Ch-Lau") \
EM(netfs_trace_tcon_ref_get_cached_lease_break, "GET Ch-Lea") \
EM(netfs_trace_tcon_ref_get_cancelled_close, "GET Cn-Cls") \
@@ -186,6 +187,7 @@
EM(netfs_trace_tcon_ref_new_ipc, "NEW Ipc ") \
EM(netfs_trace_tcon_ref_new_reconnect_server, "NEW Reconn") \
EM(netfs_trace_tcon_ref_put_cached_close, "PUT Ch-Cls") \
+ EM(netfs_trace_tcon_ref_put_cached_inval_sb, "PUT Ch-IvS") \
EM(netfs_trace_tcon_ref_put_cancelled_close, "PUT Cn-Cls") \
EM(netfs_trace_tcon_ref_put_cancelled_close_fid, "PUT Cn-Fid") \
EM(netfs_trace_tcon_ref_put_cancelled_mid, "PUT Cn-Mid") \
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 8/9] smb: client: review fixes for remount ctx/retrans sync (patches 1-4)
2026-07-02 11:35 [PATCH RESEND 0/9] smb: client: remount reconfigure option fixes rajasimandalos
` (6 preceding siblings ...)
2026-07-02 11:35 ` [PATCH 7/9] smb: client: allow nolease option to be reconfigured on remount rajasimandalos
@ 2026-07-02 11:35 ` rajasimandalos
2026-07-02 11:35 ` [PATCH 9/9] smb: client: review fixes for nolease remount (patch 7) rajasimandalos
8 siblings, 0 replies; 10+ messages in thread
From: rajasimandalos @ 2026-07-02 11:35 UTC (permalink / raw)
To: linux-cifs; +Cc: bharathsm, msetiya, smfrench, sfrench, stfrench, Rajasi Mandal
From: Rajasi Mandal <rajasimandal@microsoft.com>
Fold the review feedback for the first four remount patches into one
change. Each fix, in two lines:
- ctx sync (patch 1): sync runtime state into a private reconfigure
context, never the shared cifs_sb->ctx, to avoid racing concurrent
fspick/remount and /proc/mounts readers.
- ctx sync (patch 1): compare the new context against a runtime-synced
private base_ctx (dup + sync), freed before commit, instead of the raw
cifs_sb->ctx.
- ctx sync (patch 1): drop the fabricated "nopersistent = !use_persistent"
derivation; nopersistent is an independent user option and must keep the
dup'd value.
- block options (patch 2): mention "(signloosely)" in the ignore_signature
remount rejection so the message names the user-facing option.
- retrans (patch 3): read/write server->retrans with READ_ONCE/WRITE_ONCE
to pair the new remount writer with the lockless retry-path reader.
- retrans (patch 3): seed the baseline from READ_ONCE(server->retrans) so a
bare remount carries the live value forward instead of clobbering it.
- block cache (patch 4): reword the cache-mode comment to state that
cache=ro sets cache_ro and cache=singleclient sets cache_rw.
Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
---
fs/smb/client/cifsfs.c | 6 +-
fs/smb/client/connect.c | 4 +-
fs/smb/client/fs_context.c | 122 +++++++++++++++++++++++++++++--------
fs/smb/client/smb2ops.c | 2 +-
4 files changed, 104 insertions(+), 30 deletions(-)
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index 6b97f7a91235..e99d427fb2c5 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -612,6 +612,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
struct sockaddr *srcaddr;
unsigned int sbflags;
+ unsigned int retrans;
srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr;
@@ -765,8 +766,9 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
seq_printf(s, ",rasize=%u", cifs_sb->ctx->rasize);
if (tcon->ses->server->min_offload)
seq_printf(s, ",esize=%u", tcon->ses->server->min_offload);
- if (tcon->ses->server->retrans)
- seq_printf(s, ",retrans=%u", tcon->ses->server->retrans);
+ retrans = READ_ONCE(tcon->ses->server->retrans);
+ if (retrans)
+ seq_printf(s, ",retrans=%u", retrans);
seq_printf(s, ",echo_interval=%lu",
tcon->ses->server->echo_interval / HZ);
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 104658e318b6..14dd472c2b0f 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1657,7 +1657,7 @@ static int match_server(struct TCP_Server_Info *server,
if (server->min_offload != ctx->min_offload)
return 0;
- if (server->retrans != ctx->retrans)
+ if (READ_ONCE(server->retrans) != ctx->retrans)
return 0;
return 1;
@@ -1872,7 +1872,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
*/
__module_get(THIS_MODULE);
tcp_ses->min_offload = ctx->min_offload;
- tcp_ses->retrans = ctx->retrans;
+ WRITE_ONCE(tcp_ses->retrans, ctx->retrans);
/*
* at this point we are the only ones with the pointer
* to the struct since the kernel thread not created yet
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 53f986d8e9e0..89bf6f4604b3 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -928,18 +928,22 @@ static void smb3_fs_context_free(struct fs_context *fc)
}
/*
- * Sync cifs_sb->ctx with runtime state from tcon/server/ses so the
- * baseline matches what cifs_show_options() displays. Wide fields
- * (dstaddr, ops/vals) are protected by the matching server/tcon lock;
- * the remaining word-sized scalars rely on the same unsynchronized-read
- * pattern already used by cifs_show_options().
+ * Sync a private reconfigure context with runtime state from
+ * tcon/server/ses so the baseline matches what cifs_show_options()
+ * displays. @ctx must be the caller's freshly-duplicated context, not
+ * the live cifs_sb->ctx: this function writes into @ctx, and mutating
+ * the shared cifs_sb->ctx here would race with concurrent fspick/remount
+ * and /proc/mounts readers. Wide fields (dstaddr, ops/vals) are read
+ * under the matching server/tcon lock; the remaining word-sized scalars
+ * rely on the same unsynchronized-read pattern already used by
+ * cifs_show_options().
*/
-static int smb3_sync_ctx_from_runtime(struct cifs_sb_info *cifs_sb)
+static int smb3_sync_ctx_from_runtime(struct cifs_sb_info *cifs_sb,
+ struct smb3_fs_context *ctx)
{
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
struct TCP_Server_Info *server = tcon->ses->server;
struct cifs_ses *ses = tcon->ses;
- struct smb3_fs_context *ctx = cifs_sb->ctx;
const char *domain;
int unicode;
@@ -961,6 +965,16 @@ static int smb3_sync_ctx_from_runtime(struct cifs_sb_info *cifs_sb)
ctx->nosharesock = server->nosharesock;
spin_unlock(&server->srv_lock);
+ /*
+ * retrans lives on the shared TCP_Server_Info and can be updated by
+ * a remount of any mount sharing the connection. Sync it from the
+ * live server so a bare remount carries the current value forward
+ * instead of writing a stale per-mount copy back in
+ * smb3_sync_server_opts(). Read with READ_ONCE to pair with the
+ * lockless WRITE_ONCE writers and the runtime retry-path reader.
+ */
+ ctx->retrans = READ_ONCE(server->retrans);
+
/*
* tcon->unix_ext can be flipped post-mount by reset_cifs_unix_caps()
* on SMB1 reconnect (smb1_reconnect path). Read under tc_lock to pair
@@ -978,15 +992,27 @@ static int smb3_sync_ctx_from_runtime(struct cifs_sb_info *cifs_sb)
}
spin_unlock(&tcon->tc_lock);
ctx->seal = tcon->seal;
+ /*
+ * persistent reflects the live tcon->use_persistent so the baseline
+ * matches what cifs_show_options() reports (persistenthandles). Do
+ * NOT derive nopersistent from use_persistent: persistent and
+ * nopersistent are independent user options and use_persistent is a
+ * derived runtime result. nopersistent is not reported by
+ * cifs_show_options(), so it must keep the user's original value
+ * (carried by the dup); fabricating it here would, after the
+ * reconfigure commits the ctx, wrongly suppress persistent-handle
+ * auto-enable on continuous-availability shares at reconnect.
+ */
ctx->persistent = tcon->use_persistent;
- ctx->nopersistent = !tcon->use_persistent;
ctx->resilient = tcon->use_resilient;
ctx->witness = tcon->use_witness;
/*
* Session fields: domainName and unicode are effectively
* write-once (set during session setup, never freed/replaced
- * while the session exists), so plain reads are safe.
+ * while the session exists), so plain reads are safe. @ctx is
+ * the caller's private copy, so filling in a missing domainname
+ * here cannot leak or race.
*/
domain = ses->domainName;
unicode = ses->unicode;
@@ -1180,7 +1206,7 @@ static int smb3_verify_reconfigure_ctx(struct fs_context *fc,
return -EINVAL;
}
if (new_ctx->ignore_signature != old_ctx->ignore_signature) {
- cifs_errorf(fc, "can not change ignore_signature during remount\n");
+ cifs_errorf(fc, "can not change ignore_signature (signloosely) during remount\n");
return -EINVAL;
}
if (new_ctx->seal != old_ctx->seal) {
@@ -1212,7 +1238,11 @@ static int smb3_verify_reconfigure_ctx(struct fs_context *fc,
cifs_errorf(fc, "can not change rdma during remount\n");
return -EINVAL;
}
- /* init default: cache_ro = false, cache_rw = false (i.e. cache=strict) */
+ /*
+ * cache=ro sets cache_ro and cache=singleclient sets cache_rw; the
+ * other cache modes (strict/loose/none) leave both clear and are
+ * handled separately in smb3_update_mnt_flags().
+ */
if (new_ctx->cache_ro != old_ctx->cache_ro) {
cifs_errorf(fc, "can not change cache=ro during remount\n");
return -EINVAL;
@@ -1340,7 +1370,7 @@ 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;
- server->retrans = ctx->retrans;
+ WRITE_ONCE(server->retrans, ctx->retrans);
}
static int smb3_reconfigure(struct fs_context *fc)
@@ -1348,6 +1378,7 @@ static int smb3_reconfigure(struct fs_context *fc)
struct smb3_fs_context *ctx = smb3_fc2context(fc);
struct smb3_fs_context *new_ctx = NULL;
struct smb3_fs_context *old_ctx = NULL;
+ struct smb3_fs_context *base_ctx = NULL;
struct dentry *root = fc->root;
struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb);
struct cifs_ses *ses = cifs_sb_master_tcon(cifs_sb)->ses;
@@ -1360,9 +1391,37 @@ static int smb3_reconfigure(struct fs_context *fc)
if (ses->expired_pwd)
need_recon = true;
- rc = smb3_verify_reconfigure_ctx(fc, ctx, cifs_sb->ctx, need_recon);
+ /*
+ * Compare the new context against a runtime-synced baseline, not the
+ * raw cifs_sb->ctx. smb3_init_fs_context() syncs the new context
+ * (fc->fs_private) from runtime state, so the comparison baseline must
+ * be synced the same way; otherwise a field that drifted at runtime
+ * (e.g. dstaddr after witness failover, or use_persistent auto-enabled
+ * on a continuous-availability share) would look like a user-requested
+ * change and be rejected on an otherwise bare remount. Sync a private
+ * copy rather than cifs_sb->ctx: s_umount serializes reconfigures, but
+ * not the fspick/fsconfig init path, which dup()s cifs_sb->ctx in
+ * smb3_init_fs_context() before reconfigure_super() takes s_umount. An
+ * in-place sync would therefore race that lockless dup (e.g. a torn
+ * read of the 128-byte dstaddr).
+ */
+ base_ctx = kzalloc_obj(*base_ctx);
+ if (!base_ctx)
+ return -ENOMEM;
+ rc = smb3_fs_context_dup(base_ctx, cifs_sb->ctx);
if (rc)
- return rc;
+ goto free_base_ctx;
+ rc = smb3_sync_ctx_from_runtime(cifs_sb, base_ctx);
+ if (rc)
+ goto cleanup_base_ctx;
+
+ rc = smb3_verify_reconfigure_ctx(fc, ctx, base_ctx, need_recon);
+ if (rc)
+ goto cleanup_base_ctx;
+
+ smb3_cleanup_fs_context_contents(base_ctx);
+ kfree(base_ctx);
+ base_ctx = NULL;
rc = smb3_handle_conflicting_options(fc);
if (rc)
@@ -1537,6 +1596,13 @@ static int smb3_reconfigure(struct fs_context *fc)
free_old_ctx:
kfree(old_ctx);
+ return rc;
+
+cleanup_base_ctx:
+ smb3_cleanup_fs_context_contents(base_ctx);
+free_base_ctx:
+ kfree(base_ctx);
+
return rc;
}
@@ -2258,28 +2324,34 @@ int smb3_init_fs_context(struct fs_context *fc)
* instead of building one from scratch with init defaults.
*
* VFS sets fc->root before calling init_fs_context for reconfigure,
- * so we can access the existing superblock's context. We first sync
- * cifs_sb->ctx with runtime state (tcon/server/ses) so that ctx
- * matches what cifs_show_options() displays. Then we dup old_ctx
- * into new_ctx. The parser will overwrite only the options
- * explicitly passed on remount, so any difference between new_ctx
- * and old_ctx in smb3_verify_reconfigure_ctx() represents a real,
- * intentional change by the user.
+ * so we can access the existing superblock's context. We dup the
+ * live cifs_sb->ctx into a private new_ctx, then sync new_ctx with
+ * runtime state (tcon/server/ses) so it matches what
+ * cifs_show_options() displays. Syncing into the private copy (not
+ * the shared cifs_sb->ctx) avoids racing with concurrent
+ * fspick/remount and /proc/mounts readers. The parser will overwrite
+ * only the options explicitly passed on remount, so any difference
+ * between new_ctx and old_ctx in smb3_verify_reconfigure_ctx()
+ * represents a real, intentional change by the user.
*/
if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
struct cifs_sb_info *cifs_sb = CIFS_SB(fc->root->d_sb);
int rc;
- rc = smb3_sync_ctx_from_runtime(cifs_sb);
- if (rc)
- return rc;
-
ctx = kzalloc_obj(struct smb3_fs_context);
if (!ctx)
return -ENOMEM;
rc = smb3_fs_context_dup(ctx, cifs_sb->ctx);
if (rc) {
+ smb3_cleanup_fs_context_contents(ctx);
+ kfree(ctx);
+ return rc;
+ }
+
+ rc = smb3_sync_ctx_from_runtime(cifs_sb, ctx);
+ if (rc) {
+ smb3_cleanup_fs_context_contents(ctx);
kfree(ctx);
return rc;
}
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index a8f8feeeccb5..b30c16b0d157 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -2806,7 +2806,7 @@ bool smb2_should_replay(struct cifs_tcon *tcon,
if (!pretries || !pcur_sleep)
return false;
- if (tcon->retry || (*pretries)++ < tcon->ses->server->retrans) {
+ if (tcon->retry || (*pretries)++ < READ_ONCE(tcon->ses->server->retrans)) {
/* Update sleep time for exponential backoff */
if (!(*pcur_sleep))
(*pcur_sleep) = 1;
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 9/9] smb: client: review fixes for nolease remount (patch 7)
2026-07-02 11:35 [PATCH RESEND 0/9] smb: client: remount reconfigure option fixes rajasimandalos
` (7 preceding siblings ...)
2026-07-02 11:35 ` [PATCH 8/9] smb: client: review fixes for remount ctx/retrans sync (patches 1-4) rajasimandalos
@ 2026-07-02 11:35 ` rajasimandalos
8 siblings, 0 replies; 10+ messages in thread
From: rajasimandalos @ 2026-07-02 11:35 UTC (permalink / raw)
To: linux-cifs; +Cc: bharathsm, msetiya, smfrench, sfrench, stfrench, Rajasi Mandal
From: Rajasi Mandal <rajasimandal@microsoft.com>
Fold the review feedback for the nolease reconfigure patch into one
change. Each fix, in two lines:
- nolease transition: track the lease -> nolease transition
(became_nolease) and only run the expensive cache eviction when nolease
is actually switched on, not on every bare remount.
- nolease locking: set tcon->no_lease under tc_lock to pair with
match_tcon(), which reads tcon->no_lease with tc_lock held.
- cached dir leak: add a close_handles arg to invalidate_all_cached_dirs()
so a live remount keeps is_open and lets the laundromat send SMB2_close
instead of leaking the server handle/lease.
- callers: cifs_debug.c, file.c and smb2pdu.c pass close_handles=false to
preserve their existing teardown behaviour.
Signed-off-by: Rajasi Mandal <rajasimandal@microsoft.com>
---
fs/smb/client/cached_dir.c | 32 ++++++++++++++++++++++----------
fs/smb/client/cached_dir.h | 3 ++-
fs/smb/client/cifs_debug.c | 2 +-
fs/smb/client/file.c | 2 +-
fs/smb/client/fs_context.c | 20 +++++++++++++++++---
fs/smb/client/smb2pdu.c | 2 +-
6 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index 58d68a8f4d41..420a598f5963 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -598,10 +598,17 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
}
/*
- * Invalidate all cached dirs when a TCON has been reset
- * due to a session loss.
+ * Invalidate all cached dirs on a TCON, moving them to the dying list
+ * for the laundromat to clean up.
+ *
+ * @close_handles: if true, the connection is still live (e.g. remount),
+ * so leave cfid->is_open set and let smb2_close_cached_fid() send
+ * SMB2_close to release the server-side directory handle and lease. If
+ * false (the session-loss teardown case), mark the cfids closed so the
+ * doomed SMB2_close is skipped -- the server has already dropped them.
*/
-void invalidate_all_cached_dirs(struct cifs_tcon *tcon, bool sync)
+void invalidate_all_cached_dirs(struct cifs_tcon *tcon, bool sync,
+ bool close_handles)
{
struct cached_fids *cfids = tcon->cfids;
struct cached_fid *cfid, *q;
@@ -610,15 +617,16 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon, bool sync)
return;
/*
- * Mark all the cfids as closed, and move them to the cfids->dying list.
- * They'll be cleaned up by laundromat. Take a reference to each cfid
- * during this process.
+ * Move all the cfids to the cfids->dying list. They'll be cleaned
+ * up by laundromat. Take a reference to each cfid during this
+ * process.
*/
spin_lock(&cfids->cfid_list_lock);
list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
list_move(&cfid->entry, &cfids->dying);
cfids->num_entries--;
- cfid->is_open = false;
+ if (!close_handles)
+ cfid->is_open = false;
cfid->on_list = false;
if (cfid->has_lease) {
/*
@@ -640,10 +648,14 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon, bool sync)
/*
* Invalidate cached directory entries across all tcons under a
* superblock. Collect references on each tcon under tlink_tree_lock,
- * then call invalidate_all_cached_dirs() outside the spinlock since it
- * can sleep. Holding a tc_count reference prevents the tcon from being
+ * then close their cached dirs outside the spinlock since that can
+ * sleep. Holding a tc_count reference prevents the tcon from being
* freed by tlink_expire_delayed() between dropping the spinlock and
* the call.
+ *
+ * Called on remount while the connection is live (e.g. switching to
+ * nolease), so pass close_handles=true to actually release the
+ * server-side directory handles and their leases.
*/
void invalidate_all_cached_dirs_sb(struct cifs_sb_info *cifs_sb)
{
@@ -674,7 +686,7 @@ void invalidate_all_cached_dirs_sb(struct cifs_sb_info *cifs_sb)
spin_unlock(&cifs_sb->tlink_tree_lock);
list_for_each_entry_safe(tmp_list, q, &tcon_head, entry) {
- invalidate_all_cached_dirs(tmp_list->tcon, true);
+ invalidate_all_cached_dirs(tmp_list->tcon, true, true);
list_del(&tmp_list->entry);
cifs_put_tcon(tmp_list->tcon, netfs_trace_tcon_ref_put_cached_inval_sb);
kfree(tmp_list);
diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
index 606ba2a0b64f..3b86339ca884 100644
--- a/fs/smb/client/cached_dir.h
+++ b/fs/smb/client/cached_dir.h
@@ -91,7 +91,8 @@ void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon,
const char *name, struct cifs_sb_info *cifs_sb);
void close_all_cached_dirs(struct cifs_sb_info *cifs_sb);
void invalidate_all_cached_dirs_sb(struct cifs_sb_info *cifs_sb);
-void invalidate_all_cached_dirs(struct cifs_tcon *tcon, bool sync);
+void invalidate_all_cached_dirs(struct cifs_tcon *tcon, bool sync,
+ bool close_handles);
bool cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16]);
#endif /* _CACHED_DIR_H */
diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c
index 4ed4f55a0bb7..28b0d433810f 100644
--- a/fs/smb/client/cifs_debug.c
+++ b/fs/smb/client/cifs_debug.c
@@ -383,7 +383,7 @@ static ssize_t cifs_debug_dirs_proc_write(struct file *file, const char __user *
if (cifs_ses_exiting(ses))
continue;
list_for_each_entry(tcon, &ses->tcon_list, tcon_list)
- invalidate_all_cached_dirs(tcon, false);
+ invalidate_all_cached_dirs(tcon, false, false);
}
}
spin_unlock(&cifs_tcp_ses_lock);
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
index 58430ba51b10..c06117b1975e 100644
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -393,7 +393,7 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
}
spin_unlock(&tcon->open_file_lock);
- invalidate_all_cached_dirs(tcon, true);
+ invalidate_all_cached_dirs(tcon, true, false);
spin_lock(&tcon->tc_lock);
if (tcon->status == TID_IN_FILES_INVALIDATE)
tcon->status = TID_NEED_TCON;
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 89bf6f4604b3..70fa869b9b6d 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1333,6 +1333,7 @@ static void smb3_sync_tcon_opts(struct cifs_sb_info *cifs_sb,
struct tcon_link *tlink;
struct cifs_tcon *tcon;
struct rb_node *node;
+ bool became_nolease = false;
spin_lock(&cifs_sb->tlink_tree_lock);
for (node = rb_first(&cifs_sb->tlink_tree); node; node = rb_next(node)) {
@@ -1340,16 +1341,29 @@ static void smb3_sync_tcon_opts(struct cifs_sb_info *cifs_sb,
tcon = tlink_tcon(tlink);
if (IS_ERR(tcon))
continue;
+ /*
+ * Update under tc_lock to pair with match_tcon(), which reads
+ * tcon->no_lease with tc_lock held. Track whether this is the
+ * lease -> nolease transition so the expensive cleanup below
+ * only runs when nolease is actually being switched on.
+ */
+ spin_lock(&tcon->tc_lock);
+ if (ctx->no_lease && !tcon->no_lease)
+ became_nolease = true;
tcon->no_lease = ctx->no_lease;
+ spin_unlock(&tcon->tc_lock);
}
spin_unlock(&cifs_sb->tlink_tree_lock);
/*
- * Both _sb() helpers iterate all tcons internally and handle
- * their own locking. They can sleep, so they must be called
+ * Only when switching to nolease must we evict lease-bearing cached
+ * state (deferred handles and cached dir fids). Skipping this when
+ * nolease was already set avoids dropping caches on every bare
+ * remount. Both _sb() helpers iterate all tcons internally and
+ * handle their own locking; they can sleep, so they must be called
* outside tlink_tree_lock.
*/
- if (ctx->no_lease) {
+ if (became_nolease) {
cifs_close_all_deferred_files_sb(cifs_sb);
invalidate_all_cached_dirs_sb(cifs_sb);
}
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 958ca0753774..e68f96df8ee3 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -2278,7 +2278,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
}
spin_unlock(&ses->chan_lock);
- invalidate_all_cached_dirs(tcon, true);
+ invalidate_all_cached_dirs(tcon, true, false);
rc = smb2_plain_req_init(SMB2_TREE_DISCONNECT, tcon, server,
(void **) &req,
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-07-02 11:36 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-02 11:35 [PATCH RESEND 0/9] smb: client: remount reconfigure option fixes rajasimandalos
2026-07-02 11:35 ` [PATCH 1/9] smb: client: sync runtime state into ctx on reconfigure rajasimandalos
2026-07-02 11:35 ` [PATCH 2/9] smb: client: block non-reconfigurable option changes on remount rajasimandalos
2026-07-02 11:35 ` [PATCH 3/9] smb: client: sync retrans " rajasimandalos
2026-07-02 11:35 ` [PATCH 4/9] smb: client: block cache=ro and cache=singleclient " rajasimandalos
2026-07-02 11:35 ` [PATCH 5/9] smb: client: apply rasize " rajasimandalos
2026-07-02 11:35 ` [PATCH 6/9] smb: client: move struct tcon_list to cifsglob.h rajasimandalos
2026-07-02 11:35 ` [PATCH 7/9] smb: client: allow nolease option to be reconfigured on remount rajasimandalos
2026-07-02 11:35 ` [PATCH 8/9] smb: client: review fixes for remount ctx/retrans sync (patches 1-4) rajasimandalos
2026-07-02 11:35 ` [PATCH 9/9] smb: client: review fixes for nolease remount (patch 7) rajasimandalos
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.