2 * blknum.c --- Functions to handle blk64_t and high/low 64-bit block
5 * Copyright IBM Corporation, 2007
6 * Author Jose R. Santos <jrs@us.ibm.com>
9 * This file may be redistributed under the terms of the GNU Public
17 * Return the group # of a block
19 dgrp_t ext2fs_group_of_blk2(ext2_filsys fs, blk64_t blk)
21 return (blk - fs->super->s_first_data_block) /
22 fs->super->s_blocks_per_group;
26 * Return the first block (inclusive) in a group
28 blk64_t ext2fs_group_first_block2(ext2_filsys fs, dgrp_t group)
30 return fs->super->s_first_data_block +
31 ((blk64_t)group * fs->super->s_blocks_per_group);
35 * Return the last block (inclusive) in a group
37 blk64_t ext2fs_group_last_block2(ext2_filsys fs, dgrp_t group)
39 return (group == fs->group_desc_count - 1 ?
40 ext2fs_blocks_count(fs->super) - 1 :
41 ext2fs_group_first_block2(fs, group) +
42 (fs->super->s_blocks_per_group - 1));
46 * Return the inode data block count
48 blk64_t ext2fs_inode_data_blocks2(ext2_filsys fs,
49 struct ext2_inode *inode)
51 return (inode->i_blocks |
52 (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT ?
53 (__u64)inode->osd2.linux2.l_i_blocks_hi << 32 : 0)) -
54 (inode->i_file_acl ? fs->blocksize >> 9 : 0);
58 * Return the inode i_blocks count
60 blk64_t ext2fs_inode_i_blocks(ext2_filsys fs,
61 struct ext2_inode *inode)
63 return (inode->i_blocks |
64 (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT ?
65 (__u64)inode->osd2.linux2.l_i_blocks_hi << 32 : 0));
69 * Return the fs block count
71 blk64_t ext2fs_blocks_count(struct ext2_super_block *super)
73 return super->s_blocks_count |
74 (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT ?
75 (__u64) super->s_blocks_count_hi << 32 : 0);
79 * Set the fs block count
81 void ext2fs_blocks_count_set(struct ext2_super_block *super, blk64_t blk)
83 super->s_blocks_count = blk;
84 if (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
85 super->s_blocks_count_hi = (__u64) blk >> 32;
89 * Add to the current fs block count
91 void ext2fs_blocks_count_add(struct ext2_super_block *super, blk64_t blk)
94 tmp = ext2fs_blocks_count(super) + blk;
95 ext2fs_blocks_count_set(super, tmp);
99 * Return the fs reserved block count
101 blk64_t ext2fs_r_blocks_count(struct ext2_super_block *super)
103 return super->s_r_blocks_count |
104 (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT ?
105 (__u64) super->s_r_blocks_count_hi << 32 : 0);
109 * Set the fs reserved block count
111 void ext2fs_r_blocks_count_set(struct ext2_super_block *super, blk64_t blk)
113 super->s_r_blocks_count = blk;
114 if (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
115 super->s_r_blocks_count_hi = (__u64) blk >> 32;
119 * Add to the current reserved fs block count
121 void ext2fs_r_blocks_count_add(struct ext2_super_block *super, blk64_t blk)
124 tmp = ext2fs_r_blocks_count(super) + blk;
125 ext2fs_r_blocks_count_set(super, tmp);
129 * Return the fs free block count
131 blk64_t ext2fs_free_blocks_count(struct ext2_super_block *super)
133 return super->s_free_blocks_count |
134 (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT ?
135 (__u64) super->s_free_blocks_hi << 32 : 0);
139 * Set the fs free block count
141 void ext2fs_free_blocks_count_set(struct ext2_super_block *super, blk64_t blk)
143 super->s_free_blocks_count = blk;
144 if (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
145 super->s_free_blocks_hi = (__u64) blk >> 32;
149 * Add to the current free fs block count
151 void ext2fs_free_blocks_count_add(struct ext2_super_block *super, blk64_t blk)
154 tmp = ext2fs_free_blocks_count(super) + blk;
155 ext2fs_free_blocks_count_set(super, tmp);
159 * Get a pointer to a block group descriptor. We need the explicit
160 * pointer to the group desc for code that swaps block group
161 * descriptors before writing them out, as it wants to make a copy and
164 struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs,
165 struct ext2_group_desc *gdp,
168 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT)
169 return (struct ext2_group_desc *)
170 ((struct ext4_group_desc *) gdp + group);
172 return (struct ext2_group_desc *) gdp + group;
176 * Return the block bitmap block of a group
178 blk64_t ext2fs_block_bitmap_loc(ext2_filsys fs, dgrp_t group)
180 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
181 struct ext4_group_desc *gdp;
182 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
184 return gdp->bg_block_bitmap |
185 (fs->super->s_feature_incompat
186 & EXT4_FEATURE_INCOMPAT_64BIT ?
187 (__u64) gdp->bg_block_bitmap_hi << 32 : 0);
190 return fs->group_desc[group].bg_block_bitmap;
194 * Set the block bitmap block of a group
196 void ext2fs_block_bitmap_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
198 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
199 struct ext4_group_desc *gdp;
200 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
201 gdp->bg_block_bitmap = blk;
202 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
203 gdp->bg_block_bitmap_hi = (__u64) blk >> 32;
205 fs->group_desc[group].bg_block_bitmap = blk;
209 * Return the inode bitmap block of a group
211 blk64_t ext2fs_inode_bitmap_loc(ext2_filsys fs, dgrp_t group)
213 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
214 struct ext4_group_desc *gdp;
215 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
217 return gdp->bg_inode_bitmap |
218 (fs->super->s_feature_incompat
219 & EXT4_FEATURE_INCOMPAT_64BIT ?
220 (__u64) gdp->bg_inode_bitmap_hi << 32 : 0);
223 return fs->group_desc[group].bg_inode_bitmap;
227 * Set the inode bitmap block of a group
229 void ext2fs_inode_bitmap_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
231 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
232 struct ext4_group_desc *gdp;
233 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
234 gdp->bg_inode_bitmap = blk;
235 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
236 gdp->bg_inode_bitmap_hi = (__u64) blk >> 32;
238 fs->group_desc[group].bg_inode_bitmap = blk;
242 * Return the inode table block of a group
244 blk64_t ext2fs_inode_table_loc(ext2_filsys fs, dgrp_t group)
246 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
247 struct ext4_group_desc *gdp;
248 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
250 return gdp->bg_inode_table |
251 (fs->super->s_feature_incompat
252 & EXT4_FEATURE_INCOMPAT_64BIT ?
253 (__u64) gdp->bg_inode_table_hi << 32 : 0);
256 return fs->group_desc[group].bg_inode_table;
260 * Set the inode table block of a group
262 void ext2fs_inode_table_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
264 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
265 struct ext4_group_desc *gdp;
266 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
267 gdp->bg_inode_table = blk;
268 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
269 gdp->bg_inode_table_hi = (__u64) blk >> 32;
271 fs->group_desc[group].bg_inode_table = blk;
275 * Return the free blocks count of a group
277 blk64_t ext2fs_bg_free_blocks_count(ext2_filsys fs, dgrp_t group)
279 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
280 struct ext4_group_desc *gdp;
281 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
283 return gdp->bg_free_blocks_count |
284 (fs->super->s_feature_incompat
285 & EXT4_FEATURE_INCOMPAT_64BIT ?
286 (__u64) gdp->bg_free_blocks_count_hi << 32 : 0);
289 return fs->group_desc[group].bg_free_blocks_count;
293 * Set the free blocks count of a group
295 void ext2fs_bg_free_blocks_count_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
297 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
298 struct ext4_group_desc *gdp;
299 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
300 gdp->bg_free_blocks_count = blk;
301 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
302 gdp->bg_free_blocks_count_hi = (__u64) blk >> 32;
304 fs->group_desc[group].bg_free_blocks_count = blk;
308 * Return the free inodes count of a group
310 blk64_t ext2fs_bg_free_inodes_count(ext2_filsys fs, dgrp_t group)
312 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
313 struct ext4_group_desc *gdp;
314 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
316 return gdp->bg_free_inodes_count |
317 (fs->super->s_feature_incompat
318 & EXT4_FEATURE_INCOMPAT_64BIT ?
319 (__u64) gdp->bg_free_inodes_count_hi << 32 : 0);
322 return fs->group_desc[group].bg_free_inodes_count;
326 * Set the free inodes count of a group
328 void ext2fs_bg_free_inodes_count_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
330 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
331 struct ext4_group_desc *gdp;
332 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
333 gdp->bg_free_inodes_count = blk;
334 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
335 gdp->bg_free_inodes_count_hi = (__u64) blk >> 32;
337 fs->group_desc[group].bg_free_inodes_count = blk;
341 * Return the used dirs count of a group
343 blk64_t ext2fs_bg_used_dirs_count(ext2_filsys fs, dgrp_t group)
345 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
346 struct ext4_group_desc *gdp;
347 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
349 return gdp->bg_used_dirs_count |
350 (fs->super->s_feature_incompat
351 & EXT4_FEATURE_INCOMPAT_64BIT ?
352 (__u64) gdp->bg_used_dirs_count_hi << 32 : 0);
355 return fs->group_desc[group].bg_used_dirs_count;
359 * Set the used dirs count of a group
361 void ext2fs_bg_used_dirs_count_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
363 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
364 struct ext4_group_desc *gdp;
365 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
366 gdp->bg_used_dirs_count = blk;
367 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
368 gdp->bg_used_dirs_count_hi = (__u64) blk >> 32;
370 fs->group_desc[group].bg_used_dirs_count = blk;
374 * Return the unused inodes count of a group
376 blk64_t ext2fs_bg_itable_unused(ext2_filsys fs, dgrp_t group)
378 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
379 struct ext4_group_desc *gdp;
380 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
382 return gdp->bg_itable_unused |
383 (fs->super->s_feature_incompat
384 & EXT4_FEATURE_INCOMPAT_64BIT ?
385 (__u64) gdp->bg_itable_unused_hi << 32 : 0);
388 return fs->group_desc[group].bg_itable_unused;
392 * Set the unused inodes count of a group
394 void ext2fs_bg_itable_unused_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
396 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
397 struct ext4_group_desc *gdp;
398 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
399 gdp->bg_itable_unused = blk;
400 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
401 gdp->bg_itable_unused_hi = (__u64) blk >> 32;
403 fs->group_desc[group].bg_itable_unused = blk;
407 * Get the flags for this block group
409 __u16 ext2fs_bg_flags(ext2_filsys fs, dgrp_t group)
411 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
412 struct ext4_group_desc *gdp;
413 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
415 return gdp->bg_flags;
418 return fs->group_desc[group].bg_flags;
422 * Set the flags for this block group
424 void ext2fs_bg_flags_set(ext2_filsys fs, dgrp_t group, __u16 bg_flags)
426 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
427 struct ext4_group_desc *gdp;
428 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
430 gdp->bg_flags = bg_flags;
434 fs->group_desc[group].bg_flags = bg_flags;
438 * Clear the flags for this block group
440 void ext2fs_bg_flags_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flags)
442 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
443 struct ext4_group_desc *gdp;
444 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
450 fs->group_desc[group].bg_flags = 0;
454 * Get the value of a particular flag for this block group
456 int ext2fs_bg_flag_test(ext2_filsys fs, dgrp_t group, __u16 bg_flag)
458 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
459 struct ext4_group_desc *gdp;
460 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
462 return gdp->bg_flags & bg_flag;
465 return fs->group_desc[group].bg_flags & bg_flag;
469 * Set a particular flag for this block group
471 void ext2fs_bg_flag_set(ext2_filsys fs, dgrp_t group, __u16 bg_flag)
473 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
474 struct ext4_group_desc *gdp;
475 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
477 gdp->bg_flags |= bg_flag;
481 fs->group_desc[group].bg_flags |= bg_flag;
485 * Clear a particular flag for this block group
487 void ext2fs_bg_flag_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flag)
489 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
490 struct ext4_group_desc *gdp;
491 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
493 gdp->bg_flags &= ~bg_flag;
497 fs->group_desc[group].bg_flags &= ~bg_flag;
501 * Get the checksum for this block group
503 __u16 ext2fs_bg_checksum(ext2_filsys fs, dgrp_t group)
505 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
506 struct ext4_group_desc *gdp;
507 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
509 return gdp->bg_checksum;
512 return fs->group_desc[group].bg_checksum;
516 * Set the checksum for this block group to a previously calculated value
518 void ext2fs_bg_checksum_set(ext2_filsys fs, dgrp_t group, __u16 checksum)
520 if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
521 struct ext4_group_desc *gdp;
522 gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
524 gdp->bg_checksum = checksum;
528 fs->group_desc[group].bg_checksum = checksum;
532 * Get the acl block of a file
534 * XXX Ignoring 64-bit file system flag - most places where this is
535 * called don't have access to the fs struct, and the high bits should
536 * be 0 in the non-64-bit case anyway.
538 blk64_t ext2fs_file_acl_block(const struct ext2_inode *inode)
540 return (inode->i_file_acl |
541 (__u64) inode->osd2.linux2.l_i_file_acl_high << 32);
545 * Set the acl block of a file
547 void ext2fs_file_acl_block_set(struct ext2_inode *inode, blk64_t blk)
549 inode->i_file_acl = blk;
550 inode->osd2.linux2.l_i_file_acl_high = (__u64) blk >> 32;