diff options
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r-- | fs/jbd2/commit.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index af5280fb579b..3091d42992f0 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -1014,17 +1014,35 @@ restart_loop: | |||
1014 | * there's no point in keeping a checkpoint record for | 1014 | * there's no point in keeping a checkpoint record for |
1015 | * it. */ | 1015 | * it. */ |
1016 | 1016 | ||
1017 | /* A buffer which has been freed while still being | 1017 | /* |
1018 | * journaled by a previous transaction may end up still | 1018 | * A buffer which has been freed while still being journaled by |
1019 | * being dirty here, but we want to avoid writing back | 1019 | * a previous transaction. |
1020 | * that buffer in the future after the "add to orphan" | 1020 | */ |
1021 | * operation been committed, That's not only a performance | 1021 | if (buffer_freed(bh)) { |
1022 | * gain, it also stops aliasing problems if the buffer is | 1022 | /* |
1023 | * left behind for writeback and gets reallocated for another | 1023 | * If the running transaction is the one containing |
1024 | * use in a different page. */ | 1024 | * "add to orphan" operation (b_next_transaction != |
1025 | if (buffer_freed(bh) && !jh->b_next_transaction) { | 1025 | * NULL), we have to wait for that transaction to |
1026 | clear_buffer_freed(bh); | 1026 | * commit before we can really get rid of the buffer. |
1027 | clear_buffer_jbddirty(bh); | 1027 | * So just clear b_modified to not confuse transaction |
1028 | * credit accounting and refile the buffer to | ||
1029 | * BJ_Forget of the running transaction. If the just | ||
1030 | * committed transaction contains "add to orphan" | ||
1031 | * operation, we can completely invalidate the buffer | ||
1032 | * now. We are rather through in that since the | ||
1033 | * buffer may be still accessible when blocksize < | ||
1034 | * pagesize and it is attached to the last partial | ||
1035 | * page. | ||
1036 | */ | ||
1037 | jh->b_modified = 0; | ||
1038 | if (!jh->b_next_transaction) { | ||
1039 | clear_buffer_freed(bh); | ||
1040 | clear_buffer_jbddirty(bh); | ||
1041 | clear_buffer_mapped(bh); | ||
1042 | clear_buffer_new(bh); | ||
1043 | clear_buffer_req(bh); | ||
1044 | bh->b_bdev = NULL; | ||
1045 | } | ||
1028 | } | 1046 | } |
1029 | 1047 | ||
1030 | if (buffer_jbddirty(bh)) { | 1048 | if (buffer_jbddirty(bh)) { |