Keep stats on the size of the ordered list and keep track of
where it's added to and removed from
---
 fs/gfs2/bmap.c       |  2 +-
 fs/gfs2/file.c       |  2 +-
 fs/gfs2/incore.h     | 12 ++++++++++++
 fs/gfs2/log.c        |  7 +++++--
 fs/gfs2/log.h        | 35 +++++++++++++++++++++++++++++++++--
 fs/gfs2/ops_fstype.c |  1 +
 fs/gfs2/quota.c      |  8 ++++++++
 fs/gfs2/super.c      |  2 +-
 8 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 8569bf3..d9720ce 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -1504,7 +1504,7 @@ static int trunc_end(struct gfs2_inode *ip)
                ip->i_height = 0;
                ip->i_goal = ip->i_no_addr;
                gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
-               gfs2_ordered_del_inode(ip);
+               gfs2_ordered_del_inode(ip, ORD_WHENCE_TRUNC);
        }
        ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
        ip->i_diskflags &= ~GFS2_DIF_TRUNC_IN_PROG;
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 31b5986..757ec66 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -284,7 +284,7 @@ static int do_gfs2_set_flags(struct file *filp, u32 
reqflags, u32 mask)
                if (error)
                        goto out;
                if (new_flags & GFS2_DIF_JDATA)
-                       gfs2_ordered_del_inode(ip);
+                       gfs2_ordered_del_inode(ip, ORD_WHENCE_SETFLAGS);
        }
        error = gfs2_trans_begin(sdp, RES_DINODE, 0);
        if (error)
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 7e78d8a..6fcad2a 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -655,6 +655,17 @@ struct gfs2_pcpu_lkstats {
        struct gfs2_lkstats lkstats[10];
 };
 
+struct ord_stats {
+       unsigned long os_ct;
+       unsigned long os_add;
+       unsigned long os_rm_trunc;
+       unsigned long os_rm_evict;
+       unsigned long os_rm_wait;
+       unsigned long os_rm_syncfs;
+       unsigned long os_rm_write;
+       unsigned long os_rm_setflags;
+};
+
 struct gfs2_sbd {
        struct super_block *sd_vfs;
        struct gfs2_pcpu_lkstats __percpu *sd_lkstats;
@@ -773,6 +784,7 @@ struct gfs2_sbd {
 
        struct list_head sd_log_le_revoke;
        struct list_head sd_log_le_ordered;
+       struct ord_stats sd_ord_stats;
        spinlock_t sd_ordered_lock;
 
        atomic_t sd_log_thresh1;
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index cc3f7d1..0257704 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -526,6 +526,7 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp)
        while (!list_empty(&sdp->sd_log_le_ordered)) {
                ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, 
i_ordered);
                list_del(&ip->i_ordered);
+               ord_stats_adjust(sdp, -1, ORD_WHENCE_WAIT);
                WARN_ON(!test_and_clear_bit(GIF_ORDERED, &ip->i_flags));
                if (ip->i_inode.i_mapping->nrpages == 0)
                        continue;
@@ -536,13 +537,15 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp)
        spin_unlock(&sdp->sd_ordered_lock);
 }
 
-void gfs2_ordered_del_inode(struct gfs2_inode *ip)
+void gfs2_ordered_del_inode(struct gfs2_inode *ip, int whence)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 
        spin_lock(&sdp->sd_ordered_lock);
-       if (test_and_clear_bit(GIF_ORDERED, &ip->i_flags))
+       if (test_and_clear_bit(GIF_ORDERED, &ip->i_flags)) {
                list_del(&ip->i_ordered);
+               ord_stats_adjust(sdp, -1, whence);
+       }
        spin_unlock(&sdp->sd_ordered_lock);
 }
 
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h
index 3721663..bf7729c 100644
--- a/fs/gfs2/log.h
+++ b/fs/gfs2/log.h
@@ -48,18 +48,49 @@ static inline void gfs2_log_pointers_init(struct gfs2_sbd 
*sdp,
        sdp->sd_log_head = sdp->sd_log_tail = value;
 }
 
+enum {
+       ORD_WHENCE_TRUNC        = 0,
+       ORD_WHENCE_EVICT        = 1,
+       ORD_WHENCE_WAIT         = 2,
+       ORD_WHENCE_SYNCFS       = 3,
+       ORD_WHENCE_ORD_WRITE    = 4,
+       ORD_WHENCE_SETFLAGS     = 5,
+       ORD_WHENCE_ADD          = 6,
+};
+
+static inline void ord_stats_adjust(struct gfs2_sbd *sdp, int count, int 
whence)
+{
+       struct ord_stats *os = &sdp->sd_ord_stats;
+
+       os->os_ct += count;
+       switch (whence) {
+       case ORD_WHENCE_TRUNC:      os->os_rm_trunc += -(count); break;
+       case ORD_WHENCE_EVICT:      os->os_rm_evict += -(count); break;
+       case ORD_WHENCE_WAIT:       os->os_rm_wait += -(count); break;
+       case ORD_WHENCE_SYNCFS:     os->os_rm_syncfs += -(count); break;
+       case ORD_WHENCE_ORD_WRITE:  os->os_rm_write += -(count); break;
+       case ORD_WHENCE_SETFLAGS:   os->os_rm_setflags += -(count); break;
+
+       case ORD_WHENCE_ADD:        os->os_add += count; break;
+       default: break;
+       }
+}
+
 static inline void gfs2_ordered_add_inode(struct gfs2_inode *ip)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 
        if (!test_bit(GIF_ORDERED, &ip->i_flags)) {
                spin_lock(&sdp->sd_ordered_lock);
-               if (!test_and_set_bit(GIF_ORDERED, &ip->i_flags))
+               if (!test_and_set_bit(GIF_ORDERED, &ip->i_flags)) {
                        list_add(&ip->i_ordered, &sdp->sd_log_le_ordered);
+                       ord_stats_adjust(sdp, 1, ORD_WHENCE_ADD);
+               }
                spin_unlock(&sdp->sd_ordered_lock);
        }
 }
-extern void gfs2_ordered_del_inode(struct gfs2_inode *ip);
+
+extern void gfs2_ordered_del_inode(struct gfs2_inode *ip, int whence);
 extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,
                            unsigned int ssize);
 
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 228f38e..378f961 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -104,6 +104,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
        atomic_set(&sdp->sd_log_pinned, 0);
        INIT_LIST_HEAD(&sdp->sd_log_le_revoke);
        INIT_LIST_HEAD(&sdp->sd_log_le_ordered);
+       memset(&sdp->sd_ord_stats, 0, sizeof(struct ord_stats));
        spin_lock_init(&sdp->sd_ordered_lock);
 
        init_waitqueue_head(&sdp->sd_log_waitq);
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 3d5f868..66c5126 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1572,6 +1572,14 @@ int gfs2_quotad(void *data)
                else
                        t = 0;
                finish_wait(&sdp->sd_quota_wait, &wait);
+
+               printk(KERN_WARNING "Ord list Size:%lu +[add_inode:%lu] "
+                      "-[trunc:%lu evict:%lu wait:%lu syncfs:%lu ord_write:%lu"
+                      " setflags:%lu]\n", sdp->sd_ord_stats.os_ct,
+                      sdp->sd_ord_stats.os_add, sdp->sd_ord_stats.os_rm_trunc,
+                      sdp->sd_ord_stats.os_rm_evict, 
sdp->sd_ord_stats.os_rm_wait,
+                      sdp->sd_ord_stats.os_rm_syncfs, 
sdp->sd_ord_stats.os_rm_write,
+                      sdp->sd_ord_stats.os_rm_setflags);
        }
 
        return 0;
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 6d7fb54..ee15a50 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1641,7 +1641,7 @@ out:
        /* Case 3 starts here */
        truncate_inode_pages_final(&inode->i_data);
        gfs2_rsqa_delete(ip, NULL);
-       gfs2_ordered_del_inode(ip);
+       gfs2_ordered_del_inode(ip, ORD_WHENCE_EVICT);
        clear_inode(inode);
        gfs2_dir_hash_inval(ip);
        glock_clear_object(ip->i_gl, ip);
-- 
2.4.11

Reply via email to