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

Reply via email to