diff -ruN linux-2.4.20/fs/buffer.c linux/fs/buffer.c --- linux-2.4.20/fs/buffer.c Fri Jan 10 16:35:24 2003 +++ linux/fs/buffer.c Wed Mar 26 12:53:19 2003 @@ -586,9 +586,10 @@ void buffer_insert_inode_queue(struct buffer_head *bh, struct inode *inode) { spin_lock(&lru_list_lock); - if (bh->b_inode) + if (buffer_inode(bh)) list_del(&bh->b_inode_buffers); - bh->b_inode = inode; + else + set_buffer_inode(bh); list_add(&bh->b_inode_buffers, &inode->i_dirty_buffers); spin_unlock(&lru_list_lock); } @@ -596,9 +597,10 @@ void buffer_insert_inode_data_queue(struct buffer_head *bh, struct inode *inode) { spin_lock(&lru_list_lock); - if (bh->b_inode) + if (buffer_inode(bh)) list_del(&bh->b_inode_buffers); - bh->b_inode = inode; + else + set_buffer_inode(bh); list_add(&bh->b_inode_buffers, &inode->i_dirty_data_buffers); spin_unlock(&lru_list_lock); } @@ -607,13 +609,13 @@ remove_inode_queue functions. */ static void __remove_inode_queue(struct buffer_head *bh) { - bh->b_inode = NULL; + clear_buffer_inode(bh); list_del(&bh->b_inode_buffers); } static inline void remove_inode_queue(struct buffer_head *bh) { - if (bh->b_inode) + if (buffer_inode(bh)) __remove_inode_queue(bh); } @@ -741,6 +743,7 @@ bh->b_list = BUF_CLEAN; bh->b_end_io = handler; bh->b_private = private; + bh->b_journal_head = NULL; } static void end_buffer_io_async(struct buffer_head * bh, int uptodate) @@ -842,9 +845,9 @@ bh = BH_ENTRY(list->next); list_del(&bh->b_inode_buffers); if (!buffer_dirty(bh) && !buffer_locked(bh)) - bh->b_inode = NULL; + clear_buffer_inode(bh); else { - bh->b_inode = &tmp; + set_buffer_inode(bh); list_add(&bh->b_inode_buffers, &tmp.i_dirty_buffers); if (buffer_dirty(bh)) { get_bh(bh); @@ -1138,7 +1141,7 @@ */ static void __put_unused_buffer_head(struct buffer_head * bh) { - if (bh->b_inode) + if (buffer_inode(bh)) BUG(); if (nr_unused_buffer_heads >= MAX_UNUSED_BUFFERS) { kmem_cache_free(bh_cachep, bh); diff -ruN linux-2.4.20/fs/jbd/journal.c linux/fs/jbd/journal.c --- linux-2.4.20/fs/jbd/journal.c Fri Jan 10 16:35:27 2003 +++ linux/fs/jbd/journal.c Wed Mar 26 12:53:19 2003 @@ -1664,8 +1664,8 @@ * * Whenever a buffer has an attached journal_head, its ->b_state:BH_JBD bit * is set. This bit is tested in core kernel code where we need to take - * JBD-specific actions. Testing the zeroness of ->b_private is not reliable - * there. + * JBD-specific actions. Testing the zeroness of ->b_journal_head is not + * reliable there. * * When a buffer has its BH_JBD bit set, its ->b_count is elevated by one. * @@ -1720,9 +1720,9 @@ if (buffer_jbd(bh)) { /* Someone did it for us! */ - J_ASSERT_BH(bh, bh->b_private != NULL); + J_ASSERT_BH(bh, bh->b_journal_head != NULL); journal_free_journal_head(jh); - jh = bh->b_private; + jh = bh->b_journal_head; } else { /* * We actually don't need jh_splice_lock when @@ -1730,7 +1730,7 @@ */ spin_lock(&jh_splice_lock); set_bit(BH_JBD, &bh->b_state); - bh->b_private = jh; + bh->b_journal_head = jh; jh->b_bh = bh; atomic_inc(&bh->b_count); spin_unlock(&jh_splice_lock); @@ -1739,7 +1739,7 @@ } jh->b_jcount++; spin_unlock(&journal_datalist_lock); - return bh->b_private; + return bh->b_journal_head; } /* @@ -1772,7 +1772,7 @@ J_ASSERT_BH(bh, jh2bh(jh) == bh); BUFFER_TRACE(bh, "remove journal_head"); spin_lock(&jh_splice_lock); - bh->b_private = NULL; + bh->b_journal_head = NULL; jh->b_bh = NULL; /* debug, really */ clear_bit(BH_JBD, &bh->b_state); __brelse(bh); diff -ruN linux-2.4.20/include/linux/fs.h linux/include/linux/fs.h --- linux-2.4.20/include/linux/fs.h Fri Jan 10 16:35:55 2003 +++ linux/include/linux/fs.h Wed Mar 26 12:53:19 2003 @@ -220,6 +220,7 @@ BH_Wait_IO, /* 1 if we should write out this buffer */ BH_Launder, /* 1 if we can throttle on this buffer */ BH_JBD, /* 1 if it has an attached journal_head */ + BH_Inode, /* 1 if it is attached to i_dirty[_data]_buffers */ BH_PrivateStart,/* not a state bit, but the first bit available * for private allocation by other entities @@ -262,11 +263,10 @@ struct page *b_page; /* the page this bh is mapped to */ void (*b_end_io)(struct buffer_head *bh, int uptodate); /* I/O completion */ void *b_private; /* reserved for b_end_io */ - + void *b_journal_head; /* ext3 journal_heads */ unsigned long b_rsector; /* Real buffer location on disk */ wait_queue_head_t b_wait; - struct inode * b_inode; struct list_head b_inode_buffers; /* doubly linked list of inode dirty buffers */ }; @@ -1184,6 +1184,21 @@ set_bit(BH_Async, &bh->b_state); else clear_bit(BH_Async, &bh->b_state); +} + +static inline void set_buffer_inode(struct buffer_head *bh) +{ + set_bit(BH_Inode, &bh->b_state); +} + +static inline void clear_buffer_inode(struct buffer_head *bh) +{ + clear_bit(BH_Inode, &bh->b_state); +} + +static inline int buffer_inode(struct buffer_head *bh) +{ + return test_bit(BH_Inode, &bh->b_state); } /* diff -ruN linux-2.4.20/include/linux/jbd.h linux/include/linux/jbd.h --- linux-2.4.20/include/linux/jbd.h Fri Jan 10 16:35:55 2003 +++ linux/include/linux/jbd.h Wed Mar 26 12:53:19 2003 @@ -254,7 +254,7 @@ static inline struct journal_head *bh2jh(struct buffer_head *bh) { - return bh->b_private; + return bh->b_journal_head; } #define HAVE_JOURNAL_CALLBACK_STATUS