]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
smb3: do not start laundromat thread when dir leases
authorSteve French <stfrench@microsoft.com>
Tue, 19 Sep 2023 16:35:53 +0000 (11:35 -0500)
committerSteve French <stfrench@microsoft.com>
Tue, 19 Sep 2023 18:32:02 +0000 (13:32 -0500)
 disabled

When no directory lease support, or for IPC shares where directories
can not be opened, do not start an unneeded laundromat thread for
that mount (it wastes resources).

Fixes: d14de8067e3f ("cifs: Add a laundromat thread for cached directories")
Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
Acked-by: Tom Talpey <tom@talpey.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/cached_dir.c
fs/smb/client/cifsglob.h
fs/smb/client/cifsproto.h
fs/smb/client/connect.c
fs/smb/client/misc.c
fs/smb/client/smb2pdu.c

index b17f067e4ada0503e61550a16e6536c96055ed96..e2be8aedb26e3a4c2a8655c9d020f76dffc71dd4 100644 (file)
@@ -452,6 +452,9 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon)
        struct cached_fid *cfid, *q;
        LIST_HEAD(entry);
 
+       if (cfids == NULL)
+               return;
+
        spin_lock(&cfids->cfid_list_lock);
        list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
                list_move(&cfid->entry, &entry);
@@ -651,6 +654,9 @@ void free_cached_dirs(struct cached_fids *cfids)
        struct cached_fid *cfid, *q;
        LIST_HEAD(entry);
 
+       if (cfids == NULL)
+               return;
+
        if (cfids->laundromat) {
                kthread_stop(cfids->laundromat);
                cfids->laundromat = NULL;
index 032d8716f6719cb0084d90aa9145b29c4a55cb03..f594fcc0e889d91034ec0251bc293f1d699bdbff 100644 (file)
@@ -1943,7 +1943,7 @@ require use of the stronger protocol */
  * cifsInodeInfo->lock_sem     cifsInodeInfo->llist            cifs_init_once
  *                             ->can_cache_brlcks
  * cifsInodeInfo->deferred_lock        cifsInodeInfo->deferred_closes  cifsInodeInfo_alloc
- * cached_fid->fid_mutex               cifs_tcon->crfid                tconInfoAlloc
+ * cached_fid->fid_mutex               cifs_tcon->crfid                tcon_info_alloc
  * cifsFileInfo->fh_mutex              cifsFileInfo                    cifs_new_fileinfo
  * cifsFileInfo->file_info_lock        cifsFileInfo->count             cifs_new_fileinfo
  *                             ->invalidHandle                 initiate_cifs_search
index 7d8035846680ab224ee02300d4c0ed804a197d8c..0c37eefa18a57c0ed7be7921033ca86eda86c144 100644 (file)
@@ -512,7 +512,7 @@ extern int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses);
 
 extern struct cifs_ses *sesInfoAlloc(void);
 extern void sesInfoFree(struct cifs_ses *);
-extern struct cifs_tcon *tconInfoAlloc(void);
+extern struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled);
 extern void tconInfoFree(struct cifs_tcon *);
 
 extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
index 687754791bf0af496029bf7ba19d3cf7c46cdae7..3902e90dca6b0521062b8432b55b23cee2f7ae54 100644 (file)
@@ -1882,7 +1882,8 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)
                }
        }
 
-       tcon = tconInfoAlloc();
+       /* no need to setup directory caching on IPC share, so pass in false */
+       tcon = tcon_info_alloc(false);
        if (tcon == NULL)
                return -ENOMEM;
 
@@ -2492,7 +2493,10 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
                goto out_fail;
        }
 
-       tcon = tconInfoAlloc();
+       if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING)
+               tcon = tcon_info_alloc(true);
+       else
+               tcon = tcon_info_alloc(false);
        if (tcon == NULL) {
                rc = -ENOMEM;
                goto out_fail;
index 366b755ca9130df5177bd92ea7d1f940c18cbf1f..35b176457bbed02d0df438e127dc2c0482e5143c 100644 (file)
@@ -113,18 +113,22 @@ sesInfoFree(struct cifs_ses *buf_to_free)
 }
 
 struct cifs_tcon *
-tconInfoAlloc(void)
+tcon_info_alloc(bool dir_leases_enabled)
 {
        struct cifs_tcon *ret_buf;
 
        ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL);
        if (!ret_buf)
                return NULL;
-       ret_buf->cfids = init_cached_dirs();
-       if (!ret_buf->cfids) {
-               kfree(ret_buf);
-               return NULL;
+
+       if (dir_leases_enabled == true) {
+               ret_buf->cfids = init_cached_dirs();
+               if (!ret_buf->cfids) {
+                       kfree(ret_buf);
+                       return NULL;
+               }
        }
+       /* else ret_buf->cfids is already set to NULL above */
 
        atomic_inc(&tconInfoAllocCount);
        ret_buf->status = TID_NEW;
index 44d4943e9c566fadec7f82faaace3c4f7ab3ac58..405ea324f28df5d2e2b00363c151119a5f849ba4 100644 (file)
@@ -3878,7 +3878,7 @@ void smb2_reconnect_server(struct work_struct *work)
                goto done;
 
        /* allocate a dummy tcon struct used for reconnect */
-       tcon = tconInfoAlloc();
+       tcon = tcon_info_alloc(false);
        if (!tcon) {
                resched = true;
                list_for_each_entry_safe(ses, ses2, &tmp_ses_list, rlist) {