From patchwork Fri Aug 26 19:06:28 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 1102912 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p7QJ68Xn026515 for ; Fri, 26 Aug 2011 19:06:49 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753888Ab1HZTGt (ORCPT ); Fri, 26 Aug 2011 15:06:49 -0400 Received: from mail-gx0-f174.google.com ([209.85.161.174]:36715 "EHLO mail-gx0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753880Ab1HZTGs (ORCPT ); Fri, 26 Aug 2011 15:06:48 -0400 Received: by mail-gx0-f174.google.com with SMTP id 21so3097460gxk.19 for ; Fri, 26 Aug 2011 12:06:48 -0700 (PDT) Received: by 10.236.116.194 with SMTP id g42mr9463498yhh.0.1314385608309; Fri, 26 Aug 2011 12:06:48 -0700 (PDT) Received: from salusa.poochiereds.net (cpe-075-177-182-191.nc.res.rr.com [75.177.182.191]) by mx.google.com with ESMTPS id p63sm59852yhl.53.2011.08.26.12.06.47 (version=SSLv3 cipher=OTHER); Fri, 26 Aug 2011 12:06:47 -0700 (PDT) From: Jeff Layton To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org Subject: [PATCH 15/16] cifs: break out 3rd receive phase into separate function Date: Fri, 26 Aug 2011 15:06:28 -0400 Message-Id: <1314385589-27136-16-git-send-email-jlayton@redhat.com> X-Mailer: git-send-email 1.7.6 In-Reply-To: <1314385589-27136-1-git-send-email-jlayton@redhat.com> References: <1314385589-27136-1-git-send-email-jlayton@redhat.com> Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Fri, 26 Aug 2011 19:06:49 +0000 (UTC) Move the entire 3rd phase of the receive codepath into a separate function in preparation for the addition of a pluggable receive function. Signed-off-by: Jeff Layton --- fs/cifs/connect.c | 101 +++++++++++++++++++++++++++++++---------------------- 1 files changed, 59 insertions(+), 42 deletions(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 8a43619..dd4c3bae 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -706,6 +706,61 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) } static int +standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) +{ + int length; + char *buf = server->smallbuf; + struct smb_hdr *smb_buffer = (struct smb_hdr *)buf; + unsigned int pdu_length = be32_to_cpu(smb_buffer->smb_buf_length); + + /* make sure this will fit in a large buffer */ + if (pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { + cERROR(1, "SMB response too long (%u bytes)", + pdu_length); + cifs_reconnect(server); + wake_up(&server->response_q); + return -EAGAIN; + } + + /* switch to large buffer if too big for a small one */ + if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { + server->large_buf = true; + memcpy(server->bigbuf, server->smallbuf, server->total_read); + buf = server->bigbuf; + smb_buffer = (struct smb_hdr *)buf; + } + + /* now read the rest */ + length = read_from_socket(server, + buf + sizeof(struct smb_hdr) - 1, + pdu_length - sizeof(struct smb_hdr) + 1 + 4); + if (length < 0) + return length; + server->total_read += length; + + dump_smb(smb_buffer, server->total_read); + + /* + * We know that we received enough to get to the MID as we + * checked the pdu_length earlier. Now check to see + * if the rest of the header is OK. We borrow the length + * var for the rest of the loop to avoid a new stack var. + * + * 48 bytes is enough to display the header and a little bit + * into the payload for debugging purposes. + */ + length = checkSMB(smb_buffer, smb_buffer->Mid, server->total_read); + if (length != 0) + cifs_dump_mem("Bad SMB: ", buf, + min_t(unsigned int, server->total_read, 48)); + + if (mid) + handle_mid(mid, server, smb_buffer, length); + + return length; +} + +static int cifs_demultiplex_thread(void *p) { int length; @@ -770,57 +825,19 @@ cifs_demultiplex_thread(void *p) mid_entry = find_mid(server, smb_buffer); - if (pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { - cERROR(1, "SMB response too long (%u bytes)", - pdu_length); - cifs_reconnect(server); - wake_up(&server->response_q); + length = standard_receive3(server, mid_entry); + if (length < 0) continue; - } - /* else length ok */ - if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { - server->large_buf = true; - memcpy(server->bigbuf, server->smallbuf, - server->total_read); - smb_buffer = (struct smb_hdr *)server->bigbuf; + if (server->large_buf) { buf = server->bigbuf; + smb_buffer = (struct smb_hdr *)buf; } - /* now read the rest */ - length = read_from_socket(server, - buf + sizeof(struct smb_hdr) - 1, - pdu_length - sizeof(struct smb_hdr) + 1 + 4); - if (length < 0) - continue; - server->total_read += length; - - dump_smb(smb_buffer, server->total_read); - - /* - * We know that we received enough to get to the MID as we - * checked the pdu_length earlier. Now check to see - * if the rest of the header is OK. We borrow the length - * var for the rest of the loop to avoid a new stack var. - * - * 48 bytes is enough to display the header and a little bit - * into the payload for debugging purposes. - */ - length = checkSMB(smb_buffer, smb_buffer->Mid, - server->total_read); - if (length != 0) - cifs_dump_mem("Bad SMB: ", buf, - min_t(unsigned int, server->total_read, 48)); - server->lstrp = jiffies; - if (mid_entry != NULL) { - handle_mid(mid_entry, server, smb_buffer, length); if (!mid_entry->multiRsp || mid_entry->multiEnd) mid_entry->callback(mid_entry); - } else if (length != 0) { - /* response sanity checks failed */ - continue; } else if (!is_valid_oplock_break(smb_buffer, server)) { cERROR(1, "No task to wake, unknown frame received! " "NumMids %d", atomic_read(&midCount));