diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:49:25 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:49:25 +0000 |
commit | 464df1d5e5ab1322e2dd0a7796939fff1aeefa9a (patch) | |
tree | 6a403684e0978f0287d7f0ec0e5aab1fd31a59e1 /lib/ext2fs/i_block.c | |
parent | Initial commit. (diff) | |
download | e2fsprogs-upstream/1.47.0.tar.xz e2fsprogs-upstream/1.47.0.zip |
Adding upstream version 1.47.0.upstream/1.47.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/ext2fs/i_block.c')
-rw-r--r-- | lib/ext2fs/i_block.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/lib/ext2fs/i_block.c b/lib/ext2fs/i_block.c new file mode 100644 index 0000000..2eecf02 --- /dev/null +++ b/lib/ext2fs/i_block.c @@ -0,0 +1,90 @@ +/* + * i_block.c --- Manage the i_block field for i_blocks + * + * Copyright (C) 2008 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Library + * General Public License, version 2. + * %End-Header% + */ + +#include "config.h" +#include <stdio.h> +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <time.h> +#include <string.h> +#if HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#if HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#include <errno.h> + +#include "ext2_fs.h" +#include "ext2fs.h" + +errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode, + blk64_t num_blocks) +{ + unsigned long long b = inode->i_blocks; + + if (ext2fs_has_feature_huge_file(fs->super)) + b += ((long long) inode->osd2.linux2.l_i_blocks_hi) << 32; + + if (!ext2fs_has_feature_huge_file(fs->super) || + !(inode->i_flags & EXT4_HUGE_FILE_FL)) + num_blocks *= fs->blocksize / 512; + num_blocks *= EXT2FS_CLUSTER_RATIO(fs); + + b += num_blocks; + + if (ext2fs_has_feature_huge_file(fs->super)) + inode->osd2.linux2.l_i_blocks_hi = b >> 32; + else if (b > 0xFFFFFFFF) + return EOVERFLOW; + inode->i_blocks = b & 0xFFFFFFFF; + return 0; +} + +errcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode, + blk64_t num_blocks) +{ + unsigned long long b = inode->i_blocks; + + if (ext2fs_has_feature_huge_file(fs->super)) + b += ((long long) inode->osd2.linux2.l_i_blocks_hi) << 32; + + if (!ext2fs_has_feature_huge_file(fs->super) || + !(inode->i_flags & EXT4_HUGE_FILE_FL)) + num_blocks *= fs->blocksize / 512; + num_blocks *= EXT2FS_CLUSTER_RATIO(fs); + + if (num_blocks > b) + return EOVERFLOW; + + b -= num_blocks; + + if (ext2fs_has_feature_huge_file(fs->super)) + inode->osd2.linux2.l_i_blocks_hi = b >> 32; + inode->i_blocks = b & 0xFFFFFFFF; + return 0; +} + +errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b) +{ + if (!ext2fs_has_feature_huge_file(fs->super) || + !(inode->i_flags & EXT4_HUGE_FILE_FL)) + b *= fs->blocksize / 512; + b *= EXT2FS_CLUSTER_RATIO(fs); + + inode->i_blocks = b & 0xFFFFFFFF; + if (ext2fs_has_feature_huge_file(fs->super)) + inode->osd2.linux2.l_i_blocks_hi = b >> 32; + else if (b >> 32) + return EOVERFLOW; + return 0; +} |