summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobi <robi>2010-10-02 15:41:49 +0000
committerrobi <robi>2010-10-02 15:41:49 +0000
commit88e4c10b43783c24201e932b6494250b548ed84b (patch)
tree0e47a288f716c0e6fdf5ce425ebabd9fd3562fa5
parent36208b20d0afdd5d26fcaf57fb4b7a384d93157c (diff)
BUGs:#017547 #017556 #017557 #017559
-rw-r--r--src/inode.c21
-rw-r--r--src/inode.h2
-rw-r--r--src/journal.c2
-rw-r--r--src/magic_block_scan.c164
-rw-r--r--src/util.c64
5 files changed, 162 insertions, 91 deletions
diff --git a/src/inode.c b/src/inode.c
index d1f2571..27fff1c 100644
--- a/src/inode.c
+++ b/src/inode.c
@@ -950,15 +950,16 @@ return 1;
//add the ext3 indirect Blocks to the inode
-blk_t inode_add_meta_block(struct ext2_inode_large* inode , blk_t blk, blk_t *last, char *buf ){
- blk_t b_blk,block_count, next;
+int inode_add_meta_block(struct ext2_inode_large* inode , blk_t blk, blk_t *last, blk_t *next, unsigned char *buf ){
+ blk_t b_blk,block_count;
blk_t count=0;
int i;
__u64 i_size = 0;
+ int ret = 0;
i = 0;
block_count = 0;
- next = 0;
+
if (! (inode->i_flags & EXT4_EXTENTS_FL)){
while ((i < EXT2_N_BLOCKS) && inode->i_block[i] )
@@ -966,13 +967,13 @@ blk_t inode_add_meta_block(struct ext2_inode_large* inode , blk_t blk, blk_t *la
switch (i){
case EXT2_IND_BLOCK :
- get_ind_block_len(buf, &block_count, last, &next, &i_size);
+ ret = get_ind_block_len(buf, &block_count, last, next, &i_size);
break;
case EXT2_DIND_BLOCK :
- get_dind_block_len(buf, &block_count, last, &next, &i_size);
+ ret = get_dind_block_len(buf, &block_count, last, next, &i_size);
break;
case EXT2_TIND_BLOCK :
- get_tind_block_len(buf, &block_count, last, &next, &i_size);
+ ret = get_tind_block_len(buf, &block_count, last, next, &i_size);
break;
default:
// printf("faulty Block %u as indirekter_block %d \n", i,blk);
@@ -980,7 +981,7 @@ blk_t inode_add_meta_block(struct ext2_inode_large* inode , blk_t blk, blk_t *la
break;
}
- if (i_size){
+ if (ret && i_size){
i_size += (((__u64)inode->i_size_high << 32)| inode->i_size);
inode->i_size = i_size & 0xffffffff ;
inode->i_size_high = i_size >> 32 ;
@@ -988,14 +989,14 @@ blk_t inode_add_meta_block(struct ext2_inode_large* inode , blk_t blk, blk_t *la
inode->i_block[ i ] = blk;
}
else
- next = 0;
+ *next = 0;
- return next;
+ return ret;
}
else{
// printf("ERROR: ext3 indirect block %u ; but is a ext4_inode\n", blk);
//FIXME ext4
}
- return 1;
+ return 0;
} \ No newline at end of file
diff --git a/src/inode.h b/src/inode.h
index bcc0089..80aa711 100644
--- a/src/inode.h
+++ b/src/inode.h
@@ -69,7 +69,7 @@ struct ring_buf* get_j_inode_list(struct ext2_super_block*, ext2_ino_t);//fill a
//functions for the magic scanner
struct ext2_inode_large* new_inode(); //create a new inode
int inode_add_block(struct ext2_inode_large* , blk_t , __u32); //add a block to inode
-blk_t inode_add_meta_block(struct ext2_inode_large*, blk_t, blk_t*, char* ); //add the ext3 indirect Blocks to the inode
+int inode_add_meta_block(struct ext2_inode_large*, blk_t, blk_t*, blk_t*,unsigned char* ); //add the ext3 indirect Blocks to the inode
#endif
diff --git a/src/journal.c b/src/journal.c
index e26d66b..c8e8810 100644
--- a/src/journal.c
+++ b/src/journal.c
@@ -972,7 +972,7 @@ int next_block_bitmap(ext2fs_block_bitmap d_bmap){
}
i = 0;
-len = fs_bitmap->real_end >> 3;
+len = (fs_bitmap->end +1) >> 3;
while ((i < len) && (!(*(df_bitmap->bitmap +i))))
i++;
return ( i == len) ? 2 : 1 ;
diff --git a/src/magic_block_scan.c b/src/magic_block_scan.c
index 85bf75d..51cc34d 100644
--- a/src/magic_block_scan.c
+++ b/src/magic_block_scan.c
@@ -200,6 +200,38 @@ static int check_file_data_possible(struct found_data_t* this, __u32 scan ,unsig
+static int check_meta3_block(unsigned char *block_buf, blk_t blk, __u32 size){
+ blk_t block, *pb_block;
+ int i,j ;
+
+ size = (size + 3) & 0xFFFFFC ;
+ if (! size ) return 0;
+
+ for (i = size-4 ; i>=0 ; i -= 4){
+ pb_block = (blk_t*)(block_buf+i);
+ block = ext2fs_le32_to_cpu(*pb_block);
+ if( block && (block < current_fs->super->s_blocks_count) &&
+ (ext2fs_test_block_bitmap( d_bmap, block)) && (!ext2fs_test_block_bitmap(bmap,block))){
+ if (i) { //work not by sparse file
+ for (j = i - 4 ; j >= 0 ;j -= 4){
+ if (block == ext2fs_le32_to_cpu(*((blk_t*)(block_buf+j))))
+ return 0;
+ }
+ }
+ else {
+ if (block == blk+1)
+ return 1;
+ }
+
+ }
+ else
+ return 0;
+ }
+}
+
+
+
+
static int check_indirect_meta3(unsigned char *block_buf){
blk_t *pb_block;
blk_t last;
@@ -224,34 +256,46 @@ static int check_indirect_meta3(unsigned char *block_buf){
}
+static int check_dindirect_meta3(unsigned char * block_buf){
+ __u32 *p_blk;
+ __u32 block;
+ unsigned char *buf = NULL;
+ int ret = 0;
+
+ buf = malloc(current_fs->blocksize);
+ if (buf) {
+ p_blk = (__u32*) block_buf;
+ block = ext2fs_le32_to_cpu(*p_blk);
+ io_channel_read_blk ( current_fs->io, block, 1, buf );
+ if (check_meta3_block(buf, block, get_block_len(buf))){
+ ret = check_indirect_meta3(buf);
+ }
+ free (buf);
+ }
+
+return ret;
+}
-static int check_meta3_block(unsigned char *block_buf, blk_t blk, __u32 size){
- blk_t block, *pb_block;
- int i,j ;
- size = (size + 3) & 0xFFFFFC ;
- if (! size ) return 0;
- for (i = size-4 ; i>=0 ; i -= 4){
- pb_block = (blk_t*)(block_buf+i);
- block = ext2fs_le32_to_cpu(*pb_block);
- if( block && (block < current_fs->super->s_blocks_count) &&
- (ext2fs_test_block_bitmap( d_bmap, block)) && (!ext2fs_test_block_bitmap(bmap,block))){
- if (i) {
- for (j = i - 4 ; j >= 0 ;j -= 4){
- if (block == ext2fs_le32_to_cpu(*((blk_t*)(block_buf+j))))
- return 0;
- }
- }
- else {
- if (block == blk+1)
- return 1;
- }
-
- }
- else
- return 0;
- }
+static int check_tindirect_meta3(unsigned char * block_buf){
+ __u32 *p_blk;
+ __u32 block;
+ unsigned char *buf = NULL;
+ int ret = 0;
+
+ buf = malloc(current_fs->blocksize);
+ if (buf) {
+ p_blk = (__u32*) block_buf;
+ block = ext2fs_le32_to_cpu(*p_blk);
+ io_channel_read_blk ( current_fs->io, block, 1, buf );
+ if (check_meta3_block(buf, block, get_block_len(buf))){
+ ret = check_dindirect_meta3(buf);
+ }
+ free (buf);
+ }
+
+return ret;
}
@@ -330,29 +374,42 @@ static int check_acl_block(unsigned char *block_buf, blk_t blk, __u32 size){
static int add_ext3_file_meta_data(struct found_data_t* this, unsigned char *buf, blk_t blk){
- blk_t next_meta;
+ blk_t next_meta = 0;
+ blk_t meta = 0;
blk_t last_data = 0;
- next_meta = inode_add_meta_block(this->inode , blk, &last_data, buf );
- this->last = last_data;
+ int ret = 0;
- if (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta)))){
- io_channel_read_blk ( current_fs->io, next_meta, 1, buf );
- if (check_meta3_block(buf, blk, get_block_len(buf))){
- next_meta = inode_add_meta_block(this->inode , next_meta , &last_data, buf );
+ if (check_indirect_meta3(buf)){
+ ret = inode_add_meta_block(this->inode , blk, &last_data, &next_meta, buf );
+ this->last = last_data;
+ }
+
+ if (ret && (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta))))){
+ meta = next_meta;
+ next_meta = 0;
+ io_channel_read_blk ( current_fs->io, meta, 1, buf );
+
+ if (check_meta3_block(buf, meta, get_block_len(buf)) && check_dindirect_meta3(buf)){
+ ret = inode_add_meta_block(this->inode , meta, &last_data, &next_meta, buf );
this->last = last_data;
- if (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta)))){
- io_channel_read_blk ( current_fs->io, next_meta, 1, buf );
+ if (ret && (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta))))){
+ meta = next_meta;
+ next_meta = 0;
+ io_channel_read_blk ( current_fs->io, meta, 1, buf );
- if (check_meta3_block(buf, blk, get_block_len(buf))){
- next_meta = inode_add_meta_block(this->inode , next_meta , &last_data, buf );
+ if (check_meta3_block(buf, meta, get_block_len(buf)) && check_tindirect_meta3(buf)){
+ ret = inode_add_meta_block(this->inode , meta, &last_data, &next_meta, buf );
this->last = last_data;
}
- }
+
+ }
+
}
+
}
-return (next_meta) ? 0 : 1 ;
+return ret ;
}
@@ -365,7 +422,7 @@ static int skip_block(blk_t *p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_
o_blk = (*p_blk) >> 3;
p_bmap = (struct ext2fs_struct_loc_generic_bitmap *) bmap;
- while (((! *(ds_bmap->bitmap + o_blk)) || (*(ds_bmap->bitmap + o_blk) == 0xff)) && (o_blk < (ds_bmap->real_end >> 3))){
+ while (((! *(ds_bmap->bitmap + o_blk)) || (*(ds_bmap->bitmap + o_blk) == 0xff)) && (o_blk < (ds_bmap->end >> 3))){
o_blk ++;
flag = 1;
}
@@ -468,6 +525,8 @@ static int magic_check_block(unsigned char* buf,magic_t cookie , magic_t cookie_
}
p_search++;
}
+ if (! (retval & M_APPLI))
+ retval |= M_DATA ;
goto out;
}
@@ -537,20 +596,23 @@ static int get_range(blk_t* p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_b
blk_t begin;
blk_t end;
int count=1;
- for (begin = *p_blk; begin < ds_bmap->real_end ; begin++){
+ for (begin = *p_blk; begin <= ds_bmap->end ; begin++){
if((!(begin & 0x7)) && skip_block(&begin, ds_bmap)){
#ifdef DEBUG_MAGIC_SCAN
printf("jump to %d \n",begin);
#endif
}
+ *p_blk = begin;
+ if (begin > ds_bmap->end)
+ return 0;
if (ext2fs_test_block_bitmap ( d_bmap, begin) && (! ext2fs_test_block_bitmap( bmap, begin)))
break;
}
- *p_blk = begin;
- if (begin >= ds_bmap->real_end)
+
+ if (begin > ds_bmap->end)
return 0;
- for (end = begin,count=1 ; ((count < MAX_RANGE) && (end < ds_bmap->real_end)); ){
+ for (end = begin,count=1 ; ((count < MAX_RANGE) && (end < ds_bmap->end-1)); ){
if (ext2fs_test_block_bitmap(d_bmap, end+1) && (! ext2fs_test_block_bitmap( bmap, end+1))){
end++;
count++;
@@ -575,21 +637,21 @@ static int get_full_range(blk_t* p_blk ,struct ext2fs_struct_loc_generic_bitmap
int i;
errcode_t x;
- for (begin = *p_blk; begin < ds_bmap->real_end ; begin++){
+ for (begin = *p_blk; begin <= ds_bmap->end ; begin++){
if((!(begin & 0x7)) && skip_block(&begin, ds_bmap)){
#ifdef DEBUG_MAGIC_SCAN
printf("jump to %d \n",begin);
#endif
}
+ *p_blk = begin;
+ if (begin > ds_bmap->end)
+ return 0;
if (ext2fs_test_block_bitmap ( d_bmap, begin) && (! ext2fs_test_block_bitmap( bmap, begin)))
break;
}
- *p_blk = begin;
- if (begin >= ds_bmap->real_end)
- return 0;
i = 0;
- for (end = begin,count=1 ; ((count <= MAX_RANGE) && (end < ds_bmap->real_end)); ){
+ for (end = begin,count=1 ; ((count <= MAX_RANGE) && (end < ds_bmap->end)); ){
if (ext2fs_test_block_bitmap(d_bmap, end) && (! ext2fs_test_block_bitmap( bmap, end))){
count++;
if (!begin)
@@ -679,7 +741,9 @@ while (ds_retval){
if (d_bmap && ds_retval ){
ds_bmap = (struct ext2fs_struct_loc_generic_bitmap *) d_bmap;
-
+
+ count = 0;
+ blk[0] = 0;
count = get_range(blk ,ds_bmap, buf);
while (count){
@@ -738,7 +802,7 @@ while (ds_retval){
#ifdef DEBUG_MAGIC_SCAN
printf("try a fragment recover for metablock %ld\n",flag[i]);
#endif
- blk[1] = block_backward(flag[i] , 12);
+ blk[1] = block_backward(flag[i] , 13);
if (blk[1]){
blk[0] = blk[1];
fragment_flag = flag[i];
diff --git a/src/util.c b/src/util.c
index 2b42328..4536710 100644
--- a/src/util.c
+++ b/src/util.c
@@ -532,8 +532,7 @@ return;
}
-void get_ind_block_len(char *buf, blk_t *blk, blk_t *last ,blk_t *next, __u64 *p_len){
-// unsigned long long len;
+int get_ind_block_len(char *buf, blk_t *blk, blk_t *last ,blk_t *next, __u64 *p_len){
int i = (current_fs->blocksize >> 2)- 1;
char *priv_buf = NULL;
blk_t block, *p_block;
@@ -542,7 +541,7 @@ void get_ind_block_len(char *buf, blk_t *blk, blk_t *last ,blk_t *next, __u64 *p
priv_buf = malloc(current_fs->blocksize);
if (! priv_buf){
fprintf(stderr,"can not allocate memory\n");
- return ;
+ return 0;
}
p_block = (blk_t*)buf;
p_block += i;
@@ -555,9 +554,10 @@ void get_ind_block_len(char *buf, blk_t *blk, blk_t *last ,blk_t *next, __u64 *p
}
else break;
}
- if (io_channel_read_blk ( current_fs->io, block, 1, priv_buf )){
- fprintf(stderr,"ERROR: while read block %10u\n",block);
- return ;
+ if ((block >= current_fs->super->s_blocks_count) ||
+ (ext2fs_test_block_bitmap(bmap,block)) || (io_channel_read_blk ( current_fs->io, block, 1, priv_buf ))){
+// fprintf(stderr,"ERROR: while read block %10u\n",block);
+ return 0;
}
*next = (flag) ? 0 : block+1 ;
*last = block;
@@ -565,13 +565,13 @@ void get_ind_block_len(char *buf, blk_t *blk, blk_t *last ,blk_t *next, __u64 *p
*p_len += (i * (current_fs->blocksize)) ;
*blk += (i + 1) ;
free(priv_buf);
-return ;
+return 1;
}
-void get_dind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 *p_len){
-// unsigned long long len;
+int get_dind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 *p_len){
+ int ret = 0;
int i = (current_fs->blocksize >> 2)- 1;
char *priv_buf = NULL;
blk_t block, *p_block;
@@ -579,7 +579,7 @@ void get_dind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 *
priv_buf = malloc(current_fs->blocksize);
if (! priv_buf){
fprintf(stderr,"can not allocate memory\n");
- return;
+ return 0;
}
p_block = (blk_t*)buf;
p_block += i;
@@ -591,23 +591,26 @@ void get_dind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 *
}
else break;
}
- if (io_channel_read_blk ( current_fs->io, block, 1, priv_buf )){
- fprintf(stderr,"ERROR: while read ind-block %10u\n",block);
- return;
+ if ((block >= current_fs->super->s_blocks_count) ||
+ (ext2fs_test_block_bitmap(bmap,block)) || (io_channel_read_blk ( current_fs->io, block, 1, priv_buf ))){
+// fprintf(stderr,"ERROR: while read ind-block %10u\n",block);
+ return 0;
}
- get_ind_block_len(priv_buf, blk, last, next, p_len);
- *p_len += (i * current_fs->blocksize * (current_fs->blocksize >>2) ) ;
- *next = ( i == ((current_fs->blocksize >> 2)- 1)) ? *last : 0 ;
- *blk += ((i * ((current_fs->blocksize >>2) + 1)) + 1) ;
+ ret = get_ind_block_len(priv_buf, blk, last, next, p_len);
+ if (ret){
+ *p_len += (i * current_fs->blocksize * (current_fs->blocksize >>2) ) ;
+ *next = ( i == ((current_fs->blocksize >> 2)- 1)) ? *last : 0 ;
+ *blk += ((i * ((current_fs->blocksize >>2) + 1)) + 1) ;
+ }
free(priv_buf);
-return ;
+return ret ;
}
-void get_tind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 *p_len){
-// unsigned long long len;
+int get_tind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 *p_len){
+ int ret = 0;
int i = (current_fs->blocksize >> 2)- 1;
char *priv_buf = NULL;
blk_t block, *p_block;
@@ -615,7 +618,7 @@ void get_tind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 *
priv_buf = malloc(current_fs->blocksize);
if (! priv_buf){
fprintf(stderr,"can not allocate memory\n");
- return ;
+ return 0 ;
}
p_block = (blk_t*)buf;
p_block += i;
@@ -627,16 +630,19 @@ void get_tind_block_len(char *buf, blk_t *blk, blk_t *last, blk_t *next, __u64 *
}
else break;
}
- if (io_channel_read_blk ( current_fs->io, block, 1, priv_buf )){
- fprintf(stderr,"ERROR: while read dind-block %10u\n",block);
- return ;
+ if ((block >= current_fs->super->s_blocks_count) ||
+ (ext2fs_test_block_bitmap(bmap,block)) ||(io_channel_read_blk ( current_fs->io, block, 1, priv_buf ))){
+// fprintf(stderr,"ERROR: while read dind-block %10u\n",block);
+ return 0;
}
- get_dind_block_len(priv_buf, blk, last, next,p_len);
- *p_len += (i * current_fs->blocksize * (current_fs->blocksize >>2) * (current_fs->blocksize >>2) ) ;
- *blk += ((i * ((current_fs->blocksize >>2) + 1) * (current_fs->blocksize >>2)) + 1) ;
- *next = 0;
+ ret = get_dind_block_len(priv_buf, blk, last, next,p_len);
+ if (ret){
+ *p_len += (i * current_fs->blocksize * (current_fs->blocksize >>2) * (current_fs->blocksize >>2) ) ;
+ *blk += ((i * ((current_fs->blocksize >>2) + 1) * (current_fs->blocksize >>2)) + 1) ;
+ *next = 0;
+ }
free(priv_buf);
-return;
+return ret;
}