ref: 0c7f3604a3e2f26da99f8e126098ce8520139fbd
parent: f3e06a2a6d91b4502fb0e0f70a79fb6daaf601e1
author: ngkaho1234 <[email protected]>
date: Mon Dec 28 08:05:04 EST 2015
Introduce initial support of ext3/4 journalling. To achieve this, a glue layer between block cache and lwext4 core routines is added.
--- a/lwext4/ext4.c
+++ b/lwext4/ext4.c
@@ -251,7 +251,7 @@
return EIO;
ext4_dir_en_set_inode(res.dentry, parent->index);
- ext4_bcache_set_dirty(res.block.buf);
+ ext4_trans_set_block_dirty(res.block.buf);
r = ext4_dir_destroy_result(ch, &res);
if (r != EOK)
return r;
@@ -414,6 +414,7 @@
}
return r;
}
+ bd->fs = &mp->fs;
return r;
}
@@ -437,7 +438,7 @@
r = ext4_fs_fini(&mp->fs);
if (r != EOK)
- return r;
+ goto Finish;
mp->mounted = 0;
@@ -446,8 +447,10 @@
ext4_bcache_fini_dynamic(mp->fs.bdev->bc);
free(mp->fs.bdev->bc);
}
-
- return ext4_block_fini(mp->fs.bdev);
+ r = ext4_block_fini(mp->fs.bdev);
+Finish:
+ mp->fs.bdev->fs = NULL;
+ return r;
}
static struct ext4_mountpoint *ext4_get_mount(const char *path)
@@ -594,29 +597,6 @@
}
}
-int ext4_trans_get_write_access(struct ext4_fs *fs,
- struct ext4_block *block)
-{
- int r = EOK;
- if (fs->jbd_journal && fs->curr_trans) {
- struct jbd_journal *journal = fs->jbd_journal;
- struct jbd_trans *trans = fs->curr_trans;
- r = jbd_trans_get_access(journal, trans, block);
- }
- return r;
-}
-
-int ext4_trans_set_block_dirty(struct ext4_fs *fs,
- struct ext4_block *block)
-{
- int r = EOK;
- if (fs->jbd_journal && fs->curr_trans) {
- struct jbd_trans *trans = fs->curr_trans;
- r = jbd_trans_set_block_dirty(trans, block);
- }
- return r;
-}
-
int ext4_mount_point_stats(const char *mount_point,
struct ext4_mount_stats *stats)
{
@@ -2134,6 +2114,12 @@
Finish:
ext4_block_cache_write_back(mp->fs.bdev, 0);
+
+ if (r != EOK)
+ ext4_trans_abort(mp);
+ else
+ ext4_trans_stop(mp);
+
EXT4_MP_UNLOCK(mp);
return r;
}
@@ -2195,6 +2181,8 @@
return EINVAL;
EXT4_MP_LOCK(mp);
+ ext4_trans_start(mp);
+
r = ext4_generic_open2(&f, path, O_RDWR, EXT4_DE_UNKNOWN, NULL, NULL);
if (r != EOK)
goto Finish;
@@ -2217,6 +2205,11 @@
ext4_fs_put_xattr_ref(&xattr_ref);
ext4_fs_put_inode_ref(&inode_ref);
Finish:
+ if (r != EOK)
+ ext4_trans_abort(mp);
+ else
+ ext4_trans_stop(mp);
+
EXT4_MP_UNLOCK(mp);
return r;
}
@@ -2377,6 +2370,8 @@
return EINVAL;
EXT4_MP_LOCK(mp);
+ ext4_trans_start(mp);
+
r = ext4_generic_open2(&f, path, O_RDWR, EXT4_DE_UNKNOWN, NULL, NULL);
if (r != EOK)
goto Finish;
@@ -2399,6 +2394,11 @@
ext4_fs_put_xattr_ref(&xattr_ref);
ext4_fs_put_inode_ref(&inode_ref);
Finish:
+ if (r != EOK)
+ ext4_trans_abort(mp);
+ else
+ ext4_trans_stop(mp);
+
EXT4_MP_UNLOCK(mp);
return r;
--- a/lwext4/ext4.h
+++ b/lwext4/ext4.h
@@ -182,6 +182,9 @@
* @return standard error code */
int ext4_umount(const char *mount_point);
+int ext4_journal_start(const char *mount_point);
+
+int ext4_journal_stop(const char *mount_point);
/**@brief Journal recovery.
* @param mount_point mount point
--- a/lwext4/ext4_balloc.c
+++ b/lwext4/ext4_balloc.c
@@ -165,7 +165,7 @@
struct ext4_block bitmap_block;
- rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
+ rc = ext4_trans_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
if (rc != EOK) {
ext4_fs_put_block_group_ref(&bg_ref);
return rc;
@@ -181,7 +181,7 @@
/* Modify bitmap */
ext4_bmap_bit_clr(bitmap_block.data, index_in_group);
ext4_balloc_set_bitmap_csum(sb, bg, bitmap_block.data);
- ext4_bcache_set_dirty(bitmap_block.buf);
+ ext4_trans_set_block_dirty(bitmap_block.buf);
/* Release block with bitmap */
rc = ext4_block_set(fs->bdev, &bitmap_block);
@@ -211,6 +211,12 @@
bg_ref.dirty = true;
+ rc = ext4_trans_try_revoke_block(fs->bdev, baddr);
+ if (rc != EOK) {
+ bg_ref.dirty = false;
+ ext4_fs_put_block_group_ref(&bg_ref);
+ return rc;
+ }
ext4_bcache_invalidate_lba(fs->bdev->bc, baddr, 1);
/* Release block group reference */
return ext4_fs_put_block_group_ref(&bg_ref);
@@ -256,7 +262,7 @@
ext4_fsblk_t bitmap_blk = ext4_bg_get_block_bitmap(bg, sb);
struct ext4_block blk;
- rc = ext4_block_get(fs->bdev, &blk, bitmap_blk);
+ rc = ext4_trans_block_get(fs->bdev, &blk, bitmap_blk);
if (rc != EOK) {
ext4_fs_put_block_group_ref(&bg_ref);
return rc;
@@ -277,7 +283,7 @@
/* Modify bitmap */
ext4_bmap_bits_free(blk.data, idx_in_bg_first, free_cnt);
ext4_balloc_set_bitmap_csum(sb, bg, blk.data);
- ext4_bcache_set_dirty(blk.buf);
+ ext4_trans_set_block_dirty(blk.buf);
count -= free_cnt;
first += free_cnt;
@@ -318,6 +324,14 @@
bg_first++;
}
+ uint32_t i;
+ for (i = 0;i < count;i++) {
+ rc = ext4_trans_try_revoke_block(fs->bdev, first + i);
+ if (rc != EOK)
+ return rc;
+
+ }
+
ext4_bcache_invalidate_lba(fs->bdev->bc, first, count);
/*All blocks should be released*/
ext4_assert(count == 0);
@@ -368,7 +382,7 @@
/* Load block with bitmap */
bmp_blk_adr = ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
- r = ext4_block_get(inode_ref->fs->bdev, &b, bmp_blk_adr);
+ r = ext4_trans_block_get(inode_ref->fs->bdev, &b, bmp_blk_adr);
if (r != EOK) {
ext4_fs_put_block_group_ref(&bg_ref);
return r;
@@ -386,7 +400,7 @@
ext4_bmap_bit_set(b.data, idx_in_bg);
ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group,
b.data);
- ext4_bcache_set_dirty(b.buf);
+ ext4_trans_set_block_dirty(b.buf);
r = ext4_block_set(inode_ref->fs->bdev, &b);
if (r != EOK) {
ext4_fs_put_block_group_ref(&bg_ref);
@@ -410,7 +424,7 @@
ext4_bmap_bit_set(b.data, tmp_idx);
ext4_balloc_set_bitmap_csum(sb, bg, b.data);
- ext4_bcache_set_dirty(b.buf);
+ ext4_trans_set_block_dirty(b.buf);
r = ext4_block_set(inode_ref->fs->bdev, &b);
if (r != EOK)
return r;
@@ -425,7 +439,7 @@
if (r == EOK) {
ext4_bmap_bit_set(b.data, rel_blk_idx);
ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group, b.data);
- ext4_bcache_set_dirty(b.buf);
+ ext4_trans_set_block_dirty(b.buf);
r = ext4_block_set(inode_ref->fs->bdev, &b);
if (r != EOK)
return r;
@@ -466,7 +480,7 @@
/* Load block with bitmap */
bmp_blk_adr = ext4_bg_get_block_bitmap(bg, sb);
- r = ext4_block_get(inode_ref->fs->bdev, &b, bmp_blk_adr);
+ r = ext4_trans_block_get(inode_ref->fs->bdev, &b, bmp_blk_adr);
if (r != EOK) {
ext4_fs_put_block_group_ref(&bg_ref);
return r;
@@ -493,7 +507,7 @@
if (r == EOK) {
ext4_bmap_bit_set(b.data, rel_blk_idx);
ext4_balloc_set_bitmap_csum(sb, bg, b.data);
- ext4_bcache_set_dirty(b.buf);
+ ext4_trans_set_block_dirty(b.buf);
r = ext4_block_set(inode_ref->fs->bdev, &b);
if (r != EOK) {
ext4_fs_put_block_group_ref(&bg_ref);
@@ -576,7 +590,7 @@
bmp_blk_addr = ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
struct ext4_block b;
- rc = ext4_block_get(fs->bdev, &b, bmp_blk_addr);
+ rc = ext4_trans_block_get(fs->bdev, &b, bmp_blk_addr);
if (rc != EOK) {
ext4_fs_put_block_group_ref(&bg_ref);
return rc;
@@ -596,7 +610,7 @@
if (*free) {
ext4_bmap_bit_set(b.data, index_in_group);
ext4_balloc_set_bitmap_csum(sb, bg_ref.block_group, b.data);
- ext4_bcache_set_dirty(b.buf);
+ ext4_trans_set_block_dirty(b.buf);
}
/* Release block with bitmap */
--- a/lwext4/ext4_bcache.c
+++ b/lwext4/ext4_bcache.c
@@ -132,6 +132,7 @@
buf->lba = lba;
buf->data = data;
+ buf->bc = bc;
return buf;
}
--- a/lwext4/ext4_bcache.h
+++ b/lwext4/ext4_bcache.h
@@ -85,6 +85,9 @@
/**@brief Reference count table*/
uint32_t refctr;
+ /**@brief The block cache this buffer belongs to. */
+ struct ext4_bcache *bc;
+
/**@brief Whether or not buffer is on dirty list.*/
bool on_dirty_list;
--- a/lwext4/ext4_blockdev.h
+++ b/lwext4/ext4_blockdev.h
@@ -42,6 +42,7 @@
#include "ext4_config.h"
#include "ext4_bcache.h"
+#include "ext4_trans.h"
#include "ext4_debug.h"
#include <stdbool.h>
@@ -122,6 +123,9 @@
/**@brief Cache write back mode reference counter*/
uint32_t cache_write_back;
+
+ /**@brief The filesystem this block device belongs to. */
+ struct ext4_fs *fs;
};
/**@brief Static initialization of the block device.*/
--- a/lwext4/ext4_dir.c
+++ b/lwext4/ext4_dir.c
@@ -239,7 +239,7 @@
if (r != EOK)
return r;
- r = ext4_block_get(bdev, &it->curr_blk, next_blk);
+ r = ext4_trans_block_get(bdev, &it->curr_blk, next_blk);
if (r != EOK) {
it->curr_blk.lb_id = 0;
return r;
@@ -364,7 +364,7 @@
return r;
struct ext4_block block;
- r = ext4_block_get(fs->bdev, &block, fblock);
+ r = ext4_trans_block_get(fs->bdev, &block, fblock);
if (r != EOK)
return r;
@@ -402,7 +402,7 @@
/* Load new block */
struct ext4_block b;
- r = ext4_block_get_noread(fs->bdev, &b, fblock);
+ r = ext4_trans_block_get_noread(fs->bdev, &b, fblock);
if (r != EOK)
return r;
@@ -421,7 +421,7 @@
}
ext4_dir_set_csum(parent, (void *)b.data);
- ext4_bcache_set_dirty(b.buf);
+ ext4_trans_set_block_dirty(b.buf);
r = ext4_block_set(fs->bdev, &b);
return r;
@@ -474,7 +474,7 @@
/* Load data block */
struct ext4_block b;
- r = ext4_block_get(parent->fs->bdev, &b, fblock);
+ r = ext4_trans_block_get(parent->fs->bdev, &b, fblock);
if (r != EOK)
return r;
@@ -554,7 +554,7 @@
ext4_dir_set_csum(parent,
(struct ext4_dir_en *)result.block.data);
- ext4_bcache_set_dirty(result.block.buf);
+ ext4_trans_set_block_dirty(result.block.buf);
return ext4_dir_destroy_result(parent, &result);
}
@@ -591,7 +591,7 @@
ext4_dir_write_entry(sb, start, rec_len, child, name,
name_len);
ext4_dir_set_csum(inode_ref, (void *)dst_blk->data);
- ext4_bcache_set_dirty(dst_blk->buf);
+ ext4_trans_set_block_dirty(dst_blk->buf);
return EOK;
}
@@ -620,7 +620,7 @@
ext4_dir_set_csum(inode_ref,
(void *)dst_blk->data);
- ext4_bcache_set_dirty(dst_blk->buf);
+ ext4_trans_set_block_dirty(dst_blk->buf);
return EOK;
}
}
--- a/lwext4/ext4_dir_idx.c
+++ b/lwext4/ext4_dir_idx.c
@@ -353,7 +353,7 @@
return rc;
struct ext4_block block;
- rc = ext4_block_get_noread(dir->fs->bdev, &block, fblock);
+ rc = ext4_trans_block_get_noread(dir->fs->bdev, &block, fblock);
if (rc != EOK)
return rc;
@@ -403,7 +403,7 @@
}
struct ext4_block new_block;
- rc = ext4_block_get_noread(dir->fs->bdev, &new_block, fblock);
+ rc = ext4_trans_block_get_noread(dir->fs->bdev, &new_block, fblock);
if (rc != EOK) {
ext4_block_set(dir->fs->bdev, &block);
return rc;
@@ -425,7 +425,7 @@
ext4_dir_en_set_inode(be, 0);
- ext4_bcache_set_dirty(new_block.buf);
+ ext4_trans_set_block_dirty(new_block.buf);
rc = ext4_block_set(dir->fs->bdev, &new_block);
if (rc != EOK) {
ext4_block_set(dir->fs->bdev, &block);
@@ -437,7 +437,7 @@
ext4_dir_dx_entry_set_block(entry, iblock);
ext4_dir_set_dx_csum(dir, (struct ext4_dir_en *)block.data);
- ext4_bcache_set_dirty(block.buf);
+ ext4_trans_set_block_dirty(block.buf);
return ext4_block_set(dir->fs->bdev, &block);
}
@@ -580,7 +580,7 @@
if (r != EOK)
return r;
- r = ext4_block_get(inode_ref->fs->bdev, tmp_blk, fblk);
+ r = ext4_trans_block_get(inode_ref->fs->bdev, tmp_blk, fblk);
if (r != EOK)
return r;
@@ -662,7 +662,7 @@
return r;
struct ext4_block b;
- r = ext4_block_get(inode_ref->fs->bdev, &b, blk_adr);
+ r = ext4_trans_block_get(inode_ref->fs->bdev, &b, blk_adr);
if (r != EOK)
return r;
@@ -705,7 +705,7 @@
struct ext4_fs *fs = inode_ref->fs;
struct ext4_block root_block;
- rc = ext4_block_get(fs->bdev, &root_block, root_block_addr);
+ rc = ext4_trans_block_get(fs->bdev, &root_block, root_block_addr);
if (rc != EOK)
return rc;
@@ -753,7 +753,7 @@
if (rc != EOK)
goto cleanup;
- rc = ext4_block_get(fs->bdev, &b, leaf_block_addr);
+ rc = ext4_trans_block_get(fs->bdev, &b, leaf_block_addr);
if (rc != EOK)
goto cleanup;
@@ -897,7 +897,7 @@
ext4_dir_dx_entry_set_hash(new_index_entry, hash);
ext4_dir_dx_climit_set_count(climit, count + 1);
ext4_dir_set_dx_csum(inode_ref, (void *)index_block->b.data);
- ext4_bcache_set_dirty(index_block->b.buf);
+ ext4_trans_set_block_dirty(index_block->b.buf);
}
/**@brief Split directory entries to two parts preventing node overflow.
@@ -994,7 +994,7 @@
/* Load new block */
struct ext4_block new_data_block_tmp;
- rc = ext4_block_get_noread(inode_ref->fs->bdev, &new_data_block_tmp,
+ rc = ext4_trans_block_get_noread(inode_ref->fs->bdev, &new_data_block_tmp,
new_fblock);
if (rc != EOK) {
free(sort);
@@ -1073,8 +1073,8 @@
}
ext4_dir_set_csum(inode_ref, (void *)old_data_block->data);
ext4_dir_set_csum(inode_ref, (void *)new_data_block_tmp.data);
- ext4_bcache_set_dirty(old_data_block->buf);
- ext4_bcache_set_dirty(new_data_block_tmp.buf);
+ ext4_trans_set_block_dirty(old_data_block->buf);
+ ext4_trans_set_block_dirty(new_data_block_tmp.buf);
free(sort);
free(entry_buffer);
@@ -1142,7 +1142,7 @@
/* load new block */
struct ext4_block b;
- r = ext4_block_get_noread(ino_ref->fs->bdev, &b, new_fblk);
+ r = ext4_trans_block_get_noread(ino_ref->fs->bdev, &b, new_fblk);
if (r != EOK)
return r;
@@ -1187,7 +1187,7 @@
ino_ref,
(struct ext4_dir_en *)
dxb->b.data);
- ext4_bcache_set_dirty(dxb->b.buf);
+ ext4_trans_set_block_dirty(dxb->b.buf);
struct ext4_block block_tmp = dxb->b;
@@ -1205,11 +1205,11 @@
new_iblk);
ext4_dir_set_dx_csum(ino_ref, (void*)dx_blks[0].b.data);
ext4_dir_set_dx_csum(ino_ref, (void*)dx_blks[1].b.data);
- ext4_bcache_set_dirty(dx_blks[0].b.buf);
- ext4_bcache_set_dirty(dx_blks[1].b.buf);
+ ext4_trans_set_block_dirty(dx_blks[0].b.buf);
+ ext4_trans_set_block_dirty(dx_blks[1].b.buf);
ext4_dir_set_dx_csum(ino_ref, (void *)b.data);
- ext4_bcache_set_dirty(b.buf);
+ ext4_trans_set_block_dirty(b.buf);
return ext4_block_set(ino_ref->fs->bdev, &b);
} else {
size_t sz;
@@ -1241,8 +1241,8 @@
ext4_dir_set_dx_csum(ino_ref, (void*)dx_blks[0].b.data);
ext4_dir_set_dx_csum(ino_ref, (void*)dx_blks[1].b.data);
- ext4_bcache_set_dirty(dx_blks[0].b.buf);
- ext4_bcache_set_dirty(dx_blks[1].b.buf);
+ ext4_trans_set_block_dirty(dx_blks[0].b.buf);
+ ext4_trans_set_block_dirty(dx_blks[1].b.buf);
}
}
@@ -1263,7 +1263,7 @@
struct ext4_fs *fs = parent->fs;
struct ext4_block root_blk;
- r = ext4_block_get(fs->bdev, &root_blk, rblock_addr);
+ r = ext4_trans_block_get(fs->bdev, &root_blk, rblock_addr);
if (r != EOK)
return r;
@@ -1316,7 +1316,7 @@
goto release_target_index;
struct ext4_block target_block;
- r = ext4_block_get(fs->bdev, &target_block, leaf_block_addr);
+ r = ext4_trans_block_get(fs->bdev, &target_block, leaf_block_addr);
if (r != EOK)
goto release_index;
@@ -1394,7 +1394,7 @@
return rc;
struct ext4_block block;
- rc = ext4_block_get(dir->fs->bdev, &block, fblock);
+ rc = ext4_trans_block_get(dir->fs->bdev, &block, fblock);
if (rc != EOK)
return rc;
@@ -1414,7 +1414,7 @@
ext4_dx_dot_en_set_inode(&root->dots[1], parent_inode);
ext4_dir_set_dx_csum(dir, (void *)block.data);
- ext4_bcache_set_dirty(block.buf);
+ ext4_trans_set_block_dirty(block.buf);
return ext4_block_set(dir->fs->bdev, &block);
}
--- a/lwext4/ext4_extent.c
+++ b/lwext4/ext4_extent.c
@@ -257,7 +257,7 @@
return rc;
}
- int rc = ext4_block_get(inode_ref->fs->bdev, &block, child);
+ int rc = ext4_trans_block_get(inode_ref->fs->bdev, &block, child);
if (rc != EOK)
return rc;
if (!ext4_extent_verify_block_csum(inode_ref,
@@ -342,7 +342,7 @@
ext4_extent_index_get_leaf(tmp_path[pos].index);
struct ext4_block block;
- rc = ext4_block_get(inode_ref->fs->bdev, &block, fblock);
+ rc = ext4_trans_block_get(inode_ref->fs->bdev, &block, fblock);
if (rc != EOK)
goto cleanup;
@@ -419,7 +419,7 @@
ext4_fsblk_t fblock = ext4_extent_index_get_leaf(index);
uint32_t i;
struct ext4_block block;
- int rc = ext4_block_get(inode_ref->fs->bdev, &block, fblock);
+ int rc = ext4_trans_block_get(inode_ref->fs->bdev, &block, fblock);
if (rc != EOK)
return rc;
@@ -534,7 +534,7 @@
ext4_extent_header_set_entries_count(path_ptr->header, entries);
ext4_extent_block_csum_set(inode_ref, path_ptr->header);
- ext4_bcache_set_dirty(path_ptr->block.buf);
+ ext4_trans_set_block_dirty(path_ptr->block.buf);
/* If leaf node is empty, parent entry must be modified */
bool remove_parent_record = false;
@@ -576,7 +576,7 @@
ext4_extent_header_set_entries_count(path_ptr->header, entries);
ext4_extent_block_csum_set(inode_ref, path_ptr->header);
- ext4_bcache_set_dirty(path_ptr->block.buf);
+ ext4_trans_set_block_dirty(path_ptr->block.buf);
/* Free the node if it is empty */
if ((entries == 0) && (path_ptr != path)) {
@@ -651,7 +651,7 @@
struct ext4_block block;
rc =
- ext4_block_get_noread(inode_ref->fs->bdev, &block, fblock);
+ ext4_trans_block_get_noread(inode_ref->fs->bdev, &block, fblock);
if (rc != EOK) {
ext4_balloc_free_block(inode_ref, fblock);
return rc;
@@ -704,7 +704,7 @@
ext4_extent_header_set_generation(path_ptr->header, 0);
ext4_extent_block_csum_set(inode_ref, path_ptr->header);
- ext4_bcache_set_dirty(path_ptr->block.buf);
+ ext4_trans_set_block_dirty(path_ptr->block.buf);
/* Jump to the preceding item */
path_ptr--;
@@ -730,7 +730,7 @@
ext4_extent_header_set_entries_count(path_ptr->header,
entries + 1);
ext4_extent_block_csum_set(inode_ref, path_ptr->header);
- ext4_bcache_set_dirty(path_ptr->block.buf);
+ ext4_trans_set_block_dirty(path_ptr->block.buf);
/* No more splitting needed */
return EOK;
@@ -755,7 +755,7 @@
return rc;
struct ext4_block block;
- rc = ext4_block_get_noread(inode_ref->fs->bdev, &block, new_fblock);
+ rc = ext4_trans_block_get_noread(inode_ref->fs->bdev, &block, new_fblock);
if (rc != EOK)
return rc;
@@ -813,7 +813,7 @@
limit);
ext4_extent_block_csum_set(inode_ref, old_root->header);
- ext4_bcache_set_dirty(old_root->block.buf);
+ ext4_trans_set_block_dirty(old_root->block.buf);
/* Re-initialize new root metadata */
new_root->depth = root_depth + 1;
@@ -831,7 +831,7 @@
/* Since new_root belongs to on-disk inode,
* we don't do checksum here */
- ext4_bcache_set_dirty(new_root->block.buf);
+ ext4_trans_set_block_dirty(new_root->block.buf);
} else {
if (path->depth) {
path->index =
@@ -848,7 +848,7 @@
ext4_extent_header_set_entries_count(path->header, entries + 1);
/* Since new_root belongs to on-disk inode,
* we don't do checksum here */
- ext4_bcache_set_dirty(path->block.buf);
+ ext4_trans_set_block_dirty(path->block.buf);
}
return EOK;
@@ -928,7 +928,7 @@
}
ext4_extent_block_csum_set(inode_ref, path_ptr->header);
- ext4_bcache_set_dirty(path_ptr->block.buf);
+ ext4_trans_set_block_dirty(path_ptr->block.buf);
goto finish;
} else {
@@ -970,7 +970,7 @@
}
ext4_extent_block_csum_set(inode_ref, path_ptr->header);
- ext4_bcache_set_dirty(path_ptr->block.buf);
+ ext4_trans_set_block_dirty(path_ptr->block.buf);
goto finish;
}
@@ -1011,7 +1011,7 @@
}
ext4_extent_block_csum_set(inode_ref, path_ptr->header);
- ext4_bcache_set_dirty(path_ptr->block.buf);
+ ext4_trans_set_block_dirty(path_ptr->block.buf);
finish:
/* Set return values */
--- a/lwext4/ext4_extent_full.c
+++ b/lwext4/ext4_extent_full.c
@@ -353,7 +353,7 @@
struct ext4_extent_path *path)
{
if (path->block.lb_id)
- ext4_bcache_set_dirty(path->block.buf);
+ ext4_trans_set_block_dirty(path->block.buf);
else
inode_ref->dirty = true;
@@ -440,7 +440,7 @@
{
int err;
- err = ext4_block_get(inode_ref->fs->bdev, bh, pblk);
+ err = ext4_trans_block_get(inode_ref->fs->bdev, bh, pblk);
if (err != EOK)
goto errout;
@@ -627,7 +627,7 @@
goto cleanup;
/* For write access.# */
- ret = ext4_block_get_noread(inode_ref->fs->bdev, &bh, newblock);
+ ret = ext4_trans_block_get_noread(inode_ref->fs->bdev, &bh, newblock);
if (ret != EOK)
goto cleanup;
@@ -798,7 +798,7 @@
} else if (bh.lb_id) {
/* If we got a sibling leaf. */
ext4_extent_block_csum_set(inode_ref, ext_block_hdr(&bh));
- ext4_bcache_set_dirty(bh.buf);
+ ext4_trans_set_block_dirty(bh.buf);
spt->path.p_block = ext4_idx_pblock(ix);
spt->path.depth = to_le16(eh->depth);
@@ -1070,7 +1070,7 @@
} else if (bh.lb_id) {
/* If we got a sibling leaf. */
ext4_extent_block_csum_set(inode_ref, ext_block_hdr(&bh));
- ext4_bcache_set_dirty(bh.buf);
+ ext4_trans_set_block_dirty(bh.buf);
spt->path.p_block = ext4_ext_pblock(ex);
spt->path.depth = to_le16(eh->depth);
@@ -1129,7 +1129,7 @@
return err;
/* # */
- err = ext4_block_get_noread(inode_ref->fs->bdev, &bh, newblock);
+ err = ext4_trans_block_get_noread(inode_ref->fs->bdev, &bh, newblock);
if (err != EOK) {
ext4_ext_free_blocks(inode_ref, newblock, 1, 0);
return err;
@@ -1166,7 +1166,7 @@
}
neh->depth = to_le16(to_le16(neh->depth) + 1);
- ext4_bcache_set_dirty(bh.buf);
+ ext4_trans_set_block_dirty(bh.buf);
inode_ref->dirty = true;
ext4_block_set(inode_ref->fs->bdev, &bh);
@@ -1723,12 +1723,12 @@
uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb);
for (i = 0; i < blocks_count; i++) {
struct ext4_block bh = EXT4_BLOCK_ZERO();
- err = ext4_block_get_noread(inode_ref->fs->bdev, &bh, block + i);
+ err = ext4_trans_block_get_noread(inode_ref->fs->bdev, &bh, block + i);
if (err != EOK)
break;
memset(bh.data, 0, block_size);
- ext4_bcache_set_dirty(bh.buf);
+ ext4_trans_set_block_dirty(bh.buf);
err = ext4_block_set(inode_ref->fs->bdev, &bh);
if (err != EOK)
break;
--- a/lwext4/ext4_fs.c
+++ b/lwext4/ext4_fs.c
@@ -302,7 +302,7 @@
uint32_t inode_table_bcnt = inodes_per_group * inode_size / block_size;
struct ext4_block block_bitmap;
- rc = ext4_block_get_noread(bg_ref->fs->bdev, &block_bitmap, bmp_blk);
+ rc = ext4_trans_block_get_noread(bg_ref->fs->bdev, &block_bitmap, bmp_blk);
if (rc != EOK)
return rc;
@@ -356,7 +356,7 @@
* of bitmap ), set rest of the block bitmap to 1
*/
ext4_fs_mark_bitmap_end(group_blocks, block_size * 8, block_bitmap.data);
- ext4_bcache_set_dirty(block_bitmap.buf);
+ ext4_trans_set_block_dirty(block_bitmap.buf);
ext4_balloc_set_bitmap_csum(sb, bg_ref->block_group, block_bitmap.data);
bg_ref->dirty = true;
@@ -379,7 +379,7 @@
ext4_fsblk_t bitmap_block_addr = ext4_bg_get_inode_bitmap(bg, sb);
struct ext4_block b;
- rc = ext4_block_get_noread(bg_ref->fs->bdev, &b, bitmap_block_addr);
+ rc = ext4_trans_block_get_noread(bg_ref->fs->bdev, &b, bitmap_block_addr);
if (rc != EOK)
return rc;
@@ -399,7 +399,7 @@
if (i < end_bit)
memset(b.data + (i >> 3), 0xff, (end_bit - i) >> 3);
- ext4_bcache_set_dirty(b.buf);
+ ext4_trans_set_block_dirty(b.buf);
ext4_ialloc_set_bitmap_csum(sb, bg, b.data);
bg_ref->dirty = true;
@@ -435,12 +435,12 @@
/* Initialization of all itable blocks */
for (fblock = first_block; fblock <= last_block; ++fblock) {
struct ext4_block b;
- int rc = ext4_block_get_noread(bg_ref->fs->bdev, &b, fblock);
+ int rc = ext4_trans_block_get_noread(bg_ref->fs->bdev, &b, fblock);
if (rc != EOK)
return rc;
memset(b.data, 0, block_size);
- ext4_bcache_set_dirty(b.buf);
+ ext4_trans_set_block_dirty(b.buf);
ext4_block_set(bg_ref->fs->bdev, &b);
if (rc != EOK)
@@ -566,7 +566,7 @@
uint32_t offset = (bgid % dsc_cnt) * ext4_sb_get_desc_size(&fs->sb);
- int rc = ext4_block_get(fs->bdev, &ref->block, block_id);
+ int rc = ext4_trans_block_get(fs->bdev, &ref->block, block_id);
if (rc != EOK)
return rc;
@@ -629,7 +629,7 @@
ref->block_group->checksum = to_le16(cs);
/* Mark block dirty for writing changes to physical device */
- ext4_bcache_set_dirty(ref->block.buf);
+ ext4_trans_set_block_dirty(ref->block.buf);
}
/* Put back block, that contains block group descriptor */
@@ -745,7 +745,7 @@
ext4_fsblk_t block_id =
inode_table_start + (byte_offset_in_group / block_size);
- rc = ext4_block_get(fs->bdev, &ref->block, block_id);
+ rc = ext4_trans_block_get(fs->bdev, &ref->block, block_id);
if (rc != EOK) {
return rc;
}
@@ -781,7 +781,7 @@
if (ref->dirty) {
/* Mark block dirty for writing changes to physical device */
ext4_fs_set_inode_checksum(ref);
- ext4_bcache_set_dirty(ref->block.buf);
+ ext4_trans_set_block_dirty(ref->block.buf);
}
/* Put back block, that contains i-node */
@@ -937,7 +937,7 @@
/* 2) Double indirect */
fblock = ext4_inode_get_indirect_block(inode_ref->inode, 1);
if (fblock != 0) {
- int rc = ext4_block_get(fs->bdev, &block, fblock);
+ int rc = ext4_trans_block_get(fs->bdev, &block, fblock);
if (rc != EOK)
return rc;
@@ -968,7 +968,7 @@
fblock = ext4_inode_get_indirect_block(inode_ref->inode, 2);
if (fblock == 0)
goto finish;
- rc = ext4_block_get(fs->bdev, &block, fblock);
+ rc = ext4_trans_block_get(fs->bdev, &block, fblock);
if (rc != EOK)
return rc;
@@ -978,7 +978,7 @@
if (ind_block == 0)
continue;
- rc = ext4_block_get(fs->bdev, &subblock,
+ rc = ext4_trans_block_get(fs->bdev, &subblock,
ind_block);
if (rc != EOK) {
ext4_block_set(fs->bdev, &block);
@@ -1108,7 +1108,7 @@
if (current_block == 0)
return EOK;
- int rc = ext4_block_get(fs->bdev, &block, current_block);
+ int rc = ext4_trans_block_get(fs->bdev, &block, current_block);
if (rc != EOK)
return rc;
@@ -1118,7 +1118,7 @@
/* Set zero if physical data block address found */
if (level == 1) {
((uint32_t *)block.data)[offset_in_block] = to_le32(0);
- ext4_bcache_set_dirty(block.buf);
+ ext4_trans_set_block_dirty(block.buf);
}
rc = ext4_block_set(fs->bdev, &block);
@@ -1380,7 +1380,7 @@
*/
while (l > 0) {
/* Load indirect block */
- int rc = ext4_block_get(fs->bdev, &block, current_block);
+ int rc = ext4_trans_block_get(fs->bdev, &block, current_block);
if (rc != EOK)
return rc;
@@ -1499,7 +1499,7 @@
inode_ref->dirty = true;
/* Load newly allocated block */
- rc = ext4_block_get_noread(fs->bdev, &new_block, new_blk);
+ rc = ext4_trans_block_get_noread(fs->bdev, &new_block, new_blk);
if (rc != EOK) {
ext4_balloc_free_block(inode_ref, new_blk);
return rc;
@@ -1507,7 +1507,7 @@
/* Initialize new block */
memset(new_block.data, 0, block_size);
- ext4_bcache_set_dirty(new_block.buf);
+ ext4_trans_set_block_dirty(new_block.buf);
/* Put back the allocated block */
rc = ext4_block_set(fs->bdev, &new_block);
@@ -1522,7 +1522,7 @@
* or find null reference meaning we are dealing with sparse file
*/
while (l > 0) {
- int rc = ext4_block_get(fs->bdev, &block, current_block);
+ int rc = ext4_trans_block_get(fs->bdev, &block, current_block);
if (rc != EOK)
return rc;
@@ -1544,7 +1544,7 @@
}
/* Load newly allocated block */
- rc = ext4_block_get_noread(fs->bdev, &new_block,
+ rc = ext4_trans_block_get_noread(fs->bdev, &new_block,
new_blk);
if (rc != EOK) {
@@ -1554,7 +1554,7 @@
/* Initialize allocated block */
memset(new_block.data, 0, block_size);
- ext4_bcache_set_dirty(new_block.buf);
+ ext4_trans_set_block_dirty(new_block.buf);
rc = ext4_block_set(fs->bdev, &new_block);
if (rc != EOK) {
@@ -1565,7 +1565,7 @@
/* Write block address to the parent */
uint32_t * p = (uint32_t * )block.data;
p[off_in_blk] = to_le32((uint32_t)new_blk);
- ext4_bcache_set_dirty(block.buf);
+ ext4_trans_set_block_dirty(block.buf);
current_block = new_blk;
}
@@ -1573,7 +1573,7 @@
if (l == 1) {
uint32_t * p = (uint32_t * )block.data;
p[off_in_blk] = to_le32((uint32_t)fblock);
- ext4_bcache_set_dirty(block.buf);
+ ext4_trans_set_block_dirty(block.buf);
}
rc = ext4_block_set(fs->bdev, &block);
--- a/lwext4/ext4_ialloc.c
+++ b/lwext4/ext4_ialloc.c
@@ -169,7 +169,7 @@
ext4_bg_get_inode_bitmap(bg, sb);
struct ext4_block b;
- rc = ext4_block_get(fs->bdev, &b, bitmap_block_addr);
+ rc = ext4_trans_block_get(fs->bdev, &b, bitmap_block_addr);
if (rc != EOK)
return rc;
@@ -184,7 +184,7 @@
uint32_t index_in_group = ext4_ialloc_inode_to_bgidx(sb, index);
ext4_bmap_bit_clr(b.data, index_in_group);
ext4_ialloc_set_bitmap_csum(sb, bg, b.data);
- ext4_bcache_set_dirty(b.buf);
+ ext4_trans_set_block_dirty(b.buf);
/* Put back the block with bitmap */
rc = ext4_block_set(fs->bdev, &b);
@@ -260,7 +260,7 @@
uint32_t bmp_blk_add = ext4_bg_get_inode_bitmap(bg, sb);
struct ext4_block b;
- rc = ext4_block_get(fs->bdev, &b, bmp_blk_add);
+ rc = ext4_trans_block_get(fs->bdev, &b, bmp_blk_add);
if (rc != EOK) {
ext4_fs_put_block_group_ref(&bg_ref);
return rc;
@@ -300,7 +300,7 @@
/* Free i-node found, save the bitmap */
ext4_ialloc_set_bitmap_csum(sb,bg,
b.data);
- ext4_bcache_set_dirty(b.buf);
+ ext4_trans_set_block_dirty(b.buf);
ext4_block_set(fs->bdev, &b);
if (rc != EOK) {
--- /dev/null
+++ b/lwext4/ext4_trans.c
@@ -1,0 +1,115 @@
+/*
+ * Copyright (c) 2015 Grzegorz Kostka ([email protected])
+ * Copyright (c) 2015 Kaho Ng ([email protected])
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup lwext4
+ * @{
+ */
+/**
+ * @file ext4.h
+ * @brief Ext4 transaction buffer operations.
+ */
+
+#include "ext4_config.h"
+#include "ext4_types.h"
+#include "ext4_journal.h"
+
+static int ext4_trans_get_write_access(struct ext4_fs *fs,
+ struct ext4_block *block)
+{
+ int r = EOK;
+ if (fs->jbd_journal && fs->curr_trans) {
+ struct jbd_journal *journal = fs->jbd_journal;
+ struct jbd_trans *trans = fs->curr_trans;
+ r = jbd_trans_get_access(journal, trans, block);
+ }
+ return r;
+}
+
+int ext4_trans_set_block_dirty(struct ext4_buf *buf)
+{
+ int r = EOK;
+ struct ext4_fs *fs = buf->bc->bdev->fs;
+ struct ext4_block block = {
+ .lb_id = buf->lba,
+ .data = buf->data,
+ .buf = buf
+ };
+
+ if (fs->jbd_journal && fs->curr_trans) {
+ struct jbd_trans *trans = fs->curr_trans;
+ r = jbd_trans_set_block_dirty(trans, &block);
+ } else
+ ext4_bcache_set_dirty(buf);
+
+ return r;
+}
+
+int ext4_trans_block_get_noread(struct ext4_blockdev *bdev,
+ struct ext4_block *b,
+ uint64_t lba)
+{
+ int r = ext4_block_get_noread(bdev, b, lba);
+ if (r != EOK)
+ return r;
+
+ if((r = ext4_trans_get_write_access(bdev->fs, b)) != EOK)
+ ext4_block_set(bdev, b);
+
+ return r;
+}
+
+int ext4_trans_block_get(struct ext4_blockdev *bdev,
+ struct ext4_block *b,
+ uint64_t lba)
+{
+ int r = ext4_block_get(bdev, b, lba);
+ if (r != EOK)
+ return r;
+
+ if((r = ext4_trans_get_write_access(bdev->fs, b)) != EOK)
+ ext4_block_set(bdev, b);
+
+ return r;
+}
+
+int ext4_trans_try_revoke_block(struct ext4_blockdev *bdev,
+ uint64_t lba)
+{
+ int r = EOK;
+ struct ext4_fs *fs = bdev->fs;
+ if (fs->jbd_journal && fs->curr_trans) {
+ struct jbd_trans *trans = fs->curr_trans;
+ jbd_trans_try_revoke_block(trans, lba);
+ }
+ return r;
+}
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_trans.h
@@ -1,0 +1,90 @@
+/*
+ * Copyright (c) 2015 Grzegorz Kostka ([email protected])
+ * Copyright (c) 2015 Kaho Ng ([email protected])
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup lwext4
+ * @{
+ */
+/**
+ * @file ext4_trans.h
+ * @brief Transaction handle functions
+ */
+
+#ifndef EXT4_TRANS_H
+#define EXT4_TRANS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ext4_config.h"
+#include "ext4_types.h"
+
+
+/**@brief Mark a buffer dirty and add it to the current transaction.
+ * @param buf buffer
+ * @return standard error code*/
+int ext4_trans_set_block_dirty(struct ext4_buf *buf);
+
+/**@brief Block get function (through cache, don't read).
+ * jbd_trans_get_access would be called in order to
+ * get write access to the buffer.
+ * @param bdev block device descriptor
+ * @param b block descriptor
+ * @param lba logical block address
+ * @return standard error code*/
+int ext4_trans_block_get_noread(struct ext4_blockdev *bdev,
+ struct ext4_block *b,
+ uint64_t lba);
+
+/**@brief Block get function (through cache).
+ * jbd_trans_get_access would be called in order to
+ * get write access to the buffer.
+ * @param bdev block device descriptor
+ * @param b block descriptor
+ * @param lba logical block address
+ * @return standard error code*/
+int ext4_trans_block_get(struct ext4_blockdev *bdev,
+ struct ext4_block *b,
+ uint64_t lba);
+
+/**@brief Try to add block to be revoked to the current transaction.
+ * @param bdev block device descriptor
+ * @param lba logical block address
+ * @return standard error code*/
+int ext4_trans_try_revoke_block(struct ext4_blockdev *bdev,
+ uint64_t lba);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EXT4_TRANS_H */
+
+/**
+ * @}
+ */
--- a/lwext4/ext4_xattr.c
+++ b/lwext4/ext4_xattr.c
@@ -543,7 +543,7 @@
if (ret != EOK)
goto Finish;
- ret = ext4_block_get(xattr_ref->fs->bdev, &xattr_ref->block,
+ ret = ext4_trans_block_get(xattr_ref->fs->bdev, &xattr_ref->block,
xattr_block);
if (ret != EOK) {
ext4_balloc_free_block(xattr_ref->inode_ref,
@@ -655,7 +655,7 @@
block_data = (char *)block_header + block_size_rem;
block_size_rem -= sizeof(struct ext4_xattr_header);
- ext4_bcache_set_dirty(xattr_ref->block.buf);
+ ext4_trans_set_block_dirty(xattr_ref->block.buf);
} else {
/* We don't need an extra block.*/
if (xattr_ref->block_loaded) {
@@ -677,7 +677,7 @@
&xattr_ref->fs->sb, 0);
xattr_ref->inode_ref->dirty = true;
- ext4_bcache_set_dirty(xattr_ref->block.buf);
+ ext4_trans_set_block_dirty(xattr_ref->block.buf);
}
}
}
@@ -726,7 +726,7 @@
ext4_xattr_set_block_checksum(xattr_ref->inode_ref,
xattr_ref->block.lb_id,
block_header);
- ext4_bcache_set_dirty(xattr_ref->block.buf);
+ ext4_trans_set_block_dirty(xattr_ref->block.buf);
}
Finish:
@@ -837,7 +837,7 @@
ref->ea_size = 0;
ref->iter_from = NULL;
if (xattr_block) {
- rc = ext4_block_get(fs->bdev, &ref->block, xattr_block);
+ rc = ext4_trans_block_get(fs->bdev, &ref->block, xattr_block);
if (rc != EOK)
return EIO;