@@ -55,6 +55,8 @@ jbd2_get_transaction(journal_t *journal, transaction_t *transaction)
5555 transaction -> t_tid = journal -> j_transaction_sequence ++ ;
5656 transaction -> t_expires = jiffies + journal -> j_commit_interval ;
5757 spin_lock_init (& transaction -> t_handle_lock );
58+ atomic_set (& transaction -> t_updates , 0 );
59+ atomic_set (& transaction -> t_outstanding_credits , 0 );
5860 INIT_LIST_HEAD (& transaction -> t_inode_list );
5961 INIT_LIST_HEAD (& transaction -> t_private_list );
6062
@@ -177,7 +179,7 @@ static int start_this_handle(journal_t *journal, handle_t *handle,
177179 * checkpoint to free some more log space.
178180 */
179181 spin_lock (& transaction -> t_handle_lock );
180- needed = transaction -> t_outstanding_credits + nblocks ;
182+ needed = atomic_read ( & transaction -> t_outstanding_credits ) + nblocks ;
181183
182184 if (needed > journal -> j_max_transaction_buffers ) {
183185 /*
@@ -240,11 +242,12 @@ static int start_this_handle(journal_t *journal, handle_t *handle,
240242 }
241243
242244 handle -> h_transaction = transaction ;
243- transaction -> t_outstanding_credits += nblocks ;
244- transaction -> t_updates ++ ;
245+ atomic_add ( nblocks , & transaction -> t_outstanding_credits ) ;
246+ atomic_inc ( & transaction -> t_updates ) ;
245247 transaction -> t_handle_count ++ ;
246248 jbd_debug (4 , "Handle %p given %d credits (total %d, free %d)\n" ,
247- handle , nblocks , transaction -> t_outstanding_credits ,
249+ handle , nblocks ,
250+ atomic_read (& transaction -> t_outstanding_credits ),
248251 __jbd2_log_space_left (journal ));
249252 spin_unlock (& transaction -> t_handle_lock );
250253 spin_unlock (& journal -> j_state_lock );
@@ -369,7 +372,7 @@ int jbd2_journal_extend(handle_t *handle, int nblocks)
369372 }
370373
371374 spin_lock (& transaction -> t_handle_lock );
372- wanted = transaction -> t_outstanding_credits + nblocks ;
375+ wanted = atomic_read ( & transaction -> t_outstanding_credits ) + nblocks ;
373376
374377 if (wanted > journal -> j_max_transaction_buffers ) {
375378 jbd_debug (3 , "denied handle %p %d blocks: "
@@ -384,7 +387,7 @@ int jbd2_journal_extend(handle_t *handle, int nblocks)
384387 }
385388
386389 handle -> h_buffer_credits += nblocks ;
387- transaction -> t_outstanding_credits += nblocks ;
390+ atomic_add ( nblocks , & transaction -> t_outstanding_credits ) ;
388391 result = 0 ;
389392
390393 jbd_debug (3 , "extended handle %p by %d\n" , handle , nblocks );
@@ -426,15 +429,14 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, int gfp_mask)
426429 * First unlink the handle from its current transaction, and start the
427430 * commit on that.
428431 */
429- J_ASSERT (transaction -> t_updates > 0 );
432+ J_ASSERT (atomic_read ( & transaction -> t_updates ) > 0 );
430433 J_ASSERT (journal_current_handle () == handle );
431434
432435 spin_lock (& journal -> j_state_lock );
433436 spin_lock (& transaction -> t_handle_lock );
434- transaction -> t_outstanding_credits -= handle -> h_buffer_credits ;
435- transaction -> t_updates -- ;
436-
437- if (!transaction -> t_updates )
437+ atomic_sub (handle -> h_buffer_credits ,
438+ & transaction -> t_outstanding_credits );
439+ if (atomic_dec_and_test (& transaction -> t_updates ))
438440 wake_up (& journal -> j_wait_updates );
439441 spin_unlock (& transaction -> t_handle_lock );
440442
@@ -481,7 +483,7 @@ void jbd2_journal_lock_updates(journal_t *journal)
481483 break ;
482484
483485 spin_lock (& transaction -> t_handle_lock );
484- if (!transaction -> t_updates ) {
486+ if (!atomic_read ( & transaction -> t_updates ) ) {
485487 spin_unlock (& transaction -> t_handle_lock );
486488 break ;
487489 }
@@ -1258,15 +1260,16 @@ int jbd2_journal_stop(handle_t *handle)
12581260{
12591261 transaction_t * transaction = handle -> h_transaction ;
12601262 journal_t * journal = transaction -> t_journal ;
1261- int err ;
1263+ int err , wait_for_commit = 0 ;
1264+ tid_t tid ;
12621265 pid_t pid ;
12631266
12641267 J_ASSERT (journal_current_handle () == handle );
12651268
12661269 if (is_handle_aborted (handle ))
12671270 err = - EIO ;
12681271 else {
1269- J_ASSERT (transaction -> t_updates > 0 );
1272+ J_ASSERT (atomic_read ( & transaction -> t_updates ) > 0 );
12701273 err = 0 ;
12711274 }
12721275
@@ -1334,14 +1337,8 @@ int jbd2_journal_stop(handle_t *handle)
13341337 if (handle -> h_sync )
13351338 transaction -> t_synchronous_commit = 1 ;
13361339 current -> journal_info = NULL ;
1337- spin_lock (& transaction -> t_handle_lock );
1338- transaction -> t_outstanding_credits -= handle -> h_buffer_credits ;
1339- transaction -> t_updates -- ;
1340- if (!transaction -> t_updates ) {
1341- wake_up (& journal -> j_wait_updates );
1342- if (journal -> j_barrier_count )
1343- wake_up (& journal -> j_wait_transaction_locked );
1344- }
1340+ atomic_sub (handle -> h_buffer_credits ,
1341+ & transaction -> t_outstanding_credits );
13451342
13461343 /*
13471344 * If the handle is marked SYNC, we need to set another commit
@@ -1350,15 +1347,13 @@ int jbd2_journal_stop(handle_t *handle)
13501347 * transaction is too old now.
13511348 */
13521349 if (handle -> h_sync ||
1353- transaction -> t_outstanding_credits >
1354- journal -> j_max_transaction_buffers ||
1355- time_after_eq (jiffies , transaction -> t_expires )) {
1350+ ( atomic_read ( & transaction -> t_outstanding_credits ) >
1351+ journal -> j_max_transaction_buffers ) ||
1352+ time_after_eq (jiffies , transaction -> t_expires )) {
13561353 /* Do this even for aborted journals: an abort still
13571354 * completes the commit thread, it just doesn't write
13581355 * anything to disk. */
1359- tid_t tid = transaction -> t_tid ;
13601356
1361- spin_unlock (& transaction -> t_handle_lock );
13621357 jbd_debug (2 , "transaction too old, requesting commit for "
13631358 "handle %p\n" , handle );
13641359 /* This is non-blocking */
@@ -1369,11 +1364,25 @@ int jbd2_journal_stop(handle_t *handle)
13691364 * to wait for the commit to complete.
13701365 */
13711366 if (handle -> h_sync && !(current -> flags & PF_MEMALLOC ))
1372- err = jbd2_log_wait_commit (journal , tid );
1373- } else {
1374- spin_unlock (& transaction -> t_handle_lock );
1367+ wait_for_commit = 1 ;
13751368 }
13761369
1370+ /*
1371+ * Once we drop t_updates, if it goes to zero the transaction
1372+ * could start commiting on us and eventually disappear. So
1373+ * once we do this, we must not dereference transaction
1374+ * pointer again.
1375+ */
1376+ tid = transaction -> t_tid ;
1377+ if (atomic_dec_and_test (& transaction -> t_updates )) {
1378+ wake_up (& journal -> j_wait_updates );
1379+ if (journal -> j_barrier_count )
1380+ wake_up (& journal -> j_wait_transaction_locked );
1381+ }
1382+
1383+ if (wait_for_commit )
1384+ err = jbd2_log_wait_commit (journal , tid );
1385+
13771386 lock_map_release (& handle -> h_lockdep_map );
13781387
13791388 jbd2_free_handle (handle );
0 commit comments