This patch adds a new file: /sys/fs/gfs2/*/status which will report the status of the file system. Catting this file dumps the current status of the file system according to various superblock variables. For example:
Journal Checked: 1 Journal Live: 1 Withdrawn: 0 No barriers: 0 No recovery: 0 Demote: 0 No Journal ID: 1 RO Recovery: 0 Skip DLM Unlock: 0 Force AIL Flush: 0 FS Frozen: 0 Withdrawing: 0 Withdraw In Prog: 0 Remote Withdraw: 0 Withdraw Recovery: 0 sd_log_lock held: 0 statfs_spin held: 0 sd_rindex_spin: 0 sd_jindex_spin: 0 sd_trunc_lock: 0 sd_bitmap_lock: 0 sd_ordered_lock: 0 sd_ail_lock: 0 sd_log_error: 0 sd_log_flush_lock: 0 sd_log_flush_lock: 1 sd_ail1_list: 281 transactions, 11 ail1, 1 ail2 sd_ail2_list: 0 transactions, 0 ail1, 0 ail2 sd_log_revokes: 0 / 0 sd_log_in_flight: 1 Signed-off-by: Bob Peterson <rpete...@redhat.com> --- fs/gfs2/sys.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index d28c41bd69b0..ea86ba5e4afb 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -63,6 +63,117 @@ static ssize_t id_show(struct gfs2_sbd *sdp, char *buf) MAJOR(sdp->sd_vfs->s_dev), MINOR(sdp->sd_vfs->s_dev)); } +static int count_trans_list(struct gfs2_sbd *sdp, struct list_head *head, + int *ail1, int *ail2) +{ + struct gfs2_trans *tr; + struct gfs2_bufdata *bd; + int unlock_spin, trans = 0; + + *ail1 = *ail2 = 0; + unlock_spin = spin_trylock(&sdp->sd_ail_lock); + + list_for_each_entry(tr, head, tr_list) { + trans++; + list_for_each_entry(bd, &tr->tr_ail1_list, bd_ail_st_list) + (*ail1)++; + list_for_each_entry(bd, &tr->tr_ail2_list, bd_ail_st_list) + (*ail2)++; + } + + if (unlock_spin) + spin_unlock(&sdp->sd_ail_lock); + + return trans; +} + +static int count_list(struct gfs2_sbd *sdp, struct list_head *head) +{ + int unlock_spin, count = 0; + struct gfs2_bufdata *bd; + + unlock_spin = spin_trylock(&sdp->sd_log_lock); + + list_for_each_entry(bd, head, bd_list) + count++; + if (unlock_spin) + spin_unlock(&sdp->sd_log_lock); + + return count; +} + +static ssize_t status_show(struct gfs2_sbd *sdp, char *buf) +{ + unsigned long f = sdp->sd_flags; + int trans1, ail11, ail12, trans2, ail21, ail22; + unsigned int revokes; + ssize_t s; + + trans1 = count_trans_list(sdp, &sdp->sd_ail1_list, &ail11, &ail12); + trans2 = count_trans_list(sdp, &sdp->sd_ail2_list, &ail21, &ail22); + revokes = count_list(sdp, &sdp->sd_log_revokes); + s= snprintf(buf, PAGE_SIZE, + "Journal Checked: %d\n" + "Journal Live: %d\n" + "Withdrawn: %d\n" + "No barriers: %d\n" + "No recovery: %d\n" + "Demote: %d\n" + "No Journal ID: %d\n" + "RO Recovery: %d\n" + "Skip DLM Unlock: %d\n" + "Force AIL Flush: %d\n" + "FS Frozen: %d\n" + "Withdrawing: %d\n" + "Withdraw In Prog: %d\n" + "Remote Withdraw: %d\n" + "Withdraw Recovery: %d\n" + "sd_log_lock held: %d\n" + "statfs_spin held: %d\n" + "sd_rindex_spin: %d\n" + "sd_jindex_spin: %d\n" + "sd_trunc_lock: %d\n" + "sd_bitmap_lock: %d\n" + "sd_ordered_lock: %d\n" + "sd_ail_lock: %d\n" + "sd_log_error: %d\n" + "sd_log_flush_lock: %d\n" + "sd_ail1_list: %d transactions, %d ail1, %d ail2\n" + "sd_ail2_list: %d transactions, %d ail1, %d ail2\n" + "sd_log_revokes: %d / %u\n" + "sd_log_in_flight: %d\n", + test_bit(SDF_JOURNAL_CHECKED, &f), + test_bit(SDF_JOURNAL_LIVE, &f), + test_bit(SDF_WITHDRAWN, &f), + test_bit(SDF_NOBARRIERS, &f), + test_bit(SDF_NORECOVERY, &f), + test_bit(SDF_DEMOTE, &f), + test_bit(SDF_NOJOURNALID, &f), + test_bit(SDF_RORECOVERY, &f), + test_bit(SDF_SKIP_DLM_UNLOCK, &f), + test_bit(SDF_FORCE_AIL_FLUSH, &f), + test_bit(SDF_FS_FROZEN, &f), + test_bit(SDF_WITHDRAWING, &f), + test_bit(SDF_WITHDRAW_IN_PROG, &f), + test_bit(SDF_REMOTE_WITHDRAW, &f), + test_bit(SDF_WITHDRAW_RECOVERY, &f), + spin_is_locked(&sdp->sd_log_lock), + spin_is_locked(&sdp->sd_statfs_spin), + spin_is_locked(&sdp->sd_rindex_spin), + spin_is_locked(&sdp->sd_jindex_spin), + spin_is_locked(&sdp->sd_trunc_lock), + spin_is_locked(&sdp->sd_bitmap_lock), + spin_is_locked(&sdp->sd_ordered_lock), + spin_is_locked(&sdp->sd_ail_lock), + sdp->sd_log_error, + rwsem_is_locked(&sdp->sd_log_flush_lock), + trans1, ail11, ail12, + trans2, ail21, ail22, + revokes, sdp->sd_log_num_revoke, + atomic_read(&sdp->sd_log_in_flight)); + return s; +} + static ssize_t fsname_show(struct gfs2_sbd *sdp, char *buf) { return snprintf(buf, PAGE_SIZE, "%s\n", sdp->sd_fsname); @@ -283,6 +394,7 @@ GFS2_ATTR(quota_sync, 0200, NULL, quota_sync_store); GFS2_ATTR(quota_refresh_user, 0200, NULL, quota_refresh_user_store); GFS2_ATTR(quota_refresh_group, 0200, NULL, quota_refresh_group_store); GFS2_ATTR(demote_rq, 0200, NULL, demote_rq_store); +GFS2_ATTR(status, 0444, status_show, NULL); static struct attribute *gfs2_attrs[] = { &gfs2_attr_id.attr, @@ -295,6 +407,7 @@ static struct attribute *gfs2_attrs[] = { &gfs2_attr_quota_refresh_user.attr, &gfs2_attr_quota_refresh_group.attr, &gfs2_attr_demote_rq.attr, + &gfs2_attr_status.attr, NULL, }; ATTRIBUTE_GROUPS(gfs2); -- 2.26.2