aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd/transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jbd/transaction.c')
-rw-r--r--fs/jbd/transaction.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 2c9e8f5d13aa..67ff2024c23c 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -609,6 +609,12 @@ repeat:
609 goto done; 609 goto done;
610 610
611 /* 611 /*
612 * this is the first time this transaction is touching this buffer,
613 * reset the modified flag
614 */
615 jh->b_modified = 0;
616
617 /*
612 * If there is already a copy-out version of this buffer, then we don't 618 * If there is already a copy-out version of this buffer, then we don't
613 * need to make another one 619 * need to make another one
614 */ 620 */
@@ -681,7 +687,7 @@ repeat:
681 if (!frozen_buffer) { 687 if (!frozen_buffer) {
682 printk(KERN_EMERG 688 printk(KERN_EMERG
683 "%s: OOM for frozen_buffer\n", 689 "%s: OOM for frozen_buffer\n",
684 __FUNCTION__); 690 __func__);
685 JBUFFER_TRACE(jh, "oom!"); 691 JBUFFER_TRACE(jh, "oom!");
686 error = -ENOMEM; 692 error = -ENOMEM;
687 jbd_lock_bh_state(bh); 693 jbd_lock_bh_state(bh);
@@ -820,9 +826,16 @@ int journal_get_create_access(handle_t *handle, struct buffer_head *bh)
820 826
821 if (jh->b_transaction == NULL) { 827 if (jh->b_transaction == NULL) {
822 jh->b_transaction = transaction; 828 jh->b_transaction = transaction;
829
830 /* first access by this transaction */
831 jh->b_modified = 0;
832
823 JBUFFER_TRACE(jh, "file as BJ_Reserved"); 833 JBUFFER_TRACE(jh, "file as BJ_Reserved");
824 __journal_file_buffer(jh, transaction, BJ_Reserved); 834 __journal_file_buffer(jh, transaction, BJ_Reserved);
825 } else if (jh->b_transaction == journal->j_committing_transaction) { 835 } else if (jh->b_transaction == journal->j_committing_transaction) {
836 /* first access by this transaction */
837 jh->b_modified = 0;
838
826 JBUFFER_TRACE(jh, "set next transaction"); 839 JBUFFER_TRACE(jh, "set next transaction");
827 jh->b_next_transaction = transaction; 840 jh->b_next_transaction = transaction;
828 } 841 }
@@ -891,7 +904,7 @@ repeat:
891 committed_data = jbd_alloc(jh2bh(jh)->b_size, GFP_NOFS); 904 committed_data = jbd_alloc(jh2bh(jh)->b_size, GFP_NOFS);
892 if (!committed_data) { 905 if (!committed_data) {
893 printk(KERN_EMERG "%s: No memory for committed data\n", 906 printk(KERN_EMERG "%s: No memory for committed data\n",
894 __FUNCTION__); 907 __func__);
895 err = -ENOMEM; 908 err = -ENOMEM;
896 goto out; 909 goto out;
897 } 910 }
@@ -1222,6 +1235,7 @@ int journal_forget (handle_t *handle, struct buffer_head *bh)
1222 struct journal_head *jh; 1235 struct journal_head *jh;
1223 int drop_reserve = 0; 1236 int drop_reserve = 0;
1224 int err = 0; 1237 int err = 0;
1238 int was_modified = 0;
1225 1239
1226 BUFFER_TRACE(bh, "entry"); 1240 BUFFER_TRACE(bh, "entry");
1227 1241
@@ -1240,6 +1254,9 @@ int journal_forget (handle_t *handle, struct buffer_head *bh)
1240 goto not_jbd; 1254 goto not_jbd;
1241 } 1255 }
1242 1256
1257 /* keep track of wether or not this transaction modified us */
1258 was_modified = jh->b_modified;
1259
1243 /* 1260 /*
1244 * The buffer's going from the transaction, we must drop 1261 * The buffer's going from the transaction, we must drop
1245 * all references -bzzz 1262 * all references -bzzz
@@ -1257,7 +1274,12 @@ int journal_forget (handle_t *handle, struct buffer_head *bh)
1257 1274
1258 JBUFFER_TRACE(jh, "belongs to current transaction: unfile"); 1275 JBUFFER_TRACE(jh, "belongs to current transaction: unfile");
1259 1276
1260 drop_reserve = 1; 1277 /*
1278 * we only want to drop a reference if this transaction
1279 * modified the buffer
1280 */
1281 if (was_modified)
1282 drop_reserve = 1;
1261 1283
1262 /* 1284 /*
1263 * We are no longer going to journal this buffer. 1285 * We are no longer going to journal this buffer.
@@ -1297,7 +1319,13 @@ int journal_forget (handle_t *handle, struct buffer_head *bh)
1297 if (jh->b_next_transaction) { 1319 if (jh->b_next_transaction) {
1298 J_ASSERT(jh->b_next_transaction == transaction); 1320 J_ASSERT(jh->b_next_transaction == transaction);
1299 jh->b_next_transaction = NULL; 1321 jh->b_next_transaction = NULL;
1300 drop_reserve = 1; 1322
1323 /*
1324 * only drop a reference if this transaction modified
1325 * the buffer
1326 */
1327 if (was_modified)
1328 drop_reserve = 1;
1301 } 1329 }
1302 } 1330 }
1303 1331
@@ -2069,7 +2097,7 @@ void __journal_refile_buffer(struct journal_head *jh)
2069 jh->b_transaction = jh->b_next_transaction; 2097 jh->b_transaction = jh->b_next_transaction;
2070 jh->b_next_transaction = NULL; 2098 jh->b_next_transaction = NULL;
2071 __journal_file_buffer(jh, jh->b_transaction, 2099 __journal_file_buffer(jh, jh->b_transaction,
2072 was_dirty ? BJ_Metadata : BJ_Reserved); 2100 jh->b_modified ? BJ_Metadata : BJ_Reserved);
2073 J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING); 2101 J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING);
2074 2102
2075 if (was_dirty) 2103 if (was_dirty)