cifs_readv_callback and smb2_readv_callback are very similar and I would like to merge them ...

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi folks,

I want to simplify the read path as the first part of the changes I
would like to perform to introduce multi-channel support.

One impediment is that we have two functions, cifs_readv_callback and
smb2_readv_callback that are very similar. The following shows how
similar:

@@ -1,9 +1,11 @@
 static void
-cifs_readv_callback(struct mid_q_entry *mid)
+smb2_readv_callback(struct mid_q_entry *mid)
 {
 	struct cifs_readdata *rdata = mid->callback_data;
 	struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
 	struct TCP_Server_Info *server = tcon->ses->server;
+	struct smb2_hdr *buf = (struct smb2_hdr *)rdata->iov.iov_base;
+	unsigned int credits_received = 1;
 	struct smb_rqst rqst = { .rq_iov = &rdata->iov,
 				 .rq_nvec = 1,
 				 .rq_pages = rdata->pages,
@@ -16,13 +18,13 @@

 	switch (mid->mid_state) {
 	case MID_RESPONSE_RECEIVED:
+		credits_received = le16_to_cpu(buf->CreditRequest);
 		/* result already set, check signature */
 		if (server->sec_mode &
 		    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
-			int rc = 0;
+			int rc;

-			rc = cifs_verify_signature(&rqst, server,
-						  mid->sequence_number + 1);
+			rc = smb2_verify_signature(&rqst, server);
 			if (rc)
 				cERROR(1, "SMB signature verification returned "
 				       "error = %d", rc);
@@ -36,10 +38,14 @@
 		rdata->result = -EAGAIN;
 		break;
 	default:
-		rdata->result = -EIO;
+		if (rdata->result != -ENODATA)
+			rdata->result = -EIO;
 	}

+	if (rdata->result)
+		cifs_stats_fail_inc(tcon, SMB2_READ_HE);
+
 	queue_work(cifsiod_wq, &rdata->work);
 	DeleteMidQEntry(mid);
-	add_credits(server, 1, 0);
+	add_credits(server, credits_received, 0);
 }

So, we start off with a seemingly unused variable, struct smb2_hdr
*buf in smb2_readv_callback.

Then we have unsigned int credits_received in one and not the other.
We always assume a credit received of 1 in cifs_readv_callback. We
could unify these by:

1. declaring credits received in cifs_readv_callback and then
2. calling a protocol-specific credit-extraction routine, ie
server->ops->hdr_get_credits(buf) or something like that. The
CIFS/SMB1 hdr_get_credits function could simply return 1 every time.

Then we have different signature verification routines, but that is
caused by the fact that the signature algorithms are different, with
the message sequence number being passed in by client/server rather
than being in the header. However, this again can be handled by having
a protocol-specific signature algorithm (which we will likely need for
SMB3.0 anyway because it uses a different hashing algorithm) and
passing in the extra info regardless of whether it is needed. The
extra info we pass in could be the MID pointer.

We are almost done. There appears to be a little reorganization of the
code occurring there, and some stats collection in SMB2 that is not in
CIFS by the look of things, but we can fix that.

So, does anyone have any objections to me doing this?

-- 
Regards,
Richard Sharpe
(何以解憂?唯有杜康。--曹操)
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux