mirror of https://github.com/vitalif/e2fsprogs
libext2fs: provide a function to set inode size
Provide an API to set i_size in an inode and take care of all required feature flag modifications. Refactor the code to use this new function. [ Moved the function to lib/ext2fs/blk_num.c, which is the rest of these sorts of functions live, and renamed it to be ext2fs_inode_size_set() instead of ext2fs_inode_set_size() to be consistent with the other functions in in blk_num.c -- tytso ] Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>test-maint
parent
a30a4e93f3
commit
97c607b1a2
|
@ -1718,7 +1718,12 @@ void do_write(int argc, char *argv[])
|
|||
inode.i_atime = inode.i_ctime = inode.i_mtime =
|
||||
current_fs->now ? current_fs->now : time(0);
|
||||
inode.i_links_count = 1;
|
||||
inode.i_size = statbuf.st_size;
|
||||
retval = ext2fs_inode_size_set(current_fs, &inode, statbuf.st_size);
|
||||
if (retval) {
|
||||
com_err(argv[2], retval, 0);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
if (current_fs->super->s_feature_incompat &
|
||||
EXT3_FEATURE_INCOMPAT_EXTENTS) {
|
||||
int i;
|
||||
|
|
|
@ -265,8 +265,7 @@ static void check_size(e2fsck_t ctx, struct problem_context *pctx)
|
|||
if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
|
||||
return;
|
||||
|
||||
inode->i_size = 0;
|
||||
inode->i_size_high = 0;
|
||||
ext2fs_inode_size_set(ctx->fs, inode, 0);
|
||||
e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
|
||||
}
|
||||
|
||||
|
@ -2263,9 +2262,9 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
|
|||
pctx->num = (pb.last_block+1) * fs->blocksize;
|
||||
pctx->group = bad_size;
|
||||
if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
|
||||
inode->i_size = pctx->num;
|
||||
if (!LINUX_S_ISDIR(inode->i_mode))
|
||||
inode->i_size_high = pctx->num >> 32;
|
||||
if (LINUX_S_ISDIR(inode->i_mode))
|
||||
pctx->num &= 0xFFFFFFFFULL;
|
||||
ext2fs_inode_size_set(fs, inode, pctx->num);
|
||||
dirty_inode++;
|
||||
}
|
||||
pctx->num = 0;
|
||||
|
|
|
@ -1466,8 +1466,15 @@ static int allocate_dir_block(e2fsck_t ctx,
|
|||
*/
|
||||
e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
|
||||
ext2fs_iblk_add_blocks(fs, &inode, 1);
|
||||
if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
|
||||
inode.i_size = (db->blockcnt+1) * fs->blocksize;
|
||||
if (EXT2_I_SIZE(&inode) < (db->blockcnt+1) * fs->blocksize) {
|
||||
pctx->errcode = ext2fs_inode_size_set(fs, &inode,
|
||||
(db->blockcnt+1) * fs->blocksize);
|
||||
if (pctx->errcode) {
|
||||
pctx->str = "ext2fs_inode_size_set";
|
||||
fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
|
||||
|
||||
/*
|
||||
|
|
|
@ -804,8 +804,9 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
|
|||
return retval;
|
||||
|
||||
sz = (es.last_block + 1) * fs->blocksize;
|
||||
inode.i_size = sz;
|
||||
inode.i_size_high = sz >> 32;
|
||||
retval = ext2fs_inode_size_set(fs, &inode, sz);
|
||||
if (retval)
|
||||
return retval;
|
||||
ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
|
||||
quota_data_add(ctx->qctx, &inode, dir, es.newblocks * fs->blocksize);
|
||||
|
||||
|
|
|
@ -699,7 +699,10 @@ static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
|
|||
inode.i_flags &= ~EXT2_INDEX_FL;
|
||||
else
|
||||
inode.i_flags |= EXT2_INDEX_FL;
|
||||
inode.i_size = outdir->num * fs->blocksize;
|
||||
retval = ext2fs_inode_size_set(fs, &inode,
|
||||
outdir->num * fs->blocksize);
|
||||
if (retval)
|
||||
return retval;
|
||||
ext2fs_iblk_sub_blocks(fs, &inode, wd.cleared);
|
||||
e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
|
||||
|
||||
|
|
|
@ -128,7 +128,10 @@ errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
|
|||
if (!inode.i_ctime)
|
||||
inode.i_ctime = fs->now ? fs->now : time(0);
|
||||
ext2fs_iblk_set(fs, &inode, rec.bad_block_count);
|
||||
inode.i_size = rec.bad_block_count * fs->blocksize;
|
||||
retval = ext2fs_inode_size_set(fs, &inode,
|
||||
rec.bad_block_count * fs->blocksize);
|
||||
if (retval)
|
||||
goto cleanup;
|
||||
|
||||
retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode);
|
||||
if (retval)
|
||||
|
|
|
@ -493,3 +493,31 @@ void ext2fs_file_acl_block_set(ext2_filsys fs, struct ext2_inode *inode,
|
|||
inode->osd2.linux2.l_i_file_acl_high = (__u64) blk >> 32;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the size of the inode
|
||||
*/
|
||||
errcode_t ext2fs_inode_size_set(ext2_filsys fs, struct ext2_inode *inode,
|
||||
ext2_off64_t size)
|
||||
{
|
||||
/* Only regular files get to be larger than 4GB */
|
||||
if (!LINUX_S_ISREG(inode->i_mode) && (size >> 32))
|
||||
return EXT2_ET_FILE_TOO_BIG;
|
||||
|
||||
/* If we're writing a large file, set the large_file flag */
|
||||
if (LINUX_S_ISREG(inode->i_mode) &&
|
||||
ext2fs_needs_large_file_feature(size) &&
|
||||
(!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
|
||||
EXT2_FEATURE_RO_COMPAT_LARGE_FILE) ||
|
||||
fs->super->s_rev_level == EXT2_GOOD_OLD_REV)) {
|
||||
fs->super->s_feature_ro_compat |=
|
||||
EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
|
||||
ext2fs_update_dynamic_rev(fs);
|
||||
ext2fs_mark_super_dirty(fs);
|
||||
}
|
||||
|
||||
inode->i_size = size & 0xffffffff;
|
||||
inode->i_size_high = (size >> 32);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -866,6 +866,8 @@ extern blk64_t ext2fs_file_acl_block(ext2_filsys fs,
|
|||
const struct ext2_inode *inode);
|
||||
extern void ext2fs_file_acl_block_set(ext2_filsys fs,
|
||||
struct ext2_inode *inode, blk64_t blk);
|
||||
extern errcode_t ext2fs_inode_size_set(ext2_filsys fs, struct ext2_inode *inode,
|
||||
ext2_off64_t size);
|
||||
|
||||
/* block.c */
|
||||
extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
|
||||
|
|
|
@ -462,20 +462,10 @@ errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size)
|
|||
old_truncate = ((old_size + file->fs->blocksize - 1) >>
|
||||
EXT2_BLOCK_SIZE_BITS(file->fs->super));
|
||||
|
||||
/* If we're writing a large file, set the large_file flag */
|
||||
if (LINUX_S_ISREG(file->inode.i_mode) &&
|
||||
ext2fs_needs_large_file_feature(EXT2_I_SIZE(&file->inode)) &&
|
||||
(!EXT2_HAS_RO_COMPAT_FEATURE(file->fs->super,
|
||||
EXT2_FEATURE_RO_COMPAT_LARGE_FILE) ||
|
||||
file->fs->super->s_rev_level == EXT2_GOOD_OLD_REV)) {
|
||||
file->fs->super->s_feature_ro_compat |=
|
||||
EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
|
||||
ext2fs_update_dynamic_rev(file->fs);
|
||||
ext2fs_mark_super_dirty(file->fs);
|
||||
}
|
||||
retval = ext2fs_inode_size_set(file->fs, &file->inode, size);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
file->inode.i_size = size & 0xffffffff;
|
||||
file->inode.i_size_high = (size >> 32);
|
||||
if (file->ino) {
|
||||
retval = ext2fs_write_inode(file->fs, file->ino, &file->inode);
|
||||
if (retval)
|
||||
|
|
|
@ -383,15 +383,13 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
|
|||
goto errout;
|
||||
|
||||
inode_size = (unsigned long long)fs->blocksize * num_blocks;
|
||||
inode.i_size = inode_size & 0xFFFFFFFF;
|
||||
inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
|
||||
if (ext2fs_needs_large_file_feature(inode_size))
|
||||
fs->super->s_feature_ro_compat |=
|
||||
EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
|
||||
ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
|
||||
inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
|
||||
inode.i_links_count = 1;
|
||||
inode.i_mode = LINUX_S_IFREG | 0600;
|
||||
retval = ext2fs_inode_size_set(fs, &inode, inode_size);
|
||||
if (retval)
|
||||
goto errout;
|
||||
|
||||
if ((retval = ext2fs_write_new_inode(fs, journal_ino, &inode)))
|
||||
goto errout;
|
||||
|
|
|
@ -133,12 +133,9 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
|
|||
dindir_dirty = inode_dirty = 1;
|
||||
inode_size = apb*apb + apb + EXT2_NDIR_BLOCKS;
|
||||
inode_size *= fs->blocksize;
|
||||
inode.i_size = inode_size & 0xFFFFFFFF;
|
||||
inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
|
||||
if(inode.i_size_high) {
|
||||
sb->s_feature_ro_compat |=
|
||||
EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
|
||||
}
|
||||
retval = ext2fs_inode_size_set(fs, &inode, inode_size);
|
||||
if (retval)
|
||||
goto out_free;
|
||||
inode.i_ctime = fs->now ? fs->now : time(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ errcode_t ext2fs_symlink(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t ino,
|
|||
inode.i_uid = inode.i_gid = 0;
|
||||
ext2fs_iblk_set(fs, &inode, fastlink ? 0 : 1);
|
||||
inode.i_links_count = 1;
|
||||
inode.i_size = target_len;
|
||||
ext2fs_inode_size_set(fs, &inode, target_len);
|
||||
/* The time fields are set by ext2fs_write_new_inode() */
|
||||
|
||||
if (fastlink) {
|
||||
|
|
|
@ -357,8 +357,9 @@ static errcode_t mk_hugefile(ext2_filsys fs, blk64_t num,
|
|||
if (retval)
|
||||
goto errout;
|
||||
size = (__u64) count * fs->blocksize;
|
||||
inode.i_size = size & 0xffffffff;
|
||||
inode.i_size_high = (size >> 32);
|
||||
retval = ext2fs_inode_size_set(fs, &inode, size);
|
||||
if (retval)
|
||||
goto errout;
|
||||
|
||||
retval = ext2fs_write_new_inode(fs, *ino, &inode);
|
||||
if (retval)
|
||||
|
|
|
@ -2,11 +2,6 @@ Pass 1: Checking inodes, blocks, and sizes
|
|||
Inode 12, i_size is 61440, should be 4398050758656. Fix? yes
|
||||
|
||||
Pass 2: Checking directory structure
|
||||
Filesystem contains large files, but lacks LARGE_FILE flag in superblock.
|
||||
Fix? yes
|
||||
|
||||
Filesystem has feature flag(s) set, but is a revision 0 filesystem. Fix? yes
|
||||
|
||||
Pass 3: Checking directory connectivity
|
||||
Pass 4: Checking reference counts
|
||||
Pass 5: Checking group summary information
|
||||
|
|
Loading…
Reference in New Issue