shithub: lwext4

Download patch

ref: f3d5e9676d582496bc50e1b59ad44c86888634b8
parent: fa3bffb20e71983f71aaf17f6a287546c01b924d
author: ngkaho1234 <[email protected]>
date: Mon Dec 21 03:28:48 EST 2015

ext4_journal: two changes on adding block descriptor to a transaction.

  - jbd_trans_add_block is renamed to jbd_trans_set_block_dirty
  - jbd_trans_get_access routine should be called to gain access
    to a buffer.

--- a/lwext4/ext4.c
+++ b/lwext4/ext4.c
@@ -2562,7 +2562,7 @@
 
 			switch (rand() % 2) {
 			case 0:
-				r = jbd_trans_add_block(t, &block);
+				r = jbd_trans_get_access(journal, &block);
 				if (r != EOK) {
 					jbd_journal_free_trans(journal, t,
 							       true);
@@ -2570,7 +2570,14 @@
 					r = ENOMEM;
 					goto out;
 				}
-				ext4_bcache_set_dirty(block.buf);
+				r = jbd_trans_set_block_dirty(t, &block);
+				if (r != EOK) {
+					jbd_journal_free_trans(journal, t,
+							       true);
+					ext4_block_set(mp->fs.bdev, &block);
+					r = ENOMEM;
+					goto out;
+				}
 				break;
 			case 1:
 				r = jbd_trans_revoke_block(t, rand_block);
--- a/lwext4/ext4_journal.c
+++ b/lwext4/ext4_journal.c
@@ -1092,26 +1092,34 @@
 			  int res,
 			  void *arg);
 
-/**@brief  Add block to a transaction and gain
- *         access to it before making any modications.
- * @param  trans transaction
- * @param  block block descriptor
- * @return standard error code*/
-int jbd_trans_add_block(struct jbd_trans *trans,
-			struct ext4_block *block)
+/**@brief  gain access to it before making any modications.
+ * @param  journal current journal session
+ * @param  block descriptor
+ * @return standard error code.*/
+int jbd_trans_get_access(struct jbd_journal *journal,
+			 struct ext4_block *block)
 {
-	struct jbd_buf *buf;
-	struct ext4_fs *fs =
-		trans->journal->jbd_fs->inode_ref.fs;
+	int r = EOK;
+	struct ext4_fs *fs = journal->jbd_fs->inode_ref.fs;
 
 	/* If the buffer has already been modified, we should
 	 * flush dirty data in this buffer to disk.*/
-	if (ext4_bcache_test_flag(block->buf, BC_DIRTY)) {
-		/* XXX: i don't want to know whether the call
-		 * succeeds or not. */
-		ext4_block_flush_buf(fs->bdev, block->buf);
+	if (ext4_bcache_test_flag(block->buf, BC_DIRTY) &&
+	    block->buf->end_write == jbd_trans_end_write) {
+		r = ext4_block_flush_buf(fs->bdev, block->buf);
 	}
+	return r;
+}
 
+/**@brief  Add block to a transaction and mark it dirty.
+ * @param  trans transaction
+ * @param  block block descriptor
+ * @return standard error code*/
+int jbd_trans_set_block_dirty(struct jbd_trans *trans,
+			      struct ext4_block *block)
+{
+	struct jbd_buf *buf;
+
 	buf = calloc(1, sizeof(struct jbd_buf));
 	if (!buf)
 		return ENOMEM;
@@ -1127,6 +1135,8 @@
 
 	trans->data_cnt++;
 	LIST_INSERT_HEAD(&trans->buf_list, buf, buf_node);
+
+	ext4_bcache_set_dirty(block->buf);
 	return EOK;
 }
 
--- a/lwext4/ext4_journal.h
+++ b/lwext4/ext4_journal.h
@@ -55,8 +55,10 @@
 		      struct jbd_journal *journal);
 int jbd_journal_stop(struct jbd_journal *journal);
 struct jbd_trans *jbd_journal_new_trans(struct jbd_journal *journal);
-int jbd_trans_add_block(struct jbd_trans *trans,
-			struct ext4_block *block);
+int jbd_trans_get_access(struct jbd_journal *journal,
+			 struct ext4_block *block);
+int jbd_trans_set_block_dirty(struct jbd_trans *trans,
+			      struct ext4_block *block);
 int jbd_trans_revoke_block(struct jbd_trans *trans,
 			   ext4_fsblk_t lba);
 void jbd_journal_free_trans(struct jbd_journal *journal,