From patchwork Fri May 18 00:22:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Li X-Patchwork-Id: 915881 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linuxonhyperv.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40n88f32rsz9s33 for ; Fri, 18 May 2018 10:25:38 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752162AbeERAXf (ORCPT ); Thu, 17 May 2018 20:23:35 -0400 Received: from a2nlsmtp01-04.prod.iad2.secureserver.net ([198.71.225.38]:34646 "EHLO a2nlsmtp01-04.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751543AbeERAXe (ORCPT ); Thu, 17 May 2018 20:23:34 -0400 Received: from linuxonhyperv2.linuxonhyperv.com ([107.180.71.197]) by : HOSTING RELAY : with SMTP id JTA6frHCCN7esJTA6fCI3u; Thu, 17 May 2018 17:22:32 -0700 x-originating-ip: 107.180.71.197 Received: from longli by linuxonhyperv2.linuxonhyperv.com with local (Exim 4.91) (envelope-from ) id 1fJTA5-0001U1-TE; Thu, 17 May 2018 17:22:21 -0700 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 Cc: Long Li Subject: [RFC PATCH 01/09] Introduce offset for the 1st page in data transfer structures Date: Thu, 17 May 2018 17:22:06 -0700 Message-Id: <20180518002214.5657-2-longli@linuxonhyperv.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180518002214.5657-1-longli@linuxonhyperv.com> References: <20180518002214.5657-1-longli@linuxonhyperv.com> Reply-To: longli@microsoft.com X-CMAE-Envelope: MS4wfO8fZXtynARGtWqOPkeDrS6NM0lo4gYGp6bIh04vsq+9TnF/coRlOwVtuK8MPwQ0xdA+cZk+RALOKCuIpAgMvL4FiC0SNelO988/2pG837ivj7i7C7Bf QSty9VeeiLIt9LaiAtNow57C9YqIXKbASqruaOmQpH90xCf76RwxhGLsGFlProkAgaOlDb8NkdiO72JHC2koH2nxim2FWkU/T8rXJmMaLchSXYXzw7bLbNd0 lBnZcc9giiG7m4uBFWuMOKzw4npL1TeSsITOhdeTCEmK9kARX7uC07thTHAsYY/puVK+5nvdOs3mPmTxr/P8leKUcKHaEkJXSZzBUvJEuszbdfRscRu20QqW csA4oYkuP5v7DSH6bctpPyAdyGqk8fTCoc/trd5JSiRsyf/TxW6Nrh6VwAdnpSXbwjY2OvmG Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Long Li Currently CIFS allocates its own pages for data transfer, they don't need offset since it's always 0 in the 1st page. Direct data transfer needs to define an offset because user-data may not start on the page boundary Signed-off-by: Long Li --- fs/cifs/cifsglob.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index cb950a5..a51855c 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -176,6 +176,7 @@ struct smb_rqst { struct kvec *rq_iov; /* array of kvecs */ unsigned int rq_nvec; /* number of kvecs in array */ struct page **rq_pages; /* pointer to array of page ptrs */ + unsigned int rq_offset; /* the offset to the 1st page */ unsigned int rq_npages; /* number pages in array */ unsigned int rq_pagesz; /* page size to use */ unsigned int rq_tailsz; /* length of last page */ @@ -1167,8 +1168,10 @@ struct cifs_readdata { struct kvec iov[2]; #ifdef CONFIG_CIFS_SMB_DIRECT struct smbd_mr *mr; + struct page **direct_pages; #endif unsigned int pagesz; + unsigned int page_offset; unsigned int tailsz; unsigned int credits; unsigned int nr_pages; @@ -1192,8 +1195,10 @@ struct cifs_writedata { int result; #ifdef CONFIG_CIFS_SMB_DIRECT struct smbd_mr *mr; + struct page **direct_pages; #endif unsigned int pagesz; + unsigned int page_offset; unsigned int tailsz; unsigned int credits; unsigned int nr_pages; From patchwork Fri May 18 00:22:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Li X-Patchwork-Id: 915880 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linuxonhyperv.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40n88d4rYLz9s2R for ; Fri, 18 May 2018 10:25:37 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752272AbeERAZX (ORCPT ); Thu, 17 May 2018 20:25:23 -0400 Received: from a2nlsmtp01-02.prod.iad2.secureserver.net ([198.71.225.36]:44438 "EHLO a2nlsmtp01-02.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752130AbeERAXf (ORCPT ); Thu, 17 May 2018 20:23:35 -0400 Received: from linuxonhyperv2.linuxonhyperv.com ([107.180.71.197]) by : HOSTING RELAY : with SMTP id JTA7faXjdPEk0JTA7fthMg; Thu, 17 May 2018 17:22:33 -0700 x-originating-ip: 107.180.71.197 Received: from longli by linuxonhyperv2.linuxonhyperv.com with local (Exim 4.91) (envelope-from ) id 1fJTA7-0001U7-A0; Thu, 17 May 2018 17:22:23 -0700 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 Cc: Long Li Subject: [RFC PATCH 02/09] Change wdata alloc to support direct pages Date: Thu, 17 May 2018 17:22:07 -0700 Message-Id: <20180518002214.5657-3-longli@linuxonhyperv.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180518002214.5657-1-longli@linuxonhyperv.com> References: <20180518002214.5657-1-longli@linuxonhyperv.com> Reply-To: longli@microsoft.com X-CMAE-Envelope: MS4wfAJKzYlkdgYzaSwYT6TRJGL48k3j+wc7soNtoGr2qc9xkjewgOlkiy/ip41ldKn9stJCuwl8NuGP36P9miblNO3sEXRcHdIpE9Jdr9kHplAv29scZQGH /2GDrigOoDKjeu7fJm3ncBPu9A8fPBpk9tB5c9yFfj8PV2ht63oqBDMp+EPN+hCtJp5Vi6pyuELa3PcK/pUlxwiIBqb8p+SshHHohVMwXmEO7hr+lPuZFEPw ydnhdH/Y4BydeAZtH670wb/kvSXttPdillg/Jrir0N14Ne+kK4vMQtFOYrWX2vCvvl/3PeKKVNPvtRf/N74MwecwFw+FExQ4WkC3d8cP/J4ir7doVBkA1IWP r34M7cPdJwTo2iLVGdO0q7S1+Ijg02ja6R4NspSj6Y9d9nJv9C/Vq686YafUtcKe1XQSJsSG Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Long Li When using direct pages from user space, there is no need to allocate pages. Just ping those user pages for RDMA. Signed-off-by: Long Li --- fs/cifs/cifsproto.h | 2 +- fs/cifs/cifssmb.c | 10 +++++++--- fs/cifs/file.c | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 365a414..94106b9 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -523,7 +523,7 @@ int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid); int cifs_async_writev(struct cifs_writedata *wdata, void (*release)(struct kref *kref)); void cifs_writev_complete(struct work_struct *work); -struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages, +struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages, struct page **direct_pages, work_func_t complete); void cifs_writedata_release(struct kref *refcount); int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 1529a08..3b1731d 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1983,7 +1983,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata) tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE; } - wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete); + wdata2 = cifs_writedata_alloc(nr_pages, NULL, cifs_writev_complete); if (!wdata2) { rc = -ENOMEM; break; @@ -2067,12 +2067,16 @@ cifs_writev_complete(struct work_struct *work) } struct cifs_writedata * -cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete) +cifs_writedata_alloc(unsigned int nr_pages, struct page **direct_pages, work_func_t complete) { struct cifs_writedata *wdata; /* writedata + number of page pointers */ - wdata = kzalloc(sizeof(*wdata) + + if (direct_pages) { + wdata = kzalloc(sizeof(*wdata), GFP_NOFS); + wdata->direct_pages = direct_pages; + } else + wdata = kzalloc(sizeof(*wdata) + sizeof(struct page *) * nr_pages, GFP_NOFS); if (wdata != NULL) { kref_init(&wdata->refcount); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 23fd430..a6ec896 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1965,7 +1965,7 @@ wdata_alloc_and_fillpages(pgoff_t tofind, struct address_space *mapping, { struct cifs_writedata *wdata; - wdata = cifs_writedata_alloc((unsigned int)tofind, + wdata = cifs_writedata_alloc((unsigned int)tofind, NULL, cifs_writev_complete); if (!wdata) return NULL; @@ -2554,7 +2554,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, break; nr_pages = get_numpages(wsize, len, &cur_len); - wdata = cifs_writedata_alloc(nr_pages, + wdata = cifs_writedata_alloc(nr_pages, NULL, cifs_uncached_writev_complete); if (!wdata) { rc = -ENOMEM; From patchwork Fri May 18 00:22:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Li X-Patchwork-Id: 915883 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linuxonhyperv.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40n8971glZz9s2R for ; Fri, 18 May 2018 10:26:03 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751671AbeERAXa (ORCPT ); Thu, 17 May 2018 20:23:30 -0400 Received: from a2nlsmtp01-03.prod.iad2.secureserver.net ([198.71.225.37]:54946 "EHLO a2nlsmtp01-03.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751293AbeERAX3 (ORCPT ); Thu, 17 May 2018 20:23:29 -0400 Received: from linuxonhyperv2.linuxonhyperv.com ([107.180.71.197]) by : HOSTING RELAY : with SMTP id JTA8fWofsdjTiJTA8fL3jO; Thu, 17 May 2018 17:22:28 -0700 x-originating-ip: 107.180.71.197 Received: from longli by linuxonhyperv2.linuxonhyperv.com with local (Exim 4.91) (envelope-from ) id 1fJTA8-0001UD-Iu; Thu, 17 May 2018 17:22:24 -0700 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 Cc: Long Li Subject: [RFC PATCH 03/09] Change rdata alloc to support direct pages Date: Thu, 17 May 2018 17:22:08 -0700 Message-Id: <20180518002214.5657-4-longli@linuxonhyperv.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180518002214.5657-1-longli@linuxonhyperv.com> References: <20180518002214.5657-1-longli@linuxonhyperv.com> Reply-To: longli@microsoft.com X-CMAE-Envelope: MS4wfMhDLIYs8xHYq1k5o6aNxPJ67R1WRQW8Aqzrfn5hrfS2W328cbAEIQ6m+s4HT8jLyZInRoSt6s9Rurs4DgW7X53wBjUVUryZYgNzE2bxniBHJvEh1Bpo xHaHQGFJJJ/rahwaBbSu5SEbGBOO3qzdaEq9mAJQpmrLMft0nyjf7PxUtjiHoCtLunYNfWEe1YvCmPpKygRlhf03fX9IuJiU0pzAMCSUL7aGWU9AYrJaQkJX 6i0AA+FceAgxUqZkwrg+C9LHKwy33uh49ZWIEBjyBXzi2iXjWWqw6EW010lftU5IWrtvMhovCXCzdTgDPztkE94tD1KOge4Q0nYPnVwClu+VF2T+R0CoaY9D SbtLG8XsR3cE995JEoP1eCJtXlf/IOrs31T0USTQO0XOakjlWNlSdPKf4GlCN/t3/y/d/PX8 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Long Li There is no need to allocate pages when using pages directly from user buffer Signed-off-by: Long Li --- fs/cifs/file.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index a6ec896..ed25e04 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2880,11 +2880,15 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from) } static struct cifs_readdata * -cifs_readdata_alloc(unsigned int nr_pages, work_func_t complete) +cifs_readdata_alloc(unsigned int nr_pages, struct page **direct_pages, work_func_t complete) { struct cifs_readdata *rdata; - rdata = kzalloc(sizeof(*rdata) + (sizeof(struct page *) * nr_pages), + if (direct_pages) { + rdata = kzalloc(sizeof(*rdata), GFP_KERNEL); + rdata->direct_pages = direct_pages; + } else + rdata = kzalloc(sizeof(*rdata) + (sizeof(struct page *) * nr_pages), GFP_KERNEL); if (rdata != NULL) { kref_init(&rdata->refcount); @@ -3095,14 +3099,13 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, npages = DIV_ROUND_UP(cur_len, PAGE_SIZE); /* allocate a readdata struct */ - rdata = cifs_readdata_alloc(npages, + rdata = cifs_readdata_alloc(npages, NULL, cifs_uncached_readv_complete); if (!rdata) { add_credits_and_wake_if(server, credits, 0); rc = -ENOMEM; break; } - rc = cifs_read_allocate_pages(rdata, npages); if (rc) goto error; @@ -3770,7 +3773,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, break; } - rdata = cifs_readdata_alloc(nr_pages, cifs_readv_complete); + rdata = cifs_readdata_alloc(nr_pages, NULL, cifs_readv_complete); if (!rdata) { /* best to give up if we're out of mem */ list_for_each_entry_safe(page, tpage, &tmplist, lru) { From patchwork Fri May 18 00:22:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Li X-Patchwork-Id: 915879 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linuxonhyperv.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40n88J0Czrz9s2R for ; Fri, 18 May 2018 10:25:20 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752398AbeERAYj (ORCPT ); Thu, 17 May 2018 20:24:39 -0400 Received: from a2nlsmtp01-02.prod.iad2.secureserver.net ([198.71.225.36]:44440 "EHLO a2nlsmtp01-02.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752141AbeERAXf (ORCPT ); Thu, 17 May 2018 20:23:35 -0400 Received: from linuxonhyperv2.linuxonhyperv.com ([107.180.71.197]) by : HOSTING RELAY : with SMTP id JTAAfaXkbPEk0JTAAfthNa; Thu, 17 May 2018 17:22:33 -0700 x-originating-ip: 107.180.71.197 Received: from longli by linuxonhyperv2.linuxonhyperv.com with local (Exim 4.91) (envelope-from ) id 1fJTAA-0001UJ-AO; Thu, 17 May 2018 17:22:26 -0700 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 Cc: Long Li Subject: [RFC PATCH 04/09] Change function to support offset when reading pages Date: Thu, 17 May 2018 17:22:09 -0700 Message-Id: <20180518002214.5657-5-longli@linuxonhyperv.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180518002214.5657-1-longli@linuxonhyperv.com> References: <20180518002214.5657-1-longli@linuxonhyperv.com> Reply-To: longli@microsoft.com X-CMAE-Envelope: MS4wfAJKzYlkdgYzaSwYT6TRJGL48k3j+wc7soNtoGr2qc9xkjewgOlkiy/ip41ldKn9stJCuwl8NuGP36P9miblNO3sEXRcHdIpE9Jdr9kHplAv29scZQGH /2GDrigOoDKjeu7fJm3ncBPu9A8fPBpk9tB5c9yFfj8PV2ht63oqBDMp+EPN+hCtJp5Vi6pyuELa3PcK/pUlxwiIBqb8p+SshHHohVMwXmEO7hr+lPuZFEPw ydnhdH/Y4BydeAZtH670wb/kvSXttPdillg/Jrir0N14Ne+kK4vMQtFOYrWX2vCvvl/3PeKKVNPvtRf/N74MwecwFw+FExQ4WkC3d8cP/J4ir7doVBkA1IWP r34M7cPdJwTo2iLVGdO0q7S1+Ijg02ja6R4NspSj6Y9d9nJv9C/Vq686YafUtcKe1XQSJsSG Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Long Li It's possible that we may want to read data into an offset to the 1st page, change the functions to pass the offset to transport. Signed-off-by: Long Li --- fs/cifs/cifsproto.h | 2 +- fs/cifs/connect.c | 4 ++-- fs/cifs/file.c | 4 ++-- fs/cifs/smb2ops.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 94106b9..cc034e2 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -197,7 +197,7 @@ extern void dequeue_mid(struct mid_q_entry *mid, bool malformed); extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, unsigned int to_read); extern int cifs_read_page_from_socket(struct TCP_Server_Info *server, - struct page *page, unsigned int to_read); + struct page *page, unsigned int page_offset, unsigned int to_read); extern int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, struct cifs_sb_info *cifs_sb); extern int cifs_match_super(struct super_block *, void *); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 58c2083..46d0cf4 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -591,11 +591,11 @@ cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, } int -cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page, +cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page, unsigned int page_offset, unsigned int to_read) { struct msghdr smb_msg; - struct bio_vec bv = {.bv_page = page, .bv_len = to_read}; + struct bio_vec bv = {.bv_page = page, .bv_len = to_read, .bv_offset = page_offset}; iov_iter_bvec(&smb_msg.msg_iter, READ | ITER_BVEC, &bv, 1, to_read); return cifs_readv_from_socket(server, &smb_msg); } diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ed25e04..e240c7c 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -3044,7 +3044,7 @@ uncached_fill_pages(struct TCP_Server_Info *server, result = n; #endif else - result = cifs_read_page_from_socket(server, page, n); + result = cifs_read_page_from_socket(server, page, page_offset, n); if (result < 0) break; @@ -3614,7 +3614,7 @@ readpages_fill_pages(struct TCP_Server_Info *server, result = n; #endif else - result = cifs_read_page_from_socket(server, page, n); + result = cifs_read_page_from_socket(server, page, 0, n); if (result < 0) break; diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index b76b858..f890dd7 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -2387,7 +2387,7 @@ read_data_into_pages(struct TCP_Server_Info *server, struct page **pages, zero_user(page, len, PAGE_SIZE - len); len = 0; } - length = cifs_read_page_from_socket(server, page, n); + length = cifs_read_page_from_socket(server, page, 0, n); if (length < 0) return length; server->total_read += length; From patchwork Fri May 18 00:22:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Li X-Patchwork-Id: 915877 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linuxonhyperv.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40n87T151dz9s2R for ; Fri, 18 May 2018 10:24:37 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752183AbeERAXg (ORCPT ); Thu, 17 May 2018 20:23:36 -0400 Received: from a2nlsmtp01-04.prod.iad2.secureserver.net ([198.71.225.38]:34644 "EHLO a2nlsmtp01-04.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751564AbeERAXe (ORCPT ); Thu, 17 May 2018 20:23:34 -0400 Received: from linuxonhyperv2.linuxonhyperv.com ([107.180.71.197]) by : HOSTING RELAY : with SMTP id JTABfrHEnN7esJTABfCI60; Thu, 17 May 2018 17:22:32 -0700 x-originating-ip: 107.180.71.197 Received: from longli by linuxonhyperv2.linuxonhyperv.com with local (Exim 4.91) (envelope-from ) id 1fJTAB-0001UP-Ky; Thu, 17 May 2018 17:22:27 -0700 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 Cc: Long Li Subject: [RFC PATCH 05/09] Change RDMA send to regonize page offset in the 1st page Date: Thu, 17 May 2018 17:22:10 -0700 Message-Id: <20180518002214.5657-6-longli@linuxonhyperv.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180518002214.5657-1-longli@linuxonhyperv.com> References: <20180518002214.5657-1-longli@linuxonhyperv.com> Reply-To: longli@microsoft.com X-CMAE-Envelope: MS4wfO8fZXtynARGtWqOPkeDrS6NM0lo4gYGp6bIh04vsq+9TnF/coRlOwVtuK8MPwQ0xdA+cZk+RALOKCuIpAgMvL4FiC0SNelO988/2pG837ivj7i7C7Bf QSty9VeeiLIt9LaiAtNow57C9YqIXKbASqruaOmQpH90xCf76RwxhGLsGFlProkAgaOlDb8NkdiO72JHC2koH2nxim2FWkU/T8rXJmMaLchSXYXzw7bLbNd0 lBnZcc9giiG7m4uBFWuMOKzw4npL1TeSsITOhdeTCEmK9kARX7uC07thTHAsYY/puVK+5nvdOs3mPmTxr/P8leKUcKHaEkJXSZzBUvJEuszbdfRscRu20QqW csA4oYkuP5v7DSH6bctpPyAdyGqk8fTCoc/trd5JSiRsyf/TxW6Nrh6VwAdnpSXbwjY2OvmG Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Long Li When doing RDMA send, the offset needs to be checked as data may start in an offset in the 1st page. Signed-off-by: Long Li --- fs/cifs/smb2pdu.c | 3 ++- fs/cifs/smbdirect.c | 25 +++++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 5097f28..fdcf97e 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -3015,7 +3015,8 @@ smb2_async_writev(struct cifs_writedata *wdata, rqst.rq_iov = iov; rqst.rq_nvec = 2; - rqst.rq_pages = wdata->pages; + rqst.rq_pages = wdata->direct_pages ? wdata->direct_pages : wdata->pages; + rqst.rq_offset = wdata->page_offset; rqst.rq_npages = wdata->nr_pages; rqst.rq_pagesz = wdata->pagesz; rqst.rq_tailsz = wdata->tailsz; diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index b0a1955..b46586d 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -2084,8 +2084,10 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst) /* add in the page array if there is one */ if (rqst->rq_npages) { - buflen += rqst->rq_pagesz * (rqst->rq_npages - 1); - buflen += rqst->rq_tailsz; + if (rqst->rq_npages == 1) + buflen += rqst->rq_tailsz; + else + buflen += rqst->rq_pagesz * (rqst->rq_npages - 1) - rqst->rq_offset + rqst->rq_tailsz; } if (buflen + sizeof(struct smbd_data_transfer) > @@ -2182,8 +2184,19 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst) /* now sending pages if there are any */ for (i = 0; i < rqst->rq_npages; i++) { - buflen = (i == rqst->rq_npages-1) ? - rqst->rq_tailsz : rqst->rq_pagesz; + unsigned int offset = 0; + if (i == 0) + offset = rqst->rq_offset; + if (rqst->rq_npages == 1 || i == rqst->rq_npages-1) + buflen = rqst->rq_tailsz; + else { + /* We have at least two pages, and this is not the last page */ + if (i == 0) + buflen = rqst->rq_pagesz - rqst->rq_offset; + else + buflen = rqst->rq_pagesz; + } + nvecs = (buflen + max_iov_size - 1) / max_iov_size; log_write(INFO, "sending pages buflen=%d nvecs=%d\n", buflen, nvecs); @@ -2194,9 +2207,9 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst) remaining_data_length -= size; log_write(INFO, "sending pages i=%d offset=%d size=%d" " remaining_data_length=%d\n", - i, j*max_iov_size, size, remaining_data_length); + i, j*max_iov_size+offset, size, remaining_data_length); rc = smbd_post_send_page( - info, rqst->rq_pages[i], j*max_iov_size, + info, rqst->rq_pages[i], j*max_iov_size + offset, size, remaining_data_length); if (rc) goto done; From patchwork Fri May 18 00:22:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Li X-Patchwork-Id: 915875 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linuxonhyperv.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40n86z1FrMz9s2R for ; Fri, 18 May 2018 10:24:11 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752318AbeERAX4 (ORCPT ); Thu, 17 May 2018 20:23:56 -0400 Received: from a2nlsmtp01-05.prod.iad2.secureserver.net ([198.71.225.49]:37588 "EHLO a2nlsmtp01-05.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752253AbeERAXk (ORCPT ); Thu, 17 May 2018 20:23:40 -0400 Received: from linuxonhyperv2.linuxonhyperv.com ([107.180.71.197]) by : HOSTING RELAY : with SMTP id JTADftqqcF1fmJTADfRzv8; Thu, 17 May 2018 17:22:39 -0700 x-originating-ip: 107.180.71.197 Received: from longli by linuxonhyperv2.linuxonhyperv.com with local (Exim 4.91) (envelope-from ) id 1fJTAC-0001UV-U0; Thu, 17 May 2018 17:22:28 -0700 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 Cc: Long Li Subject: [RFC PATCH 06/09] Change RDMA recv to support offset in the 1st page Date: Thu, 17 May 2018 17:22:11 -0700 Message-Id: <20180518002214.5657-7-longli@linuxonhyperv.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180518002214.5657-1-longli@linuxonhyperv.com> References: <20180518002214.5657-1-longli@linuxonhyperv.com> Reply-To: longli@microsoft.com X-CMAE-Envelope: MS4wfMG1OO6H4E/qPux5mE2gzkuJOyl8fG7HgUBzy8Ip4ecCaUYEjtuEMRbBMlsdfoeABkumMGRytaCBaxU1fgdsBA6xVjy0aI+gDOP62VEpqMwh5U2SywCM 17vvlP00zp68lM3aEt6o8FPXdNIW12MnTIfXp+VtTVSeqffj9gDUIiU2gLhsGRXUZh7u7wHvY0PvGZo+LGTxyy+KUpyfhEEW+Njh7S5cCGwdB1JMhGk+a8CI YrE29PIRfuX4FfPQdcgt9vQbW1yNHJw8VaG6VrKFPQ6s4e/SxZIfpwHMlNV0PJoPg/pCfHyJ2Pdqu6o9abh1ex42kNdzGEQ69Y3+Leo7601fMRmTdPOtmB/m fHqoMZ9FqJgi0q1dmbzTOFkZBdRx9NIkR5YrAGXZ20F+AV3iJFjmJorT4qFAzI69h3cEXy+m Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Long Li The actaul data buffer may start with an offset in the 1st page, modify RDMA recv function to read the data to the correct buffer. Signed-off-by: Long Li --- fs/cifs/smbdirect.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index b46586d..939c289 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -1978,7 +1978,7 @@ static int smbd_recv_buf(struct smbd_connection *info, char *buf, * return value: actual data read */ static int smbd_recv_page(struct smbd_connection *info, - struct page *page, unsigned int to_read) + struct page *page, unsigned int page_offset, unsigned int to_read) { int ret; char *to_address; @@ -1989,10 +1989,10 @@ static int smbd_recv_page(struct smbd_connection *info, info->reassembly_data_length >= to_read || info->transport_status != SMBD_CONNECTED); if (ret) - return 0; + return ret; /* now we can read from reassembly queue and not sleep */ - to_address = kmap_atomic(page); + to_address = (char *) kmap_atomic(page) + page_offset; log_read(INFO, "reading from page=%p address=%p to_read=%d\n", page, to_address, to_read); @@ -2012,7 +2012,7 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg) { char *buf; struct page *page; - unsigned int to_read; + unsigned int to_read, page_offset; int rc; switch (msg->msg_iter.type) { @@ -2024,15 +2024,16 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg) case READ | ITER_BVEC: page = msg->msg_iter.bvec->bv_page; + page_offset = msg->msg_iter.bvec->bv_offset; to_read = msg->msg_iter.bvec->bv_len; - rc = smbd_recv_page(info, page, to_read); + rc = smbd_recv_page(info, page, page_offset, to_read); break; default: /* It's a bug in upper layer to get there */ cifs_dbg(VFS, "CIFS: invalid msg type %d\n", msg->msg_iter.type); - rc = -EIO; + rc = -EINVAL; } /* SMBDirect will read it all or nothing */ From patchwork Fri May 18 00:22:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Li X-Patchwork-Id: 915876 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linuxonhyperv.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40n87N6xPpz9s33 for ; Fri, 18 May 2018 10:24:32 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752197AbeERAXg (ORCPT ); Thu, 17 May 2018 20:23:36 -0400 Received: from a2nlsmtp01-04.prod.iad2.secureserver.net ([198.71.225.38]:34674 "EHLO a2nlsmtp01-04.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752121AbeERAXf (ORCPT ); Thu, 17 May 2018 20:23:35 -0400 Received: from linuxonhyperv2.linuxonhyperv.com ([107.180.71.197]) by : HOSTING RELAY : with SMTP id JTAEfrHGNN7esJTAEfCI7F; Thu, 17 May 2018 17:22:32 -0700 x-originating-ip: 107.180.71.197 Received: from longli by linuxonhyperv2.linuxonhyperv.com with local (Exim 4.91) (envelope-from ) id 1fJTAE-0001Ub-7S; Thu, 17 May 2018 17:22:30 -0700 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 Cc: Long Li Subject: [RFC PATCH 07/09] Support page offset in memory regsitrations Date: Thu, 17 May 2018 17:22:12 -0700 Message-Id: <20180518002214.5657-8-longli@linuxonhyperv.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180518002214.5657-1-longli@linuxonhyperv.com> References: <20180518002214.5657-1-longli@linuxonhyperv.com> Reply-To: longli@microsoft.com X-CMAE-Envelope: MS4wfEhApYCCGHyCILD2EvvGQ8ryuS/zP8a5nYw7PcVOjY3aK0nlWnVrvOXxk9BN67bi0W9SwAjpDmEEL7PqQb+xsbYvIXkQsp8E26qJdH9RqA+Dhwdr9P8Q RfyKfXT8+3JreRtsrSC2Gk6ZukfOihxUOKdYCjf8HHc3darHNejgBtknb7vkL4/hDVkT3XW1oSxg6dQJGN4yY7kVXtZ79l2wiZhs8qaVyNqhv/3JP/9ZaF7E OFew7M7hvv9bufGOGldYM+gSxdb1PWQ8hHvfX4lKOAuMcB8T0WXmhU4FgmMcEXzlq6lyLiH9IIqPIzfQrWUx/NtTsD90td4aKyOtVzQ06CCds8t6Oi9Z06ng Nmaeny6J+YNnud9MpICPBOnAc0RK/UQxLnRKl1EJhZa9ryZXYJdePQGEsL8WsxBhv5kxFLwC Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Long Li Now momory registration needs to recognize offset in page when direct transfer is used. Signed-off-by: Long Li --- fs/cifs/smb2pdu.c | 19 +++++++++----- fs/cifs/smbdirect.c | 74 +++++++++++++++++++++++++++++++---------------------- fs/cifs/smbdirect.h | 2 +- 3 files changed, 57 insertions(+), 38 deletions(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index fdcf97e..a23c7cb 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2586,6 +2586,8 @@ smb2_new_read_req(void **buf, unsigned int *total_len, req->MinimumCount = 0; req->Length = cpu_to_le32(io_parms->length); req->Offset = cpu_to_le64(io_parms->offset); + if (!rdata->tailsz) + rdata->tailsz = rdata->pagesz; #ifdef CONFIG_CIFS_SMB_DIRECT /* * If we want to do a RDMA write, fill in and append @@ -2601,8 +2603,8 @@ smb2_new_read_req(void **buf, unsigned int *total_len, rcu_read_lock(); rcu_dereference(server->smbd_conn); rdata->mr = smbd_register_mr( - server->smbd_conn, rdata->pages, - rdata->nr_pages, rdata->tailsz, + server->smbd_conn, rdata->direct_pages ? rdata->direct_pages : rdata->pages, + rdata->nr_pages, rdata->page_offset, rdata->tailsz, true, need_invalidate); rcu_read_unlock(); if (!rdata->mr) @@ -2967,6 +2969,8 @@ smb2_async_writev(struct cifs_writedata *wdata, req->DataOffset = cpu_to_le16( offsetof(struct smb2_write_req, Buffer)); req->RemainingBytes = 0; + if (!wdata->tailsz) + wdata->tailsz = wdata->pagesz; #ifdef CONFIG_CIFS_SMB_DIRECT /* * If we want to do a server RDMA read, fill in and append @@ -2981,8 +2985,8 @@ smb2_async_writev(struct cifs_writedata *wdata, rcu_read_lock(); rcu_dereference(server->smbd_conn); wdata->mr = smbd_register_mr( - server->smbd_conn, wdata->pages, - wdata->nr_pages, wdata->tailsz, + server->smbd_conn, wdata->direct_pages ? wdata->direct_pages : wdata->pages, + wdata->nr_pages, wdata->page_offset, wdata->tailsz, false, need_invalidate); rcu_read_unlock(); if (!wdata->mr) { @@ -2991,8 +2995,11 @@ smb2_async_writev(struct cifs_writedata *wdata, } req->Length = 0; req->DataOffset = 0; - req->RemainingBytes = - cpu_to_le32((wdata->nr_pages-1)*PAGE_SIZE + wdata->tailsz); + if (wdata->nr_pages > 1) + req->RemainingBytes = + cpu_to_le32((wdata->nr_pages-1)*PAGE_SIZE - wdata->page_offset + wdata->tailsz); + else + req->RemainingBytes = cpu_to_le32(wdata->tailsz); req->Channel = SMB2_CHANNEL_RDMA_V1_INVALIDATE; if (need_invalidate) req->Channel = SMB2_CHANNEL_RDMA_V1; diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index 939c289..bce1e7a 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -2267,37 +2267,37 @@ static void smbd_mr_recovery_work(struct work_struct *work) if (smbdirect_mr->state == MR_INVALIDATED || smbdirect_mr->state == MR_ERROR) { - if (smbdirect_mr->state == MR_INVALIDATED) { + /* recover this MR entry */ + rc = ib_dereg_mr(smbdirect_mr->mr); + if (rc) { + log_rdma_mr(ERR, + "ib_dereg_mr failed rc=%x\n", + rc); + smbd_disconnect_rdma_connection(info); + continue; + } + + smbdirect_mr->mr = ib_alloc_mr( + info->pd, info->mr_type, + info->max_frmr_depth); + if (IS_ERR(smbdirect_mr->mr)) { + log_rdma_mr(ERR, + "ib_alloc_mr failed mr_type=%x " + "max_frmr_depth=%x\n", + info->mr_type, + info->max_frmr_depth); + smbd_disconnect_rdma_connection(info); + continue; + } + + if (smbdirect_mr->state == MR_INVALIDATED) ib_dma_unmap_sg( info->id->device, smbdirect_mr->sgl, smbdirect_mr->sgl_count, smbdirect_mr->dir); - smbdirect_mr->state = MR_READY; - } else if (smbdirect_mr->state == MR_ERROR) { - - /* recover this MR entry */ - rc = ib_dereg_mr(smbdirect_mr->mr); - if (rc) { - log_rdma_mr(ERR, - "ib_dereg_mr failed rc=%x\n", - rc); - smbd_disconnect_rdma_connection(info); - } - smbdirect_mr->mr = ib_alloc_mr( - info->pd, info->mr_type, - info->max_frmr_depth); - if (IS_ERR(smbdirect_mr->mr)) { - log_rdma_mr(ERR, - "ib_alloc_mr failed mr_type=%x " - "max_frmr_depth=%x\n", - info->mr_type, - info->max_frmr_depth); - smbd_disconnect_rdma_connection(info); - } + smbdirect_mr->state = MR_READY; - smbdirect_mr->state = MR_READY; - } /* smbdirect_mr->state is updated by this function * and is read and updated by I/O issuing CPUs trying * to get a MR, the call to atomic_inc_return @@ -2443,7 +2443,7 @@ static struct smbd_mr *get_mr(struct smbd_connection *info) */ struct smbd_mr *smbd_register_mr( struct smbd_connection *info, struct page *pages[], int num_pages, - int tailsz, bool writing, bool need_invalidate) + int offset, int tailsz, bool writing, bool need_invalidate) { struct smbd_mr *smbdirect_mr; int rc, i; @@ -2466,17 +2466,29 @@ struct smbd_mr *smbd_register_mr( smbdirect_mr->sgl_count = num_pages; sg_init_table(smbdirect_mr->sgl, num_pages); - for (i = 0; i < num_pages - 1; i++) - sg_set_page(&smbdirect_mr->sgl[i], pages[i], PAGE_SIZE, 0); + log_rdma_mr(INFO, "num_pages=0x%x offset=0x%x tailsz=0x%x\n", num_pages, offset, tailsz); + if (num_pages==1) { + sg_set_page(&smbdirect_mr->sgl[0], pages[0], tailsz, offset); + goto next; + } + + /* We have at least two pages to register */ + sg_set_page(&smbdirect_mr->sgl[0], pages[0], PAGE_SIZE - offset, offset); + i = 1; + while (i < num_pages - 1) { + sg_set_page(&smbdirect_mr->sgl[i], pages[i], PAGE_SIZE, 0); + i++; + } sg_set_page(&smbdirect_mr->sgl[i], pages[i], tailsz ? tailsz : PAGE_SIZE, 0); +next: dir = writing ? DMA_FROM_DEVICE : DMA_TO_DEVICE; smbdirect_mr->dir = dir; rc = ib_dma_map_sg(info->id->device, smbdirect_mr->sgl, num_pages, dir); if (!rc) { - log_rdma_mr(INFO, "ib_dma_map_sg num_pages=%x dir=%x rc=%x\n", + log_rdma_mr(ERR, "ib_dma_map_sg num_pages=%x dir=%x rc=%x\n", num_pages, dir, rc); goto dma_map_error; } @@ -2484,8 +2496,8 @@ struct smbd_mr *smbd_register_mr( rc = ib_map_mr_sg(smbdirect_mr->mr, smbdirect_mr->sgl, num_pages, NULL, PAGE_SIZE); if (rc != num_pages) { - log_rdma_mr(INFO, - "ib_map_mr_sg failed rc = %x num_pages = %x\n", + log_rdma_mr(ERR, + "ib_map_mr_sg failed rc = %d num_pages = %x\n", rc, num_pages); goto map_mr_error; } diff --git a/fs/cifs/smbdirect.h b/fs/cifs/smbdirect.h index f568577..bb1e0c4 100644 --- a/fs/cifs/smbdirect.h +++ b/fs/cifs/smbdirect.h @@ -314,7 +314,7 @@ struct smbd_mr { /* Interfaces to register and deregister MR for RDMA read/write */ struct smbd_mr *smbd_register_mr( struct smbd_connection *info, struct page *pages[], int num_pages, - int tailsz, bool writing, bool need_invalidate); + int offset, int tailsz, bool writing, bool need_invalidate); int smbd_deregister_mr(struct smbd_mr *mr); #else From patchwork Fri May 18 00:22:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Li X-Patchwork-Id: 915874 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linuxonhyperv.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40n86h1ZkZz9s2R for ; Fri, 18 May 2018 10:23:56 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752257AbeERAXl (ORCPT ); Thu, 17 May 2018 20:23:41 -0400 Received: from a2nlsmtp01-03.prod.iad2.secureserver.net ([198.71.225.37]:54946 "EHLO a2nlsmtp01-03.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752226AbeERAXj (ORCPT ); Thu, 17 May 2018 20:23:39 -0400 Received: from linuxonhyperv2.linuxonhyperv.com ([107.180.71.197]) by : HOSTING RELAY : with SMTP id JTAFfWojWdjTiJTAFfL3mW; Thu, 17 May 2018 17:22:38 -0700 x-originating-ip: 107.180.71.197 Received: from longli by linuxonhyperv2.linuxonhyperv.com with local (Exim 4.91) (envelope-from ) id 1fJTAF-0001Uh-Qg; Thu, 17 May 2018 17:22:31 -0700 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 Cc: Long Li Subject: [RFC PATCH 08/09] Implement direct file I/O interfaces Date: Thu, 17 May 2018 17:22:13 -0700 Message-Id: <20180518002214.5657-9-longli@linuxonhyperv.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180518002214.5657-1-longli@linuxonhyperv.com> References: <20180518002214.5657-1-longli@linuxonhyperv.com> Reply-To: longli@microsoft.com X-CMAE-Envelope: MS4wfBxCAIRxUwdH6x2AHI4AmiQ38PYurMBrCIuM9AzIkP9Z2+JQclZYMprCuNVmR3F4xnZnZu75Zm9R9iVZOuJ5EET+xeqH/F0vYysM/5A3lb1GLhYLfrxZ DQaRvztCG78X8ZSYTimI4gWDNwdCt+0MOCChb/ZRjfNUh4PfNMfXYxevuzNadmF8tqM1T5xFrTyXoMM+MGAYDXYdvIlDAPP+TadEGtvoSQGZOjQmVpbbTdFh 1Xp8sdPU6gM8ZKnA6OQdrBSkGpIDcl2V2wR+Z6X9ZS1Y0CLtaB4f1BHegIP69f1gcFSpnkqIFSVGiXBDosKTrdo3samFBZndJzHHl8vpdfbCV/83qmvpkws5 AUCuqxG0QM3QFXm9WLY8dwOTYuFXAj9VsZ70vjH48ct5X7IU0y6IKzlTNFIVQaDn4GbrsyFP Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Long Li Implement the main filesystem interface for doing read and write. These functions don't copy the user data into a kenrel buffer for data transfer. Pages are directly pinned and passed to the RDMA transport. Signed-off-by: Long Li --- fs/cifs/cifsfs.c | 19 ++++ fs/cifs/cifsfs.h | 3 + fs/cifs/file.c | 322 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 329 insertions(+), 15 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index f715609..ba19fed 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -1118,6 +1118,25 @@ const struct file_operations cifs_file_direct_ops = { .fallocate = cifs_fallocate, }; +const struct file_operations cifs_file_direct_rdma_ops = { + .read_iter = cifs_direct_readv, + .write_iter = cifs_direct_writev, + .open = cifs_open, + .release = cifs_close, + .lock = cifs_lock, + .fsync = cifs_fsync, + .flush = cifs_flush, + .mmap = cifs_file_mmap, + .splice_read = generic_file_splice_read, + .splice_write = iter_file_splice_write, + .unlocked_ioctl = cifs_ioctl, + .copy_file_range = cifs_copy_file_range, + .clone_file_range = cifs_clone_file_range, + .llseek = cifs_llseek, + .setlease = cifs_setlease, + .fallocate = cifs_fallocate, +}; + const struct file_operations cifs_file_nobrl_ops = { .read_iter = cifs_loose_read_iter, .write_iter = cifs_file_write_iter, diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 013ba2a..223cca8 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -94,6 +94,7 @@ extern const struct inode_operations cifs_dfs_referral_inode_operations; /* Functions related to files and directories */ extern const struct file_operations cifs_file_ops; extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */ +extern const struct file_operations cifs_file_direct_rdma_ops; /* if directio mnt */ extern const struct file_operations cifs_file_strict_ops; /* if strictio mnt */ extern const struct file_operations cifs_file_nobrl_ops; /* no brlocks */ extern const struct file_operations cifs_file_direct_nobrl_ops; @@ -102,8 +103,10 @@ extern int cifs_open(struct inode *inode, struct file *file); extern int cifs_close(struct inode *inode, struct file *file); extern int cifs_closedir(struct inode *inode, struct file *file); extern ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to); +extern ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to); extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to); extern ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from); +extern ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from); extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from); extern int cifs_lock(struct file *, int, struct file_lock *); extern int cifs_fsync(struct file *, loff_t, loff_t, int); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index e240c7c..0b394db 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2452,15 +2452,46 @@ cifs_uncached_writedata_release(struct kref *refcount) int i; struct cifs_writedata *wdata = container_of(refcount, struct cifs_writedata, refcount); + struct page **pages = wdata->direct_pages ? wdata->direct_pages : wdata->pages; kref_put(&wdata->ctx->refcount, cifs_aio_ctx_release); for (i = 0; i < wdata->nr_pages; i++) - put_page(wdata->pages[i]); + put_page(pages[i]); cifs_writedata_release(refcount); } static void collect_uncached_write_data(struct cifs_aio_ctx *ctx); +static void cifs_direct_writedata_release(struct kref *refcount) +{ + int i; + struct cifs_writedata *wdata = container_of(refcount, + struct cifs_writedata, refcount); + + for (i = 0; i < wdata->nr_pages; i++) + put_page(wdata->direct_pages[i]); + kvfree(wdata->direct_pages); + + cifs_writedata_release(refcount); +} + +static void cifs_direct_writev_complete(struct work_struct *work) +{ + struct cifs_writedata *wdata = container_of(work, + struct cifs_writedata, work); + struct inode *inode = d_inode(wdata->cfile->dentry); + struct cifsInodeInfo *cifsi = CIFS_I(inode); + + spin_lock(&inode->i_lock); + cifs_update_eof(cifsi, wdata->offset, wdata->bytes); + if (cifsi->server_eof > inode->i_size) + i_size_write(inode, cifsi->server_eof); + spin_unlock(&inode->i_lock); + + complete(&wdata->done); + kref_put(&wdata->refcount, cifs_direct_writedata_release); +} + static void cifs_uncached_writev_complete(struct work_struct *work) { @@ -2703,6 +2734,125 @@ static void collect_uncached_write_data(struct cifs_aio_ctx *ctx) complete(&ctx->done); } +ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from) +{ + struct file *file = iocb->ki_filp; + ssize_t total_written = 0; + struct cifsFileInfo *cfile; + struct cifs_tcon *tcon; + struct cifs_sb_info *cifs_sb; + struct TCP_Server_Info *server; + pid_t pid; + unsigned long nr_pages; + loff_t offset = iocb->ki_pos; + size_t len = iov_iter_count(from); + int rc; + struct cifs_writedata *wdata; + + rc = generic_write_checks(iocb, from); + if (rc <= 0) + return rc; + + cifs_sb = CIFS_FILE_SB(file); + cfile = file->private_data; + tcon = tlink_tcon(cfile->tlink); + server = tcon->ses->server; + + if (!server->ops->async_writev) + return -ENOSYS; + + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) + pid = cfile->pid; + else + pid = current->tgid; + + do { + unsigned int wsize, credits; + struct page **pagevec; + size_t start; + ssize_t cur_len; + + rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize, + &wsize, &credits); + if (rc) + break; + + cur_len = iov_iter_get_pages_alloc(from, &pagevec, wsize, &start); + if (cur_len < 0) { + cifs_dbg(VFS, "direct_writev couldn't get user pages (rc=%zd) iter type %d iov_offset %lu count %lu\n", cur_len, from->type, from->iov_offset, from->count); + dump_stack(); + break; + } + if (cur_len < 0) + break; + + nr_pages = (cur_len + start + PAGE_SIZE -1) / PAGE_SIZE; + + wdata = cifs_writedata_alloc(nr_pages, pagevec, + cifs_direct_writev_complete); + if (!wdata) { + rc = -ENOMEM; + add_credits_and_wake_if(server, credits, 0); + break; + } + + wdata->nr_pages = nr_pages; + wdata->page_offset = start; + wdata->pagesz = PAGE_SIZE; + wdata->tailsz = + nr_pages > 1 ? + cur_len - (PAGE_SIZE-start) - (nr_pages - 2)*PAGE_SIZE : + cur_len; + + wdata->sync_mode = WB_SYNC_ALL; + wdata->offset = (__u64)offset; + wdata->cfile = cifsFileInfo_get(cfile); + wdata->pid = pid; + wdata->bytes = cur_len; + wdata->credits = credits; + + kref_get(&wdata->refcount); + + if (!wdata->cfile->invalidHandle || + !(rc = cifs_reopen_file(wdata->cfile, false))) + rc = server->ops->async_writev(wdata, + cifs_direct_writedata_release); + if (rc) { + add_credits_and_wake_if(server, wdata->credits, 0); + kref_put(&wdata->refcount, + cifs_writedata_release); + if (rc == -EAGAIN) + continue; + break; + } else + wait_for_completion(&wdata->done); + + if (wdata->result) { + rc = wdata->result; + kref_put(&wdata->refcount, cifs_direct_writedata_release); + if (rc == -EAGAIN) + continue; + break; + } + + kref_put(&wdata->refcount, cifs_direct_writedata_release); + + iov_iter_advance(from, cur_len); + total_written += cur_len; + offset += cur_len; + len -= cur_len; + } while (len); + + if (unlikely(!total_written)) { + printk(KERN_ERR "%s: total_written=%ld rc=%d\n", __func__, total_written, rc); + return rc; + } + + iocb->ki_pos += total_written; + return total_written; + +} + ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; @@ -2942,18 +3092,30 @@ cifs_read_allocate_pages(struct cifs_readdata *rdata, unsigned int nr_pages) return rc; } +static void cifs_direct_readdata_release(struct kref *refcount) +{ + struct cifs_readdata *rdata = container_of(refcount, + struct cifs_readdata, refcount); + unsigned int i; + for (i = 0; i < rdata->nr_pages; i++) { + put_page(rdata->direct_pages[i]); + } + kvfree(rdata->direct_pages); + + cifs_readdata_release(refcount); +} + static void cifs_uncached_readdata_release(struct kref *refcount) { struct cifs_readdata *rdata = container_of(refcount, struct cifs_readdata, refcount); unsigned int i; + struct page **pages = rdata->direct_pages ? rdata->direct_pages : rdata->pages; kref_put(&rdata->ctx->refcount, cifs_aio_ctx_release); - for (i = 0; i < rdata->nr_pages; i++) { - put_page(rdata->pages[i]); - rdata->pages[i] = NULL; - } + for (i = 0; i < rdata->nr_pages; i++) + put_page(pages[i]); cifs_readdata_release(refcount); } @@ -3013,30 +3175,32 @@ uncached_fill_pages(struct TCP_Server_Info *server, int result = 0; unsigned int i; unsigned int nr_pages = rdata->nr_pages; + unsigned int page_offset = rdata->page_offset; rdata->got_bytes = 0; rdata->tailsz = PAGE_SIZE; for (i = 0; i < nr_pages; i++) { - struct page *page = rdata->pages[i]; + struct page *page = rdata->direct_pages ? rdata->direct_pages[i] : rdata->pages[i]; size_t n; + unsigned int segment_size = rdata->pagesz; + + if (i == 0) + segment_size -= page_offset; + else + page_offset = 0; + if (len <= 0) { /* no need to hold page hostage */ - rdata->pages[i] = NULL; rdata->nr_pages--; put_page(page); continue; } n = len; - if (len >= PAGE_SIZE) { + if (len >= segment_size) /* enough data to fill the page */ - n = PAGE_SIZE; - len -= n; - } else { - zero_user(page, len, PAGE_SIZE - len); - rdata->tailsz = len; - len = 0; - } + n = segment_size; + len -= n; if (iter) result = copy_page_from_iter(page, 0, n, iter); #ifdef CONFIG_CIFS_SMB_DIRECT @@ -3243,6 +3407,134 @@ collect_uncached_read_data(struct cifs_aio_ctx *ctx) complete(&ctx->done); } +static void cifs_direct_readv_complete(struct work_struct *work) +{ + struct cifs_readdata *rdata = container_of(work, struct cifs_readdata, work); + int i = 0; + unsigned int bytes = 0; + + // Set them dirty? + while (bytes < rdata->got_bytes + rdata->page_offset) { + set_page_dirty(rdata->direct_pages[i++]); + bytes += rdata->pagesz; + } + + complete(&rdata->done); + kref_put(&rdata->refcount, cifs_direct_readdata_release); +} + +ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to) +{ + size_t len, cur_len, start; + unsigned int npages, rsize, credits; + struct file *file; + struct cifs_sb_info *cifs_sb; + struct cifsFileInfo *cfile; + struct cifs_tcon *tcon; + struct page **pagevec; + ssize_t rc, total_read = 0; + struct TCP_Server_Info *server; + loff_t offset = iocb->ki_pos; + pid_t pid; + struct cifs_readdata *rdata; + char *buf = to->iov->iov_base; + + len = iov_iter_count(to); + if (!len) + return 0; + + file = iocb->ki_filp; + cifs_sb = CIFS_FILE_SB(file); + cfile = file->private_data; + tcon = tlink_tcon(cfile->tlink); + server = tcon->ses->server; + + if (!server->ops->async_readv) + return -ENOSYS; + + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) + pid = cfile->pid; + else + pid = current->tgid; + + if ((file->f_flags & O_ACCMODE) == O_WRONLY) + cifs_dbg(FYI, "attempting read on write only file instance\n"); + + do { + rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize, + &rsize, &credits); + if (rc) + break; + + cur_len = min_t(const size_t, len, rsize); + + rc = iov_iter_get_pages_alloc(to, &pagevec, cur_len, &start); + if (rc < 0) { + cifs_dbg(VFS, "couldn't get user pages (rc=%zd) iter type %d iov_offset %lu count %lu\n", rc, to->type, to->iov_offset, to->count); + dump_stack(); + break; + } + + rdata = cifs_readdata_alloc(0, pagevec, cifs_direct_readv_complete); + if (!rdata) { + add_credits_and_wake_if(server, credits, 0); + rc = -ENOMEM; + break; + } + + npages = (rc + start + PAGE_SIZE-1) / PAGE_SIZE; + rdata->nr_pages = npages; + rdata->page_offset = start; + rdata->pagesz = PAGE_SIZE; + rdata->tailsz = npages > 1 ? + rc-(PAGE_SIZE-start)-(npages-2)*PAGE_SIZE : + rc; + cur_len = rc; + + rdata->cfile = cfile; + rdata->offset = offset; + rdata->bytes = rc; + rdata->pid = pid; + rdata->read_into_pages = cifs_uncached_read_into_pages; + rdata->copy_into_pages = cifs_uncached_copy_into_pages; + rdata->credits = credits; + + kref_get(&rdata->refcount); + + if (!rdata->cfile->invalidHandle || + !(rc = cifs_reopen_file(rdata->cfile, true))) + rc = server->ops->async_readv(rdata); + + if (rc) { + add_credits_and_wake_if(server, rdata->credits, 0); + kref_put(&rdata->refcount, + cifs_direct_readdata_release); + if (rc == -EAGAIN) + continue; + } else + wait_for_completion(&rdata->done); + + rc = rdata->result; + if (rc) { + kref_put(&rdata->refcount, cifs_direct_readdata_release); + if (rc == -EAGAIN) + continue; + break; + } + + total_read += rdata->got_bytes; + kref_put(&rdata->refcount, cifs_direct_readdata_release); + + iov_iter_advance(to, cur_len); + len -= cur_len; + offset += cur_len; + } while (len); + + iocb->ki_pos += total_read; + + return total_read; +} + ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to) { struct file *file = iocb->ki_filp; From patchwork Fri May 18 00:22:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Li X-Patchwork-Id: 915878 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linuxonhyperv.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40n8835Pqbz9s2R for ; Fri, 18 May 2018 10:25:07 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752420AbeERAYk (ORCPT ); Thu, 17 May 2018 20:24:40 -0400 Received: from a2nlsmtp01-04.prod.iad2.secureserver.net ([198.71.225.38]:34668 "EHLO a2nlsmtp01-04.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752128AbeERAXf (ORCPT ); Thu, 17 May 2018 20:23:35 -0400 Received: from linuxonhyperv2.linuxonhyperv.com ([107.180.71.197]) by : HOSTING RELAY : with SMTP id JTAHfrHHtN7esJTAHfCI8a; Thu, 17 May 2018 17:22:33 -0700 x-originating-ip: 107.180.71.197 Received: from longli by linuxonhyperv2.linuxonhyperv.com with local (Exim 4.91) (envelope-from ) id 1fJTAH-0001Un-0M; Thu, 17 May 2018 17:22:33 -0700 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 Cc: Long Li Subject: [RFC PATCH 09/09] Introduce cache=rdma moutning option Date: Thu, 17 May 2018 17:22:14 -0700 Message-Id: <20180518002214.5657-10-longli@linuxonhyperv.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180518002214.5657-1-longli@linuxonhyperv.com> References: <20180518002214.5657-1-longli@linuxonhyperv.com> Reply-To: longli@microsoft.com X-CMAE-Envelope: MS4wfEhApYCCGHyCILD2EvvGQ8ryuS/zP8a5nYw7PcVOjY3aK0nlWnVrvOXxk9BN67bi0W9SwAjpDmEEL7PqQb+xsbYvIXkQsp8E26qJdH9RqA+Dhwdr9P8Q RfyKfXT8+3JreRtsrSC2Gk6ZukfOihxUOKdYCjf8HHc3darHNejgBtknb7vkL4/hDVkT3XW1oSxg6dQJGN4yY7kVXtZ79l2wiZhs8qaVyNqhv/3JP/9ZaF7E OFew7M7hvv9bufGOGldYM+gSxdb1PWQ8hHvfX4lKOAuMcB8T0WXmhU4FgmMcEXzlq6lyLiH9IIqPIzfQrWUx/NtTsD90td4aKyOtVzQ06CCds8t6Oi9Z06ng Nmaeny6J+YNnud9MpICPBOnAc0RK/UQxLnRKl1EJhZa9ryZXYJdePQGEsL8WsxBhv5kxFLwC Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Long Li When cache=rdma is enabled on mount options, CIFS do not allocate internal data buffer pages for I/O, data is read/writen directly to user memory via RDMA. Signed-off-by: Long Li --- fs/cifs/cifs_fs_sb.h | 2 ++ fs/cifs/cifsglob.h | 1 + fs/cifs/connect.c | 9 +++++++++ fs/cifs/dir.c | 5 +++++ fs/cifs/file.c | 4 ++++ fs/cifs/inode.c | 4 +++- 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 350fa55..7c28dc3 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -51,6 +51,8 @@ */ #define CIFS_MOUNT_UID_FROM_ACL 0x2000000 /* try to get UID via special SID */ +#define CIFS_MOUNT_DIRECT_RDMA 0x4000000 + struct cifs_sb_info { struct rb_root tlink_tree; spinlock_t tlink_tree_lock; diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index a51855c..3bec63f 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -518,6 +518,7 @@ struct smb_vol { bool server_ino:1; /* use inode numbers from server ie UniqueId */ bool direct_io:1; bool strict_io:1; /* strict cache behavior */ + bool rdma_io:1; bool remap:1; /* set to remap seven reserved chars in filenames */ bool sfu_remap:1; /* remap seven reserved chars ala SFU */ bool posix_paths:1; /* unset to not ask for posix pathnames. */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 46d0cf4..c92b3d8 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -282,6 +282,7 @@ enum { Opt_cache_loose, Opt_cache_strict, Opt_cache_none, + Opt_cache_rdma, Opt_cache_err }; @@ -289,6 +290,7 @@ static const match_table_t cifs_cacheflavor_tokens = { { Opt_cache_loose, "loose" }, { Opt_cache_strict, "strict" }, { Opt_cache_none, "none" }, + { Opt_cache_rdma, "rdma" }, { Opt_cache_err, NULL } }; @@ -1128,6 +1130,9 @@ cifs_parse_cache_flavor(char *value, struct smb_vol *vol) vol->direct_io = true; vol->strict_io = false; break; + case Opt_cache_rdma: + vol->rdma_io = true; + break; default: cifs_dbg(VFS, "bad cache= option: %s\n", value); return 1; @@ -3612,6 +3617,10 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, cifs_dbg(FYI, "mounting share using direct i/o\n"); cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; } + if (pvolume_info->rdma_io) { + cifs_dbg(VFS, "mounting share using rdma i/o\n"); + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_RDMA; + } if (pvolume_info->mfsymlinks) { if (pvolume_info->sfu_emul) { /* diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 81ba6e0..ce69b1c 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -557,6 +557,11 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, file->f_op = &cifs_file_direct_ops; } + if (file->f_flags & O_DIRECT && + CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_DIRECT_RDMA) + file->f_op = &cifs_file_direct_rdma_ops; + + file_info = cifs_new_fileinfo(&fid, file, tlink, oplock); if (file_info == NULL) { if (server->ops->close) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 0b394db..30ccf6a 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -492,6 +492,10 @@ int cifs_open(struct inode *inode, struct file *file) file->f_op = &cifs_file_direct_ops; } + if (file->f_flags & O_DIRECT && + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_RDMA) + file->f_op = &cifs_file_direct_rdma_ops; + if (server->oplocks) oplock = REQ_OPLOCK; else diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 3c371f7..7991298 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -44,7 +44,9 @@ static void cifs_set_ops(struct inode *inode) switch (inode->i_mode & S_IFMT) { case S_IFREG: inode->i_op = &cifs_file_inode_ops; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_RDMA) + inode->i_fop = &cifs_file_direct_rdma_ops; + else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) inode->i_fop = &cifs_file_direct_nobrl_ops; else