Before this patch, when a file system was withdrawn, all further attempts to enqueue or promote glocks were rejected and returned -EIO. This is only important for media-backed glocks like inode and rgrp glocks. All other glocks may be safely used because there is no potential for metadata corruption. This patch allows some glocks to be used even after the file system is withdrawn. This is accomplished with a new glops flag, GLOF_OK_AT_WITHDRAW. This facilitates future patches that enhance fs withdraw.
Signed-off-by: Bob Peterson <rpete...@redhat.com> --- fs/gfs2/glock.c | 4 +++- fs/gfs2/glops.c | 8 ++++++-- fs/gfs2/incore.h | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index c6d6e478f5e3..25923b9e18ef 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -543,6 +543,7 @@ __acquires(&gl->gl_lockref.lock) int ret; if (unlikely(withdrawn(sdp)) && + !(glops->go_flags & GLOF_OK_AT_WITHDRAW) && target != LM_ST_UNLOCKED) return; lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | @@ -1091,7 +1092,8 @@ int gfs2_glock_nq(struct gfs2_holder *gh) struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; int error = 0; - if (unlikely(withdrawn(sdp))) + if (unlikely(withdrawn(sdp)) && + !(gl->gl_ops->go_flags & GLOF_OK_AT_WITHDRAW)) return -EIO; if (test_bit(GLF_LRU, &gl->gl_flags)) diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 9c86c8004ba7..4ba0f21aa312 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -583,6 +583,7 @@ static void iopen_go_callback(struct gfs2_glock *gl, bool remote) const struct gfs2_glock_operations gfs2_meta_glops = { .go_type = LM_TYPE_META, + .go_flags = GLOF_OK_AT_WITHDRAW, }; const struct gfs2_glock_operations gfs2_inode_glops = { @@ -610,6 +611,7 @@ const struct gfs2_glock_operations gfs2_freeze_glops = { .go_xmote_bh = freeze_go_xmote_bh, .go_demote_ok = freeze_go_demote_ok, .go_type = LM_TYPE_NONDISK, + .go_flags = GLOF_OK_AT_WITHDRAW, }; const struct gfs2_glock_operations gfs2_iopen_glops = { @@ -620,20 +622,22 @@ const struct gfs2_glock_operations gfs2_iopen_glops = { const struct gfs2_glock_operations gfs2_flock_glops = { .go_type = LM_TYPE_FLOCK, - .go_flags = GLOF_LRU, + .go_flags = GLOF_LRU | GLOF_OK_AT_WITHDRAW, }; const struct gfs2_glock_operations gfs2_nondisk_glops = { .go_type = LM_TYPE_NONDISK, + .go_flags = GLOF_OK_AT_WITHDRAW, }; const struct gfs2_glock_operations gfs2_quota_glops = { .go_type = LM_TYPE_QUOTA, - .go_flags = GLOF_LVB | GLOF_LRU, + .go_flags = GLOF_LVB | GLOF_LRU | GLOF_OK_AT_WITHDRAW, }; const struct gfs2_glock_operations gfs2_journal_glops = { .go_type = LM_TYPE_JOURNAL, + .go_flags = GLOF_OK_AT_WITHDRAW, }; const struct gfs2_glock_operations *gfs2_glops_list[] = { diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index c6984265807f..d84430eceb6c 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -250,6 +250,7 @@ struct gfs2_glock_operations { #define GLOF_ASPACE 1 #define GLOF_LVB 2 #define GLOF_LRU 4 +#define GLOF_OK_AT_WITHDRAW 8 }; enum { -- 2.20.1