/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ext4_utils.h"
#include "ext4_extents.h"
#include "allocate.h"
#include "ext4fixup.h"
#include <sparse/sparse.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#if defined(__APPLE__) && defined(__MACH__)
#define lseek64 lseek
#define off64_t off_t
#endif
/* The inode block count for a file/directory is in units of 512 byte blocks,
* _NOT_ the filesystem block size!
*/
#define INODE_BLOCK_SIZE 512
#define MAX_EXT4_BLOCK_SIZE 4096
/* The two modes the recurse_dir() can be in */
#define SANITY_CHECK_PASS 1
#define MARK_INODE_NUMS 2
#define UPDATE_INODE_NUMS 3
/* Magic numbers to indicate what state the update process is in */
#define MAGIC_STATE_MARKING_INUMS 0x7000151515565512ll
#define MAGIC_STATE_UPDATING_INUMS 0x6121131211735123ll
#define MAGIC_STATE_UPDATING_SB 0x15e1715151558477ll
/* Internal state variables corresponding to the magic numbers */
#define STATE_UNSET 0
#define STATE_MARKING_INUMS 1
#define STATE_UPDATING_INUMS 2
#define STATE_UPDATING_SB 3
/* Used for automated testing of this programs ability to stop and be restarted wthout error */
static int bail_phase = 0;
static int bail_loc = 0;
static int bail_count = 0;
static int count = 0;
/* global flags */
static int verbose = 0;
static int no_write = 0;
static int new_inodes_per_group = 0;
static int no_write_fixup_state = 0;
static int compute_new_inum(unsigned int old_inum)
{
unsigned int group, offset;
group = (old_inum - 1) / info.inodes_per_group;
offset = (old_inum -1) % info.inodes_per_group;
return (group * new_inodes_per_group) + offset + 1;
}
static int get_fs_fixup_state(int fd)
{
unsigned long long magic;
int ret, len;
if (no_write) {
return no_write_fixup_state;
}
lseek64(fd, 0, SEEK_SET);
len = read(fd, &magic, sizeof(magic));
if (len != sizeof(magic)) {
critical_error("cannot read fixup_state\n");
}
switch (magic) {
case MAGIC_STATE_MARKING_INUMS:
ret = STATE_MARKING_INUMS;
break;
case MAGIC_STATE_UPDATING_INUMS:
ret = STATE_UPDATING_INUMS;
break;
case MAGIC_STATE_UPDATING_SB:
ret = STATE_UPDATING_SB;
break;
default:
ret = STATE_UNSET;
}
return ret;
}
static int set_fs_fixup_state(int fd, int state)
{
unsigned long long magic;
struct ext4_super_block sb;
int len;
if (no_write) {
no_write_fixup_state = state;
return 0;
}
switch (state) {
case STATE_MARKING_INUMS:
magic = MAGIC_STATE_MARKING_INUMS;
break;
case STATE_UPDATING_INUMS:
magic = MAGIC_STATE_UPDATING_INUMS;
break;
case STATE_UPDATING_SB:
magic = MAGIC_STATE_UPDATING_SB;
break;
case STATE_UNSET:
default:
magic = 0ll;
break;
}
lseek64(fd, 0, SEEK_SET);
len = write(fd, &magic, sizeof(magic));
if (len != sizeof(magic)) {
critical_error("cannot write fixup_state\n");
}
read_sb(fd, &sb);
if (magic) {
/* If we are in the process of updating the filesystem, make it unmountable */
sb.s_desc_size |= 1;
} else {
/* we are done, so make the filesystem mountable again */
sb.s_desc_size &= ~1;
}
if (!no_write) {
write_sb(fd, 1024, &sb);
}
return 0;
}
static int read_inode(int fd, unsigned int inum, struct ext4_inode *inode)
{
unsigned int bg_num, bg_offset;
off64_t inode_offset;
int len;
bg_num = (inum-1) / info.inodes_per_group;
bg_offset = (inum-1) % info.inodes_per_group;
inode_offset = ((unsigned long long)aux_info.bg_desc[bg_num].bg_inode_table * info.block_size) +
(bg_offset * info.inode_size);
if (lseek64(fd, inode_offset, SEEK_SET) < 0) {
critical_error_errno("failed to seek to inode %d\n", inum);
}
len=read(fd, inode, sizeof(*inode));
if (len != sizeof(*inode)) {
critical_error_errno("failed to read inode %d\n", inum);
}
return 0;
}
static int read_block(int fd, unsigned long long block_num, void *block)
{
off64_t off;
unsigned int len;
off = block_num * info.block_size;
if (lseek64(fd, off, SEEK_SET) , 0) {
critical_error_errno("failed to seek to block %lld\n", block_num);
}
len=read(fd, block, info.block_size);
if (len != info.block_size) {
critical_error_errno("failed to read block %lld\n", block_num);
}
return 0;
}
static int write_block(int fd, unsigned long long block_num, void *block)
{
off64_t off;
unsigned int len;
if (no_write) {
return 0;
}
off = block_num * info.block_size;
if (lseek64(fd, off, SEEK_SET) < 0) {
critical_error_errno("failed to seek to block %lld\n", block_num);
}
len=write(fd, block, info.block_size);
if (len != info.block_size) {
critical_error_errno("failed to write block %lld\n", block_num);
}
return 0;
}
static void check_inode_bitmap(int fd, unsigned int bg_num)
{
unsigned int inode_bitmap_block_num;
unsigned char block[MAX_EXT4_BLOCK_SIZE];
int i, bitmap_updated = 0;
/* Using the bg_num, aux_info.bg_desc[], info.inodes_per_group and
* new_inodes_per_group, retrieve the inode bitmap, and make sure
* the bits between the old and new size are clear
*/
inode_bitmap_block_num = aux_info.bg_desc[bg_num].bg_inode_bitmap;
read_block(fd, inode_bitmap_block_num, block);
for (i = info.inodes_per_group; i < new_inodes_per_group; i++) {
if (bitmap_get_bit(block, i)) {
bitmap_clear_bit(block, i);
bitmap_updated = 1;
}
}
if (bitmap_updated) {
if (verbose) {
printf("Warning: updated inode bitmap for block group %d\n", bg_num);
}
write_block(fd, inode_bitmap_block_num, block);
}
return;
}
/* Update the superblock and bgdesc of the specified block group */
static int update_superblocks_and_bg_desc(int fd, int state)
{
off64_t ret;
struct ext4_super_block sb;
unsigned int num_block_groups, total_new_inodes;
unsigned int i;
read_sb(fd, &sb);
/* Compute how many more inodes are now available */
num_block_groups = DIV_ROUND_UP(aux_info.len_blocks, info.blocks_per_group);
total_new_inodes = num_block_groups * (new_inodes_per_group - sb.s_inodes_per_group);
if (verbose) {
printf("created %d additional inodes\n", total_new_inodes);
}
/* Update the free inodes count in each block group descriptor */
for (i = 0; i < num_block_groups; i++) {
if (state == STATE_UPDATING_SB) {
aux_info.bg_desc[i].bg_free_inodes_count += (new_inodes_per_group - sb.s_inodes_per_group);
}
check_inode_bitmap(fd, i);
}
/* First some sanity checks */
if ((sb.s_inodes_count + total_new_inodes) != (new_inodes_per_group * num_block_groups)) {
critical_error("Failed sanity check on new inode count\n");
}
if (new_inodes_per_group % (info.block_size/info.inode_size)) {
critical_error("Failed sanity check on new inode per group alignment\n");
}
/* Updat
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
make-ext4fs-2015-05-01.tar.gz (49个子文件)
make-ext4fs-2015-05-01
include
private
android_filesystem_capability.h 3KB
ext4_utils.h 4KB
ext4fixup.c 25KB
libsparse
include
sparse
sparse.h 10KB
backed_block.h 2KB
Makefile 266B
output_file.h 2KB
sparse_crc32.c 6KB
output_file.c 16KB
backed_block.c 8KB
sparse_defs.h 1KB
defs.h 758B
sparse_read.c 10KB
sparse_format.h 2KB
sparse_file.h 911B
sparse.c 8KB
sparse_crc32.h 710B
sparse_err.c 993B
wipe.c 2KB
MODULE_LICENSE_APACHE2 0B
ext4_sb.c 2KB
sha1.h 668B
extent.c 6KB
ext4_utils.c 15KB
ext4_kernel_headers.h 1KB
canned_fs_config.c 3KB
allocate.h 2KB
indirect.h 992B
Makefile 518B
allocate.c 18KB
ext4_extents.h 3KB
ext4_sb.h 1KB
jbd2.h 4KB
extent.h 1005B
ext4.h 19KB
make_ext4fs.c 14KB
wipe.h 954B
ext4fixup.h 780B
uuid.c 2KB
contents.c 14KB
crc16.c 3KB
canned_fs_config.h 892B
uuid.h 765B
make_ext4fs_main.c 4KB
contents.h 1KB
indirect.c 13KB
sha1.c 9KB
xattr.h 1KB
NOTICE 10KB
共 49 条
- 1
资源评论
zlzabc123
- 粉丝: 17
- 资源: 30
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于SpringBoot+Vue的校医院挂号平台(前端代码)
- (源码)基于NodeMCU框架的NodeHealthGuard系统心脏健康早期预警系统.zip
- 基于SpringBoot+Vue的校医院挂号平台(后端代码)
- (源码)基于PyTorch的图像分类模型训练与评估系统.zip
- AT89C52单片机加LCD12864实现贪吃蛇游戏
- (源码)基于Java的研究生管理系统.zip
- (源码)基于SpringBoot和Vue的社区论坛系统.zip
- (源码)基于Python的自动安卓APK安装系统.zip
- (源码)基于SpringBoot和Netty的即时通讯系统.zip
- (源码)基于SpringBoot和Vue的小区物业后台管理系统.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功