aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2/journal.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-07-11 19:27:31 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-07-11 19:27:31 -0400
commitc851ed540173736e60d48b53b91a16ea5c903896 (patch)
tree828fe0d71b7f18dc170090dbb2fb5ac9deae4ee0 /fs/jbd2/journal.c
parentf4c0a0fdfae708f7aa438c27a380ed4071294e11 (diff)
jbd2: Implement data=ordered mode handling via inodes
This patch adds necessary framework into JBD2 to be able to track inodes with each transaction and write-out their dirty data during transaction commit time. This new ordered mode brings all sorts of advantages such as possibility to get rid of journal heads and buffer heads for data buffers in ordered mode, better ordering of writes on transaction commit, simplification of some JBD code, no more anonymous pages when truncate of data being committed happens. Also with this new ordered mode, delayed allocation on ordered mode is much simpler. Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/jbd2/journal.c')
-rw-r--r--fs/jbd2/journal.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 2e24567c4a79..78cf7bd7f604 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -82,6 +82,10 @@ EXPORT_SYMBOL(jbd2_journal_blocks_per_page);
82EXPORT_SYMBOL(jbd2_journal_invalidatepage); 82EXPORT_SYMBOL(jbd2_journal_invalidatepage);
83EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers); 83EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers);
84EXPORT_SYMBOL(jbd2_journal_force_commit); 84EXPORT_SYMBOL(jbd2_journal_force_commit);
85EXPORT_SYMBOL(jbd2_journal_file_inode);
86EXPORT_SYMBOL(jbd2_journal_init_jbd_inode);
87EXPORT_SYMBOL(jbd2_journal_release_jbd_inode);
88EXPORT_SYMBOL(jbd2_journal_begin_ordered_truncate);
85 89
86static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); 90static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
87static void __journal_abort_soft (journal_t *journal, int errno); 91static void __journal_abort_soft (journal_t *journal, int errno);
@@ -2195,6 +2199,54 @@ void jbd2_journal_put_journal_head(struct journal_head *jh)
2195} 2199}
2196 2200
2197/* 2201/*
2202 * Initialize jbd inode head
2203 */
2204void jbd2_journal_init_jbd_inode(struct jbd2_inode *jinode, struct inode *inode)
2205{
2206 jinode->i_transaction = NULL;
2207 jinode->i_next_transaction = NULL;
2208 jinode->i_vfs_inode = inode;
2209 jinode->i_flags = 0;
2210 INIT_LIST_HEAD(&jinode->i_list);
2211}
2212
2213/*
2214 * Function to be called before we start removing inode from memory (i.e.,
2215 * clear_inode() is a fine place to be called from). It removes inode from
2216 * transaction's lists.
2217 */
2218void jbd2_journal_release_jbd_inode(journal_t *journal,
2219 struct jbd2_inode *jinode)
2220{
2221 int writeout = 0;
2222
2223 if (!journal)
2224 return;
2225restart:
2226 spin_lock(&journal->j_list_lock);
2227 /* Is commit writing out inode - we have to wait */
2228 if (jinode->i_flags & JI_COMMIT_RUNNING) {
2229 wait_queue_head_t *wq;
2230 DEFINE_WAIT_BIT(wait, &jinode->i_flags, __JI_COMMIT_RUNNING);
2231 wq = bit_waitqueue(&jinode->i_flags, __JI_COMMIT_RUNNING);
2232 prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE);
2233 spin_unlock(&journal->j_list_lock);
2234 schedule();
2235 finish_wait(wq, &wait.wait);
2236 goto restart;
2237 }
2238
2239 /* Do we need to wait for data writeback? */
2240 if (journal->j_committing_transaction == jinode->i_transaction)
2241 writeout = 1;
2242 if (jinode->i_transaction) {
2243 list_del(&jinode->i_list);
2244 jinode->i_transaction = NULL;
2245 }
2246 spin_unlock(&journal->j_list_lock);
2247}
2248
2249/*
2198 * debugfs tunables 2250 * debugfs tunables
2199 */ 2251 */
2200#ifdef CONFIG_JBD2_DEBUG 2252#ifdef CONFIG_JBD2_DEBUG