Commit 053d5034 authored by Jeff Layton's avatar Jeff Layton Committed by Steve French
Browse files

cifs: move mid result processing into common function

parent ddc8cf8f
Loading
Loading
Loading
Loading
+43 −78
Original line number Diff line number Diff line
@@ -389,6 +389,42 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
	return rc;
}

static int
sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
{
	int rc = 0;

	spin_lock(&GlobalMid_Lock);

	if (mid->resp_buf) {
		spin_unlock(&GlobalMid_Lock);
		return rc;
	}

	cERROR(1, "No response to cmd %d mid %d", mid->command, mid->mid);
	if (mid->midState == MID_REQUEST_SUBMITTED) {
		if (server->tcpStatus == CifsExiting)
			rc = -EHOSTDOWN;
		else {
			server->tcpStatus = CifsNeedReconnect;
			mid->midState = MID_RETRY_NEEDED;
		}
	}

	if (rc != -EHOSTDOWN) {
		if (mid->midState == MID_RETRY_NEEDED) {
			rc = -EAGAIN;
			cFYI(1, "marking request for retry");
		} else {
			rc = -EIO;
		}
	}
	spin_unlock(&GlobalMid_Lock);

	delete_mid(mid);
	return rc;
}

int
SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
	     struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
@@ -492,37 +528,13 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
	/* No user interrupts in wait - wreaks havoc with performance */
	wait_for_response(ses, midQ, timeout, 10 * HZ);

	spin_lock(&GlobalMid_Lock);

	if (midQ->resp_buf == NULL) {
		cERROR(1, "No response to cmd %d mid %d",
			midQ->command, midQ->mid);
		if (midQ->midState == MID_REQUEST_SUBMITTED) {
			if (ses->server->tcpStatus == CifsExiting)
				rc = -EHOSTDOWN;
			else {
				ses->server->tcpStatus = CifsNeedReconnect;
				midQ->midState = MID_RETRY_NEEDED;
			}
		}

		if (rc != -EHOSTDOWN) {
			if (midQ->midState == MID_RETRY_NEEDED) {
				rc = -EAGAIN;
				cFYI(1, "marking request for retry");
			} else {
				rc = -EIO;
			}
		}
		spin_unlock(&GlobalMid_Lock);
		delete_mid(midQ);
		/* Update # of requests on wire to server */
	rc = sync_mid_result(midQ, ses->server);
	if (rc != 0) {
		atomic_dec(&ses->server->inFlight);
		wake_up(&ses->server->request_q);
		return rc;
	}

	spin_unlock(&GlobalMid_Lock);
	receive_len = midQ->resp_buf->smb_buf_length;

	if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
@@ -684,36 +696,13 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
	/* No user interrupts in wait - wreaks havoc with performance */
	wait_for_response(ses, midQ, timeout, 10 * HZ);

	spin_lock(&GlobalMid_Lock);
	if (midQ->resp_buf == NULL) {
		cERROR(1, "No response for cmd %d mid %d",
			  midQ->command, midQ->mid);
		if (midQ->midState == MID_REQUEST_SUBMITTED) {
			if (ses->server->tcpStatus == CifsExiting)
				rc = -EHOSTDOWN;
			else {
				ses->server->tcpStatus = CifsNeedReconnect;
				midQ->midState = MID_RETRY_NEEDED;
			}
		}

		if (rc != -EHOSTDOWN) {
			if (midQ->midState == MID_RETRY_NEEDED) {
				rc = -EAGAIN;
				cFYI(1, "marking request for retry");
			} else {
				rc = -EIO;
			}
		}
		spin_unlock(&GlobalMid_Lock);
		delete_mid(midQ);
		/* Update # of requests on wire to server */
	rc = sync_mid_result(midQ, ses->server);
	if (rc != 0) {
		atomic_dec(&ses->server->inFlight);
		wake_up(&ses->server->request_q);
		return rc;
	}

	spin_unlock(&GlobalMid_Lock);
	receive_len = midQ->resp_buf->smb_buf_length;

	if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
@@ -933,35 +922,11 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
		}
	}

	spin_lock(&GlobalMid_Lock);
	if (midQ->resp_buf) {
		spin_unlock(&GlobalMid_Lock);
		receive_len = midQ->resp_buf->smb_buf_length;
	} else {
		cERROR(1, "No response for cmd %d mid %d",
			  midQ->command, midQ->mid);
		if (midQ->midState == MID_REQUEST_SUBMITTED) {
			if (ses->server->tcpStatus == CifsExiting)
				rc = -EHOSTDOWN;
			else {
				ses->server->tcpStatus = CifsNeedReconnect;
				midQ->midState = MID_RETRY_NEEDED;
			}
		}

		if (rc != -EHOSTDOWN) {
			if (midQ->midState == MID_RETRY_NEEDED) {
				rc = -EAGAIN;
				cFYI(1, "marking request for retry");
			} else {
				rc = -EIO;
			}
		}
		spin_unlock(&GlobalMid_Lock);
		delete_mid(midQ);
	rc = sync_mid_result(midQ, ses->server);
	if (rc != 0)
		return rc;
	}

	receive_len = midQ->resp_buf->smb_buf_length;
	if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
		cERROR(1, "Frame too large received.  Length: %d  Xid: %d",
			receive_len, xid);