Paulo Alcantara d487cd
From: Paulo Alcantara <pc@cjr.nz>
Paulo Alcantara d487cd
Date: Tue, 13 Dec 2022 00:29:22 -0300
Paulo Alcantara d487cd
Subject: [PATCH] cifs: don't refresh cached referrals from unactive mounts
Paulo Alcantara d487cd
Git-commit: cb3f6d8764529c33269c3478c17641cb097a615b
Paulo Alcantara d487cd
References: bsc#1193629
Paulo Alcantara d487cd
Patch-mainline: v6.2-rc1
Paulo Alcantara d487cd
Paulo Alcantara d487cd
There is no point refreshing cached referrals from unactive mounts as
Paulo Alcantara d487cd
they will no longer be used and new mounts will either create or
Paulo Alcantara d487cd
refresh them anyway.
Paulo Alcantara d487cd
Paulo Alcantara d487cd
Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Paulo Alcantara d487cd
Signed-off-by: Steve French <stfrench@microsoft.com>
Paulo Alcantara d487cd
Acked-by: Paulo Alcantara <palcantara@suse.de>
Paulo Alcantara d487cd
---
Paulo Alcantara d487cd
 fs/cifs/dfs_cache.c | 73 +--------------------------------------------
Paulo Alcantara d487cd
 1 file changed, 1 insertion(+), 72 deletions(-)
Paulo Alcantara d487cd
Paulo Alcantara d487cd
diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c
Paulo Alcantara d487cd
index bf5e674f43b8..bef672534397 100644
Paulo Alcantara d487cd
--- a/fs/cifs/dfs_cache.c
Paulo Alcantara d487cd
+++ b/fs/cifs/dfs_cache.c
Paulo Alcantara d487cd
@@ -1549,74 +1549,6 @@ static void refresh_mounts(struct cifs_ses **sessions)
Paulo Alcantara d487cd
 	}
Paulo Alcantara d487cd
 }
Paulo Alcantara d487cd
 
Paulo Alcantara d487cd
-static void refresh_cache(struct cifs_ses **sessions)
Paulo Alcantara d487cd
-{
Paulo Alcantara d487cd
-	int i;
Paulo Alcantara d487cd
-	struct cifs_ses *ses;
Paulo Alcantara d487cd
-	unsigned int xid;
Paulo Alcantara d487cd
-	char *ref_paths[CACHE_MAX_ENTRIES];
Paulo Alcantara d487cd
-	int count = 0;
Paulo Alcantara d487cd
-	struct cache_entry *ce;
Paulo Alcantara d487cd
-
Paulo Alcantara d487cd
-	/*
Paulo Alcantara d487cd
-	 * Refresh all cached entries.  Get all new referrals outside critical section to avoid
Paulo Alcantara d487cd
-	 * starvation while performing SMB2 IOCTL on broken or slow connections.
Paulo Alcantara d487cd
-
Paulo Alcantara d487cd
-	 * The cache entries may cover more paths than the active mounts
Paulo Alcantara d487cd
-	 * (e.g. domain-based DFS referrals or multi tier DFS setups).
Paulo Alcantara d487cd
-	 */
Paulo Alcantara d487cd
-	down_read(&htable_rw_lock);
Paulo Alcantara d487cd
-	for (i = 0; i < CACHE_HTABLE_SIZE; i++) {
Paulo Alcantara d487cd
-		struct hlist_head *l = &cache_htable[i];
Paulo Alcantara d487cd
-
Paulo Alcantara d487cd
-		hlist_for_each_entry(ce, l, hlist) {
Paulo Alcantara d487cd
-			if (count == ARRAY_SIZE(ref_paths))
Paulo Alcantara d487cd
-				goto out_unlock;
Paulo Alcantara d487cd
-			if (hlist_unhashed(&ce->hlist) || !cache_entry_expired(ce) ||
Paulo Alcantara d487cd
-			    IS_ERR(find_ipc_from_server_path(sessions, ce->path)))
Paulo Alcantara d487cd
-				continue;
Paulo Alcantara d487cd
-			ref_paths[count++] = kstrdup(ce->path, GFP_ATOMIC);
Paulo Alcantara d487cd
-		}
Paulo Alcantara d487cd
-	}
Paulo Alcantara d487cd
-
Paulo Alcantara d487cd
-out_unlock:
Paulo Alcantara d487cd
-	up_read(&htable_rw_lock);
Paulo Alcantara d487cd
-
Paulo Alcantara d487cd
-	for (i = 0; i < count; i++) {
Paulo Alcantara d487cd
-		char *path = ref_paths[i];
Paulo Alcantara d487cd
-		struct dfs_info3_param *refs = NULL;
Paulo Alcantara d487cd
-		int numrefs = 0;
Paulo Alcantara d487cd
-		int rc = 0;
Paulo Alcantara d487cd
-
Paulo Alcantara d487cd
-		if (!path)
Paulo Alcantara d487cd
-			continue;
Paulo Alcantara d487cd
-
Paulo Alcantara d487cd
-		ses = find_ipc_from_server_path(sessions, path);
Paulo Alcantara d487cd
-		if (IS_ERR(ses))
Paulo Alcantara d487cd
-			goto next_referral;
Paulo Alcantara d487cd
-
Paulo Alcantara d487cd
-		xid = get_xid();
Paulo Alcantara d487cd
-		rc = get_dfs_referral(xid, ses, path, &refs, &numrefs);
Paulo Alcantara d487cd
-		free_xid(xid);
Paulo Alcantara d487cd
-
Paulo Alcantara d487cd
-		if (!rc) {
Paulo Alcantara d487cd
-			down_write(&htable_rw_lock);
Paulo Alcantara d487cd
-			ce = lookup_cache_entry(path);
Paulo Alcantara d487cd
-			/*
Paulo Alcantara d487cd
-			 * We need to re-check it because other tasks might have it deleted or
Paulo Alcantara d487cd
-			 * updated.
Paulo Alcantara d487cd
-			 */
Paulo Alcantara d487cd
-			if (!IS_ERR(ce) && cache_entry_expired(ce))
Paulo Alcantara d487cd
-				update_cache_entry_locked(ce, refs, numrefs);
Paulo Alcantara d487cd
-			up_write(&htable_rw_lock);
Paulo Alcantara d487cd
-		}
Paulo Alcantara d487cd
-
Paulo Alcantara d487cd
-next_referral:
Paulo Alcantara d487cd
-		kfree(path);
Paulo Alcantara d487cd
-		free_dfs_info_array(refs, numrefs);
Paulo Alcantara d487cd
-	}
Paulo Alcantara d487cd
-}
Paulo Alcantara d487cd
-
Paulo Alcantara d487cd
 /*
Paulo Alcantara d487cd
  * Worker that will refresh DFS cache and active mounts based on lowest TTL value from a DFS
Paulo Alcantara d487cd
  * referral.
Paulo Alcantara d487cd
@@ -1654,11 +1586,8 @@ static void refresh_cache_worker(struct work_struct *work)
Paulo Alcantara d487cd
 		i += count;
Paulo Alcantara d487cd
 	}
Paulo Alcantara d487cd
 
Paulo Alcantara d487cd
-	if (sessions[0]) {
Paulo Alcantara d487cd
-		/* Refresh all active mounts and cached entries */
Paulo Alcantara d487cd
+	if (sessions[0])
Paulo Alcantara d487cd
 		refresh_mounts(sessions);
Paulo Alcantara d487cd
-		refresh_cache(sessions);
Paulo Alcantara d487cd
-	}
Paulo Alcantara d487cd
 
Paulo Alcantara d487cd
 	list_for_each_entry_safe(mg, tmp_mg, &mglist, refresh_list) {
Paulo Alcantara d487cd
 		list_del_init(&mg->refresh_list);
Paulo Alcantara d487cd
-- 
Paulo Alcantara d487cd
2.39.0
Paulo Alcantara d487cd
Paulo Alcantara d487cd