aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2015-07-01 10:26:01 -0400
committerMiklos Szeredi <mszeredi@suse.cz>2015-07-01 10:26:01 -0400
commit33e14b4dfdc477344efbcd9b4218f2b350f0f893 (patch)
tree8f56045f3f3de4f5e1fc42fe0d03e48c1ede57c4 /fs
parent7a3b2c754749c73b4a255b2a1070c24dba589098 (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/fuse/dev.c23
-rw-r--r--fs/fuse/file.c2
-rw-r--r--fs/fuse/fuse_i.h17
3 files changed, 21 insertions, 21 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index e5c541b7c7af..f1e2efd6b186 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -48,6 +48,7 @@ static void fuse_request_init(struct fuse_req *req, struct page **pages,
48 req->pages = pages; 48 req->pages = pages;
49 req->page_descs = page_descs; 49 req->page_descs = page_descs;
50 req->max_pages = npages; 50 req->max_pages = npages;
51 __set_bit(FR_PENDING, &req->flags);
51} 52}
52 53
53static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) 54static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags)
@@ -380,8 +381,10 @@ __releases(fc->lock)
380 req->end = NULL; 381 req->end = NULL;
381 list_del_init(&req->list); 382 list_del_init(&req->list);
382 list_del_init(&req->intr_entry); 383 list_del_init(&req->intr_entry);
384 WARN_ON(test_bit(FR_PENDING, &req->flags));
385 WARN_ON(test_bit(FR_SENT, &req->flags));
383 smp_wmb(); 386 smp_wmb();
384 req->state = FUSE_REQ_FINISHED; 387 set_bit(FR_FINISHED, &req->flags);
385 if (test_bit(FR_BACKGROUND, &req->flags)) { 388 if (test_bit(FR_BACKGROUND, &req->flags)) {
386 clear_bit(FR_BACKGROUND, &req->flags); 389 clear_bit(FR_BACKGROUND, &req->flags);
387 if (fc->num_background == fc->max_background) 390 if (fc->num_background == fc->max_background)
@@ -421,13 +424,13 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
421 if (!fc->no_interrupt) { 424 if (!fc->no_interrupt) {
422 /* Any signal may interrupt this */ 425 /* Any signal may interrupt this */
423 err = wait_event_interruptible(req->waitq, 426 err = wait_event_interruptible(req->waitq,
424 req->state == FUSE_REQ_FINISHED); 427 test_bit(FR_FINISHED, &req->flags));
425 if (!err) 428 if (!err)
426 return; 429 return;
427 430
428 spin_lock(&fc->lock); 431 spin_lock(&fc->lock);
429 set_bit(FR_INTERRUPTED, &req->flags); 432 set_bit(FR_INTERRUPTED, &req->flags);
430 if (req->state == FUSE_REQ_SENT) 433 if (test_bit(FR_SENT, &req->flags))
431 queue_interrupt(fc, req); 434 queue_interrupt(fc, req);
432 spin_unlock(&fc->lock); 435 spin_unlock(&fc->lock);
433 } 436 }
@@ -438,7 +441,7 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
438 /* Only fatal signals may interrupt this */ 441 /* Only fatal signals may interrupt this */
439 block_sigs(&oldset); 442 block_sigs(&oldset);
440 err = wait_event_interruptible(req->waitq, 443 err = wait_event_interruptible(req->waitq,
441 req->state == FUSE_REQ_FINISHED); 444 test_bit(FR_FINISHED, &req->flags));
442 restore_sigs(&oldset); 445 restore_sigs(&oldset);
443 446
444 if (!err) 447 if (!err)
@@ -446,7 +449,7 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
446 449
447 spin_lock(&fc->lock); 450 spin_lock(&fc->lock);
448 /* Request is not yet in userspace, bail out */ 451 /* Request is not yet in userspace, bail out */
449 if (req->state == FUSE_REQ_PENDING) { 452 if (test_bit(FR_PENDING, &req->flags)) {
450 list_del(&req->list); 453 list_del(&req->list);
451 spin_unlock(&fc->lock); 454 spin_unlock(&fc->lock);
452 __fuse_put_request(req); 455 __fuse_put_request(req);
@@ -460,7 +463,7 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
460 * Either request is already in userspace, or it was forced. 463 * Either request is already in userspace, or it was forced.
461 * Wait it out. 464 * Wait it out.
462 */ 465 */
463 wait_event(req->waitq, req->state == FUSE_REQ_FINISHED); 466 wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));
464} 467}
465 468
466static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 469static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
@@ -1273,7 +1276,7 @@ static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file,
1273 } 1276 }
1274 1277
1275 req = list_entry(fc->pending.next, struct fuse_req, list); 1278 req = list_entry(fc->pending.next, struct fuse_req, list);
1276 req->state = FUSE_REQ_IO; 1279 clear_bit(FR_PENDING, &req->flags);
1277 list_move(&req->list, &fc->io); 1280 list_move(&req->list, &fc->io);
1278 1281
1279 in = &req->in; 1282 in = &req->in;
@@ -1308,7 +1311,7 @@ static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file,
1308 if (!test_bit(FR_ISREPLY, &req->flags)) { 1311 if (!test_bit(FR_ISREPLY, &req->flags)) {
1309 request_end(fc, req); 1312 request_end(fc, req);
1310 } else { 1313 } else {
1311 req->state = FUSE_REQ_SENT; 1314 set_bit(FR_SENT, &req->flags);
1312 list_move_tail(&req->list, &fc->processing); 1315 list_move_tail(&req->list, &fc->processing);
1313 if (test_bit(FR_INTERRUPTED, &req->flags)) 1316 if (test_bit(FR_INTERRUPTED, &req->flags))
1314 queue_interrupt(fc, req); 1317 queue_interrupt(fc, req);
@@ -1904,7 +1907,7 @@ static ssize_t fuse_dev_do_write(struct fuse_conn *fc,
1904 return nbytes; 1907 return nbytes;
1905 } 1908 }
1906 1909
1907 req->state = FUSE_REQ_IO; 1910 clear_bit(FR_SENT, &req->flags);
1908 list_move(&req->list, &fc->io); 1911 list_move(&req->list, &fc->io);
1909 req->out.h = oh; 1912 req->out.h = oh;
1910 set_bit(FR_LOCKED, &req->flags); 1913 set_bit(FR_LOCKED, &req->flags);
@@ -2059,6 +2062,8 @@ __acquires(fc->lock)
2059 struct fuse_req *req; 2062 struct fuse_req *req;
2060 req = list_entry(head->next, struct fuse_req, list); 2063 req = list_entry(head->next, struct fuse_req, list);
2061 req->out.h.error = -ECONNABORTED; 2064 req->out.h.error = -ECONNABORTED;
2065 clear_bit(FR_PENDING, &req->flags);
2066 clear_bit(FR_SENT, &req->flags);
2062 request_end(fc, req); 2067 request_end(fc, req);
2063 spin_lock(&fc->lock); 2068 spin_lock(&fc->lock);
2064 } 2069 }
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index d0c23d075427..64835cf58936 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1743,7 +1743,7 @@ static bool fuse_writepage_in_flight(struct fuse_req *new_req,
1743 } 1743 }
1744 } 1744 }
1745 1745
1746 if (old_req->num_pages == 1 && old_req->state == FUSE_REQ_PENDING) { 1746 if (old_req->num_pages == 1 && test_bit(FR_PENDING, &old_req->flags)) {
1747 struct backing_dev_info *bdi = inode_to_bdi(page->mapping->host); 1747 struct backing_dev_info *bdi = inode_to_bdi(page->mapping->host);
1748 1748
1749 copy_highpage(old_req->pages[0], page); 1749 copy_highpage(old_req->pages[0], page);
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 3fd65f613515..8eaf3b0de033 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -241,14 +241,6 @@ struct fuse_args {
241 241
242#define FUSE_ARGS(args) struct fuse_args args = {} 242#define FUSE_ARGS(args) struct fuse_args args = {}
243 243
244/** The request state */
245enum fuse_req_state {
246 FUSE_REQ_PENDING = 0,
247 FUSE_REQ_IO,
248 FUSE_REQ_SENT,
249 FUSE_REQ_FINISHED
250};
251
252/** The request IO state (for asynchronous processing) */ 244/** The request IO state (for asynchronous processing) */
253struct fuse_io_priv { 245struct fuse_io_priv {
254 int async; 246 int async;
@@ -274,6 +266,9 @@ struct fuse_io_priv {
274 * FR_ABORTED: the request was aborted 266 * FR_ABORTED: the request was aborted
275 * FR_INTERRUPTED: the request has been interrupted 267 * FR_INTERRUPTED: the request has been interrupted
276 * FR_LOCKED: data is being copied to/from the request 268 * FR_LOCKED: data is being copied to/from the request
269 * FR_PENDING: request is not yet in userspace
270 * FR_SENT: request is in userspace, waiting for an answer
271 * FR_FINISHED: request is finished
277 */ 272 */
278enum fuse_req_flag { 273enum fuse_req_flag {
279 FR_ISREPLY, 274 FR_ISREPLY,
@@ -283,6 +278,9 @@ enum fuse_req_flag {
283 FR_ABORTED, 278 FR_ABORTED,
284 FR_INTERRUPTED, 279 FR_INTERRUPTED,
285 FR_LOCKED, 280 FR_LOCKED,
281 FR_PENDING,
282 FR_SENT,
283 FR_FINISHED,
286}; 284};
287 285
288/** 286/**
@@ -309,9 +307,6 @@ struct fuse_req {
309 /* Request flags, updated with test/set/clear_bit() */ 307 /* Request flags, updated with test/set/clear_bit() */
310 unsigned long flags; 308 unsigned long flags;
311 309
312 /** State of the request */
313 enum fuse_req_state state;
314
315 /** The request input */ 310 /** The request input */
316 struct fuse_in in; 311 struct fuse_in in;
317 312