diff options
author | robi <robi> | 2011-12-25 20:38:16 +0000 |
---|---|---|
committer | robi <robi> | 2011-12-25 20:38:16 +0000 |
commit | 9d0ee99f1144cec4c00e04ce6a7e3f2653005df7 (patch) | |
tree | ea2cbe5c3bf112ab1ceb1c1046ba585e4268b3aa /src | |
parent | be0c55229494231393ae0f122cac8d19753d6804 (diff) |
new partial step, recover in journal lost inodes
Diffstat (limited to 'src')
-rw-r--r-- | src/imap_search.c | 92 | ||||
-rw-r--r-- | src/journal.c | 69 | ||||
-rw-r--r-- | src/journal.h | 2 | ||||
-rw-r--r-- | src/recover.c | 40 | ||||
-rw-r--r-- | src/util.h | 1 |
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 @@ -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 |