*Update and fixed a few thins in libext2fs-wii. For changelog see http://code.google.com/p/libext2fs-wii/source/list

This commit is contained in:
strtoul 2011-11-05 18:50:49 +00:00
parent 3994181361
commit afb3b68349
93 changed files with 5016 additions and 648 deletions

View File

@ -1,22 +1,22 @@
/** /********************************************************************************
* ext2.h - devoptab file routines for EXT2/3/4-based devices. * ext2.h - devoptab file routines for EXT2/3/4-based devices. *
* * *
* Copyright (c) 2010 Dimok * Copyright (c) 2010 Dimok *
* * *
* This program/include file is free software; you can redistribute it and/or * This program/include file is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as published * modify it under the terms of the GNU General Public License as published *
* by the Free Software Foundation; either version 2 of the License, or * by the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * (at your option) any later version. *
* * *
* This program/include file is distributed in the hope that it will be * This program/include file is distributed in the hope that it will be *
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * GNU General Public License for more details. *
* * *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation, * along with this program; if not, write to the Free Software Foundation, *
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
*/ ********************************************************************************/
#ifndef __EXT2_H_ #ifndef __EXT2_H_
#define __EXT2_H_ #define __EXT2_H_
@ -28,9 +28,15 @@ extern "C" {
#include <gccore.h> #include <gccore.h>
#include <ogc/disc_io.h> #include <ogc/disc_io.h>
/* EXT2 cache options */ /**
#define CACHE_DEFAULT_PAGE_COUNT 8 /* The default number of pages in the cache */ * EXT2 cache options
#define CACHE_DEFAULT_PAGE_SIZE 128 /* The default number of sectors per cache page */ *
* It is recommended to use more pages instead of large page sizes for cache due to the sporadic write behaviour of ext file system.
* It will significantly increase the speed. A page size of 32 is mostly suffiecient. The larger the page count the faster the
* read/write between smaller files will be. Larger page sizes result in faster read/write of single big files.
*/
#define EXT2_CACHE_DEFAULT_PAGE_COUNT 64 /* The default number of pages in the cache */
#define EXT2_CACHE_DEFAULT_PAGE_SIZE 32 /* The default number of sectors per cache page */
/* EXT2 mount flags */ /* EXT2 mount flags */
#define EXT2_FLAG_RW 0x00001 /* Open the filesystem for reading and writing. Without this flag, the filesystem is opened for reading only. */ #define EXT2_FLAG_RW 0x00001 /* Open the filesystem for reading and writing. Without this flag, the filesystem is opened for reading only. */
@ -38,7 +44,8 @@ extern "C" {
#define EXT2_FLAG_JOURNAL_DEV_OK 0x01000 /* Only open external journal devices if this flag is set (e.g. ext3/ext4) */ #define EXT2_FLAG_JOURNAL_DEV_OK 0x01000 /* Only open external journal devices if this flag is set (e.g. ext3/ext4) */
#define EXT2_FLAG_64BITS 0x20000 /* Use the new style 64-Bit bitmaps. For more information see gen_bitmap64.c */ #define EXT2_FLAG_64BITS 0x20000 /* Use the new style 64-Bit bitmaps. For more information see gen_bitmap64.c */
#define EXT2_FLAG_PRINT_PROGRESS 0x40000 /* If this flag is set the progress of file operations will be printed to stdout */ #define EXT2_FLAG_PRINT_PROGRESS 0x40000 /* If this flag is set the progress of file operations will be printed to stdout */
#define EXT2_FLAG_DEFAULT (EXT2_FLAG_RW | EXT2_FLAG_64BITS | EXT2_FLAG_JOURNAL_DEV_OK) #define EXT2_FLAG_SKIP_MMP 0x100000 /* Open without multi-mount protection check. */
#define EXT2_FLAG_DEFAULT (EXT2_FLAG_RW | EXT2_FLAG_64BITS | EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_SKIP_MMP)
/** /**
* Find all EXT2/3/4 partitions on a block device. * Find all EXT2/3/4 partitions on a block device.

View File

@ -28,9 +28,7 @@ LIBDIR := ../lib
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
CFLAGS = -O3 -Wall $(MACHDEP) $(INCLUDE) -DGEKKO \ CFLAGS = -Os -Wall -Wno-unused $(MACHDEP) $(INCLUDE) -DGEKKO -DWORDS_BIGENDIAN
-DHAVE_UNISTD_H -DHAVE_SYS_STAT_H -DHAVE_SYS_TYPES_H -DHAVE_UTIME_H -DWORDS_BIGENDIAN \
-DHAVE_ERRNO_H -DHAVE_STRDUP -DHAVE_SYS_RESOURCE_H
CXXFLAGS = $(CFLAGS) CXXFLAGS = $(CFLAGS)
ASFLAGS := -g ASFLAGS := -g
export EXT2BIN := $(LIBDIR)/$(PLATFORM)/libext2fs.a export EXT2BIN := $(LIBDIR)/$(PLATFORM)/libext2fs.a

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -52,6 +53,11 @@ static void check_block_uninit(ext2_filsys fs, ext2fs_block_bitmap map,
else else
old_desc_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks; old_desc_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
for (i=0; i < fs->super->s_blocks_per_group; i++, blk++)
ext2fs_fast_unmark_block_bitmap2(map, blk);
blk = (group * fs->super->s_blocks_per_group) +
fs->super->s_first_data_block;
for (i=0; i < fs->super->s_blocks_per_group; i++, blk++) { for (i=0; i < fs->super->s_blocks_per_group; i++, blk++) {
if ((blk == super_blk) || if ((blk == super_blk) ||
(old_desc_blk && old_desc_blocks && (old_desc_blk && old_desc_blocks &&
@ -64,8 +70,6 @@ static void check_block_uninit(ext2_filsys fs, ext2fs_block_bitmap map,
(blk < ext2fs_inode_table_loc(fs, group) (blk < ext2fs_inode_table_loc(fs, group)
+ fs->inode_blocks_per_group))) + fs->inode_blocks_per_group)))
ext2fs_fast_mark_block_bitmap2(map, blk); ext2fs_fast_mark_block_bitmap2(map, blk);
else
ext2fs_fast_unmark_block_bitmap2(map, blk);
} }
ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT); ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
ext2fs_group_desc_csum_set(fs, group); ext2fs_group_desc_csum_set(fs, group);
@ -149,6 +153,7 @@ errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
ext2fs_block_bitmap map, blk64_t *ret) ext2fs_block_bitmap map, blk64_t *ret)
{ {
blk64_t i; blk64_t i;
int c_ratio;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@ -159,6 +164,9 @@ errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
if (!goal || (goal >= ext2fs_blocks_count(fs->super))) if (!goal || (goal >= ext2fs_blocks_count(fs->super)))
goal = fs->super->s_first_data_block; goal = fs->super->s_first_data_block;
i = goal; i = goal;
c_ratio = 1 << ext2fs_get_bitmap_granularity(map);
if (c_ratio > 1)
goal &= ~EXT2FS_CLUSTER_MASK(fs);
check_block_uninit(fs, map, check_block_uninit(fs, map,
(i - fs->super->s_first_data_block) / (i - fs->super->s_first_data_block) /
EXT2_BLOCKS_PER_GROUP(fs->super)); EXT2_BLOCKS_PER_GROUP(fs->super));
@ -173,7 +181,7 @@ errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
*ret = i; *ret = i;
return 0; return 0;
} }
i++; i = (i + c_ratio) & ~(c_ratio - 1);
if (i >= ext2fs_blocks_count(fs->super)) if (i >= ext2fs_blocks_count(fs->super))
i = fs->super->s_first_data_block; i = fs->super->s_first_data_block;
} while (i != goal); } while (i != goal);
@ -254,6 +262,7 @@ errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start, blk64_t finish,
int num, ext2fs_block_bitmap map, blk64_t *ret) int num, ext2fs_block_bitmap map, blk64_t *ret)
{ {
blk64_t b = start; blk64_t b = start;
int c_ratio;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@ -267,6 +276,9 @@ errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start, blk64_t finish,
finish = start; finish = start;
if (!num) if (!num)
num = 1; num = 1;
c_ratio = 1 << ext2fs_get_bitmap_granularity(map);
b &= ~(c_ratio - 1);
finish &= ~(c_ratio -1);
do { do {
if (b+num-1 > ext2fs_blocks_count(fs->super)) if (b+num-1 > ext2fs_blocks_count(fs->super))
b = fs->super->s_first_data_block; b = fs->super->s_first_data_block;
@ -274,7 +286,7 @@ errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start, blk64_t finish,
*ret = b; *ret = b;
return 0; return 0;
} }
b++; b += c_ratio;
} while (b != finish); } while (b != finish);
return EXT2_ET_BLOCK_ALLOC_FAIL; return EXT2_ET_BLOCK_ALLOC_FAIL;
} }

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -59,6 +60,9 @@ int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
if (super_blk || (group == 0)) if (super_blk || (group == 0))
ext2fs_mark_block_bitmap2(bmap, super_blk); ext2fs_mark_block_bitmap2(bmap, super_blk);
if ((group == 0) && (fs->blocksize == 1024) &&
EXT2FS_CLUSTER_RATIO(fs) > 1)
ext2fs_mark_block_bitmap2(bmap, 0);
if (old_desc_blk) { if (old_desc_blk) {
if (fs->super->s_reserved_gdt_blocks && fs->block_map == bmap) if (fs->super->s_reserved_gdt_blocks && fs->block_map == bmap)
@ -71,15 +75,7 @@ int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
if (new_desc_blk) if (new_desc_blk)
ext2fs_mark_block_bitmap2(bmap, new_desc_blk); ext2fs_mark_block_bitmap2(bmap, new_desc_blk);
if (group == fs->group_desc_count-1) { num_blocks = ext2fs_group_blocks_count(fs, group);
num_blocks = (ext2fs_blocks_count(fs->super) -
fs->super->s_first_data_block) %
fs->super->s_blocks_per_group;
if (!num_blocks)
num_blocks = fs->super->s_blocks_per_group;
} else
num_blocks = fs->super->s_blocks_per_group;
num_blocks -= 2 + fs->inode_blocks_per_group + used_blks; num_blocks -= 2 + fs->inode_blocks_per_group + used_blks;
return num_blocks ; return num_blocks ;

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include "ext2_fs.h" #include "ext2_fs.h"
@ -77,7 +78,8 @@ void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse)
ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT); ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
ext2fs_group_desc_csum_set(fs, group); ext2fs_group_desc_csum_set(fs, group);
ext2fs_free_blocks_count_add(fs->super, -inuse); ext2fs_free_blocks_count_add(fs->super,
-inuse * EXT2FS_CLUSTER_RATIO(fs));
ext2fs_mark_super_dirty(fs); ext2fs_mark_super_dirty(fs);
ext2fs_mark_bb_dirty(fs); ext2fs_mark_bb_dirty(fs);
if (fs->block_alloc_stats) if (fs->block_alloc_stats)

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -35,45 +36,45 @@
* tables can be allocated continously and in order. * tables can be allocated continously and in order.
*/ */
static blk64_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk, static blk64_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk,
ext2fs_block_bitmap bmap, int offset, int size, ext2fs_block_bitmap bmap, int rem_grp,
int elem_size) int elem_size)
{ {
int flexbg, flexbg_size; int flexbg, flexbg_size, size;
blk64_t last_blk, first_free = 0; blk64_t last_blk, first_free = 0;
dgrp_t last_grp; dgrp_t last_grp;
flexbg_size = 1 << fs->super->s_log_groups_per_flex; flexbg_size = 1 << fs->super->s_log_groups_per_flex;
flexbg = group / flexbg_size; flexbg = group / flexbg_size;
size = rem_grp * elem_size;
if (size > (int) (fs->super->s_blocks_per_group / 8)) if (size > (int) (fs->super->s_blocks_per_group / 8))
size = (int) fs->super->s_blocks_per_group / 8; size = (int) fs->super->s_blocks_per_group / 8;
if (offset)
offset -= 1;
/* /*
* Don't do a long search if the previous block * Don't do a long search if the previous block
* search is still valid. * search is still valid.
*/ */
if (start_blk && group % flexbg_size) { if (start_blk && ext2fs_test_block_bitmap_range2(bmap, start_blk,
if (ext2fs_test_block_bitmap_range2(bmap, start_blk + elem_size, elem_size))
size)) return start_blk;
return start_blk + elem_size;
}
start_blk = ext2fs_group_first_block2(fs, flexbg_size * flexbg); start_blk = ext2fs_group_first_block2(fs, flexbg_size * flexbg);
last_grp = group | (flexbg_size - 1); last_grp = group | (flexbg_size - 1);
if (last_grp > fs->group_desc_count) if (last_grp > fs->group_desc_count-1)
last_grp = fs->group_desc_count; last_grp = fs->group_desc_count-1;
last_blk = ext2fs_group_last_block2(fs, last_grp); last_blk = ext2fs_group_last_block2(fs, last_grp);
/* Find the first available block */ /* Find the first available block */
if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, 1, bmap, if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, size,
&first_free)) bmap, &first_free) == 0)
return first_free; return first_free;
if (ext2fs_get_free_blocks2(fs, first_free + offset, last_blk, size, if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, elem_size,
bmap, &first_free)) bmap, &first_free) == 0)
return first_free;
if (ext2fs_get_free_blocks2(fs, 0, last_blk, elem_size, bmap,
&first_free) == 0)
return first_free; return first_free;
return first_free; return first_free;
@ -82,10 +83,11 @@ static blk64_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk,
errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group, errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
ext2fs_block_bitmap bmap) ext2fs_block_bitmap bmap)
{ {
unsigned int j;
errcode_t retval; errcode_t retval;
blk64_t group_blk, start_blk, last_blk, new_blk, blk; blk64_t group_blk, start_blk, last_blk, new_blk, blk;
dgrp_t last_grp = 0; dgrp_t last_grp = 0;
int j, rem_grps = 0, flexbg_size = 0; int rem_grps = 0, flexbg_size = 0;
group_blk = ext2fs_group_first_block2(fs, group); group_blk = ext2fs_group_first_block2(fs, group);
last_blk = ext2fs_group_last_block2(fs, group); last_blk = ext2fs_group_last_block2(fs, group);
@ -98,9 +100,9 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
fs->super->s_log_groups_per_flex) { fs->super->s_log_groups_per_flex) {
flexbg_size = 1 << fs->super->s_log_groups_per_flex; flexbg_size = 1 << fs->super->s_log_groups_per_flex;
last_grp = group | (flexbg_size - 1); last_grp = group | (flexbg_size - 1);
rem_grps = last_grp - group; if (last_grp > fs->group_desc_count-1)
if (last_grp > fs->group_desc_count) last_grp = fs->group_desc_count-1;
last_grp = fs->group_desc_count; rem_grps = last_grp - group + 1;
} }
/* /*
@ -122,10 +124,10 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
if (flexbg_size) { if (flexbg_size) {
blk64_t prev_block = 0; blk64_t prev_block = 0;
if (group && ext2fs_block_bitmap_loc(fs, group - 1)) if (group % flexbg_size)
prev_block = ext2fs_block_bitmap_loc(fs, group - 1); prev_block = ext2fs_block_bitmap_loc(fs, group - 1) + 1;
start_blk = flexbg_offset(fs, group, prev_block, bmap, start_blk = flexbg_offset(fs, group, prev_block, bmap,
0, rem_grps, 1); rem_grps, 1);
last_blk = ext2fs_group_last_block2(fs, last_grp); last_blk = ext2fs_group_last_block2(fs, last_grp);
} }
@ -150,10 +152,13 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
if (flexbg_size) { if (flexbg_size) {
blk64_t prev_block = 0; blk64_t prev_block = 0;
if (group && ext2fs_inode_bitmap_loc(fs, group - 1)) if (group % flexbg_size)
prev_block = ext2fs_inode_bitmap_loc(fs, group - 1); prev_block = ext2fs_inode_bitmap_loc(fs, group - 1) + 1;
else
prev_block = ext2fs_block_bitmap_loc(fs, group) +
flexbg_size;
start_blk = flexbg_offset(fs, group, prev_block, bmap, start_blk = flexbg_offset(fs, group, prev_block, bmap,
flexbg_size, rem_grps, 1); rem_grps, 1);
last_blk = ext2fs_group_last_block2(fs, last_grp); last_blk = ext2fs_group_last_block2(fs, last_grp);
} }
@ -181,15 +186,16 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
*/ */
if (flexbg_size) { if (flexbg_size) {
blk64_t prev_block = 0; blk64_t prev_block = 0;
if (group && ext2fs_inode_table_loc(fs, group - 1))
prev_block = ext2fs_inode_table_loc(fs, group - 1); if (group % flexbg_size)
if (last_grp == fs->group_desc_count) prev_block = ext2fs_inode_table_loc(fs, group - 1) +
rem_grps = last_grp - group; fs->inode_blocks_per_group;
else
prev_block = ext2fs_inode_bitmap_loc(fs, group) +
flexbg_size;
group_blk = flexbg_offset(fs, group, prev_block, bmap, group_blk = flexbg_offset(fs, group, prev_block, bmap,
flexbg_size * 2, rem_grps, fs->inode_blocks_per_group);
fs->inode_blocks_per_group *
rem_grps,
fs->inode_blocks_per_group);
last_blk = ext2fs_group_last_block2(fs, last_grp); last_blk = ext2fs_group_last_block2(fs, last_grp);
} }

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -177,7 +178,7 @@ int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk)
return high; return high;
while (low < high) { while (low < high) {
mid = (low+high)/2; mid = ((unsigned)low + (unsigned)high)/2;
if (mid == low || mid == high) if (mid == low || mid == high)
break; break;
if (blk == bb->list[mid]) if (blk == bb->list[mid])

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -13,6 +13,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -27,6 +28,7 @@
#include "ext2_fs.h" #include "ext2_fs.h"
#include "ext2fs.h" #include "ext2fs.h"
#include "ext2fsP.h" #include "ext2fsP.h"
#include "bmap64.h"
void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap) void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
{ {
@ -90,9 +92,9 @@ errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
fs->write_bitmaps = ext2fs_write_bitmaps; fs->write_bitmaps = ext2fs_write_bitmaps;
start = fs->super->s_first_data_block; start = EXT2FS_B2C(fs, fs->super->s_first_data_block);
end = ext2fs_blocks_count(fs->super)-1; end = EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super)-1);
real_end = ((__u64) EXT2_BLOCKS_PER_GROUP(fs->super) real_end = ((__u64) EXT2_CLUSTERS_PER_GROUP(fs->super)
* (__u64) fs->group_desc_count)-1 + start; * (__u64) fs->group_desc_count)-1 + start;
if (fs->flags & EXT2_FLAG_64BITS) if (fs->flags & EXT2_FLAG_64BITS)
@ -110,6 +112,56 @@ errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
(ext2fs_generic_bitmap *) ret)); (ext2fs_generic_bitmap *) ret));
} }
/*
* ext2fs_allocate_block_bitmap() really allocates a per-cluster
* bitmap for backwards compatibility. This function allocates a
* block bitmap which is truly per-block, even if clusters/bigalloc
* are enabled. mke2fs and e2fsck need this for tracking the
* allocation of the file system metadata blocks.
*/
errcode_t ext2fs_allocate_subcluster_bitmap(ext2_filsys fs,
const char *descr,
ext2fs_block_bitmap *ret)
{
__u64 start, end, real_end;
ext2fs_generic_bitmap bmap;
errcode_t retval;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
fs->write_bitmaps = ext2fs_write_bitmaps;
if (!fs->cluster_ratio_bits)
return ext2fs_allocate_block_bitmap(fs, descr, ret);
if ((fs->flags & EXT2_FLAG_64BITS) == 0)
return EXT2_ET_CANT_USE_LEGACY_BITMAPS;
start = fs->super->s_first_data_block;
end = ext2fs_blocks_count(fs->super)-1;
real_end = ((__u64) EXT2_BLOCKS_PER_GROUP(fs->super)
* (__u64) fs->group_desc_count)-1 + start;
retval = ext2fs_alloc_generic_bmap(fs, EXT2_ET_MAGIC_BLOCK_BITMAP64,
EXT2FS_BMAP64_BITARRAY, start,
end, real_end, descr, &bmap);
if (retval)
return retval;
bmap->cluster_bits = 0;
*ret = bmap;
return 0;
}
int ext2fs_get_bitmap_granularity(ext2fs_block_bitmap bitmap)
{
ext2fs_generic_bitmap bmap = bitmap;
if (!EXT2FS_IS_64_BITMAP(bmap))
return 0;
return bmap->cluster_bits;
}
errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap, errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
ext2_ino_t end, ext2_ino_t *oend) ext2_ino_t end, ext2_ino_t *oend)
{ {

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_SYS_TYPES_H #if HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>

View File

@ -12,6 +12,8 @@
#ifndef _BITOPS_H_ #ifndef _BITOPS_H_
#define _BITOPS_H_ #define _BITOPS_H_
#include "config.h"
extern int ext2fs_set_bit(unsigned int nr,void * addr); extern int ext2fs_set_bit(unsigned int nr,void * addr);
extern int ext2fs_clear_bit(unsigned int nr, void * addr); extern int ext2fs_clear_bit(unsigned int nr, void * addr);
extern int ext2fs_test_bit(unsigned int nr, const void * addr); extern int ext2fs_test_bit(unsigned int nr, const void * addr);
@ -33,6 +35,8 @@ extern __u64 ext2fs_swab64(__u64 val);
#define ext2fs_le32_to_cpu(x) ext2fs_swab32((x)) #define ext2fs_le32_to_cpu(x) ext2fs_swab32((x))
#define ext2fs_cpu_to_le16(x) ext2fs_swab16((x)) #define ext2fs_cpu_to_le16(x) ext2fs_swab16((x))
#define ext2fs_le16_to_cpu(x) ext2fs_swab16((x)) #define ext2fs_le16_to_cpu(x) ext2fs_swab16((x))
#define ext2fs_cpu_to_be64(x) ((__u64)(x))
#define ext2fs_be64_to_cpu(x) ((__u64)(x))
#define ext2fs_cpu_to_be32(x) ((__u32)(x)) #define ext2fs_cpu_to_be32(x) ((__u32)(x))
#define ext2fs_be32_to_cpu(x) ((__u32)(x)) #define ext2fs_be32_to_cpu(x) ((__u32)(x))
#define ext2fs_cpu_to_be16(x) ((__u16)(x)) #define ext2fs_cpu_to_be16(x) ((__u16)(x))
@ -44,6 +48,8 @@ extern __u64 ext2fs_swab64(__u64 val);
#define ext2fs_le32_to_cpu(x) ((__u32)(x)) #define ext2fs_le32_to_cpu(x) ((__u32)(x))
#define ext2fs_cpu_to_le16(x) ((__u16)(x)) #define ext2fs_cpu_to_le16(x) ((__u16)(x))
#define ext2fs_le16_to_cpu(x) ((__u16)(x)) #define ext2fs_le16_to_cpu(x) ((__u16)(x))
#define ext2fs_cpu_to_be64(x) ext2fs_swab64((x))
#define ext2fs_be64_to_cpu(x) ext2fs_swab64((x))
#define ext2fs_cpu_to_be32(x) ext2fs_swab32((x)) #define ext2fs_cpu_to_be32(x) ext2fs_swab32((x))
#define ext2fs_be32_to_cpu(x) ext2fs_swab32((x)) #define ext2fs_be32_to_cpu(x) ext2fs_swab32((x))
#define ext2fs_cpu_to_be16(x) ext2fs_swab16((x)) #define ext2fs_cpu_to_be16(x) ext2fs_swab16((x))
@ -634,5 +640,4 @@ _INLINE_ void ext2fs_fast_unmark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
#undef _INLINE_ #undef _INLINE_
#endif #endif
#endif #endif

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -11,6 +11,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include "ext2fs.h" #include "ext2fs.h"
/* /*
@ -42,6 +43,25 @@ blk64_t ext2fs_group_last_block2(ext2_filsys fs, dgrp_t group)
(fs->super->s_blocks_per_group - 1)); (fs->super->s_blocks_per_group - 1));
} }
/*
* Return the number of blocks in a group
*/
int ext2fs_group_blocks_count(ext2_filsys fs, dgrp_t group)
{
int num_blocks;
if (group == fs->group_desc_count - 1) {
num_blocks = (ext2fs_blocks_count(fs->super) -
fs->super->s_first_data_block) %
fs->super->s_blocks_per_group;
if (!num_blocks)
num_blocks = fs->super->s_blocks_per_group;
} else
num_blocks = fs->super->s_blocks_per_group;
return num_blocks;
}
/* /*
* Return the inode data block count * Return the inode data block count
*/ */
@ -455,23 +475,24 @@ void ext2fs_bg_checksum_set(ext2_filsys fs, dgrp_t group, __u16 checksum)
/* /*
* Get the acl block of a file * Get the acl block of a file
*
* XXX Ignoring 64-bit file system flag - most places where this is
* called don't have access to the fs struct, and the high bits should
* be 0 in the non-64-bit case anyway.
*/ */
blk64_t ext2fs_file_acl_block(const struct ext2_inode *inode) blk64_t ext2fs_file_acl_block(ext2_filsys fs, const struct ext2_inode *inode)
{ {
return (inode->i_file_acl | blk64_t blk = inode->i_file_acl;
(__u64) inode->osd2.linux2.l_i_file_acl_high << 32);
if (fs && fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
blk |= ((__u64) inode->osd2.linux2.l_i_file_acl_high) << 32;
return blk;
} }
/* /*
* Set the acl block of a file * Set the acl block of a file
*/ */
void ext2fs_file_acl_block_set(struct ext2_inode *inode, blk64_t blk) void ext2fs_file_acl_block_set(ext2_filsys fs, struct ext2_inode *inode,
blk64_t blk)
{ {
inode->i_file_acl = blk; inode->i_file_acl = blk;
if (fs && fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
inode->osd2.linux2.l_i_file_acl_high = (__u64) blk >> 32; inode->osd2.linux2.l_i_file_acl_high = (__u64) blk >> 32;
} }

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -453,6 +454,17 @@ errcode_t ext2fs_block_iterate3(ext2_filsys fs,
uninit = 0; uninit = 0;
if (extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT) if (extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT)
uninit = EXT2_EXTENT_SET_BMAP_UNINIT; uninit = EXT2_EXTENT_SET_BMAP_UNINIT;
#if 0
printf("lblk %llu pblk %llu len %d blockcnt %llu\n",
extent.e_lblk, extent.e_pblk,
extent.e_len, blockcnt);
#endif
if (extent.e_lblk + extent.e_len <= blockcnt)
continue;
if (extent.e_lblk > blockcnt)
blockcnt = extent.e_lblk;
j = blockcnt - extent.e_lblk;
blk += j;
for (blockcnt = extent.e_lblk, j = 0; for (blockcnt = extent.e_lblk, j = 0;
j < extent.e_len; j < extent.e_len;
blk++, blockcnt++, j++) { blk++, blockcnt++, j++) {

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -129,6 +130,106 @@ static _BMAP_INLINE_ errcode_t block_tind_bmap(ext2_filsys fs, int flags,
return retval; return retval;
} }
static errcode_t extent_bmap(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode *inode,
ext2_extent_handle_t handle,
char *block_buf, int bmap_flags, blk64_t block,
int *ret_flags, int *blocks_alloc,
blk64_t *phys_blk);
static errcode_t implied_cluster_alloc(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode *inode,
ext2_extent_handle_t handle,
blk64_t block, blk64_t *phys_blk)
{
blk64_t base_block, pblock = 0;
int i;
if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_BIGALLOC))
return 0;
base_block = block & ~EXT2FS_CLUSTER_MASK(fs);
for (i = 0; i < EXT2FS_CLUSTER_RATIO(fs); i++) {
if (block == base_block)
return 0;
extent_bmap(fs, ino, inode, handle, 0, 0,
base_block + i, 0, 0, &pblock);
if (pblock)
break;
}
if (pblock == 0)
return 0;
*phys_blk = pblock - i + (block - base_block);
return 0;
}
static errcode_t extent_bmap(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode *inode,
ext2_extent_handle_t handle,
char *block_buf, int bmap_flags, blk64_t block,
int *ret_flags, int *blocks_alloc,
blk64_t *phys_blk)
{
struct ext2fs_extent extent;
unsigned int offset;
errcode_t retval = 0;
blk64_t blk64 = 0;
int alloc = 0;
if (bmap_flags & BMAP_SET) {
retval = ext2fs_extent_set_bmap(handle, block,
*phys_blk, 0);
return retval;
}
retval = ext2fs_extent_goto(handle, block);
if (retval) {
/* If the extent is not found, return phys_blk = 0 */
if (retval == EXT2_ET_EXTENT_NOT_FOUND)
goto got_block;
return retval;
}
retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
if (retval)
return retval;
offset = block - extent.e_lblk;
if (block >= extent.e_lblk && (offset <= extent.e_len)) {
*phys_blk = extent.e_pblk + offset;
if (ret_flags && extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT)
*ret_flags |= BMAP_RET_UNINIT;
}
got_block:
if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) {
implied_cluster_alloc(fs, ino, inode, handle, block, &blk64);
if (blk64)
goto set_extent;
retval = extent_bmap(fs, ino, inode, handle, block_buf,
0, block-1, 0, blocks_alloc, &blk64);
if (retval)
blk64 = 0;
retval = ext2fs_alloc_block2(fs, blk64, block_buf,
&blk64);
if (retval)
return retval;
blk64 &= ~EXT2FS_CLUSTER_MASK(fs);
blk64 += EXT2FS_CLUSTER_MASK(fs) & block;
alloc++;
set_extent:
retval = ext2fs_extent_set_bmap(handle, block,
blk64, 0);
if (retval)
return retval;
/* Update inode after setting extent */
retval = ext2fs_read_inode(fs, ino, inode);
if (retval)
return retval;
*blocks_alloc += alloc;
*phys_blk = blk64;
}
return 0;
}
errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
char *block_buf, int bmap_flags, blk64_t block, char *block_buf, int bmap_flags, blk64_t block,
int *ret_flags, blk64_t *phys_blk) int *ret_flags, blk64_t *phys_blk)
@ -156,54 +257,6 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
} }
addr_per_block = (blk_t) fs->blocksize >> 2; addr_per_block = (blk_t) fs->blocksize >> 2;
if (inode->i_flags & EXT4_EXTENTS_FL) {
struct ext2fs_extent extent;
unsigned int offset;
retval = ext2fs_extent_open2(fs, ino, inode, &handle);
if (retval)
goto done;
if (bmap_flags & BMAP_SET) {
retval = ext2fs_extent_set_bmap(handle, block,
*phys_blk, 0);
goto done;
}
retval = ext2fs_extent_goto(handle, block);
if (retval) {
/* If the extent is not found, return phys_blk = 0 */
if (retval == EXT2_ET_EXTENT_NOT_FOUND)
goto got_block;
goto done;
}
retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
if (retval)
goto done;
offset = block - extent.e_lblk;
if (block >= extent.e_lblk && (offset <= extent.e_len)) {
*phys_blk = extent.e_pblk + offset;
if (ret_flags && extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT)
*ret_flags |= BMAP_RET_UNINIT;
}
got_block:
if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) {
retval = ext2fs_alloc_block(fs, b, block_buf, &b);
if (retval)
goto done;
retval = ext2fs_extent_set_bmap(handle, block,
(blk64_t) b, 0);
if (retval)
goto done;
/* Update inode after setting extent */
retval = ext2fs_read_inode(fs, ino, inode);
if (retval)
return retval;
blocks_alloc++;
*phys_blk = b;
}
retval = 0;
goto done;
}
if (!block_buf) { if (!block_buf) {
retval = ext2fs_get_array(2, fs->blocksize, &buf); retval = ext2fs_get_array(2, fs->blocksize, &buf);
if (retval) if (retval)
@ -211,6 +264,16 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
block_buf = buf; block_buf = buf;
} }
if (inode->i_flags & EXT4_EXTENTS_FL) {
retval = ext2fs_extent_open2(fs, ino, inode, &handle);
if (retval)
goto done;
retval = extent_bmap(fs, ino, inode, handle, block_buf,
bmap_flags, block, ret_flags,
&blocks_alloc, phys_blk);
goto done;
}
if (block < EXT2_NDIR_BLOCKS) { if (block < EXT2_NDIR_BLOCKS) {
if (bmap_flags & BMAP_SET) { if (bmap_flags & BMAP_SET) {
b = *phys_blk; b = *phys_blk;

View File

@ -16,6 +16,7 @@ struct ext2fs_struct_generic_bitmap {
int flags; int flags;
__u64 start, end; __u64 start, end;
__u64 real_end; __u64 real_end;
int cluster_bits;
char *description; char *description;
void *private; void *private;
errcode_t base_error_code; errcode_t base_error_code;

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -140,7 +141,7 @@ errcode_t ext2fs_move_blocks(ext2_filsys fs,
while (ino) { while (ino) {
if ((inode.i_links_count == 0) || if ((inode.i_links_count == 0) ||
!ext2fs_inode_has_valid_blocks(&inode)) !ext2fs_inode_has_valid_blocks2(fs, &inode))
goto next; goto next;
pb.ino = ino; pb.ino = ino;

View File

@ -12,6 +12,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -37,11 +38,11 @@ errcode_t ext2fs_check_desc(ext2_filsys fs)
blk64_t first_block = fs->super->s_first_data_block; blk64_t first_block = fs->super->s_first_data_block;
blk64_t last_block = ext2fs_blocks_count(fs->super)-1; blk64_t last_block = ext2fs_blocks_count(fs->super)-1;
blk64_t blk, b; blk64_t blk, b;
int j; unsigned int j;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
retval = ext2fs_allocate_block_bitmap(fs, "check_desc map", &bmap); retval = ext2fs_allocate_subcluster_bitmap(fs, "check_desc map", &bmap);
if (retval) if (retval)
return retval; return retval;
@ -53,8 +54,6 @@ errcode_t ext2fs_check_desc(ext2_filsys fs)
EXT4_FEATURE_INCOMPAT_FLEX_BG)) { EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
first_block = ext2fs_group_first_block2(fs, i); first_block = ext2fs_group_first_block2(fs, i);
last_block = ext2fs_group_last_block2(fs, i); last_block = ext2fs_group_last_block2(fs, i);
if (i == (fs->group_desc_count - 1))
last_block = ext2fs_blocks_count(fs->super)-1;
} }
/* /*

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -73,6 +74,8 @@ errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs,
int has_super; int has_super;
group_block = ext2fs_group_first_block2(fs, group); group_block = ext2fs_group_first_block2(fs, group);
if (group_block == 0 && fs->blocksize == 1024)
group_block = 1; /* Deal with 1024 blocksize && bigalloc */
if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
old_desc_blocks = fs->super->s_first_meta_bg; old_desc_blocks = fs->super->s_first_meta_bg;
@ -150,14 +153,7 @@ int ext2fs_super_and_bgd_loc(ext2_filsys fs,
&ret_new_desc_blk2, &ret_new_desc_blk2,
&ret_used_blks); &ret_used_blks);
if (group == fs->group_desc_count-1) { numblocks = ext2fs_group_blocks_count(fs, group);
numblocks = (ext2fs_blocks_count(fs->super) -
(blk64_t) fs->super->s_first_data_block) %
(blk64_t) fs->super->s_blocks_per_group;
if (!numblocks)
numblocks = fs->super->s_blocks_per_group;
} else
numblocks = fs->super->s_blocks_per_group;
if (ret_super_blk) if (ret_super_blk)
*ret_super_blk = (blk_t)ret_super_blk2; *ret_super_blk = (blk_t)ret_super_blk2;
@ -265,6 +261,11 @@ static errcode_t write_backup_super(ext2_filsys fs, dgrp_t group,
} }
errcode_t ext2fs_flush(ext2_filsys fs) errcode_t ext2fs_flush(ext2_filsys fs)
{
return ext2fs_flush2(fs, 0);
}
errcode_t ext2fs_flush2(ext2_filsys fs, int flags)
{ {
dgrp_t i; dgrp_t i;
errcode_t retval; errcode_t retval;
@ -406,6 +407,7 @@ write_primary_superblock_only:
ext2fs_swap_super(super_shadow); ext2fs_swap_super(super_shadow);
#endif #endif
if (!(flags & EXT2_FLAG_FLUSH_NO_SYNC))
retval = io_channel_flush(fs->io); retval = io_channel_flush(fs->io);
retval = write_primary_superblock(fs, super_shadow); retval = write_primary_superblock(fs, super_shadow);
if (retval) if (retval)
@ -413,6 +415,7 @@ write_primary_superblock_only:
fs->flags &= ~EXT2_FLAG_DIRTY; fs->flags &= ~EXT2_FLAG_DIRTY;
if (!(flags & EXT2_FLAG_FLUSH_NO_SYNC))
retval = io_channel_flush(fs->io); retval = io_channel_flush(fs->io);
errout: errout:
fs->super->s_state = fs_state; fs->super->s_state = fs_state;
@ -426,6 +429,11 @@ errout:
} }
errcode_t ext2fs_close(ext2_filsys fs) errcode_t ext2fs_close(ext2_filsys fs)
{
return ext2fs_close2(fs, 0);
}
errcode_t ext2fs_close2(ext2_filsys fs, int flags)
{ {
errcode_t retval; errcode_t retval;
int meta_blks; int meta_blks;
@ -451,10 +459,15 @@ errcode_t ext2fs_close(ext2_filsys fs)
fs->flags |= EXT2_FLAG_SUPER_ONLY | EXT2_FLAG_DIRTY; fs->flags |= EXT2_FLAG_SUPER_ONLY | EXT2_FLAG_DIRTY;
} }
if (fs->flags & EXT2_FLAG_DIRTY) { if (fs->flags & EXT2_FLAG_DIRTY) {
retval = ext2fs_flush(fs); retval = ext2fs_flush2(fs, flags);
if (retval) if (retval)
return retval; return retval;
} }
retval = ext2fs_mmp_stop(fs);
if (retval)
return retval;
ext2fs_free(fs); ext2fs_free(fs);
return 0; return 0;
} }

View File

@ -1,10 +1,603 @@
/* lib/config.h. Generated from config.h.in by configure. */
/* lib/config.h.in. Generated from configure.in by autoheader. */
#ifndef __CONFIG_H_
#define __CONFIG_H_
#define HAVE_UNISTD_H 1 /* Define if building universal (internal helper macro) */
#define HAVE_SYS_STAT_H 1 /* #undef AC_APPLE_UNIVERSAL_BUILD */
#define HAVE_SYS_TYPES_H 1
#define HAVE_UTIME_H 1 /* Define to 1 if debugging the blkid library */
#define WORDS_BIGENDIAN 1 /* #undef CONFIG_BLKID_DEBUG */
/* Define to 1 to compile findfs */
/* #undef CONFIG_BUILD_FINDFS 1 */
/* Define to 1 if debugging ext3/4 journal code */
/* #undef CONFIG_JBD_DEBUG */
/* Define to 1 if the testio I/O manager should be enabled */
/* #undef CONFIG_TESTIO_DEBUG 1 */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */
/* Define to 1 if ext2 compression enabled */
/* #undef ENABLE_COMPRESSION */
/* Define to 1 if ext3/4 htree support enabled */
#define ENABLE_HTREE 1
/* Define to 1 if translation of program messages to the user's native
language is requested. */
#define ENABLE_NLS 1
/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#define HAVE_ALLOCA_H 1
/* Define to 1 if you have the <argz.h> header file. */
#define HAVE_ARGZ_H 1
/* Define to 1 if you have the `asprintf' function. */
#define HAVE_ASPRINTF 1
/* Define to 1 if you have the `backtrace' function. */
/* #undef HAVE_BACKTRACE 1 */
/* Define to 1 if you have the `blkid_probe_get_topology' function. */
/* #undef HAVE_BLKID_PROBE_GET_TOPOLOGY */
/* Define to 1 if you have the `chflags' function. */
/* #undef HAVE_CHFLAGS */
/* Define if the GNU dcgettext() function is already present or preinstalled.
*/
/* #undef HAVE_DCGETTEXT 1 */
/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you
don't. */
/* #undef HAVE_DECL_FEOF_UNLOCKED 1 */
/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if
you don't. */
/* #undef HAVE_DECL_FGETS_UNLOCKED 0 */
/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you
don't. */
/* #undef HAVE_DECL_GETC_UNLOCKED 1 */
/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you
don't. */
/* #undef HAVE_DECL__SNPRINTF 0 */
/* Define to 1 if you have the declaration of `_snwprintf', and to 0 if you
don't. */
/* #undef HAVE_DECL__SNWPRINTF 0 */
/* Define to 1 if you have the <dirent.h> header file. */
#define HAVE_DIRENT_H 1
/* Define to 1 if dlopen/libdl exists */
/* #undef HAVE_DLOPEN 1 */
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
/* #undef HAVE_DOPRNT */
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1 #define HAVE_ERRNO_H 1
#define EXT2_FLAT_INCLUDES 1
/* Define to 1 if you have the <execinfo.h> header file. */
/* #undef HAVE_EXECINFO_H 1 */
/* Define to 1 if Ext2 ioctls present */
/* #undef HAVE_EXT2_IOCTLS 1 */
/* Define to 1 if you have the `fallocate' function. */
/* #undef HAVE_FALLOCATE 1 */
/* Define to 1 if you have the `fallocate64' function. */
/* #undef HAVE_FALLOCATE64 1 */
/* Define to 1 if you have the `fchown' function. */
/* #undef HAVE_FCHOWN 1 */
/* Define to 1 if you have the `fdatasync' function. */
/* #undef HAVE_FDATASYNC 1 */
/* Define to 1 if you have the `fstat64' function. */
/* #undef HAVE_FSTAT64 1 */
/* Define to 1 if you have the `ftruncate64' function. */
/* #undef HAVE_FTRUNCATE64 1 */
/* Define to 1 if you have the `fwprintf' function. */
/* #undef HAVE_FWPRINTF 1 */
/* Define to 1 if you have the `getcwd' function. */
/* #undef HAVE_GETCWD 1 */
/* Define to 1 if you have the `getdtablesize' function. */
/* #undef HAVE_GETDTABLESIZE 1 */
/* Define to 1 if you have the `getegid' function. */
/* #undef HAVE_GETEGID 1 */
/* Define to 1 if you have the `geteuid' function. */
/* #undef HAVE_GETEUID 1 */
/* Define to 1 if you have the `getgid' function. */
/* #undef HAVE_GETGID 1 */
/* Define to 1 if you have the `getmntinfo' function. */
/* #undef HAVE_GETMNTINFO */
/* Define to 1 if you have the <getopt.h> header file. */
/* #undef HAVE_GETOPT_H 1 */
/* Define to 1 if you have the `getpagesize' function. */
/* #undef HAVE_GETPAGESIZE 1 */
/* Define to 1 if you have the `getrlimit' function. */
/* #undef HAVE_GETRLIMIT 1 */
/* Define to 1 if you have the `getrusage' function. */
/* #undef HAVE_GETRUSAGE 1 */
/* Define if the GNU gettext() function is already present or preinstalled. */
/* #undef HAVE_GETTEXT 1 */
/* Define to 1 if you have the `getuid' function. */
/* #undef HAVE_GETUID 1 */
/* Define if you have the iconv() function. */
/* #undef HAVE_ICONV 1 */
/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
#define HAVE_INTMAX_T 1
/* Define to 1 if the system has the type `intptr_t'. */
#define HAVE_INTPTR_T 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
declares uintmax_t. */
#define HAVE_INTTYPES_H_WITH_UINTMAX 1
/* Define to 1 if you have the `jrand48' function. */
/* #undef HAVE_JRAND48 1 */
/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
/* #undef HAVE_LANGINFO_CODESET 1 */
/* Define if your <locale.h> file defines LC_MESSAGES. */
#define HAVE_LC_MESSAGES 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the <linux/falloc.h> header file. */
/* #undef HAVE_LINUX_FALLOC_H 1 */
/* Define to 1 if you have the <linux/fd.h> header file. */
/* #undef HAVE_LINUX_FD_H 1 */
/* Define to 1 if you have the <linux/major.h> header file. */
/* #undef HAVE_LINUX_MAJOR_H 1 */
/* Define to 1 if you have the `llseek' function. */
/* #undef HAVE_LLSEEK 1 */
/* Define to 1 if llseek declared in unistd.h */
/* #undef HAVE_LLSEEK_PROTOTYPE */
/* Define to 1 if you have the <locale.h> header file. */
#define HAVE_LOCALE_H 1
/* Define if you have the 'long double' type. */
#define HAVE_LONG_DOUBLE 1
/* Define if you have the 'long long' type. */
#define HAVE_LONG_LONG 1
/* Define to 1 if you have the `lseek64' function. */
/* #undef HAVE_LSEEK64 1 */
/* Define to 1 if lseek64 declared in unistd.h */
#define HAVE_LSEEK64_PROTOTYPE 1
/* Define to 1 if you have the `mallinfo' function. */
/* #undef HAVE_MALLINFO 1 */
/* Define to 1 if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define to 1 if you have the `mbstowcs' function. */
#define HAVE_MBSTOWCS 1
/* Define to 1 if you have the `memalign' function. */
#define HAVE_MEMALIGN 1
/* Define to 1 if you have the <memory.h> header file. */
/* #undef HAVE_MEMORY_H 1 */
/* Define to 1 if you have the `mempcpy' function. */
/* #undef HAVE_MEMPCPY 1 */
/* Define to 1 if you have the `mmap' function. */
/* #undef HAVE_MMAP 1 */
/* Define to 1 if you have the <mntent.h> header file. */
/* #undef HAVE_MNTENT_H 1 */
/* Define to 1 if you have the `munmap' function. */
/* #undef HAVE_MUNMAP 1 */
/* Define to 1 if you have the `nanosleep' function. */
#define HAVE_NANOSLEEP 1
/* Define to 1 if you have the <netinet/in.h> header file. */
/* #undef HAVE_NETINET_IN_H 1 */
/* Define to 1 if you have the <net/if_dl.h> header file. */
/* #undef HAVE_NET_IF_DL_H */
/* Define to 1 if you have the <net/if.h> header file. */
/* #undef HAVE_NET_IF_H 1 */
/* Define to 1 if you have the <nl_types.h> header file. */
/* #undef HAVE_NL_TYPES_H 1 */
/* Define to 1 if you have the `open64' function. */
/* #undef HAVE_OPEN64 1 */
/* Define to 1 if optreset for getopt is present */
/* #undef HAVE_OPTRESET */
/* Define to 1 if you have the `pathconf' function. */
/* #undef HAVE_PATHCONF 1 */
/* Define to 1 if you have the <paths.h> header file. */
/* #undef HAVE_PATHS_H 1 */
/* Define to 1 if you have the `posix_fadvise' function. */
/* #undef HAVE_POSIX_FADVISE 1 */
/* Define to 1 if you have the `posix_memalign' function. */
/* #undef HAVE_POSIX_MEMALIGN 1 */
/* Define if your printf() function supports format strings with positions. */
#define HAVE_POSIX_PRINTF 1
/* Define to 1 if you have the `prctl' function. */
/* #undef HAVE_PRCTL 1 */
/* Define to 1 if you have the `putenv' function. */
/* #undef HAVE_PUTENV 1 */
/* Define to 1 if you have the `quotactl' function. */
/* #undef HAVE_QUOTACTL 1 */
/* Define to 1 if dirent has d_reclen */
/* #undef HAVE_RECLEN_DIRENT 1 */
/* Define to 1 if if struct sockaddr contains sa_len */
/* #undef HAVE_SA_LEN */
/* Define to 1 if you have the <semaphore.h> header file. */
/* #undef HAVE_SEMAPHORE_H 1 */
/* Define to 1 if sem_init() exists */
/* #undef HAVE_SEM_INIT 1 */
/* Define to 1 if you have the `setenv' function. */
/* #undef HAVE_SETENV 1 */
/* Define to 1 if you have the <setjmp.h> header file. */
/* #undef HAVE_SETJMP_H 1 */
/* Define to 1 if you have the `setlocale' function. */
#define HAVE_SETLOCALE 1
/* Define to 1 if you have the `setresgid' function. */
/* #undef HAVE_SETRESGID 1 */
/* Define to 1 if you have the `setresuid' function. */
/* #undef HAVE_SETRESUID 1*/
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1
/* Define to 1 if you have the `srandom' function. */
/* #undef HAVE_SRANDOM 1 */
/* Define to 1 if struct stat has st_flags */
/* #undef HAVE_STAT_FLAGS */
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
uintmax_t. */
#define HAVE_STDINT_H_WITH_UINTMAX 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `stpcpy' function. */
#define HAVE_STPCPY 1
/* Define to 1 if you have the `strcasecmp' function. */
#define HAVE_STRCASECMP 1
/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1 #define HAVE_STRDUP 1
/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H 1 */
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strnlen' function. */
#define HAVE_STRNLEN 1
/* Define to 1 if you have the `strptime' function. */
#define HAVE_STRPTIME 1
/* Define to 1 if you have the `strtoul' function. */
#define HAVE_STRTOUL 1
/* Define to 1 if you have the `strtoull' function. */
#define HAVE_STRTOULL 1
/* Define to 1 if you have the `sync_file_range' function. */
/* #undef HAVE_SYNC_FILE_RANGE 1 */
/* Define to 1 if you have the `sysconf' function. */
/* #undef HAVE_SYSCONF 1 */
/* Define to 1 if you have the <sys/disklabel.h> header file. */
/* #undef HAVE_SYS_DISKLABEL_H */
/* Define to 1 if you have the <sys/disk.h> header file. */
/* #undef HAVE_SYS_DISK_H */
/* Define to 1 if you have the <sys/file.h> header file. */
#define HAVE_SYS_FILE_H 1
/* Define to 1 if you have the <sys/ioctl.h> header file. */
/* #undef HAVE_SYS_IOCTL_H 1 */
/* Define to 1 if you have the <sys/mkdev.h> header file. */
/* #undef HAVE_SYS_MKDEV_H */
/* Define to 1 if you have the <sys/mman.h> header file. */
/* #undef HAVE_SYS_MMAN_H 1 */
/* Define to 1 if you have the <sys/mount.h> header file. */
/* #undef HAVE_SYS_MOUNT_H 1 */
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/prctl.h> header file. */
/* #undef HAVE_SYS_PRCTL_H 1 */
/* Define to 1 if you have the <sys/queue.h> header file. */
#define HAVE_SYS_QUEUE_H 1
/* Define to 1 if you have the <sys/quota.h> header file. */
/* #undef HAVE_SYS_QUOTA_H 1 */
/* Define to 1 if you have the <sys/resource.h> header file. */
#define HAVE_SYS_RESOURCE_H 1 #define HAVE_SYS_RESOURCE_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
/* #undef HAVE_SYS_SELECT_H 1 */
/* Define to 1 if you have the <sys/socket.h> header file. */
/* #undef HAVE_SYS_SOCKET_H 1 */
/* Define to 1 if you have the <sys/sockio.h> header file. */
/* #undef HAVE_SYS_SOCKIO_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/syscall.h> header file. */
/* #undef HAVE_SYS_SYSCALL_H 1 */
/* Define to 1 if you have the <sys/sysmacros.h> header file. */
/* #undef HAVE_SYS_SYSMACROS_H 1 */
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/un.h> header file. */
/* #undef HAVE_SYS_UN_H 1 */
/* Define to 1 if you have the <sys/wait.h> header file. */
#define HAVE_SYS_WAIT_H 1
/* Define to 1 if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 1
/* Define to 1 if you have the <termio.h> header file. */
/* #undef HAVE_TERMIO_H 1 */
/* Define to 1 if you have the `tsearch' function. */
/* #undef HAVE_TSEARCH 1 */
/* Define to 1 if ssize_t declared */
#define HAVE_TYPE_SSIZE_T 1
/* Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>. */
#define HAVE_UINTMAX_T 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define if you have the 'unsigned long long' type. */
#define HAVE_UNSIGNED_LONG_LONG 1
/* Define to 1 if you have the `usleep' function. */
#define HAVE_USLEEP 1
/* Define to 1 if you have the `utime' function. */
/* #undef HAVE_UTIME 1 */
/* Define to 1 if you have the <utime.h> header file. */
#define HAVE_UTIME_H 1
/* Define to 1 if you have the `valloc' function. */
/* #undef HAVE_VALLOC 1 */
/* Define to 1 if you have the `vprintf' function. */
#define HAVE_VPRINTF 1
/* Define if you have the 'wchar_t' type. */
#define HAVE_WCHAR_T 1
/* Define to 1 if you have the `wcslen' function. */
#define HAVE_WCSLEN 1
/* Define if you have the 'wint_t' type. */
#define HAVE_WINT_T 1
/* Define to 1 if you have the `__argz_count' function. */
/* #undef HAVE___ARGZ_COUNT 1 */
/* Define to 1 if you have the `__argz_next' function. */
/* #undef HAVE___ARGZ_NEXT 1 */
/* Define to 1 if you have the `__argz_stringify' function. */
/* #undef HAVE___ARGZ_STRINGIFY 1 */
/* Define to 1 if you have the `__fsetlocking' function. */
/* #undef HAVE___FSETLOCKING 1 */
/* Define to 1 if you have the `__secure_getenv' function. */
/* #undef HAVE___SECURE_GETENV 1 */
/* Define as const if the declaration of iconv() needs const. */
/* #undef ICONV_CONST */
/* Define if integer division by zero raises signal SIGFPE. */
/* #undef INTDIV0_RAISES_SIGFPE 1 */
/* package name for gettext */
#define PACKAGE "e2fsprogs"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* Define if <inttypes.h> exists and defines unusable PRI* macros. */
/* #undef PRI_MACROS_BROKEN */
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
/* The size of `long', as computed by sizeof. */
#define SIZEOF_LONG 4
/* The size of `long long', as computed by sizeof. */
#define SIZEOF_LONG_LONG 8
/* The size of `short', as computed by sizeof. */
#define SIZEOF_SHORT 2
/* Define as the maximum value of type 'size_t', if the system doesn't define
it. */
/* #undef SIZE_MAX */
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* If the compiler supports a TLS storage class define it to that here */
/* #undef TLS __thread */
/* Define to 1 to build uuidd */
/* #undef USE_UUIDD 1 */
/* version for gettext */
#define VERSION "0.14.1"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#define WORDS_BIGENDIAN 1
/* Define to 1 if Apple Darwin libintl workaround is needed */
/* #undef _INTL_REDIRECT_MACROS */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */
/* Define as the type of the result of subtracting two pointers, if the system
doesn't define it. */
/* #undef ptrdiff_t */
/* Define to empty if the C compiler doesn't support this keyword. */
/* #undef signed */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to unsigned long or unsigned long long if <stdint.h> and
<inttypes.h> don't define. */
/* #undef uintmax_t */
#endif

View File

@ -5,6 +5,7 @@
* Version 2. See the file COPYING for more details. * Version 2. See the file COPYING for more details.
*/ */
#include "config.h"
#if HAVE_SYS_TYPES_H #if HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
/*
* This is the CRC32c polynomial, as outlined by Castagnoli.
* x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+
* x^8+x^6+x^0
*/
#define CRCPOLY_LE 0x82F63B78
#define CRCPOLY_BE 0x1EDC6F41
/* How many bits at a time to use. Valid values are 1, 2, 4, 8, 32 and 64. */
/* For less performance-sensitive, use 4 */
#ifndef CRC_LE_BITS
# define CRC_LE_BITS 64
#endif
#ifndef CRC_BE_BITS
# define CRC_BE_BITS 64
#endif
/*
* Little-endian CRC computation. Used with serial bit streams sent
* lsbit-first. Be sure to use cpu_to_le32() to append the computed CRC.
*/
#if CRC_LE_BITS > 64 || CRC_LE_BITS < 1 || CRC_LE_BITS == 16 || \
CRC_LE_BITS & CRC_LE_BITS-1
# error "CRC_LE_BITS must be one of {1, 2, 4, 8, 32, 64}"
#endif
/*
* Big-endian CRC computation. Used with serial bit streams sent
* msbit-first. Be sure to use cpu_to_be32() to append the computed CRC.
*/
#if CRC_BE_BITS > 64 || CRC_BE_BITS < 1 || CRC_BE_BITS == 16 || \
CRC_BE_BITS & CRC_BE_BITS-1
# error "CRC_BE_BITS must be one of {1, 2, 4, 8, 32, 64}"
#endif
#define ___constant_swab32(x) \
((uint32_t)( \
(((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
(((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
(((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
(((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
#if (__GNUC__ >= 3)
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else
#define likely(x) (x)
#define unlikely(x) (x)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#if HAVE_SYS_TYPES_H #if HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif #endif
@ -46,7 +47,7 @@ STATIC __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group)
desc = ext2fs_group_desc(fs, fs->group_desc, group); desc = ext2fs_group_desc(fs, fs->group_desc, group);
if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
int offset = offsetof(struct ext2_group_desc, bg_checksum); size_t offset = offsetof(struct ext2_group_desc, bg_checksum);
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
struct ext4_group_desc swabdesc; struct ext4_group_desc swabdesc;
@ -127,10 +128,10 @@ errcode_t ext2fs_set_gdt_csum(ext2_filsys fs)
return 0; return 0;
for (i = 0; i < fs->group_desc_count; i++) { for (i = 0; i < fs->group_desc_count; i++) {
unsigned int old_csum = ext2fs_bg_checksum(fs, i); __u32 old_csum = ext2fs_bg_checksum(fs, i);
int old_unused = ext2fs_bg_itable_unused(fs, i); __u32 old_unused = ext2fs_bg_itable_unused(fs, i);
unsigned int old_flags = ext2fs_bg_flags(fs, i); __u32 old_flags = ext2fs_bg_flags(fs, i);
int old_free_inodes_count = ext2fs_bg_free_inodes_count(fs, i); __u32 old_free_inodes_count = ext2fs_bg_free_inodes_count(fs, i);
if (old_free_inodes_count == sb->s_inodes_per_group) { if (old_free_inodes_count == sb->s_inodes_per_group) {
ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT); ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT);

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -60,7 +61,7 @@ static errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size,
struct ext2_db_entry2 *list, struct ext2_db_entry2 *list,
ext2_dblist *ret_dblist) ext2_dblist *ret_dblist)
{ {
ext2_dblist dblist; ext2_dblist dblist = 0;
errcode_t retval; errcode_t retval;
ext2_ino_t num_dirs; ext2_ino_t num_dirs;
size_t len; size_t len;
@ -73,7 +74,7 @@ static errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size,
retval = ext2fs_get_mem(sizeof(struct ext2_struct_dblist), &dblist); retval = ext2fs_get_mem(sizeof(struct ext2_struct_dblist), &dblist);
if (retval) if (retval)
return retval; goto cleanup;
memset(dblist, 0, sizeof(struct ext2_struct_dblist)); memset(dblist, 0, sizeof(struct ext2_struct_dblist));
dblist->magic = EXT2_ET_MAGIC_DBLIST; dblist->magic = EXT2_ET_MAGIC_DBLIST;
@ -172,7 +173,7 @@ errcode_t ext2fs_add_dir_block2(ext2_dblist dblist, ext2_ino_t ino,
sizeof(struct ext2_db_entry2), sizeof(struct ext2_db_entry2),
&dblist->list); &dblist->list);
if (retval) { if (retval) {
dblist->size -= 100; dblist->size = old_size / sizeof(struct ext2_db_entry2);
return retval; return retval;
} }
} }

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>

View File

@ -11,6 +11,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -217,11 +218,13 @@ errcode_t ext2fs_dirhash(int version, const char *name, int len,
switch (version) { switch (version) {
case EXT2_HASH_LEGACY_UNSIGNED: case EXT2_HASH_LEGACY_UNSIGNED:
unsigned_flag++; unsigned_flag++;
/* fallthrough */
case EXT2_HASH_LEGACY: case EXT2_HASH_LEGACY:
hash = dx_hack_hash(name, len, unsigned_flag); hash = dx_hack_hash(name, len, unsigned_flag);
break; break;
case EXT2_HASH_HALF_MD4_UNSIGNED: case EXT2_HASH_HALF_MD4_UNSIGNED:
unsigned_flag++; unsigned_flag++;
/* fallthrough */
case EXT2_HASH_HALF_MD4: case EXT2_HASH_HALF_MD4:
p = name; p = name;
while (len > 0) { while (len > 0) {
@ -235,6 +238,7 @@ errcode_t ext2fs_dirhash(int version, const char *name, int len,
break; break;
case EXT2_HASH_TEA_UNSIGNED: case EXT2_HASH_TEA_UNSIGNED:
unsigned_flag++; unsigned_flag++;
/* fallthrough */
case EXT2_HASH_TEA: case EXT2_HASH_TEA:
p = name; p = name;
while (len > 0) { while (len > 0) {

View File

@ -52,12 +52,12 @@ CACHE* cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPag
if(numberOfPages==0 || sectorsPerPage==0) return NULL; if(numberOfPages==0 || sectorsPerPage==0) return NULL;
if (numberOfPages < 4) { if (numberOfPages < 32) {
numberOfPages = 4; numberOfPages = 32;
} }
if (sectorsPerPage < 32) { if (sectorsPerPage < 16) {
sectorsPerPage = 32; sectorsPerPage = 16;
} }
cache = (CACHE*) mem_alloc (sizeof(CACHE)); cache = (CACHE*) mem_alloc (sizeof(CACHE));

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>

View File

@ -12,6 +12,14 @@
* %End-Header% * %End-Header%
*/ */
/* Image types */
#define E2IMAGE_RAW 1
#define E2IMAGE_QCOW2 2
/* Image flags */
#define E2IMAGE_INSTALL_FLAG 1
#define E2IMAGE_SCRAMBLE_FLAG 2
#define E2IMAGE_IS_QCOW2_FLAG 3
struct ext2_image_hdr { struct ext2_image_hdr {
__u32 magic_number; /* This must be EXT2_ET_MAGIC_E2IMAGE */ __u32 magic_number; /* This must be EXT2_ET_MAGIC_E2IMAGE */
@ -36,16 +44,3 @@ struct ext2_image_hdr {
__u32 offset_blockmap; /* Byte offset of the inode bitmaps */ __u32 offset_blockmap; /* Byte offset of the inode bitmaps */
__u32 offset_reserved[8]; __u32 offset_reserved[8];
}; };

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -21,6 +22,7 @@
struct expand_dir_struct { struct expand_dir_struct {
int done; int done;
int newblocks; int newblocks;
blk64_t goal;
errcode_t err; errcode_t err;
}; };
@ -33,19 +35,26 @@ static int expand_dir_proc(ext2_filsys fs,
{ {
struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data; struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
blk64_t new_blk; blk64_t new_blk;
static blk64_t last_blk = 0;
char *block; char *block;
errcode_t retval; errcode_t retval;
if (*blocknr) { if (*blocknr) {
last_blk = *blocknr; if (blockcnt >= 0)
es->goal = *blocknr;
return 0; return 0;
} }
retval = ext2fs_new_block2(fs, last_blk, 0, &new_blk); if (blockcnt &&
(EXT2FS_B2C(fs, es->goal) == EXT2FS_B2C(fs, es->goal+1)))
new_blk = es->goal+1;
else {
es->goal &= ~EXT2FS_CLUSTER_MASK(fs);
retval = ext2fs_new_block2(fs, es->goal, 0, &new_blk);
if (retval) { if (retval) {
es->err = retval; es->err = retval;
return BLOCK_ABORT; return BLOCK_ABORT;
} }
es->newblocks++;
}
if (blockcnt > 0) { if (blockcnt > 0) {
retval = ext2fs_new_dir_block(fs, 0, 0, &block); retval = ext2fs_new_dir_block(fs, 0, 0, &block);
if (retval) { if (retval) {
@ -63,6 +72,8 @@ static int expand_dir_proc(ext2_filsys fs,
memset(block, 0, fs->blocksize); memset(block, 0, fs->blocksize);
retval = io_channel_write_blk64(fs->io, new_blk, 1, block); retval = io_channel_write_blk64(fs->io, new_blk, 1, block);
} }
if (blockcnt >= 0)
es->goal = new_blk;
if (retval) { if (retval) {
es->err = retval; es->err = retval;
return BLOCK_ABORT; return BLOCK_ABORT;
@ -70,7 +81,6 @@ static int expand_dir_proc(ext2_filsys fs,
ext2fs_free_mem(&block); ext2fs_free_mem(&block);
*blocknr = new_blk; *blocknr = new_blk;
ext2fs_block_alloc_stats2(fs, new_blk, +1); ext2fs_block_alloc_stats2(fs, new_blk, +1);
es->newblocks++;
if (es->done) if (es->done)
return (BLOCK_CHANGED | BLOCK_ABORT); return (BLOCK_CHANGED | BLOCK_ABORT);
@ -98,6 +108,7 @@ errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir)
es.done = 0; es.done = 0;
es.err = 0; es.err = 0;
es.goal = 0;
es.newblocks = 0; es.newblocks = 0;
retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND, retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND,

View File

@ -89,7 +89,7 @@ bool ext2Mount(const char *name, const DISC_INTERFACE *interface, sec_t startSec
io_chan->private_data = fd; io_chan->private_data = fd;
io_chan->flags = flags; io_chan->flags = flags;
retval = ext2fs_open2(io_chan->name, 0, io_chan->flags, 0, 0, &io_chan, &fs); retval = ext2fs_open2(io_chan->name, 0, io_chan->flags, 0, 0, io_chan, &fs);
if(retval) if(retval)
{ {
ext2_log_trace("error mounting %i\n", (int) retval); ext2_log_trace("error mounting %i\n", (int) retval);
@ -223,7 +223,7 @@ int ext2FindPartitions (const DISC_INTERFACE *interface, sec_t **out_partitions)
int i; int i;
union { union {
u8 buffer[512]; u8 buffer[MAX_SECTOR_SIZE];
MASTER_BOOT_RECORD mbr; MASTER_BOOT_RECORD mbr;
EXTENDED_BOOT_RECORD ebr; EXTENDED_BOOT_RECORD ebr;
} sector; } sector;
@ -249,27 +249,30 @@ int ext2FindPartitions (const DISC_INTERFACE *interface, sec_t **out_partitions)
return 0; return 0;
} }
struct ext2_super_block * super = (struct ext2_super_block *) malloc(SUPERBLOCK_SIZE); //1024 bytes // Allocate 4 x max sector size in case of 4096 sector size
if(!super) u8 *buffer = (u8 *) mem_alloc(4 * MAX_SECTOR_SIZE);
if(!buffer)
{ {
ext2_log_trace("no memory for superblock"); ext2_log_trace("no memory for superblock");
errno = ENOMEM; errno = ENOMEM;
return -1; return -1;
} }
// Super is always at offset SUPERBLOCK_OFFSET
struct ext2_super_block * super = (struct ext2_super_block *) (buffer + SUPERBLOCK_OFFSET); //1024 bytes
partitions = (sec_t *) malloc(sizeof(sec_t)); partitions = (sec_t *) malloc(sizeof(sec_t));
if(!partitions) if(!partitions)
{ {
ext2_log_trace("no memory for partitions"); ext2_log_trace("no memory for partitions");
errno = ENOMEM; errno = ENOMEM;
mem_free(super); mem_free(buffer);
return -1; return -1;
} }
// Read the first sector on the device // Read the first sector on the device
if (!interface->readSectors(0, 1, &sector.buffer)) { if (!interface->readSectors(0, 1, &sector.buffer)) {
errno = EIO; errno = EIO;
mem_free(partitions); mem_free(partitions);
mem_free(super); mem_free(buffer);
return -1; return -1;
} }
@ -295,7 +298,7 @@ int ext2FindPartitions (const DISC_INTERFACE *interface, sec_t **out_partitions)
case PARTITION_TYPE_LINUX: case PARTITION_TYPE_LINUX:
// Read and validate the EXT partition // Read and validate the EXT partition
if (interface->readSectors(part_lba+SUPERBLOCK_OFFSET/BYTES_PER_SECTOR, SUPERBLOCK_SIZE/BYTES_PER_SECTOR, super)) if (interface->readSectors(part_lba, 4, buffer))
{ {
if (ext2fs_le16_to_cpu(super->s_magic) == EXT2_SUPER_MAGIC) if (ext2fs_le16_to_cpu(super->s_magic) == EXT2_SUPER_MAGIC)
{ {
@ -334,7 +337,7 @@ int ext2FindPartitions (const DISC_INTERFACE *interface, sec_t **out_partitions)
next_erb_lba = ext2fs_le32_to_cpu(sector.ebr.next_ebr.lba_start); next_erb_lba = ext2fs_le32_to_cpu(sector.ebr.next_ebr.lba_start);
// Check if this partition has a valid EXT boot record // Check if this partition has a valid EXT boot record
if (interface->readSectors(part_lba+SUPERBLOCK_OFFSET/BYTES_PER_SECTOR, SUPERBLOCK_SIZE/BYTES_PER_SECTOR, super)) if (interface->readSectors(part_lba, 4, buffer))
{ {
if (ext2fs_le16_to_cpu(super->s_magic) == EXT2_SUPER_MAGIC) if (ext2fs_le16_to_cpu(super->s_magic) == EXT2_SUPER_MAGIC)
{ {
@ -361,7 +364,7 @@ int ext2FindPartitions (const DISC_INTERFACE *interface, sec_t **out_partitions)
{ {
// Check if this partition has a valid EXT boot record anyway, // Check if this partition has a valid EXT boot record anyway,
// it might be misrepresented due to a lazy partition editor // it might be misrepresented due to a lazy partition editor
if (interface->readSectors(part_lba+SUPERBLOCK_OFFSET/BYTES_PER_SECTOR, SUPERBLOCK_SIZE/BYTES_PER_SECTOR, super)) if (interface->readSectors(part_lba, 4, buffer))
{ {
if (ext2fs_le16_to_cpu(super->s_magic) == EXT2_SUPER_MAGIC) if (ext2fs_le16_to_cpu(super->s_magic) == EXT2_SUPER_MAGIC)
{ {
@ -386,7 +389,7 @@ int ext2FindPartitions (const DISC_INTERFACE *interface, sec_t **out_partitions)
// As a last-ditched effort, search the first 64 sectors of the device for stray EXT partitions // As a last-ditched effort, search the first 64 sectors of the device for stray EXT partitions
for (i = 1; i < 64; i++) for (i = 1; i < 64; i++)
{ {
if (interface->readSectors(i+SUPERBLOCK_OFFSET/BYTES_PER_SECTOR, SUPERBLOCK_SIZE/BYTES_PER_SECTOR, super)) if (interface->readSectors(i, 4, buffer))
{ {
if (ext2fs_le16_to_cpu(super->s_magic) == EXT2_SUPER_MAGIC) if (ext2fs_le16_to_cpu(super->s_magic) == EXT2_SUPER_MAGIC)
{ {
@ -412,8 +415,8 @@ cleanup:
if(partitions && partition_count == 0) if(partitions && partition_count == 0)
mem_free(partitions); mem_free(partitions);
if(super) if(buffer)
mem_free(super); mem_free(buffer);
return ret; return ret;
} }

View File

@ -0,0 +1,199 @@
/*
* ext2_err.c:
* This file is automatically generated; please do not edit it.
*/
#include <stdlib.h>
#define N_(a) a
static const char * const text[] = {
N_( "EXT2FS Library version 1.42-WIP"),
N_( "Wrong magic number for ext2_filsys structure"),
N_( "Wrong magic number for badblocks_list structure"),
N_( "Wrong magic number for badblocks_iterate structure"),
N_( "Wrong magic number for inode_scan structure"),
N_( "Wrong magic number for io_channel structure"),
N_( "Wrong magic number for unix io_channel structure"),
N_( "Wrong magic number for io_manager structure"),
N_( "Wrong magic number for block_bitmap structure"),
N_( "Wrong magic number for inode_bitmap structure"),
N_( "Wrong magic number for generic_bitmap structure"),
N_( "Wrong magic number for test io_channel structure"),
N_( "Wrong magic number for directory block list structure"),
N_( "Wrong magic number for icount structure"),
N_( "Wrong magic number for Powerquest io_channel structure"),
N_( "Wrong magic number for ext2 file structure"),
N_( "Wrong magic number for Ext2 Image Header"),
N_( "Wrong magic number for inode io_channel structure"),
N_( "Wrong magic number for ext4 extent handle"),
N_( "Bad magic number in super-block"),
N_( "Filesystem revision too high"),
N_( "Attempt to write to filesystem opened read-only"),
N_( "Can't read group descriptors"),
N_( "Can't write group descriptors"),
N_( "Corrupt group descriptor: bad block for block bitmap"),
N_( "Corrupt group descriptor: bad block for inode bitmap"),
N_( "Corrupt group descriptor: bad block for inode table"),
N_( "Can't write an inode bitmap"),
N_( "Can't read an inode bitmap"),
N_( "Can't write an block bitmap"),
N_( "Can't read an block bitmap"),
N_( "Can't write an inode table"),
N_( "Can't read an inode table"),
N_( "Can't read next inode"),
N_( "Filesystem has unexpected block size"),
N_( "EXT2 directory corrupted"),
N_( "Attempt to read block from filesystem resulted in short read"),
N_( "Attempt to write block to filesystem resulted in short write"),
N_( "No free space in the directory"),
N_( "Inode bitmap not loaded"),
N_( "Block bitmap not loaded"),
N_( "Illegal inode number"),
N_( "Illegal block number"),
N_( "Internal error in ext2fs_expand_dir"),
N_( "Not enough space to build proposed filesystem"),
N_( "Illegal block number passed to ext2fs_mark_block_bitmap"),
N_( "Illegal block number passed to ext2fs_unmark_block_bitmap"),
N_( "Illegal block number passed to ext2fs_test_block_bitmap"),
N_( "Illegal inode number passed to ext2fs_mark_inode_bitmap"),
N_( "Illegal inode number passed to ext2fs_unmark_inode_bitmap"),
N_( "Illegal inode number passed to ext2fs_test_inode_bitmap"),
N_( "Attempt to fudge end of block bitmap past the real end"),
N_( "Attempt to fudge end of inode bitmap past the real end"),
N_( "Illegal indirect block found" ),
N_( "Illegal doubly indirect block found" ),
N_( "Illegal triply indirect block found" ),
N_( "Block bitmaps are not the same"),
N_( "Inode bitmaps are not the same"),
N_( "Illegal or malformed device name"),
N_( "A block group is missing an inode table"),
N_( "The ext2 superblock is corrupt"),
N_( "Illegal generic bit number passed to ext2fs_mark_generic_bitmap"),
N_( "Illegal generic bit number passed to ext2fs_unmark_generic_bitmap"),
N_( "Illegal generic bit number passed to ext2fs_test_generic_bitmap"),
N_( "Too many symbolic links encountered."),
N_( "The callback function will not handle this case"),
N_( "The inode is from a bad block in the inode table"),
N_( "Filesystem has unsupported feature(s)"),
N_( "Filesystem has unsupported read-only feature(s)"),
N_( "IO Channel failed to seek on read or write"),
N_( "Memory allocation failed"),
N_( "Invalid argument passed to ext2 library"),
N_( "Could not allocate block in ext2 filesystem"),
N_( "Could not allocate inode in ext2 filesystem"),
N_( "Ext2 inode is not a directory"),
N_( "Too many references in table"),
N_( "File not found by ext2_lookup"),
N_( "File open read-only"),
N_( "Ext2 directory block not found"),
N_( "Ext2 directory already exists"),
N_( "Unimplemented ext2 library function"),
N_( "User cancel requested"),
N_( "Ext2 file too big"),
N_( "Supplied journal device not a block device"),
N_( "Journal superblock not found"),
N_( "Journal must be at least 1024 blocks"),
N_( "Unsupported journal version"),
N_( "Error loading external journal"),
N_( "Journal not found"),
N_( "Directory hash unsupported"),
N_( "Illegal extended attribute block number"),
N_( "Cannot create filesystem with requested number of inodes"),
N_( "E2image snapshot not in use"),
N_( "Too many reserved group descriptor blocks"),
N_( "Resize inode is corrupt"),
N_( "Tried to set block bmap with missing indirect block"),
N_( "TDB: Success"),
N_( "TDB: Corrupt database"),
N_( "TDB: IO Error"),
N_( "TDB: Locking error"),
N_( "TDB: Out of memory"),
N_( "TDB: Record exists"),
N_( "TDB: Lock exists on other keys"),
N_( "TDB: Invalid parameter"),
N_( "TDB: Record does not exist"),
N_( "TDB: Write not permitted"),
N_( "Ext2fs directory block list is empty"),
N_( "Attempt to modify a block mapping via a read-only block iterator"),
N_( "Wrong magic number for ext4 extent saved path"),
N_( "Wrong magic number for 64-bit generic bitmap"),
N_( "Wrong magic number for 64-bit block bitmap"),
N_( "Wrong magic number for 64-bit inode bitmap"),
N_( "Wrong magic number --- RESERVED_13"),
N_( "Wrong magic number --- RESERVED_14"),
N_( "Wrong magic number --- RESERVED_15"),
N_( "Wrong magic number --- RESERVED_16"),
N_( "Wrong magic number --- RESERVED_17"),
N_( "Wrong magic number --- RESERVED_18"),
N_( "Wrong magic number --- RESERVED_19"),
N_( "Corrupt extent header"),
N_( "Corrupt extent index"),
N_( "Corrupt extent"),
N_( "No free space in extent map"),
N_( "Inode does not use extents"),
N_( "No 'next' extent"),
N_( "No 'previous' extent"),
N_( "No 'up' extent"),
N_( "No 'down' extent"),
N_( "No current node"),
N_( "Ext2fs operation not supported"),
N_( "No room to insert extent in node"),
N_( "Splitting would result in empty node"),
N_( "Extent not found"),
N_( "Operation not supported for inodes containing extents"),
N_( "Extent length is invalid"),
N_( "I/O Channel does not support 64-bit block numbers"),
N_( "Can't check if filesystem is mounted due to missing mtab file"),
N_( "Filesystem too large to use legacy bitmaps"),
N_( "MMP: invalid magic number"),
N_( "MMP: device currently active"),
N_( "MMP: fsck being run"),
N_( "MMP: block number beyond filesystem range"),
N_( "MMP: undergoing an unknown operation"),
N_( "MMP: filesystem still in use"),
N_( "MMP: open with O_DIRECT failed"),
0
};
struct error_table {
char const * const * msgs;
long base;
int n_msgs;
};
struct et_list {
struct et_list *next;
const struct error_table * table;
};
extern struct et_list *_et_list;
const struct error_table et_ext2_error_table = { text, 2133571328L, 145 };
static struct et_list link = { 0, 0 };
void initialize_ext2_error_table_r(struct et_list **list);
void initialize_ext2_error_table(void);
void initialize_ext2_error_table(void) {
initialize_ext2_error_table_r(&_et_list);
}
/* For Heimdal compatibility */
void initialize_ext2_error_table_r(struct et_list **list)
{
struct et_list *et, **end;
for (end = list, et = *list; et; end = &et->next, et = et->next)
if (et->table->msgs == text)
return;
et = malloc(sizeof(struct et_list));
if (et == 0) {
if (!link.table)
et = &link;
else
return;
}
et->table = &et_ext2_error_table;
et->next = 0;
*end = et;
}

View File

@ -1,152 +1,169 @@
// /*
// Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. * ext2_err.h:
// * This file is automatically generated; please do not edit it.
// This file may be redistributed under the terms of the GNU Public */
// License.
#ifndef EXT2_ERR_H_ #ifndef EXT2_ERR_H_
#define EXT2_ERR_H_ #define EXT2_ERR_H_
#define EXT2_ET_OK 0 #include "com_err.h"
#define EXT2_ET_BASE -1
#define EXT2_ET_MAGIC_EXT2FS_FILSYS -2 #define EXT2_ET_OK (0)
#define EXT2_ET_MAGIC_BADBLOCKS_LIST -3 #define EXT2_ET_BASE (2133571328L)
#define EXT2_ET_MAGIC_BADBLOCKS_ITERATE -4 #define EXT2_ET_MAGIC_EXT2FS_FILSYS (2133571329L)
#define EXT2_ET_MAGIC_INODE_SCAN -5 #define EXT2_ET_MAGIC_BADBLOCKS_LIST (2133571330L)
#define EXT2_ET_MAGIC_IO_CHANNEL -6 #define EXT2_ET_MAGIC_BADBLOCKS_ITERATE (2133571331L)
#define EXT2_ET_MAGIC_UNIX_IO_CHANNEL -7 #define EXT2_ET_MAGIC_INODE_SCAN (2133571332L)
#define EXT2_ET_MAGIC_IO_MANAGER -8 #define EXT2_ET_MAGIC_IO_CHANNEL (2133571333L)
#define EXT2_ET_MAGIC_BLOCK_BITMAP -9 #define EXT2_ET_MAGIC_UNIX_IO_CHANNEL (2133571334L)
#define EXT2_ET_MAGIC_INODE_BITMAP -10 #define EXT2_ET_MAGIC_IO_MANAGER (2133571335L)
#define EXT2_ET_MAGIC_GENERIC_BITMAP -11 #define EXT2_ET_MAGIC_BLOCK_BITMAP (2133571336L)
#define EXT2_ET_MAGIC_TEST_IO_CHANNEL -12 #define EXT2_ET_MAGIC_INODE_BITMAP (2133571337L)
#define EXT2_ET_MAGIC_DBLIST -13 #define EXT2_ET_MAGIC_GENERIC_BITMAP (2133571338L)
#define EXT2_ET_MAGIC_ICOUNT -14 #define EXT2_ET_MAGIC_TEST_IO_CHANNEL (2133571339L)
#define EXT2_ET_MAGIC_PQ_IO_CHANNEL -15 #define EXT2_ET_MAGIC_DBLIST (2133571340L)
#define EXT2_ET_MAGIC_EXT2_FILE -16 #define EXT2_ET_MAGIC_ICOUNT (2133571341L)
#define EXT2_ET_MAGIC_E2IMAGE -17 #define EXT2_ET_MAGIC_PQ_IO_CHANNEL (2133571342L)
#define EXT2_ET_MAGIC_INODE_IO_CHANNEL -18 #define EXT2_ET_MAGIC_EXT2_FILE (2133571343L)
#define EXT2_ET_MAGIC_EXTENT_HANDLE -19 #define EXT2_ET_MAGIC_E2IMAGE (2133571344L)
#define EXT2_ET_BAD_MAGIC -20 #define EXT2_ET_MAGIC_INODE_IO_CHANNEL (2133571345L)
#define EXT2_ET_REV_TOO_HIGH -21 #define EXT2_ET_MAGIC_EXTENT_HANDLE (2133571346L)
#define EXT2_ET_RO_FILSYS -22 #define EXT2_ET_BAD_MAGIC (2133571347L)
#define EXT2_ET_GDESC_READ -23 #define EXT2_ET_REV_TOO_HIGH (2133571348L)
#define EXT2_ET_GDESC_WRITE -24 #define EXT2_ET_RO_FILSYS (2133571349L)
#define EXT2_ET_GDESC_BAD_BLOCK_MAP -25 #define EXT2_ET_GDESC_READ (2133571350L)
#define EXT2_ET_GDESC_BAD_INODE_MAP -26 #define EXT2_ET_GDESC_WRITE (2133571351L)
#define EXT2_ET_GDESC_BAD_INODE_TABLE -27 #define EXT2_ET_GDESC_BAD_BLOCK_MAP (2133571352L)
#define EXT2_ET_INODE_BITMAP_WRITE -28 #define EXT2_ET_GDESC_BAD_INODE_MAP (2133571353L)
#define EXT2_ET_INODE_BITMAP_READ -29 #define EXT2_ET_GDESC_BAD_INODE_TABLE (2133571354L)
#define EXT2_ET_BLOCK_BITMAP_WRITE -30 #define EXT2_ET_INODE_BITMAP_WRITE (2133571355L)
#define EXT2_ET_BLOCK_BITMAP_READ -31 #define EXT2_ET_INODE_BITMAP_READ (2133571356L)
#define EXT2_ET_INODE_TABLE_WRITE -32 #define EXT2_ET_BLOCK_BITMAP_WRITE (2133571357L)
#define EXT2_ET_INODE_TABLE_READ -33 #define EXT2_ET_BLOCK_BITMAP_READ (2133571358L)
#define EXT2_ET_NEXT_INODE_READ -34 #define EXT2_ET_INODE_TABLE_WRITE (2133571359L)
#define EXT2_ET_UNEXPECTED_BLOCK_SIZE -35 #define EXT2_ET_INODE_TABLE_READ (2133571360L)
#define EXT2_ET_DIR_CORRUPTED -36 #define EXT2_ET_NEXT_INODE_READ (2133571361L)
#define EXT2_ET_SHORT_READ -37 #define EXT2_ET_UNEXPECTED_BLOCK_SIZE (2133571362L)
#define EXT2_ET_SHORT_WRITE -38 #define EXT2_ET_DIR_CORRUPTED (2133571363L)
#define EXT2_ET_DIR_NO_SPACE -39 #define EXT2_ET_SHORT_READ (2133571364L)
#define EXT2_ET_NO_INODE_BITMAP -40 #define EXT2_ET_SHORT_WRITE (2133571365L)
#define EXT2_ET_NO_BLOCK_BITMAP -41 #define EXT2_ET_DIR_NO_SPACE (2133571366L)
#define EXT2_ET_BAD_INODE_NUM -42 #define EXT2_ET_NO_INODE_BITMAP (2133571367L)
#define EXT2_ET_BAD_BLOCK_NUM -45 #define EXT2_ET_NO_BLOCK_BITMAP (2133571368L)
#define EXT2_ET_EXPAND_DIR_ERR -46 #define EXT2_ET_BAD_INODE_NUM (2133571369L)
#define EXT2_ET_TOOSMALL -47 #define EXT2_ET_BAD_BLOCK_NUM (2133571370L)
#define EXT2_ET_BAD_BLOCK_MARK -48 #define EXT2_ET_EXPAND_DIR_ERR (2133571371L)
#define EXT2_ET_BAD_BLOCK_UNMARK -49 #define EXT2_ET_TOOSMALL (2133571372L)
#define EXT2_ET_BAD_BLOCK_TEST -50 #define EXT2_ET_BAD_BLOCK_MARK (2133571373L)
#define EXT2_ET_BAD_INODE_MARK -51 #define EXT2_ET_BAD_BLOCK_UNMARK (2133571374L)
#define EXT2_ET_BAD_INODE_UNMARK -52 #define EXT2_ET_BAD_BLOCK_TEST (2133571375L)
#define EXT2_ET_BAD_INODE_TEST -53 #define EXT2_ET_BAD_INODE_MARK (2133571376L)
#define EXT2_ET_FUDGE_BLOCK_BITMAP_END -54 #define EXT2_ET_BAD_INODE_UNMARK (2133571377L)
#define EXT2_ET_FUDGE_INODE_BITMAP_END -55 #define EXT2_ET_BAD_INODE_TEST (2133571378L)
#define EXT2_ET_BAD_IND_BLOCK -56 #define EXT2_ET_FUDGE_BLOCK_BITMAP_END (2133571379L)
#define EXT2_ET_BAD_DIND_BLOCK -57 #define EXT2_ET_FUDGE_INODE_BITMAP_END (2133571380L)
#define EXT2_ET_BAD_TIND_BLOCK -58 #define EXT2_ET_BAD_IND_BLOCK (2133571381L)
#define EXT2_ET_NEQ_BLOCK_BITMAP -59 #define EXT2_ET_BAD_DIND_BLOCK (2133571382L)
#define EXT2_ET_NEQ_INODE_BITMAP -60 #define EXT2_ET_BAD_TIND_BLOCK (2133571383L)
#define EXT2_ET_BAD_DEVICE_NAME -61 #define EXT2_ET_NEQ_BLOCK_BITMAP (2133571384L)
#define EXT2_ET_MISSING_INODE_TABLE -62 #define EXT2_ET_NEQ_INODE_BITMAP (2133571385L)
#define EXT2_ET_CORRUPT_SUPERBLOCK -63 #define EXT2_ET_BAD_DEVICE_NAME (2133571386L)
#define EXT2_ET_BAD_GENERIC_MARK -64 #define EXT2_ET_MISSING_INODE_TABLE (2133571387L)
#define EXT2_ET_BAD_GENERIC_UNMARK -65 #define EXT2_ET_CORRUPT_SUPERBLOCK (2133571388L)
#define EXT2_ET_BAD_GENERIC_TEST -66 #define EXT2_ET_BAD_GENERIC_MARK (2133571389L)
#define EXT2_ET_SYMLINK_LOOP -67 #define EXT2_ET_BAD_GENERIC_UNMARK (2133571390L)
#define EXT2_ET_CALLBACK_NOTHANDLED -68 #define EXT2_ET_BAD_GENERIC_TEST (2133571391L)
#define EXT2_ET_BAD_BLOCK_IN_INODE_TABLE -69 #define EXT2_ET_SYMLINK_LOOP (2133571392L)
#define EXT2_ET_UNSUPP_FEATURE -70 #define EXT2_ET_CALLBACK_NOTHANDLED (2133571393L)
#define EXT2_ET_RO_UNSUPP_FEATURE -71 #define EXT2_ET_BAD_BLOCK_IN_INODE_TABLE (2133571394L)
#define EXT2_ET_LLSEEK_FAILED -72 #define EXT2_ET_UNSUPP_FEATURE (2133571395L)
#define EXT2_ET_NO_MEMORY -73 #define EXT2_ET_RO_UNSUPP_FEATURE (2133571396L)
#define EXT2_ET_INVALID_ARGUMENT -74 #define EXT2_ET_LLSEEK_FAILED (2133571397L)
#define EXT2_ET_BLOCK_ALLOC_FAIL -75 #define EXT2_ET_NO_MEMORY (2133571398L)
#define EXT2_ET_INODE_ALLOC_FAIL -76 #define EXT2_ET_INVALID_ARGUMENT (2133571399L)
#define EXT2_ET_NO_DIRECTORY -77 #define EXT2_ET_BLOCK_ALLOC_FAIL (2133571400L)
#define EXT2_ET_TOO_MANY_REFS -78 #define EXT2_ET_INODE_ALLOC_FAIL (2133571401L)
#define EXT2_ET_FILE_NOT_FOUND -79 #define EXT2_ET_NO_DIRECTORY (2133571402L)
#define EXT2_ET_FILE_RO -80 #define EXT2_ET_TOO_MANY_REFS (2133571403L)
#define EXT2_ET_DB_NOT_FOUND -81 #define EXT2_ET_FILE_NOT_FOUND (2133571404L)
#define EXT2_ET_DIR_EXISTS -82 #define EXT2_ET_FILE_RO (2133571405L)
#define EXT2_ET_UNIMPLEMENTED -83 #define EXT2_ET_DB_NOT_FOUND (2133571406L)
#define EXT2_ET_CANCEL_REQUESTED -84 #define EXT2_ET_DIR_EXISTS (2133571407L)
#define EXT2_ET_FILE_TOO_BIG -85 #define EXT2_ET_UNIMPLEMENTED (2133571408L)
#define EXT2_ET_JOURNAL_NOT_BLOCK -86 #define EXT2_ET_CANCEL_REQUESTED (2133571409L)
#define EXT2_ET_NO_JOURNAL_SB -87 #define EXT2_ET_FILE_TOO_BIG (2133571410L)
#define EXT2_ET_JOURNAL_TOO_SMALL -88 #define EXT2_ET_JOURNAL_NOT_BLOCK (2133571411L)
#define EXT2_ET_JOURNAL_UNSUPP_VERSION -89 #define EXT2_ET_NO_JOURNAL_SB (2133571412L)
#define EXT2_ET_LOAD_EXT_JOURNAL -90 #define EXT2_ET_JOURNAL_TOO_SMALL (2133571413L)
#define EXT2_ET_NO_JOURNAL -91 #define EXT2_ET_JOURNAL_UNSUPP_VERSION (2133571414L)
#define EXT2_ET_DIRHASH_UNSUPP -92 #define EXT2_ET_LOAD_EXT_JOURNAL (2133571415L)
#define EXT2_ET_BAD_EA_BLOCK_NUM -93 #define EXT2_ET_NO_JOURNAL (2133571416L)
#define EXT2_ET_TOO_MANY_INODES -94 #define EXT2_ET_DIRHASH_UNSUPP (2133571417L)
#define EXT2_ET_NOT_IMAGE_FILE -95 #define EXT2_ET_BAD_EA_BLOCK_NUM (2133571418L)
#define EXT2_ET_RES_GDT_BLOCKS -96 #define EXT2_ET_TOO_MANY_INODES (2133571419L)
#define EXT2_ET_RESIZE_INODE_CORRUPT -97 #define EXT2_ET_NOT_IMAGE_FILE (2133571420L)
#define EXT2_ET_SET_BMAP_NO_IND -98 #define EXT2_ET_RES_GDT_BLOCKS (2133571421L)
#define EXT2_ET_TDB_SUCCESS -99 #define EXT2_ET_RESIZE_INODE_CORRUPT (2133571422L)
#define EXT2_ET_TDB_ERR_CORRUPT -100 #define EXT2_ET_SET_BMAP_NO_IND (2133571423L)
#define EXT2_ET_TDB_ERR_IO -101 #define EXT2_ET_TDB_SUCCESS (2133571424L)
#define EXT2_ET_TDB_ERR_LOCK -102 #define EXT2_ET_TDB_ERR_CORRUPT (2133571425L)
#define EXT2_ET_TDB_ERR_OOM -103 #define EXT2_ET_TDB_ERR_IO (2133571426L)
#define EXT2_ET_TDB_ERR_EXISTS -104 #define EXT2_ET_TDB_ERR_LOCK (2133571427L)
#define EXT2_ET_TDB_ERR_NOLOCK -105 #define EXT2_ET_TDB_ERR_OOM (2133571428L)
#define EXT2_ET_TDB_ERR_EINVAL -106 #define EXT2_ET_TDB_ERR_EXISTS (2133571429L)
#define EXT2_ET_TDB_ERR_NOEXIST -107 #define EXT2_ET_TDB_ERR_NOLOCK (2133571430L)
#define EXT2_ET_TDB_ERR_RDONLY -108 #define EXT2_ET_TDB_ERR_EINVAL (2133571431L)
#define EXT2_ET_DBLIST_EMPTY -109 #define EXT2_ET_TDB_ERR_NOEXIST (2133571432L)
#define EXT2_ET_RO_BLOCK_ITERATE -110 #define EXT2_ET_TDB_ERR_RDONLY (2133571433L)
#define EXT2_ET_MAGIC_EXTENT_PATH -111 #define EXT2_ET_DBLIST_EMPTY (2133571434L)
#define EXT2_ET_MAGIC_RESERVED_10 -112 #define EXT2_ET_RO_BLOCK_ITERATE (2133571435L)
#define EXT2_ET_MAGIC_RESERVED_11 -113 #define EXT2_ET_MAGIC_EXTENT_PATH (2133571436L)
#define EXT2_ET_MAGIC_RESERVED_12 -114 #define EXT2_ET_MAGIC_GENERIC_BITMAP64 (2133571437L)
#define EXT2_ET_MAGIC_RESERVED_13 -115 #define EXT2_ET_MAGIC_BLOCK_BITMAP64 (2133571438L)
#define EXT2_ET_MAGIC_RESERVED_14 -116 #define EXT2_ET_MAGIC_INODE_BITMAP64 (2133571439L)
#define EXT2_ET_MAGIC_RESERVED_15 -117 #define EXT2_ET_MAGIC_RESERVED_13 (2133571440L)
#define EXT2_ET_MAGIC_RESERVED_16 -118 #define EXT2_ET_MAGIC_RESERVED_14 (2133571441L)
#define EXT2_ET_MAGIC_RESERVED_17 -119 #define EXT2_ET_MAGIC_RESERVED_15 (2133571442L)
#define EXT2_ET_MAGIC_RESERVED_18 -120 #define EXT2_ET_MAGIC_RESERVED_16 (2133571443L)
#define EXT2_ET_MAGIC_RESERVED_19 -121 #define EXT2_ET_MAGIC_RESERVED_17 (2133571444L)
#define EXT2_ET_EXTENT_HEADER_BAD -122 #define EXT2_ET_MAGIC_RESERVED_18 (2133571445L)
#define EXT2_ET_EXTENT_INDEX_BAD -123 #define EXT2_ET_MAGIC_RESERVED_19 (2133571446L)
#define EXT2_ET_EXTENT_LEAF_BAD -124 #define EXT2_ET_EXTENT_HEADER_BAD (2133571447L)
#define EXT2_ET_EXTENT_NO_SPACE -125 #define EXT2_ET_EXTENT_INDEX_BAD (2133571448L)
#define EXT2_ET_INODE_NOT_EXTENT -126 #define EXT2_ET_EXTENT_LEAF_BAD (2133571449L)
#define EXT2_ET_EXTENT_NO_NEXT -127 #define EXT2_ET_EXTENT_NO_SPACE (2133571450L)
#define EXT2_ET_EXTENT_NO_PREV -128 #define EXT2_ET_INODE_NOT_EXTENT (2133571451L)
#define EXT2_ET_EXTENT_NO_UP -129 #define EXT2_ET_EXTENT_NO_NEXT (2133571452L)
#define EXT2_ET_EXTENT_NO_DOWN -130 #define EXT2_ET_EXTENT_NO_PREV (2133571453L)
#define EXT2_ET_NO_CURRENT_NODE -131 #define EXT2_ET_EXTENT_NO_UP (2133571454L)
#define EXT2_ET_OP_NOT_SUPPORTED -132 #define EXT2_ET_EXTENT_NO_DOWN (2133571455L)
#define EXT2_ET_CANT_INSERT_EXTENT -133 #define EXT2_ET_NO_CURRENT_NODE (2133571456L)
#define EXT2_ET_CANT_SPLIT_EXTENT -134 #define EXT2_ET_OP_NOT_SUPPORTED (2133571457L)
#define EXT2_ET_EXTENT_NOT_FOUND -135 #define EXT2_ET_CANT_INSERT_EXTENT (2133571458L)
#define EXT2_ET_EXTENT_NOT_SUPPORTED -136 #define EXT2_ET_CANT_SPLIT_EXTENT (2133571459L)
#define EXT2_ET_EXTENT_INVALID_LENGTH -137 #define EXT2_ET_EXTENT_NOT_FOUND (2133571460L)
#define EXT2_ET_IO_CHANNEL_NO_SUPPORT_64 -138 #define EXT2_ET_EXTENT_NOT_SUPPORTED (2133571461L)
#define EXT2_NO_MTAB_FILE -139 #define EXT2_ET_EXTENT_INVALID_LENGTH (2133571462L)
#define EXT2_ET_MAGIC_GENERIC_BITMAP64 -140 #define EXT2_ET_IO_CHANNEL_NO_SUPPORT_64 (2133571463L)
#define EXT2_ET_MAGIC_BLOCK_BITMAP64 -141 #define EXT2_NO_MTAB_FILE (2133571464L)
#define EXT2_ET_MAGIC_INODE_BITMAP64 -142 #define EXT2_ET_CANT_USE_LEGACY_BITMAPS (2133571465L)
#define EXT2_ET_CANT_USE_LEGACY_BITMAPS -143 #define EXT2_ET_MMP_MAGIC_INVALID (2133571466L)
#define EXT2_ET_MMP_FAILED (2133571467L)
#define EXT2_ET_MMP_FSCK_ON (2133571468L)
#define EXT2_ET_MMP_BAD_BLOCK (2133571469L)
#define EXT2_ET_MMP_UNKNOWN_SEQ (2133571470L)
#define EXT2_ET_MMP_CHANGE_ABORT (2133571471L)
#define EXT2_ET_MMP_OPEN_DIRECT (2133571472L)
extern const struct error_table et_ext2_error_table;
extern void initialize_ext2_error_table(void);
/* For compatibility with Heimdal */
extern void initialize_ext2_error_table_r(struct et_list **list);
#define ERROR_TABLE_BASE_ext2 (2133571328L)
/* for compatibility with older versions... */
#define init_ext2_err_tbl initialize_ext2_error_table
#define ext2_err_base ERROR_TABLE_BASE_ext2
#endif #endif

View File

@ -108,6 +108,18 @@
(s)->s_log_cluster_size) (s)->s_log_cluster_size)
#define EXT2_CLUSTER_SIZE_BITS(s) ((s)->s_log_cluster_size + 10) #define EXT2_CLUSTER_SIZE_BITS(s) ((s)->s_log_cluster_size + 10)
/*
* Macro-instructions used to manage fragments
*
* Note: for backwards compatibility only, for the dump program.
* Ext2/3/4 will never support fragments....
*/
#define EXT2_MIN_FRAG_SIZE EXT2_MIN_BLOCK_SIZE
#define EXT2_MAX_FRAG_SIZE EXT2_MAX_BLOCK_SIZE
#define EXT2_MIN_FRAG_LOG_SIZE EXT2_MIN_BLOCK_LOG_SIZE
#define EXT2_FRAG_SIZE(s) EXT2_BLOCK_SIZE(s)
#define EXT2_FRAGS_PER_BLOCK(s) 1
/* /*
* ACL structures * ACL structures
*/ */
@ -142,7 +154,9 @@ struct ext2_group_desc
__u16 bg_free_inodes_count; /* Free inodes count */ __u16 bg_free_inodes_count; /* Free inodes count */
__u16 bg_used_dirs_count; /* Directories count */ __u16 bg_used_dirs_count; /* Directories count */
__u16 bg_flags; __u16 bg_flags;
__u32 bg_reserved[2]; __u32 bg_exclude_bitmap_lo; /* Exclude bitmap for snapshots */
__u16 bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */
__u16 bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */
__u16 bg_itable_unused; /* Unused inodes count */ __u16 bg_itable_unused; /* Unused inodes count */
__u16 bg_checksum; /* crc16(s_uuid+grouo_num+group_desc)*/ __u16 bg_checksum; /* crc16(s_uuid+grouo_num+group_desc)*/
}; };
@ -159,7 +173,9 @@ struct ext4_group_desc
__u16 bg_free_inodes_count; /* Free inodes count */ __u16 bg_free_inodes_count; /* Free inodes count */
__u16 bg_used_dirs_count; /* Directories count */ __u16 bg_used_dirs_count; /* Directories count */
__u16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */ __u16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
__u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */ __u32 bg_exclude_bitmap_lo; /* Exclude bitmap for snapshots */
__u16 bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */
__u16 bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */
__u16 bg_itable_unused; /* Unused inodes count */ __u16 bg_itable_unused; /* Unused inodes count */
__u16 bg_checksum; /* crc16(sb_uuid+group+desc) */ __u16 bg_checksum; /* crc16(sb_uuid+group+desc) */
__u32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ __u32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
@ -169,7 +185,10 @@ struct ext4_group_desc
__u16 bg_free_inodes_count_hi;/* Free inodes count MSB */ __u16 bg_free_inodes_count_hi;/* Free inodes count MSB */
__u16 bg_used_dirs_count_hi; /* Directories count MSB */ __u16 bg_used_dirs_count_hi; /* Directories count MSB */
__u16 bg_itable_unused_hi; /* Unused inodes count MSB */ __u16 bg_itable_unused_hi; /* Unused inodes count MSB */
__u32 bg_reserved2[3]; __u32 bg_exclude_bitmap_hi; /* Exclude bitmap block MSB */
__u16 bg_block_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bitmap) MSB */
__u16 bg_inode_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bitmap) MSB */
__u32 bg_reserved;
}; };
#define EXT2_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not initialized */ #define EXT2_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not initialized */
@ -228,10 +247,15 @@ struct ext2_dx_countlimit {
#define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group) #define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group)
#define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group) #define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group)
#define EXT2_CLUSTERS_PER_GROUP(s) (EXT2_SB(s)->s_clusters_per_group)
#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s)) #define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
/* limits imposed by 16-bit value gd_free_{blocks,inode}_count */ /* limits imposed by 16-bit value gd_free_{blocks,inode}_count */
#define EXT2_MAX_BLOCKS_PER_GROUP(s) ((1 << 16) - 8) #define EXT2_MAX_BLOCKS_PER_GROUP(s) ((((unsigned) 1 << 16) - 8) * \
#define EXT2_MAX_INODES_PER_GROUP(s) ((1 << 16) - EXT2_INODES_PER_BLOCK(s)) (EXT2_CLUSTER_SIZE(s) / \
EXT2_BLOCK_SIZE(s)))
#define EXT2_MAX_CLUSTERS_PER_GROUP(s) (((unsigned) 1 << 16) - 8)
#define EXT2_MAX_INODES_PER_GROUP(s) (((unsigned) 1 << 16) - \
EXT2_INODES_PER_BLOCK(s))
#ifdef __KERNEL__ #ifdef __KERNEL__
#define EXT2_DESC_PER_BLOCK(s) (EXT2_SB(s)->s_desc_per_block) #define EXT2_DESC_PER_BLOCK(s) (EXT2_SB(s)->s_desc_per_block)
#define EXT2_DESC_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_desc_per_block_bits) #define EXT2_DESC_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_desc_per_block_bits)
@ -322,6 +346,7 @@ struct ext4_new_group_input {
#define EXT2_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) #define EXT2_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
#define EXT2_IOC_GROUP_ADD _IOW('f', 8,struct ext2_new_group_input) #define EXT2_IOC_GROUP_ADD _IOW('f', 8,struct ext2_new_group_input)
#define EXT4_IOC_GROUP_ADD _IOW('f', 8,struct ext4_new_group_input) #define EXT4_IOC_GROUP_ADD _IOW('f', 8,struct ext4_new_group_input)
#define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64)
/* /*
* Structure of an inode on the disk * Structure of an inode on the disk
@ -357,7 +382,8 @@ struct ext2_inode {
__u16 l_i_file_acl_high; __u16 l_i_file_acl_high;
__u16 l_i_uid_high; /* these 2 fields */ __u16 l_i_uid_high; /* these 2 fields */
__u16 l_i_gid_high; /* were reserved2[0] */ __u16 l_i_gid_high; /* were reserved2[0] */
__u32 l_i_reserved2; __u16 l_i_checksum_lo; /* crc32c(uuid+inum+inode) */
__u16 l_i_reserved;
} linux2; } linux2;
struct { struct {
__u8 h_i_frag; /* Fragment number */ __u8 h_i_frag; /* Fragment number */
@ -404,7 +430,8 @@ struct ext2_inode_large {
__u16 l_i_file_acl_high; __u16 l_i_file_acl_high;
__u16 l_i_uid_high; /* these 2 fields */ __u16 l_i_uid_high; /* these 2 fields */
__u16 l_i_gid_high; /* were reserved2[0] */ __u16 l_i_gid_high; /* were reserved2[0] */
__u32 l_i_reserved2; __u16 l_i_checksum_lo; /* crc32c(uuid+inum+inode) */
__u16 l_i_reserved;
} linux2; } linux2;
struct { struct {
__u8 h_i_frag; /* Fragment number */ __u8 h_i_frag; /* Fragment number */
@ -416,7 +443,7 @@ struct ext2_inode_large {
} hurd2; } hurd2;
} osd2; /* OS dependent 2 */ } osd2; /* OS dependent 2 */
__u16 i_extra_isize; __u16 i_extra_isize;
__u16 i_pad1; __u16 i_checksum_hi; /* crc32c(uuid+inum+inode) */
__u32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */ __u32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */
__u32 i_mtime_extra; /* extra Modification time (nsec << 2 | epoch) */ __u32 i_mtime_extra; /* extra Modification time (nsec << 2 | epoch) */
__u32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */ __u32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */
@ -435,7 +462,6 @@ struct ext2_inode_large {
#define i_gid_low i_gid #define i_gid_low i_gid
#define i_uid_high osd2.linux2.l_i_uid_high #define i_uid_high osd2.linux2.l_i_uid_high
#define i_gid_high osd2.linux2.l_i_gid_high #define i_gid_high osd2.linux2.l_i_gid_high
#define i_reserved2 osd2.linux2.l_i_reserved2
#else #else
#if defined(__GNU__) #if defined(__GNU__)
@ -588,7 +614,7 @@ struct ext2_super_block {
__u16 s_want_extra_isize; /* New inodes should reserve # bytes */ __u16 s_want_extra_isize; /* New inodes should reserve # bytes */
__u32 s_flags; /* Miscellaneous flags */ __u32 s_flags; /* Miscellaneous flags */
__u16 s_raid_stride; /* RAID stride */ __u16 s_raid_stride; /* RAID stride */
__u16 s_mmp_interval; /* # seconds to wait in MMP checking */ __u16 s_mmp_update_interval; /* # seconds to wait in MMP checking */
__u64 s_mmp_block; /* Block for multi-mount protection */ __u64 s_mmp_block; /* Block for multi-mount protection */
__u32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ __u32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
__u8 s_log_groups_per_flex; /* FLEX_BG group size */ __u8 s_log_groups_per_flex; /* FLEX_BG group size */
@ -617,7 +643,8 @@ struct ext2_super_block {
__u32 s_usr_quota_inum; /* inode number of user quota file */ __u32 s_usr_quota_inum; /* inode number of user quota file */
__u32 s_grp_quota_inum; /* inode number of group quota file */ __u32 s_grp_quota_inum; /* inode number of group quota file */
__u32 s_overhead_blocks; /* overhead blocks/clusters in fs */ __u32 s_overhead_blocks; /* overhead blocks/clusters in fs */
__u32 s_reserved[109]; /* Padding to the end of the block */ __u32 s_reserved[108]; /* Padding to the end of the block */
__u32 s_checksum; /* crc32c(superblock) */
}; };
#define EXT4_S_ERR_LEN (EXT4_S_ERR_END - EXT4_S_ERR_START) #define EXT4_S_ERR_LEN (EXT4_S_ERR_END - EXT4_S_ERR_START)
@ -665,7 +692,9 @@ struct ext2_super_block {
#define EXT2_FEATURE_COMPAT_RESIZE_INODE 0x0010 #define EXT2_FEATURE_COMPAT_RESIZE_INODE 0x0010
#define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 #define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020
#define EXT2_FEATURE_COMPAT_LAZY_BG 0x0040 #define EXT2_FEATURE_COMPAT_LAZY_BG 0x0040
#define EXT2_FEATURE_COMPAT_EXCLUDE_INODE 0x0080 /* #define EXT2_FEATURE_COMPAT_EXCLUDE_INODE 0x0080 not used, legacy */
#define EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP 0x0100
#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 #define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
@ -677,6 +706,7 @@ struct ext2_super_block {
#define EXT4_FEATURE_RO_COMPAT_HAS_SNAPSHOT 0x0080 #define EXT4_FEATURE_RO_COMPAT_HAS_SNAPSHOT 0x0080
#define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100 #define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100
#define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200 #define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200
#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400
#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001 #define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001
#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 #define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
@ -691,7 +721,8 @@ struct ext2_super_block {
#define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000 #define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000
#define EXT2_FEATURE_COMPAT_SUPP 0 #define EXT2_FEATURE_COMPAT_SUPP 0
#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE) #define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \
EXT4_FEATURE_INCOMPAT_MMP)
#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ #define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \ EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
@ -772,28 +803,52 @@ struct ext2_dir_entry_2 {
~EXT2_DIR_ROUND) ~EXT2_DIR_ROUND)
/* /*
* This structure will be used for multiple mount protection. It will be * This structure is used for multiple mount protection. It is written
* written into the block number saved in the s_mmp_block field in the * into the block number saved in the s_mmp_block field in the superblock.
* superblock. * Programs that check MMP should assume that if SEQ_FSCK (or any unknown
* code above SEQ_MAX) is present then it is NOT safe to use the filesystem,
* regardless of how old the timestamp is.
*
* The timestamp in the MMP structure will be updated by e2fsck at some
* arbitary intervals (start of passes, after every few groups of inodes
* in pass1 and pass1b). There is no guarantee that e2fsck is updating
* the MMP block in a timely manner, and the updates it does are purely
* for the convenience of the sysadmin and not for automatic validation.
*
* Note: Only the mmp_seq value is used to determine whether the MMP block
* is being updated. The mmp_time, mmp_nodename, and mmp_bdevname
* fields are only for informational purposes for the administrator,
* due to clock skew between nodes and hostname HA service takeover.
*/ */
#define EXT2_MMP_MAGIC 0x004D4D50 /* ASCII for MMP */ #define EXT4_MMP_MAGIC 0x004D4D50U /* ASCII for MMP */
#define EXT2_MMP_CLEAN 0xFF4D4D50 /* Value of mmp_seq for clean unmount */ #define EXT4_MMP_SEQ_CLEAN 0xFF4D4D50U /* mmp_seq value for clean unmount */
#define EXT2_MMP_FSCK_ON 0xE24D4D50 /* Value of mmp_seq when being fscked */ #define EXT4_MMP_SEQ_FSCK 0xE24D4D50U /* mmp_seq value when being fscked */
#define EXT4_MMP_SEQ_MAX 0xE24D4D4FU /* maximum valid mmp_seq value */
struct mmp_struct { struct mmp_struct {
__u32 mmp_magic; __u32 mmp_magic; /* Magic number for MMP */
__u32 mmp_seq; __u32 mmp_seq; /* Sequence no. updated periodically */
__u64 mmp_time; __u64 mmp_time; /* Time last updated */
char mmp_nodename[64]; char mmp_nodename[64]; /* Node which last updated MMP block */
char mmp_bdevname[32]; char mmp_bdevname[32]; /* Bdev which last updated MMP block */
__u16 mmp_interval; __u16 mmp_check_interval; /* Changed mmp_check_interval */
__u16 mmp_pad1; __u16 mmp_pad1;
__u32 mmp_pad2; __u32 mmp_pad2[227];
}; };
/* /*
* Interval in number of seconds to update the MMP sequence number. * Default interval for MMP update in seconds.
*/ */
#define EXT2_MMP_DEF_INTERVAL 5 #define EXT4_MMP_UPDATE_INTERVAL 5
/*
* Maximum interval for MMP update in seconds.
*/
#define EXT4_MMP_MAX_UPDATE_INTERVAL 300
/*
* Minimum interval for MMP checking in seconds.
*/
#define EXT4_MMP_MIN_CHECK_INTERVAL 5
#endif /* _LINUX_EXT2_FS_H */ #endif /* _LINUX_EXT2_FS_H */

View File

@ -249,7 +249,7 @@ static ext2_ino_t ext2PathToInode(ext2_vd *vd, const char * path)
filename[i] = '\0'; filename[i] = '\0';
errorcode = ext2fs_namei(vd->fs, vd->root, parent, filename, &ino); errorcode = ext2fs_namei_follow(vd->fs, vd->root, parent, filename, &ino);
if(errorcode != EXT2_ET_OK) if(errorcode != EXT2_ET_OK)
return 0; return 0;
@ -389,7 +389,7 @@ static ext2_ino_t ext2CreateSymlink(ext2_vd *vd, const char *path, const char *
if (!err) if (!err)
{ {
inode.i_block[0] = blk; inode.i_block[0] = blk;
inode.i_blocks = vd->fs->blocksize / BYTES_PER_SECTOR; inode.i_blocks = vd->fs->blocksize / 512;
vd->fs->io->manager->write_blk(vd->fs->io, blk, 1, buffer); vd->fs->io->manager->write_blk(vd->fs->io, blk, 1, buffer);
ext2fs_block_alloc_stats(vd->fs, blk, +1); ext2fs_block_alloc_stats(vd->fs, blk, +1);
} }

View File

@ -28,6 +28,7 @@ typedef struct struct_io_stats *io_stats;
#define CHANNEL_FLAGS_WRITETHROUGH 0x01 #define CHANNEL_FLAGS_WRITETHROUGH 0x01
#define CHANNEL_FLAGS_DISCARD_ZEROES 0x02 #define CHANNEL_FLAGS_DISCARD_ZEROES 0x02
#define CHANNEL_FLAGS_BLOCK_DEVICE 0x04
#define io_channel_discard_zeroes_data(i) (i->flags & CHANNEL_FLAGS_DISCARD_ZEROES) #define io_channel_discard_zeroes_data(i) (i->flags & CHANNEL_FLAGS_DISCARD_ZEROES)

View File

@ -6,13 +6,138 @@
#ifndef _EXT2_TYPES_H #ifndef _EXT2_TYPES_H
#define _EXT2_TYPES_H #define _EXT2_TYPES_H
typedef unsigned char __u8; #define __S8_TYPEDEF __signed__ char
typedef signed char __s8; #define __U8_TYPEDEF unsigned char
typedef unsigned short __u16; #define __S16_TYPEDEF __signed__ short
typedef short __s16; #define __U16_TYPEDEF unsigned short
typedef unsigned int __u32; #define __S32_TYPEDEF __signed__ int
typedef int __s32; #define __U32_TYPEDEF unsigned int
typedef unsigned long long __u64; #define __S64_TYPEDEF __signed__ long long
typedef signed long long __s64; #define __U64_TYPEDEF unsigned long long
#endif /* _EXT2_TYPES_H */ #ifdef __U8_TYPEDEF
typedef __U8_TYPEDEF __u8;
#else
typedef unsigned char __u8;
#endif
#ifdef __S8_TYPEDEF
typedef __S8_TYPEDEF __s8;
#else
typedef signed char __s8;
#endif
#ifdef __U16_TYPEDEF
typedef __U16_TYPEDEF __u16;
#else
#if (4 == 2)
typedef unsigned int __u16;
#else
#if (2 == 2)
typedef unsigned short __u16;
#else
?==error: undefined 16 bit type
#endif /* SIZEOF_SHORT == 2 */
#endif /* SIZEOF_INT == 2 */
#endif /* __U16_TYPEDEF */
#ifdef __S16_TYPEDEF
typedef __S16_TYPEDEF __s16;
#else
#if (4 == 2)
typedef int __s16;
#else
#if (2 == 2)
typedef short __s16;
#else
?==error: undefined 16 bit type
#endif /* SIZEOF_SHORT == 2 */
#endif /* SIZEOF_INT == 2 */
#endif /* __S16_TYPEDEF */
#ifdef __U32_TYPEDEF
typedef __U32_TYPEDEF __u32;
#else
#if (4 == 4)
typedef unsigned int __u32;
#else
#if (4 == 4)
typedef unsigned long __u32;
#else
#if (2 == 4)
typedef unsigned short __u32;
#else
?== error: undefined 32 bit type
#endif /* SIZEOF_SHORT == 4 */
#endif /* SIZEOF_LONG == 4 */
#endif /* SIZEOF_INT == 4 */
#endif /* __U32_TYPEDEF */
#ifdef __S32_TYPEDEF
typedef __S32_TYPEDEF __s32;
#else
#if (4 == 4)
typedef int __s32;
#else
#if (4 == 4)
typedef long __s32;
#else
#if (2 == 4)
typedef short __s32;
#else
?== error: undefined 32 bit type
#endif /* SIZEOF_SHORT == 4 */
#endif /* SIZEOF_LONG == 4 */
#endif /* SIZEOF_INT == 4 */
#endif /* __S32_TYPEDEF */
#ifdef __U64_TYPEDEF
typedef __U64_TYPEDEF __u64;
#else
#if (4 == 8)
typedef unsigned int __u64;
#else
#if (4 == 8)
typedef unsigned long __u64;
#else
#if (8 == 8)
typedef unsigned long long __u64;
#endif /* SIZEOF_LONG_LONG == 8 */
#endif /* SIZEOF_LONG == 8 */
#endif /* SIZEOF_INT == 8 */
#endif /* __U64_TYPEDEF */
#ifdef __S64_TYPEDEF
typedef __S64_TYPEDEF __s64;
#else
#if (4 == 8)
typedef int __s64;
#else
#if (4 == 8)
typedef long __s64;
#else
#if (8 == 8)
#if defined(__GNUC__)
typedef __signed__ long long __s64;
#else
typedef signed long long __s64;
#endif /* __GNUC__ */
#endif /* SIZEOF_LONG_LONG == 8 */
#endif /* SIZEOF_LONG == 8 */
#endif /* SIZEOF_INT == 8 */
#endif /* __S64_TYPEDEF */
#undef __S8_TYPEDEF
#undef __U8_TYPEDEF
#undef __S16_TYPEDEF
#undef __U16_TYPEDEF
#undef __S32_TYPEDEF
#undef __U32_TYPEDEF
#undef __S64_TYPEDEF
#undef __U64_TYPEDEF
#endif /* _*_TYPES_H */
/* These defines are needed for the public ext2fs.h header file */
#define HAVE_SYS_TYPES_H 1

View File

@ -41,11 +41,7 @@ void ext2CloseFile (ext2_file_state *file)
// Sync the file (and its attributes) to disc // Sync the file (and its attributes) to disc
if(file->write) if(file->write)
{
// Read in node changes before writing them
ext2fs_read_inode(file->vd->fs, file->ni->ino, &file->ni->ni);
ext2UpdateTimes(file->vd, file->ni, EXT2_UPDATE_ACTIME); ext2UpdateTimes(file->vd, file->ni, EXT2_UPDATE_ACTIME);
}
if (file->read) if (file->read)
ext2UpdateTimes(file->vd, file->ni, EXT2_UPDATE_ATIME); ext2UpdateTimes(file->vd, file->ni, EXT2_UPDATE_ATIME);
@ -243,11 +239,25 @@ ssize_t ext2_write_r (struct _reent *r, int fd, const char *ptr, size_t len)
// Lock // Lock
ext2Lock(file->vd); ext2Lock(file->vd);
u32 writen = 0; errcode_t err = 0;
u32 written = 0;
// Write to the files data atrribute // Write to the files data atrribute
errcode_t err = ext2fs_file_write(file->fd, ptr, len, &writen); while (len > 0)
if (writen <= 0 || err) { {
u32 wrote = 0;
err = ext2fs_file_write(file->fd, ptr, len, &wrote);
if (err)
break;
len -= wrote;
ptr += wrote;
written += wrote;
}
// Check for errors
if (err) {
ext2Unlock(file->vd); ext2Unlock(file->vd);
r->_errno = errno; r->_errno = errno;
return (err ? err : -1); return (err ? err : -1);
@ -256,7 +266,7 @@ ssize_t ext2_write_r (struct _reent *r, int fd, const char *ptr, size_t len)
// Unlock // Unlock
ext2Unlock(file->vd); ext2Unlock(file->vd);
return (writen == 0 ? -1 : writen); return (written == 0 ? -1 : written);
} }
ssize_t ext2_read_r (struct _reent *r, int fd, char *ptr, size_t len) ssize_t ext2_read_r (struct _reent *r, int fd, char *ptr, size_t len)

View File

@ -29,6 +29,10 @@ extern "C" {
#define NO_INLINE_FUNCS #define NO_INLINE_FUNCS
#endif #endif
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600 /* for posix_memalign() */
#endif
/* /*
* Where the master copy of the superblock is located, and how big * Where the master copy of the superblock is located, and how big
* superblocks are supposed to be. We define SUPERBLOCK_SIZE because * superblocks are supposed to be. We define SUPERBLOCK_SIZE because
@ -53,9 +57,18 @@ extern "C" {
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifndef __USE_XOPEN2K
/* If the "#define _XOPEN_SOURCE 600" didn't succeed in declaring
* posix_memalign(), maybe due to <features.h> or <stdlib.h> included beforej
* _XOPEN_SOURCE, declare it here to avoid compiler warnings. */
extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size);
#endif
#include "ext2_types.h" #include "ext2_types.h"
#include "com_err.h"
#include "ext2_fs.h" #include "ext2_fs.h"
#include "ext3_extents.h" #include "ext3_extents.h"
@ -68,6 +81,7 @@ typedef __u64 ext2_off64_t;
typedef __s64 e2_blkcnt_t; typedef __s64 e2_blkcnt_t;
typedef __u32 ext2_dirhash_t; typedef __u32 ext2_dirhash_t;
#include "com_err.h"
#include "ext2_io.h" #include "ext2_io.h"
#include "ext2_err.h" #include "ext2_err.h"
#include "ext2_ext_attr.h" #include "ext2_ext_attr.h"
@ -171,6 +185,7 @@ typedef struct ext2_file *ext2_file_t;
#define EXT2_FLAG_64BITS 0x20000 #define EXT2_FLAG_64BITS 0x20000
#define EXT2_FLAG_PRINT_PROGRESS 0x40000 #define EXT2_FLAG_PRINT_PROGRESS 0x40000
#define EXT2_FLAG_DIRECT_IO 0x80000 #define EXT2_FLAG_DIRECT_IO 0x80000
#define EXT2_FLAG_SKIP_MMP 0x100000
/* /*
* Special flag in the ext2 inode i_flag field that means that this is * Special flag in the ext2 inode i_flag field that means that this is
@ -180,10 +195,9 @@ typedef struct ext2_file *ext2_file_t;
/* /*
* Flags for mkjournal * Flags for mkjournal
*
* EXT2_MKJOURNAL_V1_SUPER Make a (deprecated) V1 journal superblock
*/ */
#define EXT2_MKJOURNAL_V1_SUPER 0x0000001 #define EXT2_MKJOURNAL_V1_SUPER 0x0000001 /* create V1 superblock (deprecated) */
#define EXT2_MKJOURNAL_LAZYINIT 0x0000002 /* don't zero journal inode before use*/
struct opaque_ext2_group_desc; struct opaque_ext2_group_desc;
@ -194,11 +208,11 @@ struct struct_ext2_filsys {
char * device_name; char * device_name;
struct ext2_super_block * super; struct ext2_super_block * super;
unsigned int blocksize; unsigned int blocksize;
int clustersize; int fragsize;
dgrp_t group_desc_count; dgrp_t group_desc_count;
unsigned long desc_blocks; unsigned long desc_blocks;
struct opaque_ext2_group_desc * group_desc; struct opaque_ext2_group_desc * group_desc;
int inode_blocks_per_group; unsigned int inode_blocks_per_group;
ext2fs_inode_bitmap inode_map; ext2fs_inode_bitmap inode_map;
ext2fs_block_bitmap block_map; ext2fs_block_bitmap block_map;
/* XXX FIXME-64: not 64-bit safe, but not used? */ /* XXX FIXME-64: not 64-bit safe, but not used? */
@ -216,10 +230,11 @@ struct struct_ext2_filsys {
struct ext2_image_hdr * image_header; struct ext2_image_hdr * image_header;
__u32 umask; __u32 umask;
time_t now; time_t now;
int cluster_ratio_bits;
/* /*
* Reserved for future expansion * Reserved for future expansion
*/ */
__u32 reserved[7]; __u32 reserved[6];
/* /*
* Reserved for the use of the calling application. * Reserved for the use of the calling application.
@ -232,6 +247,18 @@ struct struct_ext2_filsys {
struct ext2_inode_cache *icache; struct ext2_inode_cache *icache;
io_channel image_io; io_channel image_io;
/*
* Buffers for Multiple mount protection(MMP) block.
*/
void *mmp_buf;
void *mmp_cmp;
int mmp_fd;
/*
* Time at which e2fsck last updated the MMP block.
*/
long mmp_last_written;
/* /*
* More callback functions * More callback functions
*/ */
@ -519,6 +546,7 @@ typedef struct ext2_icount *ext2_icount_t;
EXT3_FEATURE_INCOMPAT_RECOVER|\ EXT3_FEATURE_INCOMPAT_RECOVER|\
EXT3_FEATURE_INCOMPAT_EXTENTS|\ EXT3_FEATURE_INCOMPAT_EXTENTS|\
EXT4_FEATURE_INCOMPAT_FLEX_BG|\ EXT4_FEATURE_INCOMPAT_FLEX_BG|\
EXT4_FEATURE_INCOMPAT_MMP|\
EXT4_FEATURE_INCOMPAT_64BIT) EXT4_FEATURE_INCOMPAT_64BIT)
#else #else
#define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\ #define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
@ -527,6 +555,7 @@ typedef struct ext2_icount *ext2_icount_t;
EXT3_FEATURE_INCOMPAT_RECOVER|\ EXT3_FEATURE_INCOMPAT_RECOVER|\
EXT3_FEATURE_INCOMPAT_EXTENTS|\ EXT3_FEATURE_INCOMPAT_EXTENTS|\
EXT4_FEATURE_INCOMPAT_FLEX_BG|\ EXT4_FEATURE_INCOMPAT_FLEX_BG|\
EXT4_FEATURE_INCOMPAT_MMP|\
EXT4_FEATURE_INCOMPAT_64BIT) EXT4_FEATURE_INCOMPAT_64BIT)
#endif #endif
#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\ #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
@ -534,7 +563,9 @@ typedef struct ext2_icount *ext2_icount_t;
EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\ EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\ EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\ EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\
EXT4_FEATURE_RO_COMPAT_GDT_CSUM) EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\
EXT4_FEATURE_RO_COMPAT_BIGALLOC|\
EXT4_FEATURE_RO_COMPAT_QUOTA)
/* /*
* These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
@ -543,6 +574,29 @@ typedef struct ext2_icount *ext2_icount_t;
#define EXT2_LIB_SOFTSUPP_INCOMPAT (0) #define EXT2_LIB_SOFTSUPP_INCOMPAT (0)
#define EXT2_LIB_SOFTSUPP_RO_COMPAT (EXT4_FEATURE_RO_COMPAT_BIGALLOC) #define EXT2_LIB_SOFTSUPP_RO_COMPAT (EXT4_FEATURE_RO_COMPAT_BIGALLOC)
/* Translate a block number to a cluster number */
#define EXT2FS_CLUSTER_RATIO(fs) (1 << (fs)->cluster_ratio_bits)
#define EXT2FS_CLUSTER_MASK(fs) (EXT2FS_CLUSTER_RATIO(fs) - 1)
#define EXT2FS_B2C(fs, blk) ((blk) >> (fs)->cluster_ratio_bits)
/* Translate a cluster number to a block number */
#define EXT2FS_C2B(fs, cluster) ((cluster) << (fs)->cluster_ratio_bits)
/* Translate # of blks to # of clusters */
#define EXT2FS_NUM_B2C(fs, blks) (((blks) + EXT2FS_CLUSTER_MASK(fs)) >> \
(fs)->cluster_ratio_bits)
#if defined(HAVE_STAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
typedef struct stat64 ext2fs_struct_stat;
#else
typedef struct stat ext2fs_struct_stat;
#endif
/*
* For ext2fs_close2() and ext2fs_flush2(), this flag allows you to
* avoid the fsync call.
*/
#define EXT2_FLAG_FLUSH_NO_SYNC 1
/* /*
* function prototypes * function prototypes
*/ */
@ -656,6 +710,10 @@ extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs, extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
const char *descr, const char *descr,
ext2fs_block_bitmap *ret); ext2fs_block_bitmap *ret);
extern errcode_t ext2fs_allocate_subcluster_bitmap(ext2_filsys fs,
const char *descr,
ext2fs_block_bitmap *ret);
extern int ext2fs_get_bitmap_granularity(ext2fs_block_bitmap bitmap);
extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs, extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
const char *descr, const char *descr,
ext2fs_inode_bitmap *ret); ext2fs_inode_bitmap *ret);
@ -712,6 +770,7 @@ extern errcode_t ext2fs_get_block_bitmap_range2(ext2fs_block_bitmap bmap,
extern dgrp_t ext2fs_group_of_blk2(ext2_filsys fs, blk64_t); extern dgrp_t ext2fs_group_of_blk2(ext2_filsys fs, blk64_t);
extern blk64_t ext2fs_group_first_block2(ext2_filsys fs, dgrp_t group); extern blk64_t ext2fs_group_first_block2(ext2_filsys fs, dgrp_t group);
extern blk64_t ext2fs_group_last_block2(ext2_filsys fs, dgrp_t group); extern blk64_t ext2fs_group_last_block2(ext2_filsys fs, dgrp_t group);
extern int ext2fs_group_blocks_count(ext2_filsys fs, dgrp_t group);
extern blk64_t ext2fs_inode_data_blocks2(ext2_filsys fs, extern blk64_t ext2fs_inode_data_blocks2(ext2_filsys fs,
struct ext2_inode *inode); struct ext2_inode *inode);
extern blk64_t ext2fs_inode_i_blocks(ext2_filsys fs, extern blk64_t ext2fs_inode_i_blocks(ext2_filsys fs,
@ -763,8 +822,10 @@ extern void ext2fs_bg_flags_set(ext2_filsys fs, dgrp_t group, __u16 bg_flags);
extern void ext2fs_bg_flags_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flags); extern void ext2fs_bg_flags_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flags);
extern __u16 ext2fs_bg_checksum(ext2_filsys fs, dgrp_t group); extern __u16 ext2fs_bg_checksum(ext2_filsys fs, dgrp_t group);
extern void ext2fs_bg_checksum_set(ext2_filsys fs, dgrp_t group, __u16 checksum); extern void ext2fs_bg_checksum_set(ext2_filsys fs, dgrp_t group, __u16 checksum);
extern blk64_t ext2fs_file_acl_block(const struct ext2_inode *inode); extern blk64_t ext2fs_file_acl_block(ext2_filsys fs,
extern void ext2fs_file_acl_block_set(struct ext2_inode *inode, blk64_t blk); const struct ext2_inode *inode);
extern void ext2fs_file_acl_block_set(ext2_filsys fs,
struct ext2_inode *inode, blk64_t blk);
/* block.c */ /* block.c */
extern errcode_t ext2fs_block_iterate(ext2_filsys fs, extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
@ -822,7 +883,9 @@ extern errcode_t ext2fs_check_desc(ext2_filsys fs);
/* closefs.c */ /* closefs.c */
extern errcode_t ext2fs_close(ext2_filsys fs); extern errcode_t ext2fs_close(ext2_filsys fs);
extern errcode_t ext2fs_close2(ext2_filsys fs, int flags);
extern errcode_t ext2fs_flush(ext2_filsys fs); extern errcode_t ext2fs_flush(ext2_filsys fs);
extern errcode_t ext2fs_flush2(ext2_filsys fs, int flags);
extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block); extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block);
extern errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs, extern errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs,
dgrp_t group, dgrp_t group,
@ -838,6 +901,10 @@ extern int ext2fs_super_and_bgd_loc(ext2_filsys fs,
int *ret_meta_bg); int *ret_meta_bg);
extern void ext2fs_update_dynamic_rev(ext2_filsys fs); extern void ext2fs_update_dynamic_rev(ext2_filsys fs);
/* crc32c.c */
extern __u32 ext2fs_crc32c_be(__u32 crc, unsigned char const *p, size_t len);
extern __u32 ext2fs_crc32c_le(__u32 crc, unsigned char const *p, size_t len);
/* csum.c */ /* csum.c */
extern void ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group); extern void ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group);
extern int ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group); extern int ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group);
@ -1088,6 +1155,8 @@ errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap,
errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap, errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap,
__u64 start, unsigned int num, __u64 start, unsigned int num,
void *in); void *in);
errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
ext2fs_block_bitmap *bitmap);
/* getsize.c */ /* getsize.c */
extern errcode_t ext2fs_get_device_size(const char *file, int blocksize, extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
@ -1227,21 +1296,21 @@ extern errcode_t ext2fs_zero_blocks(ext2_filsys fs, blk_t blk, int num,
extern errcode_t ext2fs_zero_blocks2(ext2_filsys fs, blk64_t blk, int num, extern errcode_t ext2fs_zero_blocks2(ext2_filsys fs, blk64_t blk, int num,
blk64_t *ret_blk, int *ret_count); blk64_t *ret_blk, int *ret_count);
extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs, extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
__u32 size, int flags, __u32 num_blocks, int flags,
char **ret_jsb); char **ret_jsb);
extern errcode_t ext2fs_add_journal_device(ext2_filsys fs, extern errcode_t ext2fs_add_journal_device(ext2_filsys fs,
ext2_filsys journal_dev); ext2_filsys journal_dev);
extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size, extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks,
int flags); int flags);
extern int ext2fs_default_journal_size(__u64 blocks); extern int ext2fs_default_journal_size(__u64 num_blocks);
/* openfs.c */ /* openfs.c */
extern errcode_t ext2fs_open(const char *name, int flags, int superblock, extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
unsigned int block_size, io_channel * chan, unsigned int block_size, io_channel chan,
ext2_filsys *ret_fs); ext2_filsys *ret_fs);
extern errcode_t ext2fs_open2(const char *name, const char *io_options, extern errcode_t ext2fs_open2(const char *name, const char *io_options,
int flags, int superblock, int flags, int superblock,
unsigned int block_size, io_channel * chan, unsigned int block_size, io_channel chan,
ext2_filsys *ret_fs); ext2_filsys *ret_fs);
extern blk64_t ext2fs_descriptor_block_loc2(ext2_filsys fs, extern blk64_t ext2fs_descriptor_block_loc2(ext2_filsys fs,
blk64_t group_block, dgrp_t i); blk64_t group_block, dgrp_t i);
@ -1261,6 +1330,16 @@ errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name, errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name,
ext2_ino_t ino, int flags); ext2_ino_t ino, int flags);
/* mmp.c */
errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf);
errcode_t ext2fs_mmp_write(ext2_filsys fs, blk64_t mmp_blk, void *buf);
errcode_t ext2fs_mmp_clear(ext2_filsys fs);
errcode_t ext2fs_mmp_init(ext2_filsys fs);
errcode_t ext2fs_mmp_start(ext2_filsys fs);
errcode_t ext2fs_mmp_update(ext2_filsys fs);
errcode_t ext2fs_mmp_stop(ext2_filsys fs);
unsigned ext2fs_mmp_new_seq(void);
/* read_bb.c */ /* read_bb.c */
extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs, extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs,
ext2_badblocks_list *bb_list); ext2_badblocks_list *bb_list);
@ -1296,9 +1375,12 @@ extern void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
int bufsize); int bufsize);
extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t, extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
struct ext2_inode *f, int hostorder); struct ext2_inode *f, int hostorder);
extern void ext2fs_swap_mmp(struct mmp_struct *mmp);
/* valid_blk.c */ /* valid_blk.c */
extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode); extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
extern int ext2fs_inode_has_valid_blocks2(ext2_filsys fs,
struct ext2_inode *inode);
/* version.c */ /* version.c */
extern int ext2fs_parse_version_string(const char *ver_string); extern int ext2fs_parse_version_string(const char *ver_string);
@ -1315,6 +1397,11 @@ extern errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list,
extern errcode_t ext2fs_get_mem(unsigned long size, void *ptr); extern errcode_t ext2fs_get_mem(unsigned long size, void *ptr);
extern errcode_t ext2fs_get_memalign(unsigned long size, extern errcode_t ext2fs_get_memalign(unsigned long size,
unsigned long align, void *ptr); unsigned long align, void *ptr);
extern errcode_t ext2fs_get_memzero(unsigned long size, void *ptr);
extern errcode_t ext2fs_get_array(unsigned long count,
unsigned long size, void *ptr);
extern errcode_t ext2fs_get_arrayzero(unsigned long count,
unsigned long size, void *ptr);
extern errcode_t ext2fs_free_mem(void *ptr); extern errcode_t ext2fs_free_mem(void *ptr);
extern errcode_t ext2fs_resize_mem(unsigned long old_size, extern errcode_t ext2fs_resize_mem(unsigned long old_size,
unsigned long size, void *ptr); unsigned long size, void *ptr);
@ -1336,6 +1423,9 @@ extern blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
struct ext2_inode *inode); struct ext2_inode *inode);
extern unsigned int ext2fs_div_ceil(unsigned int a, unsigned int b); extern unsigned int ext2fs_div_ceil(unsigned int a, unsigned int b);
extern __u64 ext2fs_div64_ceil(__u64 a, __u64 b); extern __u64 ext2fs_div64_ceil(__u64 a, __u64 b);
extern int ext2fs_open_file(const char *pathname, int flags, mode_t mode);
extern int ext2fs_stat(const char *path, ext2fs_struct_stat *buf);
extern int ext2fs_fstat(int fd, ext2fs_struct_stat *buf);
/* /*
* The actual inlined functions definitions themselves... * The actual inlined functions definitions themselves...
@ -1371,19 +1461,14 @@ _INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
return 0; return 0;
} }
_INLINE_ errcode_t ext2fs_get_memalign(unsigned long size, _INLINE_ errcode_t ext2fs_get_memzero(unsigned long size, void *ptr)
unsigned long align, void *ptr)
{ {
void *pp; void *pp;
#ifdef HWRVL
pp = mem_align(32, size);
#else
pp = mem_alloc(size); pp = mem_alloc(size);
#endif
if (!pp) if (!pp)
return EXT2_ET_NO_MEMORY; return EXT2_ET_NO_MEMORY;
memset(pp, 0, size);
memcpy(ptr, &pp, sizeof(pp)); memcpy(ptr, &pp, sizeof(pp));
return 0; return 0;
} }
@ -1391,10 +1476,24 @@ _INLINE_ errcode_t ext2fs_get_memalign(unsigned long size,
_INLINE_ errcode_t ext2fs_get_array(unsigned long count, unsigned long size, void *ptr) _INLINE_ errcode_t ext2fs_get_array(unsigned long count, unsigned long size, void *ptr)
{ {
if (count && (-1UL)/count<size) if (count && (-1UL)/count<size)
return EXT2_ET_NO_MEMORY; //maybe define EXT2_ET_OVERFLOW ? return EXT2_ET_NO_MEMORY;
return ext2fs_get_mem(count*size, ptr); return ext2fs_get_mem(count*size, ptr);
} }
_INLINE_ errcode_t ext2fs_get_arrayzero(unsigned long count,
unsigned long size, void *ptr)
{
void *pp;
if (count && (-1UL)/count<size)
return EXT2_ET_NO_MEMORY;
pp = mem_calloc(count, size);
if (!pp)
return EXT2_ET_NO_MEMORY;
memcpy(ptr, &pp, sizeof(pp));
return 0;
}
/* /*
* Free memory * Free memory
*/ */
@ -1562,6 +1661,40 @@ _INLINE_ __u64 ext2fs_div64_ceil(__u64 a, __u64 b)
return ((a - 1) / b) + 1; return ((a - 1) / b) + 1;
} }
_INLINE_ int ext2fs_open_file(const char *pathname, int flags, mode_t mode)
{
va_list args;
if (mode)
#if defined(HAVE_OPEN64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
return open64(pathname, flags, mode);
else
return open64(pathname, flags);
#else
return open(pathname, flags, mode);
else
return open(pathname, flags);
#endif
}
_INLINE_ int ext2fs_stat(const char *path, ext2fs_struct_stat *buf)
{
#if defined(HAVE_STAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
return stat64(path, buf);
#else
return stat(path, buf);
#endif
}
_INLINE_ int ext2fs_fstat(int fd, ext2fs_struct_stat *buf)
{
#if defined(HAVE_STAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
return fstat64(fd, buf);
#else
return fstat(fd, buf);
#endif
}
#undef _INLINE_ #undef _INLINE_
#endif #endif

View File

@ -138,6 +138,6 @@ extern errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bitmap,
extern errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bitmap, extern errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bitmap,
__u64 start, unsigned int num, __u64 start, unsigned int num,
void *out); void *out);
extern int ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func); extern void ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap,const char *func);
extern int ext2fs_mem_is_zero(const char *mem, size_t len); extern int ext2fs_mem_is_zero(const char *mem, size_t len);

View File

@ -11,6 +11,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -82,9 +83,9 @@ errcode_t ext2fs_write_ext_attr2(ext2_filsys fs, blk64_t block, void *inbuf)
{ {
errcode_t retval; errcode_t retval;
char *write_buf; char *write_buf;
#ifdef WORDS_BIGENDIAN
char *buf = NULL; char *buf = NULL;
#ifdef WORDS_BIGENDIAN
retval = ext2fs_get_mem(fs->blocksize, &buf); retval = ext2fs_get_mem(fs->blocksize, &buf);
if (retval) if (retval)
return retval; return retval;
@ -94,8 +95,9 @@ errcode_t ext2fs_write_ext_attr2(ext2_filsys fs, blk64_t block, void *inbuf)
write_buf = (char *) inbuf; write_buf = (char *) inbuf;
#endif #endif
retval = io_channel_write_blk64(fs->io, block, 1, write_buf); retval = io_channel_write_blk64(fs->io, block, 1, write_buf);
if (buf) #ifdef WORDS_BIGENDIAN
ext2fs_free_mem(&buf); ext2fs_free_mem(&buf);
#endif
if (!retval) if (!retval)
ext2fs_mark_changed(fs); ext2fs_mark_changed(fs);
return retval; return retval;

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -253,9 +254,8 @@ extern errcode_t ext2fs_extent_open2(ext2_filsys fs, ext2_ino_t ino,
handle->path[0].max_entries = ext2fs_le16_to_cpu(eh->eh_max); handle->path[0].max_entries = ext2fs_le16_to_cpu(eh->eh_max);
handle->path[0].curr = 0; handle->path[0].curr = 0;
handle->path[0].end_blk = handle->path[0].end_blk =
((((__u64) handle->inode->i_size_high << 32) + (EXT2_I_SIZE(handle->inode) + fs->blocksize - 1) >>
handle->inode->i_size + (fs->blocksize - 1)) EXT2_BLOCK_SIZE_BITS(fs->super);
>> EXT2_BLOCK_SIZE_BITS(fs->super));
handle->path[0].visit_num = 1; handle->path[0].visit_num = 1;
handle->level = 0; handle->level = 0;
handle->magic = EXT2_ET_MAGIC_EXTENT_HANDLE; handle->magic = EXT2_ET_MAGIC_EXTENT_HANDLE;
@ -374,9 +374,11 @@ retry:
case EXT2_EXTENT_ROOT: case EXT2_EXTENT_ROOT:
handle->level = 0; handle->level = 0;
path = handle->path + handle->level; path = handle->path + handle->level;
/* fallthrough */
case EXT2_EXTENT_FIRST_SIB: case EXT2_EXTENT_FIRST_SIB:
path->left = path->entries; path->left = path->entries;
path->curr = 0; path->curr = 0;
/* fallthrough */
case EXT2_EXTENT_NEXT_SIB: case EXT2_EXTENT_NEXT_SIB:
if (path->left <= 0) if (path->left <= 0)
return EXT2_ET_EXTENT_NO_NEXT; return EXT2_ET_EXTENT_NO_NEXT;

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -22,7 +23,7 @@ struct ext2_file {
errcode_t magic; errcode_t magic;
ext2_filsys fs; ext2_filsys fs;
ext2_ino_t ino; ext2_ino_t ino;
struct ext2_inode inode; struct ext2_inode *inode;
int flags; int flags;
__u64 pos; __u64 pos;
blk64_t blockno; blk64_t blockno;
@ -56,12 +57,8 @@ errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
file->fs = fs; file->fs = fs;
file->ino = ino; file->ino = ino;
file->flags = flags & EXT2_FILE_MASK; file->flags = flags & EXT2_FILE_MASK;
file->inode = inode;
if (inode) { if (!inode) {
memcpy(&file->inode, inode, sizeof(struct ext2_inode));
} else {
retval = ext2fs_read_inode(fs, ino, &file->inode);
if (retval)
goto fail; goto fail;
} }
@ -102,7 +99,7 @@ struct ext2_inode *ext2fs_file_get_inode(ext2_file_t file)
{ {
if (file->magic != EXT2_ET_MAGIC_EXT2_FILE) if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
return NULL; return NULL;
return &file->inode; return file->inode;
} }
/* /*
@ -121,15 +118,12 @@ errcode_t ext2fs_file_flush(ext2_file_t file)
!(file->flags & EXT2_FILE_BUF_DIRTY)) !(file->flags & EXT2_FILE_BUF_DIRTY))
return 0; return 0;
// Flushing out the new size - Dimok
ext2fs_write_inode(file->fs, file->ino, &file->inode);
/* /*
* OK, the physical block hasn't been allocated yet. * OK, the physical block hasn't been allocated yet.
* Allocate it. * Allocate it.
*/ */
if (!file->physblock) { if (!file->physblock) {
retval = ext2fs_bmap2(fs, file->ino, &file->inode, retval = ext2fs_bmap2(fs, file->ino, file->inode,
BMAP_BUFFER, file->ino ? BMAP_ALLOC : 0, BMAP_BUFFER, file->ino ? BMAP_ALLOC : 0,
file->blockno, 0, &file->physblock); file->blockno, 0, &file->physblock);
if (retval) if (retval)
@ -181,7 +175,7 @@ static errcode_t load_buffer(ext2_file_t file, int dontfill)
errcode_t retval; errcode_t retval;
if (!(file->flags & EXT2_FILE_BUF_VALID)) { if (!(file->flags & EXT2_FILE_BUF_VALID)) {
retval = ext2fs_bmap2(fs, file->ino, &file->inode, retval = ext2fs_bmap2(fs, file->ino, file->inode,
BMAP_BUFFER, 0, file->blockno, 0, BMAP_BUFFER, 0, file->blockno, 0,
&file->physblock); &file->physblock);
if (retval) if (retval)
@ -230,7 +224,7 @@ errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE); EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
fs = file->fs; fs = file->fs;
while ((file->pos < EXT2_I_SIZE(&file->inode)) && (wanted > 0)) { while ((file->pos < EXT2_I_SIZE(file->inode)) && (wanted > 0)) {
retval = sync_buffer_position(file); retval = sync_buffer_position(file);
if (retval) if (retval)
goto fail; goto fail;
@ -242,7 +236,7 @@ errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
c = fs->blocksize - start; c = fs->blocksize - start;
if (c > wanted) if (c > wanted)
c = wanted; c = wanted;
left = EXT2_I_SIZE(&file->inode) - file->pos ; left = EXT2_I_SIZE(file->inode) - file->pos ;
if (c > left) if (c > left)
c = left; c = left;
@ -300,11 +294,11 @@ errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
nbytes -= c; nbytes -= c;
} }
// I don't see why changing size is my duty - Dimok // Modify file size in inode if required
if(EXT2_I_SIZE(&file->inode) < file->pos) if(EXT2_I_SIZE(file->inode) < file->pos)
{ {
file->inode.i_size = file->pos & 0xFFFFFFFF; file->inode->i_size = file->pos & 0xFFFFFFFF;
file->inode.i_size_high = (file->pos >> 32) & 0xFFFFFFFF; file->inode->i_size_high = (file->pos >> 32) & 0xFFFFFFFF;
} }
fail: fail:
@ -323,7 +317,7 @@ errcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset,
else if (whence == EXT2_SEEK_CUR) else if (whence == EXT2_SEEK_CUR)
file->pos += offset; file->pos += offset;
else if (whence == EXT2_SEEK_END) else if (whence == EXT2_SEEK_END)
file->pos = EXT2_I_SIZE(&file->inode) + offset; file->pos = EXT2_I_SIZE(file->inode) + offset;
else else
return EXT2_ET_INVALID_ARGUMENT; return EXT2_ET_INVALID_ARGUMENT;
@ -336,7 +330,7 @@ errcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset,
errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset, errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
int whence, ext2_off_t *ret_pos) int whence, ext2_off_t *ret_pos)
{ {
__u64 loffset, ret_loffset = 0; __u64 loffset, ret_loffset;
errcode_t retval; errcode_t retval;
loffset = offset; loffset = offset;
@ -354,7 +348,7 @@ errcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size)
{ {
if (file->magic != EXT2_ET_MAGIC_EXT2_FILE) if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
return EXT2_ET_MAGIC_EXT2_FILE; return EXT2_ET_MAGIC_EXT2_FILE;
*ret_size = EXT2_I_SIZE(&file->inode); *ret_size = EXT2_I_SIZE(file->inode);
return 0; return 0;
} }
@ -386,15 +380,14 @@ errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size)
truncate_block = ((size + file->fs->blocksize - 1) >> truncate_block = ((size + file->fs->blocksize - 1) >>
EXT2_BLOCK_SIZE_BITS(file->fs->super)) + 1; EXT2_BLOCK_SIZE_BITS(file->fs->super)) + 1;
old_size = file->inode.i_size + old_size = EXT2_I_SIZE(file->inode);
(((blk64_t) file->inode.i_size_high) << 32);
old_truncate = ((old_size + file->fs->blocksize - 1) >> old_truncate = ((old_size + file->fs->blocksize - 1) >>
EXT2_BLOCK_SIZE_BITS(file->fs->super)) + 1; EXT2_BLOCK_SIZE_BITS(file->fs->super)) + 1;
file->inode.i_size = size & 0xffffffff; file->inode->i_size = size & 0xffffffff;
file->inode.i_size_high = (size >> 32); file->inode->i_size_high = (size >> 32);
if (file->ino) { if (file->ino) {
retval = ext2fs_write_inode(file->fs, file->ino, &file->inode); retval = ext2fs_write_inode(file->fs, file->ino, file->inode);
if (retval) if (retval)
return retval; return retval;
} }
@ -402,7 +395,7 @@ errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size)
if (truncate_block <= old_truncate) if (truncate_block <= old_truncate)
return 0; return 0;
return ext2fs_punch(file->fs, file->ino, &file->inode, 0, return ext2fs_punch(file->fs, file->ino, file->inode, 0,
truncate_block, ~0ULL); truncate_block, ~0ULL);
} }

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_ERRNO_H #if HAVE_ERRNO_H
#include <errno.h> #include <errno.h>
@ -65,9 +66,13 @@ errcode_t ext2fs_sync_device(int fd, int flushb)
#ifdef BLKFLSBUF #ifdef BLKFLSBUF
if (ioctl (fd, BLKFLSBUF, 0) == 0) if (ioctl (fd, BLKFLSBUF, 0) == 0)
return 0; return 0;
#elif defined(__linux__)
#warning BLKFLSBUF not defined
#endif #endif
#ifdef FDFLUSH #ifdef FDFLUSH
ioctl (fd, FDFLUSH, 0); /* In case this is a floppy */ ioctl (fd, FDFLUSH, 0); /* In case this is a floppy */
#elif defined(__linux__)
#warning FDFLUSH not defined
#endif #endif
} }
return 0; return 0;

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -53,6 +54,11 @@ void ext2fs_free(ext2_filsys fs)
if (fs->icache) if (fs->icache)
ext2fs_free_inode_cache(fs->icache); ext2fs_free_inode_cache(fs->icache);
if (fs->mmp_buf)
ext2fs_free_mem(&fs->mmp_buf);
if (fs->mmp_cmp)
ext2fs_free_mem(&fs->mmp_cmp);
fs->magic = 0; fs->magic = 0;
ext2fs_free_mem(&fs); ext2fs_free_mem(&fs);

View File

@ -47,6 +47,59 @@ static bool device_gekko_io_readsectors(io_channel dev, sec_t sector, sec_t numS
static s64 device_gekko_io_writebytes(io_channel dev, s64 offset, s64 count, const void *buf); static s64 device_gekko_io_writebytes(io_channel dev, s64 offset, s64 count, const void *buf);
static bool device_gekko_io_writesectors(io_channel dev, sec_t sector, sec_t numSectors, const void* buffer); static bool device_gekko_io_writesectors(io_channel dev, sec_t sector, sec_t numSectors, const void* buffer);
/**
* Get the sector size of the device
*/
static int readSectorSize(const DISC_INTERFACE* interace)
{
int counter1 = 0;
int counter2 = 0;
int i;
u8 *memblock = (u8 *) mem_alloc(MAX_SECTOR_SIZE);
if(!memblock)
return 512;
memset(memblock, 0x00, MAX_SECTOR_SIZE);
if(!interace->readSectors(0, 1, memblock)) {
mem_free(memblock);
return 512;
}
for(i = 0; i < MAX_SECTOR_SIZE; ++i)
{
if(memblock[i] != 0x00)
counter1++;
}
memset(memblock, 0xFF, MAX_SECTOR_SIZE);
if(!interace->readSectors(0, 1, memblock)) {
mem_free(memblock);
return 512;
}
for(i = 0; i < MAX_SECTOR_SIZE; ++i)
{
if(memblock[i] != 0xFF)
counter2++;
}
mem_free(memblock);
if(counter1 <= 512 && counter2 <= 512)
return 512;
if(counter1 <= 1024 && counter2 <= 1024)
return 1024;
if(counter1 <= 2048 && counter2 <= 2048)
return 2048;
return 4096;
}
/** /**
* *
*/ */
@ -78,8 +131,9 @@ static errcode_t device_gekko_io_open(const char *name, int flags, io_channel *d
return -1; return -1;
} }
struct ext2_super_block * super = (struct ext2_super_block *) mem_alloc(SUPERBLOCK_SIZE); //1024 bytes // Allocate 4 x max sector size in case of 4096 sector size
if(!super) u8 *buffer = (u8 *) mem_alloc(4 * MAX_SECTOR_SIZE);
if(!buffer)
{ {
ext2_log_trace("no memory for superblock"); ext2_log_trace("no memory for superblock");
errno = ENOMEM; errno = ENOMEM;
@ -87,44 +141,49 @@ static errcode_t device_gekko_io_open(const char *name, int flags, io_channel *d
} }
// Check that there is a valid EXT boot sector at the start of the device // Check that there is a valid EXT boot sector at the start of the device
if (!interface->readSectors(fd->startSector+SUPERBLOCK_OFFSET/BYTES_PER_SECTOR, SUPERBLOCK_SIZE/BYTES_PER_SECTOR, super)) if (!interface->readSectors(fd->startSector, 4, buffer))
{ {
ext2_log_trace("read failure @ sector %d\n", fd->startSector); ext2_log_trace("read failure @ sector %d\n", fd->startSector);
errno = EROFS; errno = EROFS;
mem_free(super); mem_free(buffer);
return -1; return -1;
} }
struct ext2_super_block * super = (struct ext2_super_block *) (buffer + SUPERBLOCK_OFFSET);
if(ext2fs_le16_to_cpu(super->s_magic) != EXT2_SUPER_MAGIC) if(ext2fs_le16_to_cpu(super->s_magic) != EXT2_SUPER_MAGIC)
{ {
mem_free(super); ext2_log_trace("super mismatch: read %04X - expected %04X\n", ext2fs_le16_to_cpu(super->s_magic), EXT2_SUPER_MAGIC);
mem_free(buffer);
errno = EROFS; errno = EROFS;
return -1; return -1;
} }
// Parse the boot sector
fd->sectorSize = BYTES_PER_SECTOR;
fd->offset = 0;
fd->sectorCount = 0;
switch(ext2fs_le32_to_cpu(super->s_log_block_size)) switch(ext2fs_le32_to_cpu(super->s_log_block_size))
{ {
case 1: case 1:
fd->sectorCount = (sec_t) ((u64) ext2fs_le32_to_cpu(super->s_blocks_count) * (u64) 2048 / (u64) BYTES_PER_SECTOR); (*dev)->block_size = 2048;
break; break;
case 2: case 2:
fd->sectorCount = (sec_t) ((u64) ext2fs_le32_to_cpu(super->s_blocks_count) * (u64) 4096 / (u64) BYTES_PER_SECTOR); (*dev)->block_size = 4096;
break; break;
case 3: case 3:
fd->sectorCount = (sec_t) ((u64) ext2fs_le32_to_cpu(super->s_blocks_count) * (u64) 8192 / (u64) BYTES_PER_SECTOR); (*dev)->block_size = 8192;
break; break;
default: default:
case 0: case 0:
fd->sectorCount = (sec_t) ((u64) ext2fs_le32_to_cpu(super->s_blocks_count) * (u64) 1024 / (u64) BYTES_PER_SECTOR); (*dev)->block_size = 1024;
break; break;
} }
mem_free(super);
// Parse the boot sector
fd->sectorSize = readSectorSize(interface);
fd->offset = 0;
fd->sectorCount = 0;
fd->sectorCount = (sec_t) ((u64) ext2fs_le32_to_cpu(super->s_blocks_count) * (u64) ((*dev)->block_size) / (u64) fd->sectorSize);
mem_free(buffer);
// Create the cache // Create the cache
fd->cache = cache_constructor(fd->cachePageCount, fd->cachePageSize, interface, fd->startSector + fd->sectorCount, fd->sectorSize); fd->cache = cache_constructor(fd->cachePageCount, fd->cachePageSize, interface, fd->startSector + fd->sectorCount, fd->sectorSize);

View File

@ -27,7 +27,7 @@
#include "disc_cache.h" #include "disc_cache.h"
#include "ext2fs.h" #include "ext2fs.h"
#define BYTES_PER_SECTOR 512 #define MAX_SECTOR_SIZE (4096)
/** /**
* gekko_fd - Gekko device driver descriptor * gekko_fd - Gekko device driver descriptor

View File

@ -10,6 +10,7 @@
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -25,7 +26,6 @@
#endif #endif
#include "ext2_fs.h" #include "ext2_fs.h"
#include "ext2fs.h"
#include "ext2fsP.h" #include "ext2fsP.h"
struct ext2fs_struct_generic_bitmap { struct ext2fs_struct_generic_bitmap {
@ -179,8 +179,8 @@ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
#ifndef OMIT_COM_ERR #ifndef OMIT_COM_ERR
com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
"test_bitmap(%lu)", (unsigned long) bitno); "test_bitmap(%lu)", (unsigned long) bitno);
return 0;
#endif #endif
return 0;
} }
if ((bitno < bitmap->start) || (bitno > bitmap->end)) { if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
@ -201,8 +201,8 @@ int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
#ifndef OMIT_COM_ERR #ifndef OMIT_COM_ERR
com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
"mark_bitmap(%lu)", (unsigned long) bitno); "mark_bitmap(%lu)", (unsigned long) bitno);
return 0;
#endif #endif
return 0;
} }
if ((bitno < bitmap->start) || (bitno > bitmap->end)) { if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
@ -223,8 +223,8 @@ int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
#ifndef OMIT_COM_ERR #ifndef OMIT_COM_ERR
com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
"mark_bitmap(%lu)", (unsigned long) bitno); "mark_bitmap(%lu)", (unsigned long) bitno);
return 0;
#endif #endif
return 0;
} }
if ((bitno < bitmap->start) || (bitno > bitmap->end)) { if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
@ -244,8 +244,8 @@ __u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap)
#ifndef OMIT_COM_ERR #ifndef OMIT_COM_ERR
com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
"get_bitmap_start"); "get_bitmap_start");
return 0;
#endif #endif
return 0;
} }
return bitmap->start; return bitmap->start;
@ -261,8 +261,8 @@ __u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap)
#ifndef OMIT_COM_ERR #ifndef OMIT_COM_ERR
com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
"get_bitmap_end"); "get_bitmap_end");
return 0;
#endif #endif
return 0;
} }
return bitmap->end; return bitmap->end;
} }
@ -278,8 +278,8 @@ void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap)
#ifndef OMIT_COM_ERR #ifndef OMIT_COM_ERR
com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
"clear_generic_bitmap"); "clear_generic_bitmap");
return;
#endif #endif
return;
} }
memset(bitmap->bitmap, 0, memset(bitmap->bitmap, 0,

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -107,12 +108,14 @@ errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
bitmap->end = end; bitmap->end = end;
bitmap->real_end = real_end; bitmap->real_end = real_end;
bitmap->bitmap_ops = ops; bitmap->bitmap_ops = ops;
bitmap->cluster_bits = 0;
switch (magic) { switch (magic) {
case EXT2_ET_MAGIC_INODE_BITMAP64: case EXT2_ET_MAGIC_INODE_BITMAP64:
bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK; bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
break; break;
case EXT2_ET_MAGIC_BLOCK_BITMAP64: case EXT2_ET_MAGIC_BLOCK_BITMAP64:
bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK; bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
bitmap->cluster_bits = fs->cluster_ratio_bits;
break; break;
default: default:
bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK; bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
@ -191,6 +194,7 @@ errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src,
new_bmap->real_end = src->real_end; new_bmap->real_end = src->real_end;
new_bmap->bitmap_ops = src->bitmap_ops; new_bmap->bitmap_ops = src->bitmap_ops;
new_bmap->base_error_code = src->base_error_code; new_bmap->base_error_code = src->base_error_code;
new_bmap->cluster_bits = src->cluster_bits;
descr = src->description; descr = src->description;
if (descr) { if (descr) {
@ -315,6 +319,8 @@ int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap,
if (!EXT2FS_IS_64_BITMAP(bitmap)) if (!EXT2FS_IS_64_BITMAP(bitmap))
return 0; return 0;
arg >>= bitmap->cluster_bits;
if ((arg < bitmap->start) || (arg > bitmap->end)) { if ((arg < bitmap->start) || (arg > bitmap->end)) {
warn_bitmap(bitmap, EXT2FS_MARK_ERROR, arg); warn_bitmap(bitmap, EXT2FS_MARK_ERROR, arg);
return 0; return 0;
@ -341,6 +347,8 @@ int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap bitmap,
if (!EXT2FS_IS_64_BITMAP(bitmap)) if (!EXT2FS_IS_64_BITMAP(bitmap))
return 0; return 0;
arg >>= bitmap->cluster_bits;
if ((arg < bitmap->start) || (arg > bitmap->end)) { if ((arg < bitmap->start) || (arg > bitmap->end)) {
warn_bitmap(bitmap, EXT2FS_UNMARK_ERROR, arg); warn_bitmap(bitmap, EXT2FS_UNMARK_ERROR, arg);
return 0; return 0;
@ -367,6 +375,8 @@ int ext2fs_test_generic_bmap(ext2fs_generic_bitmap bitmap,
if (!EXT2FS_IS_64_BITMAP(bitmap)) if (!EXT2FS_IS_64_BITMAP(bitmap))
return 0; return 0;
arg >>= bitmap->cluster_bits;
if ((arg < bitmap->start) || (arg > bitmap->end)) { if ((arg < bitmap->start) || (arg > bitmap->end)) {
warn_bitmap(bitmap, EXT2FS_TEST_ERROR, arg); warn_bitmap(bitmap, EXT2FS_TEST_ERROR, arg);
return 0; return 0;
@ -383,7 +393,7 @@ errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap,
return EINVAL; return EINVAL;
if (EXT2FS_IS_32_BITMAP(bmap)) { if (EXT2FS_IS_32_BITMAP(bmap)) {
if ((start+num) & ~0xffffffffULL) { if ((start+num-1) & ~0xffffffffULL) {
ext2fs_warn_bitmap2(bmap, EXT2FS_UNMARK_ERROR, ext2fs_warn_bitmap2(bmap, EXT2FS_UNMARK_ERROR,
0xffffffff); 0xffffffff);
return EINVAL; return EINVAL;
@ -406,7 +416,7 @@ errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap,
return EINVAL; return EINVAL;
if (EXT2FS_IS_32_BITMAP(bmap)) { if (EXT2FS_IS_32_BITMAP(bmap)) {
if ((start+num) & ~0xffffffffULL) { if ((start+num-1) & ~0xffffffffULL) {
ext2fs_warn_bitmap2(bmap, ext2fs_warn_bitmap2(bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff); EXT2FS_UNMARK_ERROR, 0xffffffff);
return EINVAL; return EINVAL;
@ -477,7 +487,7 @@ int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap,
bmap, block); bmap, block);
if (EXT2FS_IS_32_BITMAP(bmap)) { if (EXT2FS_IS_32_BITMAP(bmap)) {
if ((block+num) & ~0xffffffffULL) { if ((block+num-1) & ~0xffffffffULL) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap, ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff); EXT2FS_UNMARK_ERROR, 0xffffffff);
return EINVAL; return EINVAL;
@ -499,7 +509,7 @@ void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap,
return; return;
if (EXT2FS_IS_32_BITMAP(bmap)) { if (EXT2FS_IS_32_BITMAP(bmap)) {
if ((block+num) & ~0xffffffffULL) { if ((block+num-1) & ~0xffffffffULL) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap, ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff); EXT2FS_UNMARK_ERROR, 0xffffffff);
return; return;
@ -527,7 +537,7 @@ void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap,
return; return;
if (EXT2FS_IS_32_BITMAP(bmap)) { if (EXT2FS_IS_32_BITMAP(bmap)) {
if ((block+num) & ~0xffffffffULL) { if ((block+num-1) & ~0xffffffffULL) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap, ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff); EXT2FS_UNMARK_ERROR, 0xffffffff);
return; return;
@ -548,7 +558,7 @@ void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap,
bmap->bitmap_ops->unmark_bmap_extent(bmap, block, num); bmap->bitmap_ops->unmark_bmap_extent(bmap, block, num);
} }
int ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func) void ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func)
{ {
#ifndef OMIT_COM_ERR #ifndef OMIT_COM_ERR
if (bitmap && bitmap->description) if (bitmap && bitmap->description)
@ -559,5 +569,47 @@ int ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func)
com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
"called %s with 64-bit bitmap", func); "called %s with 64-bit bitmap", func);
#endif #endif
}
errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
ext2fs_block_bitmap *bitmap)
{
ext2fs_block_bitmap cmap, bmap;
errcode_t retval;
blk64_t i, b_end, c_end;
int n, ratio;
bmap = *bitmap;
if (fs->cluster_ratio_bits == ext2fs_get_bitmap_granularity(bmap))
return 0; /* Nothing to do */
retval = ext2fs_allocate_block_bitmap(fs, "converted cluster bitmap",
&cmap);
if (retval)
return retval;
i = bmap->start;
b_end = bmap->end;
bmap->end = bmap->real_end;
c_end = cmap->end;
cmap->end = cmap->real_end;
n = 0;
ratio = 1 << fs->cluster_ratio_bits;
while (i < bmap->real_end) {
if (ext2fs_test_block_bitmap2(bmap, i)) {
ext2fs_mark_block_bitmap2(cmap, i);
i += ratio - n;
n = 0;
continue;
}
i++; n++;
if (n >= ratio)
n = 0;
}
bmap->end = b_end;
cmap->end = c_end;
ext2fs_free_block_bitmap(bmap);
*bitmap = cmap;
return 0; return 0;
} }

View File

@ -21,6 +21,7 @@
* *
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -13,6 +13,7 @@
#define _LARGEFILE_SOURCE #define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -45,11 +46,7 @@ errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize)
{ {
int fd; int fd;
#ifdef HAVE_OPEN64 fd = ext2fs_open_file(file, O_RDONLY, 0);
fd = open64(file, O_RDONLY);
#else
fd = open(file, O_RDONLY);
#endif
if (fd < 0) if (fd < 0)
return errno; return errno;
@ -71,11 +68,7 @@ errcode_t ext2fs_get_device_phys_sectsize(const char *file, int *sectsize)
{ {
int fd; int fd;
#ifdef HAVE_OPEN64 fd = ext2fs_open_file(file, O_RDONLY, 0);
fd = open64(file, O_RDONLY);
#else
fd = open(file, O_RDONLY);
#endif
if (fd < 0) if (fd < 0)
return errno; return errno;

View File

@ -15,6 +15,7 @@
#define _LARGEFILE_SOURCE #define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -142,10 +143,12 @@ errcode_t ext2fs_get_device_size2(const char *file, int blocksize,
blk64_t *retblocks) blk64_t *retblocks)
{ {
int fd, rc = 0; int fd, rc = 0;
int valid_blkgetsize64 = 1;
#ifdef __linux__ #ifdef __linux__
struct utsname ut; struct utsname ut;
#endif #endif
unsigned long long size64; unsigned long long size64;
unsigned long size;
ext2_loff_t high, low; ext2_loff_t high, low;
#ifdef FDGETPRM #ifdef FDGETPRM
struct floppy_struct this_floppy; struct floppy_struct this_floppy;
@ -157,11 +160,7 @@ errcode_t ext2fs_get_device_size2(const char *file, int blocksize,
char ch; char ch;
#endif /* HAVE_SYS_DISKLABEL_H */ #endif /* HAVE_SYS_DISKLABEL_H */
#ifdef HAVE_OPEN64 fd = ext2fs_open_file(file, O_RDONLY, 0);
fd = open64(file, O_RDONLY);
#else
fd = open(file, O_RDONLY);
#endif
if (fd < 0) if (fd < 0)
return errno; return errno;
@ -233,13 +232,9 @@ errcode_t ext2fs_get_device_size2(const char *file, int blocksize,
#endif /* HAVE_SYS_DISKLABEL_H */ #endif /* HAVE_SYS_DISKLABEL_H */
{ {
#ifdef HAVE_FSTAT64 ext2fs_struct_stat st;
struct stat64 st;
if (fstat64(fd, &st) == 0) if (ext2fs_fstat(fd, &st) == 0)
#else
struct stat st;
if (fstat(fd, &st) == 0)
#endif
if (S_ISREG(st.st_mode)) { if (S_ISREG(st.st_mode)) {
*retblocks = st.st_size / blocksize; *retblocks = st.st_size / blocksize;
goto out; goto out;

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -38,6 +39,7 @@ errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode,
EXT4_FEATURE_RO_COMPAT_HUGE_FILE) || EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
!(inode->i_flags & EXT4_HUGE_FILE_FL)) !(inode->i_flags & EXT4_HUGE_FILE_FL))
num_blocks *= fs->blocksize / 512; num_blocks *= fs->blocksize / 512;
num_blocks *= EXT2FS_CLUSTER_RATIO(fs);
b += num_blocks; b += num_blocks;
@ -61,6 +63,7 @@ errcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode,
EXT4_FEATURE_RO_COMPAT_HUGE_FILE) || EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
!(inode->i_flags & EXT4_HUGE_FILE_FL)) !(inode->i_flags & EXT4_HUGE_FILE_FL))
num_blocks *= fs->blocksize / 512; num_blocks *= fs->blocksize / 512;
num_blocks *= EXT2FS_CLUSTER_RATIO(fs);
if (num_blocks > b) if (num_blocks > b)
return EOVERFLOW; return EOVERFLOW;
@ -79,6 +82,7 @@ errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b)
EXT4_FEATURE_RO_COMPAT_HUGE_FILE) || EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
!(inode->i_flags & EXT4_HUGE_FILE_FL)) !(inode->i_flags & EXT4_HUGE_FILE_FL))
b *= fs->blocksize / 512; b *= fs->blocksize / 512;
b *= EXT2FS_CLUSTER_RATIO(fs);
inode->i_blocks = b & 0xFFFFFFFF; inode->i_blocks = b & 0xFFFFFFFF;
if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE)

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -363,31 +364,7 @@ static struct ext2_icount_el *get_icount_el(ext2_icount_t icount,
low = 0; low = 0;
high = (int) icount->count-1; high = (int) icount->count-1;
while (low <= high) { while (low <= high) {
#if 0 mid = ((unsigned)low + (unsigned)high) >> 1;
mid = (low+high)/2;
#else
if (low == high)
mid = low;
else {
/* Interpolate for efficiency */
lowval = icount->list[low].ino;
highval = icount->list[high].ino;
if (ino < lowval)
range = 0;
else if (ino > highval)
range = 1;
else {
range = ((float) (ino - lowval)) /
(highval - lowval);
if (range > 0.9)
range = 0.9;
if (range < 0.1)
range = 0.1;
}
mid = low + ((int) (range * (high-low)));
}
#endif
if (ino == icount->list[mid].ino) { if (ino == icount->list[mid].ino) {
icount->cursor = mid+1; icount->cursor = mid+1;
return &icount->list[mid]; return &icount->list[mid];

View File

@ -13,6 +13,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -91,9 +92,11 @@ errcode_t ext2fs_initialize(const char *name, int flags,
unsigned int overhead = 0; unsigned int overhead = 0;
unsigned int ipg; unsigned int ipg;
dgrp_t i; dgrp_t i;
blk64_t free_blocks;
blk_t numblocks; blk_t numblocks;
int rsv_gdt; int rsv_gdt;
int csum_flag; int csum_flag;
int bigalloc_flag;
int io_flags; int io_flags;
char *buf = 0; char *buf = 0;
char c; char c;
@ -134,13 +137,26 @@ errcode_t ext2fs_initialize(const char *name, int flags,
#define set_field(field, default) (super->field = param->field ? \ #define set_field(field, default) (super->field = param->field ? \
param->field : (default)) param->field : (default))
#define assign_field(field) (super->field = param->field)
super->s_magic = EXT2_SUPER_MAGIC; super->s_magic = EXT2_SUPER_MAGIC;
super->s_state = EXT2_VALID_FS; super->s_state = EXT2_VALID_FS;
set_field(s_log_block_size, 0); /* default blocksize: 1024 bytes */ bigalloc_flag = EXT2_HAS_RO_COMPAT_FEATURE(param,
set_field(s_log_cluster_size, 0); EXT4_FEATURE_RO_COMPAT_BIGALLOC);
set_field(s_first_data_block, super->s_log_block_size ? 0 : 1);
assign_field(s_log_block_size);
if (bigalloc_flag) {
set_field(s_log_cluster_size, super->s_log_block_size+4);
if (super->s_log_block_size > super->s_log_cluster_size) {
retval = EXT2_ET_INVALID_ARGUMENT;
goto cleanup;
}
} else
super->s_log_cluster_size = super->s_log_block_size;
set_field(s_first_data_block, super->s_log_cluster_size ? 0 : 1);
set_field(s_max_mnt_count, 0); set_field(s_max_mnt_count, 0);
set_field(s_errors, EXT2_ERRORS_DEFAULT); set_field(s_errors, EXT2_ERRORS_DEFAULT);
set_field(s_feature_compat, 0); set_field(s_feature_compat, 0);
@ -181,16 +197,39 @@ errcode_t ext2fs_initialize(const char *name, int flags,
super->s_creator_os = CREATOR_OS; super->s_creator_os = CREATOR_OS;
fs->blocksize = EXT2_BLOCK_SIZE(super); fs->fragsize = fs->blocksize = EXT2_BLOCK_SIZE(super);
fs->clustersize = EXT2_CLUSTER_SIZE(super); fs->cluster_ratio_bits = super->s_log_cluster_size -
super->s_log_block_size;
/* default: (fs->blocksize*8) blocks/group, up to 2^16 (GDT limit) */ if (bigalloc_flag) {
if (param->s_blocks_per_group &&
param->s_clusters_per_group &&
((param->s_clusters_per_group * EXT2FS_CLUSTER_RATIO(fs)) !=
param->s_blocks_per_group)) {
retval = EXT2_ET_INVALID_ARGUMENT;
goto cleanup;
}
if (param->s_clusters_per_group)
assign_field(s_clusters_per_group);
else if (param->s_blocks_per_group)
super->s_clusters_per_group =
param->s_blocks_per_group /
EXT2FS_CLUSTER_RATIO(fs);
else
super->s_clusters_per_group = fs->blocksize * 8;
if (super->s_clusters_per_group > EXT2_MAX_CLUSTERS_PER_GROUP(super))
super->s_clusters_per_group = EXT2_MAX_CLUSTERS_PER_GROUP(super);
super->s_blocks_per_group = EXT2FS_C2B(fs,
super->s_clusters_per_group);
} else {
set_field(s_blocks_per_group, fs->blocksize * 8); set_field(s_blocks_per_group, fs->blocksize * 8);
if (super->s_blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(super)) if (super->s_blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(super))
super->s_blocks_per_group = EXT2_MAX_BLOCKS_PER_GROUP(super); super->s_blocks_per_group = EXT2_MAX_BLOCKS_PER_GROUP(super);
super->s_clusters_per_group = super->s_blocks_per_group; super->s_clusters_per_group = super->s_blocks_per_group;
}
ext2fs_blocks_count_set(super, ext2fs_blocks_count(param)); ext2fs_blocks_count_set(super, ext2fs_blocks_count(param) &
~((blk64_t) EXT2FS_CLUSTER_MASK(fs)));
ext2fs_r_blocks_count_set(super, ext2fs_r_blocks_count(param)); ext2fs_r_blocks_count_set(super, ext2fs_r_blocks_count(param));
if (ext2fs_r_blocks_count(super) >= ext2fs_blocks_count(param)) { if (ext2fs_r_blocks_count(super) >= ext2fs_blocks_count(param)) {
retval = EXT2_ET_INVALID_ARGUMENT; retval = EXT2_ET_INVALID_ARGUMENT;
@ -209,7 +248,7 @@ errcode_t ext2fs_initialize(const char *name, int flags,
} }
retry: retry:
fs->group_desc_count = (blk_t) ext2fs_div64_ceil( fs->group_desc_count = (dgrp_t) ext2fs_div64_ceil(
ext2fs_blocks_count(super) - super->s_first_data_block, ext2fs_blocks_count(super) - super->s_first_data_block,
EXT2_BLOCKS_PER_GROUP(super)); EXT2_BLOCKS_PER_GROUP(super));
if (fs->group_desc_count == 0) { if (fs->group_desc_count == 0) {
@ -246,7 +285,7 @@ retry:
*/ */
ipg = ext2fs_div_ceil(super->s_inodes_count, fs->group_desc_count); ipg = ext2fs_div_ceil(super->s_inodes_count, fs->group_desc_count);
if (ipg > fs->blocksize * 8) { if (ipg > fs->blocksize * 8) {
if (super->s_blocks_per_group >= 256) { if (!bigalloc_flag && super->s_blocks_per_group >= 256) {
/* Try again with slightly different parameters */ /* Try again with slightly different parameters */
super->s_blocks_per_group -= 8; super->s_blocks_per_group -= 8;
ext2fs_blocks_count_set(super, ext2fs_blocks_count_set(super,
@ -364,7 +403,7 @@ ipg_retry:
strcpy(buf, "block bitmap for "); strcpy(buf, "block bitmap for ");
strcat(buf, fs->device_name); strcat(buf, fs->device_name);
retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->block_map); retval = ext2fs_allocate_subcluster_bitmap(fs, buf, &fs->block_map);
if (retval) if (retval)
goto cleanup; goto cleanup;
@ -394,7 +433,7 @@ ipg_retry:
* superblock and group descriptors (the inode tables and * superblock and group descriptors (the inode tables and
* bitmaps will be accounted for when allocated). * bitmaps will be accounted for when allocated).
*/ */
ext2fs_free_blocks_count_set(super, 0); free_blocks = 0;
csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super, csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_GDT_CSUM); EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
for (i = 0; i < fs->group_desc_count; i++) { for (i = 0; i < fs->group_desc_count; i++) {
@ -416,14 +455,14 @@ ipg_retry:
if (fs->super->s_log_groups_per_flex) if (fs->super->s_log_groups_per_flex)
numblocks += 2 + fs->inode_blocks_per_group; numblocks += 2 + fs->inode_blocks_per_group;
ext2fs_free_blocks_count_set(super, free_blocks += numblocks;
ext2fs_free_blocks_count(super) +
numblocks);
ext2fs_bg_free_blocks_count_set(fs, i, numblocks); ext2fs_bg_free_blocks_count_set(fs, i, numblocks);
ext2fs_bg_free_inodes_count_set(fs, i, fs->super->s_inodes_per_group); ext2fs_bg_free_inodes_count_set(fs, i, fs->super->s_inodes_per_group);
ext2fs_bg_used_dirs_count_set(fs, i, 0); ext2fs_bg_used_dirs_count_set(fs, i, 0);
ext2fs_group_desc_csum_set(fs, i); ext2fs_group_desc_csum_set(fs, i);
} }
free_blocks &= ~EXT2FS_CLUSTER_MASK(fs);
ext2fs_free_blocks_count_set(super, free_blocks);
c = (char) 255; c = (char) 255;
if (((int) c) == -1) { if (((int) c) == -1) {

View File

@ -12,6 +12,7 @@
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -30,3 +31,42 @@
#define INCLUDE_INLINE_FUNCS #define INCLUDE_INLINE_FUNCS
#include "ext2fs.h" #include "ext2fs.h"
#include "mem_allocate.h"
/*
* We used to define this as an inline, but since we are now using
* autoconf-defined #ifdef's, we need to export this as a
* library-provided function exclusively.
*/
errcode_t ext2fs_get_memalign(unsigned long size,
unsigned long align, void *ptr)
{
errcode_t retval;
if (align == 0)
align = 8;
#ifdef HAVE_POSIX_MEMALIGN
retval = posix_memalign((void **) ptr, align, size);
if (retval) {
if (retval == ENOMEM)
return EXT2_ET_NO_MEMORY;
return retval;
}
#else
#ifdef HAVE_MEMALIGN
void *pp;
pp = mem_align(align, size);
if (pp == NULL) {
if (errno)
return errno;
else
return EXT2_ET_NO_MEMORY;
}
memcpy(ptr, &pp, sizeof (pp));
#else
#error memalign or posix_memalign must be defined!
#endif
#endif
return 0;
}

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -522,7 +523,8 @@ errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino, errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode * inode, int bufsize) struct ext2_inode * inode, int bufsize)
{ {
unsigned long group, block, block_nr, offset; blk64_t block_nr;
unsigned long group, block, offset;
char *ptr; char *ptr;
errcode_t retval; errcode_t retval;
int clen, i, inodes_per_block, length; int clen, i, inodes_per_block, length;
@ -628,7 +630,8 @@ errcode_t ext2fs_read_inode(ext2_filsys fs, ext2_ino_t ino,
errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino, errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode * inode, int bufsize) struct ext2_inode * inode, int bufsize)
{ {
unsigned long group, block, block_nr, offset; blk64_t block_nr;
unsigned long group, block, offset;
errcode_t retval = 0; errcode_t retval = 0;
struct ext2_inode_large temp_inode, *w_inode; struct ext2_inode_large temp_inode, *w_inode;
char *ptr; char *ptr;
@ -669,8 +672,10 @@ errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
if (length > (int) sizeof(struct ext2_inode_large)) { if (length > (int) sizeof(struct ext2_inode_large)) {
w_inode = malloc(length); w_inode = malloc(length);
if (!w_inode) if (!w_inode) {
return ENOMEM; retval = ENOMEM;
goto errout;
}
} else } else
w_inode = &temp_inode; w_inode = &temp_inode;
memset(w_inode, 0, length); memset(w_inode, 0, length);

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -163,7 +164,7 @@ static errcode_t inode_open(const char *name, int flags, io_channel *channel)
return 0; return 0;
cleanup: cleanup:
if (io->name) if (io && io->name)
ext2fs_free_mem(&io->name); ext2fs_free_mem(&io->name);
if (data) if (data)
ext2fs_free_mem(&data); ext2fs_free_mem(&data);

View File

@ -2,6 +2,7 @@
* io_manager.c --- the I/O manager abstraction * io_manager.c --- the I/O manager abstraction
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -52,9 +53,9 @@ static int link_proc(struct ext2_dir_entry *dirent,
* if so, absorb it into this one. * if so, absorb it into this one.
*/ */
next = (struct ext2_dir_entry *) (buf + offset + curr_rec_len); next = (struct ext2_dir_entry *) (buf + offset + curr_rec_len);
if ((offset + curr_rec_len < blocksize - 8) && if ((offset + (int) curr_rec_len < blocksize - 8) &&
(next->inode == 0) && (next->inode == 0) &&
(offset + curr_rec_len + next->rec_len <= blocksize)) { (offset + (int) curr_rec_len + (int) next->rec_len <= blocksize)) {
curr_rec_len += next->rec_len; curr_rec_len += next->rec_len;
ls->err = ext2fs_set_rec_len(ls->fs, curr_rec_len, dirent); ls->err = ext2fs_set_rec_len(ls->fs, curr_rec_len, dirent);
if (ls->err) if (ls->err)

View File

@ -12,6 +12,7 @@
#define _LARGEFILE_SOURCE #define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE
#include "config.h"
#if HAVE_SYS_TYPES_H #if HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif #endif

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -8,6 +8,14 @@ extern __inline__ void* mem_alloc (size_t size) {
return MEM2_alloc(size); return MEM2_alloc(size);
} }
extern __inline__ void* mem_calloc (size_t count, size_t size) {
void *p = MEM2_alloc(count * size);
if(p) {
memset(p, 0, count * size);
}
return p;
}
extern __inline__ void* mem_realloc (void *p, size_t size) { extern __inline__ void* mem_realloc (void *p, size_t size) {
return MEM2_realloc(p, size); return MEM2_realloc(p, size);
} }

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -33,6 +34,7 @@
errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum, errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
const char *name) const char *name)
{ {
ext2_extent_handle_t handle;
errcode_t retval; errcode_t retval;
struct ext2_inode parent_inode, inode; struct ext2_inode parent_inode, inode;
ext2_ino_t ino = inum; ext2_ino_t ino = inum;
@ -83,7 +85,9 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask); inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask);
inode.i_uid = inode.i_gid = 0; inode.i_uid = inode.i_gid = 0;
ext2fs_iblk_set(fs, &inode, 1); ext2fs_iblk_set(fs, &inode, 1);
/* FIXME-64 */ if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS)
inode.i_flags |= EXT4_EXTENTS_FL;
else
inode.i_block[0] = blk; inode.i_block[0] = blk;
inode.i_links_count = 2; inode.i_links_count = 2;
inode.i_size = fs->blocksize; inode.i_size = fs->blocksize;
@ -98,6 +102,16 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
if (retval) if (retval)
goto cleanup; goto cleanup;
if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) {
retval = ext2fs_extent_open2(fs, ino, &inode, &handle);
if (retval)
goto cleanup;
retval = ext2fs_extent_set_bmap(handle, 0, blk, 0);
ext2fs_extent_free(handle);
if (retval)
goto cleanup;
}
/* /*
* Link the directory into the filesystem hierarchy * Link the directory into the filesystem hierarchy
*/ */

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -44,13 +45,13 @@
* returns it as an allocated block. * returns it as an allocated block.
*/ */
errcode_t ext2fs_create_journal_superblock(ext2_filsys fs, errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
__u32 size, int flags, __u32 num_blocks, int flags,
char **ret_jsb) char **ret_jsb)
{ {
errcode_t retval; errcode_t retval;
journal_superblock_t *jsb; journal_superblock_t *jsb;
if (size < 1024) if (num_blocks < 1024)
return EXT2_ET_JOURNAL_TOO_SMALL; return EXT2_ET_JOURNAL_TOO_SMALL;
if ((retval = ext2fs_get_mem(fs->blocksize, &jsb))) if ((retval = ext2fs_get_mem(fs->blocksize, &jsb)))
@ -64,7 +65,7 @@ errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
else else
jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2); jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
jsb->s_blocksize = htonl(fs->blocksize); jsb->s_blocksize = htonl(fs->blocksize);
jsb->s_maxlen = htonl(size); jsb->s_maxlen = htonl(num_blocks);
jsb->s_nr_users = htonl(1); jsb->s_nr_users = htonl(1);
jsb->s_first = htonl(1); jsb->s_first = htonl(1);
jsb->s_sequence = htonl(1); jsb->s_sequence = htonl(1);
@ -92,20 +93,21 @@ errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
* filesystems. * filesystems.
*/ */
static errcode_t write_journal_file(ext2_filsys fs, char *filename, static errcode_t write_journal_file(ext2_filsys fs, char *filename,
blk_t size, int flags) blk_t num_blocks, int flags)
{ {
errcode_t retval; errcode_t retval;
char *buf = 0; char *buf = 0;
int fd, ret_size; int fd, ret_size;
blk_t i; blk_t i;
if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf))) if ((retval = ext2fs_create_journal_superblock(fs, num_blocks, flags,
&buf)))
return retval; return retval;
/* Open the device or journal file */ /* Open the device or journal file */
if ((fd = open(filename, O_WRONLY)) < 0) { if ((fd = open(filename, O_WRONLY)) < 0) {
retval = errno; retval = errno;
goto errout; goto errfree;
} }
/* Write the superblock out */ /* Write the superblock out */
@ -119,7 +121,10 @@ static errcode_t write_journal_file(ext2_filsys fs, char *filename,
goto errout; goto errout;
memset(buf, 0, fs->blocksize); memset(buf, 0, fs->blocksize);
for (i = 1; i < size; i++) { if (flags & EXT2_MKJOURNAL_LAZYINIT)
goto success;
for (i = 1; i < num_blocks; i++) {
ret_size = write(fd, buf, fs->blocksize); ret_size = write(fd, buf, fs->blocksize);
if (ret_size < 0) { if (ret_size < 0) {
retval = errno; retval = errno;
@ -128,10 +133,12 @@ static errcode_t write_journal_file(ext2_filsys fs, char *filename,
if (ret_size != (int) fs->blocksize) if (ret_size != (int) fs->blocksize)
goto errout; goto errout;
} }
close(fd);
success:
retval = 0; retval = 0;
errout: errout:
close(fd);
errfree:
ext2fs_free_mem(&buf); ext2fs_free_mem(&buf);
return retval; return retval;
} }
@ -215,6 +222,7 @@ struct mkjournal_struct {
blk64_t goal; blk64_t goal;
blk64_t blk_to_zero; blk64_t blk_to_zero;
int zero_count; int zero_count;
int flags;
char *buf; char *buf;
errcode_t err; errcode_t err;
}; };
@ -234,19 +242,25 @@ static int mkjournal_proc(ext2_filsys fs,
es->goal = *blocknr; es->goal = *blocknr;
return 0; return 0;
} }
if (blockcnt &&
(EXT2FS_B2C(fs, es->goal) == EXT2FS_B2C(fs, es->goal+1)))
new_blk = es->goal+1;
else {
es->goal &= ~EXT2FS_CLUSTER_MASK(fs);
retval = ext2fs_new_block2(fs, es->goal, 0, &new_blk); retval = ext2fs_new_block2(fs, es->goal, 0, &new_blk);
if (retval) { if (retval) {
es->err = retval; es->err = retval;
return BLOCK_ABORT; return BLOCK_ABORT;
} }
es->newblocks++;
}
if (blockcnt >= 0) if (blockcnt >= 0)
es->num_blocks--; es->num_blocks--;
es->newblocks++;
retval = 0; retval = 0;
if (blockcnt <= 0) if (blockcnt <= 0)
retval = io_channel_write_blk64(fs->io, new_blk, 1, es->buf); retval = io_channel_write_blk64(fs->io, new_blk, 1, es->buf);
else { else if (!(es->flags & EXT2_MKJOURNAL_LAZYINIT)) {
if (es->zero_count) { if (es->zero_count) {
if ((es->blk_to_zero + es->zero_count == new_blk) && if ((es->blk_to_zero + es->zero_count == new_blk) &&
(es->zero_count < 1024)) (es->zero_count < 1024))
@ -286,15 +300,17 @@ static int mkjournal_proc(ext2_filsys fs,
* This function creates a journal using direct I/O routines. * This function creates a journal using direct I/O routines.
*/ */
static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino, static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
blk64_t size, int flags) blk_t num_blocks, int flags)
{ {
char *buf; char *buf;
dgrp_t group, start, end, i, log_flex; dgrp_t group, start, end, i, log_flex;
errcode_t retval; errcode_t retval;
struct ext2_inode inode; struct ext2_inode inode;
unsigned long long inode_size;
struct mkjournal_struct es; struct mkjournal_struct es;
if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf))) if ((retval = ext2fs_create_journal_superblock(fs, num_blocks, flags,
&buf)))
return retval; return retval;
if ((retval = ext2fs_read_bitmaps(fs))) if ((retval = ext2fs_read_bitmaps(fs)))
@ -306,10 +322,11 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
if (inode.i_blocks > 0) if (inode.i_blocks > 0)
return EEXIST; return EEXIST;
es.num_blocks = size; es.num_blocks = num_blocks;
es.newblocks = 0; es.newblocks = 0;
es.buf = buf; es.buf = buf;
es.err = 0; es.err = 0;
es.flags = flags;
es.zero_count = 0; es.zero_count = 0;
if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) { if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) {
@ -362,7 +379,12 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
if ((retval = ext2fs_read_inode(fs, journal_ino, &inode))) if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
goto errout; goto errout;
inode.i_size += fs->blocksize * size; inode_size = (unsigned long long)fs->blocksize * num_blocks;
inode.i_size = inode_size & 0xFFFFFFFF;
inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
if (inode.i_size_high)
fs->super->s_feature_ro_compat |=
EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
ext2fs_iblk_add_blocks(fs, &inode, es.newblocks); ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0); inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
inode.i_links_count = 1; inode.i_links_count = 1;
@ -373,6 +395,7 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
retval = 0; retval = 0;
memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4); memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4);
fs->super->s_jnl_blocks[15] = inode.i_size_high;
fs->super->s_jnl_blocks[16] = inode.i_size; fs->super->s_jnl_blocks[16] = inode.i_size;
fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS; fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
ext2fs_mark_super_dirty(fs); ext2fs_mark_super_dirty(fs);
@ -388,17 +411,17 @@ errout:
* in the filesystem. For very small filesystems, it is not reasonable to * in the filesystem. For very small filesystems, it is not reasonable to
* have a journal that fills more than half of the filesystem. * have a journal that fills more than half of the filesystem.
*/ */
int ext2fs_default_journal_size(__u64 blocks) int ext2fs_default_journal_size(__u64 num_blocks)
{ {
if (blocks < 2048) if (num_blocks < 2048)
return -1; return -1;
if (blocks < 32768) if (num_blocks < 32768)
return (1024); return (1024);
if (blocks < 256*1024) if (num_blocks < 256*1024)
return (4096); return (4096);
if (blocks < 512*1024) if (num_blocks < 512*1024)
return (8192); return (8192);
if (blocks < 1024*1024) if (num_blocks < 1024*1024)
return (16384); return (16384);
return 32768; return 32768;
} }
@ -469,13 +492,13 @@ errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev)
* POSIX routines if the filesystem is mounted, or using direct I/O * POSIX routines if the filesystem is mounted, or using direct I/O
* functions if it is not. * functions if it is not.
*/ */
errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size, int flags) errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks, int flags)
{ {
errcode_t retval; errcode_t retval;
ext2_ino_t journal_ino; ext2_ino_t journal_ino;
struct stat st; struct stat st;
char jfile[1024]; char jfile[1024];
int mount_flags; int mount_flags, f;
int fd = -1; int fd = -1;
if ((retval = ext2fs_check_mount_point(fs->device_name, &mount_flags, if ((retval = ext2fs_check_mount_point(fs->device_name, &mount_flags,
@ -506,7 +529,14 @@ errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size, int flags)
if ((fd = open(jfile, O_CREAT|O_WRONLY, 0600)) < 0) if ((fd = open(jfile, O_CREAT|O_WRONLY, 0600)) < 0)
return errno; return errno;
if ((retval = write_journal_file(fs, jfile, size, flags))) /* Note that we can't do lazy journal initialization for mounted
* filesystems, since the zero writing is also allocating the
* journal blocks. We could use fallocate, but not all kernels
* support that, and creating a journal on a mounted ext2
* filesystems is extremely rare these days... Ignore it. */
flags &= ~EXT2_MKJOURNAL_LAZYINIT;
if ((retval = write_journal_file(fs, jfile, num_blocks, flags)))
goto errout; goto errout;
/* Get inode number of the journal file */ /* Get inode number of the journal file */
@ -546,7 +576,7 @@ errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size, int flags)
} }
journal_ino = EXT2_JOURNAL_INO; journal_ino = EXT2_JOURNAL_INO;
if ((retval = write_journal_inode(fs, journal_ino, if ((retval = write_journal_inode(fs, journal_ino,
size, flags))) num_blocks, flags)))
return retval; return retval;
} }

View File

@ -0,0 +1,417 @@
/*
* Helper functions for multiple mount protection (MMP).
*
* Copyright (C) 2011 Whamcloud, Inc.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Public
* License.
* %End-Header%
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "config.h"
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "ext2_fs.h"
#include "ext2fs.h"
#undef _SC_PAGESIZE
static int mmp_pagesize(void)
{
#ifdef _SC_PAGESIZE
int sysval = sysconf(_SC_PAGESIZE);
if (sysval > 0)
return sysval;
#endif /* _SC_PAGESIZE */
#ifdef HAVE_GETPAGESIZE
return getpagesize();
#else
return 4096;
#endif
}
#ifndef O_DIRECT
#define O_DIRECT 0
#endif
errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf)
{
struct mmp_struct *mmp_cmp;
errcode_t retval = 0;
if ((mmp_blk <= fs->super->s_first_data_block) ||
(mmp_blk >= fs->super->s_blocks_count))
return EXT2_ET_MMP_BAD_BLOCK;
if (fs->mmp_cmp == NULL) {
/* O_DIRECT in linux 2.4: page aligned
* O_DIRECT in linux 2.6: sector aligned
* A filesystem cannot be created with blocksize < sector size,
* or with blocksize > page_size. */
int bufsize = fs->blocksize;
if (bufsize < mmp_pagesize())
bufsize = mmp_pagesize();
retval = ext2fs_get_memalign(bufsize, bufsize, &fs->mmp_cmp);
if (retval)
return retval;
}
/* ext2fs_open() reserves fd0,1,2 to avoid stdio collision, so checking
* mmp_fd <= 0 is OK to validate that the fd is valid. This opens its
* own fd to read the MMP block to ensure that it is using O_DIRECT,
* regardless of how the io_manager is doing reads, to avoid caching of
* the MMP block by the io_manager or the VM. It needs to be fresh. */
if (fs->mmp_fd <= 0) {
fs->mmp_fd = open(fs->device_name, O_RDWR | O_DIRECT);
if (fs->mmp_fd < 0) {
retval = EXT2_ET_MMP_OPEN_DIRECT;
goto out;
}
}
if (ext2fs_llseek(fs->mmp_fd, mmp_blk * fs->blocksize, SEEK_SET) !=
mmp_blk * fs->blocksize) {
retval = EXT2_ET_LLSEEK_FAILED;
goto out;
}
if (read(fs->mmp_fd, fs->mmp_cmp, fs->blocksize) != fs->blocksize) {
retval = EXT2_ET_SHORT_READ;
goto out;
}
mmp_cmp = fs->mmp_cmp;
#ifdef WORDS_BIGENDIAN
ext2fs_swap_mmp(mmp_cmp);
#endif
if (buf != NULL && buf != fs->mmp_cmp)
memcpy(buf, fs->mmp_cmp, fs->blocksize);
if (mmp_cmp->mmp_magic != EXT4_MMP_MAGIC) {
retval = EXT2_ET_MMP_MAGIC_INVALID;
goto out;
}
out:
return retval;
}
errcode_t ext2fs_mmp_write(ext2_filsys fs, blk64_t mmp_blk, void *buf)
{
struct mmp_struct *mmp_s = buf;
struct timeval tv;
errcode_t retval = 0;
gettimeofday(&tv, 0);
mmp_s->mmp_time = tv.tv_sec;
fs->mmp_last_written = tv.tv_sec;
if (fs->super->s_mmp_block < fs->super->s_first_data_block ||
fs->super->s_mmp_block > ext2fs_blocks_count(fs->super))
return EXT2_ET_MMP_BAD_BLOCK;
#ifdef WORDS_BIGENDIAN
ext2fs_swap_mmp(mmp_s);
#endif
/* I was tempted to make this use O_DIRECT and the mmp_fd, but
* this caused no end of grief, while leaving it as-is works. */
retval = io_channel_write_blk64(fs->io, mmp_blk, -fs->blocksize, buf);
#ifdef WORDS_BIGENDIAN
ext2fs_swap_mmp(mmp_s);
#endif
/* Make sure the block gets to disk quickly */
io_channel_flush(fs->io);
return retval;
}
#ifdef HAVE_SRANDOM
#define srand(x) srandom(x)
#define rand() random()
#endif
unsigned ext2fs_mmp_new_seq()
{
unsigned new_seq;
struct timeval tv;
gettimeofday(&tv, 0);
srand((getpid() << 16) /*^ getuid()*/ ^ tv.tv_sec ^ tv.tv_usec);
gettimeofday(&tv, 0);
/* Crank the random number generator a few times */
for (new_seq = (tv.tv_sec ^ tv.tv_usec) & 0x1F; new_seq > 0; new_seq--)
rand();
do {
new_seq = rand();
} while (new_seq > EXT4_MMP_SEQ_MAX);
return new_seq;
}
static errcode_t ext2fs_mmp_reset(ext2_filsys fs)
{
struct mmp_struct *mmp_s = NULL;
errcode_t retval = 0;
if (fs->mmp_buf == NULL) {
retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf);
if (retval)
goto out;
}
memset(fs->mmp_buf, 0, fs->blocksize);
mmp_s = fs->mmp_buf;
mmp_s->mmp_magic = EXT4_MMP_MAGIC;
mmp_s->mmp_seq = EXT4_MMP_SEQ_CLEAN;
mmp_s->mmp_time = 0;
#if (0 && (_BSD_SOURCE || _XOPEN_SOURCE >= 500))
gethostname(mmp_s->mmp_nodename, sizeof(mmp_s->mmp_nodename));
#else
mmp_s->mmp_nodename[0] = '\0';
#endif
strncpy(mmp_s->mmp_bdevname, fs->device_name,
sizeof(mmp_s->mmp_bdevname));
mmp_s->mmp_check_interval = fs->super->s_mmp_update_interval;
if (mmp_s->mmp_check_interval < EXT4_MMP_MIN_CHECK_INTERVAL)
mmp_s->mmp_check_interval = EXT4_MMP_MIN_CHECK_INTERVAL;
retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf);
out:
return retval;
}
errcode_t ext2fs_mmp_clear(ext2_filsys fs)
{
errcode_t retval = 0;
if (!(fs->flags & EXT2_FLAG_RW))
return EXT2_ET_RO_FILSYS;
retval = ext2fs_mmp_reset(fs);
return retval;
}
errcode_t ext2fs_mmp_init(ext2_filsys fs)
{
struct ext2_super_block *sb = fs->super;
blk64_t mmp_block;
errcode_t retval;
if (sb->s_mmp_update_interval == 0)
sb->s_mmp_update_interval = EXT4_MMP_UPDATE_INTERVAL;
/* This is probably excessively large, but who knows? */
else if (sb->s_mmp_update_interval > EXT4_MMP_MAX_UPDATE_INTERVAL)
return EXT2_ET_INVALID_ARGUMENT;
if (fs->mmp_buf == NULL) {
retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf);
if (retval)
goto out;
}
retval = ext2fs_alloc_block2(fs, 0, fs->mmp_buf, &mmp_block);
if (retval)
goto out;
sb->s_mmp_block = mmp_block;
retval = ext2fs_mmp_reset(fs);
if (retval)
goto out;
out:
return retval;
}
/*
* Make sure that the fs is not mounted or being fsck'ed while opening the fs.
*/
errcode_t ext2fs_mmp_start(ext2_filsys fs)
{
struct mmp_struct *mmp_s;
unsigned seq;
unsigned int mmp_check_interval;
errcode_t retval = 0;
if (fs->mmp_buf == NULL) {
retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf);
if (retval)
goto mmp_error;
}
retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
if (retval)
goto mmp_error;
mmp_s = fs->mmp_buf;
mmp_check_interval = fs->super->s_mmp_update_interval;
if (mmp_check_interval < EXT4_MMP_MIN_CHECK_INTERVAL)
mmp_check_interval = EXT4_MMP_MIN_CHECK_INTERVAL;
seq = mmp_s->mmp_seq;
if (seq == EXT4_MMP_SEQ_CLEAN)
goto clean_seq;
if (seq == EXT4_MMP_SEQ_FSCK) {
retval = EXT2_ET_MMP_FSCK_ON;
goto mmp_error;
}
if (seq > EXT4_MMP_SEQ_FSCK) {
retval = EXT2_ET_MMP_UNKNOWN_SEQ;
goto mmp_error;
}
/*
* If check_interval in MMP block is larger, use that instead of
* check_interval from the superblock.
*/
if (mmp_s->mmp_check_interval > mmp_check_interval)
mmp_check_interval = mmp_s->mmp_check_interval;
sleep(2 * mmp_check_interval + 1);
retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
if (retval)
goto mmp_error;
if (seq != mmp_s->mmp_seq) {
retval = EXT2_ET_MMP_FAILED;
goto mmp_error;
}
clean_seq:
if (!(fs->flags & EXT2_FLAG_RW))
goto mmp_error;
mmp_s->mmp_seq = seq = ext2fs_mmp_new_seq();
#if (0 && (_BSD_SOURCE || _XOPEN_SOURCE >= 500))
gethostname(mmp_s->mmp_nodename, sizeof(mmp_s->mmp_nodename));
#else
strcpy(mmp_s->mmp_nodename, "unknown host");
#endif
strncpy(mmp_s->mmp_bdevname, fs->device_name,
sizeof(mmp_s->mmp_bdevname));
retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf);
if (retval)
goto mmp_error;
sleep(2 * mmp_check_interval + 1);
retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
if (retval)
goto mmp_error;
if (seq != mmp_s->mmp_seq) {
retval = EXT2_ET_MMP_FAILED;
goto mmp_error;
}
mmp_s->mmp_seq = EXT4_MMP_SEQ_FSCK;
retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf);
if (retval)
goto mmp_error;
return 0;
mmp_error:
return retval;
}
/*
* Clear the MMP usage in the filesystem. If this function returns an
* error EXT2_ET_MMP_CHANGE_ABORT it means the filesystem was modified
* by some other process while in use, and changes should be dropped, or
* risk filesystem corruption.
*/
errcode_t ext2fs_mmp_stop(ext2_filsys fs)
{
struct mmp_struct *mmp, *mmp_cmp;
errcode_t retval = 0;
if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) ||
!(fs->flags & EXT2_FLAG_RW) || (fs->flags & EXT2_FLAG_SKIP_MMP))
goto mmp_error;
retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
if (retval)
goto mmp_error;
/* Check if the MMP block is not changed. */
mmp = fs->mmp_buf;
mmp_cmp = fs->mmp_cmp;
if (memcmp(mmp, mmp_cmp, sizeof(*mmp_cmp))) {
retval = EXT2_ET_MMP_CHANGE_ABORT;
goto mmp_error;
}
mmp_cmp->mmp_seq = EXT4_MMP_SEQ_CLEAN;
retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_cmp);
mmp_error:
if (fs->mmp_fd > 0) {
close(fs->mmp_fd);
fs->mmp_fd = -1;
}
return retval;
}
#define EXT2_MIN_MMP_UPDATE_INTERVAL 60
/*
* Update the on-disk mmp buffer, after checking that it hasn't been changed.
*/
errcode_t ext2fs_mmp_update(ext2_filsys fs)
{
struct mmp_struct *mmp, *mmp_cmp;
struct timeval tv;
errcode_t retval = 0;
if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) ||
!(fs->flags & EXT2_FLAG_RW) || (fs->flags & EXT2_FLAG_SKIP_MMP))
return 0;
gettimeofday(&tv, 0);
if (tv.tv_sec - fs->mmp_last_written < EXT2_MIN_MMP_UPDATE_INTERVAL)
return 0;
retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, NULL);
if (retval)
goto mmp_error;
mmp = fs->mmp_buf;
mmp_cmp = fs->mmp_cmp;
if (memcmp(mmp, mmp_cmp, sizeof(*mmp_cmp)))
return EXT2_ET_MMP_CHANGE_ABORT;
mmp->mmp_time = tv.tv_sec;
mmp->mmp_seq = EXT4_MMP_SEQ_FSCK;
retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf);
mmp_error:
return retval;
}

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include "ext2_fs.h" #include "ext2_fs.h"

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -22,6 +23,9 @@
#if HAVE_SYS_TYPES_H #if HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif #endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "ext2_fs.h" #include "ext2_fs.h"
@ -65,7 +69,7 @@ blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, dgrp_t i)
} }
errcode_t ext2fs_open(const char *name, int flags, int superblock, errcode_t ext2fs_open(const char *name, int flags, int superblock,
unsigned int block_size, io_channel * io, unsigned int block_size, io_channel io,
ext2_filsys *ret_fs) ext2_filsys *ret_fs)
{ {
return ext2fs_open2(name, 0, flags, superblock, block_size, return ext2fs_open2(name, 0, flags, superblock, block_size,
@ -82,18 +86,19 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
* EXT2_FLAG_FORCE - Open the filesystem even if some of the * EXT2_FLAG_FORCE - Open the filesystem even if some of the
* features aren't supported. * features aren't supported.
* EXT2_FLAG_JOURNAL_DEV_OK - Open an ext3 journal device * EXT2_FLAG_JOURNAL_DEV_OK - Open an ext3 journal device
* EXT2_FLAG_SKIP_MMP - Open without multi-mount protection check.
*/ */
errcode_t ext2fs_open2(const char *name, const char *io_options, errcode_t ext2fs_open2(const char *name, const char *io_options,
int flags, int superblock, int flags, int superblock,
unsigned int block_size, io_channel * io, unsigned int block_size, io_channel io,
ext2_filsys *ret_fs) ext2_filsys *ret_fs)
{ {
ext2_filsys fs; ext2_filsys fs;
io_manager manager = (*io)->manager; io_manager manager = io->manager;
errcode_t retval; errcode_t retval;
unsigned long i, first_meta_bg; unsigned long i, first_meta_bg;
__u32 features; __u32 features;
int groups_per_block, blocks_per_group, io_flags; unsigned int groups_per_block, blocks_per_group, io_flags;
blk64_t group_block, blk; blk64_t group_block, blk;
char *dest, *cp; char *dest, *cp;
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
@ -109,7 +114,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
memset(fs, 0, sizeof(struct struct_ext2_filsys)); memset(fs, 0, sizeof(struct struct_ext2_filsys));
fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS; fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
fs->io = *io; fs->io = io;
fs->flags = flags; fs->flags = flags;
/* don't overwrite sb backups unless flag is explicitly cleared */ /* don't overwrite sb backups unless flag is explicitly cleared */
fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
@ -216,7 +221,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
features = fs->super->s_feature_incompat; features = fs->super->s_feature_incompat;
#ifdef EXT2_LIB_SOFTSUPP_INCOMPAT #ifdef EXT2_LIB_SOFTSUPP_INCOMPAT
if (flags & EXT2_FLAG_SOFTSUPP_FEATURES) if (flags & EXT2_FLAG_SOFTSUPP_FEATURES)
features &= !EXT2_LIB_SOFTSUPP_INCOMPAT; features &= ~EXT2_LIB_SOFTSUPP_INCOMPAT;
#endif #endif
if (features & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) { if (features & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
retval = EXT2_ET_UNSUPP_FEATURE; retval = EXT2_ET_UNSUPP_FEATURE;
@ -226,7 +231,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
features = fs->super->s_feature_ro_compat; features = fs->super->s_feature_ro_compat;
#ifdef EXT2_LIB_SOFTSUPP_RO_COMPAT #ifdef EXT2_LIB_SOFTSUPP_RO_COMPAT
if (flags & EXT2_FLAG_SOFTSUPP_FEATURES) if (flags & EXT2_FLAG_SOFTSUPP_FEATURES)
features &= !EXT2_LIB_SOFTSUPP_RO_COMPAT; features &= ~EXT2_LIB_SOFTSUPP_RO_COMPAT;
#endif #endif
if ((flags & EXT2_FLAG_RW) && if ((flags & EXT2_FLAG_RW) &&
(features & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)) { (features & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)) {
@ -247,12 +252,24 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
retval = EXT2_ET_CORRUPT_SUPERBLOCK; retval = EXT2_ET_CORRUPT_SUPERBLOCK;
goto cleanup; goto cleanup;
} }
fs->blocksize = EXT2_BLOCK_SIZE(fs->super); if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_BIGALLOC) &&
(fs->super->s_log_block_size != fs->super->s_log_cluster_size)) {
retval = EXT2_ET_CORRUPT_SUPERBLOCK;
goto cleanup;
}
fs->fragsize = fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
if (EXT2_INODE_SIZE(fs->super) < EXT2_GOOD_OLD_INODE_SIZE) { if (EXT2_INODE_SIZE(fs->super) < EXT2_GOOD_OLD_INODE_SIZE) {
retval = EXT2_ET_CORRUPT_SUPERBLOCK; retval = EXT2_ET_CORRUPT_SUPERBLOCK;
goto cleanup; goto cleanup;
} }
fs->clustersize = EXT2_CLUSTER_SIZE(fs->super); fs->cluster_ratio_bits = fs->super->s_log_cluster_size -
fs->super->s_log_block_size;
if (EXT2_BLOCKS_PER_GROUP(fs->super) !=
EXT2_CLUSTERS_PER_GROUP(fs->super) << fs->cluster_ratio_bits) {
retval = EXT2_ET_CORRUPT_SUPERBLOCK;
goto cleanup;
}
fs->inode_blocks_per_group = ((EXT2_INODES_PER_GROUP(fs->super) * fs->inode_blocks_per_group = ((EXT2_INODES_PER_GROUP(fs->super) *
EXT2_INODE_SIZE(fs->super) + EXT2_INODE_SIZE(fs->super) +
EXT2_BLOCK_SIZE(fs->super) - 1) / EXT2_BLOCK_SIZE(fs->super) - 1) /
@ -312,6 +329,8 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
goto cleanup; goto cleanup;
if (!group_block) if (!group_block)
group_block = fs->super->s_first_data_block; group_block = fs->super->s_first_data_block;
if (group_block == 0 && fs->blocksize == 1024)
group_block = 1; /* Deal with 1024 blocksize && bigalloc */
dest = (char *) fs->group_desc; dest = (char *) fs->group_desc;
groups_per_block = EXT2_DESC_PER_BLOCK(fs->super); groups_per_block = EXT2_DESC_PER_BLOCK(fs->super);
if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
@ -367,6 +386,18 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
fs->flags &= ~EXT2_FLAG_NOFREE_ON_ERROR; fs->flags &= ~EXT2_FLAG_NOFREE_ON_ERROR;
*ret_fs = fs; *ret_fs = fs;
if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) &&
!(flags & EXT2_FLAG_SKIP_MMP) &&
(flags & (EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE))) {
retval = ext2fs_mmp_start(fs);
if (retval) {
fs->flags |= EXT2_FLAG_SKIP_MMP; /* just do cleanup */
ext2fs_mmp_stop(fs);
goto cleanup;
}
}
return 0; return 0;
cleanup: cleanup:
if (flags & EXT2_FLAG_NOFREE_ON_ERROR) if (flags & EXT2_FLAG_NOFREE_ON_ERROR)

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include "ext2fs.h" #include "ext2fs.h"
#include "ext2fsP.h" #include "ext2fsP.h"
@ -68,7 +69,7 @@ void ext2fs_numeric_progress_update(ext2_filsys fs,
if (progress->skip_progress) if (progress->skip_progress)
return; return;
fprintf(stdout, "%*llu/%*llu", progress->log_max, val, printf("%*llu/%*llu", progress->log_max, val,
progress->log_max, progress->max); progress->log_max, progress->max);
fprintf(stdout, "%.*s", (2*progress->log_max)+1, backspaces); fprintf(stdout, "%.*s", (2*progress->log_max)+1, backspaces);
} }

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -203,7 +204,7 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino,
if (start <= extent.e_lblk) { if (start <= extent.e_lblk) {
if (end < extent.e_lblk) if (end < extent.e_lblk)
goto next_extent; goto next_extent;
dbg_printf("Case #1\n"); dbg_printf("Case #%d\n", 1);
/* Start of deleted region before extent; /* Start of deleted region before extent;
adjust beginning of extent */ adjust beginning of extent */
free_start = extent.e_pblk; free_start = extent.e_pblk;
@ -219,7 +220,7 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino,
break; break;
/* End of deleted region after extent; /* End of deleted region after extent;
adjust end of extent */ adjust end of extent */
dbg_printf("Case #2\n"); dbg_printf("Case #%d\n", 2);
newlen = start - extent.e_lblk; newlen = start - extent.e_lblk;
free_start = extent.e_pblk + newlen; free_start = extent.e_pblk + newlen;
free_count = extent.e_len - newlen; free_count = extent.e_len - newlen;
@ -227,7 +228,7 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino,
} else { } else {
struct ext2fs_extent newex; struct ext2fs_extent newex;
dbg_printf("Case #3\n"); dbg_printf("Case #%d\n", 3);
/* The hard case; we need to split the extent */ /* The hard case; we need to split the extent */
newex.e_pblk = extent.e_pblk + newex.e_pblk = extent.e_pblk +
(end + 1 - extent.e_lblk); (end + 1 - extent.e_lblk);
@ -255,7 +256,7 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino,
dbg_print_extent("replacing", &extent); dbg_print_extent("replacing", &extent);
retval = ext2fs_extent_replace(handle, 0, &extent); retval = ext2fs_extent_replace(handle, 0, &extent);
} else { } else {
dbg_printf("deleting current extent\n"); dbg_printf("deleting current extent%s\n", "");
retval = ext2fs_extent_delete(handle, 0); retval = ext2fs_extent_delete(handle, 0);
} }
if (retval) if (retval)

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
@ -63,11 +64,11 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
errcode_t retval, retval2; errcode_t retval, retval2;
struct ext2_super_block *sb; struct ext2_super_block *sb;
struct ext2_inode inode; struct ext2_inode inode;
__u32 *dindir_buf = 0, *gdt_buf = 0; __u32 *dindir_buf, *gdt_buf;
unsigned long long apb, inode_size; unsigned long long apb, inode_size;
/* FIXME-64 - can't deal with extents */ /* FIXME-64 - can't deal with extents */
blk_t dindir_blk, rsv_off, gdt_off, gdt_blk; blk_t dindir_blk, rsv_off, gdt_off, gdt_blk;
int dindir_dirty = 0, inode_dirty = 0; int dindir_dirty = 0, inode_dirty = 0, sb_blk = 0;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@ -75,13 +76,22 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
retval = ext2fs_get_array(2, fs->blocksize, &dindir_buf); retval = ext2fs_get_array(2, fs->blocksize, &dindir_buf);
if (retval) if (retval)
goto out_free; return retval;
gdt_buf = (__u32 *)((char *)dindir_buf + fs->blocksize); gdt_buf = (__u32 *)((char *)dindir_buf + fs->blocksize);
retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode); retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
if (retval) if (retval)
goto out_free; goto out_free;
/*
* File systems with a blocksize of 1024 and bigalloc have
* sb->s_first_data_block of 0; yet the superblock is still at
* block #1. We compensate for it here.
*/
sb_blk = sb->s_first_data_block;
if (fs->blocksize == 1024 && sb_blk == 0)
sb_blk = 1;
/* Maximum possible file size (we donly use the dindirect blocks) */ /* Maximum possible file size (we donly use the dindirect blocks) */
apb = EXT2_ADDR_PER_BLOCK(sb); apb = EXT2_ADDR_PER_BLOCK(sb);
if ((dindir_blk = inode.i_block[EXT2_DIND_BLOCK])) { if ((dindir_blk = inode.i_block[EXT2_DIND_BLOCK])) {
@ -92,7 +102,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
if (retval) if (retval)
goto out_inode; goto out_inode;
} else { } else {
blk_t goal = sb->s_first_data_block + fs->desc_blocks + blk_t goal = sb_blk + fs->desc_blocks +
sb->s_reserved_gdt_blocks + 2 + sb->s_reserved_gdt_blocks + 2 +
fs->inode_blocks_per_group; fs->inode_blocks_per_group;
@ -120,7 +130,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
} }
for (rsv_off = 0, gdt_off = fs->desc_blocks, for (rsv_off = 0, gdt_off = fs->desc_blocks,
gdt_blk = sb->s_first_data_block + 1 + fs->desc_blocks; gdt_blk = sb_blk + 1 + fs->desc_blocks;
rsv_off < sb->s_reserved_gdt_blocks; rsv_off < sb->s_reserved_gdt_blocks;
rsv_off++, gdt_off++, gdt_blk++) { rsv_off++, gdt_off++, gdt_blk++) {
unsigned int three = 1, five = 5, seven = 7; unsigned int three = 1, five = 5, seven = 7;

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@ -34,10 +35,10 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
int block_nbytes, inode_nbytes; int block_nbytes, inode_nbytes;
unsigned int nbits; unsigned int nbits;
errcode_t retval; errcode_t retval;
char *block_buf = 0, *inode_buf = 0; char *block_buf = NULL, *inode_buf = NULL;
int csum_flag = 0; int csum_flag = 0;
blk64_t blk; blk64_t blk;
blk64_t blk_itr = fs->super->s_first_data_block; blk64_t blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block);
ext2_ino_t ino_itr = 1; ext2_ino_t ino_itr = 1;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@ -51,11 +52,11 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
inode_nbytes = block_nbytes = 0; inode_nbytes = block_nbytes = 0;
if (do_block) { if (do_block) {
block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8;
retval = ext2fs_get_memalign(fs->blocksize, fs->blocksize, retval = ext2fs_get_memalign(fs->blocksize, fs->blocksize,
&block_buf); &block_buf);
if (retval) if (retval)
return retval; goto errout;
memset(block_buf, 0xff, fs->blocksize); memset(block_buf, 0xff, fs->blocksize);
} }
if (do_inode) { if (do_inode) {
@ -64,7 +65,7 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
retval = ext2fs_get_memalign(fs->blocksize, fs->blocksize, retval = ext2fs_get_memalign(fs->blocksize, fs->blocksize,
&inode_buf); &inode_buf);
if (retval) if (retval)
return retval; goto errout;
memset(inode_buf, 0xff, fs->blocksize); memset(inode_buf, 0xff, fs->blocksize);
} }
@ -79,13 +80,14 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
retval = ext2fs_get_block_bitmap_range2(fs->block_map, retval = ext2fs_get_block_bitmap_range2(fs->block_map,
blk_itr, block_nbytes << 3, block_buf); blk_itr, block_nbytes << 3, block_buf);
if (retval) if (retval)
return retval; goto errout;
if (i == fs->group_desc_count - 1) { if (i == fs->group_desc_count - 1) {
/* Force bitmap padding for the last group */ /* Force bitmap padding for the last group */
nbits = ((ext2fs_blocks_count(fs->super) nbits = EXT2FS_NUM_B2C(fs,
((ext2fs_blocks_count(fs->super)
- (__u64) fs->super->s_first_data_block) - (__u64) fs->super->s_first_data_block)
% (__u64) EXT2_BLOCKS_PER_GROUP(fs->super)); % (__u64) EXT2_BLOCKS_PER_GROUP(fs->super)));
if (nbits) if (nbits)
for (j = nbits; j < fs->blocksize * 8; j++) for (j = nbits; j < fs->blocksize * 8; j++)
ext2fs_set_bit(j, block_buf); ext2fs_set_bit(j, block_buf);
@ -94,8 +96,10 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
if (blk) { if (blk) {
retval = io_channel_write_blk64(fs->io, blk, 1, retval = io_channel_write_blk64(fs->io, blk, 1,
block_buf); block_buf);
if (retval) if (retval) {
return EXT2_ET_BLOCK_BITMAP_WRITE; retval = EXT2_ET_BLOCK_BITMAP_WRITE;
goto errout;
}
} }
skip_this_block_bitmap: skip_this_block_bitmap:
blk_itr += block_nbytes << 3; blk_itr += block_nbytes << 3;
@ -111,14 +115,16 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
retval = ext2fs_get_inode_bitmap_range2(fs->inode_map, retval = ext2fs_get_inode_bitmap_range2(fs->inode_map,
ino_itr, inode_nbytes << 3, inode_buf); ino_itr, inode_nbytes << 3, inode_buf);
if (retval) if (retval)
return retval; goto errout;
blk = ext2fs_inode_bitmap_loc(fs, i); blk = ext2fs_inode_bitmap_loc(fs, i);
if (blk) { if (blk) {
retval = io_channel_write_blk64(fs->io, blk, 1, retval = io_channel_write_blk64(fs->io, blk, 1,
inode_buf); inode_buf);
if (retval) if (retval) {
return EXT2_ET_INODE_BITMAP_WRITE; retval = EXT2_ET_INODE_BITMAP_WRITE;
goto errout;
}
} }
skip_this_inode_bitmap: skip_this_inode_bitmap:
ino_itr += inode_nbytes << 3; ino_itr += inode_nbytes << 3;
@ -133,6 +139,12 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
ext2fs_free_mem(&inode_buf); ext2fs_free_mem(&inode_buf);
} }
return 0; return 0;
errout:
if (inode_buf)
ext2fs_free_mem(&inode_buf);
if (block_buf)
ext2fs_free_mem(&block_buf);
return retval;
} }
static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
@ -141,13 +153,13 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
char *block_bitmap = 0, *inode_bitmap = 0; char *block_bitmap = 0, *inode_bitmap = 0;
char *buf; char *buf;
errcode_t retval; errcode_t retval;
int block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; int block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8;
int inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8; int inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8;
int csum_flag = 0; int csum_flag = 0;
int do_image = fs->flags & EXT2_FLAG_IMAGE_FILE; int do_image = fs->flags & EXT2_FLAG_IMAGE_FILE;
unsigned int cnt; unsigned int cnt;
blk64_t blk; blk64_t blk;
blk64_t blk_itr = fs->super->s_first_data_block; blk64_t blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block);
blk64_t blk_cnt; blk64_t blk_cnt;
ext2_ino_t ino_itr = 1; ext2_ino_t ino_itr = 1;
ext2_ino_t ino_cnt; ext2_ino_t ino_cnt;
@ -219,7 +231,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
} }
blk = (fs->image_header->offset_blockmap / blk = (fs->image_header->offset_blockmap /
fs->blocksize); fs->blocksize);
blk_cnt = (blk64_t)EXT2_BLOCKS_PER_GROUP(fs->super) * blk_cnt = (blk64_t)EXT2_CLUSTERS_PER_GROUP(fs->super) *
fs->group_desc_count; fs->group_desc_count;
while (block_nbytes > 0) { while (block_nbytes > 0) {
retval = io_channel_read_blk64(fs->image_io, blk++, retval = io_channel_read_blk64(fs->image_io, blk++,

View File

@ -10,6 +10,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include "ext2_fs.h" #include "ext2_fs.h"

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -70,6 +71,8 @@ void ext2fs_swap_super(struct ext2_super_block * sb)
sb->s_min_extra_isize = ext2fs_swab16(sb->s_min_extra_isize); sb->s_min_extra_isize = ext2fs_swab16(sb->s_min_extra_isize);
sb->s_want_extra_isize = ext2fs_swab16(sb->s_want_extra_isize); sb->s_want_extra_isize = ext2fs_swab16(sb->s_want_extra_isize);
sb->s_flags = ext2fs_swab32(sb->s_flags); sb->s_flags = ext2fs_swab32(sb->s_flags);
sb->s_mmp_update_interval = ext2fs_swab16(sb->s_mmp_update_interval);
sb->s_mmp_block = ext2fs_swab64(sb->s_mmp_block);
sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written); sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written);
sb->s_snapshot_inum = ext2fs_swab32(sb->s_snapshot_inum); sb->s_snapshot_inum = ext2fs_swab32(sb->s_snapshot_inum);
sb->s_snapshot_id = ext2fs_swab32(sb->s_snapshot_id); sb->s_snapshot_id = ext2fs_swab32(sb->s_snapshot_id);
@ -78,21 +81,23 @@ void ext2fs_swap_super(struct ext2_super_block * sb)
sb->s_snapshot_list = ext2fs_swab32(sb->s_snapshot_list); sb->s_snapshot_list = ext2fs_swab32(sb->s_snapshot_list);
sb->s_usr_quota_inum = ext2fs_swab32(sb->s_usr_quota_inum); sb->s_usr_quota_inum = ext2fs_swab32(sb->s_usr_quota_inum);
sb->s_grp_quota_inum = ext2fs_swab32(sb->s_grp_quota_inum); sb->s_grp_quota_inum = ext2fs_swab32(sb->s_grp_quota_inum);
sb->s_overhead_blocks = ext2fs_swab32(sb->s_overhead_blocks);
sb->s_checksum = ext2fs_swab32(sb->s_checksum);
for (i=0; i < 4; i++) for (i=0; i < 4; i++)
sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]); sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
/* if journal backup is for a valid extent-based journal... */ /* if journal backup is for a valid extent-based journal... */
if (!ext2fs_extent_header_verify(sb->s_jnl_blocks, if (ext2fs_extent_header_verify(sb->s_jnl_blocks,
sizeof(sb->s_jnl_blocks))) { sizeof(sb->s_jnl_blocks)) == 0) {
/* ... swap only the journal i_size */ /* ... swap only the journal i_size and i_size_high,
sb->s_jnl_blocks[16] = ext2fs_swab32(sb->s_jnl_blocks[16]); * and the extent data is not swapped on read */
/* and the extent data is not swapped on read */ i = 15;
return; } else {
}
/* direct/indirect journal: swap it all */ /* direct/indirect journal: swap it all */
for (i=0; i < 17; i++) i = 0;
}
for (; i < 17; i++)
sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]); sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
} }
@ -106,6 +111,11 @@ void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp)
gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count); gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count);
gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count); gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
gdp->bg_flags = ext2fs_swab16(gdp->bg_flags); gdp->bg_flags = ext2fs_swab16(gdp->bg_flags);
gdp->bg_exclude_bitmap_lo = ext2fs_swab32(gdp->bg_exclude_bitmap_lo);
gdp->bg_block_bitmap_csum_lo =
ext2fs_swab16(gdp->bg_block_bitmap_csum_lo);
gdp->bg_inode_bitmap_csum_lo =
ext2fs_swab16(gdp->bg_inode_bitmap_csum_lo);
gdp->bg_itable_unused = ext2fs_swab16(gdp->bg_itable_unused); gdp->bg_itable_unused = ext2fs_swab16(gdp->bg_itable_unused);
gdp->bg_checksum = ext2fs_swab16(gdp->bg_checksum); gdp->bg_checksum = ext2fs_swab16(gdp->bg_checksum);
/* If we're 32-bit, we're done */ /* If we're 32-bit, we're done */
@ -125,11 +135,16 @@ void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp)
gdp4->bg_used_dirs_count_hi = gdp4->bg_used_dirs_count_hi =
ext2fs_swab16(gdp4->bg_used_dirs_count_hi); ext2fs_swab16(gdp4->bg_used_dirs_count_hi);
gdp4->bg_itable_unused_hi = ext2fs_swab16(gdp4->bg_itable_unused_hi); gdp4->bg_itable_unused_hi = ext2fs_swab16(gdp4->bg_itable_unused_hi);
gdp4->bg_exclude_bitmap_hi = ext2fs_swab16(gdp4->bg_exclude_bitmap_hi);
gdp4->bg_block_bitmap_csum_hi =
ext2fs_swab16(gdp4->bg_block_bitmap_csum_hi);
gdp4->bg_inode_bitmap_csum_hi =
ext2fs_swab16(gdp4->bg_inode_bitmap_csum_hi);
} }
void ext2fs_swap_group_desc(struct ext2_group_desc *gdp) void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
{ {
return ext2fs_swap_group_desc2(0, gdp); ext2fs_swap_group_desc2(0, gdp);
} }
@ -244,8 +259,8 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
ext2fs_swab16 (f->osd2.linux2.l_i_uid_high); ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
t->osd2.linux2.l_i_gid_high = t->osd2.linux2.l_i_gid_high =
ext2fs_swab16 (f->osd2.linux2.l_i_gid_high); ext2fs_swab16 (f->osd2.linux2.l_i_gid_high);
t->osd2.linux2.l_i_reserved2 = t->osd2.linux2.l_i_checksum_lo =
ext2fs_swab32(f->osd2.linux2.l_i_reserved2); ext2fs_swab16(f->osd2.linux2.l_i_checksum_lo);
break; break;
case EXT2_OS_HURD: case EXT2_OS_HURD:
t->osd1.hurd1.h_i_translator = t->osd1.hurd1.h_i_translator =
@ -279,6 +294,21 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
return; return;
} }
if (extra_isize >= 4)
t->i_checksum_hi = ext2fs_swab16(f->i_checksum_hi);
if (extra_isize >= 8)
t->i_ctime_extra = ext2fs_swab32(f->i_ctime_extra);
if (extra_isize >= 12)
t->i_mtime_extra = ext2fs_swab32(f->i_mtime_extra);
if (extra_isize >= 16)
t->i_atime_extra = ext2fs_swab32(f->i_atime_extra);
if (extra_isize >= 20)
t->i_crtime = ext2fs_swab32(f->i_crtime);
if (extra_isize >= 24)
t->i_crtime_extra = ext2fs_swab32(f->i_crtime_extra);
if (extra_isize >= 28)
t->i_version_hi = ext2fs_swab32(f->i_version_hi);
i = sizeof(struct ext2_inode) + extra_isize + sizeof(__u32); i = sizeof(struct ext2_inode) + extra_isize + sizeof(__u32);
if (bufsize < (int) i) if (bufsize < (int) i)
return; /* no space for EA magic */ return; /* no space for EA magic */
@ -312,4 +342,12 @@ void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
sizeof(struct ext2_inode)); sizeof(struct ext2_inode));
} }
void ext2fs_swap_mmp(struct mmp_struct *mmp)
{
mmp->mmp_magic = ext2fs_swab32(mmp->mmp_magic);
mmp->mmp_seq = ext2fs_swab32(mmp->mmp_seq);
mmp->mmp_time = ext2fs_swab64(mmp->mmp_time);
mmp->mmp_check_interval = ext2fs_swab16(mmp->mmp_check_interval);
}
#endif #endif

View File

@ -38,6 +38,7 @@ Last Changed Date: 2007-06-22 13:36:10 -0400 (Fri, 22 Jun 2007)
#endif #endif
#define _XOPEN_SOURCE 600 #define _XOPEN_SOURCE 600
#include "config.h"
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -23,7 +24,7 @@
* This function returns 1 if the inode's block entries actually * This function returns 1 if the inode's block entries actually
* contain block entries. * contain block entries.
*/ */
int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode) int ext2fs_inode_has_valid_blocks2(ext2_filsys fs, struct ext2_inode *inode)
{ {
/* /*
* Only directories, regular files, and some symbolic links * Only directories, regular files, and some symbolic links
@ -38,7 +39,7 @@ int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode)
* target is stored in the block entries. * target is stored in the block entries.
*/ */
if (LINUX_S_ISLNK (inode->i_mode)) { if (LINUX_S_ISLNK (inode->i_mode)) {
if (ext2fs_file_acl_block(inode) == 0) { if (ext2fs_file_acl_block(fs, inode) == 0) {
/* With no EA block, we can rely on i_blocks */ /* With no EA block, we can rely on i_blocks */
if (inode->i_blocks == 0) if (inode->i_blocks == 0)
return 0; return 0;
@ -53,3 +54,8 @@ int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode)
} }
return 1; return 1;
} }
int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode)
{
return ext2fs_inode_has_valid_blocks2(NULL, inode);
}

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -19,6 +20,7 @@
#include "ext2_fs.h" #include "ext2_fs.h"
#include "ext2fs.h" #include "ext2fs.h"
static const char *lib_version = ""; static const char *lib_version = "";
static const char *lib_date = ""; static const char *lib_date = "";

View File

@ -9,6 +9,7 @@
* %End-Header% * %End-Header%
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include "ext2_fs.h" #include "ext2_fs.h"