From 365ae710df91edc97d24817e3271e01bffaaee32 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 1 Jul 2015 16:26:06 +0200 Subject: fuse: request_end(): do once When the connection is aborted it is possible that request_end() will be called twice. Use atomic test and set to do the actual ending only once. test_and_set_bit() also provides the necessary barrier semantics so no explicit smp_wmb() is necessary. Signed-off-by: Miklos Szeredi Reviewed-by: Ashish Samant --- fs/fuse/dev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'fs/fuse') diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 7f37e55edc0e..cd242fc6a92b 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -384,14 +384,18 @@ __releases(fc->lock) { struct fuse_iqueue *fiq = &fc->iq; void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; + + if (test_and_set_bit(FR_FINISHED, &req->flags)) { + spin_unlock(&fc->lock); + return; + } + req->end = NULL; spin_lock(&fiq->waitq.lock); list_del_init(&req->intr_entry); spin_unlock(&fiq->waitq.lock); WARN_ON(test_bit(FR_PENDING, &req->flags)); WARN_ON(test_bit(FR_SENT, &req->flags)); - smp_wmb(); - 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) -- cgit v1.2.3