diff options
author | Csaba Henk <csaba@redhat.com> | 2020-07-14 19:22:19 +0200 |
---|---|---|
committer | Amar Tumballi <amar@kadalu.io> | 2020-07-24 04:35:42 +0000 |
commit | 6195636dae5a476b3d08d7ad1d7b1afebb640c49 (patch) | |
tree | b3e45e1bc9b9a9c265308d285fd59e151e4c5df0 | |
parent | c6205023f3992d165e18d78bbeedbb2eb1cc5beb (diff) |
fuse: change setlk interrupt strategy to 'sync'
The setlk interrupt handler uses a 'fork' of the resolved
fuse state from setlk (a copy with some edits) to initiate
its own auxiliary fop. Thus the references stored in the
fuse states of the setlk fop and of its interrupt handler
are shared (apart from the ones edited by the interrupt
handler -- but the bulk of them remain as is). The lifetimes
of these references are tied to the setlk fop, which has
established them by properly claiming their backing
resources. To guarantee the validity of these references in
the interrupt context, we need to make sure that the setlk
fop did not reclaim the fuse state while the interrupt
handler is running.
In other words, the setlk fop needs to wait for the
termination of the interrupt handler, which is accomplished
by the 'sync' strategy of the interrupt API (passing
true for the 'sync' argument of
fuse_interrupt_finish_{fop,interrupt} functions).
Change-Id: I9a6dc76972507be4b7ba8d023cc876e5fddf813f
Updates: #1374
Signed-off-by: Csaba Henk <csaba@redhat.com>
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 19 |
1 files changed, 5 insertions, 14 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 91eaf9cf6f6..f2eeac1d1ee 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -4737,12 +4737,10 @@ fuse_setlk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, fuse_state_t *state = NULL; int ret = 0; - ret = fuse_interrupt_finish_fop(frame, this, _gf_false, (void **)&state); - if (state) { - GF_FREE(state->name); - dict_unref(state->xdata); - GF_FREE(state); - } + ret = fuse_interrupt_finish_fop(frame, this, _gf_true, (void **)&state); + GF_FREE(state->name); + dict_unref(state->xdata); + GF_FREE(state); if (ret) { return 0; } @@ -4799,17 +4797,10 @@ fuse_setlk_interrupt_handler_cbk(call_frame_t *frame, void *cookie, { fuse_interrupt_state_t intstat = INTERRUPT_NONE; fuse_interrupt_record_t *fir = cookie; - fuse_state_t *state = NULL; intstat = op_ret >= 0 ? INTERRUPT_HANDLED : INTERRUPT_SQUELCHED; - fuse_interrupt_finish_interrupt(this, fir, intstat, _gf_false, - (void **)&state); - if (state) { - GF_FREE(state->name); - dict_unref(state->xdata); - GF_FREE(state); - } + fuse_interrupt_finish_interrupt(this, fir, intstat, _gf_true, NULL); STACK_DESTROY(frame->root); |