diff options
| author | ngkaho1234 <ngkaho1234@gmail.com> | 2015-12-28 13:05:04 +0000 |
|---|---|---|
| committer | gkostka <kostka.grzegorz@gmail.com> | 2015-12-29 10:41:40 +0100 |
| commit | 0c7f3604a3e2f26da99f8e126098ce8520139fbd (patch) | |
| tree | 9e7a643d1e7e0954e662709133aca6297e9d143c | |
| parent | f3e06a2a6d91b4502fb0e0f70a79fb6daaf601e1 (diff) | |
Introduce initial support of ext3/4 journalling.
To achieve this, a glue layer between block cache and lwext4 core routines
is added.
| -rw-r--r-- | lwext4/ext4.c | 54 | ||||
| -rw-r--r-- | lwext4/ext4.h | 3 | ||||
| -rw-r--r-- | lwext4/ext4_balloc.c | 38 | ||||
| -rw-r--r-- | lwext4/ext4_bcache.c | 1 | ||||
| -rw-r--r-- | lwext4/ext4_bcache.h | 3 | ||||
| -rw-r--r-- | lwext4/ext4_blockdev.h | 4 | ||||
| -rw-r--r-- | lwext4/ext4_dir.c | 16 | ||||
| -rw-r--r-- | lwext4/ext4_dir_idx.c | 46 | ||||
| -rw-r--r-- | lwext4/ext4_extent.c | 30 | ||||
| -rw-r--r-- | lwext4/ext4_extent_full.c | 18 | ||||
| -rw-r--r-- | lwext4/ext4_fs.c | 46 | ||||
| -rw-r--r-- | lwext4/ext4_ialloc.c | 8 | ||||
| -rw-r--r-- | lwext4/ext4_trans.c | 115 | ||||
| -rw-r--r-- | lwext4/ext4_trans.h | 90 | ||||
| -rw-r--r-- | lwext4/ext4_xattr.c | 10 |
15 files changed, 356 insertions, 126 deletions
diff --git a/lwext4/ext4.c b/lwext4/ext4.c index 2857fc6..8663001 100644 --- a/lwext4/ext4.c +++ b/lwext4/ext4.c @@ -251,7 +251,7 @@ static int ext4_link(struct ext4_mountpoint *mp, struct ext4_inode_ref *parent, 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 @@ int ext4_mount(const char *dev_name, const char *mount_point) } return r; } + bd->fs = &mp->fs; return r; } @@ -437,7 +438,7 @@ int ext4_umount(const char *mount_point) r = ext4_fs_fini(&mp->fs); if (r != EOK) - return r; + goto Finish; mp->mounted = 0; @@ -446,8 +447,10 @@ int ext4_umount(const char *mount_point) 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 @@ static void ext4_trans_abort(struct ext4_mountpoint *mp) } } -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 @@ int ext4_fsymlink(const char *target, const char *path) 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 @@ int ext4_setxattr(const char *path, const char *name, size_t name_len, 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 @@ int ext4_setxattr(const char *path, const char *name, size_t name_len, 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 @@ int ext4_removexattr(const char *path, const char *name, size_t name_len) 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 @@ int ext4_removexattr(const char *path, const char *name, size_t name_len) 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; diff --git a/lwext4/ext4.h b/lwext4/ext4.h index 09abcbc..9679eb8 100644 --- a/lwext4/ext4.h +++ b/lwext4/ext4.h @@ -182,6 +182,9 @@ int ext4_mount(const char *dev_name, const char *mount_point); * @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 diff --git a/lwext4/ext4_balloc.c b/lwext4/ext4_balloc.c index b840bea..8bba9f7 100644 --- a/lwext4/ext4_balloc.c +++ b/lwext4/ext4_balloc.c @@ -165,7 +165,7 @@ int ext4_balloc_free_block(struct ext4_inode_ref *inode_ref, ext4_fsblk_t baddr) 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 @@ int ext4_balloc_free_block(struct ext4_inode_ref *inode_ref, ext4_fsblk_t baddr) /* 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 @@ int ext4_balloc_free_block(struct ext4_inode_ref *inode_ref, ext4_fsblk_t baddr) 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 @@ int ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref, 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 @@ int ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref, /* 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 @@ int ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref, 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 @@ int ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref, /* 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 @@ int ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref, 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 @@ int ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref, 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 @@ int ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref, 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 @@ goal_failed: /* 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 @@ goal_failed: 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 @@ int ext4_balloc_try_alloc_block(struct ext4_inode_ref *inode_ref, 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 @@ int ext4_balloc_try_alloc_block(struct ext4_inode_ref *inode_ref, 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 */ diff --git a/lwext4/ext4_bcache.c b/lwext4/ext4_bcache.c index 628735a..c1da95d 100644 --- a/lwext4/ext4_bcache.c +++ b/lwext4/ext4_bcache.c @@ -132,6 +132,7 @@ ext4_buf_alloc(struct ext4_bcache *bc, uint64_t lba) buf->lba = lba; buf->data = data; + buf->bc = bc; return buf; } diff --git a/lwext4/ext4_bcache.h b/lwext4/ext4_bcache.h index c83f1b9..ca606ad 100644 --- a/lwext4/ext4_bcache.h +++ b/lwext4/ext4_bcache.h @@ -85,6 +85,9 @@ struct ext4_buf { /**@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; diff --git a/lwext4/ext4_blockdev.h b/lwext4/ext4_blockdev.h index aeb348b..f5329ec 100644 --- a/lwext4/ext4_blockdev.h +++ b/lwext4/ext4_blockdev.h @@ -42,6 +42,7 @@ extern "C" { #include "ext4_config.h" #include "ext4_bcache.h" +#include "ext4_trans.h" #include "ext4_debug.h" #include <stdbool.h> @@ -122,6 +123,9 @@ struct ext4_blockdev { /**@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.*/ diff --git a/lwext4/ext4_dir.c b/lwext4/ext4_dir.c index b22e88b..62909e4 100644 --- a/lwext4/ext4_dir.c +++ b/lwext4/ext4_dir.c @@ -239,7 +239,7 @@ static int ext4_dir_iterator_seek(struct ext4_dir_iter *it, uint64_t pos) 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 @@ int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name, 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 @@ int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name, /* 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 @@ int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name, } 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 @@ int ext4_dir_find_entry(struct ext4_dir_search_result *result, /* 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 @@ int ext4_dir_remove_entry(struct ext4_inode_ref *parent, const char *name, 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 @@ int ext4_dir_try_insert_entry(struct ext4_sblock *sb, 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 @@ int ext4_dir_try_insert_entry(struct ext4_sblock *sb, 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; } } diff --git a/lwext4/ext4_dir_idx.c b/lwext4/ext4_dir_idx.c index 1b78905..28ec00c 100644 --- a/lwext4/ext4_dir_idx.c +++ b/lwext4/ext4_dir_idx.c @@ -353,7 +353,7 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir, struct ext4_inode_ref *parent) 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 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir, struct ext4_inode_ref *parent) } 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 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir, struct ext4_inode_ref *parent) 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 @@ int ext4_dir_dx_init(struct ext4_inode_ref *dir, struct ext4_inode_ref *parent) 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 @@ static int ext4_dir_dx_get_leaf(struct ext4_hash_info *hinfo, 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 @@ static int ext4_dir_dx_next_block(struct ext4_inode_ref *inode_ref, 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 @@ int ext4_dir_dx_find_entry(struct ext4_dir_search_result *result, 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 @@ int ext4_dir_dx_find_entry(struct ext4_dir_search_result *result, 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_insert_entry(struct ext4_inode_ref *inode_ref __unused, 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 @@ static int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref, /* 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 @@ static int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref, } 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 @@ ext4_dir_dx_split_index(struct ext4_inode_ref *ino_ref, /* 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 @@ ext4_dir_dx_split_index(struct ext4_inode_ref *ino_ref, 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 @@ ext4_dir_dx_split_index(struct ext4_inode_ref *ino_ref, 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_dx_split_index(struct ext4_inode_ref *ino_ref, 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 @@ int ext4_dir_dx_add_entry(struct ext4_inode_ref *parent, 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 @@ int ext4_dir_dx_add_entry(struct ext4_inode_ref *parent, 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 @@ int ext4_dir_dx_reset_parent_inode(struct ext4_inode_ref *dir, 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 @@ int ext4_dir_dx_reset_parent_inode(struct ext4_inode_ref *dir, 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); } diff --git a/lwext4/ext4_extent.c b/lwext4/ext4_extent.c index d6f373b..831cb48 100644 --- a/lwext4/ext4_extent.c +++ b/lwext4/ext4_extent.c @@ -257,7 +257,7 @@ ext4_extent_find_block(struct ext4_inode_ref *inode_ref, uint32_t iblock, 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 @@ static int ext4_extent_find_extent(struct ext4_inode_ref *inode_ref, 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 @@ static int ext4_extent_release_branch(struct ext4_inode_ref *inode_ref, 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 @@ int ext4_extent_remove_space(struct ext4_inode_ref *inode_ref, ext4_lblk_t from, 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 @@ int ext4_extent_remove_space(struct ext4_inode_ref *inode_ref, ext4_lblk_t from, 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 @@ static int ext4_extent_append_extent(struct ext4_inode_ref *inode_ref, 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 @@ static int ext4_extent_append_extent(struct ext4_inode_ref *inode_ref, 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 @@ static int ext4_extent_append_extent(struct ext4_inode_ref *inode_ref, 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 @@ static int ext4_extent_append_extent(struct ext4_inode_ref *inode_ref, 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 @@ static int ext4_extent_append_extent(struct ext4_inode_ref *inode_ref, 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 @@ static int ext4_extent_append_extent(struct ext4_inode_ref *inode_ref, /* 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 @@ static int ext4_extent_append_extent(struct ext4_inode_ref *inode_ref, 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_append_block(struct ext4_inode_ref *inode_ref, uint32_t *iblock, } 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_append_block(struct ext4_inode_ref *inode_ref, uint32_t *iblock, } 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 @@ append_extent: } 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 */ diff --git a/lwext4/ext4_extent_full.c b/lwext4/ext4_extent_full.c index 2d34d67..3bc1836 100644 --- a/lwext4/ext4_extent_full.c +++ b/lwext4/ext4_extent_full.c @@ -353,7 +353,7 @@ static int ext4_ext_dirty(struct ext4_inode_ref *inode_ref, 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 @@ static int read_extent_tree_block(struct ext4_inode_ref *inode_ref, { 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 @@ static int ext4_ext_split_node(struct ext4_inode_ref *inode_ref, 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 @@ out: } 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 @@ out: } 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 @@ static int ext4_ext_grow_indepth(struct ext4_inode_ref *inode_ref, 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 @@ static int ext4_ext_grow_indepth(struct ext4_inode_ref *inode_ref, } 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 @@ static int ext4_ext_zero_unwritten_range(struct ext4_inode_ref *inode_ref, 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; diff --git a/lwext4/ext4_fs.c b/lwext4/ext4_fs.c index 7250839..f76cda8 100644 --- a/lwext4/ext4_fs.c +++ b/lwext4/ext4_fs.c @@ -302,7 +302,7 @@ static int ext4_fs_init_block_bitmap(struct ext4_block_group_ref *bg_ref) 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 @@ static int ext4_fs_init_block_bitmap(struct ext4_block_group_ref *bg_ref) * 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 @@ static int ext4_fs_init_inode_bitmap(struct ext4_block_group_ref *bg_ref) 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 @@ static int ext4_fs_init_inode_bitmap(struct ext4_block_group_ref *bg_ref) 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 @@ static int ext4_fs_init_inode_table(struct ext4_block_group_ref *bg_ref) /* 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 @@ int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid, 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 @@ int ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref) 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_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index, 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 @@ int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref) 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 @@ int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref) /* 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 @@ int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref) 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 @@ int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref) 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 @@ static int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref, 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 @@ static int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref, /* 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 @@ static int ext4_fs_get_inode_dblk_idx_internal(struct ext4_inode_ref *inode_ref, */ 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 @@ static int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, 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 @@ static int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, /* 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 @@ static int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, * 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 @@ static int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, } /* 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 @@ static int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, /* 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 @@ static int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, /* 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 @@ static int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, 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); diff --git a/lwext4/ext4_ialloc.c b/lwext4/ext4_ialloc.c index 7dad65d..a612a75 100644 --- a/lwext4/ext4_ialloc.c +++ b/lwext4/ext4_ialloc.c @@ -169,7 +169,7 @@ int ext4_ialloc_free_inode(struct ext4_fs *fs, uint32_t index, bool is_dir) 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 @@ int ext4_ialloc_free_inode(struct ext4_fs *fs, uint32_t index, bool is_dir) 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 @@ int ext4_ialloc_alloc_inode(struct ext4_fs *fs, uint32_t *idx, bool is_dir) 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 @@ int ext4_ialloc_alloc_inode(struct ext4_fs *fs, uint32_t *idx, bool is_dir) /* 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) { diff --git a/lwext4/ext4_trans.c b/lwext4/ext4_trans.c new file mode 100644 index 0000000..1aa8f40 --- /dev/null +++ b/lwext4/ext4_trans.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com) + * Copyright (c) 2015 Kaho Ng (ngkaho1234@gmail.com) + * 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; +} + +/** + * @} + */ diff --git a/lwext4/ext4_trans.h b/lwext4/ext4_trans.h new file mode 100644 index 0000000..e3cb28a --- /dev/null +++ b/lwext4/ext4_trans.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com) + * Copyright (c) 2015 Kaho Ng (ngkaho1234@gmail.com) + * + * 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 */ + +/** + * @} + */ diff --git a/lwext4/ext4_xattr.c b/lwext4/ext4_xattr.c index b446d62..b8465a7 100644 --- a/lwext4/ext4_xattr.c +++ b/lwext4/ext4_xattr.c @@ -543,7 +543,7 @@ static int ext4_xattr_try_alloc_block(struct ext4_xattr_ref *xattr_ref) 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 @@ static int ext4_xattr_write_to_disk(struct ext4_xattr_ref *xattr_ref) 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 @@ static int ext4_xattr_write_to_disk(struct ext4_xattr_ref *xattr_ref) &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 @@ static int ext4_xattr_write_to_disk(struct ext4_xattr_ref *xattr_ref) 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 @@ int ext4_fs_get_xattr_ref(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref, 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; |
