cifs: smbd: Invalidate and deregister memory registration on re-send for direct I/O
authorLong Li <longli@microsoft.com>
Tue, 15 Oct 2019 22:54:50 +0000 (22:54 +0000)
committerSteve French <stfrench@microsoft.com>
Mon, 25 Nov 2019 07:14:14 +0000 (01:14 -0600)
On re-send, there might be a reconnect and all prevoius memory registrations
need to be invalidated and deregistered.

Signed-off-by: Long Li <longli@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/file.c

index a80ec68..67e7d0f 100644 (file)
@@ -2803,9 +2803,17 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
                if (!rc) {
                        if (wdata->cfile->invalidHandle)
                                rc = -EAGAIN;
-                       else
+                       else {
+#ifdef CONFIG_CIFS_SMB_DIRECT
+                               if (wdata->mr) {
+                                       wdata->mr->need_invalidate = true;
+                                       smbd_deregister_mr(wdata->mr);
+                                       wdata->mr = NULL;
+                               }
+#endif
                                rc = server->ops->async_writev(wdata,
                                        cifs_uncached_writedata_release);
+                       }
                }
 
                /* If the write was successfully sent, we are done */
@@ -3528,8 +3536,16 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
                if (!rc) {
                        if (rdata->cfile->invalidHandle)
                                rc = -EAGAIN;
-                       else
+                       else {
+#ifdef CONFIG_CIFS_SMB_DIRECT
+                               if (rdata->mr) {
+                                       rdata->mr->need_invalidate = true;
+                                       smbd_deregister_mr(rdata->mr);
+                                       rdata->mr = NULL;
+                               }
+#endif
                                rc = server->ops->async_readv(rdata);
+                       }
                }
 
                /* If the read was successfully sent, we are done */