Message ID | 20230706023224.609324-1-lsahlber@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | cifs: Add a laundromat thread for cached directories | expand |
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 >
On Thu, Jul 6, 2023 at 8:51 AM Steve French <smfrench@gmail.com> wrote: > > 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 Hi Ronnie, Why do we need this? We only cache dirents if we have the parent directory lease. As long as we have the lease, why can't we continue to cache these?
We can only cache a limited amount of entries. We need to force entries to be dropped from the cache at regular intervals to make room for potential new entries/different directories. Access patterns change over time and what is the "hot" directory will also change over time so we need to drop entries to make sure that when some directory becomes hot there will be decent chance that it will be able to become cached. If a directory becomes "cold" we no longer want it to take up entries in our cache. regards ronnie sahlberg On Fri, 7 Jul 2023 at 15:37, Shyam Prasad N <nspmangalore@gmail.com> wrote: > > On Thu, Jul 6, 2023 at 8:51 AM Steve French <smfrench@gmail.com> wrote: > > > > 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 > > Hi Ronnie, > > Why do we need this? > We only cache dirents if we have the parent directory lease. As long > as we have the lease, why can't we continue to cache these? > > -- > Regards, > Shyam
On Fri, Jul 7, 2023 at 11:20 AM ronnie sahlberg <ronniesahlberg@gmail.com> wrote: > > We can only cache a limited amount of entries. > We need to force entries to be dropped from the cache at regular > intervals to make room for potential new entries/different > directories. > > Access patterns change over time and what is the "hot" directory will > also change over time so we need to drop entries to make sure that > when some directory becomes hot there will be decent chance that it > will be able to become cached. > > If a directory becomes "cold" we no longer want it to take up entries > in our cache. > Makes sense. However, the value of MAX_CACHED_FIDS to 16 seems very restrictive. And as Steve suggested, 30s expiry seems very aggressive. I think we can increase both. Also, I was wondering how do we handle cleanup of cfids when VFS decides to free the inode (maybe due to memory crunch?). Regards, Shyam > regards > ronnie sahlberg > > > On Fri, 7 Jul 2023 at 15:37, Shyam Prasad N <nspmangalore@gmail.com> wrote: > > > > On Thu, Jul 6, 2023 at 8:51 AM Steve French <smfrench@gmail.com> wrote: > > > > > > 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 > > > > Hi Ronnie, > > > > Why do we need this? > > We only cache dirents if we have the parent directory lease. As long > > as we have the lease, why can't we continue to cache these? > > > > -- > > Regards, > > Shyam
On Fri, 7 Jul 2023 at 16:37, Shyam Prasad N <nspmangalore@gmail.com> wrote: > > On Fri, Jul 7, 2023 at 11:20 AM ronnie sahlberg > <ronniesahlberg@gmail.com> wrote: > > > > We can only cache a limited amount of entries. > > We need to force entries to be dropped from the cache at regular > > intervals to make room for potential new entries/different > > directories. > > > > Access patterns change over time and what is the "hot" directory will > > also change over time so we need to drop entries to make sure that > > when some directory becomes hot there will be decent chance that it > > will be able to become cached. > > > > If a directory becomes "cold" we no longer want it to take up entries > > in our cache. > > > > Makes sense. > > However, the value of MAX_CACHED_FIDS to 16 seems very restrictive. > And as Steve suggested, 30s expiry seems very aggressive. > I think we can increase both. We can and should increase it at some stage but lets keep it small and short for now until we feel confident it is all stable. Once we are confident it is good we can increase these quite a bit.
On Fri, Jul 7, 2023 at 1:37 AM Shyam Prasad N <nspmangalore@gmail.com> wrote: > > On Fri, Jul 7, 2023 at 11:20 AM ronnie sahlberg > <ronniesahlberg@gmail.com> wrote: > > > > We can only cache a limited amount of entries. > > We need to force entries to be dropped from the cache at regular > > intervals to make room for potential new entries/different > > directories. > > > > Access patterns change over time and what is the "hot" directory will > > also change over time so we need to drop entries to make sure that > > when some directory becomes hot there will be decent chance that it > > will be able to become cached. > > > > If a directory becomes "cold" we no longer want it to take up entries > > in our cache. > > > > Makes sense. > > However, the value of MAX_CACHED_FIDS to 16 seems very restrictive. > And as Steve suggested, 30s expiry seems very aggressive. > I think we can increase both. At least for the short term we can make this configurable (which will make it easier to test the best default values in the long run) e.g. via mount parm. Will make it much easier to experiment to optimize the value
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);
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(+)