How do I read ext2 root directory from mapped memory?

979 views Asked by At

I'm making a Remote Filesystem Server for my university and I'm having some trouble with reading the root directory... Here's the thing: I've read the root inode (inode 2) and it has consistent data, I mean that, for example, owner user Id field is set at '1000'. Then I proceed to read the contents of the inode data blocks, but when I try to access to the data block in question (the only one that is addressed in the inode i_block array, 240 on my debugging) all bytes are set to '0'. Can anyone help me with this? It's really important. Note: I cannot make it another way than with mapped memory and I'm not opening a real disk, but rather opening a .disk linux file. It has been created with the command-line

mkfs.ext2 -F -r 0 -b 1024 ext2.disk 30000

Here's my code:

#include <linux/ext2_fs.h>

typedef struct s_inode *pinode;         /* Pointer to inode struct  */
typedef struct s_direct *pdir;          /* Pointer to direct struct */

int main(int argv, char *argc[]){
   int *data;
   pdir root = malloc(sizeof(struct s_direct));

   /* Code for mpping .disk file, fetching supernode, and other ext2 data */
   /* fsys is a global variable that holds general ext2 system data       */
   fsys->root           = get_inode(2);
   data                 = get_cont(fsys->root);
   root                 = (pdir)getblock(data[0]);

}

pinode get_inode(int idx){
    pinode inod;
    int grp, offs;

    grp =  (idx-1)/fsys->superblock->s_inodes_per_group;
    offs = (idx-1)%fsys->superblock->s_inodes_per_group;
    inod = (pinode)&fsys->diskmap[(fsys->group[grp]->itab)+offs*sizeof(struct s_inode)];

    return inod;
}

int *get_cont(pinode inod){
    int *cont; 
    int *idx;
    int i=0;
    int *block;

    idx  = malloc(sizeof(int)); 
    cont = malloc(sizeof(int));

    while(i < inod->i_blocks && i<13) {
            realloc(cont, i*sizeof(int));
            cont[i]=inod->i_block[i];
            i++;
    }

    if(i < inod->i_blocks){
        *idx=13;
        block=(int*)getblock(inod->i_block[*idx]);
        fetchcont(block, idx, cont, inod->i_blocks, 0);
    }
    if(i < inod->i_blocks){
        block=(int*)getblock(inod->i_block[*idx]);
        fetchcont(block, idx, cont, inod->i_blocks, 1);
    }
    if(i < inod->i_blocks){
        block=(int*)getblock(inod->i_block[*idx]);
        fetchcont(block, idx, cont, inod->i_blocks, 2);
    }

    return cont;

}

int fetchcont(int *block, int *idx, int *cont, int lim, int lvl){
    int i=0;

    if(lvl == 0){
        while((*idx) < lim && i<fsys->bsize){
            realloc(cont, (*idx)*sizeof(int));
            cont[*idx]=block[i];
            (*idx)++;
            i++;
        }
        if(i>=fsys->bsize){
            return 1;
        }else{
            return 0;
        }
    }else{
        lvl--;
        while(i<fsys->bsize){
            if(!fetchcont((int*)getblock(block[i]), idx, cont, lim, lvl)){
                return 0;
            }
            i++;
        }

    }
}

void *getblock(int idx){
    char *block;
    int grp, offs;

    grp   = (idx-1)/fsys->superblock->s_blocks_per_group;
    offs  = (idx-1)%fsys->superblock->s_blocks_per_group;
    block =  &fsys->diskmap[fsys->group[grp]->blocks+offs*fsys->bsize];

    return block; 
}
1

There are 1 answers

0
Vladimir On

Solved the problem. I assumed that block n was the n data block, but the offset included ALL the blocks. I've changed my getblock function to

void *getblock(int idx){

    return &fsys->diskmap[fsys->bsize*idx];
}

and worked!