5

A directory inode isn't substantially different from that of a regular file's inode, what I comprehend from Ext4 Disk Layout is that:

Directory Entries: Therefore, it is more accurate to say that a directory is a series of data blocks and that each block contains a linear array of directory entries.

The directory entry stores the filename together with a pointer to its inode. Hence, if the documentation says each block contains directory entries, why debugfs reports something different that the filenames stored in the directory's inode? This is a debugging session on an ext4 formatted flash drive:

debugfs:  cat /sub
�
 .
  ..�
     spam�spam2�spam3��spam4

I don't think inode_i_block can store those filenames, I've created files with really long filenames, more than 60 bytes in size. Running cat on the inode from debugfs displayed the filenames too, so the long filenames were in the inode again!

The Contents of inode.i_block:

Depending on the type of file an inode describes, the 60 bytes of storage in inode.i_block can be used in different ways. In general, regular files and directories will use it for file block indexing information, and special files will use it for special purposes.

Also, there's no reference to the inode storing the filenames in Hash Tree Directories section which is the newer implementation. I feel I missed something in that document.

The main question is if a directory's inode contain filenames, what do its data blocks store then?

direprobs
  • 944
  • 14
  • 29

4 Answers4

13

Directory entries are stored both in inode.i_block and the data blocks. See "Inline Data" and "Inline Directories" in the document you linked to.

Johan Myréen
  • 12,862
  • 1
  • 32
  • 33
  • 1
    On my filesystem it turned out that the inode doesn't actually store the filenames! `debugfs`. `dump_inode` and `cat` don't read the directory's inode, they instead read the actual contents in its allocated blocks. You could check that by using `debugfs: dump_inode / out.hex`, from the hex editor I noticed the size is 4096 bytes of the file this is equal to the filesystem's I/O block on my machine. Not all of that block was actually used, so I added more to it to see if the zeros are going to be filled. I added more entries to the dir that exceeded 4096B, more 4K blocks were alloc! – direprobs Aug 20 '17 at 22:56
9

cat outputs file contents, i.e. data blocks. Similar to /bin/cat.

The cat command would not be useful if it wrote the bytes of the inode structure to the terminal. Compare inode_dump and stat.

Some documents will tell you that historical unix allowed e.g. /bin/cat to read this data, and this was the original way to list directory entries from userspace. I.e. ls would open the directory, read() the entries, and interpret them for you. As opposed to using readdir(), where the kernel provides the entries in a standard format, regardless of the underlying file system format.

sourcejedi
  • 48,311
  • 17
  • 143
  • 296
  • If you enter ? in the interactive session of `debugfs` you'll see this description for `cat`: "Dump an inode out to stdout" – direprobs Aug 20 '17 at 21:03
  • You're right about that, `cat` doesn't really shows the directory's inode, but its contents. `debugfs` 's man page doesn't mention anything about that. – direprobs Aug 20 '17 at 22:38
6

A directory's data contains dirent entries. Each directory entry contains a filename and a pointer to an inode. An ext4 inode can contain the data contents of a small file for efficiency, so that it doesn't have to perform yet another block read.

The value of "small" can be 60 bytes with file attributes, or up to 160 bytes if extended file attributes aren't being used.

roaima
  • 107,089
  • 14
  • 139
  • 261
  • That was a typo sorry about that! :\ In both cases that's what I meant essentially. I need to edit my question. – direprobs Aug 20 '17 at 20:40
4

I don't think the debugfs cat command shows the contents of the inode itself, though I think the language in the man page is confusing. Numerous places, the man page refers an "inode filespec" which I think is a redundant way of reminding the reader that a filespec can be either a pathname or an inode number. Compare the following excerpts from the man page:

cat filespec - Dump the contents of the inode filespec to stdout.

stat filespec - Display the contents of the inode structure of the inode filespec.

I think cat is showing the contents of the "inode filespec", not showing the contents of the inode, filespec. The filenames are definitely listed in the data blocks, not the inode.

sourcejedi
  • 48,311
  • 17
  • 143
  • 296
Jeremy Dover
  • 206
  • 1
  • 6
  • Hi, edited to match formatting of `man debugfs` on my terminal, allowing for stackexchange lacking underline. It does seem the manpage was confusing, but let us not make it even more so... unless there was the same problem on both of your terminals? – sourcejedi Aug 20 '17 at 20:05