summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCsaba Henk <csaba@redhat.com>2020-07-14 19:22:19 +0200
committerAmar Tumballi <amar@kadalu.io>2020-07-24 04:35:42 +0000
commit6195636dae5a476b3d08d7ad1d7b1afebb640c49 (patch)
treeb3e45e1bc9b9a9c265308d285fd59e151e4c5df0
parentc6205023f3992d165e18d78bbeedbb2eb1cc5beb (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.c19
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);