Add a GL_NOPID flag to indicate that a holder isn't associated with the
current process.  This is useful for iopen glocks which are associated
with open files, as well as journal glock holders and similar which are
associated with the filesystem.

When the GL_NOPID flag is set, the pid and process name are only
reported while that process is still waiting for the holder to be
acquired.  After that, the pid is reported as 0 and the process name is
reported as "(none)".

When this flag is used (see the next patch), processes will no longer be
reported as holding glocks which they are not actually holding in the
glocks dump file.  So when a process is reported as having "(ended)",
this will actually indicate a bug.

Signed-off-by: Andreas Gruenbacher <agrue...@redhat.com>
---
 fs/gfs2/glock.c | 41 +++++++++++++++++++++++++++++++----------
 fs/gfs2/glock.h |  1 +
 2 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 630c6550eacf..106a994b20c0 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1461,6 +1461,15 @@ void gfs2_print_dbg(struct seq_file *seq, const char 
*fmt, ...)
        va_end(args);
 }
 
+static inline bool pid_is_meaningful(const struct gfs2_holder *gh)
+{
+       if (!(gh->gh_flags & GL_NOPID))
+               return true;
+       if (gh->gh_state == LM_ST_UNLOCKED && !(gh->gh_flags & GL_ASYNC))
+               return true;
+       return false;
+}
+
 /**
  * add_to_queue - Add a holder to the wait queue (but look for recursion)
  * @gh: the holder structure to add
@@ -1497,10 +1506,17 @@ __acquires(&gl->gl_lockref.lock)
        }
 
        list_for_each_entry(gh2, &gl->gl_holders, gh_list) {
-               if (unlikely(gh2->gh_owner_pid == gh->gh_owner_pid &&
-                   (gh->gh_gl->gl_ops->go_type != LM_TYPE_FLOCK) &&
-                   !test_bit(HIF_MAY_DEMOTE, &gh2->gh_iflags)))
-                       goto trap_recursive;
+               if (likely(gh2->gh_owner_pid != gh->gh_owner_pid))
+                       continue;
+               if (gh->gh_gl->gl_ops->go_type == LM_TYPE_FLOCK)
+                       continue;
+               if (test_bit(HIF_MAY_DEMOTE, &gh2->gh_iflags))
+                       continue;
+               if (!pid_is_meaningful(gh2))
+                       continue;
+               goto trap_recursive;
+       }
+       list_for_each_entry(gh2, &gl->gl_holders, gh_list) {
                if (try_futile &&
                    !(gh2->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) {
 fail:
@@ -2315,19 +2331,24 @@ static const char *hflags2str(char *buf, u16 flags, 
unsigned long iflags)
 static void dump_holder(struct seq_file *seq, const struct gfs2_holder *gh,
                        const char *fs_id_buf)
 {
-       struct task_struct *gh_owner = NULL;
+       const char *comm = "(none)";
+       pid_t owner_pid = 0;
        char flags_buf[32];
 
        rcu_read_lock();
-       if (gh->gh_owner_pid)
+       if (pid_is_meaningful(gh)) {
+               struct task_struct *gh_owner;
+
+               comm = "(ended)";
+               owner_pid = pid_nr(gh->gh_owner_pid);
                gh_owner = pid_task(gh->gh_owner_pid, PIDTYPE_PID);
+               if (gh_owner)
+                       comm = gh_owner->comm;
+       }
        gfs2_print_dbg(seq, "%s H: s:%s f:%s e:%d p:%ld [%s] %pS\n",
                       fs_id_buf, state2str(gh->gh_state),
                       hflags2str(flags_buf, gh->gh_flags, gh->gh_iflags),
-                      gh->gh_error,
-                      gh->gh_owner_pid ? (long)pid_nr(gh->gh_owner_pid) : -1,
-                      gh_owner ? gh_owner->comm : "(ended)",
-                      (void *)gh->gh_ip);
+                      gh->gh_error, (long)owner_pid, comm, (void *)gh->gh_ip);
        rcu_read_unlock();
 }
 
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 4f8642301801..13e567645618 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -91,6 +91,7 @@ enum {
 #define GL_ASYNC               0x0040
 #define GL_EXACT               0x0080
 #define GL_SKIP                        0x0100
+#define GL_NOPID               0x0200
 #define GL_NOCACHE             0x0400
   
 /*
-- 
2.35.1

Reply via email to