diff options
| author | gkostka <kostka.grzegorz@gmail.com> | 2015-10-16 16:43:07 +0200 |
|---|---|---|
| committer | gkostka <kostka.grzegorz@gmail.com> | 2015-10-16 16:43:07 +0200 |
| commit | dfe85bdd95ee71ce3bea80790f30205bfc0cd2b8 (patch) | |
| tree | 75ac59e4c7af28dc32d37d13b96ddeac6548dc51 | |
| parent | 0d951d61e5ae9c64091daf6f469dc71af6175daf (diff) | |
Introduce ext4_fs_init_inode_data_block_index
| -rw-r--r-- | lwext4/ext4.c | 26 | ||||
| -rw-r--r-- | lwext4/ext4_fs.c | 72 | ||||
| -rw-r--r-- | lwext4/ext4_fs.h | 9 |
3 files changed, 78 insertions, 29 deletions
diff --git a/lwext4/ext4.c b/lwext4/ext4.c index e3c8154..164e07b 100644 --- a/lwext4/ext4.c +++ b/lwext4/ext4.c @@ -1326,15 +1326,21 @@ int ext4_fread(ext4_file *f, void *buf, size_t size, size_t *rcnt) if (r != EOK) goto Finish; - r = ext4_block_get(f->mp->fs.bdev, &b, fblock); - if (r != EOK) - goto Finish; + /* Do we get an unwritten range? */ + if (fblock != 0) { + r = ext4_block_get(f->mp->fs.bdev, &b, fblock); + if (r != EOK) + goto Finish; - memcpy(u8_buf, b.data + u, ll); + memcpy(u8_buf, b.data + u, ll); - r = ext4_block_set(f->mp->fs.bdev, &b); - if (r != EOK) - goto Finish; + r = ext4_block_set(f->mp->fs.bdev, &b); + if (r != EOK) + goto Finish; + } else { + /* Yes, we do. */ + memset(u8_buf, 0, ll); + } u8_buf += ll; size -= ll; @@ -1465,7 +1471,7 @@ int ext4_fwrite(ext4_file *f, const void *buf, size_t size, size_t *wcnt) if (u) { uint32_t ll = size > (block_size - u) ? (block_size - u) : size; - r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock); + r = ext4_fs_init_inode_data_block_index(&ref, sblock, &fblock); if (r != EOK) goto Finish; @@ -1501,7 +1507,7 @@ int ext4_fwrite(ext4_file *f, const void *buf, size_t size, size_t *wcnt) while (sblock < sblock_end) { if (sblock < file_blocks) { - r = ext4_fs_get_inode_data_block_index( + r = ext4_fs_init_inode_data_block_index( &ref, sblock, &fblock); if (r != EOK) break; @@ -1548,7 +1554,7 @@ int ext4_fwrite(ext4_file *f, const void *buf, size_t size, size_t *wcnt) if (size) { if (sblock < file_blocks) { - r = ext4_fs_get_inode_data_block_index(&ref, sblock, + r = ext4_fs_init_inode_data_block_index(&ref, sblock, &fblock); if (r != EOK) goto Finish; diff --git a/lwext4/ext4_fs.c b/lwext4/ext4_fs.c index c7d3a9d..eec746a 100644 --- a/lwext4/ext4_fs.c +++ b/lwext4/ext4_fs.c @@ -51,6 +51,7 @@ #include "ext4_inode.h" #include "ext4_ialloc.h" #include "ext4_extent.h" +#include "ext4_extent_full.h" #include <string.h> @@ -689,6 +690,7 @@ void ext4_fs_inode_blocks_init(struct ext4_fs *fs, struct ext4_inode_ref *inode_ for (i = 0; i < EXT4_INODE_BLOCKS; i++) inode->blocks[i] = 0; + (void)fs; #if CONFIG_EXTENT_ENABLE /* Initialize extents if needed */ if (ext4_sb_has_feature_incompatible(&fs->sb, @@ -696,17 +698,7 @@ void ext4_fs_inode_blocks_init(struct ext4_fs *fs, struct ext4_inode_ref *inode_ ext4_inode_set_flag(inode, EXT4_INODE_FLAG_EXTENTS); /* Initialize extent root header */ - struct ext4_extent_header *header = ext4_inode_get_extent_header(inode); - ext4_extent_header_set_depth(header, 0); - ext4_extent_header_set_entries_count(header, 0); - ext4_extent_header_set_generation(header, 0); - ext4_extent_header_set_magic(header, EXT4_EXTENT_MAGIC); - - uint16_t max_entries = (EXT4_INODE_BLOCKS * sizeof(uint32_t) - - sizeof(struct ext4_extent_header)) / - sizeof(struct ext4_extent); - - ext4_extent_header_set_max_entries_count(header, max_entries); + ext4_ext_tree_init(inode_ref); } #endif } @@ -982,9 +974,10 @@ int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size) /* Extents require special operation */ if (diff_blocks_count) { - int rc = ext4_extent_release_blocks_from( + int rc = ext4_ext_remove_space( inode_ref, - new_blocks_count); + new_blocks_count, + (ext4_lblk_t)-1); if (rc != EOK) return rc; @@ -1011,8 +1004,9 @@ int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size) return EOK; } -int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref, - uint64_t iblock, uint32_t *fblock) +static int ext4_fs_get_inode_data_block_idx(struct ext4_inode_ref *inode_ref, + uint64_t iblock, uint32_t *fblock, + bool extent_create) { struct ext4_fs *fs = inode_ref->fs; @@ -1023,18 +1017,24 @@ int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref, } uint32_t current_block; + + (void)extent_create; #if CONFIG_EXTENT_ENABLE /* Handle i-node using extents */ if ((ext4_sb_has_feature_incompatible(&fs->sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) && (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { - int rc = - ext4_extent_find_block(inode_ref, iblock, ¤t_block); + ext4_fsblk_t current_fsblk; + int rc = ext4_ext_get_blocks(inode_ref, iblock, 1, ¤t_fsblk, + extent_create, NULL); if (rc != EOK) return rc; + current_block = (uint32_t)current_fsblk; *fblock = current_block; + + ext4_assert(*fblock); return EOK; } #endif @@ -1121,6 +1121,21 @@ int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref, return EOK; } + +int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref, + uint64_t iblock, uint32_t *fblock) +{ + return ext4_fs_get_inode_data_block_idx(inode_ref, iblock, fblock, + false); +} + +int ext4_fs_init_inode_data_block_index(struct ext4_inode_ref *inode_ref, + uint64_t iblock, uint32_t *fblock) +{ + return ext4_fs_get_inode_data_block_idx(inode_ref, iblock, fblock, + true); +} + int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref, uint64_t iblock, uint32_t fblock) { @@ -1389,8 +1404,27 @@ int ext4_fs_append_inode_block(struct ext4_inode_ref *inode_ref, if ((ext4_sb_has_feature_incompatible(&inode_ref->fs->sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) && (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { - return ext4_extent_append_block(inode_ref, iblock, fblock, - true); + int rc; + ext4_fsblk_t current_fsblk; + struct ext4_sblock *sb = &inode_ref->fs->sb; + uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode); + uint32_t block_size = ext4_sb_get_block_size(sb); + *iblock = (inode_size + block_size - 1) / + block_size; + + rc = ext4_ext_get_blocks(inode_ref, *iblock, 1, ¤t_fsblk, + true, NULL); + + + *fblock = current_fsblk; + ext4_assert(*fblock); + + ext4_inode_set_size(inode_ref->inode, + inode_size + block_size); + inode_ref->dirty = true; + + + return rc; } #endif struct ext4_sblock *sb = &inode_ref->fs->sb; diff --git a/lwext4/ext4_fs.h b/lwext4/ext4_fs.h index b475af7..1f34875 100644 --- a/lwext4/ext4_fs.h +++ b/lwext4/ext4_fs.h @@ -176,6 +176,15 @@ int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size); int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref, uint64_t iblock, uint32_t *fblock); +/**@brief Initialize a part of unwritten range of the inode. + * @param inode_ref I-node to proceed on. + * @param iblock Logical index of block + * @param fblock Output pointer for return physical block address + * @return Error code + */ +int ext4_fs_init_inode_data_block_index(struct ext4_inode_ref *inode_ref, + uint64_t iblock, uint32_t *fblock); + /**@brief Set physical block address for the block logical address into the * i-node. * @param inode_ref I-node to set block address to |
