[LU-7370] improve e2fsck lost+found insert performance Created: 02/Nov/15 Updated: 11/Jun/20 Resolved: 11/Jun/20 |
|
| Status: | Resolved |
| Project: | Lustre |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Improvement | Priority: | Major |
| Reporter: | Andreas Dilger | Assignee: | WC Triage |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | e2fsck, e2fsprogs | ||
| Issue Links: |
|
||||||||
| Rank (Obsolete): | 9223372036854775807 | ||||||||
| Description |
|
When there are unattached inodes, e2fsck inserts entries into lost+found after a full linear search of the directory to find a slot for the name. This means that if there are a lot of unattached inodes due to corruption of the OST object directories, it is a very lengthy O(n^2) operation to reattach all inodes. It would be much more efficient to keep a cursor pointing to the last leaf block in the directory in which an entry was inserted. Since e2fsck is not deleting entries from lost+found, and because the entries are always getting longer (due to scanning in increasing inode number order) there is no value to search earlier blocks again. This would make lost+found insertion O(1) and significantly improve e2fsck performance in this case. |
| Comments |
| Comment by Andreas Dilger [ 04/Nov/15 ] |
|
Comment from e2fsprogs developer Darrick Wong:
Unfortunately, I don't think this will work directly, since we don't necessarily want to insert into lost+found in the last block, but the most recent block used. Otherwise, the preallocated blocks in lost+found would never be used as intended and all new entries would be added in the last block and new blocks appended to the directory. |
| Comment by Andreas Dilger [ 06/Nov/15 ] |
|
Further discussion with Ted and Darrick on the ext4 concall led to the conclusion that there should be a new series of interfaces for managing directories:
The link and unlink operations should write the directory inode for every operation, to ensure consistency with other operations that may be ongoing. When a filename is linked into the directory, the leaf block iterator will scan from the start of the cursor block number (initially zero), unless it has a smaller dirent size from the previous cursor, in which case it will search leaf blocks from the beginning. The directory context would contain the cursor (logical block number) where the previous entry was linked, along with the size of the dirent, to handle the case of a long name insertion skipping a lot of blocks with small slots. If a directory is indexed (htree) the link operation will clear the EXT2_INDEX_FL flag from the directory, since this is only inserting linearly into the directory. If a file is unlinked it will reset the cursor to that block if it is a lower logical block number and save the dirent size with the cursor. It does not need to clear the INDEX flag in this case. The old ext2fs_link() and ext2fs_unlink() functions should just become wrappers that call ext2fs_dir_open(), ext2fs_dir_{link,unlink}(), and ext2fs_dir_close(). |
| Comment by Andreas Dilger [ 11/Jun/20 ] |
|
This will be fixed in upstream e2fsprogs-1.46 by the implementation of htree directory creation in libext2fs: commit 31fff03fa8af5b581175830cbe75890e9bf630d1 tests: modify f_large_dir test to excercise indexed dir handling Modify f_large_dir test to create indexed directory and create entries Reviewed-by: Andreas Dilger <adilger@dilger.ca> commit 9a4d2dcc8deaa1c28b3a713c2f610be503855946 ext2fs: implement dir entry creation in htree directories Implement proper creation of new directory entries in htree directories Signed-off-by: Jan Kara <jack@suse.cz> |