[Devel,vz7,17/46] fuse: req state use flags

Submitted by Maxim Patlasov on March 25, 2017, 2:19 a.m.

Details

Message ID 149040834136.25341.8496198714381861048.stgit@maxim-thinkpad
State New
Series "fuse: add multi-threading support"
Headers show

Commit Message

Maxim Patlasov March 25, 2017, 2:19 a.m.
Backport from ml:

commit 33e14b4dfdc477344efbcd9b4218f2b350f0f893
Author: Miklos Szeredi <mszeredi@suse.cz>
Date:   Wed Jul 1 16:26:01 2015 +0200

    fuse: req state use flags

    Use flags for representing the state in fuse_req.  This is needed since
    req->list will be protected by different locks in different states, hence
    we'll want the state itself to be split into distinct bits, each protected
    with the relevant lock in that state.

    Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>

Signed-off-by: Maxim Patlasov <mpatlasov@virtuozzo.com>
---
 fs/fuse/control.c |    6 ++++--
 fs/fuse/dev.c     |   23 ++++++++++++++---------
 fs/fuse/file.c    |    2 +-
 fs/fuse/fuse_i.h  |   17 ++++++-----------
 4 files changed, 25 insertions(+), 23 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/control.c b/fs/fuse/control.c
index 6afa384..889c907 100644
--- a/fs/fuse/control.c
+++ b/fs/fuse/control.c
@@ -233,10 +233,9 @@  static int fuse_req_show(struct seq_file *f, void *v)
 	struct fuse_req *req;
 
 	req = list_entry((struct list_head *)v, struct fuse_req, list);
-	seq_printf(f, "state: %-2d flags: %c%c%c%c%c%c%c "
+	seq_printf(f, "flags: %c%c%c%c%c%c%c%c%c%c "
 			"in: op %-4d uniq 0x%016Lx node 0x%016Lx "
 			"out: err %-6d uniq 0x%016Lx\n",
-			req->state,
 			test_bit(FR_ISREPLY, &req->flags) ? 'r' : '-',
 			test_bit(FR_FORCE, &req->flags) ? 'f' : '-',
 			test_bit(FR_ABORTED, &req->flags) ? 'a' : '-',
@@ -244,6 +243,9 @@  static int fuse_req_show(struct seq_file *f, void *v)
 			test_bit(FR_INTERRUPTED, &req->flags) ? 'i' : '-',
 			test_bit(FR_LOCKED, &req->flags) ? 'l' : '-',
 			test_bit(FR_WAITING, &req->flags) ? 'w': '-',
+			test_bit(FR_PENDING, &req->flags) ? 'p': '-',
+			test_bit(FR_SENT, &req->flags) ? 's': '-',
+			test_bit(FR_FINISHED, &req->flags) ? 'f': '-',
 			req->in.h.opcode,
 			req->in.h.unique,
 			req->in.h.nodeid,
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 79bc649..943e050 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -50,6 +50,7 @@  static void fuse_request_init(struct fuse_req *req, struct page **pages,
 	req->pages = pages;
 	req->page_descs = page_descs;
 	req->max_pages = npages;
+	__set_bit(FR_PENDING, &req->flags);
 }
 
 static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags)
@@ -363,8 +364,10 @@  __releases(fc->lock)
 	req->end = NULL;
 	list_del_init(&req->list);
 	list_del_init(&req->intr_entry);
+	WARN_ON(test_bit(FR_PENDING, &req->flags));
+	WARN_ON(test_bit(FR_SENT, &req->flags));
 	smp_wmb();
-	req->state = FUSE_REQ_FINISHED;
+	set_bit(FR_FINISHED, &req->flags);
 	if (test_bit(FR_BACKGROUND, &req->flags)) {
 		clear_bit(FR_BACKGROUND, &req->flags);
 		if (fc->num_background == fc->max_background)
@@ -404,13 +407,13 @@  static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
 	if (!fc->no_interrupt) {
 		/* Any signal may interrupt this */
 		err = wait_event_interruptible(req->waitq,
-					req->state == FUSE_REQ_FINISHED);
+					test_bit(FR_FINISHED, &req->flags));
 		if (!err)
 			return;
 
 		spin_lock(&fc->lock);
 		set_bit(FR_INTERRUPTED, &req->flags);
-		if (req->state == FUSE_REQ_SENT)
+		if (test_bit(FR_SENT, &req->flags))
 			queue_interrupt(fc, req);
 		spin_unlock(&fc->lock);
 	}
@@ -418,14 +421,14 @@  static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
 	if (!test_bit(FR_FORCE, &req->flags)) {
 		/* Only fatal signals may interrupt this */
 		err = wait_event_killable(req->waitq,
-					req->state == FUSE_REQ_FINISHED);
+					test_bit(FR_FINISHED, &req->flags));
 
 		if (!err)
 			return;
 
 		spin_lock(&fc->lock);
 		/* Request is not yet in userspace, bail out */
-		if (req->state == FUSE_REQ_PENDING) {
+		if (test_bit(FR_PENDING, &req->flags)) {
 			list_del(&req->list);
 			spin_unlock(&fc->lock);
 			__fuse_put_request(req);
@@ -439,7 +442,7 @@  static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
 	 * Either request is already in userspace, or it was forced.
 	 * Wait it out.
 	 */
-	wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
+	wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));
 }
 
 static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req,
@@ -1237,7 +1240,7 @@  static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file,
 	}
 
 	req = list_entry(fc->pending.next, struct fuse_req, list);
-	req->state = FUSE_REQ_IO;
+	clear_bit(FR_PENDING, &req->flags);
 	list_move(&req->list, &fc->io);
 
 	in = &req->in;
@@ -1272,7 +1275,7 @@  static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file,
 	if (!test_bit(FR_ISREPLY, &req->flags)) {
 		request_end(fc, req);
 	} else {
-		req->state = FUSE_REQ_SENT;
+		set_bit(FR_SENT, &req->flags);
 		list_move_tail(&req->list, &fc->processing);
 		if (test_bit(FR_INTERRUPTED, &req->flags))
 			queue_interrupt(fc, req);
@@ -1902,7 +1905,7 @@  static ssize_t fuse_dev_do_write(struct fuse_conn *fc,
 		return nbytes;
 	}
 
-	req->state = FUSE_REQ_IO;
+	clear_bit(FR_SENT, &req->flags);
 	list_move(&req->list, &fc->io);
 	req->out.h = oh;
 	set_bit(FR_LOCKED, &req->flags);
@@ -2054,6 +2057,8 @@  __acquires(fc->lock)
 		struct fuse_req *req;
 		req = list_entry(head->next, struct fuse_req, list);
 		req->out.h.error = -ECONNABORTED;
+		clear_bit(FR_PENDING, &req->flags);
+		clear_bit(FR_SENT, &req->flags);
 		request_end(fc, req);
 		spin_lock(&fc->lock);
 	}
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index bdb0e49..3a5388e 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -163,7 +163,7 @@  static void fuse_file_put(struct fuse_file *ff, bool sync)
 			__clear_bit(FR_BACKGROUND, &req->flags);
 			fuse_request_send(ff->fc, req);
 			if (req->out.h.error == -EINTR) {
-				req->state = FUSE_REQ_PENDING;
+				__set_bit(FR_PENDING, &req->flags);
 				req->out.h.error = 0;
 				goto async_fallback;
 			}
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 93deda7..eddc995 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -258,14 +258,6 @@  struct fuse_page_desc {
 	unsigned int offset;
 };
 
-/** The request state */
-enum fuse_req_state {
-	FUSE_REQ_PENDING = 0,
-	FUSE_REQ_IO,
-	FUSE_REQ_SENT,
-	FUSE_REQ_FINISHED
-};
-
 /** The request IO state (for asynchronous processing) */
 struct fuse_io_priv {
 	int async;
@@ -291,6 +283,9 @@  struct fuse_io_priv {
  * FR_ABORTED:		the request was aborted
  * FR_INTERRUPTED:	the request has been interrupted
  * FR_LOCKED:		data is being copied to/from the request
+ * FR_PENDING:		request is not yet in userspace
+ * FR_SENT:		request is in userspace, waiting for an answer
+ * FR_FINISHED:		request is finished
  */
 enum fuse_req_flag {
 	FR_ISREPLY,
@@ -300,6 +295,9 @@  enum fuse_req_flag {
 	FR_ABORTED,
 	FR_INTERRUPTED,
 	FR_LOCKED,
+	FR_PENDING,
+	FR_SENT,
+	FR_FINISHED,
 };
 
 /**
@@ -335,9 +333,6 @@  struct fuse_req {
 	/** Request was killed -- pages were released */
 	unsigned killed:1;
 
-	/** State of the request */
-	enum fuse_req_state state;
-
 	/** The request input */
 	struct fuse_in in;