summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnzo Matsumiya <ematsumiya@suse.de>2025-09-08 10:13:32 -0300
committerEnzo Matsumiya <ematsumiya@suse.de>2025-09-08 10:13:32 -0300
commitdb28092064f679cdbe1bb0a4228a62918190bf96 (patch)
tree915b93956432c7dc7003f7a8612d8932ee62db4b
parent3f134bd4192d4b5285b254167b392d67bf89e7b5 (diff)
downloadlinux-db28092064f679cdbe1bb0a4228a62918190bf96.tar.gz
linux-db28092064f679cdbe1bb0a4228a62918190bf96.tar.bz2
linux-db28092064f679cdbe1bb0a4228a62918190bf96.zip
smb: client: remove cached_dir_put_work/put_work
Move cfid to dying list directly on cached_dir_lease_break(), and schedule laundromat for cleanup there too. Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
-rw-r--r--fs/smb/client/cached_dir.c57
-rw-r--r--fs/smb/client/cached_dir.h1
2 files changed, 17 insertions, 41 deletions
diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index 7c992141576c..8912c27cbc23 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -577,41 +577,13 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon)
flush_delayed_work(&cfids->laundromat_work);
}
-/*
- * Release the cached directory's dentry and schedule immediate cleanup on laundromat.
- * Must be called with a reference to the cached_fid and a reference to the tcon.
- */
-static void cached_dir_put_work(struct work_struct *work)
-{
- struct cached_fid *cfid = container_of(work, struct cached_fid, put_work);
- struct cached_fids *cfids = cfid->cfids;
- struct cifs_tcon *tcon = cfid->tcon;
- struct dentry *dentry;
-
- spin_lock(&cfid->fid_lock);
- dentry = cfid->dentry;
- cfid->dentry = NULL;
- spin_unlock(&cfid->fid_lock);
-
- dput(dentry);
-
- /* move to dying list so laundromat can clean it up */
- spin_lock(&cfids->cfid_list_lock);
- list_move(&cfid->entry, &cfids->dying);
- cfid->on_list = false;
- cfids->num_entries--;
- spin_unlock(&cfids->cfid_list_lock);
-
- cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_cached_close);
- mod_delayed_work(cfid_put_wq, &cfids->laundromat_work, 0);
-}
-
bool cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16])
{
struct cached_fids *cfids = tcon->cfids;
struct cached_fid *cfid;
+ bool found = false;
- if (cfids == NULL)
+ if (!cfids)
return false;
spin_lock(&cfids->cfid_list_lock);
@@ -623,16 +595,24 @@ bool cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16])
cfid->has_lease = false;
cfid->time = 0;
- ++tcon->tc_count;
- trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
- netfs_trace_tcon_ref_get_cached_lease_break);
- queue_work(cfid_put_wq, &cfid->put_work);
- spin_unlock(&cfids->cfid_list_lock);
- return true;
+ /*
+ * We found a lease, move it to the dying list and schedule immediate
+ * cleanup on laundromat.
+ * No need to take a ref here, as we still hold our initial one.
+ */
+ list_move(&cfid->entry, &cfids->dying);
+ cfids->num_entries--;
+ cfid->on_list = false;
+ found = true;
+ break;
}
}
spin_unlock(&cfids->cfid_list_lock);
- return false;
+
+ if (found)
+ mod_delayed_work(cfid_put_wq, &cfids->laundromat_work, 0);
+
+ return found;
}
static struct cached_fid *init_cached_dir(const char *path)
@@ -648,7 +628,6 @@ static struct cached_fid *init_cached_dir(const char *path)
return NULL;
}
- INIT_WORK(&cfid->put_work, cached_dir_put_work);
INIT_LIST_HEAD(&cfid->entry);
INIT_LIST_HEAD(&cfid->dirents.entries);
mutex_init(&cfid->dirents.de_mutex);
@@ -661,8 +640,6 @@ static void free_cached_dir(struct cached_fid *cfid)
{
struct cached_dirent *dirent, *q;
- WARN_ON(work_pending(&cfid->put_work));
-
dput(cfid->dentry);
cfid->dentry = NULL;
diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
index e5445e3a7bd3..5e892d53a67a 100644
--- a/fs/smb/client/cached_dir.h
+++ b/fs/smb/client/cached_dir.h
@@ -44,7 +44,6 @@ struct cached_fid {
spinlock_t fid_lock;
struct cifs_tcon *tcon;
struct dentry *dentry;
- struct work_struct put_work;
struct smb2_file_all_info file_all_info;
struct cached_dirents dirents;
};