Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751842AbdH2Ta4 (ORCPT ); Tue, 29 Aug 2017 15:30:56 -0400 Received: from a2nlsmtp01-05.prod.iad2.secureserver.net ([198.71.225.49]:40436 "EHLO a2nlsmtp01-05.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751814AbdH2Tax (ORCPT ); Tue, 29 Aug 2017 15:30:53 -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 v3 16/19] CIFS: SMBD: Read correct returned data length for RDMA write (SMB read) I/O Date: Tue, 29 Aug 2017 12:29:12 -0700 Message-Id: <20170829192915.26251-17-longli@exchange.microsoft.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170829192915.26251-1-longli@exchange.microsoft.com> References: <20170829192915.26251-1-longli@exchange.microsoft.com> X-CMAE-Envelope: MS4wfC0vn7Zspo+XUiWttTauGgaPtvSaXO4YxivOc3rquZgUrjcoymDo+DynB/x9kR31L4EnHBj8zU6ziIwtE/61zOMeh5PPHGRajkDHmJWjDBYF4O9HpHr2 SXPCsjOdsm65nLEepZavMlBBjEt7a39s+0Bgi23c8XgTtQHqMRaGxMgkbtObJUZAo+LMoXI8BWOdr2C9lGa4K/5/5XOypzS3cJGNkkh6ePPwusmtzsismCXD m4U0gRtC+f7CusVtcFRlEKT2I9OKzH+gDrUW+zzYMaMX4aIq2VBDsn2aOkKlW6ZS2+LPaTxSu1cietXNQe4LisYzL60obz1JruxMPuSvaam/HpUWYY7ZruM0 R6kJW1KmuauS0vzr4EUvKs7ISCAIl6OPmygrFO2dU+opqhzeINq/jw7r16977kEJvIuBWId4k02ycN8+Ocav73fcSMqLuG2G4Td+NWSyrqL5aRroInaGWgX7 tIF2ucHwp/mixxq+ Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3205 Lines: 93 From: Long Li When RDMA write is used for SMB read, the returned data length is 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 6e1de21..ff2848b 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1524,8 +1524,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