release 6.15.2 (preliminary)
This commit is contained in:
29
debian/patches/patchset-pf/smb/0001-smb-client-add-NULL-check-in-automount_fullpath.patch
vendored
Normal file
29
debian/patches/patchset-pf/smb/0001-smb-client-add-NULL-check-in-automount_fullpath.patch
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
From 97831e31e43bb023d208b2344546a4e51e580dc6 Mon Sep 17 00:00:00 2001
|
||||
From: Ruben Devos <devosruben6@gmail.com>
|
||||
Date: Sun, 1 Jun 2025 19:18:55 +0200
|
||||
Subject: smb: client: add NULL check in automount_fullpath
|
||||
|
||||
page is checked for null in __build_path_from_dentry_optional_prefix
|
||||
when tcon->origin_fullpath is not set. However, the check is missing when
|
||||
it is set.
|
||||
Add a check to prevent a potential NULL pointer dereference.
|
||||
|
||||
Signed-off-by: Ruben Devos <devosruben6@gmail.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Steve French <stfrench@microsoft.com>
|
||||
---
|
||||
fs/smb/client/namespace.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/fs/smb/client/namespace.c
|
||||
+++ b/fs/smb/client/namespace.c
|
||||
@@ -146,6 +146,9 @@ static char *automount_fullpath(struct d
|
||||
}
|
||||
spin_unlock(&tcon->tc_lock);
|
||||
|
||||
+ if (unlikely(!page))
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
s = dentry_path_raw(dentry, page, PATH_MAX);
|
||||
if (IS_ERR(s))
|
||||
return s;
|
39
debian/patches/patchset-pf/smb/0002-cifs-reset-connections-for-all-channels-when-reconne.patch
vendored
Normal file
39
debian/patches/patchset-pf/smb/0002-cifs-reset-connections-for-all-channels-when-reconne.patch
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
From 0ca6d39b6d40b868eb6b4021f918de7a0f6a0f2e Mon Sep 17 00:00:00 2001
|
||||
From: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Date: Mon, 2 Jun 2025 22:37:13 +0530
|
||||
Subject: cifs: reset connections for all channels when reconnect requested
|
||||
|
||||
cifs_reconnect can be called with a flag to mark the session as needing
|
||||
reconnect too. When this is done, we expect the connections of all
|
||||
channels to be reconnected too, which is not happening today.
|
||||
|
||||
Without doing this, we have seen bad things happen when primary and
|
||||
secondary channels are connected to different servers (in case of cloud
|
||||
services like Azure Files SMB).
|
||||
|
||||
This change would force all connections to reconnect as well, not just
|
||||
the sessions and tcons.
|
||||
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Signed-off-by: Steve French <stfrench@microsoft.com>
|
||||
---
|
||||
fs/smb/client/connect.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
--- a/fs/smb/client/connect.c
|
||||
+++ b/fs/smb/client/connect.c
|
||||
@@ -377,6 +377,13 @@ static int __cifs_reconnect(struct TCP_S
|
||||
if (!cifs_tcp_ses_needs_reconnect(server, 1))
|
||||
return 0;
|
||||
|
||||
+ /*
|
||||
+ * if smb session has been marked for reconnect, also reconnect all
|
||||
+ * connections. This way, the other connections do not end up bad.
|
||||
+ */
|
||||
+ if (mark_smb_session)
|
||||
+ cifs_signal_cifsd_for_reconnect(server, mark_smb_session);
|
||||
+
|
||||
cifs_mark_tcp_ses_conns_for_reconnect(server, mark_smb_session);
|
||||
|
||||
cifs_abort_connection(server);
|
31
debian/patches/patchset-pf/smb/0003-cifs-update-dstaddr-whenever-channel-iface-is-update.patch
vendored
Normal file
31
debian/patches/patchset-pf/smb/0003-cifs-update-dstaddr-whenever-channel-iface-is-update.patch
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
From d1f84c6baebc480106c9558dea4842ecb3059017 Mon Sep 17 00:00:00 2001
|
||||
From: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Date: Mon, 2 Jun 2025 22:37:14 +0530
|
||||
Subject: cifs: update dstaddr whenever channel iface is updated
|
||||
|
||||
When the server interface info changes (more common in clustered
|
||||
servers like Azure Files), the per-channel iface gets updated.
|
||||
However, this did not update the corresponding dstaddr. As a result
|
||||
these channels will still connect (or try connecting) to older addresses.
|
||||
|
||||
Fixes: b54034a73baf ("cifs: during reconnect, update interface if necessary")
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Signed-off-by: Steve French <stfrench@microsoft.com>
|
||||
---
|
||||
fs/smb/client/sess.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/fs/smb/client/sess.c
|
||||
+++ b/fs/smb/client/sess.c
|
||||
@@ -445,6 +445,10 @@ cifs_chan_update_iface(struct cifs_ses *
|
||||
|
||||
ses->chans[chan_index].iface = iface;
|
||||
spin_unlock(&ses->chan_lock);
|
||||
+
|
||||
+ spin_lock(&server->srv_lock);
|
||||
+ memcpy(&server->dstaddr, &iface->sockaddr, sizeof(server->dstaddr));
|
||||
+ spin_unlock(&server->srv_lock);
|
||||
}
|
||||
|
||||
static int
|
33
debian/patches/patchset-pf/smb/0004-cifs-dns-resolution-is-needed-only-for-primary-chann.patch
vendored
Normal file
33
debian/patches/patchset-pf/smb/0004-cifs-dns-resolution-is-needed-only-for-primary-chann.patch
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
From 2bffd71a70fa4695f62712688a720393cc92032b Mon Sep 17 00:00:00 2001
|
||||
From: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Date: Mon, 2 Jun 2025 22:37:16 +0530
|
||||
Subject: cifs: dns resolution is needed only for primary channel
|
||||
|
||||
When calling cifs_reconnect, before the connection to the
|
||||
server is reestablished, the code today does a DNS resolution and
|
||||
updates server->dstaddr.
|
||||
|
||||
However, this is not necessary for secondary channels. Secondary
|
||||
channels use the interface list returned by the server to decide
|
||||
which address to connect to. And that happens after tcon is reconnected
|
||||
and server interfaces are requested.
|
||||
|
||||
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Steve French <stfrench@microsoft.com>
|
||||
---
|
||||
fs/smb/client/connect.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/fs/smb/client/connect.c
|
||||
+++ b/fs/smb/client/connect.c
|
||||
@@ -392,7 +392,8 @@ static int __cifs_reconnect(struct TCP_S
|
||||
try_to_freeze();
|
||||
cifs_server_lock(server);
|
||||
|
||||
- if (!cifs_swn_set_server_dstaddr(server)) {
|
||||
+ if (!cifs_swn_set_server_dstaddr(server) &&
|
||||
+ !SERVER_IS_CHAN(server)) {
|
||||
/* resolve the hostname again to make sure that IP address is up-to-date */
|
||||
rc = reconn_set_ipaddr_from_hostname(server);
|
||||
cifs_dbg(FYI, "%s: reconn_set_ipaddr_from_hostname: rc=%d\n", __func__, rc);
|
73
debian/patches/patchset-pf/smb/0005-cifs-deal-with-the-channel-loading-lag-while-picking.patch
vendored
Normal file
73
debian/patches/patchset-pf/smb/0005-cifs-deal-with-the-channel-loading-lag-while-picking.patch
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
From 918f494c058028cee8bdff33a4aa613377da61f0 Mon Sep 17 00:00:00 2001
|
||||
From: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Date: Mon, 2 Jun 2025 22:37:12 +0530
|
||||
Subject: cifs: deal with the channel loading lag while picking channels
|
||||
|
||||
Our current approach to select a channel for sending requests is this:
|
||||
1. iterate all channels to find the min and max queue depth
|
||||
2. if min and max are not the same, pick the channel with min depth
|
||||
3. if min and max are same, round robin, as all channels are equally loaded
|
||||
|
||||
The problem with this approach is that there's a lag between selecting
|
||||
a channel and sending the request (that increases the queue depth on the channel).
|
||||
While these numbers will eventually catch up, there could be a skew in the
|
||||
channel usage, depending on the application's I/O parallelism and the server's
|
||||
speed of handling requests.
|
||||
|
||||
With sufficient parallelism, this lag can artificially increase the queue depth,
|
||||
thereby impacting the performance negatively.
|
||||
|
||||
This change will change the step 1 above to start the iteration from the last
|
||||
selected channel. This is to reduce the skew in channel usage even in the presence
|
||||
of this lag.
|
||||
|
||||
Fixes: ea90708d3cf3 ("cifs: use the least loaded channel for sending requests")
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Signed-off-by: Steve French <stfrench@microsoft.com>
|
||||
---
|
||||
fs/smb/client/transport.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/fs/smb/client/transport.c
|
||||
+++ b/fs/smb/client/transport.c
|
||||
@@ -1018,14 +1018,16 @@ struct TCP_Server_Info *cifs_pick_channe
|
||||
uint index = 0;
|
||||
unsigned int min_in_flight = UINT_MAX, max_in_flight = 0;
|
||||
struct TCP_Server_Info *server = NULL;
|
||||
- int i;
|
||||
+ int i, start, cur;
|
||||
|
||||
if (!ses)
|
||||
return NULL;
|
||||
|
||||
spin_lock(&ses->chan_lock);
|
||||
+ start = atomic_inc_return(&ses->chan_seq);
|
||||
for (i = 0; i < ses->chan_count; i++) {
|
||||
- server = ses->chans[i].server;
|
||||
+ cur = (start + i) % ses->chan_count;
|
||||
+ server = ses->chans[cur].server;
|
||||
if (!server || server->terminate)
|
||||
continue;
|
||||
|
||||
@@ -1042,17 +1044,15 @@ struct TCP_Server_Info *cifs_pick_channe
|
||||
*/
|
||||
if (server->in_flight < min_in_flight) {
|
||||
min_in_flight = server->in_flight;
|
||||
- index = i;
|
||||
+ index = cur;
|
||||
}
|
||||
if (server->in_flight > max_in_flight)
|
||||
max_in_flight = server->in_flight;
|
||||
}
|
||||
|
||||
/* if all channels are equally loaded, fall back to round-robin */
|
||||
- if (min_in_flight == max_in_flight) {
|
||||
- index = (uint)atomic_inc_return(&ses->chan_seq);
|
||||
- index %= ses->chan_count;
|
||||
- }
|
||||
+ if (min_in_flight == max_in_flight)
|
||||
+ index = (uint)start % ses->chan_count;
|
||||
|
||||
server = ses->chans[index].server;
|
||||
spin_unlock(&ses->chan_lock);
|
82
debian/patches/patchset-pf/smb/0006-cifs-serialize-other-channels-when-query-server-inte.patch
vendored
Normal file
82
debian/patches/patchset-pf/smb/0006-cifs-serialize-other-channels-when-query-server-inte.patch
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
From 2cc6528030c91406031698e047896faa99fc0092 Mon Sep 17 00:00:00 2001
|
||||
From: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Date: Mon, 2 Jun 2025 22:37:15 +0530
|
||||
Subject: cifs: serialize other channels when query server interfaces is
|
||||
pending
|
||||
|
||||
Today, during smb2_reconnect, session_mutex is released as soon as
|
||||
the tcon is reconnected and is in a good state. However, in case
|
||||
multichannel is enabled, there is also a query of server interfaces that
|
||||
follows. We've seen that this query can race with reconnects of other
|
||||
channels, causing them to step on each other with reconnects.
|
||||
|
||||
This change extends the hold of session_mutex till after the query of
|
||||
server interfaces is complete. In order to avoid recursive smb2_reconnect
|
||||
checks during query ioctl, this change also introduces a session flag
|
||||
for sessions where such a query is in progress.
|
||||
|
||||
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Steve French <stfrench@microsoft.com>
|
||||
---
|
||||
fs/smb/client/cifsglob.h | 1 +
|
||||
fs/smb/client/smb2pdu.c | 24 ++++++++++++++++++------
|
||||
2 files changed, 19 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/fs/smb/client/cifsglob.h
|
||||
+++ b/fs/smb/client/cifsglob.h
|
||||
@@ -1084,6 +1084,7 @@ struct cifs_chan {
|
||||
};
|
||||
|
||||
#define CIFS_SES_FLAG_SCALE_CHANNELS (0x1)
|
||||
+#define CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES (0x2)
|
||||
|
||||
/*
|
||||
* Session structure. One of these for each uid session with a particular host
|
||||
--- a/fs/smb/client/smb2pdu.c
|
||||
+++ b/fs/smb/client/smb2pdu.c
|
||||
@@ -411,14 +411,19 @@ skip_sess_setup:
|
||||
if (!rc &&
|
||||
(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL) &&
|
||||
server->ops->query_server_interfaces) {
|
||||
- mutex_unlock(&ses->session_mutex);
|
||||
-
|
||||
/*
|
||||
- * query server network interfaces, in case they change
|
||||
+ * query server network interfaces, in case they change.
|
||||
+ * Also mark the session as pending this update while the query
|
||||
+ * is in progress. This will be used to avoid calling
|
||||
+ * smb2_reconnect recursively.
|
||||
*/
|
||||
+ ses->flags |= CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES;
|
||||
xid = get_xid();
|
||||
rc = server->ops->query_server_interfaces(xid, tcon, false);
|
||||
free_xid(xid);
|
||||
+ ses->flags &= ~CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES;
|
||||
+
|
||||
+ mutex_unlock(&ses->session_mutex);
|
||||
|
||||
if (rc == -EOPNOTSUPP && ses->chan_count > 1) {
|
||||
/*
|
||||
@@ -560,11 +565,18 @@ static int smb2_ioctl_req_init(u32 opcod
|
||||
struct TCP_Server_Info *server,
|
||||
void **request_buf, unsigned int *total_len)
|
||||
{
|
||||
- /* Skip reconnect only for FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs */
|
||||
- if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO) {
|
||||
+ /*
|
||||
+ * Skip reconnect in one of the following cases:
|
||||
+ * 1. For FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs
|
||||
+ * 2. For FSCTL_QUERY_NETWORK_INTERFACE_INFO IOCTL when called from
|
||||
+ * smb2_reconnect (indicated by CIFS_SES_FLAG_SCALE_CHANNELS ses flag)
|
||||
+ */
|
||||
+ if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO ||
|
||||
+ (opcode == FSCTL_QUERY_NETWORK_INTERFACE_INFO &&
|
||||
+ (tcon->ses->flags & CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES)))
|
||||
return __smb2_plain_req_init(SMB2_IOCTL, tcon, server,
|
||||
request_buf, total_len);
|
||||
- }
|
||||
+
|
||||
return smb2_plain_req_init(SMB2_IOCTL, tcon, server,
|
||||
request_buf, total_len);
|
||||
}
|
64
debian/patches/patchset-pf/smb/0007-cifs-do-not-disable-interface-polling-on-failure.patch
vendored
Normal file
64
debian/patches/patchset-pf/smb/0007-cifs-do-not-disable-interface-polling-on-failure.patch
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
From 48fd713e7c35aba7a4c3ed327977897909575e3e Mon Sep 17 00:00:00 2001
|
||||
From: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Date: Mon, 2 Jun 2025 22:37:17 +0530
|
||||
Subject: cifs: do not disable interface polling on failure
|
||||
|
||||
When a server has multichannel enabled, we keep polling the server
|
||||
for interfaces periodically. However, when this query fails, we
|
||||
disable the polling. This can be problematic as it takes away the
|
||||
chance for the server to start advertizing again.
|
||||
|
||||
This change reschedules the delayed work, even if the current call
|
||||
failed. That way, multichannel sessions can recover.
|
||||
|
||||
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Steve French <stfrench@microsoft.com>
|
||||
---
|
||||
fs/smb/client/connect.c | 6 +-----
|
||||
fs/smb/client/smb2pdu.c | 9 +++++----
|
||||
2 files changed, 6 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/fs/smb/client/connect.c
|
||||
+++ b/fs/smb/client/connect.c
|
||||
@@ -116,13 +116,9 @@ static void smb2_query_server_interfaces
|
||||
rc = server->ops->query_server_interfaces(xid, tcon, false);
|
||||
free_xid(xid);
|
||||
|
||||
- if (rc) {
|
||||
- if (rc == -EOPNOTSUPP)
|
||||
- return;
|
||||
-
|
||||
+ if (rc)
|
||||
cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n",
|
||||
__func__, rc);
|
||||
- }
|
||||
|
||||
queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
|
||||
(SMB_INTERFACE_POLL_INTERVAL * HZ));
|
||||
--- a/fs/smb/client/smb2pdu.c
|
||||
+++ b/fs/smb/client/smb2pdu.c
|
||||
@@ -423,6 +423,10 @@ skip_sess_setup:
|
||||
free_xid(xid);
|
||||
ses->flags &= ~CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES;
|
||||
|
||||
+ /* regardless of rc value, setup polling */
|
||||
+ queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
|
||||
+ (SMB_INTERFACE_POLL_INTERVAL * HZ));
|
||||
+
|
||||
mutex_unlock(&ses->session_mutex);
|
||||
|
||||
if (rc == -EOPNOTSUPP && ses->chan_count > 1) {
|
||||
@@ -443,11 +447,8 @@ skip_sess_setup:
|
||||
if (ses->chan_max > ses->chan_count &&
|
||||
ses->iface_count &&
|
||||
!SERVER_IS_CHAN(server)) {
|
||||
- if (ses->chan_count == 1) {
|
||||
+ if (ses->chan_count == 1)
|
||||
cifs_server_dbg(VFS, "supports multichannel now\n");
|
||||
- queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
|
||||
- (SMB_INTERFACE_POLL_INTERVAL * HZ));
|
||||
- }
|
||||
|
||||
cifs_try_adding_channels(ses);
|
||||
}
|
148
debian/patches/patchset-pf/smb/0008-smb-improve-directory-cache-reuse-for-readdir-operat.patch
vendored
Normal file
148
debian/patches/patchset-pf/smb/0008-smb-improve-directory-cache-reuse-for-readdir-operat.patch
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
From 17457c5d0fa0b98cef9d2236a1518b1ded25fa5d Mon Sep 17 00:00:00 2001
|
||||
From: Bharath SM <bharathsm.hsk@gmail.com>
|
||||
Date: Wed, 11 Jun 2025 16:59:02 +0530
|
||||
Subject: smb: improve directory cache reuse for readdir operations
|
||||
|
||||
Currently, cached directory contents were not reused across subsequent
|
||||
'ls' operations because the cache validity check relied on comparing
|
||||
the ctx pointer, which changes with each readdir invocation. As a
|
||||
result, the cached dir entries was not marked as valid and the cache was
|
||||
not utilized for subsequent 'ls' operations.
|
||||
|
||||
This change uses the file pointer, which remains consistent across all
|
||||
readdir calls for a given directory instance, to associate and validate
|
||||
the cache. As a result, cached directory contents can now be
|
||||
correctly reused, improving performance for repeated directory listings.
|
||||
|
||||
Performance gains with local windows SMB server:
|
||||
|
||||
Without the patch and default actimeo=1:
|
||||
1000 directory enumeration operations on dir with 10k files took 135.0s
|
||||
|
||||
With this patch and actimeo=0:
|
||||
1000 directory enumeration operations on dir with 10k files took just 5.1s
|
||||
|
||||
Signed-off-by: Bharath SM <bharathsm@microsoft.com>
|
||||
Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Steve French <stfrench@microsoft.com>
|
||||
---
|
||||
fs/smb/client/cached_dir.h | 8 ++++----
|
||||
fs/smb/client/readdir.c | 28 +++++++++++++++-------------
|
||||
2 files changed, 19 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/fs/smb/client/cached_dir.h
|
||||
+++ b/fs/smb/client/cached_dir.h
|
||||
@@ -21,10 +21,10 @@ struct cached_dirent {
|
||||
struct cached_dirents {
|
||||
bool is_valid:1;
|
||||
bool is_failed:1;
|
||||
- struct dir_context *ctx; /*
|
||||
- * Only used to make sure we only take entries
|
||||
- * from a single context. Never dereferenced.
|
||||
- */
|
||||
+ struct file *file; /*
|
||||
+ * Used to associate the cache with a single
|
||||
+ * open file instance.
|
||||
+ */
|
||||
struct mutex de_mutex;
|
||||
int pos; /* Expected ctx->pos */
|
||||
struct list_head entries;
|
||||
--- a/fs/smb/client/readdir.c
|
||||
+++ b/fs/smb/client/readdir.c
|
||||
@@ -850,9 +850,9 @@ static bool emit_cached_dirents(struct c
|
||||
}
|
||||
|
||||
static void update_cached_dirents_count(struct cached_dirents *cde,
|
||||
- struct dir_context *ctx)
|
||||
+ struct file *file)
|
||||
{
|
||||
- if (cde->ctx != ctx)
|
||||
+ if (cde->file != file)
|
||||
return;
|
||||
if (cde->is_valid || cde->is_failed)
|
||||
return;
|
||||
@@ -861,9 +861,9 @@ static void update_cached_dirents_count(
|
||||
}
|
||||
|
||||
static void finished_cached_dirents_count(struct cached_dirents *cde,
|
||||
- struct dir_context *ctx)
|
||||
+ struct dir_context *ctx, struct file *file)
|
||||
{
|
||||
- if (cde->ctx != ctx)
|
||||
+ if (cde->file != file)
|
||||
return;
|
||||
if (cde->is_valid || cde->is_failed)
|
||||
return;
|
||||
@@ -876,11 +876,12 @@ static void finished_cached_dirents_coun
|
||||
static void add_cached_dirent(struct cached_dirents *cde,
|
||||
struct dir_context *ctx,
|
||||
const char *name, int namelen,
|
||||
- struct cifs_fattr *fattr)
|
||||
+ struct cifs_fattr *fattr,
|
||||
+ struct file *file)
|
||||
{
|
||||
struct cached_dirent *de;
|
||||
|
||||
- if (cde->ctx != ctx)
|
||||
+ if (cde->file != file)
|
||||
return;
|
||||
if (cde->is_valid || cde->is_failed)
|
||||
return;
|
||||
@@ -910,7 +911,8 @@ static void add_cached_dirent(struct cac
|
||||
static bool cifs_dir_emit(struct dir_context *ctx,
|
||||
const char *name, int namelen,
|
||||
struct cifs_fattr *fattr,
|
||||
- struct cached_fid *cfid)
|
||||
+ struct cached_fid *cfid,
|
||||
+ struct file *file)
|
||||
{
|
||||
bool rc;
|
||||
ino_t ino = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
|
||||
@@ -922,7 +924,7 @@ static bool cifs_dir_emit(struct dir_con
|
||||
if (cfid) {
|
||||
mutex_lock(&cfid->dirents.de_mutex);
|
||||
add_cached_dirent(&cfid->dirents, ctx, name, namelen,
|
||||
- fattr);
|
||||
+ fattr, file);
|
||||
mutex_unlock(&cfid->dirents.de_mutex);
|
||||
}
|
||||
|
||||
@@ -1022,7 +1024,7 @@ static int cifs_filldir(char *find_entry
|
||||
cifs_prime_dcache(file_dentry(file), &name, &fattr);
|
||||
|
||||
return !cifs_dir_emit(ctx, name.name, name.len,
|
||||
- &fattr, cfid);
|
||||
+ &fattr, cfid, file);
|
||||
}
|
||||
|
||||
|
||||
@@ -1073,8 +1075,8 @@ int cifs_readdir(struct file *file, stru
|
||||
* we need to initialize scanning and storing the
|
||||
* directory content.
|
||||
*/
|
||||
- if (ctx->pos == 0 && cfid->dirents.ctx == NULL) {
|
||||
- cfid->dirents.ctx = ctx;
|
||||
+ if (ctx->pos == 0 && cfid->dirents.file == NULL) {
|
||||
+ cfid->dirents.file = file;
|
||||
cfid->dirents.pos = 2;
|
||||
}
|
||||
/*
|
||||
@@ -1142,7 +1144,7 @@ int cifs_readdir(struct file *file, stru
|
||||
} else {
|
||||
if (cfid) {
|
||||
mutex_lock(&cfid->dirents.de_mutex);
|
||||
- finished_cached_dirents_count(&cfid->dirents, ctx);
|
||||
+ finished_cached_dirents_count(&cfid->dirents, ctx, file);
|
||||
mutex_unlock(&cfid->dirents.de_mutex);
|
||||
}
|
||||
cifs_dbg(FYI, "Could not find entry\n");
|
||||
@@ -1183,7 +1185,7 @@ int cifs_readdir(struct file *file, stru
|
||||
ctx->pos++;
|
||||
if (cfid) {
|
||||
mutex_lock(&cfid->dirents.de_mutex);
|
||||
- update_cached_dirents_count(&cfid->dirents, ctx);
|
||||
+ update_cached_dirents_count(&cfid->dirents, file);
|
||||
mutex_unlock(&cfid->dirents.de_mutex);
|
||||
}
|
||||
|
Reference in New Issue
Block a user