diff mbox series

[4/5] smb: No need to wait for work when cleaning up cached directories

Message ID 20241108222906.3257172-5-paul@darkrain42.org (mailing list archive)
State New
Headers show
Series SMB cached directory fixes around reconnection/unmounting | expand

Commit Message

Paul Aurich Nov. 8, 2024, 10:29 p.m. UTC
It isn't possible for cfids_laundromat_worker(),
invalidate_all_cached_dirs(), and cached_dir_lease_break() to race with
each other. Each holds the spinlock while walking the list of cfids, and
removes entries from the list. cfids_laundromat_worker() and
invalidate_all_cached_dirs() will never see a cfid that has pending
work.

Signed-off-by: Paul Aurich <paul@darkrain42.org>
---
 fs/smb/client/cached_dir.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index 06eb19dabb0e..de1e41abdaf2 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -516,11 +516,10 @@  void invalidate_all_cached_dirs(struct cifs_tcon *tcon)
 	}
 	spin_unlock(&cfids->cfid_list_lock);
 
 	list_for_each_entry_safe(cfid, q, &entry, entry) {
 		list_del(&cfid->entry);
-		cancel_work_sync(&cfid->lease_break);
 		/*
 		 * Drop the ref-count from above, either the lease-ref (if there
 		 * was one) or the extra one acquired.
 		 */
 		kref_put(&cfid->refcount, smb2_close_cached_fid);
@@ -594,10 +593,12 @@  static struct cached_fid *init_cached_dir(const char *path)
 
 static void free_cached_dir(struct cached_fid *cfid)
 {
 	struct cached_dirent *dirent, *q;
 
+	WARN_ON(work_pending(&cfid->lease_break));
+
 	dput(cfid->dentry);
 	cfid->dentry = NULL;
 
 	/*
 	 * Delete all cached dirent names
@@ -640,15 +641,10 @@  static void cfids_laundromat_worker(struct work_struct *work)
 	}
 	spin_unlock(&cfids->cfid_list_lock);
 
 	list_for_each_entry_safe(cfid, q, &entry, entry) {
 		list_del(&cfid->entry);
-		/*
-		 * Cancel and wait for the work to finish in case we are racing
-		 * with it.
-		 */
-		cancel_work_sync(&cfid->lease_break);
 		/*
 		 * Drop the ref-count from above, either the lease-ref (if there
 		 * was one) or the extra one acquired.
 		 */
 		kref_put(&cfid->refcount, smb2_close_cached_fid);