[Devel] [PATCH VZ9 11/20] fuse: implement acceleration for synchronous writes

Alexey Kuznetsov kuznet at virtuozzo.com
Fri Oct 6 13:43:23 MSK 2023


Signed-off-by: Alexey Kuznetsov <kuznet at acronis.com>
---
 fs/fuse/kio/pcs/pcs_cs.c       | 22 ++++++++--------------
 fs/fuse/kio/pcs/pcs_cs_accel.c | 30 +++++++++++++++++++++++++++++-
 2 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/fs/fuse/kio/pcs/pcs_cs.c b/fs/fuse/kio/pcs/pcs_cs.c
index d298be9..20840f8 100644
--- a/fs/fuse/kio/pcs/pcs_cs.c
+++ b/fs/fuse/kio/pcs/pcs_cs.c
@@ -829,18 +829,14 @@ void pcs_cs_submit(struct pcs_cs *cs, struct pcs_int_request *ireq)
 			if (pcs_csa_cs_submit(cs, ireq))
 				return;
 		} else if (ireq->iochunk.cmd == PCS_REQ_T_WRITE) {
-			/* Synchronous writes in accel mode are still not supported */
-			if (!(ireq->dentry->fileinfo.attr.attrib & PCS_FATTR_IMMEDIATE_WRITE) &&
-			    !ireq->dentry->no_write_delay) {
-				struct pcs_int_request * sreq;
-
-				sreq = pcs_csa_csl_write_submit(ireq);
-				if (!sreq)
-					return;
-				if (sreq != ireq) {
-					ireq = sreq;
-					cs = ireq->iochunk.csl->cs[ireq->iochunk.cs_index].cslink.cs;
-				}
+			struct pcs_int_request * sreq;
+
+			sreq = pcs_csa_csl_write_submit(ireq);
+			if (!sreq)
+				return;
+			if (sreq != ireq) {
+				ireq = sreq;
+				cs = ireq->iochunk.csl->cs[ireq->iochunk.cs_index].cslink.cs;
 			}
 		}
 	}
@@ -879,8 +875,6 @@ void pcs_cs_submit(struct pcs_cs *cs, struct pcs_int_request *ireq)
 			 * chain.
 			 */
 			if (idx == ireq->iochunk.cs_index ||
-			    (ireq->dentry->fileinfo.attr.attrib & PCS_FATTR_IMMEDIATE_WRITE) ||
-			    ireq->dentry->no_write_delay ||
 			    ((ireq->iochunk.size|ireq->iochunk.offset) & 511) ||
 			    (ireq->flags & IREQ_F_NO_ACCEL) ||
 			    !pcs_csa_csl_write_submit_single(sreq, idx))
diff --git a/fs/fuse/kio/pcs/pcs_cs_accel.c b/fs/fuse/kio/pcs/pcs_cs_accel.c
index 5d44862..8a7e7f9 100644
--- a/fs/fuse/kio/pcs/pcs_cs_accel.c
+++ b/fs/fuse/kio/pcs/pcs_cs_accel.c
@@ -827,6 +827,25 @@ static void __pcs_csa_write_final_completion(struct pcs_accel_write_req *areq)
 	csa_complete_acr(ireq);
 }
 
+static void csa_sync_work(struct work_struct *w)
+{
+	struct pcs_accel_write_req * areq = container_of(w, struct pcs_accel_write_req, work);
+	struct pcs_int_request * ireq = container_of(areq-areq->index, struct pcs_int_request, iochunk.acr.awr[0]);
+	int res;
+
+	res = vfs_fsync(areq->iocb.ki_filp, 1);
+
+	if (res) {
+		ireq->error.remote = 1;
+		ireq->error.offender = ireq->iochunk.csl->cs[ireq->iochunk.cs_index].info.id;
+		ireq->error.value = PCS_ERR_IO;
+		ireq->flags |= IREQ_F_ACCELERROR;
+	}
+
+	if (atomic_dec_and_test(&areq->iocount))
+		__pcs_csa_write_final_completion(areq);
+}
+
 static void csa_write_complete_work(struct work_struct *w)
 {
 	struct pcs_accel_write_req * areq = container_of(w, struct pcs_accel_write_req, work);
@@ -851,6 +870,15 @@ static void csa_write_complete(struct kiocb *iocb, long ret)
 		}
 	}
 
+	if (!ireq->error.value) {
+		if ((ireq->dentry->fileinfo.attr.attrib & PCS_FATTR_IMMEDIATE_WRITE) ||
+		    ireq->dentry->no_write_delay) {
+			INIT_WORK(&areq->work, csa_sync_work);
+			queue_work(ireq->cc->wq, &areq->work);
+			return;
+		}
+	}
+
 	if (atomic_dec_and_test(&areq->iocount)) {
 		INIT_WORK(&areq->work, csa_write_complete_work);
 		queue_work(ireq->cc->wq, &areq->work);
@@ -1027,7 +1055,7 @@ static inline int csa_submit_write(struct file * file, struct pcs_int_request *
 			return ret >= 0 ? -EIO : ret;
 		}
 
-		/* IO already finished. Drop AIO refcnt and proceed to crc */
+		/* IO already finished. Drop AIO refcnt yet. */
 		FUSE_KTRACE(ireq->cc->fc, "No good, AIO executed synchronously, ireq:%p : %llu:%u+%u",
 			    ireq, (unsigned long long)ireq->iochunk.chunk,
 			    (unsigned)ireq->iochunk.offset,
-- 
1.8.3.1



More information about the Devel mailing list