diff options
| author | ngkaho1234 <ngkaho1234@gmail.com> | 2016-01-17 02:28:18 +0800 |
|---|---|---|
| committer | ngkaho1234 <ngkaho1234@gmail.com> | 2016-01-17 02:30:28 +0800 |
| commit | f346efe5f222d05b6b6f2c65af89cddf76e83fcf (patch) | |
| tree | 36f9d981596ab5c08ef213d78c5ab124e057635c | |
| parent | ff03533e16f1efa132e7bbd8599575ab8c795000 (diff) | |
ext4_journal: flushes buffers claimed by multiple transactions.
| -rw-r--r-- | lwext4/ext4_journal.c | 40 |
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 |
