How to read an inode table from an ext2 block group? - c

In writing an ext2 driver for my hobby OS, I ran into a problem reading the inode table from a block group descriptor.
The third field of the block group descriptor is the block ID of the inode table for that group. In my case for the root directory of my file system this comes back as 64. The superblock is located at block 1, which is 1024 bytes past the beginning of the volume. The block size is 1024 bytes, but my disk sector size is 512. So to access the superblock, I read from lba 2.
The problem is when I try to read the inode table. If it's block id is 64, and my block size is 1024 and disk sector size is 512, wouldn't I read the inode table from disk sector 130? I do that, but nothing is there...
What is the proper way to read an inode table given a valid block group descriptor?

The block IDs in the block group descriptor table are all absolute, so block ID 64 is going to be stored at LBA 128 and 129 in your case.

Related

What is the data structure used to store your inodes?

As I understand it each file has an inode that holds the data block location and some metadata about that file. What is the method in which these inodes are stored and referenced too? I'm not asking about the inode structure itself but how we differentiate each by its inode number. Do we have a new structure of an inode table kind of like a bitmap? an array of say inodes[0] would make sense to access the inode number of zero.
or I think I am miss understanding. In our file system we store an Inode into the first blocks of memory so say our first block of memory is inode1 and to access the second inode you reach the second block of memory by point to the start of memory plus the size of a block of memory
This is a possible disk layout for a simple file system. The boot block contains special data used to start the entire system. The superblock contains information describing the file system.After the superblock, there may be a section of memory dedicated to a bitmap that tracks how unused blocks in the system. After the bitmap, there is the inode section.
You could have an inode table that is an array of inode structs that would do the translation of inode number to inode for you. It would be as easy as inode_table[0].
Alternatively, and this is how I learned it in my systems class, if you have functions to read and write sectors from physical disk and you know which sector for which the inode section starts and the size of a sector and the size of an inode in bytes, using a bit of arithmetic and modulus operations you can easily fetch the specific inode from the filesystem without the use of an inode table.

Block Size and inode size in a filesystem

I am going through the book , "Practical Filesystem design " by "Dominic Giampaolo" .
The two important concepts are
Block : The smallest readable or writable unit of memory for a filesystem .
Inode : Inode , is , an area, which stores the data about a file , stores the data about where the blocks composing a file are stored .
The author states about the simplicity introduced by storing a few block addresses directly in i-node . Then he mentions about tradeoff that is faced between "the size of the i-node" and how much data the i-node map .
As such he mentions that the size of the i-node works best when it is an even divisor of the block size .
How to reason out the above statement ? Any calculations to support this ?
Since all read/write operations operate at the block-level, then having your inodes block-aligned and occupying entire blocks ensures that your reads/writes are not wasteful.
If a block is 4096 bytes, but an inode is just 4000 bytes, then either:
1. our inodes are block-aligned: we're not very efficient since we always waste 96 bytes of every block.
2. our inodes are not block-aligned: we're not very efficient since when we want to read an inode, we often need to read two blocks - and none of them will be 100% occupied by inode data.
We remain efficient when:
1. The size of an inode equals to the size of a block (1:1 ratio)
2. The size of an inode is an exact multiple of the size of a block (1:n ratio)
3. The size of a block is an exact multiple of the size of an inode (n:1 ratio)

Does a zero-length file take up a block on disk?

I understand if a file has 1 byte, it will still take up an entire block on disk (e.g. 4KB). Is the same true for a zero-length file? I am specifically wondering about NTFS but insight on other file systems welcome!
No, in case of NTFS, if file has 1 byte, it doesn't use any block. In general, if file has less than 300 bytes (approximately and in case that file record in MFT has 512 bytes - this value depends on file name length, size of MTF file record, etc.), data are located in MFT (master file table). Only if it doesn't fit in one file record (in MFT), then data are externalized to blocks (usually 4 KB).

How does memory translation work in the FAT filesystem?

I am required to create my own implementation of a filesystem in C. I am planning on creating a system similar to that of the FAT system. We are given one file of size 10MB, which acts as our own "disk." I understand that the FAT table stores cluster numbers, and the Root Directory stores other pertinent information about each file we create (e.g. file name, size, date and time of last modification, start block in FAT, etc.). But I am confused about how the cluster numbers are translated to physical addresses in the data region on the disk.
For example, let's say an entry in the Root Directory says that a file starts in block 100 in the FAT table, and in block 100 of the FAT table is the integer 327, which is where the next cluster of the file is located. How are these addresses translated to physical addresses in the data region of the disk? Where are these physical addresses translated and stored?
Clusters vary in size between different versions of FAT (FAT12, FAT16, and FAT32), but in general the cluster number points to a consecutively numbered cluster of whatever size is present in the format for the existing file system. As I recall (from long ago) FAT12, at least on hard disks, used 2 kibibyte clusters (made up of four 512-byte sectors each), with a maximum cluster number of 2^11 (12 bits starting with zero), so cluster 327 would be 327 * 2048 bytes from the start of the data area of the disk.
The data area includes the FAT, backup FAT, and all directories. My recollection is that each cluster entry in the FAT contains a pointer to the next cluster in the file that occupies that cluster, length of data if it's the last cluster of the file, and some other information needed in reading or writing the file, while the directory entry contains the file name, first cluster, size/date/etc..
A disk is divided into sectors. A hard disk for example has a sector size of 512 bytes. Addressing data on the disk usually uses these sectors and data is read/written in blocks of this size. The FAT filesystem groups a number of sectors into clusters. For example you could have 8 sectors per cluster. This constant is stored along with other information about the filesystem in the first few sectors of the partition. The FAT driver uses this value to compute the sector number from the cluster number. The formula is something like this:
SectorNumber = SectorsPerCluster * ClusterNumber + Constant
The constant is the sector number of the first sector of the data region of the partition. You can find the exact formula in the FAT Specification.

Xfs file size, inode size and block size

ll /srv/node/dcodxx/test.sh
-rw-r--r--. 1 root root 7 Nov 5 11:18 /srv/node/dcodxx/test.sh
The size of the file is shown in bytes. This file is stored in an xfs filesystem with block size 4096 bytes.
xfs_info /srv/node/sdaxx/
meta-data=/dev/sda isize=256 agcount=32, agsize=7630958 blks
= sectsz=4096 attr=2, projid32bit=0
data = bsize=4096 blocks=244190646, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0
log =internal bsize=4096 blocks=119233, version=2
= sectsz=4096 sunit=1 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
Does this mean that a block can house more than one file, if not what happens to the remaining bytes (4096-7)?
Also, where is the 256 bytes reserved for an inode stored, if it stored in the same block as the file, shouldn't the file size be larger(256+7)?
File data is stored in units of the filesystem block size, and no block sharing is currently possible across multiple files on XFS. So used disk space is always the number of bytes in the file rounded up to the next block size - a 1-byte file will consume 4k of diskspace on a 4k block size filesystem.
The inode itself contains file metadata such as size, timestamps, extent data, etc - and on xfs it can also contain extended attribute information.
The on-disk inode is separate from the file data blocks, and will always consume 256 bytes on a filesystem with 256 byte inodes, regardless of the amount of metadata used. If more than 256 bytes is required to store additional extent information or extended attribute data, additional filesystem-block-sized metadata blocks will be allocated.
Does this mean that a block can house more than one file, if not what happens to the remaining bytes (4096-7)?
A block cannot contain more than one file. If a file is bigger than one block, multiple blocks are used.
Modern filesystems like XFS have a functionality called "inline", where files small enough (no more than 60 bytes) can be stored in the inode, in the space taken to store pointers to the blocks.
where is the 256 bytes reserved for an inode stored, if it stored in the same block as the file, shouldn't the file size be larger(256+7)?
Inode information is stored in the inode table.

Resources