The current withdraw code duplicates the journal recovery code gfs2
already has for dealing with node failures, and it does so poorly. That
code was added because when releasing a lockspace, we didn't have a way
to indicate that the lockspace needs recovery. We now do have this
feature, so the current withdraw code can be removed almost entirely.
This is one of several steps towards that.
The withdrawing node has no role in recovering from the withdraw
anymore, so it also no longer needs to read metadata blocks after a
withdraw.
We now only need to set a single bit in gfs2_withdraw(), so switch from
try_cmpxchg() to test_and_set_bit().
Reverts commit
8cc67f704f4b ("gfs2: don't stop reads while withdraw in
progress").
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
SDF_SKIP_DLM_UNLOCK = 8,
SDF_FORCE_AIL_FLUSH = 9,
SDF_FREEZE_INITIATOR = 10,
- SDF_WITHDRAW_IN_PROG = 12, /* Withdraw is in progress */
SDF_REMOTE_WITHDRAW = 13, /* Performing remote recovery */
SDF_WITHDRAW_RECOVERY = 14, /* Wait for journal recovery when we are
withdrawing */
struct buffer_head *bh, *bhs[2];
int num = 0;
- if (gfs2_withdrawn(sdp) &&
- !gfs2_withdraw_in_prog(sdp)) {
+ if (gfs2_withdrawn(sdp)) {
*bhp = NULL;
return -EIO;
}
int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
{
- if (gfs2_withdrawn(sdp) &&
- !gfs2_withdraw_in_prog(sdp))
+ if (gfs2_withdrawn(sdp))
return -EIO;
wait_on_buffer(bh);
gfs2_io_error_bh(sdp, bh);
return -EIO;
}
- if (gfs2_withdrawn(sdp) &&
- !gfs2_withdraw_in_prog(sdp))
+ if (gfs2_withdrawn(sdp))
return -EIO;
return 0;
"Force AIL Flush: %d\n"
"FS Freeze Initiator: %d\n"
"FS Frozen: %d\n"
- "Withdraw In Prog: %d\n"
"Remote Withdraw: %d\n"
"Withdraw Recovery: %d\n"
"Killing: %d\n"
test_bit(SDF_FORCE_AIL_FLUSH, &f),
test_bit(SDF_FREEZE_INITIATOR, &f),
test_bit(SDF_FROZEN, &f),
- test_bit(SDF_WITHDRAW_IN_PROG, &f),
test_bit(SDF_REMOTE_WITHDRAW, &f),
test_bit(SDF_WITHDRAW_RECOVERY, &f),
test_bit(SDF_KILL, &f),
if (lm->lm_unmount)
lm->lm_unmount(sdp, false);
fs_err(sdp, "file system withdrawn\n");
- clear_bit(SDF_WITHDRAW_IN_PROG, &sdp->sd_flags);
}
void gfs2_withdraw(struct gfs2_sbd *sdp)
{
if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) {
- unsigned long old = READ_ONCE(sdp->sd_flags), new;
-
- do {
- if (old & BIT(SDF_WITHDRAWN))
- return;
- new = old | BIT(SDF_WITHDRAWN) | BIT(SDF_WITHDRAW_IN_PROG);
- } while (unlikely(!try_cmpxchg(&sdp->sd_flags, &old, new)));
+ if (test_and_set_bit(SDF_WITHDRAWN, &sdp->sd_flags))
+ return;
dump_stack();
/*
return;
fs_err(sdp, "about to withdraw this file system\n");
schedule_work(&sdp->sd_withdraw_work);
+ return;
}
if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
return unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags));
}
-static inline bool gfs2_withdraw_in_prog(struct gfs2_sbd *sdp)
-{
- return unlikely(test_bit(SDF_WITHDRAW_IN_PROG, &sdp->sd_flags));
-}
-
#define gfs2_tune_get(sdp, field) \
gfs2_tune_get_i(&(sdp)->sd_tune, &(sdp)->sd_tune.field)