summaryrefslogtreecommitdiff
path: root/src/inode.c
diff options
context:
space:
mode:
authorrobi <robi>2011-10-19 00:02:48 +0000
committerrobi <robi>2011-10-19 00:02:48 +0000
commitaacfa4d0120b4d979f62a37a10b9d3cf2755e8dc (patch)
treef6b47457209d82498ee4f599f5c869fbd3268a62 /src/inode.c
parent76cdc3cf7ccdd9fa0d796c829924c7d00fab22dd (diff)
ext4 magic function part 1
Diffstat (limited to 'src/inode.c')
-rw-r--r--src/inode.c157
1 files changed, 81 insertions, 76 deletions
diff --git a/src/inode.c b/src/inode.c
index 5ce54ad..7fb673e 100644
--- a/src/inode.c
+++ b/src/inode.c
@@ -30,6 +30,7 @@
#include "inode.h"
#include "ring_buf.h"
+#include "extent_db.h"
extern ext2_filsys current_fs;
extern time_t now_time ;
@@ -841,6 +842,7 @@ errout:
return NULL;
}
+
// get the first Journal Inode by time_stamp
int read_time_match_inode( ext2_ino_t inode_nr, struct ext2_inode* inode_buf, __u32 time_stamp){
struct ring_buf* i_ring;
@@ -913,92 +915,90 @@ return inode;
}
+
+
//add extent to inode
-int inode_add_extent(struct ext2_inode_large* inode , blk_t blk , void *buf, int flag) {
+int inode_add_extent(struct ext2_inode_large* inode , struct extent_area* ea, __u32* last, int flag ){
+ int ret = 0;
struct ext3_extent_idx *idx;
struct ext3_extent_header *header;
- struct ext3_extent_header *data_header;
struct ext3_extent *extent;
- unsigned long long i_size;
- __u32 l_block,l_count,l_start,i;
-
+ struct ext3_extent *extent_new;
+ __u64 i_size;
+
+ if ((!ea ) || (!ea->blocknr))
+ return 0;
header = (struct ext3_extent_header*) inode->i_block;
- if (flag && buf){
- data_header = (struct ext3_extent_header*) buf;
- if (ext2fs_le32_to_cpu(header->eh_entries) >= ext2fs_le32_to_cpu(header->eh_max)){
+ if (flag){
+// flag == 1 ; add extent index
+ if (ext2fs_le16_to_cpu(header->eh_entries) >= ext2fs_le16_to_cpu(header->eh_max)){
fprintf(stderr," Error: can not add a extent to inode\n");
return 0;
}
idx = (struct ext3_extent_idx*) (header + (ext2fs_le16_to_cpu(header->eh_entries) + 1));
if (! header->eh_entries)
- header->eh_depth = ext2fs_cpu_to_le16(ext2fs_le16_to_cpu(data_header->eh_depth) +1);
+ header->eh_depth = ext2fs_cpu_to_le16(ea->depth) +1;
- idx->ei_leaf = ext2fs_cpu_to_le32(blk);
+ idx->ei_leaf = ext2fs_cpu_to_le32(ea->blocknr);
idx->ei_leaf_hi = 0;
idx->ei_unused = 0;
- l_count = 0;
- extent = (struct ext3_extent*)(data_header + 1);
- l_start = ext2fs_le32_to_cpu(extent->ee_block);
- for (i=1; i<=ext2fs_le16_to_cpu(data_header->eh_entries); i++){
- l_count += ext2fs_le16_to_cpu(extent->ee_len);
- l_block = ext2fs_le32_to_cpu(extent->ee_block) + ext2fs_le16_to_cpu(extent->ee_len) ;
- extent++;
- }
-
- idx->ei_block = ext2fs_cpu_to_le32(l_start);
+ idx->ei_block = ext2fs_cpu_to_le32(ea-> l_start);
header->eh_entries = ext2fs_cpu_to_le16(ext2fs_le16_to_cpu(header->eh_entries) + 1 );
-//blockhex (stdout, (void*) inode->i_block, 0, 60);
+ ret = 1;
+ }
+ else{
+// flag == 0 : add or attach a extent entry
+ if (! ext2fs_le16_to_cpu(header->eh_entries))
+ header->eh_entries = ext2fs_cpu_to_le16(1);
+
+ extent = (struct ext3_extent*) (header + (ext2fs_le16_to_cpu(header->eh_entries)+1));
+// new
+ if(!(ext2fs_le32_to_cpu(extent->ee_start))){
+ extent->ee_start = ext2fs_cpu_to_le32(ea->start_b);
+ extent->ee_len = ext2fs_cpu_to_le16(ea->len);
+ ret = 1 ;
+ }
+ else{
+// attach
+ if (ea->start_b == (ext2fs_le32_to_cpu(extent->ee_start) + ext2fs_le16_to_cpu(extent->ee_len))){
+ extent->ee_len = ext2fs_cpu_to_le16(ext2fs_le16_to_cpu(extent->ee_len)+ ea->len);
+ ret = 1;
+ }
+ }
+ if ((! ret) && (ext2fs_le16_to_cpu(header->eh_entries) < ext2fs_le16_to_cpu(header->eh_max))){
+// new entry
+ header->eh_entries = ext2fs_cpu_to_le16(ext2fs_le16_to_cpu(header->eh_entries) + 1 );
+ extent_new = (struct ext3_extent*) (header + (ext2fs_le16_to_cpu(header->eh_entries)+1));
+// extent->ee_start_hi
+ extent_new->ee_start = ext2fs_cpu_to_le32(ea->start_b);
+ extent_new->ee_len = ext2fs_cpu_to_le16(ea->len);
+ extent_new->ee_block = ext2fs_cpu_to_le32(ext2fs_le32_to_cpu(extent->ee_block)+ext2fs_le16_to_cpu(extent->ee_len));
+ ret = 1 ;
+ }
+ }
+ if (ret){
i_size = (unsigned long long)(inode->i_size | ((unsigned long long)inode->i_size_high << 32));
- i_size += (l_block * current_fs->blocksize);
+ i_size += ea->size;
inode->i_size = i_size & 0xffffffff ;
inode->i_size_high = i_size >> 32 ;
- inode->i_blocks += ((l_count + 1) * (current_fs->blocksize / 512)) ;
-blockhex (stdout, (void*) inode, 0, 128);
- }
-
-return 1;
-}
-
-
-
-//search the last data block ext4-inode
-blk_t get_last_block_ext4(struct ext2_inode_large* inode){
- blk_t blk;
- struct ext3_extent_idx *idx;
- struct ext3_extent_header *header;
- struct ext3_extent *extent;
- unsigned char *buf = NULL;
-
- buf = malloc(current_fs->blocksize);
- if (!buf) return 0;
-
- header = (struct ext3_extent_header*) inode->i_block;
- while (ext2fs_le16_to_cpu(header->eh_depth)){
- idx = (struct ext3_extent_idx*) (header + (ext2fs_le16_to_cpu(header->eh_entries)));
-
- if(io_channel_read_blk ( current_fs->io,ext2fs_le32_to_cpu(idx->ei_leaf), 1, buf )){
- fprintf(stderr,"Error read block %lu\n",ext2fs_le32_to_cpu(idx->ei_leaf));
- return 0;
- }
-
- header = (struct ext3_extent_header*) buf ;
-
+ inode->i_blocks += (ea->b_count * (current_fs->blocksize / 512)) ;
+ *last = (ea->end_b) ? ea->end_b : 0 ;
+// blockhex (stdout, (void*) inode, 0, 128);
}
- extent = (struct ext3_extent*)(header + ext2fs_le16_to_cpu(header->eh_entries));
-
- blk = ext2fs_le32_to_cpu(extent->ee_start) + ext2fs_le16_to_cpu(extent->ee_len);
-
- if (buf) free(buf);
-return --blk;
+ else
+ fprintf(stderr," Error: can not add a extent to inode\n");
+return ret;
}
-//add a block to inode
-int inode_add_block(struct ext2_inode_large* inode , blk_t blk , __u32 size) {
+//add a block to inode, (ext3 only the first 12 blocks)
+int inode_add_block(struct ext2_inode_large* inode , blk_t blk ){
int i = 0 ;
unsigned long long i_size;
+ struct ext3_extent *extent;
+ struct ext3_extent_header *header;
if (! (inode->i_flags & EXT4_EXTENTS_FL)){
//ext3
@@ -1011,30 +1011,36 @@ int inode_add_block(struct ext2_inode_large* inode , blk_t blk , __u32 size) {
}
inode->i_block[i] = blk;
- i_size = (unsigned long long)(inode->i_size | ((unsigned long long)inode->i_size_high << 32));
- i_size += size;
- inode->i_size = i_size & 0xffffffff ;
- inode->i_size_high = i_size >> 32 ;
- inode->i_blocks += (current_fs->blocksize / 512);
}
else{
-// printf("ERROR: ext3 block %u : but is a ext4_inode\n", blk);
- //FIXME ext4
+ //ext4
+ header = (struct ext3_extent_header*) inode->i_block;
+ if (! ext2fs_le16_to_cpu(header->eh_entries)) {
+ header->eh_entries = ext2fs_cpu_to_le16(1);
+ extent = (struct ext3_extent*) (header + (ext2fs_le16_to_cpu(header->eh_entries)));
+ extent->ee_start = ext2fs_cpu_to_le32(blk);
+ }
+ else
+ extent = (struct ext3_extent*) (header + (ext2fs_le16_to_cpu(header->eh_entries)));
+ extent->ee_len = ext2fs_cpu_to_le16(ext2fs_le16_to_cpu(extent->ee_len) +1);
}
+ i_size = (unsigned long long)(inode->i_size | ((unsigned long long)inode->i_size_high << 32));
+ i_size += current_fs->blocksize;
+ inode->i_size = i_size & 0xffffffff ;
+ inode->i_size_high = i_size >> 32 ;
+ inode->i_blocks += (current_fs->blocksize / 512);
+
return 1;
-}
+}
//add the ext3 indirect Blocks to the inode
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;
+ blk_t block_count = 0;
+ //blk_t b_blk,count=0;
+ int i = 0;
__u64 i_size = 0;
int ret = 0;
-
- i = 0;
- block_count = 0;
if (! (inode->i_flags & EXT4_EXTENTS_FL)){
@@ -1073,6 +1079,5 @@ int inode_add_meta_block(struct ext2_inode_large* inode , blk_t blk, blk_t *last
// printf("ERROR: ext3 indirect block %u ; but is a ext4_inode\n", blk);
//FIXME ext4
}
-
return 0;
}