Messages in this thread | | | Subject | Re: [PATCH v2] ocfs2: ocfs2_downconvert_lock failure results in deadlock | From | Joseph Qi <> | Date | Mon, 30 Aug 2021 19:05:14 +0800 |
| |
On 8/30/21 12:46 PM, Gang He wrote: > Usually, ocfs2_downconvert_lock() function always downconverts > dlm lock to the expected level for satisfy dlm bast requests > from the other nodes. > But there is a rare situation. When dlm lock conversion is being > canceled, ocfs2_downconvert_lock() function will return -EBUSY. > You need to be aware that ocfs2_cancel_convert() function is > asynchronous in fsdlm implementation. > If we does not requeue this lockres entry, ocfs2 downconvert > thread no longer handles this dlm lock bast request. Then, the > other nodes will not get the dlm lock again, the current node's > process will be blocked when acquire this dlm lock again. > > Signed-off-by: Gang He <ghe@suse.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com> > --- > v2: keep error print in ocfs2_downconvert_lock function, add more detailed > comments in code, add msleep to avoid repeated attempts. > --- > fs/ocfs2/dlmglue.c | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > > diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c > index 48fd369c29a4..f8f561850470 100644 > --- a/fs/ocfs2/dlmglue.c > +++ b/fs/ocfs2/dlmglue.c > @@ -16,6 +16,7 @@ > #include <linux/debugfs.h> > #include <linux/seq_file.h> > #include <linux/time.h> > +#include <linux/delay.h> > #include <linux/quotaops.h> > #include <linux/sched/signal.h> > > @@ -3912,6 +3913,17 @@ static int ocfs2_unblock_lock(struct ocfs2_super *osb, > spin_unlock_irqrestore(&lockres->l_lock, flags); > ret = ocfs2_downconvert_lock(osb, lockres, new_level, set_lvb, > gen); > + /* The dlm lock convert is being cancelled in background, > + * ocfs2_cancel_convert() is asynchronous in fs/dlm, > + * requeue it, try again later. > + */ > + if (ret == -EBUSY) { > + ctl->requeue = 1; > + mlog(ML_BASTS, "lockres %s, ReQ: Downconvert busy\n", > + lockres->l_name); > + ret = 0; > + msleep(20); > + } > > leave: > if (ret) >
| |