FAILED: patch "[PATCH] cifs: avoid potential races when handling multiple dfs tcons" failed to apply to 6.2-stable tree
[email protected]
maintainerThe patch below does not apply to the 6.2-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.2.y
git checkout FETCH_HEAD
git cherry-pick -x 6be2ea33a4093402252724a00c4af8033725184c
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2023050757-banked-expulsion-d269@gregkh' --subject-prefix 'PATCH 6.2.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 6be2ea33a4093402252724a00c4af8033725184c Mon Sep 17 00:00:00 2001
From: Paulo Alcantara <[email protected]>
Date: Thu, 27 Apr 2023 04:40:08 -0300
Subject: [PATCH] cifs: avoid potential races when handling multiple dfs tcons
Now that a DFS tcon manages its own list of DFS referrals and sessions, there is no point in having a single worker to refresh referrals of all DFS tcons. Make it faster and less prone to race conditions when having several mounts by queueing a worker per DFS tcon that will take care of refreshing only the DFS referrals related to it.
fs/cifs/cifsglob.h +1 -1
@@ -1238,8 +1238,8 @@ struct cifs_tcon {struct cached_fids *cfids;/* BB add field for back pointer to sb struct(s)? */ #ifdef CONFIG_CIFS_DFS_UPCALL -struct list_head ulist;/* cache update list */ struct list_head dfs_ses_list; +struct delayed_work dfs_cache_work;#endif struct delayed_work query_interfaces;/* query interfaces workqueue job */ };
fs/cifs/connect.c +6 -1
@@ -2340,6 +2340,9 @@ cifs_put_tcon(struct cifs_tcon *tcon)/* cancel polling of interfaces */ cancel_delayed_work_sync (&tcon->query_interfaces); +#ifdef CONFIG_CIFS_DFS_UPCALL +cancel_delayed_work_sync (&tcon->dfs_cache_work); +#endif if (tcon->use_witness) {int rc;
@@ -2587,7 +2590,9 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)queue_delayed_work (cifsiod_wq, &tcon->query_interfaces, (SMB_INTERFACE_POLL_INTERVAL *HZ )); } - +#ifdef CONFIG_CIFS_DFS_UPCALL +INIT_DELAYED_WORK (&tcon->dfs_cache_work, dfs_cache_refresh); +#endif spin_lock (&cifs_tcp_ses_lock);list_add (&tcon->tcon_list, &ses->tcon_list);spin_unlock (&cifs_tcp_ses_lock);
fs/cifs/dfs.c +4 -0
@@ -157,6 +157,8 @@ static int get_dfs_conn(struct cifs_mount_ctx *mnt_ctx, const char *ref_path, co rc =cifs_is_path_remote (mnt_ctx); } +dfs_cache_noreq_update_tgthint (ref_path +1 , tit); +if (rc == -EREMOTE && is_refsrv) { rc2 =get_root_smb_session (mnt_ctx);if (rc2)
@@ -259,6 +261,8 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx)if (list_empty (&tcon->dfs_ses_list)) {list_replace_init (&mnt_ctx->dfs_ses_list, &tcon->dfs_ses_list); +queue_delayed_work (dfscache_wq, &tcon->dfs_cache_work, +dfs_cache_get_ttl () *HZ ); }else {dfs_put_root_smb_sessions (&mnt_ctx->dfs_ses_list); }
fs/cifs/dfs_cache.c +60 -77
250 lines not on this page · raw message
fs/cifs/dfs_cache.h +9 -0
@@ -13,6 +13,9 @@#include <linux/uuid.h> #include "cifsglob.h" +extern struct workqueue_struct *dfscache_wq; +extern atomic_t dfs_cache_ttl; +#define DFS_CACHE_TGT_LIST_INIT (var) { .tl_numtgts = 0, .tl_list = LIST_HEAD_INIT((var).tl_list), }struct dfs_cache_tgt_list {
@@ -42,6 +45,7 @@ int dfs_cache_get_tgt_share(char *path, const struct dfs_cache_tgt_iterator *it, char **prefix);char *dfs_cache_canonical_path (const char *path,const struct nls_table *cp,int remap);int dfs_cache_remount_fs (struct cifs_sb_info *cifs_sb); +void dfs_cache_refresh (struct work_struct *work);static inline struct dfs_cache_tgt_iterator * dfs_cache_get_next_tgt(struct dfs_cache_tgt_list *tl,
@@ -89,4 +93,9 @@ dfs_cache_get_nr_tgts(const struct dfs_cache_tgt_list *tl) return tl ? tl->tl_numtgts : 0; } +static inline int dfs_cache_get_ttl (void ) +{ +return atomic_read (&dfs_cache_ttl); +} +#endif /* _CIFS_DFS_CACHE_H */