#include <common.h>
#include <ext_common.h>
#include <ext4fs.h>
+#include <inttypes.h>
#include <malloc.h>
#include <stddef.h>
#include <linux/stat.h>
if ((startblock + (size >> log2blksz)) >
(part_offset + fs->total_sect)) {
printf("part_offset is " LBAFU "\n", part_offset);
- printf("total_sector is %llu\n", fs->total_sect);
+ printf("total_sector is %" PRIu64 "\n", fs->total_sect);
printf("error: overflow occurs\n");
return;
}
restart:
fs->curr_blkno++;
/* get the blockbitmap index respective to blockno */
- if (fs->blksz != 1024) {
- bg_idx = fs->curr_blkno / blk_per_grp;
- } else {
- bg_idx = fs->curr_blkno / blk_per_grp;
+ bg_idx = fs->curr_blkno / blk_per_grp;
+ if (fs->blksz == 1024) {
remainder = fs->curr_blkno % blk_per_grp;
if (!remainder)
bg_idx--;
unsigned int no_blks_reqd = 0;
/* allocation of direct blocks */
- for (i = 0; i < INDIRECT_BLOCKS; i++) {
+ for (i = 0; total_remaining_blocks && i < INDIRECT_BLOCKS; i++) {
direct_blockno = ext4fs_get_new_blk_no();
if (direct_blockno == -1) {
printf("no block left to assign\n");
debug("DB %ld: %u\n", direct_blockno, total_remaining_blocks);
total_remaining_blocks--;
- if (total_remaining_blocks == 0)
- break;
}
alloc_single_indirect_block(file_inode, &total_remaining_blocks,
{
struct ext4_extent_idx *index;
unsigned long long block;
- struct ext_filesystem *fs = get_fs();
+ int blksz = EXT2_BLOCK_SIZE(data);
int i;
while (1) {
i++;
if (i >= le16_to_cpu(ext_block->eh_entries))
break;
- } while (fileblock > le32_to_cpu(index[i].ei_block));
+ } while (fileblock >= le32_to_cpu(index[i].ei_block));
if (--i < 0)
return 0;
block = le16_to_cpu(index[i].ei_leaf_hi);
block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo);
- if (ext4fs_devread((lbaint_t)block << log2_blksz, 0, fs->blksz,
+ if (ext4fs_devread((lbaint_t)block << log2_blksz, 0, blksz,
buf))
ext_block = (struct ext4_extent_header *)buf;
else
return blknr;
}
-void ext4fs_close(void)
+/**
+ * ext4fs_reinit_global() - Reinitialize values of ext4 write implementation's
+ * global pointers
+ *
+ * This function assures that for a file with the same name but different size
+ * the sequential store on the ext4 filesystem will be correct.
+ *
+ * In this function the global data, responsible for internal representation
+ * of the ext4 data are initialized to the reset state. Without this, during
+ * replacement of the smaller file with the bigger truncation of new file was
+ * performed.
+ */
+void ext4fs_reinit_global(void)
{
- if ((ext4fs_file != NULL) && (ext4fs_root != NULL)) {
- ext4fs_free_node(ext4fs_file, &ext4fs_root->diropen);
- ext4fs_file = NULL;
- }
- if (ext4fs_root != NULL) {
- free(ext4fs_root);
- ext4fs_root = NULL;
- }
if (ext4fs_indir1_block != NULL) {
free(ext4fs_indir1_block);
ext4fs_indir1_block = NULL;
ext4fs_indir3_blkno = -1;
}
}
+void ext4fs_close(void)
+{
+ if ((ext4fs_file != NULL) && (ext4fs_root != NULL)) {
+ ext4fs_free_node(ext4fs_file, &ext4fs_root->diropen);
+ ext4fs_file = NULL;
+ }
+ if (ext4fs_root != NULL) {
+ free(ext4fs_root);
+ ext4fs_root = NULL;
+ }
+
+ ext4fs_reinit_global();
+}
int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
struct ext2fs_node **fnode, int *ftype)
{
unsigned int fpos = 0;
int status;
+ loff_t actread;
struct ext2fs_node *diro = (struct ext2fs_node *) dir;
#ifdef DEBUG
status = ext4fs_read_file(diro, fpos,
sizeof(struct ext2_dirent),
- (char *) &dirent);
- if (status < 1)
+ (char *)&dirent, &actread);
+ if (status < 0)
return 0;
if (dirent.namelen != 0) {
status = ext4fs_read_file(diro,
fpos +
sizeof(struct ext2_dirent),
- dirent.namelen, filename);
- if (status < 1)
+ dirent.namelen, filename,
+ &actread);
+ if (status < 0)
return 0;
fdiro = zalloc(sizeof(struct ext2fs_node));
printf("< ? > ");
break;
}
- printf("%10d %s\n",
- __le32_to_cpu(fdiro->inode.size),
+ printf("%10u %s\n",
+ __le32_to_cpu(fdiro->inode.size),
filename);
}
free(fdiro);
char *symlink;
struct ext2fs_node *diro = node;
int status;
+ loff_t actread;
if (!diro->inode_read) {
status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode);
} else {
status = ext4fs_read_file(diro, 0,
__le32_to_cpu(diro->inode.size),
- symlink);
+ symlink, &actread);
if (status == 0) {
free(symlink);
return 0;
return 1;
}
-int ext4fs_open(const char *filename)
+int ext4fs_open(const char *filename, loff_t *len)
{
struct ext2fs_node *fdiro = NULL;
int status;
- int len;
if (ext4fs_root == NULL)
return -1;
if (status == 0)
goto fail;
}
- len = __le32_to_cpu(fdiro->inode.size);
+ *len = __le32_to_cpu(fdiro->inode.size);
ext4fs_file = fdiro;
- return len;
+ return 0;
fail:
ext4fs_free_node(fdiro, &ext4fs_root->diropen);