|
@@ -88,6 +88,7 @@ enum {
|
|
|
Opt_fsc, Opt_mfsymlinks,
|
|
|
Opt_multiuser, Opt_sloppy, Opt_nosharesock,
|
|
|
Opt_persistent, Opt_nopersistent,
|
|
|
+ Opt_resilient, Opt_noresilient,
|
|
|
|
|
|
/* Mount options which take numeric value */
|
|
|
Opt_backupuid, Opt_backupgid, Opt_uid,
|
|
@@ -172,6 +173,8 @@ static const match_table_t cifs_mount_option_tokens = {
|
|
|
{ Opt_nosharesock, "nosharesock" },
|
|
|
{ Opt_persistent, "persistenthandles"},
|
|
|
{ Opt_nopersistent, "nopersistenthandles"},
|
|
|
+ { Opt_resilient, "resilienthandles"},
|
|
|
+ { Opt_noresilient, "noresilienthandles"},
|
|
|
|
|
|
{ Opt_backupuid, "backupuid=%s" },
|
|
|
{ Opt_backupgid, "backupgid=%s" },
|
|
@@ -1510,12 +1513,23 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
|
|
|
break;
|
|
|
case Opt_persistent:
|
|
|
vol->persistent = true;
|
|
|
- if (vol->nopersistent) {
|
|
|
+ if ((vol->nopersistent) || (vol->resilient)) {
|
|
|
cifs_dbg(VFS,
|
|
|
"persistenthandles mount options conflict\n");
|
|
|
goto cifs_parse_mount_err;
|
|
|
}
|
|
|
break;
|
|
|
+ case Opt_resilient:
|
|
|
+ vol->resilient = true;
|
|
|
+ if (vol->persistent) {
|
|
|
+ cifs_dbg(VFS,
|
|
|
+ "persistenthandles mount options conflict\n");
|
|
|
+ goto cifs_parse_mount_err;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case Opt_noresilient:
|
|
|
+ vol->resilient = false; /* already the default */
|
|
|
+ break;
|
|
|
|
|
|
/* Numeric Values */
|
|
|
case Opt_backupuid:
|
|
@@ -2681,6 +2695,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
|
|
|
"SMB3 or later required for persistent handles\n");
|
|
|
rc = -EOPNOTSUPP;
|
|
|
goto out_fail;
|
|
|
+#ifdef CONFIG_CIFS_SMB2
|
|
|
} else if (ses->server->capabilities &
|
|
|
SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
|
|
|
tcon->use_persistent = true;
|
|
@@ -2689,12 +2704,23 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
|
|
|
"Persistent handles not supported on share\n");
|
|
|
rc = -EOPNOTSUPP;
|
|
|
goto out_fail;
|
|
|
+#endif /* CONFIG_CIFS_SMB2 */
|
|
|
}
|
|
|
+#ifdef CONFIG_CIFS_SMB2
|
|
|
} else if ((tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
|
|
|
&& (ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
|
|
|
&& (volume_info->nopersistent == false)) {
|
|
|
cifs_dbg(FYI, "enabling persistent handles\n");
|
|
|
tcon->use_persistent = true;
|
|
|
+#endif /* CONFIG_CIFS_SMB2 */
|
|
|
+ } else if (volume_info->resilient) {
|
|
|
+ if (ses->server->vals->protocol_id == 0) {
|
|
|
+ cifs_dbg(VFS,
|
|
|
+ "SMB2.1 or later required for resilient handles\n");
|
|
|
+ rc = -EOPNOTSUPP;
|
|
|
+ goto out_fail;
|
|
|
+ }
|
|
|
+ tcon->use_resilient = true;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -3545,12 +3571,15 @@ try_mount_again:
|
|
|
goto mount_fail_check;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_CIFS_SMB2
|
|
|
if ((volume_info->persistent == true) && ((ses->server->capabilities &
|
|
|
SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) == 0)) {
|
|
|
cifs_dbg(VFS, "persistent handles not supported by server\n");
|
|
|
rc = -EOPNOTSUPP;
|
|
|
goto mount_fail_check;
|
|
|
}
|
|
|
+#endif /* CONFIG_CIFS_SMB2*/
|
|
|
+
|
|
|
/* search for existing tcon to this server share */
|
|
|
tcon = cifs_get_tcon(ses, volume_info);
|
|
|
if (IS_ERR(tcon)) {
|