.. | .. |
---|
984 | 984 | * ie. locked but not dirty) or tune2fs (which may actually have |
---|
985 | 985 | * the buffer dirtied, ugh.) */ |
---|
986 | 986 | |
---|
987 | | - if (buffer_dirty(bh)) { |
---|
| 987 | + if (buffer_dirty(bh) && jh->b_transaction) { |
---|
| 988 | + warn_dirty_buffer(bh); |
---|
988 | 989 | /* |
---|
989 | | - * First question: is this buffer already part of the current |
---|
990 | | - * transaction or the existing committing transaction? |
---|
991 | | - */ |
---|
992 | | - if (jh->b_transaction) { |
---|
993 | | - J_ASSERT_JH(jh, |
---|
994 | | - jh->b_transaction == transaction || |
---|
995 | | - jh->b_transaction == |
---|
996 | | - journal->j_committing_transaction); |
---|
997 | | - if (jh->b_next_transaction) |
---|
998 | | - J_ASSERT_JH(jh, jh->b_next_transaction == |
---|
999 | | - transaction); |
---|
1000 | | - warn_dirty_buffer(bh); |
---|
1001 | | - } |
---|
1002 | | - /* |
---|
1003 | | - * In any case we need to clean the dirty flag and we must |
---|
1004 | | - * do it under the buffer lock to be sure we don't race |
---|
1005 | | - * with running write-out. |
---|
| 990 | + * We need to clean the dirty flag and we must do it under the |
---|
| 991 | + * buffer lock to be sure we don't race with running write-out. |
---|
1006 | 992 | */ |
---|
1007 | 993 | JBUFFER_TRACE(jh, "Journalling dirty buffer"); |
---|
1008 | 994 | clear_buffer_dirty(bh); |
---|
| 995 | + /* |
---|
| 996 | + * The buffer is going to be added to BJ_Reserved list now and |
---|
| 997 | + * nothing guarantees jbd2_journal_dirty_metadata() will be |
---|
| 998 | + * ever called for it. So we need to set jbddirty bit here to |
---|
| 999 | + * make sure the buffer is dirtied and written out when the |
---|
| 1000 | + * journaling machinery is done with it. |
---|
| 1001 | + */ |
---|
1009 | 1002 | set_buffer_jbddirty(bh); |
---|
1010 | 1003 | } |
---|
1011 | | - |
---|
1012 | | - unlock_buffer(bh); |
---|
1013 | 1004 | |
---|
1014 | 1005 | error = -EROFS; |
---|
1015 | 1006 | if (is_handle_aborted(handle)) { |
---|
1016 | 1007 | spin_unlock(&jh->b_state_lock); |
---|
| 1008 | + unlock_buffer(bh); |
---|
1017 | 1009 | goto out; |
---|
1018 | 1010 | } |
---|
1019 | 1011 | error = 0; |
---|
.. | .. |
---|
1023 | 1015 | * b_next_transaction points to it |
---|
1024 | 1016 | */ |
---|
1025 | 1017 | if (jh->b_transaction == transaction || |
---|
1026 | | - jh->b_next_transaction == transaction) |
---|
| 1018 | + jh->b_next_transaction == transaction) { |
---|
| 1019 | + unlock_buffer(bh); |
---|
1027 | 1020 | goto done; |
---|
| 1021 | + } |
---|
1028 | 1022 | |
---|
1029 | 1023 | /* |
---|
1030 | 1024 | * this is the first time this transaction is touching this buffer, |
---|
.. | .. |
---|
1048 | 1042 | */ |
---|
1049 | 1043 | smp_wmb(); |
---|
1050 | 1044 | spin_lock(&journal->j_list_lock); |
---|
| 1045 | + if (test_clear_buffer_dirty(bh)) { |
---|
| 1046 | + /* |
---|
| 1047 | + * Execute buffer dirty clearing and jh->b_transaction |
---|
| 1048 | + * assignment under journal->j_list_lock locked to |
---|
| 1049 | + * prevent bh being removed from checkpoint list if |
---|
| 1050 | + * the buffer is in an intermediate state (not dirty |
---|
| 1051 | + * and jh->b_transaction is NULL). |
---|
| 1052 | + */ |
---|
| 1053 | + JBUFFER_TRACE(jh, "Journalling dirty buffer"); |
---|
| 1054 | + set_buffer_jbddirty(bh); |
---|
| 1055 | + } |
---|
1051 | 1056 | __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); |
---|
1052 | 1057 | spin_unlock(&journal->j_list_lock); |
---|
| 1058 | + unlock_buffer(bh); |
---|
1053 | 1059 | goto done; |
---|
1054 | 1060 | } |
---|
| 1061 | + unlock_buffer(bh); |
---|
| 1062 | + |
---|
1055 | 1063 | /* |
---|
1056 | 1064 | * If there is already a copy-out version of this buffer, then we don't |
---|
1057 | 1065 | * need to make another one |
---|
.. | .. |
---|
2370 | 2378 | spin_unlock(&jh->b_state_lock); |
---|
2371 | 2379 | write_unlock(&journal->j_state_lock); |
---|
2372 | 2380 | jbd2_journal_put_journal_head(jh); |
---|
| 2381 | + /* Already zapped buffer? Nothing to do... */ |
---|
| 2382 | + if (!bh->b_bdev) |
---|
| 2383 | + return 0; |
---|
2373 | 2384 | return -EBUSY; |
---|
2374 | 2385 | } |
---|
2375 | 2386 | /* |
---|