diff options
author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2012-08-18 23:58:53 +0900 |
---|---|---|
committer | Daniel Phillips <daniel@tux3.org> | 2012-08-18 23:58:53 +0900 |
commit | deb34e57842f4bb4ab3519f5f1e83e8d193e7a30 (patch) | |
tree | 1da70ad424be3bd63b79843c5ec5579db8425e10 | |
parent | 06e69c0ad23b21a43a27fcfa0905ea2605c19d11 (diff) | |
download | linux-tux3-deb34e57842f4bb4ab3519f5f1e83e8d193e7a30.tar.gz |
tux3: Add/rename helpers to manage dirty buffers
1) Instead of set_buffer_dirty_when(), this adds
tux3_set_buffer_dirty_list(). This takes "delta" and "list_head"
parameter to manage buffer in tux3.
2) Add tux3_set_buffer_dirty() (note: set_buffer_dirty() is already
used in kernel). This helper to insert the buffer to inode's dirty
heads.
Tux3 will use those 2 functions to manage dirty buffers.
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
-rw-r--r-- | fs/tux3/buffer.c | 32 | ||||
-rw-r--r-- | fs/tux3/buffer.h | 5 | ||||
-rw-r--r-- | fs/tux3/writeback.c | 32 |
3 files changed, 62 insertions, 7 deletions
diff --git a/fs/tux3/buffer.c b/fs/tux3/buffer.c index 338e9291ad068f..b7e211461e23fa 100644 --- a/fs/tux3/buffer.c +++ b/fs/tux3/buffer.c @@ -8,13 +8,35 @@ #define trace trace_on #endif -void set_buffer_state_list(struct buffer_head *buffer, unsigned state, - struct list_head *list) +/* FIXME: we should rewrite with own buffer management */ +void tux3_set_buffer_dirty_list(struct buffer_head *buffer, int delta, + struct list_head *head) { - /* FIXME: this would be broken */ - assert(state >= BUFFER_DIRTY); - list_move_tail(&buffer->b_assoc_buffers, list); + struct inode *inode = buffer_inode(buffer); + struct address_space *mapping = inode->i_mapping; + struct address_space *buffer_mapping = buffer->b_page->mapping; + mark_buffer_dirty(buffer); + + if (!mapping->assoc_mapping) + mapping->assoc_mapping = buffer_mapping; + else + BUG_ON(mapping->assoc_mapping != buffer_mapping); + + if (!buffer->b_assoc_map) { + spin_lock(&buffer_mapping->private_lock); + list_move_tail(&buffer->b_assoc_buffers, head); + buffer->b_assoc_map = mapping; + spin_unlock(&buffer_mapping->private_lock); + } +} + +/* FIXME: we should rewrite with own buffer management */ +void tux3_set_buffer_dirty(struct buffer_head *buffer, int delta) +{ + struct dirty_buffers *dirty = inode_dirty_heads(buffer_inode(buffer)); + struct list_head *head = dirty_head_when(dirty, delta); + tux3_set_buffer_dirty_list(buffer, delta, head); } void init_dirty_buffers(struct dirty_buffers *dirty) diff --git a/fs/tux3/buffer.h b/fs/tux3/buffer.h index e2b1e087a5c305..f55cd091bcdf85 100644 --- a/fs/tux3/buffer.h +++ b/fs/tux3/buffer.h @@ -38,8 +38,9 @@ static inline int buffer_can_modify(struct buffer_head *buffer, unsigned delta) return buffer_dirty(buffer); } -void set_buffer_state_list(struct buffer_head *buffer, unsigned state, - struct list_head *list); +void tux3_set_buffer_dirty_list(struct buffer_head *buffer, int delta, + struct list_head *head); +void tux3_set_buffer_dirty(struct buffer_head *buffer, int delta); void init_dirty_buffers(struct dirty_buffers *dirty); #endif /* !__KERNEL__ */ #endif /* !TUX3_BUFFER_H */ diff --git a/fs/tux3/writeback.c b/fs/tux3/writeback.c index 73474bb17e38b3..a79d7de84b6f54 100644 --- a/fs/tux3/writeback.c +++ b/fs/tux3/writeback.c @@ -3,17 +3,49 @@ */ #include "tux3.h" +#include "buffer.h" #ifndef trace #define trace trace_on #endif +/* FIXME: we should rewrite with own buffer management. */ void tux3_mark_buffer_dirty(struct buffer_head *buffer) { + /* + * Very *carefully* optimize the it-is-already-dirty case. + * + * Don't let the final "is it dirty" escape to before we + * perhaps modified the buffer. + */ + if (buffer_dirty(buffer)) { + smp_mb(); + if (buffer_dirty(buffer)) + return; + } + + tux3_set_buffer_dirty(buffer, DEFAULT_DIRTY_WHEN); } +/* FIXME: we should rewrite with own buffer management. */ void tux3_mark_buffer_rollup(struct buffer_head *buffer) { + struct sb *sb = tux_sb(buffer_inode(buffer)->i_sb); + + /* + * Very *carefully* optimize the it-is-already-dirty case. + * + * Don't let the final "is it dirty" escape to before we + * perhaps modified the buffer. + */ + if (buffer_dirty(buffer)) { + smp_mb(); + if (buffer_dirty(buffer)) + return; + } + + tux3_set_buffer_dirty_list(buffer, sb->rollup, + dirty_head_when(&sb->pinned, sb->rollup)); } int tux3_flush_inode(struct inode *inode, unsigned delta) |