]> err.no Git - linux-2.6/blobdiff - fs/buffer.c
[PATCH] alloc_buffer_head() and free_buffer_head() cleanup
[linux-2.6] / fs / buffer.c
index 561e63a149667abafef2c92aabe287e0eae2f27d..a92b814035528e2d7787ef342a842f3e5fb906ef 100644 (file)
@@ -513,8 +513,8 @@ static void free_more_memory(void)
  */
 static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
 {
-       static DEFINE_SPINLOCK(page_uptodate_lock);
        unsigned long flags;
+       struct buffer_head *first;
        struct buffer_head *tmp;
        struct page *page;
        int page_uptodate = 1;
@@ -536,7 +536,9 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
         * two buffer heads end IO at almost the same time and both
         * decide that the page is now completely done.
         */
-       spin_lock_irqsave(&page_uptodate_lock, flags);
+       first = page_buffers(page);
+       local_irq_save(flags);
+       bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
        clear_buffer_async_read(bh);
        unlock_buffer(bh);
        tmp = bh;
@@ -549,7 +551,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
                }
                tmp = tmp->b_this_page;
        } while (tmp != bh);
-       spin_unlock_irqrestore(&page_uptodate_lock, flags);
+       bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
+       local_irq_restore(flags);
 
        /*
         * If none of the buffers had errors and they are all
@@ -561,7 +564,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
        return;
 
 still_busy:
-       spin_unlock_irqrestore(&page_uptodate_lock, flags);
+       bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
+       local_irq_restore(flags);
        return;
 }
 
@@ -572,8 +576,8 @@ still_busy:
 void end_buffer_async_write(struct buffer_head *bh, int uptodate)
 {
        char b[BDEVNAME_SIZE];
-       static DEFINE_SPINLOCK(page_uptodate_lock);
        unsigned long flags;
+       struct buffer_head *first;
        struct buffer_head *tmp;
        struct page *page;
 
@@ -594,7 +598,10 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate)
                SetPageError(page);
        }
 
-       spin_lock_irqsave(&page_uptodate_lock, flags);
+       first = page_buffers(page);
+       local_irq_save(flags);
+       bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
+
        clear_buffer_async_write(bh);
        unlock_buffer(bh);
        tmp = bh->b_this_page;
@@ -605,12 +612,14 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate)
                }
                tmp = tmp->b_this_page;
        }
-       spin_unlock_irqrestore(&page_uptodate_lock, flags);
+       bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
+       local_irq_restore(flags);
        end_page_writeback(page);
        return;
 
 still_busy:
-       spin_unlock_irqrestore(&page_uptodate_lock, flags);
+       bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
+       local_irq_restore(flags);
        return;
 }
 
@@ -3037,10 +3046,9 @@ struct buffer_head *alloc_buffer_head(unsigned int __nocast gfp_flags)
 {
        struct buffer_head *ret = kmem_cache_alloc(bh_cachep, gfp_flags);
        if (ret) {
-               preempt_disable();
-               __get_cpu_var(bh_accounting).nr++;
+               get_cpu_var(bh_accounting).nr++;
                recalc_bh_state();
-               preempt_enable();
+               put_cpu_var(bh_accounting);
        }
        return ret;
 }
@@ -3050,10 +3058,9 @@ void free_buffer_head(struct buffer_head *bh)
 {
        BUG_ON(!list_empty(&bh->b_assoc_buffers));
        kmem_cache_free(bh_cachep, bh);
-       preempt_disable();
-       __get_cpu_var(bh_accounting).nr--;
+       get_cpu_var(bh_accounting).nr--;
        recalc_bh_state();
-       preempt_enable();
+       put_cpu_var(bh_accounting);
 }
 EXPORT_SYMBOL(free_buffer_head);