11ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o/* 21ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o * i_block.c --- Manage the i_block field for i_blocks 31ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o * 41ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o * Copyright (C) 2008 Theodore Ts'o. 51ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o * 61ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o * %Begin-Header% 7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 91ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o * %End-Header% 101ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o */ 111ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o 121ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#include <stdio.h> 131ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#if HAVE_UNISTD_H 141ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#include <unistd.h> 151ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#endif 161ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#include <time.h> 171ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#include <string.h> 181ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#if HAVE_SYS_STAT_H 191ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#include <sys/stat.h> 201ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#endif 211ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#if HAVE_SYS_TYPES_H 221ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#include <sys/types.h> 231ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#endif 245d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o#include <errno.h> 251ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o 261ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#include "ext2_fs.h" 271ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o#include "ext2fs.h" 281ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o 291ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'oerrcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode, 301ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o blk64_t num_blocks) 311ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o{ 325d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o unsigned long long b = inode->i_blocks; 331ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o 34e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) 35e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall b += ((long long) inode->osd2.linux2.l_i_blocks_hi) << 32; 36e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 375d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o if (!(fs->super->s_feature_ro_compat & 385d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o EXT4_FEATURE_RO_COMPAT_HUGE_FILE) || 395d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o !(inode->i_flags & EXT4_HUGE_FILE_FL)) 405d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o num_blocks *= fs->blocksize / 512; 41e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall num_blocks *= EXT2FS_CLUSTER_RATIO(fs); 425d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o 435d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o b += num_blocks; 445d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o 45e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) 461ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o inode->osd2.linux2.l_i_blocks_hi = b >> 32; 47e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall else if (b > 0xFFFFFFFF) 485d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o return EOVERFLOW; 495d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o inode->i_blocks = b & 0xFFFFFFFF; 501ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o return 0; 511ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o} 521ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o 531ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'oerrcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode, 541ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o blk64_t num_blocks) 551ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o{ 565d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o unsigned long long b = inode->i_blocks; 575d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o 58e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) 59e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall b += ((long long) inode->osd2.linux2.l_i_blocks_hi) << 32; 60e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 615d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o if (!(fs->super->s_feature_ro_compat & 625d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o EXT4_FEATURE_RO_COMPAT_HUGE_FILE) || 635d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o !(inode->i_flags & EXT4_HUGE_FILE_FL)) 645d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o num_blocks *= fs->blocksize / 512; 65e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall num_blocks *= EXT2FS_CLUSTER_RATIO(fs); 661ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o 675d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o if (num_blocks > b) 685d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o return EOVERFLOW; 695d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o 705d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o b -= num_blocks; 715d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o 72e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) 731ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o inode->osd2.linux2.l_i_blocks_hi = b >> 32; 745d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o inode->i_blocks = b & 0xFFFFFFFF; 751ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o return 0; 761ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o} 771ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o 781ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'oerrcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b) 791ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o{ 805d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o if (!(fs->super->s_feature_ro_compat & 815d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o EXT4_FEATURE_RO_COMPAT_HUGE_FILE) || 825d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o !(inode->i_flags & EXT4_HUGE_FILE_FL)) 835d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o b *= fs->blocksize / 512; 84e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall b *= EXT2FS_CLUSTER_RATIO(fs); 855d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o 865d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o inode->i_blocks = b & 0xFFFFFFFF; 875d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) 881ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o inode->osd2.linux2.l_i_blocks_hi = b >> 32; 895d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o else if (b >> 32) 905d10807070ae13a89c2a0cc217e30af6f061d60eTheodore Ts'o return EOVERFLOW; 911ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o return 0; 921ca1059fd0126fd2c065f272a566c18f14bab16dTheodore Ts'o} 93