On Tue, Dec 10, 2019 at 10:35:31AM -0800, Eric Biggers wrote: > From: Eric Biggers <ebiggers@xxxxxxxxxx> > > When it builds the first level of the Merkle tree, FS_IOC_ENABLE_VERITY > sequentially reads each page of the file using read_mapping_page(). > This works fine if the file's data is already in pagecache, which should > normally be the case, since this ioctl is normally used immediately > after writing out the file. > > But in any other case this implementation performs very poorly, since > only one page is read at a time. > > Fix this by implementing readahead using the functions from > mm/readahead.c. > > This improves performance in the uncached case by about 20x, as seen in > the following benchmarks done on a 250MB file (on x86_64 with SHA-NI): > > FS_IOC_ENABLE_VERITY uncached (before) 3.299s > FS_IOC_ENABLE_VERITY uncached (after) 0.160s > FS_IOC_ENABLE_VERITY cached 0.147s > sha256sum uncached 0.191s > sha256sum cached 0.145s > > Note: we could instead switch to kernel_read(). But that would mean > we'd no longer be hashing the data directly from the pagecache, which is > a nice optimization of its own. And using kernel_read() would require > allocating another temporary buffer, hashing the data and tree pages > separately, and explicitly zero-padding the last page -- so it wouldn't > really be any simpler than direct pagecache access, at least for now. > > Signed-off-by: Eric Biggers <ebiggers@xxxxxxxxxx> > --- > > Changed v1 => v2: > - Only do sync readahead when the page wasn't found in the pagecache at all. > - Use ->f_mapping so that the inode doesn't have to be passed. > > > fs/verity/enable.c | 45 +++++++++++++++++++++++++++++++++++++++------ > 1 file changed, 39 insertions(+), 6 deletions(-) > Applied to fscrypt.git#fsverity for 5.6. - Eric