From patchwork Tue Apr 4 14:53:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Albershteyn X-Patchwork-Id: 13200423 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1FE9C77B6C for ; Tue, 4 Apr 2023 14:56:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235003AbjDDO4s (ORCPT ); Tue, 4 Apr 2023 10:56:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58976 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233770AbjDDO4V (ORCPT ); Tue, 4 Apr 2023 10:56:21 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C7D7527F for ; Tue, 4 Apr 2023 07:55:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1680620121; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=k8y9WhZdDNtrUXoW/FedDtUjjZj566BJYHrOtFmmOqc=; b=gh7wNOpTLv5MXxElv19OTcoODCzQJLSkJuT8cj8zy/dpj3F+nTrfQs60EuPYdZswFDVUvq R01pfK1C230TTuhZx86xk3W1q/v6glQoJJcGhRE2/yAwt9sA6GS8sfkRoYAmMJTv1BRdtv RtrVP3PYAl51J5K6hBy2h7UY01Pgg2Q= Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-384-YbT-yIl3MWKE4AycBRh22A-1; Tue, 04 Apr 2023 10:55:20 -0400 X-MC-Unique: YbT-yIl3MWKE4AycBRh22A-1 Received: by mail-qv1-f71.google.com with SMTP id dg8-20020a056214084800b005acc280bf19so14725280qvb.22 for ; Tue, 04 Apr 2023 07:55:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680620119; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=k8y9WhZdDNtrUXoW/FedDtUjjZj566BJYHrOtFmmOqc=; b=n9EF+KtU4wq0dokVw7nz6Qm3peBbo8ronWac9Wm1GxCmXGr++0rpt79sb2wkgdTRAp W/OxQLvTvAGuksAA/j6LJw4IxzBhH5B3T+fFPoyUFWwldjaIClwE5PFMgQd+jEEFmOLk omeYOKPoQfWE+UEYekjNjDqkQmlmNmXwgQCqqotouh2XWFrVU9NLuJAL02+53CUvb9+6 L2i9oS1W2E48M9xN1IYqOLY/8frONidw0/n9qbB55aNLL1fwkrMv2KIOEoiFRo5h1Joz 9Hg/l1VktBDtNh8IIu0zXDcNHqb0Fp/PMB1VMZgDdXbVwYh44n35ddXDX+4L8URi31mF Yb3w== X-Gm-Message-State: AAQBX9cCBIAS6oZyIcwPG2MQm9B9BW0EIegyIMAWsrSTLBMo5Xcm9zAC xSpdn/2iFuuKCX5tTx6vhK9unGDwP3HnUpMke2t9WQueujWVrzTD77E7ea79VPoYg4a4FQvwu1u 3I32ampDEj1W7QYJvf1rd+A== X-Received: by 2002:ac8:5b06:0:b0:3d4:3d6c:a62b with SMTP id m6-20020ac85b06000000b003d43d6ca62bmr3793784qtw.27.1680620118585; Tue, 04 Apr 2023 07:55:18 -0700 (PDT) X-Google-Smtp-Source: AKy350Zq76N3HAqDggjHqbDMyBg5khfORiFnim8gNTT1pLECc9GdD6VxBnlyiVZupUjB3vAUZcGqDA== X-Received: by 2002:ac8:5b06:0:b0:3d4:3d6c:a62b with SMTP id m6-20020ac85b06000000b003d43d6ca62bmr3793740qtw.27.1680620118202; Tue, 04 Apr 2023 07:55:18 -0700 (PDT) Received: from aalbersh.remote.csb ([109.183.6.197]) by smtp.gmail.com with ESMTPSA id j4-20020ac86644000000b003e6387431dcsm3296539qtp.7.2023.04.04.07.55.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Apr 2023 07:55:17 -0700 (PDT) From: Andrey Albershteyn To: djwong@kernel.org, dchinner@redhat.com, ebiggers@kernel.org, hch@infradead.org, linux-xfs@vger.kernel.org, fsverity@lists.linux.dev Cc: rpeterso@redhat.com, agruenba@redhat.com, xiang@kernel.org, chao@kernel.org, damien.lemoal@opensource.wdc.com, jth@kernel.org, linux-erofs@lists.ozlabs.org, linux-btrfs@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, cluster-devel@redhat.com, Andrey Albershteyn Subject: [PATCH v2 11/23] xfs: add XFS_DA_OP_BUFFER to make xfs_attr_get() return buffer Date: Tue, 4 Apr 2023 16:53:07 +0200 Message-Id: <20230404145319.2057051-12-aalbersh@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230404145319.2057051-1-aalbersh@redhat.com> References: <20230404145319.2057051-1-aalbersh@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org One of essential ideas of fs-verity is that pages which are already verified won't need to be re-verified if they still in page cache. The XFS stores Merkle tree blocks in extended attributes. Each attribute has one Merkle tree block. We can not directly mark underlying xfs_buf's pages as checked. The are not aligned with xattr value and we don't have a reference to that buffer which is immediately release when value is copied out. One way to track that this block was verified is to mark xattr's buffer as verified. If buffer is evicted the incore XBF_VERITY_CHECKED flag is lost. When the xattr is read again xfs_attr_get() returns new buffer without the flag. The flag is then used to tell fs-verity if it's new page or cached one. This patch adds XFS_DA_OP_BUFFER to tell xfs_attr_get() to xfs_buf_hold() underlying buffer and return it as xfs_da_args->bp. The caller must then xfs_buf_rele() the buffer. Signed-off-by: Andrey Albershteyn --- fs/xfs/libxfs/xfs_attr.c | 5 ++++- fs/xfs/libxfs/xfs_attr_leaf.c | 7 +++++++ fs/xfs/libxfs/xfs_attr_remote.c | 13 +++++++++++-- fs/xfs/libxfs/xfs_da_btree.h | 5 ++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 711022742e34..298b74245267 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -251,6 +251,8 @@ xfs_attr_get_ilocked( * If the attribute is found, but exceeds the size limit set by the caller in * args->valuelen, return -ERANGE with the size of the attribute that was found * in args->valuelen. + * + * Using XFS_DA_OP_BUFFER the caller have to release the buffer args->bp. */ int xfs_attr_get( @@ -269,7 +271,8 @@ xfs_attr_get( args->hashval = xfs_da_hashname(args->name, args->namelen); /* Entirely possible to look up a name which doesn't exist */ - args->op_flags = XFS_DA_OP_OKNOENT; + args->op_flags = XFS_DA_OP_OKNOENT | + (args->op_flags & XFS_DA_OP_BUFFER); lock_mode = xfs_ilock_attr_map_shared(args->dp); error = xfs_attr_get_ilocked(args); diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index beee51ad75ce..112bb2604c89 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -2533,6 +2533,13 @@ xfs_attr3_leaf_getvalue( name_loc = xfs_attr3_leaf_name_local(leaf, args->index); ASSERT(name_loc->namelen == args->namelen); ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0); + + /* must be released by the caller */ + if (args->op_flags & XFS_DA_OP_BUFFER) { + xfs_buf_hold(bp); + args->bp = bp; + } + return xfs_attr_copy_value(args, &name_loc->nameval[args->namelen], be16_to_cpu(name_loc->valuelen)); diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index d440393b40eb..72908e0e1c86 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -424,9 +424,18 @@ xfs_attr_rmtval_get( error = xfs_attr_rmtval_copyout(mp, bp, args->dp->i_ino, &offset, &valuelen, &dst); - xfs_buf_relse(bp); - if (error) + xfs_buf_unlock(bp); + /* must be released by the caller */ + if (args->op_flags & XFS_DA_OP_BUFFER) + args->bp = bp; + else + xfs_buf_rele(bp); + + if (error) { + if (args->op_flags & XFS_DA_OP_BUFFER) + xfs_buf_rele(args->bp); return error; + } /* roll attribute extent map forwards */ lblkno += map[i].br_blockcount; diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index a4b29827603f..269d26730bca 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -61,6 +61,7 @@ typedef struct xfs_da_args { uint8_t filetype; /* filetype of inode for directories */ void *value; /* set of bytes (maybe contain NULLs) */ int valuelen; /* length of value */ + struct xfs_buf *bp; /* OUT: xfs_buf which contains the attr */ unsigned int attr_filter; /* XFS_ATTR_{ROOT,SECURE,INCOMPLETE} */ unsigned int attr_flags; /* XATTR_{CREATE,REPLACE} */ xfs_dahash_t hashval; /* hash value of name */ @@ -95,6 +96,7 @@ typedef struct xfs_da_args { #define XFS_DA_OP_REMOVE (1u << 6) /* this is a remove operation */ #define XFS_DA_OP_RECOVERY (1u << 7) /* Log recovery operation */ #define XFS_DA_OP_LOGGED (1u << 8) /* Use intent items to track op */ +#define XFS_DA_OP_BUFFER (1u << 9) /* Return underlying buffer */ #define XFS_DA_OP_FLAGS \ { XFS_DA_OP_JUSTCHECK, "JUSTCHECK" }, \ @@ -105,7 +107,8 @@ typedef struct xfs_da_args { { XFS_DA_OP_NOTIME, "NOTIME" }, \ { XFS_DA_OP_REMOVE, "REMOVE" }, \ { XFS_DA_OP_RECOVERY, "RECOVERY" }, \ - { XFS_DA_OP_LOGGED, "LOGGED" } + { XFS_DA_OP_LOGGED, "LOGGED" }, \ + { XFS_DA_OP_BUFFER, "BUFFER" } /* * Storage for holding state during Btree searches and split/join ops.