summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorngkaho1234 <ngkaho1234@gmail.com>2016-01-17 02:28:18 +0800
committerngkaho1234 <ngkaho1234@gmail.com>2016-01-17 02:30:28 +0800
commitf346efe5f222d05b6b6f2c65af89cddf76e83fcf (patch)
tree36f9d981596ab5c08ef213d78c5ab124e057635c
parentff03533e16f1efa132e7bbd8599575ab8c795000 (diff)
ext4_journal: flushes buffers claimed by multiple transactions.
-rw-r--r--lwext4/ext4_journal.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/lwext4/ext4_journal.c b/lwext4/ext4_journal.c
index 4f5ca59..7ca5172 100644
--- a/lwext4/ext4_journal.c
+++ b/lwext4/ext4_journal.c
@@ -1266,17 +1266,48 @@ int jbd_journal_start(struct jbd_fs *jbd_fs,
return jbd_write_sb(jbd_fs);
}
+static void jbd_trans_end_write(struct ext4_bcache *bc __unused,
+ struct ext4_buf *buf __unused,
+ int res,
+ void *arg);
+
static void jbd_journal_flush_trans(struct jbd_trans *trans)
{
struct jbd_buf *jbd_buf, *tmp;
struct jbd_journal *journal = trans->journal;
struct ext4_fs *fs = journal->jbd_fs->inode_ref.fs;
+ void *tmp_data = malloc(journal->block_size);
+ if (!tmp_data)
+ return;
+
TAILQ_FOREACH_SAFE(jbd_buf, &trans->buf_queue, buf_node,
tmp) {
struct ext4_buf *buf = jbd_buf->block_rec->buf;
- if (buf)
- ext4_block_flush_buf(fs->bdev, buf);
+ /* The buffer in memory is still dirty. */
+ if (buf) {
+ if (jbd_buf->block_rec->trans != trans) {
+ int r;
+ struct ext4_block jbd_block = EXT4_BLOCK_ZERO();
+ struct jbd_buf *orig_arg = buf->end_write_arg;
+ ext4_assert(ext4_block_get(fs->bdev,
+ &jbd_block,
+ jbd_buf->jbd_lba) == EOK);
+ memcpy(tmp_data, jbd_block.data,
+ journal->block_size);
+ ext4_block_set(fs->bdev, &jbd_block);
+ r = ext4_blocks_set_direct(fs->bdev, tmp_data,
+ buf->lba, 1);
+ jbd_trans_end_write(fs->bdev->bc, buf, r, jbd_buf);
+ buf->end_write = jbd_trans_end_write;
+ buf->end_write_arg = orig_arg;
+ orig_arg->block_rec->buf = buf;
+ } else
+ ext4_block_flush_buf(fs->bdev, buf);
+
+ }
}
+
+ free(tmp_data);
}
static void
@@ -1416,11 +1447,6 @@ jbd_journal_new_trans(struct jbd_journal *journal)
return trans;
}
-static void jbd_trans_end_write(struct ext4_bcache *bc __unused,
- struct ext4_buf *buf __unused,
- int res,
- void *arg);
-
/**@brief gain access to it before making any modications.
* @param journal current journal session
* @param trans transaction