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

Commit 38104c00 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '5.1-rc1-cifs-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull smb3 fixes from Steve French:

 - two fixes for stable for guest mount problems with smb3.1.1

 - two fixes for crediting (SMB3 flow control) on resent requests

 - a byte range lock leak fix

 - two fixes for incorrect rc mappings

* tag '5.1-rc1-cifs-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: update internal module version number
  SMB3: Fix SMB3.1.1 guest mounts to Samba
  cifs: Fix slab-out-of-bounds when tracing SMB tcon
  cifs: allow guest mounts to work for smb3.11
  fix incorrect error code mapping for OBJECTID_NOT_FOUND
  cifs: fix that return -EINVAL when do dedupe operation
  CIFS: Fix an issue with re-sending rdata when transport returning -EAGAIN
  CIFS: Fix an issue with re-sending wdata when transport returning -EAGAIN
parents e0046bb3 cf7d624f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1008,7 +1008,7 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
	unsigned int xid;
	int rc;

	if (remap_flags & ~REMAP_FILE_ADVISORY)
	if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
		return -EINVAL;

	cifs_dbg(FYI, "clone range\n");
+1 −1
Original line number Diff line number Diff line
@@ -150,5 +150,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
extern const struct export_operations cifs_export_ops;
#endif /* CONFIG_CIFS_NFSD_EXPORT */

#define CIFS_VERSION   "2.18"
#define CIFS_VERSION   "2.19"
#endif				/* _CIFSFS_H */
+86 −62
Original line number Diff line number Diff line
@@ -2632,43 +2632,56 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
	struct TCP_Server_Info *server =
		tlink_tcon(wdata->cfile->tlink)->ses->server;

	do {
		if (wdata->cfile->invalidHandle) {
			rc = cifs_reopen_file(wdata->cfile, false);
			if (rc == -EAGAIN)
				continue;
			else if (rc)
				break;
		}


		/*
		 * Wait for credits to resend this wdata.
	 * Note: we are attempting to resend the whole wdata not in segments
		 * Note: we are attempting to resend the whole wdata not in
		 * segments
		 */
		do {
		rc = server->ops->wait_mtu_credits(server, wdata->bytes, &wsize,
						   &credits);

			rc = server->ops->wait_mtu_credits(server, wdata->bytes,
						&wsize, &credits);
			if (rc)
			goto out;
				goto fail;

			if (wsize < wdata->bytes) {
				add_credits_and_wake_if(server, &credits, 0);
				msleep(1000);
			}
		} while (wsize < wdata->bytes);

		wdata->credits = credits;
	rc = -EAGAIN;
	while (rc == -EAGAIN) {
		rc = 0;

		rc = adjust_credits(server, &wdata->credits, wdata->bytes);

		if (!rc) {
			if (wdata->cfile->invalidHandle)
			rc = cifs_reopen_file(wdata->cfile, false);
		if (!rc)
				rc = -EAGAIN;
			else
				rc = server->ops->async_writev(wdata,
					cifs_uncached_writedata_release);
		}

		/* If the write was successfully sent, we are done */
		if (!rc) {
			list_add_tail(&wdata->list, wdata_list);
			return 0;
		}

		/* Roll back credits and retry if needed */
		add_credits_and_wake_if(server, &wdata->credits, 0);
out:
	kref_put(&wdata->refcount, cifs_uncached_writedata_release);
	} while (rc == -EAGAIN);

fail:
	kref_put(&wdata->refcount, cifs_uncached_writedata_release);
	return rc;
}

@@ -2896,12 +2909,12 @@ static void collect_uncached_write_data(struct cifs_aio_ctx *ctx)
						wdata->bytes, &tmp_from,
						ctx->cfile, cifs_sb, &tmp_list,
						ctx);
				}

				list_splice(&tmp_list, &ctx->list);

					kref_put(&wdata->refcount,
						cifs_uncached_writedata_release);
				}

				list_splice(&tmp_list, &ctx->list);
				goto restart_loop;
			}
		}
@@ -3348,44 +3361,55 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
	struct TCP_Server_Info *server =
		tlink_tcon(rdata->cfile->tlink)->ses->server;

	do {
		if (rdata->cfile->invalidHandle) {
			rc = cifs_reopen_file(rdata->cfile, true);
			if (rc == -EAGAIN)
				continue;
			else if (rc)
				break;
		}

		/*
		 * Wait for credits to resend this rdata.
	 * Note: we are attempting to resend the whole rdata not in segments
		 * Note: we are attempting to resend the whole rdata not in
		 * segments
		 */
		do {
			rc = server->ops->wait_mtu_credits(server, rdata->bytes,
						&rsize, &credits);

			if (rc)
			goto out;
				goto fail;

			if (rsize < rdata->bytes) {
				add_credits_and_wake_if(server, &credits, 0);
				msleep(1000);
			}
		} while (rsize < rdata->bytes);

		rdata->credits = credits;
	rc = -EAGAIN;
	while (rc == -EAGAIN) {
		rc = 0;

		rc = adjust_credits(server, &rdata->credits, rdata->bytes);
		if (!rc) {
			if (rdata->cfile->invalidHandle)
			rc = cifs_reopen_file(rdata->cfile, true);
		if (!rc)
				rc = -EAGAIN;
			else
				rc = server->ops->async_readv(rdata);
		}

		/* If the read was successfully sent, we are done */
		if (!rc) {
			/* Add to aio pending list */
			list_add_tail(&rdata->list, rdata_list);
			return 0;
		}

		/* Roll back credits and retry if needed */
		add_credits_and_wake_if(server, &rdata->credits, 0);
out:
	kref_put(&rdata->refcount,
		cifs_uncached_readdata_release);
	} while (rc == -EAGAIN);

fail:
	kref_put(&rdata->refcount, cifs_uncached_readdata_release);
	return rc;
}

+2 −1
Original line number Diff line number Diff line
@@ -1036,7 +1036,8 @@ static const struct status_to_posix_error smb2_error_map_table[] = {
	{STATUS_UNFINISHED_CONTEXT_DELETED, -EIO,
	"STATUS_UNFINISHED_CONTEXT_DELETED"},
	{STATUS_NO_TGT_REPLY, -EIO, "STATUS_NO_TGT_REPLY"},
	{STATUS_OBJECTID_NOT_FOUND, -EIO, "STATUS_OBJECTID_NOT_FOUND"},
	/* Note that ENOATTTR and ENODATA are the same errno */
	{STATUS_OBJECTID_NOT_FOUND, -ENODATA, "STATUS_OBJECTID_NOT_FOUND"},
	{STATUS_NO_IP_ADDRESSES, -EIO, "STATUS_NO_IP_ADDRESSES"},
	{STATUS_WRONG_CREDENTIAL_HANDLE, -EIO,
	"STATUS_WRONG_CREDENTIAL_HANDLE"},
+9 −2
Original line number Diff line number Diff line
@@ -1628,9 +1628,16 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
	iov[1].iov_base = unc_path;
	iov[1].iov_len = unc_path_len;

	/* 3.11 tcon req must be signed if not encrypted. See MS-SMB2 3.2.4.1.1 */
	/*
	 * 3.11 tcon req must be signed if not encrypted. See MS-SMB2 3.2.4.1.1
	 * unless it is guest or anonymous user. See MS-SMB2 3.2.5.3.1
	 * (Samba servers don't always set the flag so also check if null user)
	 */
	if ((ses->server->dialect == SMB311_PROT_ID) &&
	    !smb3_encryption_required(tcon))
	    !smb3_encryption_required(tcon) &&
	    !(ses->session_flags &
		    (SMB2_SESSION_FLAG_IS_GUEST|SMB2_SESSION_FLAG_IS_NULL)) &&
	    ((ses->user_name != NULL) || (ses->sectype == Kerberos)))
		req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;

	memset(&rqst, 0, sizeof(struct smb_rqst));
Loading