diff options
Diffstat (limited to 'fs/jbd2/transaction.c')
-rw-r--r-- | fs/jbd2/transaction.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index b9b0b6f899b9..d6e006e67804 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -618,6 +618,12 @@ repeat: | |||
618 | goto done; | 618 | goto done; |
619 | 619 | ||
620 | /* | 620 | /* |
621 | * this is the first time this transaction is touching this buffer, | ||
622 | * reset the modified flag | ||
623 | */ | ||
624 | jh->b_modified = 0; | ||
625 | |||
626 | /* | ||
621 | * If there is already a copy-out version of this buffer, then we don't | 627 | * If there is already a copy-out version of this buffer, then we don't |
622 | * need to make another one | 628 | * need to make another one |
623 | */ | 629 | */ |
@@ -690,7 +696,7 @@ repeat: | |||
690 | if (!frozen_buffer) { | 696 | if (!frozen_buffer) { |
691 | printk(KERN_EMERG | 697 | printk(KERN_EMERG |
692 | "%s: OOM for frozen_buffer\n", | 698 | "%s: OOM for frozen_buffer\n", |
693 | __FUNCTION__); | 699 | __func__); |
694 | JBUFFER_TRACE(jh, "oom!"); | 700 | JBUFFER_TRACE(jh, "oom!"); |
695 | error = -ENOMEM; | 701 | error = -ENOMEM; |
696 | jbd_lock_bh_state(bh); | 702 | jbd_lock_bh_state(bh); |
@@ -829,9 +835,16 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) | |||
829 | 835 | ||
830 | if (jh->b_transaction == NULL) { | 836 | if (jh->b_transaction == NULL) { |
831 | jh->b_transaction = transaction; | 837 | jh->b_transaction = transaction; |
838 | |||
839 | /* first access by this transaction */ | ||
840 | jh->b_modified = 0; | ||
841 | |||
832 | JBUFFER_TRACE(jh, "file as BJ_Reserved"); | 842 | JBUFFER_TRACE(jh, "file as BJ_Reserved"); |
833 | __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); | 843 | __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); |
834 | } else if (jh->b_transaction == journal->j_committing_transaction) { | 844 | } else if (jh->b_transaction == journal->j_committing_transaction) { |
845 | /* first access by this transaction */ | ||
846 | jh->b_modified = 0; | ||
847 | |||
835 | JBUFFER_TRACE(jh, "set next transaction"); | 848 | JBUFFER_TRACE(jh, "set next transaction"); |
836 | jh->b_next_transaction = transaction; | 849 | jh->b_next_transaction = transaction; |
837 | } | 850 | } |
@@ -901,7 +914,7 @@ repeat: | |||
901 | committed_data = jbd2_alloc(jh2bh(jh)->b_size, GFP_NOFS); | 914 | committed_data = jbd2_alloc(jh2bh(jh)->b_size, GFP_NOFS); |
902 | if (!committed_data) { | 915 | if (!committed_data) { |
903 | printk(KERN_EMERG "%s: No memory for committed data\n", | 916 | printk(KERN_EMERG "%s: No memory for committed data\n", |
904 | __FUNCTION__); | 917 | __func__); |
905 | err = -ENOMEM; | 918 | err = -ENOMEM; |
906 | goto out; | 919 | goto out; |
907 | } | 920 | } |
@@ -1230,6 +1243,7 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) | |||
1230 | struct journal_head *jh; | 1243 | struct journal_head *jh; |
1231 | int drop_reserve = 0; | 1244 | int drop_reserve = 0; |
1232 | int err = 0; | 1245 | int err = 0; |
1246 | int was_modified = 0; | ||
1233 | 1247 | ||
1234 | BUFFER_TRACE(bh, "entry"); | 1248 | BUFFER_TRACE(bh, "entry"); |
1235 | 1249 | ||
@@ -1248,6 +1262,9 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) | |||
1248 | goto not_jbd; | 1262 | goto not_jbd; |
1249 | } | 1263 | } |
1250 | 1264 | ||
1265 | /* keep track of wether or not this transaction modified us */ | ||
1266 | was_modified = jh->b_modified; | ||
1267 | |||
1251 | /* | 1268 | /* |
1252 | * The buffer's going from the transaction, we must drop | 1269 | * The buffer's going from the transaction, we must drop |
1253 | * all references -bzzz | 1270 | * all references -bzzz |
@@ -1265,7 +1282,12 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) | |||
1265 | 1282 | ||
1266 | JBUFFER_TRACE(jh, "belongs to current transaction: unfile"); | 1283 | JBUFFER_TRACE(jh, "belongs to current transaction: unfile"); |
1267 | 1284 | ||
1268 | drop_reserve = 1; | 1285 | /* |
1286 | * we only want to drop a reference if this transaction | ||
1287 | * modified the buffer | ||
1288 | */ | ||
1289 | if (was_modified) | ||
1290 | drop_reserve = 1; | ||
1269 | 1291 | ||
1270 | /* | 1292 | /* |
1271 | * We are no longer going to journal this buffer. | 1293 | * We are no longer going to journal this buffer. |
@@ -1305,7 +1327,13 @@ int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh) | |||
1305 | if (jh->b_next_transaction) { | 1327 | if (jh->b_next_transaction) { |
1306 | J_ASSERT(jh->b_next_transaction == transaction); | 1328 | J_ASSERT(jh->b_next_transaction == transaction); |
1307 | jh->b_next_transaction = NULL; | 1329 | jh->b_next_transaction = NULL; |
1308 | drop_reserve = 1; | 1330 | |
1331 | /* | ||
1332 | * only drop a reference if this transaction modified | ||
1333 | * the buffer | ||
1334 | */ | ||
1335 | if (was_modified) | ||
1336 | drop_reserve = 1; | ||
1309 | } | 1337 | } |
1310 | } | 1338 | } |
1311 | 1339 | ||
@@ -1434,7 +1462,8 @@ int jbd2_journal_stop(handle_t *handle) | |||
1434 | return err; | 1462 | return err; |
1435 | } | 1463 | } |
1436 | 1464 | ||
1437 | /**int jbd2_journal_force_commit() - force any uncommitted transactions | 1465 | /** |
1466 | * int jbd2_journal_force_commit() - force any uncommitted transactions | ||
1438 | * @journal: journal to force | 1467 | * @journal: journal to force |
1439 | * | 1468 | * |
1440 | * For synchronous operations: force any uncommitted transactions | 1469 | * For synchronous operations: force any uncommitted transactions |
@@ -2077,7 +2106,7 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh) | |||
2077 | jh->b_transaction = jh->b_next_transaction; | 2106 | jh->b_transaction = jh->b_next_transaction; |
2078 | jh->b_next_transaction = NULL; | 2107 | jh->b_next_transaction = NULL; |
2079 | __jbd2_journal_file_buffer(jh, jh->b_transaction, | 2108 | __jbd2_journal_file_buffer(jh, jh->b_transaction, |
2080 | was_dirty ? BJ_Metadata : BJ_Reserved); | 2109 | jh->b_modified ? BJ_Metadata : BJ_Reserved); |
2081 | J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING); | 2110 | J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING); |
2082 | 2111 | ||
2083 | if (was_dirty) | 2112 | if (was_dirty) |