summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobi <robi>2011-12-25 20:38:16 +0000
committerrobi <robi>2011-12-25 20:38:16 +0000
commit9d0ee99f1144cec4c00e04ce6a7e3f2653005df7 (patch)
treeea2cbe5c3bf112ab1ceb1c1046ba585e4268b3aa
parentbe0c55229494231393ae0f122cac8d19753d6804 (diff)
new partial step, recover in journal lost inodes
-rw-r--r--src/imap_search.c92
-rw-r--r--src/journal.c69
-rw-r--r--src/journal.h2
-rw-r--r--src/recover.c40
-rw-r--r--src/util.h1
5 files changed, 202 insertions, 2 deletions
diff --git a/src/imap_search.c b/src/imap_search.c
index d397380..20ea9d8 100644
--- a/src/imap_search.c
+++ b/src/imap_search.c
@@ -27,9 +27,15 @@
#include "inode.h"
#include <sys/stat.h>
#include <errno.h>
+#include <time.h>
+//#include <ext2fs/ext2fs.h>
+//#include <ext2fs/ext2_fs.h>
#include "magic.h"
+#include "journal.h"
+
+extern ext2_filsys current_fs;
+extern time_t now_time ;
-extern ext2_filsys current_fs;
struct privat {
int count;
@@ -358,12 +364,96 @@ return retval;
}
+
+void search_journal_lost_inode(char* des_dir, __u32 t_after, __u32 t_before, int flag){
+
+struct ext2_inode *p_inode;
+struct ext2_inode inode;
+int retval,i ;
+char *pathname = NULL;
+char *i_pathname = NULL;
+char *buf= NULL;
+unsigned char *tmp_buf = NULL;
+__u32 blocksize, inodesize;
+__u32 inode_per_block;
+ext2_ino_t inode_max, inode_nr;
+
+
+pathname = malloc(26);
+blocksize = current_fs->blocksize;
+inodesize = current_fs->super->s_inode_size;
+inode_max = current_fs->super->s_inodes_count;
+inode_per_block = blocksize / inodesize;
+inode_nr = inode_max ;
+
+buf = malloc(blocksize);
+if (! (flag & 0x01) ){
+ tmp_buf = malloc (12 * blocksize);
+ if (!tmp_buf)
+ goto errout;
+ cookie = magic_open(MAGIC_MIME | MAGIC_NO_CHECK_COMPRESS | MAGIC_NO_CHECK_ELF | MAGIC_CONTINUE);
+ if ((! cookie) || magic_load(cookie, NULL)){
+ fprintf(stderr,"ERROR: can't find libmagic\n");
+ goto errout;
+ }
+}
+
+while ( get_pool_block(buf) ){
+ for (i=0 ;i < inode_per_block; i++){
+ inode_nr++;
+ p_inode = (struct ext2_inode*) (buf + (i * inodesize));
+
+ memset(&inode, 0, sizeof(struct ext2_inode));
+#ifdef WORDS_BIGENDIAN
+ ext2fs_swap_inode(current_fs, &inode, p_inode, 0);
+#else
+ memcpy(&inode, p_inode,128);
+#endif
+ if((inode.i_dtime) || (!inode.i_size) || (!inode.i_blocks) || (!LINUX_S_ISREG(inode.i_mode)))
+ continue;
+ if (check_file_stat(&inode)){
+ i_pathname = identify_filename(i_pathname, tmp_buf, &inode, inode_nr);
+ sprintf(pathname,"<%lu>",inode_nr);
+ recover_file(des_dir,"MAGIC-2", ((i_pathname)?i_pathname : pathname), &inode, inode_nr, 1);
+ }
+ if(i_pathname){
+ free(i_pathname);
+ i_pathname = NULL;
+ }
+
+ }
+}
+errout:
+ if (pathname)
+ free(pathname);
+
+ if(buf) {
+ free(buf);
+ buf = NULL;
+ }
+
+ if (tmp_buf){
+ free(tmp_buf);
+ tmp_buf = NULL;
+ }
+ if (cookie){
+ magic_close(cookie);
+ cookie = 0;
+ }
+return;
+}
+
+
//2 step search for journalinode, will find some lost directory and files
void imap_search(char* des_dir, __u32 t_after, __u32 t_before , int disaster ){
printf("MAGIC-1 : start lost directory search\n");
search_imap_inode(des_dir, t_after, t_before, 1 | disaster ); //search for lost fragments of directorys
printf("MAGIC-2 : start lost file search\n");
search_imap_inode(des_dir, t_after, t_before, 0 | disaster ); //search for lost files
+ if ((!disaster) && (t_before == (__u32)now_time)){
+ printf("MAGIC-2 : start lost in journal search\n");
+ search_journal_lost_inode(des_dir, t_after, t_before, 0);
+ }
return;
}
diff --git a/src/journal.c b/src/journal.c
index bfd255a..d8ccd83 100644
--- a/src/journal.c
+++ b/src/journal.c
@@ -64,11 +64,14 @@ struct journal_source
//static variable for work with journal
struct journal_source journal_source;
extern ext2_filsys current_fs ;
+extern time_t now_time ;
struct ext2_super_block *jsb_pointer; //pointer for find & open journal
char jsb_buffer[1024]; //buffer for journal-superblock (be_to_CPU)
void* pt_buff; /*pointer of the privat descriptor Table */
journal_descriptor_tag_t *pt; /*pointer for descriptor Table*/
+__u32 *ptl; /*reverse pointer for lost inodeblocks*/
__u32 pt_count; /*counter for privat descriptor Table */
+__u32 ptl_count; /*counter for lost inodeblocks*/
struct j_bitmap_list_t jbbm ; /* for Block Bitmaps of Journal */
@@ -149,6 +152,7 @@ extern int journal_open( char *journal_file_name, int journal_backup_flag )
ext2_file_t journal_file;
pt_buff = NULL;
+ ptl = NULL;
if (current_fs) jsb_pointer = current_fs->super;
else {
fprintf(stderr,"No filesystem open, this must be a bug\n");
@@ -395,6 +399,43 @@ static const char *type_to_name(int btype)
}
+//check if journal block is a lost inodeblock local function
+int jb_is_inodetable(unsigned char *buf){
+ struct ext2_inode *inode;
+ __u16 mode;
+ __u32 atime;
+ __u32 ctime;
+ __u32 mtime;
+ __u32 dtime;
+ int i;
+ __u32 min = 315601200; // 315601200 = "1980-01-01 20:00:00"
+ __u32 max = (__u32) now_time;
+ int ret = 0;
+ int i_size = EXT2_INODE_SIZE(current_fs->super);
+ int inodes_per_block = (current_fs->blocksize / i_size );
+ int flag = 0;
+
+
+ for (i=0; i<inodes_per_block;i++){
+ inode = (struct ext2_inode*) (buf + (i_size * i));
+ mode = ext2fs_le16_to_cpu(inode->i_mode);
+ atime = ext2fs_le32_to_cpu(inode->i_atime);
+ ctime = ext2fs_le32_to_cpu(inode->i_ctime);
+ mtime = ext2fs_le32_to_cpu(inode->i_mtime);
+ dtime = ext2fs_le32_to_cpu(inode->i_dtime);
+ if ((!mode) && (!atime) && (!ctime) && (!mtime) && (!dtime) && (!i))
+ return 0;
+ if ((!dtime) && (ctime > min) && (ctime < max) && (atime > min) && (atime < max)
+ && (mtime > min) && (mtime < max) && inode->i_size && inode->i_blocks
+ && LINUX_S_ISREG(mode) && inode->i_block[0] )
+ flag++;
+ if (ctime > max)
+ return 0;
+ }
+ return flag;
+}
+
+
//check if block is a inodeblock local function
static int block_is_inodetable(blk64_t block){
int group;
@@ -813,6 +854,8 @@ static int init_journal(void)
fprintf(stderr,"Error: can't allocate %d Memory\n",maxlen * sizeof(journal_descriptor_tag_t));
goto errout;
}
+ ptl = (__u32*)(pt_buff + (maxlen * sizeof(journal_descriptor_tag_t)));
+ ptl_count = 0;
#ifdef DEBUG
fprintf(stdout, "Journal starts at block %u, transaction %u\n", blocknr, transaction);
@@ -834,6 +877,12 @@ static int init_journal(void)
// fprintf (stdout, "No magic number at block %u: skip this block\n", blocknr);
fprintf(stdout,"-");
#endif
+ if (jb_is_inodetable(buf)){
+// printf("lost %d\n", blocknr);
+ ptl--;
+ *ptl = blocknr;
+ ptl_count ++;
+ }
if ( ! wrapflag ) wrapflag = WRAP_ON ;
blocknr++ ;
continue;
@@ -1069,3 +1118,23 @@ errout:
}
+
+//read the next journal-lost inode block
+int get_pool_block(unsigned char *buf){
+ int retval = 0;
+ int ret = 0;
+ int got,i ;
+ int blocksize = current_fs->blocksize;
+
+ if (ptl_count){
+ retval = read_journal_block(*ptl * blocksize ,buf,blocksize,&got);
+ if ((! retval) && (got == blocksize)){
+ ret = 1;
+ }
+ ptl_count--;
+ ptl++;
+ }
+return ret;
+}
+
+
diff --git a/src/journal.h b/src/journal.h
index 1e90ca9..be28b85 100644
--- a/src/journal.h
+++ b/src/journal.h
@@ -76,5 +76,5 @@ int get_block_bitmap_list( journal_bitmap_tag_t**);//get a list of all copies of
int init_block_bitmap_list(ext2fs_block_bitmap* , __u32); //create and init the the journal block bitmap
void clear_block_bitmap_list(ext2fs_block_bitmap); //destroy the journal block bitmap
int next_block_bitmap(ext2fs_block_bitmap); //produces a differential block bitmap for a transaction from the Journal
-
+int get_pool_block(unsigned char*);
#endif
diff --git a/src/recover.c b/src/recover.c
index 84e3b72..87ac9ed 100644
--- a/src/recover.c
+++ b/src/recover.c
@@ -73,6 +73,11 @@ struct alloc_stat{
__u32 not_allocated;};
+struct alloc_recover_stat{
+ __u32 allocated;
+ __u32 recovered;};
+
+
// recover files from a "double quotes" listfile
void recover_list(char *des_dir, char *input_file,__u32 t_after, __u32 t_before, int flag){
@@ -148,6 +153,21 @@ return ;
}
+// Subfunction for "local_block_iterate3()" for check if blocks not allocated and not recovered
+ static int check_block_stat(ext2_filsys fs, blk64_t *blocknr, e2_blkcnt_t blockcnt,
+ blk64_t /*ref_blk*/x, int /*ref_offset*/y, void *priv )
+{
+//FIXME:
+ if (*blocknr >= fs->super->s_blocks_count)
+ return BLOCK_ERROR;
+ struct alloc_recover_stat *stat = priv;
+ if ( ext2fs_test_block_bitmap (fs->block_map, *blocknr ))
+ (stat->allocated)++ ;
+ if ((bmap) && ( ext2fs_test_block_bitmap (bmap, *blocknr )))
+ (stat->recovered)++ ;
+return 0;
+}
+
// Subfunction for "local_block_iterate3()" for check if the blocks allocated
static int check_block(ext2_filsys fs, blk64_t *blocknr, e2_blkcnt_t blockcnt,
@@ -543,6 +563,26 @@ return retval;
}
+// check inode; return true if blocks not allocated and not recovered
+int check_file_stat(struct ext2_inode *inode){
+ int retval =-1;
+ struct alloc_recover_stat stat;
+
+ if (!(inode->i_mode & LINUX_S_IFMT)) // no type flag
+ return 0;
+
+ stat.allocated = 0;
+ stat.recovered = 0;
+ if ((! inode->i_blocks) || (LINUX_S_ISLNK(inode->i_mode) && (inode->i_size < EXT2_N_BLOCKS*4)) ||
+ ! (ext2fs_inode_data_blocks(current_fs,inode)))
+ retval = 1;
+ else{
+ retval = local_block_iterate3 ( current_fs, *inode, BLOCK_FLAG_DATA_ONLY, NULL, check_block_stat, &stat );
+ if ( retval ) return 0;
+ retval = ((! stat.allocated) && (! stat.recovered)) ? 1 : 0 ;
+ }
+return retval;
+}
// check Datafile return the percentage of not allocated blocks
diff --git a/src/util.h b/src/util.h
index ac1d576..243968e 100644
--- a/src/util.h
+++ b/src/util.h
@@ -205,6 +205,7 @@ ext2_ino_t local_namei(struct dir_list_head_t*, char* , __u32, __u32, int);// se
//public functions recover.c
void recover_list(char*, char*,__u32, __u32, int); // recover files from a "double quotes" listfile
int recover_file( char* ,char* , char* , struct ext2_inode* , ext2_ino_t, int); //recover all filetypes
+int check_file_stat(struct ext2_inode*); //check inode; return true if blocks not allocated and not recovered
int check_file_recover(struct ext2_inode*); // return percentage of not allocated blocks
void set_dir_attributes(char* ,char* ,struct ext2_inode*); //set owner,file mode bits an timestamps for directory
int check_dir(char*);//check if the target directory existent