On Fri, Mar 05, 2021 at 11:26:30AM -0800, Boris Burkov wrote: > +/* > + * fsverity op that ends enabling verity. > + * fsverity calls this when it's done with all of the pages in the file > + * and all of the merkle items have been inserted. We write the > + * descriptor and update the inode in the btree to reflect its new life > + * as a verity file. > + */ > +static int btrfs_end_enable_verity(struct file *filp, const void *desc, > + size_t desc_size, u64 merkle_tree_size) > +{ > + struct btrfs_trans_handle *trans; > + struct inode *inode = file_inode(filp); > + struct btrfs_root *root = BTRFS_I(inode)->root; > + struct btrfs_verity_descriptor_item item; > + int ret; > + > + if (desc != NULL) { > + /* write out the descriptor item */ > + memset(&item, 0, sizeof(item)); > + btrfs_set_stack_verity_descriptor_size(&item, desc_size); > + ret = write_key_bytes(BTRFS_I(inode), > + BTRFS_VERITY_DESC_ITEM_KEY, 0, > + (const char *)&item, sizeof(item)); > + if (ret) > + goto out; > + /* write out the descriptor itself */ > + ret = write_key_bytes(BTRFS_I(inode), > + BTRFS_VERITY_DESC_ITEM_KEY, 1, > + desc, desc_size); > + if (ret) > + goto out; > + > + /* update our inode flags to include fs verity */ > + trans = btrfs_start_transaction(root, 1); > + if (IS_ERR(trans)) { > + ret = PTR_ERR(trans); > + goto out; > + } > + BTRFS_I(inode)->compat_flags |= BTRFS_INODE_VERITY; > + btrfs_sync_inode_flags_to_i_flags(inode); > + ret = btrfs_update_inode(trans, root, BTRFS_I(inode)); > + btrfs_end_transaction(trans); > + } > + > +out: > + if (desc == NULL || ret) { > + /* If we failed, drop all the verity items */ > + drop_verity_items(BTRFS_I(inode), BTRFS_VERITY_DESC_ITEM_KEY); > + drop_verity_items(BTRFS_I(inode), BTRFS_VERITY_MERKLE_ITEM_KEY); > + } else > + btrfs_set_fs_compat_ro(root->fs_info, VERITY); > + clear_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &BTRFS_I(inode)->runtime_flags); > + return ret; > +} If enabling verity failed, I think you also need to call truncate_inode_pages(inode->i_mapping, inode->i_size) to remove the cached Merkle tree pages from the page cache. Otherwise they can be exposed to userspace if the file is later extended. I recently fixed this same problem for ext4 and f2fs: https://lkml.kernel.org/linux-f2fs-devel/20210302200420.137977-1-ebiggers@xxxxxxxxxx/T/#u - Eric