Page 1 of 3

Ext2: reading directory entries reads zeros.

Posted: Mon Sep 05, 2016 2:12 pm
by osdever
I've tried everything, but nothing happens. Maybe it reads info from wrong address, so please correct me.

Code: Select all

//ext2_info:  Outputs ext2 volume information from superblock.
void ext2_info(unsigned int ata_drive)
{
	if(!is_valid_ext2(ata_drive))
	{
		fprintf(stderr, "[EXT2] Invalid ext2 filesystem on disk %d.", ata_drive);
		return;
	}
	struct ext2_superblock *superblock=malloc(sizeof(struct ext2_superblock));
	ata_read_bytes(ata_drive, (void*)superblock, sizeof(struct ext2_superblock), 1024);
	printf("EXT2 %u.%u volume with ATA number %u and volume label \"%s\" information:\n", superblock->ver_major, superblock->ver_minor, ata_drive, superblock->volume_label);
	printf("\tLast mounted on %s\n", superblock->last_mount_path);
	uint32_t block_size=1024 << superblock->block_size;
	uint32_t inode_size=1024 << superblock->inode_size;
	printf("\tFree space: %d/%d bytes (%d/%d blocks)\n", (superblock->blocks_count-superblock->unallocated_blocks_count) * block_size, superblock->blocks_count * block_size, superblock->blocks_count-superblock->unallocated_blocks_count, superblock->blocks_count);
	printf("\tFilesystem is %s\n", (superblock->fs_state==1) ? "clean" : "with errors");
	//Parse inode 2 and list root directory.
	uint32_t block_group_count = superblock->blocks_count / superblock->blocks_count_in_blk_group;
	struct ext2_block_group_descriptor *bgd=malloc(sizeof(struct ext2_block_group_descriptor) * block_group_count);
	ata_read_bytes(ata_drive, (void*)bgd, sizeof(struct ext2_block_group_descriptor) * block_group_count,
	  (block_size == 1024) ? block_size * (2+1) : block_size * (1+1));
	//get inode function:
	uint32_t inode = 2; //Root directory inode is defined to always be 2.
	uint32_t block_group = (inode - 1)  / superblock->inodes_count_in_blk_group;
	uint32_t inode_index = (inode - 1)  % superblock->inodes_count_in_blk_group;
	uint32_t block       = (inode_index * inode_size) / block_size;
	uint32_t inodes_cnt  = superblock->inodes_count_in_blk_group - bgd->unallocated_inodes_count;
	printf("\tAllocating %u bytes,\n", sizeof(struct ext2_inode));
	struct ext2_inode *inode_struct = malloc(sizeof(struct ext2_inode));
	ata_read_bytes(ata_drive, (void*)inode_struct, sizeof(struct ext2_inode) * inodes_cnt, bgd[block_group].inode_table_address * block_size + inode_index * inode_size);
	//inode_struct[inode_index].direct_block_pointers[0];
	block=block;
	printf("\tInode table is on %u, block number of root directory is %u, block size is %u\n", bgd[block_group].inode_table_address, inode_struct->direct_block_pointers[0], block_size);
	struct ext2_directory_entry *dirent = malloc(sizeof(struct ext2_directory_entry));
	uint16_t name_length = dirent->name_length_low | (dirent->type_or_name_length_high << 8);
	ata_read_bytes(ata_drive, (void*)dirent, sizeof(struct ext2_directory_entry), inode_struct->direct_block_pointers[0] * block_size + sizeof(struct ext2_directory_entry));
	dirent = realloc((void*)dirent, sizeof(struct ext2_directory_entry) + name_length);
	char *filename = malloc(name_length);
	ata_read_bytes(ata_drive, (void*)filename, name_length, inode_struct->direct_block_pointers[0] * block_size+sizeof(struct ext2_directory_entry) * 2);
	printf("Filename: %s\n", filename);
	printf("Read inode from 0x%08X\n", inode_struct->direct_block_pointers[0] * block_size + sizeof(struct ext2_directory_entry));
	for(unsigned i=0; i<sizeof(struct ext2_directory_entry) + name_length; i++)
		printf("0x%02x ", *((char*)dirent+i)); //Zeros!
	//end
}

Re: Ext2: reading directory entries reads zeros.

Posted: Mon Sep 05, 2016 3:06 pm
by glauxosdever
Hi,

catnikita255 wrote:

Code: Select all

printf("0x%02x ", *((char*)dirent+i)); //Zeros!
Have you tried to change casts in this line?
Note: I didn't take more that a few looks at the code, so I can't know.
catnikita255 wrote:

Code: Select all

block=block;
This line is redundant.

As for used variables, have you tried to print them out, in order to figure out which ones are unexpected? These unexpected values are usually the root cause of the problem.

On a last note, you might want to write a new version of the code, while looking however at the old one. I have found this method can help catch many bugs.


Regards,
glauxosdever

Re: Ext2: reading directory entries reads zeros.

Posted: Mon Sep 05, 2016 3:26 pm
by crunch
Are you sure your ATA driver functions are correct? Where exactly is your code failing? Can you see the superblock info, or is it an issue with reading the inode?

Re: Ext2: reading directory entries reads zeros.

Posted: Tue Sep 06, 2016 6:24 am
by osdever
ATA driver works perfectly, only inodes are failing. Code in first lines works.

Re: Ext2: reading directory entries reads zeros.

Posted: Tue Sep 06, 2016 8:52 am
by osdever
glauxosdever wrote: As for used variables, have you tried to print them out, in order to figure out which ones are unexpected? These unexpected values are usually the root cause of the problem.
Code wrote that inode table is on 0 block. It's can't be true, yes?

Re: Ext2: reading directory entries reads zeros.

Posted: Tue Sep 06, 2016 9:00 am
by glauxosdever
Hi,

catnikita255 wrote:
glauxosdever wrote: As for used variables, have you tried to print them out, in order to figure out which ones are unexpected? These unexpected values are usually the root cause of the problem.
Code wrote that inode table is on 0 block. It's can't be true, yes?
I'm sorry, but I don't see any real correlation between your statement and my statement.

Next time, please try to be more precise and more specific.


Regards,
glauxosdever

Re: Ext2: reading directory entries reads zeros.

Posted: Tue Sep 06, 2016 2:39 pm
by osdever
Problem is in inode table block number that I get: it's zero. But I don't know the cause of it.

Re: Ext2: reading directory entries reads zeros.

Posted: Tue Sep 06, 2016 6:58 pm
by crunch
I have a feeling that you're not reading the block group descriptors or superblock correctly. Try dumping out those structures and making sure everything is right.
There is code in the github repositories in my signature with working ext2 read and write. Hopefully not too hard to read. If you can paste a screenshot of your output showing values for the block group desc and superblock, maybe I can help you some more.

Re: Ext2: reading directory entries reads zeros.

Posted: Wed Sep 07, 2016 6:22 am
by osdever
Block group descriptor's data is fully zero, exactly as directory entry. About superblock: should I show you all its data?

Re: Ext2: reading directory entries reads zeros.

Posted: Wed Sep 07, 2016 10:40 am
by crunch
catnikita255 wrote:Block group descriptor's data is fully zero, exactly as directory entry. About superblock: should I show you all its data?
Well it sounds like one of three things:
- Disk driver doesn't work
- You're trying to read the wrong blocks for superblock/group desc (Should be block 1 [1024-2048 bytes on disk] for super block)
- The disk image is not properly formatted. Run fsck or dumpe2fs on your image.

Re: Ext2: reading directory entries reads zeros.

Posted: Fri Sep 09, 2016 8:43 am
by osdever
crunch wrote:
catnikita255 wrote:Block group descriptor's data is fully zero, exactly as directory entry. About superblock: should I show you all its data?
Well it sounds like one of three things:
- Disk driver doesn't work
- You're trying to read the wrong blocks for superblock/group desc (Should be block 1 [1024-2048 bytes on disk] for super block)
- The disk image is not properly formatted. Run fsck or dumpe2fs on your image.
1) It works normally. 2) Superblock data is valid, but not BGD. 3) It works normally in Linux.

Re: Ext2: reading directory entries reads zeros.

Posted: Fri Sep 09, 2016 10:38 am
by crunch
You're reading the wrong block number for the BGD. BGD is located in the block immediately following the super block (block 2)

Re: Ext2: reading directory entries reads zeros.

Posted: Fri Sep 09, 2016 11:15 am
by osdever
Fixed, now BGD reads from right location, now its values are non-null, but data isn't right anyway. Modified code and output are included.

Code: Select all

printf("Block group descriptor table is on byte %d from start of the disk.\n", block_size * ((block_size == 1024) ? 2 : 1));
	uint32_t block_group_count = superblock->blocks_count / superblock->blocks_count_in_blk_group;
	struct ext2_block_group_descriptor *bgd=malloc(sizeof(struct ext2_block_group_descriptor) * block_group_count);
	ata_read_bytes(ata_drive, (void*)bgd, sizeof(struct ext2_block_group_descriptor) * block_group_count,
	  block_size * ((block_size == 1024) ? 2 : 1));

Re: Ext2: reading directory entries reads zeros.

Posted: Fri Sep 09, 2016 12:04 pm
by crunch
Those values don't all look bogus. Depending on the size of your disk, the bitmap and inode table positions look to be correct.
Why does your superblock say only 306 blocks are free? Is that right?

I'd check to make sure your structures are correct.

You can use this for reference or check on the wiki
Image

Re: Ext2: reading directory entries reads zeros.

Posted: Fri Sep 09, 2016 1:11 pm
by osdever
crunch wrote:Those values don't all look bogus. Depending on the size of your disk, the bitmap and inode table positions look to be correct.
Why does your superblock say only 306 blocks are free? Is that right?

I'd check to make sure your structures are correct.

You can use this for reference or check on the wiki
Image
1) I know.
2) I don't know, why it says it.
3) Ok.