fs/fuse kio: missed cleanup for interrupted shrink request

Submitted by Pavel Butsykin on Dec. 17, 2018, 2:08 p.m.

Details

Message ID 20181217140853.4343-1-pbutsykin@virtuozzo.com
State New
Series "fs/fuse kio: missed cleanup for interrupted shrink request"
Headers show

Commit Message

Pavel Butsykin Dec. 17, 2018, 2:08 p.m.
In the case when shrink request was interrupted we need cleanup di->size.op and
resubmit pending read requests by analogy with this patch:
"fs/fuse kio: missed clean di->size.op in failed shrink request"

Also if the request has already gone to userspace, this request cannot be
interrupted in order to avoid racing with request_end(). But it's still
possible race with req->end callback, so let's also fix the wait condition.

#VSTOR-19074

Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
---
 fs/fuse/dev.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 6fcbb117aa9c..dc21886ee55d 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -517,6 +517,8 @@  static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
 			spin_unlock(&fiq->waitq.lock);
 			__fuse_put_request(req);
 			req->out.h.error = -EINTR;
+			if (req->end)
+				req->end(fc, req);
 			return;
 		}
 		spin_unlock(&fiq->waitq.lock);
@@ -526,7 +528,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, test_bit(FR_FINISHED, &req->flags));
+	wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags) && !req->end);
 }
 
 static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req,

Comments

Kirill Tkhai Dec. 17, 2018, 2:52 p.m.
On 17.12.2018 17:08, Pavel Butsykin wrote:
> In the case when shrink request was interrupted we need cleanup di->size.op and
> resubmit pending read requests by analogy with this patch:
> "fs/fuse kio: missed clean di->size.op in failed shrink request"
> 
> Also if the request has already gone to userspace, this request cannot be
> interrupted in order to avoid racing with request_end(). But it's still
> possible race with req->end callback, so let's also fix the wait condition.
> 
> #VSTOR-19074
> 
> Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>

Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com>

> ---
>  fs/fuse/dev.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
> index 6fcbb117aa9c..dc21886ee55d 100644
> --- a/fs/fuse/dev.c
> +++ b/fs/fuse/dev.c
> @@ -517,6 +517,8 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
>  			spin_unlock(&fiq->waitq.lock);
>  			__fuse_put_request(req);
>  			req->out.h.error = -EINTR;
> +			if (req->end)
> +				req->end(fc, req);
>  			return;
>  		}
>  		spin_unlock(&fiq->waitq.lock);
> @@ -526,7 +528,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, test_bit(FR_FINISHED, &req->flags));
> +	wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags) && !req->end);
>  }
>  
>  static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req,
>