<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 6.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>ext2 root directory reader</title>
</head>

<body>



<p align="left"><font size="6" color="#FF0000"><span lang="en-ca"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </b></span>
</font><span lang="en-ca"><font size="6" color="#FF0000"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
ext2 file system reading</b></font></span></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A. First Edition</font></b></pre>
</div>
<div align="left">
	<pre><font size="3"><b>This is just a simple assignment for comp444 and it even takes me a whole day to figure out the &quot;block group </b></font></pre>
</div>
<div align="left">
	<pre><font size="3"><b>descriptor&quot;! What a shame!</b></font></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<div align="left">
  <p ALIGN="LEFT"><span lang="en-ca"><b>To read the root directory!</b></span></div>
<div align="left">
  <p ALIGN="LEFT">　</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca"><a name="explain"></a>C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  　</div>
<p>　</p>
<div align="left">
  <pre><b><font color="#ff0000" size="5">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
  <font SIZE="2">1. Your first partition depends on your system. At command 
	line: type &quot;df&quot; to see what is your main partition. i.e.
	<p>[root@spec127 ~]# df</p>
	<p>Filesystem 1K-blocks Used Available Use% Mounted on</p>
	<p>/dev/sda1 4956284 3971316 729136 85% /</p>
	<p>/dev/shm 1036732 0 1036732 0% /dev/shm</p>
	<p>/dev/sda2 9920624 55336 9353220 1% /home</p>
	<p>/dev/sda4 134490920 170412 127378420 1% /var</p>
	<p>So, your partition name is &quot;/dev/sda1&quot;. And you need to &quot;open&quot; it.</p>
	<p>2. The block size of file system depends on your machine. It is NOT 
	always 1024 bytes. So, you need to read the &quot;super block&quot; and then calculate 
	it by a macro </p>
	<p>int myBlocksize=EXT2_BLOCK_SIZE(&amp;super);</p>
	<p>And the &quot;super&quot; is ext2_super_block where you already read it from 
	system.</p>
	<p>3. &quot;Block Group Descriptor&quot; is NOT immediately after &quot;super block&quot;! (I 
	spent quite a few hours to realize this.) It starts at the beginning of NEXT 
	block after &quot;super block&quot;. i.e. After you read your super block, &quot;lseek&quot; 
	from beginning by offset of 1 block size. </p>
	<p>4. inode table starts at the block index of 
	blockgroupdescriptor.bg_inode_table. And root inode starts after 
	(EXT2_ROOT_INO-1) inodes offset. i.e. lseek to the offset of &quot;block_size*bg_inode_table&quot; 
	and continue lseek &quot;(EXT2_ROOT_INO-1)*inode_size&quot;. Then it is root_inode! 
	(finally!!)</p>
	<p>5. The contents of root inode is stored at the first block even though it 
	says it has 16 blocks! Usually the root inode only needs ONE block. Read the 
	&quot;i_blocks[0]&quot; of inode structure and use this block index to seek the 
	&quot;directory entry table&quot;.</p>
	<p>6. Directory entry is NOT fixed length! You can NOT read it with 
	structure &quot;ext2_dir_entry_2&quot; or &quot;ext2_dir_entry&quot; because it is not right! 
	Just read one by one and offset &quot;rec_len&quot; for next record! Don't forget to 
	add null for each name you read. </p>
	<p>7. If you don't understand what I am talking after #2, then you can only 
	finish first part of assignment. Good luck.</p>
	</font>
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">E</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">F</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>File listing</b></font></span></pre>
</div>
<div align="left" style="width: 898; height: 86">
	<pre><span lang="en-ca"><font size="3"><b>1. myreader.c</b></font></span></pre>
  <pre><font size="3" color="#FF0000"><b><span lang="en-ca">file name: </span></b></font><span lang="en-ca"><font size="3"><b><font color="#FF0000">myreader.c</font></b></font></span></pre>
  <pre>#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;unistd.h&gt;

#include &lt;/usr/include/linux/ext2_fs.h&gt;

int main(int argc, char** argv)
{
	const int SuperSize=sizeof(struct ext2_super_block);
	const int DescSize=sizeof(struct ext2_group_desc);
	const int InodeSize=sizeof(struct ext2_inode);
	const int DirSize=sizeof(struct ext2_dir_entry_2);
	struct ext2_dir_entry_2 dir_entry;
	struct ext2_super_block super;
	struct ext2_group_desc groupDesc;
	int bitmapSize;
	struct ext2_inode root;
	int fd;
	unsigned int nodeCount, blockCount;
	if ((fd=open(&quot;/dev/sda1&quot;, O_RDONLY))&lt;0)
	{
		printf(&quot;open fails\n&quot;);
		_exit(12);
	}

	if (lseek(fd, SuperSize, SEEK_SET)&lt;0)
	{
		printf(&quot;seek fails\n&quot;);
		_exit(13);
	}

	if (read(fd, &amp;super, SuperSize)!=SuperSize)
	{
		printf(&quot;read fails\n&quot;);
		_exit(14);
	}

	if (super.s_magic!=EXT2_SUPER_MAGIC)
	{
		printf(&quot;oh no!\n&quot;);
	}
	printf(&quot;node count=%d and block count=%d\n&quot;, super.s_inodes_count, super.s_blocks_count);
	printf(&quot;block per group=%d\n&quot;, super.s_blocks_per_group);
	printf(&quot;inodes per group=%d\n&quot;, super.s_inodes_per_group);
	printf(&quot;mount count=%d\n&quot;, super.s_mnt_count);
	printf(&quot;first inode=%d\n&quot;, super.s_first_ino);
	printf(&quot;inode size=%d\n&quot;, super.s_inode_size);
	printf(&quot;my block index=%d\n&quot;,super.s_block_group_nr);
	printf(&quot;volume name=%s\n&quot;, super.s_volume_name);
	printf(&quot;pre-allocate block number=%d\n&quot;, super.s_prealloc_blocks);
	printf(&quot;pre_allocate blocks for directory=%d\n&quot;, super.s_prealloc_dir_blocks);

	printf(&quot;first data block=%d\n&quot;, super.s_first_data_block);
	printf(&quot;block size=%d\n&quot;, super.s_log_block_size);
	printf(&quot;block size=%d\n&quot;, EXT2_BLOCK_SIZE(&amp;super));

/*
	memset(&amp;groupDesc, 255, DescSize);
	printf(&quot;block bitmap block index=%d\n&quot;, groupDesc.bg_block_bitmap);
	printf(&quot;inode bitmap block index=%d\n&quot;, groupDesc.bg_inode_bitmap);
	printf(&quot;inode table block index=%d\n&quot;, groupDesc.bg_inode_table);
	printf(&quot;free block count=%d\n&quot;, groupDesc.bg_free_blocks_count);
	printf(&quot;used dir count=%d\n&quot;, groupDesc.bg_used_dirs_count);
*/
	if (lseek(fd, 4096, SEEK_SET)&lt;0)
	{
		printf(&quot;seek fails\n&quot;);
		_exit(13);
	}

	if (read(fd, &amp;groupDesc, DescSize)!=DescSize)
	{
		printf(&quot;read group desc fails\n&quot;);
		_exit(18);
	}
	printf(&quot;block bitmap block index=%d\n&quot;, groupDesc.bg_block_bitmap);
	printf(&quot;inode bitmap block index=%d\n&quot;, groupDesc.bg_inode_bitmap);
	printf(&quot;inode table block index=%d\n&quot;, groupDesc.bg_inode_table);
	printf(&quot;free block count=%d\n&quot;, groupDesc.bg_free_blocks_count);
	printf(&quot;free INODE count=%d\n&quot;, groupDesc.bg_free_inodes_count);
	printf(&quot;pad=%d\n&quot;, groupDesc.bg_pad);

	printf(&quot;used dir count=%d\n&quot;, groupDesc.bg_used_dirs_count);

	//bitmapSize=EXT2_BLOCK_SIZE(&amp;super);

	printf(&quot;go to inode table block %d\n&quot;, groupDesc.bg_inode_table);
	if (lseek(fd, 4096*groupDesc.bg_inode_table, SEEK_SET)&lt;0)
	//if (lseek(fd, 4096*5, SEEK_SET)&lt;0)
	{
		printf(&quot;seek fail again\n&quot;);
		_exit(20);
	}
	if (lseek(fd, InodeSize*(EXT2_ROOT_INO-1), SEEK_CUR)&lt;0)
	//if (lseek(fd, InodeSize*(super.s_first_ino+1), SEEK_CUR)&lt;0)
	{
		printf(&quot;what\n&quot;);
		_exit(23);
	}
	if (read(fd, &amp;root, InodeSize)!=InodeSize)
	{
		printf(&quot;what\n&quot;);
		_exit(23);
	}
	printf(&quot;size=%d, this inode has block number=%d\n&quot;, root.i_size, root.i_blocks);		
	printf(&quot;block numberof first block=%d\n&quot;, root.i_block[0]);
	printf(&quot;imode=%d\n&quot;, root.i_mode);
	printf(&quot;link count=%d, access time %d, modified time %d\n&quot;, root.i_links_count, root.i_atime, root.i_mtime); 

	int i;
	for (i=0; i&lt;root.i_blocks; i++)
	{
		printf(&quot;the pointer of block %d =%d\n&quot;, i, root.i_block[i]);
	}
	printf(&quot;the root directory's data block is %d and let's go there\n&quot;, root.i_block[0]);
	if (lseek(fd, 4096*root.i_block[0], SEEK_SET)&lt;0)
	{
		printf(&quot;what\n&quot;);
		_exit(23);
	}
	int counter=0;
	unsigned int inode;
	unsigned short rec_len;
	unsigned char name_len;
	unsigned char file_type;
	char buffer[255];
	int offset;
	do
	{
		read(fd, &amp;inode, 4);
		printf(&quot;inode number %d\n&quot;,inode);
		read(fd, &amp;rec_len, 2);
		printf(&quot;inode reclength %d\n&quot;,rec_len);
		read(fd, &amp;name_len, 1);
		printf(&quot;name len=%d\n&quot;, name_len);
		read(fd, &amp;file_type, 1);
		read(fd, buffer, name_len);
		buffer[name_len]='\0';
		printf(&quot;name is %s\n&quot;, buffer);
		offset=rec_len-4-2-1-1-name_len;
		lseek(fd, offset, SEEK_CUR);
		switch(file_type)
		{
		case EXT2_FT_UNKNOWN:
			printf(&quot;unknown\n&quot;);
			break;
		case EXT2_FT_REG_FILE:
			printf(&quot;regular\n&quot;);
			break;
		case EXT2_FT_DIR:
			printf(&quot;directory\n&quot;);
			break;
		case EXT2_FT_CHRDEV:
			printf(&quot;chardev\n&quot;);
			break;
		case EXT2_FT_BLKDEV:
			printf(&quot;blk\n&quot;);
			break;
		case EXT2_FT_FIFO:
			printf(&quot;fifo\n&quot;);
			break;
		case EXT2_FT_SOCK:
			printf(&quot;socket\n&quot;);
			break;
		case EXT2_FT_SYMLINK:
			printf(&quot;symbolic link\n&quot;);
			break;
		case EXT2_FT_MAX:
			printf(&quot;max\n&quot;);
			break;
		}
		counter++;
	}
	//while (dir_entry.rec_len!=3999);
	while (rec_len!=4096);
	//while (counter&lt;40);

/*
	if (lseek(fd, 2*SuperSize+DescSize+4096*2+(EXT2_ROOT_INO-1)*InodeSize, SEEK_SET)&lt;0)
	{
		printf(&quot;what?\n&quot;);
		_exit(34);
	}
	read(fd, &amp;root, InodeSize);
	printf(&quot;isize=%d\niblocks=%d\n&quot;, root.i_size, root.i_blocks);

*/
	
	
	
	return 0;
}</pre>
</div>

<pre><span lang="en-ca">			</span></pre>

<pre><span lang="en-ca">				</span> <a href="game24.htm"><img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35"> </pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp;</p>

</body>

</html>