aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2012-08-18 23:58:53 +0900
committerDaniel Phillips <daniel@tux3.org>2012-08-18 23:58:53 +0900
commitdeb34e57842f4bb4ab3519f5f1e83e8d193e7a30 (patch)
tree1da70ad424be3bd63b79843c5ec5579db8425e10
parent06e69c0ad23b21a43a27fcfa0905ea2605c19d11 (diff)
downloadlinux-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.c32
-rw-r--r--fs/tux3/buffer.h5
-rw-r--r--fs/tux3/writeback.c32
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)