91 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * 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;
 | |
| }
 |