Inodes store information about files and directories (folders), such as file ownership, access mode (read, write, execute permissions), and file type. Each file is associated with an inode, which is identified by an integer, often referred to as an i-number or inode number.
ok, let’s start:
struct erofs_inode *erofs_mkfs_build_tree(struct erofs_inode *dir) { ... if (!S_ISDIR(dir->i_mode)) { if (S_ISLNK(dir->i_mode)) { char *const symlink = malloc(dir->i_size);
if (!symlink) return ERR_PTR(-ENOMEM); ret = readlink(dir->i_srcpath, symlink, dir->i_size); if (ret < 0) { free(symlink); return ERR_PTR(-errno); }
ret = erofs_write_file_from_buffer(dir, symlink); free(symlink); if (ret) return ERR_PTR(ret); } else { ret = erofs_write_file(dir); if (ret) return ERR_PTR(ret); }
if (is_inode_layout_compression(inode)) goto noinline; //tj: 压缩不会出现inline了
/* * if the file size is block-aligned for uncompressed files, * should use EROFS_INODE_FLAT_PLAIN data mapping mode. */ if (!inode->idata_size) inode->datalayout = EROFS_INODE_FLAT_PLAIN;
bh = erofs_balloc(INODE, inodesize, 0, inode->idata_size); if (bh == ERR_PTR(-ENOSPC)) { int ret;
inode->datalayout = EROFS_INODE_FLAT_PLAIN; noinline: /* expend an extra block for tail-end data */ ret = erofs_prepare_tail_block(inode); if (ret) return ret; bh = erofs_balloc(INODE, inodesize, 0, 0); if (IS_ERR(bh)) return PTR_ERR(bh); DBG_BUGON(inode->bh_inline); } elseif (IS_ERR(bh)) { return PTR_ERR(bh); } elseif (inode->idata_size) { inode->datalayout = EROFS_INODE_FLAT_INLINE;
另,整个的buffer cache就是用来管理不完整的metadata的,mark to check later.
关于inline data, readme有写到:
[1] According to the erofs on-disk format, the tail block of files could be inlined aggressively with its metadata in order to reduce the I/O overhead and save the storage space (called tail-packing).
查了下ext4:
The inline data feature was designed to handle the case that a file’s data is so tiny that it readily fits inside the inode, which (theoretically) reduces disk block consumption and reduces seeks.