cifs: smbd: Don't use RDMA read/write when signing is used
authorLong Li <longli@microsoft.com>
Tue, 17 Apr 2018 19:17:08 +0000 (12:17 -0700)
committerSteve French <stfrench@microsoft.com>
Wed, 25 Apr 2018 16:15:53 +0000 (11:15 -0500)
SMB server will not sign data transferred through RDMA read/write. When
signing is used, it's a good idea to have all the data signed.

In this case, use RDMA send/recv for all data transfers. This will degrade
performance as this is not generally configured in RDMA environemnt. So
warn the user on signing and RDMA send/recv.

Signed-off-by: Long Li <longli@microsoft.com>
Acked-by: Ronnie Sahlberg <lsahlber@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Steve French <smfrench@gmail.com>
fs/cifs/cifssmb.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c

index 6d3e40d7029c47c6abd7264e8a8aa0cf526f4ee5..1529a088383d048554cfd129de7b8898aa12f6e1 100644 (file)
@@ -455,6 +455,9 @@ cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
                server->sign = true;
        }
 
+       if (cifs_rdma_enabled(server) && server->sign)
+               cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled");
+
        return 0;
 }
 
index 38ebf3f357d29233571c2319fb45940f1cc1f5fe..b76b85881dcc668e87f99ee55b6bb4463f25510e 100644 (file)
@@ -252,9 +252,14 @@ smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
        wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE;
        wsize = min_t(unsigned int, wsize, server->max_write);
 #ifdef CONFIG_CIFS_SMB_DIRECT
-       if (server->rdma)
-               wsize = min_t(unsigned int,
+       if (server->rdma) {
+               if (server->sign)
+                       wsize = min_t(unsigned int,
+                               wsize, server->smbd_conn->max_fragmented_send_size);
+               else
+                       wsize = min_t(unsigned int,
                                wsize, server->smbd_conn->max_readwrite_size);
+       }
 #endif
        if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
                wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE);
@@ -272,9 +277,14 @@ smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
        rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE;
        rsize = min_t(unsigned int, rsize, server->max_read);
 #ifdef CONFIG_CIFS_SMB_DIRECT
-       if (server->rdma)
-               rsize = min_t(unsigned int,
+       if (server->rdma) {
+               if (server->sign)
+                       rsize = min_t(unsigned int,
+                               rsize, server->smbd_conn->max_fragmented_recv_size);
+               else
+                       rsize = min_t(unsigned int,
                                rsize, server->smbd_conn->max_readwrite_size);
+       }
 #endif
 
        if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
index 9aea138dd71fb1d57d89e5f9cd744f3460bf6f51..60db51bae0e3a88cec2147cf9d7e709bebb0c7fd 100644 (file)
@@ -2591,7 +2591,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
         * If we want to do a RDMA write, fill in and append
         * smbd_buffer_descriptor_v1 to the end of read request
         */
-       if (server->rdma && rdata &&
+       if (server->rdma && rdata && !server->sign &&
                rdata->bytes >= server->smbd_conn->rdma_readwrite_threshold) {
 
                struct smbd_buffer_descriptor_v1 *v1;
@@ -2969,7 +2969,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
         * If we want to do a server RDMA read, fill in and append
         * smbd_buffer_descriptor_v1 to the end of write request
         */
-       if (server->rdma && wdata->bytes >=
+       if (server->rdma && !server->sign && wdata->bytes >=
                server->smbd_conn->rdma_readwrite_threshold) {
 
                struct smbd_buffer_descriptor_v1 *v1;