smb3: allow disabling requesting leases
authorSteve French <stfrench@microsoft.com>
Thu, 12 Sep 2019 02:46:20 +0000 (21:46 -0500)
committerSteve French <stfrench@microsoft.com>
Mon, 16 Sep 2019 16:43:38 +0000 (11:43 -0500)
In some cases to work around server bugs or performance
problems it can be helpful to be able to disable requesting
SMB2.1/SMB3 leases on a particular mount (not to all servers
and all shares we are mounted to). Add new mount parm
"nolease" which turns off requesting leases on directory
or file opens.  Currently the only way to disable leases is
globally through a module load parameter. This is more
granular.

Suggested-by: Pavel Shilovsky <pshilov@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
CC: Stable <stable@vger.kernel.org>
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/smb2pdu.c

index c1b6850720635c9e16f07596f0cd3e2a725ceddf..69601a9b29ad611da8c038c7d2f0295e974dca09 100644 (file)
@@ -438,6 +438,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
        cifs_show_security(s, tcon->ses);
        cifs_show_cache_flavor(s, cifs_sb);
 
+       if (tcon->no_lease)
+               seq_puts(s, ",nolease");
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
                seq_puts(s, ",multiuser");
        else if (tcon->ses->user_name)
index ef219991321746b80f82aa284a847097a61cab46..09b60ec5de3eb7679550e4ccb4ddd4e357bb8faa 100644 (file)
@@ -579,6 +579,7 @@ struct smb_vol {
        bool noblocksnd:1;
        bool noautotune:1;
        bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
+       bool no_lease:1;     /* disable requesting leases */
        bool fsc:1;     /* enable fscache */
        bool mfsymlinks:1; /* use Minshall+French Symlinks */
        bool multiuser:1;
@@ -1090,6 +1091,7 @@ struct cifs_tcon {
        bool need_reopen_files:1; /* need to reopen tcon file handles */
        bool use_resilient:1; /* use resilient instead of durable handles */
        bool use_persistent:1; /* use persistent instead of durable handles */
+       bool no_lease:1;    /* Do not request leases on files or directories */
        __le32 capabilities;
        __u32 share_flags;
        __u32 maximal_access;
index df1ccb581828c0d43e24315e60648102c32abcc3..e16b6cc1e31b42fe6c98b1a735762628fc997425 100644 (file)
@@ -74,7 +74,7 @@ enum {
        Opt_user_xattr, Opt_nouser_xattr,
        Opt_forceuid, Opt_noforceuid,
        Opt_forcegid, Opt_noforcegid,
-       Opt_noblocksend, Opt_noautotune,
+       Opt_noblocksend, Opt_noautotune, Opt_nolease,
        Opt_hard, Opt_soft, Opt_perm, Opt_noperm,
        Opt_mapposix, Opt_nomapposix,
        Opt_mapchars, Opt_nomapchars, Opt_sfu,
@@ -135,6 +135,7 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_noforcegid, "noforcegid" },
        { Opt_noblocksend, "noblocksend" },
        { Opt_noautotune, "noautotune" },
+       { Opt_nolease, "nolease" },
        { Opt_hard, "hard" },
        { Opt_soft, "soft" },
        { Opt_perm, "perm" },
@@ -1738,6 +1739,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                case Opt_noautotune:
                        vol->noautotune = 1;
                        break;
+               case Opt_nolease:
+                       vol->no_lease = 1;
+                       break;
                case Opt_hard:
                        vol->retry = 1;
                        break;
@@ -3294,6 +3298,8 @@ static int match_tcon(struct cifs_tcon *tcon, struct smb_vol *volume_info)
                return 0;
        if (tcon->handle_timeout != volume_info->handle_timeout)
                return 0;
+       if (tcon->no_lease != volume_info->no_lease)
+               return 0;
        return 1;
 }
 
@@ -3516,6 +3522,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
        tcon->nocase = volume_info->nocase;
        tcon->nohandlecache = volume_info->nohandlecache;
        tcon->local_lease = volume_info->local_lease;
+       tcon->no_lease = volume_info->no_lease;
        INIT_LIST_HEAD(&tcon->pending_opens);
 
        spin_lock(&cifs_tcp_ses_lock);
index 01d5c4af24586ccf5358f1ba84ee8f225f7dc4fb..ce647cfdc04fdfefdc2394d3575807e4c5f5af15 100644 (file)
@@ -2459,7 +2459,7 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock,
        iov[1].iov_len = uni_path_len;
        iov[1].iov_base = path;
 
-       if (!server->oplocks)
+       if ((!server->oplocks) || (tcon->no_lease))
                *oplock = SMB2_OPLOCK_LEVEL_NONE;
 
        if (!(server->capabilities & SMB2_GLOBAL_CAP_LEASING) ||