Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Revert "gfs2: don't stop reads while withdraw in progress"

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>

+6 -22
-1
fs/gfs2/incore.h
··· 599 599 SDF_SKIP_DLM_UNLOCK = 8, 600 600 SDF_FORCE_AIL_FLUSH = 9, 601 601 SDF_FREEZE_INITIATOR = 10, 602 - SDF_WITHDRAW_IN_PROG = 12, /* Withdraw is in progress */ 603 602 SDF_REMOTE_WITHDRAW = 13, /* Performing remote recovery */ 604 603 SDF_WITHDRAW_RECOVERY = 14, /* Wait for journal recovery when we are 605 604 withdrawing */
+3 -6
fs/gfs2/meta_io.c
··· 263 263 struct buffer_head *bh, *bhs[2]; 264 264 int num = 0; 265 265 266 - if (gfs2_withdrawn(sdp) && 267 - !gfs2_withdraw_in_prog(sdp)) { 266 + if (gfs2_withdrawn(sdp)) { 268 267 *bhp = NULL; 269 268 return -EIO; 270 269 } ··· 321 322 322 323 int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh) 323 324 { 324 - if (gfs2_withdrawn(sdp) && 325 - !gfs2_withdraw_in_prog(sdp)) 325 + if (gfs2_withdrawn(sdp)) 326 326 return -EIO; 327 327 328 328 wait_on_buffer(bh); ··· 332 334 gfs2_io_error_bh(sdp, bh); 333 335 return -EIO; 334 336 } 335 - if (gfs2_withdrawn(sdp) && 336 - !gfs2_withdraw_in_prog(sdp)) 337 + if (gfs2_withdrawn(sdp)) 337 338 return -EIO; 338 339 339 340 return 0;
-2
fs/gfs2/sys.c
··· 84 84 "Force AIL Flush: %d\n" 85 85 "FS Freeze Initiator: %d\n" 86 86 "FS Frozen: %d\n" 87 - "Withdraw In Prog: %d\n" 88 87 "Remote Withdraw: %d\n" 89 88 "Withdraw Recovery: %d\n" 90 89 "Killing: %d\n" ··· 115 116 test_bit(SDF_FORCE_AIL_FLUSH, &f), 116 117 test_bit(SDF_FREEZE_INITIATOR, &f), 117 118 test_bit(SDF_FROZEN, &f), 118 - test_bit(SDF_WITHDRAW_IN_PROG, &f), 119 119 test_bit(SDF_REMOTE_WITHDRAW, &f), 120 120 test_bit(SDF_WITHDRAW_RECOVERY, &f), 121 121 test_bit(SDF_KILL, &f),
+3 -8
fs/gfs2/util.c
··· 330 330 if (lm->lm_unmount) 331 331 lm->lm_unmount(sdp, false); 332 332 fs_err(sdp, "file system withdrawn\n"); 333 - clear_bit(SDF_WITHDRAW_IN_PROG, &sdp->sd_flags); 334 333 } 335 334 336 335 void gfs2_withdraw(struct gfs2_sbd *sdp) 337 336 { 338 337 if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) { 339 - unsigned long old = READ_ONCE(sdp->sd_flags), new; 340 - 341 - do { 342 - if (old & BIT(SDF_WITHDRAWN)) 343 - return; 344 - new = old | BIT(SDF_WITHDRAWN) | BIT(SDF_WITHDRAW_IN_PROG); 345 - } while (unlikely(!try_cmpxchg(&sdp->sd_flags, &old, new))); 338 + if (test_and_set_bit(SDF_WITHDRAWN, &sdp->sd_flags)) 339 + return; 346 340 347 341 dump_stack(); 348 342 /* ··· 347 353 return; 348 354 fs_err(sdp, "about to withdraw this file system\n"); 349 355 schedule_work(&sdp->sd_withdraw_work); 356 + return; 350 357 } 351 358 352 359 if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
-5
fs/gfs2/util.h
··· 187 187 return unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags)); 188 188 } 189 189 190 - static inline bool gfs2_withdraw_in_prog(struct gfs2_sbd *sdp) 191 - { 192 - return unlikely(test_bit(SDF_WITHDRAW_IN_PROG, &sdp->sd_flags)); 193 - } 194 - 195 190 #define gfs2_tune_get(sdp, field) \ 196 191 gfs2_tune_get_i(&(sdp)->sd_tune, &(sdp)->sd_tune.field) 197 192