summaryrefslogtreecommitdiffstats
path: root/lib/ext2fs/i_block.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ext2fs/i_block.c')
-rw-r--r--lib/ext2fs/i_block.c90
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;
+}