Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3996e6a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6

Pull SMB3 updates from Steve French:
 "A collection of SMB3 patches adding some reliability features
  (persistent and resilient handles) and improving SMB3 copy offload.

  I will have some additional patches for SMB3 encryption and SMB3.1.1
  signing (important security features), and also for improving SMB3
  persistent handle reconnection (setting ChannelSequence number e.g.)
  that I am still working on but wanted to get this set in since they
  can stand alone"

* 'for-next' of git://git.samba.org/sfrench/cifs-2.6:
  Allow copy offload (CopyChunk) across shares
  Add resilienthandles mount parm
  [SMB3] Send durable handle v2 contexts when use of persistent handles required
  [SMB3] Display persistenthandles in /proc/mounts for SMB3 shares if enabled
  [SMB3] Enable checking for continuous availability and persistent handle support
  [SMB3] Add parsing for new mount option controlling persistent handles
  Allow duplicate extents in SMB3 not just SMB3.1.1
parents e75cdf98 7b52e279
Loading
Loading
Loading
Loading
+4 −12
Original line number Diff line number Diff line
@@ -454,6 +454,10 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
		seq_puts(s, ",nocase");
	if (tcon->retry)
		seq_puts(s, ",hard");
	if (tcon->use_persistent)
		seq_puts(s, ",persistenthandles");
	else if (tcon->use_resilient)
		seq_puts(s, ",resilienthandles");
	if (tcon->unix_ext)
		seq_puts(s, ",unix");
	else
@@ -921,9 +925,7 @@ const struct file_operations cifs_file_ops = {
	.mmap  = cifs_file_mmap,
	.splice_read = generic_file_splice_read,
	.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_POSIX
	.unlocked_ioctl	= cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
	.setlease = cifs_setlease,
	.fallocate = cifs_fallocate,
};
@@ -939,9 +941,7 @@ const struct file_operations cifs_file_strict_ops = {
	.mmap = cifs_file_strict_mmap,
	.splice_read = generic_file_splice_read,
	.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_POSIX
	.unlocked_ioctl	= cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
	.setlease = cifs_setlease,
	.fallocate = cifs_fallocate,
};
@@ -957,9 +957,7 @@ const struct file_operations cifs_file_direct_ops = {
	.flush = cifs_flush,
	.mmap = cifs_file_mmap,
	.splice_read = generic_file_splice_read,
#ifdef CONFIG_CIFS_POSIX
	.unlocked_ioctl  = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
	.llseek = cifs_llseek,
	.setlease = cifs_setlease,
	.fallocate = cifs_fallocate,
@@ -975,9 +973,7 @@ const struct file_operations cifs_file_nobrl_ops = {
	.mmap  = cifs_file_mmap,
	.splice_read = generic_file_splice_read,
	.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_POSIX
	.unlocked_ioctl	= cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
	.setlease = cifs_setlease,
	.fallocate = cifs_fallocate,
};
@@ -992,9 +988,7 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
	.mmap = cifs_file_strict_mmap,
	.splice_read = generic_file_splice_read,
	.llseek = cifs_llseek,
#ifdef CONFIG_CIFS_POSIX
	.unlocked_ioctl	= cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
	.setlease = cifs_setlease,
	.fallocate = cifs_fallocate,
};
@@ -1009,9 +1003,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
	.flush = cifs_flush,
	.mmap = cifs_file_mmap,
	.splice_read = generic_file_splice_read,
#ifdef CONFIG_CIFS_POSIX
	.unlocked_ioctl  = cifs_ioctl,
#endif /* CONFIG_CIFS_POSIX */
	.llseek = cifs_llseek,
	.setlease = cifs_setlease,
	.fallocate = cifs_fallocate,
+7 −1
Original line number Diff line number Diff line
@@ -493,7 +493,10 @@ struct smb_vol {
	bool mfsymlinks:1; /* use Minshall+French Symlinks */
	bool multiuser:1;
	bool rwpidforward:1; /* pid forward for read/write operations */
	bool nosharesock;
	bool nosharesock:1;
	bool persistent:1;
	bool nopersistent:1;
	bool resilient:1; /* noresilient not required since not fored for CA */
	unsigned int rsize;
	unsigned int wsize;
	bool sockopt_tcp_nodelay:1;
@@ -895,6 +898,8 @@ struct cifs_tcon {
	bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
	bool broken_sparse_sup; /* if server or share does not support sparse */
	bool need_reconnect:1; /* connection reset, tid now invalid */
	bool use_resilient:1; /* use resilient instead of durable handles */
	bool use_persistent:1; /* use persistent instead of durable handles */
#ifdef CONFIG_CIFS_SMB2
	bool print:1;		/* set if connection to printer share */
	bool bad_network_name:1; /* set if ret status STATUS_BAD_NETWORK_NAME */
@@ -1015,6 +1020,7 @@ struct cifs_fid {
	__u64 persistent_fid;	/* persist file id for smb2 */
	__u64 volatile_fid;	/* volatile file id for smb2 */
	__u8 lease_key[SMB2_LEASE_KEY_SIZE];	/* lease key for smb2 */
	__u8 create_guid[16];
#endif
	struct cifs_pending_open *pending_open;
	unsigned int epoch;
+78 −0
Original line number Diff line number Diff line
@@ -87,6 +87,8 @@ enum {
	Opt_sign, Opt_seal, Opt_noac,
	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,
@@ -169,6 +171,10 @@ static const match_table_t cifs_mount_option_tokens = {
	{ Opt_multiuser, "multiuser" },
	{ Opt_sloppy, "sloppy" },
	{ Opt_nosharesock, "nosharesock" },
	{ Opt_persistent, "persistenthandles"},
	{ Opt_nopersistent, "nopersistenthandles"},
	{ Opt_resilient, "resilienthandles"},
	{ Opt_noresilient, "noresilienthandles"},

	{ Opt_backupuid, "backupuid=%s" },
	{ Opt_backupgid, "backupgid=%s" },
@@ -1497,6 +1503,33 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
		case Opt_nosharesock:
			vol->nosharesock = true;
			break;
		case Opt_nopersistent:
			vol->nopersistent = true;
			if (vol->persistent) {
				cifs_dbg(VFS,
				  "persistenthandles mount options conflict\n");
				goto cifs_parse_mount_err;
			}
			break;
		case Opt_persistent:
			vol->persistent = true;
			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:
@@ -2655,6 +2688,42 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
		cifs_dbg(FYI, "DFS disabled (%d)\n", tcon->Flags);
	}
	tcon->seal = volume_info->seal;
	tcon->use_persistent = false;
	/* check if SMB2 or later, CIFS does not support persistent handles */
	if (volume_info->persistent) {
		if (ses->server->vals->protocol_id == 0) {
			cifs_dbg(VFS,
			     "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;
		else /* persistent handles requested but not supported */ {
			cifs_dbg(VFS,
				"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;
	}

	/*
	 * We can have only one retry value for a connection to a share so for
	 * resources mounted more than once to the same server share the last
@@ -3503,6 +3572,15 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
		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)) {
+8 −3
Original line number Diff line number Diff line
@@ -85,9 +85,14 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file,
	src_tcon = tlink_tcon(smb_file_src->tlink);
	target_tcon = tlink_tcon(smb_file_target->tlink);

	/* check if source and target are on same tree connection */
	if (src_tcon != target_tcon) {
		cifs_dbg(VFS, "file copy src and target on different volume\n");
	/* check source and target on same server (or volume if dup_extents) */
	if (dup_extents && (src_tcon != target_tcon)) {
		cifs_dbg(VFS, "source and target of copy not on same share\n");
		goto out_fput;
	}

	if (!dup_extents && (src_tcon->ses != target_tcon->ses)) {
		cifs_dbg(VFS, "source and target of copy not on same server\n");
		goto out_fput;
	}

+19 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
	struct smb2_file_all_info *smb2_data = NULL;
	__u8 smb2_oplock[17];
	struct cifs_fid *fid = oparms->fid;
	struct network_resiliency_req nr_ioctl_req;

	smb2_path = cifs_convert_path_to_utf16(oparms->path, oparms->cifs_sb);
	if (smb2_path == NULL) {
@@ -67,6 +68,24 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
	if (rc)
		goto out;


	 if (oparms->tcon->use_resilient) {
		nr_ioctl_req.Timeout = 0; /* use server default (120 seconds) */
		nr_ioctl_req.Reserved = 0;
		rc = SMB2_ioctl(xid, oparms->tcon, fid->persistent_fid,
			fid->volatile_fid, FSCTL_LMR_REQUEST_RESILIENCY, true,
			(char *)&nr_ioctl_req, sizeof(nr_ioctl_req),
			NULL, NULL /* no return info */);
		if (rc == -EOPNOTSUPP) {
			cifs_dbg(VFS,
			     "resiliency not supported by server, disabling\n");
			oparms->tcon->use_resilient = false;
		} else if (rc)
			cifs_dbg(FYI, "error %d setting resiliency\n", rc);

		rc = 0;
	}

	if (buf) {
		/* open response does not have IndexNumber field - get it */
		rc = SMB2_get_srv_num(xid, oparms->tcon, fid->persistent_fid,
Loading