aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/smbdirect.c
diff options
context:
space:
mode:
authorLong Li <longli@microsoft.com>2018-05-30 15:48:01 -0400
committerSteve French <stfrench@microsoft.com>2018-06-05 18:43:27 -0400
commit6509f50cd1167d9540df24578401a2032f0782f8 (patch)
tree076977459781290b4bf0c2ad09f4e12319a9330e /fs/cifs/smbdirect.c
parentb6903bcf0acc9961fc0eedf0b3c1eadb9020758f (diff)
CIFS: SMBD: Support page offset in RDMA recv
RDMA recv function needs to place data to the correct place starting at page offset. Signed-off-by: Long Li <longli@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/smbdirect.c')
-rw-r--r--fs/cifs/smbdirect.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c
index 6141e3ce3442..ba53c5257bbc 100644
--- a/fs/cifs/smbdirect.c
+++ b/fs/cifs/smbdirect.c
@@ -2004,10 +2004,12 @@ read_rfc1002_done:
2004 * return value: actual data read 2004 * return value: actual data read
2005 */ 2005 */
2006static int smbd_recv_page(struct smbd_connection *info, 2006static int smbd_recv_page(struct smbd_connection *info,
2007 struct page *page, unsigned int to_read) 2007 struct page *page, unsigned int page_offset,
2008 unsigned int to_read)
2008{ 2009{
2009 int ret; 2010 int ret;
2010 char *to_address; 2011 char *to_address;
2012 void *page_address;
2011 2013
2012 /* make sure we have the page ready for read */ 2014 /* make sure we have the page ready for read */
2013 ret = wait_event_interruptible( 2015 ret = wait_event_interruptible(
@@ -2015,16 +2017,17 @@ static int smbd_recv_page(struct smbd_connection *info,
2015 info->reassembly_data_length >= to_read || 2017 info->reassembly_data_length >= to_read ||
2016 info->transport_status != SMBD_CONNECTED); 2018 info->transport_status != SMBD_CONNECTED);
2017 if (ret) 2019 if (ret)
2018 return 0; 2020 return ret;
2019 2021
2020 /* now we can read from reassembly queue and not sleep */ 2022 /* now we can read from reassembly queue and not sleep */
2021 to_address = kmap_atomic(page); 2023 page_address = kmap_atomic(page);
2024 to_address = (char *) page_address + page_offset;
2022 2025
2023 log_read(INFO, "reading from page=%p address=%p to_read=%d\n", 2026 log_read(INFO, "reading from page=%p address=%p to_read=%d\n",
2024 page, to_address, to_read); 2027 page, to_address, to_read);
2025 2028
2026 ret = smbd_recv_buf(info, to_address, to_read); 2029 ret = smbd_recv_buf(info, to_address, to_read);
2027 kunmap_atomic(to_address); 2030 kunmap_atomic(page_address);
2028 2031
2029 return ret; 2032 return ret;
2030} 2033}
@@ -2038,7 +2041,7 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
2038{ 2041{
2039 char *buf; 2042 char *buf;
2040 struct page *page; 2043 struct page *page;
2041 unsigned int to_read; 2044 unsigned int to_read, page_offset;
2042 int rc; 2045 int rc;
2043 2046
2044 info->smbd_recv_pending++; 2047 info->smbd_recv_pending++;
@@ -2052,15 +2055,16 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
2052 2055
2053 case READ | ITER_BVEC: 2056 case READ | ITER_BVEC:
2054 page = msg->msg_iter.bvec->bv_page; 2057 page = msg->msg_iter.bvec->bv_page;
2058 page_offset = msg->msg_iter.bvec->bv_offset;
2055 to_read = msg->msg_iter.bvec->bv_len; 2059 to_read = msg->msg_iter.bvec->bv_len;
2056 rc = smbd_recv_page(info, page, to_read); 2060 rc = smbd_recv_page(info, page, page_offset, to_read);
2057 break; 2061 break;
2058 2062
2059 default: 2063 default:
2060 /* It's a bug in upper layer to get there */ 2064 /* It's a bug in upper layer to get there */
2061 cifs_dbg(VFS, "CIFS: invalid msg type %d\n", 2065 cifs_dbg(VFS, "CIFS: invalid msg type %d\n",
2062 msg->msg_iter.type); 2066 msg->msg_iter.type);
2063 rc = -EIO; 2067 rc = -EINVAL;
2064 } 2068 }
2065 2069
2066 info->smbd_recv_pending--; 2070 info->smbd_recv_pending--;