Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753717AbdHTTG5 (ORCPT ); Sun, 20 Aug 2017 15:06:57 -0400 Received: from a2nlsmtp01-05.prod.iad2.secureserver.net ([198.71.225.49]:34228 "EHLO a2nlsmtp01-05.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753653AbdHTTGy (ORCPT ); Sun, 20 Aug 2017 15:06:54 -0400 x-originating-ip: 107.180.71.197 From: Long Li To: Steve French , linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org, Christoph Hellwig , Tom Talpey , Matthew Wilcox Cc: Long Li Subject: [Patch v2 16/19] CIFS: SMBD: Read correct returned data length for RDMA write (SMB READ) I/O Date: Sun, 20 Aug 2017 12:04:40 -0700 Message-Id: <1503255883-3041-17-git-send-email-longli@exchange.microsoft.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1503255883-3041-1-git-send-email-longli@exchange.microsoft.com> References: <1503255883-3041-1-git-send-email-longli@exchange.microsoft.com> X-CMAE-Envelope: MS4wfFIMreJ9lmsvgmDeEPT9MN+hywR3dWodQze7PaBVsZS1rKqyh2nG/vzJxRF/zEQIAh7Hk67gQ0jn6PScTPsz4XkUE2QdDMg6Gkg2dltxKJY6zunVRE1Q r0OjVtFQLhfPKdqm34cHTRBMsIppe+4/aHsl3pZIEKoa3FWi699BsFT9a19mHIJTOdOUSBxZu4BRvOpY/bSPu9nPK9jVBqUtbvJejaPqhBijj7reXtWORMOw hfPWHA1GdF070eag7FCZ740a7e8LPpnVngdC96Pj7NrV+q10T54T7/SRraxkX2hTstjmFuv8bkRI2HEGYXzk5Zra89Fll76EhdV8LfeEzctRMyKmAjaHu4pu H/gXvZUoGdhyaV29BNPk/ZpPxhitmATwuC8iNNZs4J5bHAFcnTHf0C99n6JwBeZKy/I/20mqf0vbhtQck1+g5ciKdc3KyufEwdV7ZsB6GMMIgL76FyQPngul YEcdRhLo4/HnXo4h Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3214 Lines: 91 From: Long Li When RDMA write is used for SMB READ, the returned data length is returned in DataRemaining in the response packet. Reading it properly by adding a parameter to specifiy where the returned data length is. Signed-off-by: Long Li --- fs/cifs/cifsglob.h | 10 ++++++++-- fs/cifs/cifssmb.c | 4 ++-- fs/cifs/smb1ops.c | 2 +- fs/cifs/smb2ops.c | 8 ++++++-- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index dcd2b63..d391767 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -231,8 +231,14 @@ struct smb_version_operations { __u64 (*get_next_mid)(struct TCP_Server_Info *); /* data offset from read response message */ unsigned int (*read_data_offset)(char *); - /* data length from read response message */ - unsigned int (*read_data_length)(char *); + /* + * Data length from read response message + * When in_remaining is true, the returned data length is in + * message field DataRemaining for out-of-band data read (e.g through + * Memory Registration RDMA write in SMBD). + * Otherwise, the returned data length is in message field DataLength. + */ + unsigned int (*read_data_length)(char *, bool in_remaining); /* map smb to linux error */ int (*map_error)(char *, bool); /* find mid corresponding to the response message */ diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index fbb0d4c..9030fb5 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1523,8 +1523,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) rdata->iov[0].iov_base, server->total_read); /* how much data is in the response? */ - data_len = server->ops->read_data_length(buf); - if (data_offset + data_len > buflen) { + data_len = server->ops->read_data_length(buf, rdata->mr); + if (!rdata->mr && (data_offset + data_len > buflen)) { /* data_len is corrupt -- discard frame */ rdata->result = -EIO; return cifs_readv_discard(server, mid); diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index a723df3..27a8280 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -87,7 +87,7 @@ cifs_read_data_offset(char *buf) } static unsigned int -cifs_read_data_length(char *buf) +cifs_read_data_length(char *buf, bool in_remaining) { READ_RSP *rsp = (READ_RSP *)buf; return (le16_to_cpu(rsp->DataLengthHigh) << 16) + diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index e67f5f0..4067629 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -747,9 +747,13 @@ smb2_read_data_offset(char *buf) } static unsigned int -smb2_read_data_length(char *buf) +smb2_read_data_length(char *buf, bool in_remaining) { struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf; + + if (in_remaining) + return le32_to_cpu(rsp->DataRemaining); + return le32_to_cpu(rsp->DataLength); } @@ -2181,7 +2185,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, } data_offset = server->ops->read_data_offset(buf) + 4; - data_len = server->ops->read_data_length(buf); + data_len = server->ops->read_data_length(buf, rdata->mr); if (data_offset < server->vals->read_rsp_size) { /* -- 2.7.4