block: make queue stat accounting a reference
[linux-2.6-block.git] / block / blk-stat.c
index efb2a80db90616bbcd3130dd6fc5c7fc0c85f6fb..2ea01b5c1aca0437e6c48444f0d3571f99735f1f 100644 (file)
@@ -15,7 +15,7 @@
 struct blk_queue_stats {
        struct list_head callbacks;
        spinlock_t lock;
-       bool enable_accounting;
+       int accounting;
 };
 
 void blk_rq_stat_init(struct blk_rq_stat *stat)
@@ -161,7 +161,7 @@ void blk_stat_remove_callback(struct request_queue *q,
 
        spin_lock_irqsave(&q->stats->lock, flags);
        list_del_rcu(&cb->list);
-       if (list_empty(&q->stats->callbacks) && !q->stats->enable_accounting)
+       if (list_empty(&q->stats->callbacks) && !q->stats->accounting)
                blk_queue_flag_clear(QUEUE_FLAG_STATS, q);
        spin_unlock_irqrestore(&q->stats->lock, flags);
 
@@ -184,13 +184,24 @@ void blk_stat_free_callback(struct blk_stat_callback *cb)
                call_rcu(&cb->rcu, blk_stat_free_callback_rcu);
 }
 
+void blk_stat_disable_accounting(struct request_queue *q)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&q->stats->lock, flags);
+       if (!--q->stats->accounting)
+               blk_queue_flag_clear(QUEUE_FLAG_STATS, q);
+       spin_unlock_irqrestore(&q->stats->lock, flags);
+}
+EXPORT_SYMBOL_GPL(blk_stat_disable_accounting);
+
 void blk_stat_enable_accounting(struct request_queue *q)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&q->stats->lock, flags);
-       q->stats->enable_accounting = true;
-       blk_queue_flag_set(QUEUE_FLAG_STATS, q);
+       if (!q->stats->accounting++)
+               blk_queue_flag_set(QUEUE_FLAG_STATS, q);
        spin_unlock_irqrestore(&q->stats->lock, flags);
 }
 EXPORT_SYMBOL_GPL(blk_stat_enable_accounting);
@@ -205,7 +216,7 @@ struct blk_queue_stats *blk_alloc_queue_stats(void)
 
        INIT_LIST_HEAD(&stats->callbacks);
        spin_lock_init(&stats->lock);
-       stats->enable_accounting = false;
+       stats->accounting = 0;
 
        return stats;
 }