All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steve French <smfrench@gmail.com>
To: Ronnie Sahlberg <lsahlber@redhat.com>
Cc: linux-cifs <linux-cifs@vger.kernel.org>
Subject: Re: [PATCH] cifs: Add a laundromat thread for cached directories
Date: Wed, 5 Jul 2023 22:07:38 -0500	[thread overview]
Message-ID: <CAH2r5mtAXKOOUN6BfVD25SzAq6TXfeRt+9u19i5o+f6oSgfGrA@mail.gmail.com> (raw)
In-Reply-To: <20230706023224.609324-1-lsahlber@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 4648 bytes --]

updated to fix two checkpatch warnings (see attached) and tentatively
merged into for-next pending review/testing


On Wed, Jul 5, 2023 at 9:32 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> and drop cached directories after 30 seconds
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
>  fs/smb/client/cached_dir.c | 67 ++++++++++++++++++++++++++++++++++++++
>  fs/smb/client/cached_dir.h |  1 +
>  2 files changed, 68 insertions(+)
>
> diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
> index bfc964b36c72..f567eea0a456 100644
> --- a/fs/smb/client/cached_dir.c
> +++ b/fs/smb/client/cached_dir.c
> @@ -568,6 +568,53 @@ static void free_cached_dir(struct cached_fid *cfid)
>         kfree(cfid);
>  }
>
> +static int
> +cifs_cfids_laundromat_thread(void *p)
> +{
> +       struct cached_fids *cfids = p;
> +       struct cached_fid *cfid, *q;
> +       struct list_head entry;
> +
> +       while (!kthread_should_stop()) {
> +               ssleep(1);
> +               INIT_LIST_HEAD(&entry);
> +               if (kthread_should_stop())
> +                       return 0;
> +               spin_lock(&cfids->cfid_list_lock);
> +               list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
> +                       if (jiffies > cfid->time + HZ * 30) {
> +                               list_del(&cfid->entry);
> +                               list_add(&cfid->entry, &entry);
> +                               cfids->num_entries--;
> +                       }
> +               }
> +               spin_unlock(&cfids->cfid_list_lock);
> +
> +               list_for_each_entry_safe(cfid, q, &entry, entry) {
> +                       cfid->on_list = false;
> +                       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);
> +                       if (cfid->has_lease) {
> +                               /*
> +                                * We lease has not yet been cancelled from
> +                                * the server so we need to drop the reference.
> +                                */
> +                               spin_lock(&cfids->cfid_list_lock);
> +                               cfid->has_lease = false;
> +                               spin_unlock(&cfids->cfid_list_lock);
> +                               kref_put(&cfid->refcount, smb2_close_cached_fid);
> +                       }
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +
>  struct cached_fids *init_cached_dirs(void)
>  {
>         struct cached_fids *cfids;
> @@ -577,6 +624,20 @@ struct cached_fids *init_cached_dirs(void)
>                 return NULL;
>         spin_lock_init(&cfids->cfid_list_lock);
>         INIT_LIST_HEAD(&cfids->entries);
> +
> +       /*
> +        * since we're in a cifs function already, we know that
> +        * this will succeed. No need for try_module_get().
> +        */
> +       __module_get(THIS_MODULE);
> +       cfids->laundromat = kthread_run(cifs_cfids_laundromat_thread,
> +                                 cfids, "cifsd-cfid-laundromat");
> +       if (IS_ERR(cfids->laundromat)) {
> +               cifs_dbg(VFS, "Failed to start cfids laundromat thread.\n");
> +               kfree(cfids);
> +               module_put(THIS_MODULE);
> +               return NULL;
> +       }
>         return cfids;
>  }
>
> @@ -589,6 +650,12 @@ void free_cached_dirs(struct cached_fids *cfids)
>         struct cached_fid *cfid, *q;
>         LIST_HEAD(entry);
>
> +       if (cfids->laundromat) {
> +               kthread_stop(cfids->laundromat);
> +               cfids->laundromat = NULL;
> +               module_put(THIS_MODULE);
> +       }
> +
>         spin_lock(&cfids->cfid_list_lock);
>         list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
>                 cfid->on_list = false;
> diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
> index 2f4e764c9ca9..facc9b154d00 100644
> --- a/fs/smb/client/cached_dir.h
> +++ b/fs/smb/client/cached_dir.h
> @@ -57,6 +57,7 @@ struct cached_fids {
>         spinlock_t cfid_list_lock;
>         int num_entries;
>         struct list_head entries;
> +       struct task_struct *laundromat;
>  };
>
>  extern struct cached_fids *init_cached_dirs(void);
> --
> 2.35.3
>


-- 
Thanks,

Steve

[-- Attachment #2: 0001-cifs-Add-a-laundromat-thread-for-cached-directories.patch --]
[-- Type: text/x-patch, Size: 3400 bytes --]

From cc9ed26848f724065aba50647540e5ebe6e0d3e9 Mon Sep 17 00:00:00 2001
From: Ronnie Sahlberg <lsahlber@redhat.com>
Date: Thu, 6 Jul 2023 12:32:24 +1000
Subject: [PATCH] cifs: Add a laundromat thread for cached directories

and drop cached directories after 30 seconds

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
---
 fs/smb/client/cached_dir.c | 67 ++++++++++++++++++++++++++++++++++++++
 fs/smb/client/cached_dir.h |  1 +
 2 files changed, 68 insertions(+)

diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index bfc964b36c72..f567eea0a456 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -568,6 +568,53 @@ static void free_cached_dir(struct cached_fid *cfid)
 	kfree(cfid);
 }
 
+static int
+cifs_cfids_laundromat_thread(void *p)
+{
+	struct cached_fids *cfids = p;
+	struct cached_fid *cfid, *q;
+	struct list_head entry;
+
+	while (!kthread_should_stop()) {
+		ssleep(1);
+		INIT_LIST_HEAD(&entry);
+		if (kthread_should_stop())
+			return 0;
+		spin_lock(&cfids->cfid_list_lock);
+		list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
+			if (time_after(jiffies, cfid->time + HZ * 30) {
+				list_del(&cfid->entry);
+				list_add(&cfid->entry, &entry);
+				cfids->num_entries--;
+			}
+		}
+		spin_unlock(&cfids->cfid_list_lock);
+
+		list_for_each_entry_safe(cfid, q, &entry, entry) {
+			cfid->on_list = false;
+			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);
+			if (cfid->has_lease) {
+				/*
+				 * We lease has not yet been cancelled from
+				 * the server so we need to drop the reference.
+				 */
+				spin_lock(&cfids->cfid_list_lock);
+				cfid->has_lease = false;
+				spin_unlock(&cfids->cfid_list_lock);
+				kref_put(&cfid->refcount, smb2_close_cached_fid);
+			}
+		}
+	}
+
+	return 0;
+}
+
+
 struct cached_fids *init_cached_dirs(void)
 {
 	struct cached_fids *cfids;
@@ -577,6 +624,20 @@ struct cached_fids *init_cached_dirs(void)
 		return NULL;
 	spin_lock_init(&cfids->cfid_list_lock);
 	INIT_LIST_HEAD(&cfids->entries);
+
+	/*
+	 * since we're in a cifs function already, we know that
+	 * this will succeed. No need for try_module_get().
+	 */
+	__module_get(THIS_MODULE);
+	cfids->laundromat = kthread_run(cifs_cfids_laundromat_thread,
+				  cfids, "cifsd-cfid-laundromat");
+	if (IS_ERR(cfids->laundromat)) {
+		cifs_dbg(VFS, "Failed to start cfids laundromat thread.\n");
+		kfree(cfids);
+		module_put(THIS_MODULE);
+		return NULL;
+	}
 	return cfids;
 }
 
@@ -589,6 +650,12 @@ void free_cached_dirs(struct cached_fids *cfids)
 	struct cached_fid *cfid, *q;
 	LIST_HEAD(entry);
 
+	if (cfids->laundromat) {
+		kthread_stop(cfids->laundromat);
+		cfids->laundromat = NULL;
+		module_put(THIS_MODULE);
+	}
+
 	spin_lock(&cfids->cfid_list_lock);
 	list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
 		cfid->on_list = false;
diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
index 2f4e764c9ca9..facc9b154d00 100644
--- a/fs/smb/client/cached_dir.h
+++ b/fs/smb/client/cached_dir.h
@@ -57,6 +57,7 @@ struct cached_fids {
 	spinlock_t cfid_list_lock;
 	int num_entries;
 	struct list_head entries;
+	struct task_struct *laundromat;
 };
 
 extern struct cached_fids *init_cached_dirs(void);
-- 
2.34.1


  reply	other threads:[~2023-07-06  3:08 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-06  2:32 [PATCH] cifs: Add a laundromat thread for cached directories Ronnie Sahlberg
2023-07-06  3:07 ` Steve French [this message]
2023-07-07  5:31   ` Shyam Prasad N
2023-07-07  5:50     ` ronnie sahlberg
2023-07-07  6:37       ` Shyam Prasad N
2023-07-07  6:41         ` ronnie sahlberg
2023-07-07 16:17         ` Steve French

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAH2r5mtAXKOOUN6BfVD25SzAq6TXfeRt+9u19i5o+f6oSgfGrA@mail.gmail.com \
    --to=smfrench@gmail.com \
    --cc=linux-cifs@vger.kernel.org \
    --cc=lsahlber@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.