Jens Axboe wrote:
>
> ...
> Thank you, this is what I was looking for (if you look further up, I was
> advocating this very thing). Slimming down buffer_head and just add the
> ext3 hack is perfectly acceptable to me.
>
> Which just means that device mapper needs to do the stacking properly,
> EOD.
>
Here it is. We can slot this into 2.4.20-pre, or Joe can own
it. Any preferences?
fs/buffer.c | 21 ++++++++++++---------
fs/jbd/journal.c | 14 +++++++-------
include/linux/fs.h | 19 +++++++++++++++++--
include/linux/jbd.h | 2 +-
4 files changed, 37 insertions(+), 19 deletions(-)
--- 2.4.19-rc1/fs/buffer.c~ext3-journal-head Thu Jul 4 02:25:17 2002
+++ 2.4.19-rc1-akpm/fs/buffer.c Thu Jul 4 02:36:06 2002
@@ -587,9 +587,10 @@ struct buffer_head * get_hash_table(kdev
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);
}
@@ -597,9 +598,10 @@ void buffer_insert_inode_queue(struct bu
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);
}
@@ -608,13 +610,13 @@ void buffer_insert_inode_data_queue(stru
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);
}
@@ -746,6 +748,7 @@ void init_buffer(struct buffer_head *bh,
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)
@@ -843,9 +846,9 @@ int fsync_buffers_list(struct list_head
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);
@@ -1129,7 +1132,7 @@ struct buffer_head * bread(kdev_t dev, i
*/
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);
--- 2.4.19-rc1/include/linux/fs.h~ext3-journal-head Thu Jul 4 02:25:17 2002
+++ 2.4.19-rc1-akpm/include/linux/fs.h Thu Jul 4 02:25:17 2002
@@ -219,6 +219,7 @@ enum bh_state_bits {
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
@@ -261,11 +262,10 @@ struct buffer_head {
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 */
};
@@ -1181,6 +1181,21 @@ static inline void mark_buffer_async(str
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);
+}
+
/*
* If an error happens during the make_request, this function
* has to be recalled. It marks the buffer as clean and not
--- 2.4.19-rc1/fs/jbd/journal.c~ext3-journal-head Thu Jul 4 02:25:17 2002
+++ 2.4.19-rc1-akpm/fs/jbd/journal.c Thu Jul 4 02:25:17 2002
@@ -1625,8 +1625,8 @@ static void journal_free_journal_head(st
*
* 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.
*
@@ -1681,9 +1681,9 @@ struct journal_head *journal_add_journal
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
@@ -1691,7 +1691,7 @@ struct journal_head *journal_add_journal
*/
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);
@@ -1700,7 +1700,7 @@ struct journal_head *journal_add_journal
}
jh->b_jcount++;
spin_unlock(&journal_datalist_lock);
- return bh->b_private;
+ return bh->b_journal_head;
}
/*
@@ -1733,7 +1733,7 @@ void __journal_remove_journal_head(struc
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);
--- 2.4.19-rc1/include/linux/jbd.h~ext3-journal-head Thu Jul 4 02:25:17 2002
+++ 2.4.19-rc1-akpm/include/linux/jbd.h Thu Jul 4 02:26:29 2002
@@ -246,7 +246,7 @@ static inline struct buffer_head *jh2bh(
static inline struct journal_head *bh2jh(struct buffer_head *bh)
{
- return bh->b_private;
+ return bh->b_journal_head;
}
struct jbd_revoke_table_s;
-
Andrew,
On Thu, Jul 04, 2002 at 02:44:30AM -0700, Andrew Morton wrote:
> Here it is. We can slot this into 2.4.20-pre, or Joe can own
> it. Any preferences?
Thanks for doing this, I'll keep this with the device-mapper patches
for now.
- Joe