diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-11-10 03:10:44 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-10 03:10:44 -0500 |
commit | a5a64498c194c82ecad3a2d67cff6231cda8d3dd (patch) | |
tree | 723d5d81419f9960b8d30ed9a2ece8a58d6c4328 /fs/jbd2 | |
parent | bb93d802ae5c1949977cc6da247b218240677f11 (diff) | |
parent | f7160c7573615ec82c691e294cf80d920b5d588d (diff) |
Merge commit 'v2.6.28-rc4' into timers/rtc
Conflicts:
drivers/rtc/rtc-cmos.c
Diffstat (limited to 'fs/jbd2')
-rw-r--r-- | fs/jbd2/Kconfig | 33 | ||||
-rw-r--r-- | fs/jbd2/checkpoint.c | 32 | ||||
-rw-r--r-- | fs/jbd2/commit.c | 8 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 2 |
4 files changed, 64 insertions, 11 deletions
diff --git a/fs/jbd2/Kconfig b/fs/jbd2/Kconfig new file mode 100644 index 000000000000..f32f346f4b0a --- /dev/null +++ b/fs/jbd2/Kconfig | |||
@@ -0,0 +1,33 @@ | |||
1 | config JBD2 | ||
2 | tristate | ||
3 | select CRC32 | ||
4 | help | ||
5 | This is a generic journaling layer for block devices that support | ||
6 | both 32-bit and 64-bit block numbers. It is currently used by | ||
7 | the ext4 and OCFS2 filesystems, but it could also be used to add | ||
8 | journal support to other file systems or block devices such | ||
9 | as RAID or LVM. | ||
10 | |||
11 | If you are using ext4 or OCFS2, you need to say Y here. | ||
12 | If you are not using ext4 or OCFS2 then you will | ||
13 | probably want to say N. | ||
14 | |||
15 | To compile this device as a module, choose M here. The module will be | ||
16 | called jbd2. If you are compiling ext4 or OCFS2 into the kernel, | ||
17 | you cannot compile this code as a module. | ||
18 | |||
19 | config JBD2_DEBUG | ||
20 | bool "JBD2 (ext4) debugging support" | ||
21 | depends on JBD2 && DEBUG_FS | ||
22 | help | ||
23 | If you are using the ext4 journaled file system (or | ||
24 | potentially any other filesystem/device using JBD2), this option | ||
25 | allows you to enable debugging output while the system is running, | ||
26 | in order to help track down any problems you are having. | ||
27 | By default, the debugging output will be turned off. | ||
28 | |||
29 | If you select Y here, then you will be able to turn on debugging | ||
30 | with "echo N > /sys/kernel/debug/jbd2/jbd2-debug", where N is a | ||
31 | number between 1 and 5. The higher the number, the more debugging | ||
32 | output is generated. To turn debugging off again, do | ||
33 | "echo 0 > /sys/kernel/debug/jbd2/jbd2-debug". | ||
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 9203c3332f17..9497718fe920 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c | |||
@@ -116,7 +116,7 @@ static int __try_to_free_cp_buf(struct journal_head *jh) | |||
116 | */ | 116 | */ |
117 | void __jbd2_log_wait_for_space(journal_t *journal) | 117 | void __jbd2_log_wait_for_space(journal_t *journal) |
118 | { | 118 | { |
119 | int nblocks; | 119 | int nblocks, space_left; |
120 | assert_spin_locked(&journal->j_state_lock); | 120 | assert_spin_locked(&journal->j_state_lock); |
121 | 121 | ||
122 | nblocks = jbd_space_needed(journal); | 122 | nblocks = jbd_space_needed(journal); |
@@ -129,25 +129,43 @@ void __jbd2_log_wait_for_space(journal_t *journal) | |||
129 | /* | 129 | /* |
130 | * Test again, another process may have checkpointed while we | 130 | * Test again, another process may have checkpointed while we |
131 | * were waiting for the checkpoint lock. If there are no | 131 | * were waiting for the checkpoint lock. If there are no |
132 | * outstanding transactions there is nothing to checkpoint and | 132 | * transactions ready to be checkpointed, try to recover |
133 | * we can't make progress. Abort the journal in this case. | 133 | * journal space by calling cleanup_journal_tail(), and if |
134 | * that doesn't work, by waiting for the currently committing | ||
135 | * transaction to complete. If there is absolutely no way | ||
136 | * to make progress, this is either a BUG or corrupted | ||
137 | * filesystem, so abort the journal and leave a stack | ||
138 | * trace for forensic evidence. | ||
134 | */ | 139 | */ |
135 | spin_lock(&journal->j_state_lock); | 140 | spin_lock(&journal->j_state_lock); |
136 | spin_lock(&journal->j_list_lock); | 141 | spin_lock(&journal->j_list_lock); |
137 | nblocks = jbd_space_needed(journal); | 142 | nblocks = jbd_space_needed(journal); |
138 | if (__jbd2_log_space_left(journal) < nblocks) { | 143 | space_left = __jbd2_log_space_left(journal); |
144 | if (space_left < nblocks) { | ||
139 | int chkpt = journal->j_checkpoint_transactions != NULL; | 145 | int chkpt = journal->j_checkpoint_transactions != NULL; |
146 | tid_t tid = 0; | ||
140 | 147 | ||
148 | if (journal->j_committing_transaction) | ||
149 | tid = journal->j_committing_transaction->t_tid; | ||
141 | spin_unlock(&journal->j_list_lock); | 150 | spin_unlock(&journal->j_list_lock); |
142 | spin_unlock(&journal->j_state_lock); | 151 | spin_unlock(&journal->j_state_lock); |
143 | if (chkpt) { | 152 | if (chkpt) { |
144 | jbd2_log_do_checkpoint(journal); | 153 | jbd2_log_do_checkpoint(journal); |
154 | } else if (jbd2_cleanup_journal_tail(journal) == 0) { | ||
155 | /* We were able to recover space; yay! */ | ||
156 | ; | ||
157 | } else if (tid) { | ||
158 | jbd2_log_wait_commit(journal, tid); | ||
145 | } else { | 159 | } else { |
146 | printk(KERN_ERR "%s: no transactions\n", | 160 | printk(KERN_ERR "%s: needed %d blocks and " |
147 | __func__); | 161 | "only had %d space available\n", |
162 | __func__, nblocks, space_left); | ||
163 | printk(KERN_ERR "%s: no way to get more " | ||
164 | "journal space in %s\n", __func__, | ||
165 | journal->j_devname); | ||
166 | WARN_ON(1); | ||
148 | jbd2_journal_abort(journal, 0); | 167 | jbd2_journal_abort(journal, 0); |
149 | } | 168 | } |
150 | |||
151 | spin_lock(&journal->j_state_lock); | 169 | spin_lock(&journal->j_state_lock); |
152 | } else { | 170 | } else { |
153 | spin_unlock(&journal->j_list_lock); | 171 | spin_unlock(&journal->j_list_lock); |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 8b119e16aa36..ebc667bc54a8 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -974,6 +974,9 @@ restart_loop: | |||
974 | journal->j_committing_transaction = NULL; | 974 | journal->j_committing_transaction = NULL; |
975 | spin_unlock(&journal->j_state_lock); | 975 | spin_unlock(&journal->j_state_lock); |
976 | 976 | ||
977 | if (journal->j_commit_callback) | ||
978 | journal->j_commit_callback(journal, commit_transaction); | ||
979 | |||
977 | if (commit_transaction->t_checkpoint_list == NULL && | 980 | if (commit_transaction->t_checkpoint_list == NULL && |
978 | commit_transaction->t_checkpoint_io_list == NULL) { | 981 | commit_transaction->t_checkpoint_io_list == NULL) { |
979 | __jbd2_journal_drop_transaction(journal, commit_transaction); | 982 | __jbd2_journal_drop_transaction(journal, commit_transaction); |
@@ -995,11 +998,8 @@ restart_loop: | |||
995 | } | 998 | } |
996 | spin_unlock(&journal->j_list_lock); | 999 | spin_unlock(&journal->j_list_lock); |
997 | 1000 | ||
998 | if (journal->j_commit_callback) | ||
999 | journal->j_commit_callback(journal, commit_transaction); | ||
1000 | |||
1001 | trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", | 1001 | trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", |
1002 | journal->j_devname, commit_transaction->t_tid, | 1002 | journal->j_devname, journal->j_commit_sequence, |
1003 | journal->j_tail_sequence); | 1003 | journal->j_tail_sequence); |
1004 | jbd_debug(1, "JBD: commit %d complete, head %d\n", | 1004 | jbd_debug(1, "JBD: commit %d complete, head %d\n", |
1005 | journal->j_commit_sequence, journal->j_tail_sequence); | 1005 | journal->j_commit_sequence, journal->j_tail_sequence); |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 783de118de92..e70d657a19f8 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -1089,6 +1089,7 @@ journal_t * jbd2_journal_init_inode (struct inode *inode) | |||
1089 | if (!journal->j_wbuf) { | 1089 | if (!journal->j_wbuf) { |
1090 | printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", | 1090 | printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", |
1091 | __func__); | 1091 | __func__); |
1092 | jbd2_stats_proc_exit(journal); | ||
1092 | kfree(journal); | 1093 | kfree(journal); |
1093 | return NULL; | 1094 | return NULL; |
1094 | } | 1095 | } |
@@ -1098,6 +1099,7 @@ journal_t * jbd2_journal_init_inode (struct inode *inode) | |||
1098 | if (err) { | 1099 | if (err) { |
1099 | printk(KERN_ERR "%s: Cannnot locate journal superblock\n", | 1100 | printk(KERN_ERR "%s: Cannnot locate journal superblock\n", |
1100 | __func__); | 1101 | __func__); |
1102 | jbd2_stats_proc_exit(journal); | ||
1101 | kfree(journal); | 1103 | kfree(journal); |
1102 | return NULL; | 1104 | return NULL; |
1103 | } | 1105 | } |