The call stack is as follows:
finish_xmote()
...
spin_lock(&gl->gl_lockref.lock);
...
--> do_xmote()
spin_unlock(&gl->gl_lockref.lock);
...
return;
...
spin_unlock(&gl->gl_lockref.lock);
do_xmote function needs to be locked before returning,
Otherwise, there will be a double release lock in finish_xmote() function.
Signed-off-by: Wu Bo <[email protected]>
---
fs/gfs2/glock.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 29f9b66..7129d10 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -613,6 +613,7 @@ static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int
fs_err(sdp, "Error %d syncing glock \n", ret);
gfs2_dump_glock(NULL, gl, true);
}
+ spin_lock(&gl->gl_lockref.lock);
return;
}
}
--
1.8.3.1
Hi,
On Tue, Apr 28, 2020 at 5:30 AM Wu Bo <[email protected]> wrote:
> The call stack is as follows:
> finish_xmote()
> ...
> spin_lock(&gl->gl_lockref.lock);
> ...
> --> do_xmote()
> spin_unlock(&gl->gl_lockref.lock);
> ...
> return;
> ...
> spin_unlock(&gl->gl_lockref.lock);
>
> do_xmote function needs to be locked before returning,
> Otherwise, there will be a double release lock in finish_xmote() function.
>
> Signed-off-by: Wu Bo <[email protected]>
> ---
> fs/gfs2/glock.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
> index 29f9b66..7129d10 100644
> --- a/fs/gfs2/glock.c
> +++ b/fs/gfs2/glock.c
> @@ -613,6 +613,7 @@ static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int
> fs_err(sdp, "Error %d syncing glock \n", ret);
> gfs2_dump_glock(NULL, gl, true);
> }
> + spin_lock(&gl->gl_lockref.lock);
> return;
> }
> }
> --
> 1.8.3.1
this patch looks correct. We've independently discovered this bug as
well in the meantime, and we'll send the fix upstream.
Thanks,
Andreas