1 Index: linux-2.6.7/include/linux/jbd.h
2 ===================================================================
3 --- linux-2.6.7.orig/include/linux/jbd.h 2004-08-26 17:12:16.000000000 +0400
4 +++ linux-2.6.7/include/linux/jbd.h 2005-01-19 17:08:33.144512008 +0300
6 struct jbd_revoke_table_s *j_revoke_table[2];
9 + * array of bhs for journal_commit_transaction
11 + struct buffer_head **j_wbuf;
15 * An opaque pointer to fs-private information. ext3 puts its
16 * superblock pointer here
18 Index: linux-2.6.7/include/linux/journal-head.h
19 ===================================================================
20 --- linux-2.6.7.orig/include/linux/journal-head.h 2003-06-24 18:05:26.000000000 +0400
21 +++ linux-2.6.7/include/linux/journal-head.h 2005-01-19 14:09:59.000000000 +0300
25 struct journal_head *b_cpnext, *b_cpprev;
28 + * counter to track users of the buffer in current transaction
33 #endif /* JOURNAL_HEAD_H_INCLUDED */
34 Index: linux-2.6.7/fs/jbd/commit.c
35 ===================================================================
36 --- linux-2.6.7.orig/fs/jbd/commit.c 2004-08-26 17:12:40.000000000 +0400
37 +++ linux-2.6.7/fs/jbd/commit.c 2005-01-19 17:28:32.965111552 +0300
40 transaction_t *commit_transaction;
41 struct journal_head *jh, *new_jh, *descriptor;
42 - struct buffer_head *wbuf[64];
43 + struct buffer_head **wbuf = journal->j_wbuf;
48 BUFFER_TRACE(bh, "start journal writeout");
51 - if (bufs == ARRAY_SIZE(wbuf)) {
52 + if (bufs == journal->j_wbufsize) {
53 jbd_debug(2, "submit %d writes\n",
55 spin_unlock(&journal->j_list_lock);
57 /* If there's no more to do, or if the descriptor is full,
60 - if (bufs == ARRAY_SIZE(wbuf) ||
61 + if (bufs == journal->j_wbufsize ||
62 commit_transaction->t_buffers == NULL ||
63 space_left < sizeof(journal_block_tag_t) + 16) {
65 Index: linux-2.6.7/fs/jbd/journal.c
66 ===================================================================
67 --- linux-2.6.7.orig/fs/jbd/journal.c 2005-01-19 12:07:59.000000000 +0300
68 +++ linux-2.6.7/fs/jbd/journal.c 2005-01-19 17:11:08.589880720 +0300
71 journal_t *journal = journal_init_common();
72 struct buffer_head *bh;
78 journal->j_sb_buffer = bh;
79 journal->j_superblock = (journal_superblock_t *)bh->b_data;
81 + /* journal descriptor can store upto n blocks -bzzz */
82 + n = journal->j_blocksize / sizeof(journal_block_tag_t);
83 + journal->j_wbufsize = n;
84 + journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL);
85 + if (!journal->j_wbuf) {
86 + printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n",
97 struct buffer_head *bh;
98 journal_t *journal = journal_init_common();
101 unsigned long blocknr;
105 journal->j_maxlen = inode->i_size >> inode->i_sb->s_blocksize_bits;
106 journal->j_blocksize = inode->i_sb->s_blocksize;
108 + /* journal descriptor can store upto n blocks -bzzz */
109 + n = journal->j_blocksize / sizeof(journal_block_tag_t);
110 + journal->j_wbufsize = n;
111 + journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL);
112 + if (!journal->j_wbuf) {
113 + printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n",
119 err = journal_bmap(journal, 0, &blocknr);
120 /* If that failed, give up */
122 @@ -1107,6 +1130,10 @@
123 iput(journal->j_inode);
124 if (journal->j_revoke)
125 journal_destroy_revoke(journal);
126 + if (journal->j_wbuf) {
127 + kfree(journal->j_wbuf);
128 + journal->j_wbuf = NULL;
133 Index: linux-2.6.7/fs/jbd/transaction.c
134 ===================================================================
135 --- linux-2.6.7.orig/fs/jbd/transaction.c 2004-08-26 17:12:40.000000000 +0400
136 +++ linux-2.6.7/fs/jbd/transaction.c 2005-01-19 17:23:30.058160408 +0300
138 handle->h_buffer_credits--;
142 + /* the block's becoming member of the trasaction -bzzz */
152 + /* the block's becoming member of the trasaction -bzzz */
156 * Finally, if the buffer is not journaled right now, we need to make
157 * sure it doesn't get written to disk before the caller actually
159 memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size);
160 kunmap_atomic(source, KM_USER0);
163 + /* track all references to the block to be able to recognize the
164 + * situation when the buffer is not part of transaction -bzzz */
167 jbd_unlock_bh_state(bh);
170 @@ -822,11 +834,20 @@
171 jh->b_transaction = transaction;
172 JBUFFER_TRACE(jh, "file as BJ_Reserved");
173 __journal_file_buffer(jh, transaction, BJ_Reserved);
175 } else if (jh->b_transaction == journal->j_committing_transaction) {
176 JBUFFER_TRACE(jh, "set next transaction");
177 jh->b_next_transaction = transaction;
180 spin_unlock(&journal->j_list_lock);
183 + * track all reference to the block to be able to recognize
184 + * the situation when the buffer is not part of transaction -bzzz
188 jbd_unlock_bh_state(bh);
191 @@ -1178,8 +1199,40 @@
193 journal_release_buffer(handle_t *handle, struct buffer_head *bh, int credits)
195 + journal_t *journal = handle->h_transaction->t_journal;
196 + struct journal_head *jh = bh2jh(bh);
198 BUFFER_TRACE(bh, "entry");
199 - handle->h_buffer_credits += credits;
201 + /* return credit back to the handle if it was really spent */
203 + handle->h_buffer_credits++;
205 + jbd_lock_bh_state(bh);
206 + J_ASSERT(jh->b_tcount > 0);
209 + if (jh->b_tcount == 0) {
210 + /* we can drop it from the transaction -bzzz */
211 + J_ASSERT(jh->b_transaction == handle->h_transaction ||
212 + jh->b_next_transaction == handle->h_transaction);
213 + if (jh->b_transaction == handle->h_transaction) {
214 + spin_lock(&journal->j_list_lock);
215 + __journal_unfile_buffer(jh);
216 + spin_unlock(&journal->j_list_lock);
217 + } else if(jh->b_next_transaction) {
218 + jh->b_next_transaction = NULL;
222 + * this was last reference to the block from the current
223 + * transaction and we'd like to return credit to the
224 + * whole transaction -bzzz
227 + handle->h_buffer_credits++;
229 + jbd_unlock_bh_state(bh);
233 @@ -1204,6 +1257,7 @@
234 transaction_t *transaction = handle->h_transaction;
235 journal_t *journal = transaction->t_journal;
236 struct journal_head *jh;
237 + int drop_reserve = 0;
239 BUFFER_TRACE(bh, "entry");
241 @@ -1227,6 +1281,7 @@
242 J_ASSERT_JH(jh, !jh->b_committed_data);
244 __journal_unfile_buffer(jh);
248 * We are no longer going to journal this buffer.
249 @@ -1249,7 +1304,7 @@
250 spin_unlock(&journal->j_list_lock);
251 jbd_unlock_bh_state(bh);
257 } else if (jh->b_transaction) {
258 @@ -1264,6 +1319,7 @@
259 if (jh->b_next_transaction) {
260 J_ASSERT(jh->b_next_transaction == transaction);
261 jh->b_next_transaction = NULL;
266 @@ -1271,6 +1327,15 @@
267 spin_unlock(&journal->j_list_lock);
268 jbd_unlock_bh_state(bh);
272 + if (drop_reserve) {
273 + /* no need to reserve log space for this block -bzzz */
274 + spin_lock(&transaction->t_handle_lock);
275 + transaction->t_outstanding_credits--;
276 + spin_unlock(&transaction->t_handle_lock);