diff --git a/fs/buffer.c b/fs/buffer.c index d2ee954..6a0159d 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -282,7 +282,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) */ first = page_buffers(page); local_irq_save(flags); - bit_spin_lock(BH_Uptodate_Lock, &first->b_state); + //bit_spin_lock(BH_Uptodate_Lock, &first->b_state); + spin_lock(&first->bh_uptodate_lock); clear_buffer_async_read(bh); unlock_buffer(bh); tmp = bh; @@ -295,7 +296,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) } tmp = tmp->b_this_page; } while (tmp != bh); - bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); + spin_unlock(&first->bh_uptodate_lock); + //bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); local_irq_restore(flags); /* @@ -308,7 +310,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) return; still_busy: - bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); + spin_unlock(&first->bh_uptodate_lock); + //bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); local_irq_restore(flags); return; } @@ -345,7 +348,8 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate) first = page_buffers(page); local_irq_save(flags); - bit_spin_lock(BH_Uptodate_Lock, &first->b_state); + //bit_spin_lock(BH_Uptodate_Lock, &first->b_state); + spin_lock(&first->bh_uptodate_lock); clear_buffer_async_write(bh); unlock_buffer(bh); @@ -357,13 +361,15 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate) } tmp = tmp->b_this_page; } - bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); + spin_unlock(&first->bh_uptodate_lock); + //bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); local_irq_restore(flags); end_page_writeback(page); return; still_busy: - bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); + spin_unlock(&first->bh_uptodate_lock); + //bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); local_irq_restore(flags); return; } @@ -1164,6 +1170,7 @@ void __bforget(struct buffer_head *bh) } EXPORT_SYMBOL(__bforget); + static struct buffer_head *__bread_slow(struct buffer_head *bh) { lock_buffer(bh); @@ -3185,6 +3192,15 @@ struct buffer_head *alloc_buffer_head(gfp_t gfp_flags) { struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags); if (ret) { + static struct lock_class_key bh_uptodate_class; + static struct lock_class_key bh_state_class; + static struct lock_class_key bh_journalhead_class; + spin_lock_init(&ret->bh_uptodate_lock); + spin_lock_init(&ret->bh_state_lock); + spin_lock_init(&ret->bh_journalhead_lock); + lockdep_set_class(&ret->bh_uptodate_lock, &bh_uptodate_class); + lockdep_set_class(&ret->bh_state_lock, &bh_state_class); + lockdep_set_class(&ret->bh_journalhead_lock, &bh_journalhead_class); INIT_LIST_HEAD(&ret->b_assoc_buffers); preempt_disable(); __this_cpu_inc(bh_accounting.nr); diff --git a/fs/next3/buffer.c b/fs/next3/buffer.c index 833ec16..2a114b9 100644 --- a/fs/next3/buffer.c +++ b/fs/next3/buffer.c @@ -253,7 +253,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) */ first = page_buffers(page); local_irq_save(flags); - bit_spin_lock(BH_Uptodate_Lock, &first->b_state); + //bit_spin_lock(BH_Uptodate_Lock, &first->b_state); + spin_lock(&first->bh_uptodate_lock); clear_buffer_async_read(bh); unlock_buffer(bh); tmp = bh; @@ -266,7 +267,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) } tmp = tmp->b_this_page; } while (tmp != bh); - bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); + spin_unlock(&first->bh_uptodate_lock); + //bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); local_irq_restore(flags); /* @@ -279,7 +281,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) return; still_busy: - bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); + spin_unlock(&first->bh_uptodate_lock); + //bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); local_irq_restore(flags); return; } diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 2f36652..bf3a682 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -72,6 +72,9 @@ struct buffer_head { struct address_space *b_assoc_map; /* mapping this buffer is associated with */ atomic_t b_count; /* users using this buffer_head */ + spinlock_t bh_uptodate_lock; + spinlock_t bh_state_lock; + spinlock_t bh_journalhead_lock; }; /* diff --git a/include/linux/jbd_common.h b/include/linux/jbd_common.h index 6230f85..ef65b9e 100644 --- a/include/linux/jbd_common.h +++ b/include/linux/jbd_common.h @@ -9,8 +9,8 @@ enum jbd_state_bits { BH_Revoked, /* Has been revoked from the log */ BH_RevokeValid, /* Revoked flag is valid */ BH_JBDDirty, /* Is dirty but journaled */ - BH_State, /* Pins most journal_head state */ - BH_JournalHead, /* Pins bh->b_private and jh->b_bh */ + //BH_State, /* Pins most journal_head state */ + //BH_JournalHead, /* Pins bh->b_private and jh->b_bh */ BH_Unshadow, /* Dummy bit, for BJ_Shadow wakeup filtering */ BH_JBDPrivateStart, /* First bit available for private use by FS */ }; @@ -37,32 +37,38 @@ static inline struct journal_head *bh2jh(struct buffer_head *bh) static inline void jbd_lock_bh_state(struct buffer_head *bh) { - bit_spin_lock(BH_State, &bh->b_state); + //bit_spin_lock(BH_State, &bh->b_state); + spin_lock(&bh->bh_state_lock); } static inline int jbd_trylock_bh_state(struct buffer_head *bh) { - return bit_spin_trylock(BH_State, &bh->b_state); + //return bit_spin_trylock(BH_State, &bh->b_state); + return spin_trylock(&bh->bh_state_lock); } static inline int jbd_is_locked_bh_state(struct buffer_head *bh) { - return bit_spin_is_locked(BH_State, &bh->b_state); + //return bit_spin_is_locked(BH_State, &bh->b_state); + return spin_is_locked(&bh->bh_state_lock); } static inline void jbd_unlock_bh_state(struct buffer_head *bh) { - bit_spin_unlock(BH_State, &bh->b_state); + //bit_spin_unlock(BH_State, &bh->b_state); + spin_unlock(&bh->bh_state_lock); } static inline void jbd_lock_bh_journal_head(struct buffer_head *bh) { - bit_spin_lock(BH_JournalHead, &bh->b_state); + //bit_spin_lock(BH_JournalHead, &bh->b_state); + spin_lock(&bh->bh_journalhead_lock); } static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh) { - bit_spin_unlock(BH_JournalHead, &bh->b_state); + //bit_spin_unlock(BH_JournalHead, &bh->b_state); + spin_unlock(&bh->bh_journalhead_lock); } #endif