Merge tag 'kvmarm-fixes-5.14-2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / fs / cifs / cifsfs.c
index 5ddd20b..64b71c4 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: LGPL-2.1
 /*
  *   fs/cifs/cifsfs.c
  *
@@ -6,19 +7,6 @@
  *
  *   Common Internet FileSystem (CIFS) client
  *
- *   This library is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU Lesser General Public License as published
- *   by the Free Software Foundation; either version 2.1 of the License, or
- *   (at your option) any later version.
- *
- *   This library is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU Lesser General Public License for more details.
- *
- *   You should have received a copy of the GNU Lesser General Public License
- *   along with this library; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 /* Note that BB means BUGBUG (ie something to fix eventually) */
@@ -75,8 +63,9 @@ bool enable_oplocks = true;
 bool linuxExtEnabled = true;
 bool lookupCacheEnabled = true;
 bool disable_legacy_dialects; /* false by default */
-bool enable_gcm_256;  /* false by default, change when more servers support it */
+bool enable_gcm_256 = true;
 bool require_gcm_256; /* false by default */
+bool enable_negotiate_signing; /* false by default */
 unsigned int global_secflags = CIFSSEC_DEF;
 /* unsigned int ntlmv2_support = 0; */
 unsigned int sign_CIFS_PDUs = 1;
@@ -116,6 +105,9 @@ MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encr
 module_param(require_gcm_256, bool, 0644);
 MODULE_PARM_DESC(require_gcm_256, "Require strongest (256 bit) GCM encryption. Default: n/N/0");
 
+module_param(enable_negotiate_signing, bool, 0644);
+MODULE_PARM_DESC(enable_negotiate_signing, "Enable negotiating packet signing algorithm with server. Default: n/N/0");
+
 module_param(disable_legacy_dialects, bool, 0644);
 MODULE_PARM_DESC(disable_legacy_dialects, "To improve security it may be "
                                  "helpful to restrict the ability to "
@@ -133,6 +125,7 @@ struct workqueue_struct     *cifsiod_wq;
 struct workqueue_struct        *decrypt_wq;
 struct workqueue_struct        *fileinfo_put_wq;
 struct workqueue_struct        *cifsoplockd_wq;
+struct workqueue_struct        *deferredclose_wq;
 __u32 cifs_lock_secret;
 
 /*
@@ -217,8 +210,11 @@ cifs_read_super(struct super_block *sb)
        rc = super_setup_bdi(sb);
        if (rc)
                goto out_no_root;
-       /* tune readahead according to rsize */
-       sb->s_bdi->ra_pages = cifs_sb->ctx->rsize / PAGE_SIZE;
+       /* tune readahead according to rsize if readahead size not set on mount */
+       if (cifs_sb->ctx->rasize)
+               sb->s_bdi->ra_pages = cifs_sb->ctx->rasize / PAGE_SIZE;
+       else
+               sb->s_bdi->ra_pages = cifs_sb->ctx->rsize / PAGE_SIZE;
 
        sb->s_blocksize = CIFS_MAX_MSGSIZE;
        sb->s_blocksize_bits = 14;      /* default 2**14 = CIFS_MAX_MSGSIZE */
@@ -257,6 +253,29 @@ out_no_root:
 static void cifs_kill_sb(struct super_block *sb)
 {
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+       struct cifs_tcon *tcon;
+       struct cached_fid *cfid;
+
+       /*
+        * We ned to release all dentries for the cached directories
+        * before we kill the sb.
+        */
+       if (cifs_sb->root) {
+               dput(cifs_sb->root);
+               cifs_sb->root = NULL;
+       }
+       tcon = cifs_sb_master_tcon(cifs_sb);
+       if (tcon) {
+               cfid = &tcon->crfid;
+               mutex_lock(&cfid->fid_mutex);
+               if (cfid->dentry) {
+
+                       dput(cfid->dentry);
+                       cfid->dentry = NULL;
+               }
+               mutex_unlock(&cfid->fid_mutex);
+       }
+
        kill_anon_super(sb);
        cifs_umount(cifs_sb);
 }
@@ -364,6 +383,8 @@ cifs_alloc_inode(struct super_block *sb)
        /* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME; */
        INIT_LIST_HEAD(&cifs_inode->openFileList);
        INIT_LIST_HEAD(&cifs_inode->llist);
+       INIT_LIST_HEAD(&cifs_inode->deferred_closes);
+       spin_lock_init(&cifs_inode->deferred_lock);
        return &cifs_inode->vfs_inode;
 }
 
@@ -626,6 +647,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
        seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize);
        seq_printf(s, ",wsize=%u", cifs_sb->ctx->wsize);
        seq_printf(s, ",bsize=%u", cifs_sb->ctx->bsize);
+       if (cifs_sb->ctx->rasize)
+               seq_printf(s, ",rasize=%u", cifs_sb->ctx->rasize);
        if (tcon->ses->server->min_offload)
                seq_printf(s, ",esize=%u", tcon->ses->server->min_offload);
        seq_printf(s, ",echo_interval=%lu",
@@ -656,10 +679,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
                seq_printf(s, ",multichannel,max_channels=%zu",
                           tcon->ses->chan_max);
 
-#ifdef CONFIG_CIFS_SWN_UPCALL
        if (tcon->use_witness)
                seq_puts(s, ",witness");
-#endif
 
        return 0;
 }
@@ -834,7 +855,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
                goto out;
        }
 
-       rc = cifs_setup_volume_info(cifs_sb->ctx, NULL, old_ctx->UNC);
+       rc = cifs_setup_volume_info(cifs_sb->ctx, NULL, NULL);
        if (rc) {
                root = ERR_PTR(rc);
                goto out;
@@ -888,6 +909,9 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
        if (IS_ERR(root))
                goto out_super;
 
+       if (cifs_sb)
+               cifs_sb->root = dget(root);
+
        cifs_dbg(FYI, "dentry root is: %p\n", root);
        return root;
 
@@ -1528,10 +1552,6 @@ init_cifs(void)
        int rc = 0;
        cifs_proc_init();
        INIT_LIST_HEAD(&cifs_tcp_ses_list);
-#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
-       INIT_LIST_HEAD(&GlobalDnotifyReqList);
-       INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
-#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
 /*
  *  Initialize Global counters
  */
@@ -1606,9 +1626,16 @@ init_cifs(void)
                goto out_destroy_fileinfo_put_wq;
        }
 
+       deferredclose_wq = alloc_workqueue("deferredclose",
+                                          WQ_FREEZABLE|WQ_MEM_RECLAIM, 0);
+       if (!deferredclose_wq) {
+               rc = -ENOMEM;
+               goto out_destroy_cifsoplockd_wq;
+       }
+
        rc = cifs_fscache_register();
        if (rc)
-               goto out_destroy_cifsoplockd_wq;
+               goto out_destroy_deferredclose_wq;
 
        rc = cifs_init_inodecache();
        if (rc)
@@ -1676,6 +1703,8 @@ out_destroy_inodecache:
        cifs_destroy_inodecache();
 out_unreg_fscache:
        cifs_fscache_unregister();
+out_destroy_deferredclose_wq:
+       destroy_workqueue(deferredclose_wq);
 out_destroy_cifsoplockd_wq:
        destroy_workqueue(cifsoplockd_wq);
 out_destroy_fileinfo_put_wq:
@@ -1710,6 +1739,7 @@ exit_cifs(void)
        cifs_destroy_mids();
        cifs_destroy_inodecache();
        cifs_fscache_unregister();
+       destroy_workqueue(deferredclose_wq);
        destroy_workqueue(cifsoplockd_wq);
        destroy_workqueue(decrypt_wq);
        destroy_workqueue(fileinfo_put_wq);