• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * i_block.c --- Manage the i_block field for i_blocks
3  *
4  * Copyright (C) 2008 Theodore Ts'o.
5  *
6  * %Begin-Header%
7  * This file may be redistributed under the terms of the GNU Library
8  * General Public License, version 2.
9  * %End-Header%
10  */
11 
12 #include "config.h"
13 #include <stdio.h>
14 #if HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif
17 #include <time.h>
18 #include <string.h>
19 #if HAVE_SYS_STAT_H
20 #include <sys/stat.h>
21 #endif
22 #if HAVE_SYS_TYPES_H
23 #include <sys/types.h>
24 #endif
25 #include <errno.h>
26 
27 #include "ext2_fs.h"
28 #include "ext2fs.h"
29 
ext2fs_iblk_add_blocks(ext2_filsys fs,struct ext2_inode * inode,blk64_t num_blocks)30 errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode,
31 				 blk64_t num_blocks)
32 {
33 	unsigned long long b = inode->i_blocks;
34 
35 	if (ext2fs_has_feature_huge_file(fs->super))
36 		b += ((long long) inode->osd2.linux2.l_i_blocks_hi) << 32;
37 
38 	if (!ext2fs_has_feature_huge_file(fs->super) ||
39 	    !(inode->i_flags & EXT4_HUGE_FILE_FL))
40 	    num_blocks *= fs->blocksize / 512;
41 	num_blocks *= EXT2FS_CLUSTER_RATIO(fs);
42 
43 	b += num_blocks;
44 
45 	if (ext2fs_has_feature_huge_file(fs->super))
46 		inode->osd2.linux2.l_i_blocks_hi = b >> 32;
47 	else if (b > 0xFFFFFFFF)
48 		return EOVERFLOW;
49 	inode->i_blocks = b & 0xFFFFFFFF;
50 	return 0;
51 }
52 
ext2fs_iblk_sub_blocks(ext2_filsys fs,struct ext2_inode * inode,blk64_t num_blocks)53 errcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode,
54 				 blk64_t num_blocks)
55 {
56 	unsigned long long b = inode->i_blocks;
57 
58 	if (ext2fs_has_feature_huge_file(fs->super))
59 		b += ((long long) inode->osd2.linux2.l_i_blocks_hi) << 32;
60 
61 	if (!ext2fs_has_feature_huge_file(fs->super) ||
62 	    !(inode->i_flags & EXT4_HUGE_FILE_FL))
63 	    num_blocks *= fs->blocksize / 512;
64 	num_blocks *= EXT2FS_CLUSTER_RATIO(fs);
65 
66 	if (num_blocks > b)
67 		return EOVERFLOW;
68 
69 	b -= num_blocks;
70 
71 	if (ext2fs_has_feature_huge_file(fs->super))
72 		inode->osd2.linux2.l_i_blocks_hi = b >> 32;
73 	inode->i_blocks = b & 0xFFFFFFFF;
74 	return 0;
75 }
76 
ext2fs_iblk_set(ext2_filsys fs,struct ext2_inode * inode,blk64_t b)77 errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b)
78 {
79 	if (!ext2fs_has_feature_huge_file(fs->super) ||
80 	    !(inode->i_flags & EXT4_HUGE_FILE_FL))
81 		b *= fs->blocksize / 512;
82 	b *= EXT2FS_CLUSTER_RATIO(fs);
83 
84 	inode->i_blocks = b & 0xFFFFFFFF;
85 	if (ext2fs_has_feature_huge_file(fs->super))
86 		inode->osd2.linux2.l_i_blocks_hi = b >> 32;
87 	else if (b >> 32)
88 		return EOVERFLOW;
89 	return 0;
90 }
91