Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] mke2fs: enable copying of fs-verity metadata #203

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

allisonkarlitskaya
Copy link

@allisonkarlitskaya allisonkarlitskaya commented Nov 25, 2024

When creating a filesystem with mke2fs -O verity and populating content via -d, check if that content is fs-verity enabled, and if it is, copy the fs-verity metadata from the host-native filesystem into the created filesystem.

This currently doesn't work for reading from btrfs, which fails to implement the required ioctl(), but it will work between two ext4 filesystems.

Closes #201

This is very much WIP. It has quite some issues to work out. Input greatly appreciated!

  • the current code checks for fs-verity on a file after reading and copying the data contents and sets the EXT4_VERITY_FL flag after the fact. Most of the other flags are set ahead of time. We could check the file flags for FS_VERITY_FL with FS_IOC_GETFLAGS to help with that, but it's a matter of taste. I sort of prefer the current approach
  • after copying the verity data we need to rewrite the inode to fixup the size and version fields, currently. The way this is done in the patch is very ugly, mostly because I'm not familiar with the code. Help appreciated
  • we ought to document why we need to set the version field to 2. I was only able to discover that by dumping the inode on a file on a real filesystem that I mounted and ran fsverity enable on and looking for differences vs. the filesystem created by mke2fs -d.
  • This doesn't work with btrfs (which is what my work laptop with Fedora is using) due to a missing ioctl. See https://lore.kernel.org/fsverity/[email protected]/T/#u for a fix. edit: This has gone in for -next: btrfs/linux@0af58a6

Right now we jump to the end as soon as we've found a method that works.
This is a reasonable approach because it's the last operation in the
function, but soon it won't be.  Switch to a logically-equivalent
alternative approach: keep trying until we find the approach that works,
dropping the `goto out`.  Now we can add code after this.

Signed-off-by: Allison Karlitskaya <[email protected]>
@allisonkarlitskaya
Copy link
Author

@tytso This PR is working but there are some things I don't like about it. Can you please give advice here about how I can fix those ugly corners up? If not, I can try to clean things up on my own...

When writing data to an inode (with mke2fs -d) we need to do the typical
loop to handle partial writes to make sure all of the data gets written.

Move that code to its own function.  This function also takes an offset
parameter, which makes it feel a bit like pwrite() (except that it does
modify the file offset).

Signed-off-by: Allison Karlitskaya <[email protected]>
When creating a filesystem with `mke2fs -O verity` and populating
content via `-d`, check if that content is fs-verity enabled, and if it
is, copy the fs-verity metadata from the host-native filesystem into the
created filesystem.

This currently doesn't work for reading from btrfs, which fails to
implement the required ioctl(), but it will work between two ext4
filesystems.

Closes: tytso#201
Signed-off-by: Allison Karlitskaya <[email protected]>

e2_offset += size;
*written += size;
} while (size != 0);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the loop here. I think we only need retry around the ioctl, since write_all handles the data loop.
We could just use glibc's TEMP_FAILURE_RETRY around the ioctl (any usage of that elsewhere in this code?)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop is indeed about repeating the ioctl(). It's a pread-style interface and we might have to call it more than once to get all of the data. For large files, the merkle tree data, in particular, can easily be larger than our read size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support fs-verity for mkfs.ext4 -d
2 participants