| .. | .. |
|---|
| 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 | /* |
|---|