diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-07 16:03:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-07 16:03:53 -0400 |
commit | 09dc942c2a767e2d298f1cc9294bc19c7d7208c5 (patch) | |
tree | d310c118467c90c264e953bdc320ae08394c662a /fs/jbd2/transaction.c | |
parent | 90e0c225968f0878e090c7ff3f88323973476cee (diff) | |
parent | 6c7a120ac6c62316ab1fc78dfc0a7b13f3bfcbff (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (40 commits)
ext4: Adding error check after calling ext4_mb_regular_allocator()
ext4: Fix dirtying of journalled buffers in data=journal mode
ext4: re-inline ext4_rec_len_(to|from)_disk functions
jbd2: Remove t_handle_lock from start_this_handle()
jbd2: Change j_state_lock to be a rwlock_t
jbd2: Use atomic variables to avoid taking t_handle_lock in jbd2_journal_stop
ext4: Add mount options in superblock
ext4: force block allocation on quota_off
ext4: fix freeze deadlock under IO
ext4: drop inode from orphan list if ext4_delete_inode() fails
ext4: check to make make sure bd_dev is set before dereferencing it
jbd2: Make barrier messages less scary
ext4: don't print scary messages for allocation failures post-abort
ext4: fix EFBIG edge case when writing to large non-extent file
ext4: fix ext4_get_blocks references
ext4: Always journal quota file modifications
ext4: Fix potential memory leak in ext4_fill_super
ext4: Don't error out the fs if the user tries to make a file too big
ext4: allocate stripe-multiple IOs on stripe boundaries
ext4: move aio completion after unwritten extent conversion
...
Fix up conflicts in fs/ext4/inode.c as per Ted.
Fix up xfs conflicts as per earlier xfs merge.
Diffstat (limited to 'fs/jbd2/transaction.c')
-rw-r--r-- | fs/jbd2/transaction.c | 233 |
1 files changed, 141 insertions, 92 deletions
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index b8e0806681bb..d95cc9d0401d 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
27 | #include <linux/highmem.h> | 27 | #include <linux/highmem.h> |
28 | #include <linux/hrtimer.h> | 28 | #include <linux/hrtimer.h> |
29 | #include <linux/backing-dev.h> | ||
30 | #include <linux/module.h> | ||
29 | 31 | ||
30 | static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh); | 32 | static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh); |
31 | 33 | ||
@@ -53,6 +55,9 @@ jbd2_get_transaction(journal_t *journal, transaction_t *transaction) | |||
53 | transaction->t_tid = journal->j_transaction_sequence++; | 55 | transaction->t_tid = journal->j_transaction_sequence++; |
54 | transaction->t_expires = jiffies + journal->j_commit_interval; | 56 | transaction->t_expires = jiffies + journal->j_commit_interval; |
55 | spin_lock_init(&transaction->t_handle_lock); | 57 | spin_lock_init(&transaction->t_handle_lock); |
58 | atomic_set(&transaction->t_updates, 0); | ||
59 | atomic_set(&transaction->t_outstanding_credits, 0); | ||
60 | atomic_set(&transaction->t_handle_count, 0); | ||
56 | INIT_LIST_HEAD(&transaction->t_inode_list); | 61 | INIT_LIST_HEAD(&transaction->t_inode_list); |
57 | INIT_LIST_HEAD(&transaction->t_private_list); | 62 | INIT_LIST_HEAD(&transaction->t_private_list); |
58 | 63 | ||
@@ -83,65 +88,75 @@ jbd2_get_transaction(journal_t *journal, transaction_t *transaction) | |||
83 | * transaction's buffer credits. | 88 | * transaction's buffer credits. |
84 | */ | 89 | */ |
85 | 90 | ||
86 | static int start_this_handle(journal_t *journal, handle_t *handle) | 91 | static int start_this_handle(journal_t *journal, handle_t *handle, |
92 | int gfp_mask) | ||
87 | { | 93 | { |
88 | transaction_t *transaction; | 94 | transaction_t *transaction; |
89 | int needed; | 95 | int needed; |
90 | int nblocks = handle->h_buffer_credits; | 96 | int nblocks = handle->h_buffer_credits; |
91 | transaction_t *new_transaction = NULL; | 97 | transaction_t *new_transaction = NULL; |
92 | int ret = 0; | ||
93 | unsigned long ts = jiffies; | 98 | unsigned long ts = jiffies; |
94 | 99 | ||
95 | if (nblocks > journal->j_max_transaction_buffers) { | 100 | if (nblocks > journal->j_max_transaction_buffers) { |
96 | printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n", | 101 | printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n", |
97 | current->comm, nblocks, | 102 | current->comm, nblocks, |
98 | journal->j_max_transaction_buffers); | 103 | journal->j_max_transaction_buffers); |
99 | ret = -ENOSPC; | 104 | return -ENOSPC; |
100 | goto out; | ||
101 | } | 105 | } |
102 | 106 | ||
103 | alloc_transaction: | 107 | alloc_transaction: |
104 | if (!journal->j_running_transaction) { | 108 | if (!journal->j_running_transaction) { |
105 | new_transaction = kzalloc(sizeof(*new_transaction), | 109 | new_transaction = kzalloc(sizeof(*new_transaction), gfp_mask); |
106 | GFP_NOFS|__GFP_NOFAIL); | ||
107 | if (!new_transaction) { | 110 | if (!new_transaction) { |
108 | ret = -ENOMEM; | 111 | /* |
109 | goto out; | 112 | * If __GFP_FS is not present, then we may be |
113 | * being called from inside the fs writeback | ||
114 | * layer, so we MUST NOT fail. Since | ||
115 | * __GFP_NOFAIL is going away, we will arrange | ||
116 | * to retry the allocation ourselves. | ||
117 | */ | ||
118 | if ((gfp_mask & __GFP_FS) == 0) { | ||
119 | congestion_wait(BLK_RW_ASYNC, HZ/50); | ||
120 | goto alloc_transaction; | ||
121 | } | ||
122 | return -ENOMEM; | ||
110 | } | 123 | } |
111 | } | 124 | } |
112 | 125 | ||
113 | jbd_debug(3, "New handle %p going live.\n", handle); | 126 | jbd_debug(3, "New handle %p going live.\n", handle); |
114 | 127 | ||
115 | repeat: | ||
116 | |||
117 | /* | 128 | /* |
118 | * We need to hold j_state_lock until t_updates has been incremented, | 129 | * We need to hold j_state_lock until t_updates has been incremented, |
119 | * for proper journal barrier handling | 130 | * for proper journal barrier handling |
120 | */ | 131 | */ |
121 | spin_lock(&journal->j_state_lock); | 132 | repeat: |
122 | repeat_locked: | 133 | read_lock(&journal->j_state_lock); |
123 | if (is_journal_aborted(journal) || | 134 | if (is_journal_aborted(journal) || |
124 | (journal->j_errno != 0 && !(journal->j_flags & JBD2_ACK_ERR))) { | 135 | (journal->j_errno != 0 && !(journal->j_flags & JBD2_ACK_ERR))) { |
125 | spin_unlock(&journal->j_state_lock); | 136 | read_unlock(&journal->j_state_lock); |
126 | ret = -EROFS; | 137 | kfree(new_transaction); |
127 | goto out; | 138 | return -EROFS; |
128 | } | 139 | } |
129 | 140 | ||
130 | /* Wait on the journal's transaction barrier if necessary */ | 141 | /* Wait on the journal's transaction barrier if necessary */ |
131 | if (journal->j_barrier_count) { | 142 | if (journal->j_barrier_count) { |
132 | spin_unlock(&journal->j_state_lock); | 143 | read_unlock(&journal->j_state_lock); |
133 | wait_event(journal->j_wait_transaction_locked, | 144 | wait_event(journal->j_wait_transaction_locked, |
134 | journal->j_barrier_count == 0); | 145 | journal->j_barrier_count == 0); |
135 | goto repeat; | 146 | goto repeat; |
136 | } | 147 | } |
137 | 148 | ||
138 | if (!journal->j_running_transaction) { | 149 | if (!journal->j_running_transaction) { |
139 | if (!new_transaction) { | 150 | read_unlock(&journal->j_state_lock); |
140 | spin_unlock(&journal->j_state_lock); | 151 | if (!new_transaction) |
141 | goto alloc_transaction; | 152 | goto alloc_transaction; |
153 | write_lock(&journal->j_state_lock); | ||
154 | if (!journal->j_running_transaction) { | ||
155 | jbd2_get_transaction(journal, new_transaction); | ||
156 | new_transaction = NULL; | ||
142 | } | 157 | } |
143 | jbd2_get_transaction(journal, new_transaction); | 158 | write_unlock(&journal->j_state_lock); |
144 | new_transaction = NULL; | 159 | goto repeat; |
145 | } | 160 | } |
146 | 161 | ||
147 | transaction = journal->j_running_transaction; | 162 | transaction = journal->j_running_transaction; |
@@ -155,7 +170,7 @@ repeat_locked: | |||
155 | 170 | ||
156 | prepare_to_wait(&journal->j_wait_transaction_locked, | 171 | prepare_to_wait(&journal->j_wait_transaction_locked, |
157 | &wait, TASK_UNINTERRUPTIBLE); | 172 | &wait, TASK_UNINTERRUPTIBLE); |
158 | spin_unlock(&journal->j_state_lock); | 173 | read_unlock(&journal->j_state_lock); |
159 | schedule(); | 174 | schedule(); |
160 | finish_wait(&journal->j_wait_transaction_locked, &wait); | 175 | finish_wait(&journal->j_wait_transaction_locked, &wait); |
161 | goto repeat; | 176 | goto repeat; |
@@ -166,8 +181,8 @@ repeat_locked: | |||
166 | * buffers requested by this operation, we need to stall pending a log | 181 | * buffers requested by this operation, we need to stall pending a log |
167 | * checkpoint to free some more log space. | 182 | * checkpoint to free some more log space. |
168 | */ | 183 | */ |
169 | spin_lock(&transaction->t_handle_lock); | 184 | needed = atomic_add_return(nblocks, |
170 | needed = transaction->t_outstanding_credits + nblocks; | 185 | &transaction->t_outstanding_credits); |
171 | 186 | ||
172 | if (needed > journal->j_max_transaction_buffers) { | 187 | if (needed > journal->j_max_transaction_buffers) { |
173 | /* | 188 | /* |
@@ -178,11 +193,11 @@ repeat_locked: | |||
178 | DEFINE_WAIT(wait); | 193 | DEFINE_WAIT(wait); |
179 | 194 | ||
180 | jbd_debug(2, "Handle %p starting new commit...\n", handle); | 195 | jbd_debug(2, "Handle %p starting new commit...\n", handle); |
181 | spin_unlock(&transaction->t_handle_lock); | 196 | atomic_sub(nblocks, &transaction->t_outstanding_credits); |
182 | prepare_to_wait(&journal->j_wait_transaction_locked, &wait, | 197 | prepare_to_wait(&journal->j_wait_transaction_locked, &wait, |
183 | TASK_UNINTERRUPTIBLE); | 198 | TASK_UNINTERRUPTIBLE); |
184 | __jbd2_log_start_commit(journal, transaction->t_tid); | 199 | __jbd2_log_start_commit(journal, transaction->t_tid); |
185 | spin_unlock(&journal->j_state_lock); | 200 | read_unlock(&journal->j_state_lock); |
186 | schedule(); | 201 | schedule(); |
187 | finish_wait(&journal->j_wait_transaction_locked, &wait); | 202 | finish_wait(&journal->j_wait_transaction_locked, &wait); |
188 | goto repeat; | 203 | goto repeat; |
@@ -215,35 +230,48 @@ repeat_locked: | |||
215 | */ | 230 | */ |
216 | if (__jbd2_log_space_left(journal) < jbd_space_needed(journal)) { | 231 | if (__jbd2_log_space_left(journal) < jbd_space_needed(journal)) { |
217 | jbd_debug(2, "Handle %p waiting for checkpoint...\n", handle); | 232 | jbd_debug(2, "Handle %p waiting for checkpoint...\n", handle); |
218 | spin_unlock(&transaction->t_handle_lock); | 233 | atomic_sub(nblocks, &transaction->t_outstanding_credits); |
219 | __jbd2_log_wait_for_space(journal); | 234 | read_unlock(&journal->j_state_lock); |
220 | goto repeat_locked; | 235 | write_lock(&journal->j_state_lock); |
236 | if (__jbd2_log_space_left(journal) < jbd_space_needed(journal)) | ||
237 | __jbd2_log_wait_for_space(journal); | ||
238 | write_unlock(&journal->j_state_lock); | ||
239 | goto repeat; | ||
221 | } | 240 | } |
222 | 241 | ||
223 | /* OK, account for the buffers that this operation expects to | 242 | /* OK, account for the buffers that this operation expects to |
224 | * use and add the handle to the running transaction. */ | 243 | * use and add the handle to the running transaction. |
225 | 244 | * | |
226 | if (time_after(transaction->t_start, ts)) { | 245 | * In order for t_max_wait to be reliable, it must be |
246 | * protected by a lock. But doing so will mean that | ||
247 | * start_this_handle() can not be run in parallel on SMP | ||
248 | * systems, which limits our scalability. So we only enable | ||
249 | * it when debugging is enabled. We may want to use a | ||
250 | * separate flag, eventually, so we can enable this | ||
251 | * independently of debugging. | ||
252 | */ | ||
253 | #ifdef CONFIG_JBD2_DEBUG | ||
254 | if (jbd2_journal_enable_debug && | ||
255 | time_after(transaction->t_start, ts)) { | ||
227 | ts = jbd2_time_diff(ts, transaction->t_start); | 256 | ts = jbd2_time_diff(ts, transaction->t_start); |
257 | spin_lock(&transaction->t_handle_lock); | ||
228 | if (ts > transaction->t_max_wait) | 258 | if (ts > transaction->t_max_wait) |
229 | transaction->t_max_wait = ts; | 259 | transaction->t_max_wait = ts; |
260 | spin_unlock(&transaction->t_handle_lock); | ||
230 | } | 261 | } |
231 | 262 | #endif | |
232 | handle->h_transaction = transaction; | 263 | handle->h_transaction = transaction; |
233 | transaction->t_outstanding_credits += nblocks; | 264 | atomic_inc(&transaction->t_updates); |
234 | transaction->t_updates++; | 265 | atomic_inc(&transaction->t_handle_count); |
235 | transaction->t_handle_count++; | ||
236 | jbd_debug(4, "Handle %p given %d credits (total %d, free %d)\n", | 266 | jbd_debug(4, "Handle %p given %d credits (total %d, free %d)\n", |
237 | handle, nblocks, transaction->t_outstanding_credits, | 267 | handle, nblocks, |
268 | atomic_read(&transaction->t_outstanding_credits), | ||
238 | __jbd2_log_space_left(journal)); | 269 | __jbd2_log_space_left(journal)); |
239 | spin_unlock(&transaction->t_handle_lock); | 270 | read_unlock(&journal->j_state_lock); |
240 | spin_unlock(&journal->j_state_lock); | ||
241 | 271 | ||
242 | lock_map_acquire(&handle->h_lockdep_map); | 272 | lock_map_acquire(&handle->h_lockdep_map); |
243 | out: | 273 | kfree(new_transaction); |
244 | if (unlikely(new_transaction)) /* It's usually NULL */ | 274 | return 0; |
245 | kfree(new_transaction); | ||
246 | return ret; | ||
247 | } | 275 | } |
248 | 276 | ||
249 | static struct lock_class_key jbd2_handle_key; | 277 | static struct lock_class_key jbd2_handle_key; |
@@ -278,7 +306,7 @@ static handle_t *new_handle(int nblocks) | |||
278 | * | 306 | * |
279 | * Return a pointer to a newly allocated handle, or NULL on failure | 307 | * Return a pointer to a newly allocated handle, or NULL on failure |
280 | */ | 308 | */ |
281 | handle_t *jbd2_journal_start(journal_t *journal, int nblocks) | 309 | handle_t *jbd2__journal_start(journal_t *journal, int nblocks, int gfp_mask) |
282 | { | 310 | { |
283 | handle_t *handle = journal_current_handle(); | 311 | handle_t *handle = journal_current_handle(); |
284 | int err; | 312 | int err; |
@@ -298,7 +326,7 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks) | |||
298 | 326 | ||
299 | current->journal_info = handle; | 327 | current->journal_info = handle; |
300 | 328 | ||
301 | err = start_this_handle(journal, handle); | 329 | err = start_this_handle(journal, handle, gfp_mask); |
302 | if (err < 0) { | 330 | if (err < 0) { |
303 | jbd2_free_handle(handle); | 331 | jbd2_free_handle(handle); |
304 | current->journal_info = NULL; | 332 | current->journal_info = NULL; |
@@ -308,6 +336,15 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks) | |||
308 | out: | 336 | out: |
309 | return handle; | 337 | return handle; |
310 | } | 338 | } |
339 | EXPORT_SYMBOL(jbd2__journal_start); | ||
340 | |||
341 | |||
342 | handle_t *jbd2_journal_start(journal_t *journal, int nblocks) | ||
343 | { | ||
344 | return jbd2__journal_start(journal, nblocks, GFP_NOFS); | ||
345 | } | ||
346 | EXPORT_SYMBOL(jbd2_journal_start); | ||
347 | |||
311 | 348 | ||
312 | /** | 349 | /** |
313 | * int jbd2_journal_extend() - extend buffer credits. | 350 | * int jbd2_journal_extend() - extend buffer credits. |
@@ -342,7 +379,7 @@ int jbd2_journal_extend(handle_t *handle, int nblocks) | |||
342 | 379 | ||
343 | result = 1; | 380 | result = 1; |
344 | 381 | ||
345 | spin_lock(&journal->j_state_lock); | 382 | read_lock(&journal->j_state_lock); |
346 | 383 | ||
347 | /* Don't extend a locked-down transaction! */ | 384 | /* Don't extend a locked-down transaction! */ |
348 | if (handle->h_transaction->t_state != T_RUNNING) { | 385 | if (handle->h_transaction->t_state != T_RUNNING) { |
@@ -352,7 +389,7 @@ int jbd2_journal_extend(handle_t *handle, int nblocks) | |||
352 | } | 389 | } |
353 | 390 | ||
354 | spin_lock(&transaction->t_handle_lock); | 391 | spin_lock(&transaction->t_handle_lock); |
355 | wanted = transaction->t_outstanding_credits + nblocks; | 392 | wanted = atomic_read(&transaction->t_outstanding_credits) + nblocks; |
356 | 393 | ||
357 | if (wanted > journal->j_max_transaction_buffers) { | 394 | if (wanted > journal->j_max_transaction_buffers) { |
358 | jbd_debug(3, "denied handle %p %d blocks: " | 395 | jbd_debug(3, "denied handle %p %d blocks: " |
@@ -367,14 +404,14 @@ int jbd2_journal_extend(handle_t *handle, int nblocks) | |||
367 | } | 404 | } |
368 | 405 | ||
369 | handle->h_buffer_credits += nblocks; | 406 | handle->h_buffer_credits += nblocks; |
370 | transaction->t_outstanding_credits += nblocks; | 407 | atomic_add(nblocks, &transaction->t_outstanding_credits); |
371 | result = 0; | 408 | result = 0; |
372 | 409 | ||
373 | jbd_debug(3, "extended handle %p by %d\n", handle, nblocks); | 410 | jbd_debug(3, "extended handle %p by %d\n", handle, nblocks); |
374 | unlock: | 411 | unlock: |
375 | spin_unlock(&transaction->t_handle_lock); | 412 | spin_unlock(&transaction->t_handle_lock); |
376 | error_out: | 413 | error_out: |
377 | spin_unlock(&journal->j_state_lock); | 414 | read_unlock(&journal->j_state_lock); |
378 | out: | 415 | out: |
379 | return result; | 416 | return result; |
380 | } | 417 | } |
@@ -394,8 +431,7 @@ out: | |||
394 | * transaction capabable of guaranteeing the requested number of | 431 | * transaction capabable of guaranteeing the requested number of |
395 | * credits. | 432 | * credits. |
396 | */ | 433 | */ |
397 | 434 | int jbd2__journal_restart(handle_t *handle, int nblocks, int gfp_mask) | |
398 | int jbd2_journal_restart(handle_t *handle, int nblocks) | ||
399 | { | 435 | { |
400 | transaction_t *transaction = handle->h_transaction; | 436 | transaction_t *transaction = handle->h_transaction; |
401 | journal_t *journal = transaction->t_journal; | 437 | journal_t *journal = transaction->t_journal; |
@@ -410,29 +446,35 @@ int jbd2_journal_restart(handle_t *handle, int nblocks) | |||
410 | * First unlink the handle from its current transaction, and start the | 446 | * First unlink the handle from its current transaction, and start the |
411 | * commit on that. | 447 | * commit on that. |
412 | */ | 448 | */ |
413 | J_ASSERT(transaction->t_updates > 0); | 449 | J_ASSERT(atomic_read(&transaction->t_updates) > 0); |
414 | J_ASSERT(journal_current_handle() == handle); | 450 | J_ASSERT(journal_current_handle() == handle); |
415 | 451 | ||
416 | spin_lock(&journal->j_state_lock); | 452 | read_lock(&journal->j_state_lock); |
417 | spin_lock(&transaction->t_handle_lock); | 453 | spin_lock(&transaction->t_handle_lock); |
418 | transaction->t_outstanding_credits -= handle->h_buffer_credits; | 454 | atomic_sub(handle->h_buffer_credits, |
419 | transaction->t_updates--; | 455 | &transaction->t_outstanding_credits); |
420 | 456 | if (atomic_dec_and_test(&transaction->t_updates)) | |
421 | if (!transaction->t_updates) | ||
422 | wake_up(&journal->j_wait_updates); | 457 | wake_up(&journal->j_wait_updates); |
423 | spin_unlock(&transaction->t_handle_lock); | 458 | spin_unlock(&transaction->t_handle_lock); |
424 | 459 | ||
425 | jbd_debug(2, "restarting handle %p\n", handle); | 460 | jbd_debug(2, "restarting handle %p\n", handle); |
426 | __jbd2_log_start_commit(journal, transaction->t_tid); | 461 | __jbd2_log_start_commit(journal, transaction->t_tid); |
427 | spin_unlock(&journal->j_state_lock); | 462 | read_unlock(&journal->j_state_lock); |
428 | 463 | ||
429 | lock_map_release(&handle->h_lockdep_map); | 464 | lock_map_release(&handle->h_lockdep_map); |
430 | handle->h_buffer_credits = nblocks; | 465 | handle->h_buffer_credits = nblocks; |
431 | ret = start_this_handle(journal, handle); | 466 | ret = start_this_handle(journal, handle, gfp_mask); |
432 | return ret; | 467 | return ret; |
433 | } | 468 | } |
469 | EXPORT_SYMBOL(jbd2__journal_restart); | ||
434 | 470 | ||
435 | 471 | ||
472 | int jbd2_journal_restart(handle_t *handle, int nblocks) | ||
473 | { | ||
474 | return jbd2__journal_restart(handle, nblocks, GFP_NOFS); | ||
475 | } | ||
476 | EXPORT_SYMBOL(jbd2_journal_restart); | ||
477 | |||
436 | /** | 478 | /** |
437 | * void jbd2_journal_lock_updates () - establish a transaction barrier. | 479 | * void jbd2_journal_lock_updates () - establish a transaction barrier. |
438 | * @journal: Journal to establish a barrier on. | 480 | * @journal: Journal to establish a barrier on. |
@@ -447,7 +489,7 @@ void jbd2_journal_lock_updates(journal_t *journal) | |||
447 | { | 489 | { |
448 | DEFINE_WAIT(wait); | 490 | DEFINE_WAIT(wait); |
449 | 491 | ||
450 | spin_lock(&journal->j_state_lock); | 492 | write_lock(&journal->j_state_lock); |
451 | ++journal->j_barrier_count; | 493 | ++journal->j_barrier_count; |
452 | 494 | ||
453 | /* Wait until there are no running updates */ | 495 | /* Wait until there are no running updates */ |
@@ -458,19 +500,19 @@ void jbd2_journal_lock_updates(journal_t *journal) | |||
458 | break; | 500 | break; |
459 | 501 | ||
460 | spin_lock(&transaction->t_handle_lock); | 502 | spin_lock(&transaction->t_handle_lock); |
461 | if (!transaction->t_updates) { | 503 | if (!atomic_read(&transaction->t_updates)) { |
462 | spin_unlock(&transaction->t_handle_lock); | 504 | spin_unlock(&transaction->t_handle_lock); |
463 | break; | 505 | break; |
464 | } | 506 | } |
465 | prepare_to_wait(&journal->j_wait_updates, &wait, | 507 | prepare_to_wait(&journal->j_wait_updates, &wait, |
466 | TASK_UNINTERRUPTIBLE); | 508 | TASK_UNINTERRUPTIBLE); |
467 | spin_unlock(&transaction->t_handle_lock); | 509 | spin_unlock(&transaction->t_handle_lock); |
468 | spin_unlock(&journal->j_state_lock); | 510 | write_unlock(&journal->j_state_lock); |
469 | schedule(); | 511 | schedule(); |
470 | finish_wait(&journal->j_wait_updates, &wait); | 512 | finish_wait(&journal->j_wait_updates, &wait); |
471 | spin_lock(&journal->j_state_lock); | 513 | write_lock(&journal->j_state_lock); |
472 | } | 514 | } |
473 | spin_unlock(&journal->j_state_lock); | 515 | write_unlock(&journal->j_state_lock); |
474 | 516 | ||
475 | /* | 517 | /* |
476 | * We have now established a barrier against other normal updates, but | 518 | * We have now established a barrier against other normal updates, but |
@@ -494,9 +536,9 @@ void jbd2_journal_unlock_updates (journal_t *journal) | |||
494 | J_ASSERT(journal->j_barrier_count != 0); | 536 | J_ASSERT(journal->j_barrier_count != 0); |
495 | 537 | ||
496 | mutex_unlock(&journal->j_barrier); | 538 | mutex_unlock(&journal->j_barrier); |
497 | spin_lock(&journal->j_state_lock); | 539 | write_lock(&journal->j_state_lock); |
498 | --journal->j_barrier_count; | 540 | --journal->j_barrier_count; |
499 | spin_unlock(&journal->j_state_lock); | 541 | write_unlock(&journal->j_state_lock); |
500 | wake_up(&journal->j_wait_transaction_locked); | 542 | wake_up(&journal->j_wait_transaction_locked); |
501 | } | 543 | } |
502 | 544 | ||
@@ -1238,7 +1280,8 @@ int jbd2_journal_stop(handle_t *handle) | |||
1238 | { | 1280 | { |
1239 | transaction_t *transaction = handle->h_transaction; | 1281 | transaction_t *transaction = handle->h_transaction; |
1240 | journal_t *journal = transaction->t_journal; | 1282 | journal_t *journal = transaction->t_journal; |
1241 | int err; | 1283 | int err, wait_for_commit = 0; |
1284 | tid_t tid; | ||
1242 | pid_t pid; | 1285 | pid_t pid; |
1243 | 1286 | ||
1244 | J_ASSERT(journal_current_handle() == handle); | 1287 | J_ASSERT(journal_current_handle() == handle); |
@@ -1246,7 +1289,7 @@ int jbd2_journal_stop(handle_t *handle) | |||
1246 | if (is_handle_aborted(handle)) | 1289 | if (is_handle_aborted(handle)) |
1247 | err = -EIO; | 1290 | err = -EIO; |
1248 | else { | 1291 | else { |
1249 | J_ASSERT(transaction->t_updates > 0); | 1292 | J_ASSERT(atomic_read(&transaction->t_updates) > 0); |
1250 | err = 0; | 1293 | err = 0; |
1251 | } | 1294 | } |
1252 | 1295 | ||
@@ -1291,9 +1334,9 @@ int jbd2_journal_stop(handle_t *handle) | |||
1291 | 1334 | ||
1292 | journal->j_last_sync_writer = pid; | 1335 | journal->j_last_sync_writer = pid; |
1293 | 1336 | ||
1294 | spin_lock(&journal->j_state_lock); | 1337 | read_lock(&journal->j_state_lock); |
1295 | commit_time = journal->j_average_commit_time; | 1338 | commit_time = journal->j_average_commit_time; |
1296 | spin_unlock(&journal->j_state_lock); | 1339 | read_unlock(&journal->j_state_lock); |
1297 | 1340 | ||
1298 | trans_time = ktime_to_ns(ktime_sub(ktime_get(), | 1341 | trans_time = ktime_to_ns(ktime_sub(ktime_get(), |
1299 | transaction->t_start_time)); | 1342 | transaction->t_start_time)); |
@@ -1314,14 +1357,8 @@ int jbd2_journal_stop(handle_t *handle) | |||
1314 | if (handle->h_sync) | 1357 | if (handle->h_sync) |
1315 | transaction->t_synchronous_commit = 1; | 1358 | transaction->t_synchronous_commit = 1; |
1316 | current->journal_info = NULL; | 1359 | current->journal_info = NULL; |
1317 | spin_lock(&transaction->t_handle_lock); | 1360 | atomic_sub(handle->h_buffer_credits, |
1318 | transaction->t_outstanding_credits -= handle->h_buffer_credits; | 1361 | &transaction->t_outstanding_credits); |
1319 | transaction->t_updates--; | ||
1320 | if (!transaction->t_updates) { | ||
1321 | wake_up(&journal->j_wait_updates); | ||
1322 | if (journal->j_barrier_count) | ||
1323 | wake_up(&journal->j_wait_transaction_locked); | ||
1324 | } | ||
1325 | 1362 | ||
1326 | /* | 1363 | /* |
1327 | * If the handle is marked SYNC, we need to set another commit | 1364 | * If the handle is marked SYNC, we need to set another commit |
@@ -1330,15 +1367,13 @@ int jbd2_journal_stop(handle_t *handle) | |||
1330 | * transaction is too old now. | 1367 | * transaction is too old now. |
1331 | */ | 1368 | */ |
1332 | if (handle->h_sync || | 1369 | if (handle->h_sync || |
1333 | transaction->t_outstanding_credits > | 1370 | (atomic_read(&transaction->t_outstanding_credits) > |
1334 | journal->j_max_transaction_buffers || | 1371 | journal->j_max_transaction_buffers) || |
1335 | time_after_eq(jiffies, transaction->t_expires)) { | 1372 | time_after_eq(jiffies, transaction->t_expires)) { |
1336 | /* Do this even for aborted journals: an abort still | 1373 | /* Do this even for aborted journals: an abort still |
1337 | * completes the commit thread, it just doesn't write | 1374 | * completes the commit thread, it just doesn't write |
1338 | * anything to disk. */ | 1375 | * anything to disk. */ |
1339 | tid_t tid = transaction->t_tid; | ||
1340 | 1376 | ||
1341 | spin_unlock(&transaction->t_handle_lock); | ||
1342 | jbd_debug(2, "transaction too old, requesting commit for " | 1377 | jbd_debug(2, "transaction too old, requesting commit for " |
1343 | "handle %p\n", handle); | 1378 | "handle %p\n", handle); |
1344 | /* This is non-blocking */ | 1379 | /* This is non-blocking */ |
@@ -1349,11 +1384,25 @@ int jbd2_journal_stop(handle_t *handle) | |||
1349 | * to wait for the commit to complete. | 1384 | * to wait for the commit to complete. |
1350 | */ | 1385 | */ |
1351 | if (handle->h_sync && !(current->flags & PF_MEMALLOC)) | 1386 | if (handle->h_sync && !(current->flags & PF_MEMALLOC)) |
1352 | err = jbd2_log_wait_commit(journal, tid); | 1387 | wait_for_commit = 1; |
1353 | } else { | ||
1354 | spin_unlock(&transaction->t_handle_lock); | ||
1355 | } | 1388 | } |
1356 | 1389 | ||
1390 | /* | ||
1391 | * Once we drop t_updates, if it goes to zero the transaction | ||
1392 | * could start commiting on us and eventually disappear. So | ||
1393 | * once we do this, we must not dereference transaction | ||
1394 | * pointer again. | ||
1395 | */ | ||
1396 | tid = transaction->t_tid; | ||
1397 | if (atomic_dec_and_test(&transaction->t_updates)) { | ||
1398 | wake_up(&journal->j_wait_updates); | ||
1399 | if (journal->j_barrier_count) | ||
1400 | wake_up(&journal->j_wait_transaction_locked); | ||
1401 | } | ||
1402 | |||
1403 | if (wait_for_commit) | ||
1404 | err = jbd2_log_wait_commit(journal, tid); | ||
1405 | |||
1357 | lock_map_release(&handle->h_lockdep_map); | 1406 | lock_map_release(&handle->h_lockdep_map); |
1358 | 1407 | ||
1359 | jbd2_free_handle(handle); | 1408 | jbd2_free_handle(handle); |
@@ -1719,7 +1768,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) | |||
1719 | goto zap_buffer_unlocked; | 1768 | goto zap_buffer_unlocked; |
1720 | 1769 | ||
1721 | /* OK, we have data buffer in journaled mode */ | 1770 | /* OK, we have data buffer in journaled mode */ |
1722 | spin_lock(&journal->j_state_lock); | 1771 | write_lock(&journal->j_state_lock); |
1723 | jbd_lock_bh_state(bh); | 1772 | jbd_lock_bh_state(bh); |
1724 | spin_lock(&journal->j_list_lock); | 1773 | spin_lock(&journal->j_list_lock); |
1725 | 1774 | ||
@@ -1772,7 +1821,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) | |||
1772 | jbd2_journal_put_journal_head(jh); | 1821 | jbd2_journal_put_journal_head(jh); |
1773 | spin_unlock(&journal->j_list_lock); | 1822 | spin_unlock(&journal->j_list_lock); |
1774 | jbd_unlock_bh_state(bh); | 1823 | jbd_unlock_bh_state(bh); |
1775 | spin_unlock(&journal->j_state_lock); | 1824 | write_unlock(&journal->j_state_lock); |
1776 | return ret; | 1825 | return ret; |
1777 | } else { | 1826 | } else { |
1778 | /* There is no currently-running transaction. So the | 1827 | /* There is no currently-running transaction. So the |
@@ -1786,7 +1835,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) | |||
1786 | jbd2_journal_put_journal_head(jh); | 1835 | jbd2_journal_put_journal_head(jh); |
1787 | spin_unlock(&journal->j_list_lock); | 1836 | spin_unlock(&journal->j_list_lock); |
1788 | jbd_unlock_bh_state(bh); | 1837 | jbd_unlock_bh_state(bh); |
1789 | spin_unlock(&journal->j_state_lock); | 1838 | write_unlock(&journal->j_state_lock); |
1790 | return ret; | 1839 | return ret; |
1791 | } else { | 1840 | } else { |
1792 | /* The orphan record's transaction has | 1841 | /* The orphan record's transaction has |
@@ -1810,7 +1859,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) | |||
1810 | jbd2_journal_put_journal_head(jh); | 1859 | jbd2_journal_put_journal_head(jh); |
1811 | spin_unlock(&journal->j_list_lock); | 1860 | spin_unlock(&journal->j_list_lock); |
1812 | jbd_unlock_bh_state(bh); | 1861 | jbd_unlock_bh_state(bh); |
1813 | spin_unlock(&journal->j_state_lock); | 1862 | write_unlock(&journal->j_state_lock); |
1814 | return 0; | 1863 | return 0; |
1815 | } else { | 1864 | } else { |
1816 | /* Good, the buffer belongs to the running transaction. | 1865 | /* Good, the buffer belongs to the running transaction. |
@@ -1829,7 +1878,7 @@ zap_buffer: | |||
1829 | zap_buffer_no_jh: | 1878 | zap_buffer_no_jh: |
1830 | spin_unlock(&journal->j_list_lock); | 1879 | spin_unlock(&journal->j_list_lock); |
1831 | jbd_unlock_bh_state(bh); | 1880 | jbd_unlock_bh_state(bh); |
1832 | spin_unlock(&journal->j_state_lock); | 1881 | write_unlock(&journal->j_state_lock); |
1833 | zap_buffer_unlocked: | 1882 | zap_buffer_unlocked: |
1834 | clear_buffer_dirty(bh); | 1883 | clear_buffer_dirty(bh); |
1835 | J_ASSERT_BH(bh, !buffer_jbddirty(bh)); | 1884 | J_ASSERT_BH(bh, !buffer_jbddirty(bh)); |
@@ -2136,9 +2185,9 @@ int jbd2_journal_begin_ordered_truncate(journal_t *journal, | |||
2136 | /* Locks are here just to force reading of recent values, it is | 2185 | /* Locks are here just to force reading of recent values, it is |
2137 | * enough that the transaction was not committing before we started | 2186 | * enough that the transaction was not committing before we started |
2138 | * a transaction adding the inode to orphan list */ | 2187 | * a transaction adding the inode to orphan list */ |
2139 | spin_lock(&journal->j_state_lock); | 2188 | read_lock(&journal->j_state_lock); |
2140 | commit_trans = journal->j_committing_transaction; | 2189 | commit_trans = journal->j_committing_transaction; |
2141 | spin_unlock(&journal->j_state_lock); | 2190 | read_unlock(&journal->j_state_lock); |
2142 | spin_lock(&journal->j_list_lock); | 2191 | spin_lock(&journal->j_list_lock); |
2143 | inode_trans = jinode->i_transaction; | 2192 | inode_trans = jinode->i_transaction; |
2144 | spin_unlock(&journal->j_list_lock); | 2193 | spin_unlock(&journal->j_list_lock); |