UFS1 Inodes
Inode data structures store the metadata for each file and directory. Again, UFS1 and UFS2 use different data structures because UFS2 has larger fields. Inodes are divided among the different cylinder groups, and the number of inodes per group is given in the superblock. Each cylinder group has its own inode table, with its location given in the superblock. The starting location of a UFS1 inode table will stagger with each cylinder group, but UFS2 inode tables are always at the same offset relative to the start of the group.
The UFS1 inode is 128 bytes in size and has the fields given in Table 17.7.
Byte Range |
Description |
Essential |
---|---|---|
01 |
File mode (Type and permissions) (see "Inode" section in Chapter 15) |
Yes |
23 |
Link count |
Yes |
47 |
Unused |
No |
815 |
Size |
Yes |
1619 |
Access time |
No |
2023 |
Access time (nanoseconds) |
No |
2427 |
Modified time |
No |
2831 |
Modified time (nanoseconds) |
No |
3235 |
Change time |
No |
3639 |
Change time (nanoseconds) |
No |
4087 |
12 Direct block pointers |
Yes |
8891 |
1 Indirect block pointer |
Yes |
9295 |
1 Double indirect block pointer |
Yes |
9699 |
1 Triple indirect block pointer |
Yes |
100103 |
Status flags |
No |
104107 |
Blocks Held |
No |
108111 |
Generation number (NFS) |
No |
112115 |
User ID |
No |
116119 |
Group ID |
No |
120127 |
Unused |
No |
The mode field has the same values as were given for ExtX. The link serves the same purpose as we previously saw with ExtX, and it is incremented for every file name pointing to it. Refer to Chapter 15 for more details.
Let's look at an inode in our UFS1 image. We saw in the beginning of the chapter that the superblock showed the inode table as being 32 fragments from the group base, and because this is group 0, we know it is in fragment 32. The first usable inode in the file system is number 3, so we extract it with dcat and dd:
# dcat -f openbsd openbsd.dd 32 | dd bs=128 skip=3 count=1 | xxd 0000000: a481 0100 0000 0000 0074 1300 0000 0000 .........t...... 0000016: 689d 0f41 8033 023b 7a9d 0f41 0057 a616 h..A.3.;z..A.W.. 0000032: 7a9d 0f41 0057 a616 2001 0000 2801 0000 z..A.W.. ...(... 0000048: 3001 0000 3801 0000 4001 0000 4801 0000 0...8...@...H... 0000064: 5001 0000 5801 0000 9001 0000 9801 0000 P...X........... 0000080: a001 0000 a801 0000 8001 0000 0000 0000 ................ 0000096: 0000 0000 0000 0000 d009 0000 5ade 19ac ............Z... 00000112: 0000 0000 0000 0000 0000 0000 0000 0000 ................
The first four bytes are the mode, and we parsed one of UFS2 these in the "Inodes" section of Chapter 15, so we will skip that process in this chapter. We can see the 8 in bits 12 to 15, though, so we know that is a regular file. The size is given in bytes 8 to 15, and we see that it is 1,274,880 bytes (0x00137400). The A-time is given in bytes 16 to 19, and when converted to a human readable format results in Tue Aug 3 14:12:56 2004 UTC.
The address of the first block is in bytes 40 to 43, and it is 288 (0x0120). The second block is 296 (0x0128). Note that these are consecutive blocks because the file system has eight fragments per block. We see in bytes 88 to 91 that there is an indirect block pointer being used, and it is located in block 384.
The istat output of this file is as follows:
# istat -f openbsd -z UTC openbsd.dd 3 inode: 3 Allocated Group: 0 uid / gid: 0 / 0 mode: -rw-r--r-- size: 1274880 num of links: 1 Inode Times: Accessed: Tue Aug 3 14:12:56 2004 File Modified: Tue Aug 3 14:13:14 2004 Inode Modified: Tue Aug 3 14:13:14 2004 Direct Blocks: 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 [REMOVED] 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 Indirect Blocks: 384 385 386 387 388 389 390 391
Notice that the output of istat lists every fragment allocated and that the final line has only five fragments.
The allocation status of an inode is stored in an inode bitmap. Each cylinder group has an inode bitmap, and it is located inside of the group descriptor. We saw in the UFS1 group descriptor that the inode table started at a byte offset of 264. We can see it here:
# dcat -f openbsd openbsd.dd 24 8 | xxd [REMOVED] 0000256: 3f00 3f00 3f00 3f00 ff00 0000 0000 0000 ?.?.?.?......... 0000272: 0000 0000 0000 0000 0000 0000 0000 0000 ................ [REMOVED]
Byte 264 is set to 0xff, which means that inodes 0 to 7 are allocated. We previously analyzed inode 3, which we can see is allocated. Inodes 8 and beyond are unallocated in this cylinder group.