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

Commit 7c2614bf authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull smb3 fixes from Steve French:
 "A set of small smb3 fixes, some fixing various crediting issues
  discovered during xfstest runs, five for stable"

* tag '5.0-rc3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: print CIFSMaxBufSize as part of /proc/fs/cifs/DebugData
  smb3: add credits we receive from oplock/break PDUs
  CIFS: Fix mounts if the client is low on credits
  CIFS: Do not assume one credit for async responses
  CIFS: Fix credit calculations in compound mid callback
  CIFS: Fix credit calculation for encrypted reads with errors
  CIFS: Fix credits calculations for reads with errors
  CIFS: Do not reconnect TCP session in add_credits()
  smb3: Cleanup license mess
  CIFS: Fix possible hang during async MTU reads and writes
  cifs: fix memory leak of an allocated cifs_ntsd structure
parents 2580acb2 a5f1a81f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -252,6 +252,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
	seq_printf(m, ",ACL");
#endif
	seq_putc(m, '\n');
	seq_printf(m, "CIFSMaxBufSize: %d\n", CIFSMaxBufSize);
	seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
	seq_printf(m, "Servers:");

+23 −12
Original line number Diff line number Diff line
@@ -1549,18 +1549,26 @@ cifs_discard_remaining_data(struct TCP_Server_Info *server)
}

static int
cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
__cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
		     bool malformed)
{
	int length;
	struct cifs_readdata *rdata = mid->callback_data;

	length = cifs_discard_remaining_data(server);
	dequeue_mid(mid, rdata->result);
	dequeue_mid(mid, malformed);
	mid->resp_buf = server->smallbuf;
	server->smallbuf = NULL;
	return length;
}

static int
cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
{
	struct cifs_readdata *rdata = mid->callback_data;

	return  __cifs_readv_discard(server, mid, rdata->result);
}

int
cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
{
@@ -1602,12 +1610,23 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
		return -1;
	}

	/* set up first two iov for signature check and to get credits */
	rdata->iov[0].iov_base = buf;
	rdata->iov[0].iov_len = 4;
	rdata->iov[1].iov_base = buf + 4;
	rdata->iov[1].iov_len = server->total_read - 4;
	cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
		 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
	cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
		 rdata->iov[1].iov_base, rdata->iov[1].iov_len);

	/* Was the SMB read successful? */
	rdata->result = server->ops->map_error(buf, false);
	if (rdata->result != 0) {
		cifs_dbg(FYI, "%s: server returned error %d\n",
			 __func__, rdata->result);
		return cifs_readv_discard(server, mid);
		/* normal error on read response */
		return __cifs_readv_discard(server, mid, false);
	}

	/* Is there enough to get to the rest of the READ_RSP header? */
@@ -1651,14 +1670,6 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
		server->total_read += length;
	}

	/* set up first iov for signature check */
	rdata->iov[0].iov_base = buf;
	rdata->iov[0].iov_len = 4;
	rdata->iov[1].iov_base = buf + 4;
	rdata->iov[1].iov_len = server->total_read - 4;
	cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n",
		 rdata->iov[0].iov_base, server->total_read);

	/* how much data is in the response? */
#ifdef CONFIG_CIFS_SMB_DIRECT
	use_rdma_mr = rdata->mr;
+21 −0
Original line number Diff line number Diff line
@@ -720,6 +720,21 @@ server_unresponsive(struct TCP_Server_Info *server)
	return false;
}

static inline bool
zero_credits(struct TCP_Server_Info *server)
{
	int val;

	spin_lock(&server->req_lock);
	val = server->credits + server->echo_credits + server->oplock_credits;
	if (server->in_flight == 0 && val == 0) {
		spin_unlock(&server->req_lock);
		return true;
	}
	spin_unlock(&server->req_lock);
	return false;
}

static int
cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
{
@@ -732,6 +747,12 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
	for (total_read = 0; msg_data_left(smb_msg); total_read += length) {
		try_to_freeze();

		/* reconnect if no credits and no requests in flight */
		if (zero_credits(server)) {
			cifs_reconnect(server);
			return -ECONNABORTED;
		}

		if (server_unresponsive(server))
			return -ECONNABORTED;
		if (cifs_rdma_enabled(server) && server->smbd_conn)
+17 −0
Original line number Diff line number Diff line
@@ -293,6 +293,8 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
	int rc;
	struct smb2_file_all_info *smb2_data;
	__u32 create_options = 0;
	struct cifs_fid fid;
	bool no_cached_open = tcon->nohandlecache;

	*adjust_tz = false;
	*symlink = false;
@@ -301,6 +303,21 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
			    GFP_KERNEL);
	if (smb2_data == NULL)
		return -ENOMEM;

	/* If it is a root and its handle is cached then use it */
	if (!strlen(full_path) && !no_cached_open) {
		rc = open_shroot(xid, tcon, &fid);
		if (rc)
			goto out;
		rc = SMB2_query_info(xid, tcon, fid.persistent_fid,
				     fid.volatile_fid, smb2_data);
		close_shroot(&tcon->crfid);
		if (rc)
			goto out;
		move_smb2_info_to_cifs(data, smb2_data);
		goto out;
	}

	if (backup_cred(cifs_sb))
		create_options |= CREATE_OPEN_BACKUP_INTENT;

+7 −0
Original line number Diff line number Diff line
@@ -648,6 +648,13 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
	if (rsp->sync_hdr.Command != SMB2_OPLOCK_BREAK)
		return false;

	if (rsp->sync_hdr.CreditRequest) {
		spin_lock(&server->req_lock);
		server->credits += le16_to_cpu(rsp->sync_hdr.CreditRequest);
		spin_unlock(&server->req_lock);
		wake_up(&server->request_q);
	}

	if (rsp->StructureSize !=
				smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) {
		if (le16_to_cpu(rsp->StructureSize) == 44)
Loading