[Devel] [PATCH rh7] fuse: resend interrupted release

Maxim Patlasov mpatlasov at virtuozzo.com
Fri Apr 8 07:47:00 PDT 2016


No, the problem came with our "close_wait" feature. ML doesn't have it.

On 04/08/2016 12:20 AM, Konstantin Khorenko wrote:
> Maxim, should this patch be sent to mainstream as well?
>
> -- 
> Best regards,
>
> Konstantin Khorenko,
> Virtuozzo Linux Kernel Team
>
> On 03/30/2016 03:58 AM, Maxim Patlasov wrote:
>> If a client gets fatal signal while explicitly waiting for ACK from 
>> fused
>> (request_wait_answer()), kernel fuse discards the request like this:
>>
>>>         /* Request is not yet in userspace, bail out */
>>>         if (req->state == FUSE_REQ_PENDING) {
>>>             list_del(&req->list);
>>>             __fuse_put_request(req);
>>>             req->out.h.error = -EINTR;
>>>             return;
>>>         }
>>
>> This is nice for requests directly initiated by client, but not for 
>> RELEASE
>> requests: we have to avoid discarding RELEASE requests because otherwise
>> fused won't know when the file is "closed" by client (last fput called).
>>
>> The problem didn't exist before close_wait feature because then 
>> fuse_file_put
>> sent RELEASE asynchronously. Hence no request_wait_answer() involved.
>>
>> The patch solves the problem by resending interrupted RELEASE 
>> asynchronously.
>> This is OK because if the client is killed, he/she doesn't care about
>> sync/async close(2) behavior.
>>
>> https://jira.sw.ru/browse/PSBM-45428
>>
>> Signed-off-by: Maxim Patlasov <mpatlasov at virtuozzo.com>
>> ---
>>   fs/fuse/file.c |    6 ++++++
>>   1 file changed, 6 insertions(+)
>>
>> diff --git a/fs/fuse/file.c b/fs/fuse/file.c
>> index f432b70..11c5959 100644
>> --- a/fs/fuse/file.c
>> +++ b/fs/fuse/file.c
>> @@ -155,10 +155,16 @@ static void fuse_file_put(struct fuse_file *ff, 
>> bool sync)
>>           if (sync) {
>>               req->background = 0;
>>               fuse_request_send(ff->fc, req);
>> +            if (req->out.h.error == -EINTR) {
>> +                req->state = FUSE_REQ_INIT;
>> +                req->out.h.error = 0;
>> +                goto async_fallback;
>> +            }
>>               fuse_file_list_del(ff);
>>               path_put(&req->misc.release.path);
>>               fuse_put_request(ff->fc, req);
>>           } else {
>> +async_fallback:
>>               fuse_file_list_del(ff);
>>               req->end = fuse_release_end;
>>               req->background = 1;
>>
>> .
>>



More information about the Devel mailing list