From patchwork Tue Oct 10 20:40:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416061 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 EFAFECD8CBE for ; Tue, 10 Oct 2023 20:41:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234528AbjJJUlN (ORCPT ); Tue, 10 Oct 2023 16:41:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55184 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231208AbjJJUlI (ORCPT ); Tue, 10 Oct 2023 16:41:08 -0400 Received: from mail-yb1-xb2f.google.com (mail-yb1-xb2f.google.com [IPv6:2607:f8b0:4864:20::b2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5DF6DB0 for ; Tue, 10 Oct 2023 13:41:06 -0700 (PDT) Received: by mail-yb1-xb2f.google.com with SMTP id 3f1490d57ef6-d89ba259964so6710111276.2 for ; Tue, 10 Oct 2023 13:41:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970465; x=1697575265; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=t3AtE57cfE4ke3TNDK2zyjx2+8CAXIno7J26EywbEhE=; b=tLiDHazrIRdBQE7hE24ZJ//35zg8mXot0ALA6hPjIxiFicGeSBDYKffxuVPku7RfJG W/8L884yPAbQbPSAeyTi9q0G1z50fN0rQq0Qb20XuEyUS1v+QqbuyfJvyKMOnh7ekl+e IpsbsE+tHGmspA86K8nyyP7Fr4WHLHL867GJf6JKlWcegxERdcVFpdZDpm5yzQOJJYvG xJhBq6AVpvflcV2zLY9HIPACje+O8NZT/NW3G5ASwIuhMRXQvFIN4g/MEX6PDfFYDATW IeGwsYt+PR5xWrG9YK9Oc8f9JDIVR8u7GBG/g85Bf4GrUs1BWlnyIPi1F6kxKhp8RqBg 45jQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970465; x=1697575265; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=t3AtE57cfE4ke3TNDK2zyjx2+8CAXIno7J26EywbEhE=; b=F9qzw3vPMOGBbSUuAdIOyWADren0zKDKYWPPQ7chthC3B9muK6CBDUaW4oF7ef19b6 H5pR+EZB+FpuuxVDBCKECiZIAvk5utIXsQDNsDCTrg46tX2g7APufSBSJ8sUOJBDPq5u +jnsASHp3SRWOdB4Tml3eesD2NpRgvUskBrvgix4hMY6//eQZpkluHIsh402/Qld3pfn lq989miuVsXS/BCdVh09aZIwfb3DWAyTMa4T/LinDrpVVlcMmVr9btJBMWtlM8uUXUVk PfU0e1eXU0R/avXi+U8kZesOtgJ1MzLDnZE5p7RmAnFrwec7YD53nLuJSzuuuoVpK8Gs 6RCw== X-Gm-Message-State: AOJu0Yy2rC4s0iCVA4rfeah2q08Jl1gCpMyJWt4cuFhOo0MOFQszmwKZ MjhuwmRgdaFMNLrhSVq4DVML4rckZTrT/hIZNMnPBA== X-Google-Smtp-Source: AGHT+IH+HddtrEfyeHZpxOqvjphtb2wnL6aRU96LWS6eFgRyVsdxV1iw7xuXsyX64rDKY8i5bwPDVA== X-Received: by 2002:a25:8f8d:0:b0:d48:1936:14d0 with SMTP id u13-20020a258f8d000000b00d48193614d0mr19368582ybl.53.1696970464995; Tue, 10 Oct 2023 13:41:04 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id a5-20020a259805000000b00d7bb3c4893fsm3907331ybo.8.2023.10.10.13.41.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:04 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 01/36] fscrypt: use a flag to indicate that the master key is being evicted Date: Tue, 10 Oct 2023 16:40:16 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Currently we wipe the mk->mk_secret when we remove the master key, and we use this status to tell everybody whether or not the master key is available for use. With extent based encryption we're going to need to keep the secret around until the inode is evicted, so we need a different mechanism to tell everybody that the key is currently unusable. Accomplish this with a mk_flags member in the master key, and update the is_master_key_secret_present() helper to return the status of this bit. Update the removal and adding helpers to manipulate this bit and use it as the source of truth about whether or not the key is available for use. Signed-off-by: Josef Bacik --- fs/crypto/fscrypt_private.h | 17 ++++++++--------- fs/crypto/hooks.c | 2 +- fs/crypto/keyring.c | 20 ++++++++++++++------ fs/crypto/keysetup.c | 4 ++-- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index 2fb4ba435d27..f44342f17269 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -471,6 +471,10 @@ struct fscrypt_master_key_secret { } __randomize_layout; +enum fscrypt_mk_flags { + FSCRYPT_MK_FLAG_EVICTED = BIT(0), +}; + /* * fscrypt_master_key - an in-use master key * @@ -565,19 +569,14 @@ struct fscrypt_master_key { siphash_key_t mk_ino_hash_key; bool mk_ino_hash_key_initialized; + /* Flags for the master key. */ + unsigned long mk_flags; } __randomize_layout; static inline bool -is_master_key_secret_present(const struct fscrypt_master_key_secret *secret) +is_master_key_secret_present(const struct fscrypt_master_key *mk) { - /* - * The READ_ONCE() is only necessary for fscrypt_drop_inode(). - * fscrypt_drop_inode() runs in atomic context, so it can't take the key - * semaphore and thus 'secret' can change concurrently which would be a - * data race. But fscrypt_drop_inode() only need to know whether the - * secret *was* present at the time of check, so READ_ONCE() suffices. - */ - return READ_ONCE(secret->size) != 0; + return !test_bit(FSCRYPT_MK_FLAG_EVICTED, &mk->mk_flags); } static inline const char *master_key_spec_type( diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c index 85d2975b69b7..f7cf724cf256 100644 --- a/fs/crypto/hooks.c +++ b/fs/crypto/hooks.c @@ -187,7 +187,7 @@ int fscrypt_prepare_setflags(struct inode *inode, return -EINVAL; mk = ci->ci_master_key; down_read(&mk->mk_sem); - if (is_master_key_secret_present(&mk->mk_secret)) + if (is_master_key_secret_present(mk)) err = fscrypt_derive_dirhash_key(ci, mk); else err = -ENOKEY; diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index a51fa6a33de1..e0e311ed6b88 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -102,7 +102,7 @@ void fscrypt_put_master_key_activeref(struct super_block *sb, * ->mk_active_refs == 0 implies that ->mk_secret is not present and * that ->mk_decrypted_inodes is empty. */ - WARN_ON_ONCE(is_master_key_secret_present(&mk->mk_secret)); + WARN_ON_ONCE(is_master_key_secret_present(mk)); WARN_ON_ONCE(!list_empty(&mk->mk_decrypted_inodes)); for (i = 0; i <= FSCRYPT_MODE_MAX; i++) { @@ -236,11 +236,17 @@ void fscrypt_destroy_keyring(struct super_block *sb) * the keyring due to the single active ref associated * with ->mk_secret. There should be no structural refs * beyond the one associated with the active ref. + * + * We set the EVICTED flag in order to avoid the + * WARN_ON_ONCE(is_master_key_secret_present(mk)) in + * fscrypt_put_master_key_activeref(), as we want to + * maintain that warning for improper cleanup elsewhere. */ WARN_ON_ONCE(refcount_read(&mk->mk_active_refs) != 1); WARN_ON_ONCE(refcount_read(&mk->mk_struct_refs) != 1); - WARN_ON_ONCE(!is_master_key_secret_present(&mk->mk_secret)); + WARN_ON_ONCE(!is_master_key_secret_present(mk)); wipe_master_key_secret(&mk->mk_secret); + set_bit(FSCRYPT_MK_FLAG_EVICTED, &mk->mk_flags); fscrypt_put_master_key_activeref(sb, mk); } } @@ -479,9 +485,11 @@ static int add_existing_master_key(struct fscrypt_master_key *mk, } /* Re-add the secret if needed. */ - if (!is_master_key_secret_present(&mk->mk_secret)) { - if (!refcount_inc_not_zero(&mk->mk_active_refs)) + if (test_and_clear_bit(FSCRYPT_MK_FLAG_EVICTED, &mk->mk_flags)) { + if (!refcount_inc_not_zero(&mk->mk_active_refs)) { + set_bit(FSCRYPT_MK_FLAG_EVICTED, &mk->mk_flags); return KEY_DEAD; + } move_master_key_secret(&mk->mk_secret, secret); } @@ -1055,7 +1063,7 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users) /* No user claims remaining. Go ahead and wipe the secret. */ err = -ENOKEY; - if (is_master_key_secret_present(&mk->mk_secret)) { + if (!test_and_set_bit(FSCRYPT_MK_FLAG_EVICTED, &mk->mk_flags)) { wipe_master_key_secret(&mk->mk_secret); fscrypt_put_master_key_activeref(sb, mk); err = 0; @@ -1150,7 +1158,7 @@ int fscrypt_ioctl_get_key_status(struct file *filp, void __user *uarg) } down_read(&mk->mk_sem); - if (!is_master_key_secret_present(&mk->mk_secret)) { + if (!is_master_key_secret_present(mk)) { arg.status = refcount_read(&mk->mk_active_refs) > 0 ? FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED : FSCRYPT_KEY_STATUS_ABSENT /* raced with full removal */; diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index 094d1b7a1ae6..92eca1400b2d 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -487,7 +487,7 @@ static int setup_file_encryption_key(struct fscrypt_inode_info *ci, down_read(&mk->mk_sem); /* Has the secret been removed (via FS_IOC_REMOVE_ENCRYPTION_KEY)? */ - if (!is_master_key_secret_present(&mk->mk_secret)) { + if (!is_master_key_secret_present(mk)) { err = -ENOKEY; goto out_release_key; } @@ -808,6 +808,6 @@ int fscrypt_drop_inode(struct inode *inode) * then the thread removing the key will either evict the inode itself * or will correctly detect that it wasn't evicted due to the race. */ - return !is_master_key_secret_present(&ci->ci_master_key->mk_secret); + return !is_master_key_secret_present(ci->ci_master_key); } EXPORT_SYMBOL_GPL(fscrypt_drop_inode); From patchwork Tue Oct 10 20:40:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416062 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 E2823CD8CB9 for ; Tue, 10 Oct 2023 20:41:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231825AbjJJUlP (ORCPT ); Tue, 10 Oct 2023 16:41:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55204 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234393AbjJJUlJ (ORCPT ); Tue, 10 Oct 2023 16:41:09 -0400 Received: from mail-yw1-x1136.google.com (mail-yw1-x1136.google.com [IPv6:2607:f8b0:4864:20::1136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 36ECC94 for ; Tue, 10 Oct 2023 13:41:07 -0700 (PDT) Received: by mail-yw1-x1136.google.com with SMTP id 00721157ae682-5a7afd45199so21354477b3.0 for ; Tue, 10 Oct 2023 13:41:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970466; x=1697575266; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=fkPDGYDbzsyT2iviorbG84fmLsSBIDBYGMivDDhcaSA=; b=Fw12OkQzJz1RqOIy5OpR4Cy7l7SIn84viBkp36/p04qC2CLP6ebe34hP9ZoxPltmEd pVn1HTMK3VTJIxIr4J5fT3wVDrLvSBPx7tzV9AKA/aRVRc0qE3X9+RPT3Kt4rBj/SqZy sknmKjtZedi63p56frXZy/tZYILauVt+Ibl96h8Kuw9r+ZjJ1GDVQn7wZpUIlJX+D5qV zBHa9yHrL+uc6wrWDDnsWXrLQvCy7MHfnKhYBPEsPPoOUtShOx2wuZP75hITrWbrRxcu Brs/s7KGnbDCNM5h/IfZL+xzF/FvkCi85wHQZxo17HN2X1OlTmyZIWq4hRqtd0vrKr0d oSOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970466; x=1697575266; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fkPDGYDbzsyT2iviorbG84fmLsSBIDBYGMivDDhcaSA=; b=B9MVw7keOWpWYlZsJqvFq7d4Mx8HPnkgwcITtKIas3PlZp9dqF0xNhe4nxJNOnHgZk 1OtFKfaTJo+cmgsMjXMFOkce6fnzhcxECOdA0FREvCNYcpcXDNhwfh4oPGmZ4b31Jp1I QmEae2fnybUp1hxMm9yh1tor64Il+T7O0RlZ8UNmKyT/Wgvt7bhvwiyqtkcv2/qlr305 pFNd6FX+jqeGW4D15tUznP0iRaNSGOkxIJb5pn/vn85oPtAByNnAqh6/6jo89u9O1oKT K5kfSMbJ6HtFMjLtWuPQhoMH+f0HjJsghEzqh5ITDpkcLuHoR585ZYwgr4WneO5l+F+H D2WA== X-Gm-Message-State: AOJu0Yz15wkGq58IXKDPWn/Kw3OBXsYJvsYYGR1j9/iXOVb3pnZAdayt jJfPqdIVkzZ+SNpv0N0Vliy7PhfK9LRg01cMMA+pIw== X-Google-Smtp-Source: AGHT+IF3+989+mVbsCnTHYZ6gvtzCY6x1ia4u7mwISczqB7A5h4+dXkdgsfoaI3v75hIIbv4o4zN9Q== X-Received: by 2002:a81:6f85:0:b0:569:e7cb:cd4e with SMTP id k127-20020a816f85000000b00569e7cbcd4emr18009889ywc.48.1696970466174; Tue, 10 Oct 2023 13:41:06 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id c65-20020a0df344000000b005925765aa30sm4697589ywf.135.2023.10.10.13.41.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:05 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 02/36] fscrypt: don't wipe mk secret until the last active user is gone Date: Tue, 10 Oct 2023 16:40:17 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Previously we were wiping the master key secret when we do FS_IOC_REMOVE_ENCRYPTION_KEY, and then using the fact that it was cleared as the mechanism from keeping new users from being setup. This works with inode based encryption, as the per-inode key is derived at setup time, so the secret disappearing doesn't affect any currently open files from being able to continue working. However for extent based encryption we do our key derivation at page writeout and readpage time, which means we need the master key secret to be available while we still have our file open. Since the master key lifetime is controlled by a flag, move the clearing of the secret to the mk_active_users cleanup stage. This counter represents the actively open files that still exist on the file system, and thus should still be able to operate normally. Once the last user is closed we can clear the secret. Until then no new users are allowed, and this allows currently open files to continue to operate until they're closed. Signed-off-by: Josef Bacik --- fs/crypto/keyring.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index e0e311ed6b88..31ea81d97075 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -116,6 +116,7 @@ void fscrypt_put_master_key_activeref(struct super_block *sb, memzero_explicit(&mk->mk_ino_hash_key, sizeof(mk->mk_ino_hash_key)); mk->mk_ino_hash_key_initialized = false; + wipe_master_key_secret(&mk->mk_secret); /* Drop the structural ref associated with the active refs. */ fscrypt_put_master_key(mk); @@ -245,7 +246,6 @@ void fscrypt_destroy_keyring(struct super_block *sb) WARN_ON_ONCE(refcount_read(&mk->mk_active_refs) != 1); WARN_ON_ONCE(refcount_read(&mk->mk_struct_refs) != 1); WARN_ON_ONCE(!is_master_key_secret_present(mk)); - wipe_master_key_secret(&mk->mk_secret); set_bit(FSCRYPT_MK_FLAG_EVICTED, &mk->mk_flags); fscrypt_put_master_key_activeref(sb, mk); } @@ -1064,7 +1064,6 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users) /* No user claims remaining. Go ahead and wipe the secret. */ err = -ENOKEY; if (!test_and_set_bit(FSCRYPT_MK_FLAG_EVICTED, &mk->mk_flags)) { - wipe_master_key_secret(&mk->mk_secret); fscrypt_put_master_key_activeref(sb, mk); err = 0; } From patchwork Tue Oct 10 20:40:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416064 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 3F508CD6115 for ; Tue, 10 Oct 2023 20:41:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234473AbjJJUlR (ORCPT ); Tue, 10 Oct 2023 16:41:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234416AbjJJUlN (ORCPT ); Tue, 10 Oct 2023 16:41:13 -0400 Received: from mail-yw1-x112f.google.com (mail-yw1-x112f.google.com [IPv6:2607:f8b0:4864:20::112f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1A98EA7 for ; Tue, 10 Oct 2023 13:41:09 -0700 (PDT) Received: by mail-yw1-x112f.google.com with SMTP id 00721157ae682-59f6441215dso75755027b3.2 for ; Tue, 10 Oct 2023 13:41:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970468; x=1697575268; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ptIykhvVmDV5wYmbmhkhou1KdWmw8NP+zHPSeBcATWU=; b=J2Yn96UvMXSVCiMs2b+YgkcYW9RnFa0V/y/A1K8qcDpAtJ1ACutYMXx+6RTi7buGOL 15wLMYSxhRG6WEA1gZlGBmb3rNG5JKeykQ6c1q+Dv+iaQpiYYDab5MHr84yxEXvZZUF4 GZmGleyL5I0t4W8CdFu+fUQTu6FrOUz+rYApH/jZwmeRGFImDX26b/hdJcAB1aPXyKVv 6pwzp2LigpTcnBJxPlr8Js7wfhjNoo6d8V102Ht6aVZ6jBxIADC5+QE/9vi2wXuh29q8 PlV6yGpyWuRknl5jaMfLL45GPibxxVH4RPuqCyf0K44OWHeGWrbao+/COVcK9E2j4h+g 8zbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970468; x=1697575268; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ptIykhvVmDV5wYmbmhkhou1KdWmw8NP+zHPSeBcATWU=; b=Yem3J7FGk55zBGgD0B2axiEMIXXeJ0M7SRxFZA/1ZR+BRJ9xcYXVXikifKPBZw0GMt lsiFZLaQbWBRlLgBGKOSKv9A0DKKuwO05oWpni9aAj23QM8qGuyame+vyUcIUpMW648R BonkP5XdeojO5uus3HyWCLHoW5x9CWCy0DxFSLd7TZnHNNM3249AJRcd8dZvMRhZ1lBh 41GKVBHwa0IHZcgCe1meK3/eVbTCo5xIMs2uEU66kceJ5r8jMKdJrWaDK1Iov/qDFWzj 272OaGcb8B6L2xOqApTNY0kkk1tiuIyaU0QyqIav4w6zIsQNWBN4KosmPrvXDy9VLgco gQkA== X-Gm-Message-State: AOJu0YzLBWJgiT/8LbmlBDJyPkTpiBmBJAxC3SSd5dRBluMKQ3OLHFiw ITepuH7hpBCZnfLWzIWRm+0NM+AVuQTzqxWNXn+2wA== X-Google-Smtp-Source: AGHT+IGScARPLfxJAJxWq4Ayy1mL7Y/VqtKIttBRulZlEyVjZxjIWSk5h2DRzV2cHEZoG0D2o+OmyA== X-Received: by 2002:a25:b203:0:b0:d9a:61d1:3a85 with SMTP id i3-20020a25b203000000b00d9a61d13a85mr2597733ybj.0.1696970467579; Tue, 10 Oct 2023 13:41:07 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id x142-20020a25ce94000000b00d89679f6d22sm795669ybe.64.2023.10.10.13.41.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:06 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 03/36] fscrypt: add per-extent encryption support Date: Tue, 10 Oct 2023 16:40:18 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org This adds the code necessary for per-extent encryption. We will store a nonce for every extent we create, and then use the inode's policy and the extents nonce to derive a per-extent key. This is meant to be flexible, if we choose to expand the on-disk extent information in the future we have a version number we can use to change what exists on disk. The file system indicates it wants to use per-extent encryption by setting s_cop->set_extent_context. This also requires the use of inline block encryption. The support is relatively straightforward, the only "extra" bit is we're deriving a per-extent key to use for the encryption, the inode still controls the policy and access to the master key. Signed-off-by: Josef Bacik --- fs/crypto/crypto.c | 10 ++- fs/crypto/fscrypt_private.h | 44 ++++++++++ fs/crypto/inline_crypt.c | 84 +++++++++++++++++++ fs/crypto/keysetup.c | 155 ++++++++++++++++++++++++++++++++++++ fs/crypto/policy.c | 47 +++++++++++ include/linux/fscrypt.h | 71 +++++++++++++++++ 6 files changed, 410 insertions(+), 1 deletion(-) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 328470d40dec..18bd96b9db4e 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -40,6 +40,7 @@ static struct workqueue_struct *fscrypt_read_workqueue; static DEFINE_MUTEX(fscrypt_init_mutex); struct kmem_cache *fscrypt_inode_info_cachep; +struct kmem_cache *fscrypt_extent_info_cachep; void fscrypt_enqueue_decrypt_work(struct work_struct *work) { @@ -414,12 +415,19 @@ static int __init fscrypt_init(void) if (!fscrypt_inode_info_cachep) goto fail_free_queue; + fscrypt_extent_info_cachep = KMEM_CACHE(fscrypt_extent_info, + SLAB_RECLAIM_ACCOUNT); + if (!fscrypt_extent_info_cachep) + goto fail_free_inode_info; + err = fscrypt_init_keyring(); if (err) - goto fail_free_inode_info; + goto fail_free_extent_info; return 0; +fail_free_extent_info: + kmem_cache_destroy(fscrypt_extent_info_cachep); fail_free_inode_info: kmem_cache_destroy(fscrypt_inode_info_cachep); fail_free_queue: diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index f44342f17269..c672c3e537f3 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -30,6 +30,8 @@ #define FSCRYPT_CONTEXT_V1 1 #define FSCRYPT_CONTEXT_V2 2 +#define FSCRYPT_EXTENT_CONTEXT_V1 1 + /* Keep this in sync with include/uapi/linux/fscrypt.h */ #define FSCRYPT_MODE_MAX FSCRYPT_MODE_AES_256_HCTR2 @@ -53,6 +55,28 @@ struct fscrypt_context_v2 { u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; }; +/* + * fscrypt_extent_context - the encryption context of an extent + * + * This is the on-disk information stored for an extent. The policy and + * relevante information is stored in the inode, the per-extent information is + * simply the nonce that's used in as KDF input in conjunction with the inode + * context to derive a per-extent key for encryption. + * + * At this point the master_key_identifier exists only for possible future + * expansion. This will allow for an inode to have extents with multiple master + * keys, although sharing the same encryption mode. This would be for re-keying + * or for reflinking between two differently encrypted inodes. For now the + * master_key_descriptor must match the inode's, and we'll be using the inode's + * for all key derivation. + */ +struct fscrypt_extent_context { + u8 version; /* FSCRYPT_EXTENT_CONTEXT_V2 */ + u8 encryption_mode; + u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; + u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; +}; + /* * fscrypt_context - the encryption context of an inode * @@ -288,6 +312,25 @@ struct fscrypt_inode_info { u32 ci_hashed_ino; }; +/* + * fscrypt_extent_info - the "encryption key" for an extent. + * + * This contains the dervied key for the given extent and the nonce for the + * extent. + */ +struct fscrypt_extent_info { + refcount_t refs; + + /* The derived key for this extent. */ + struct fscrypt_prepared_key prep_key; + + /* The super block that this extent belongs to. */ + struct super_block *sb; + + /* This is the extents nonce, loaded from the fscrypt_extent_context */ + u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; +}; + typedef enum { FS_DECRYPT = 0, FS_ENCRYPT, @@ -295,6 +338,7 @@ typedef enum { /* crypto.c */ extern struct kmem_cache *fscrypt_inode_info_cachep; +extern struct kmem_cache *fscrypt_extent_info_cachep; int fscrypt_initialize(struct super_block *sb); int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci, fscrypt_direction_t rw, u64 index, diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index b4002aea7cdb..4eeb75410ba8 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -279,6 +279,40 @@ void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, } EXPORT_SYMBOL_GPL(fscrypt_set_bio_crypt_ctx); +/** + * fscrypt_set_bio_crypt_ctx() - prepare a file contents bio for inline crypto + * @bio: a bio which will eventually be submitted to the file + * @inode: the file's inode + * @ei: the extent's crypto info + * @first_lblk: the first file logical block number in the I/O + * @gfp_mask: memory allocation flags - these must be a waiting mask so that + * bio_crypt_set_ctx can't fail. + * + * If the contents of the file should be encrypted (or decrypted) with inline + * encryption, then assign the appropriate encryption context to the bio. + * + * Normally the bio should be newly allocated (i.e. no pages added yet), as + * otherwise fscrypt_mergeable_bio() won't work as intended. + * + * The encryption context will be freed automatically when the bio is freed. + */ +void fscrypt_set_bio_crypt_ctx_from_extent(struct bio *bio, + const struct inode *inode, + const struct fscrypt_extent_info *ei, + u64 first_lblk, gfp_t gfp_mask) +{ + const struct fscrypt_inode_info *ci; + u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE]; + + if (!fscrypt_inode_uses_inline_crypto(inode)) + return; + ci = inode->i_crypt_info; + + fscrypt_generate_dun(ci, first_lblk, dun); + bio_crypt_set_ctx(bio, ei->prep_key.blk_key, dun, gfp_mask); +} +EXPORT_SYMBOL_GPL(fscrypt_set_bio_crypt_ctx_from_extent); + /* Extract the inode and logical block number from a buffer_head. */ static bool bh_get_inode_and_lblk_num(const struct buffer_head *bh, const struct inode **inode_ret, @@ -370,6 +404,56 @@ bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, } EXPORT_SYMBOL_GPL(fscrypt_mergeable_bio); +/** + * fscrypt_mergeable_extent_bio() - test whether data can be added to a bio + * @bio: the bio being built up + * @inode: the inode for the next part of the I/O + * @ei: the fscrypt_extent_info for this extent + * @next_lblk: the next file logical block number in the I/O + * + * When building a bio which may contain data which should undergo inline + * encryption (or decryption) via fscrypt, filesystems should call this function + * to ensure that the resulting bio contains only contiguous data unit numbers. + * This will return false if the next part of the I/O cannot be merged with the + * bio because either the encryption key would be different or the encryption + * data unit numbers would be discontiguous. + * + * fscrypt_set_bio_crypt_ctx_from_extent() must have already been called on the + * bio. + * + * This function isn't required in cases where crypto-mergeability is ensured in + * another way, such as I/O targeting only a single file (and thus a single key) + * combined with fscrypt_limit_io_blocks() to ensure DUN contiguity. + * + * Return: true iff the I/O is mergeable + */ +bool fscrypt_mergeable_extent_bio(struct bio *bio, const struct inode *inode, + const struct fscrypt_extent_info *ei, + u64 next_lblk) +{ + const struct bio_crypt_ctx *bc = bio->bi_crypt_context; + u64 next_dun[BLK_CRYPTO_DUN_ARRAY_SIZE]; + + if (!ei) + return true; + if (!!bc != fscrypt_inode_uses_inline_crypto(inode)) + return false; + if (!bc) + return true; + + /* + * Comparing the key pointers is good enough, as all I/O for each key + * uses the same pointer. I.e., there's currently no need to support + * merging requests where the keys are the same but the pointers differ. + */ + if (bc->bc_key != ei->prep_key.blk_key) + return false; + + fscrypt_generate_dun(inode->i_crypt_info, next_lblk, next_dun); + return bio_crypt_dun_is_contiguous(bc, bio->bi_iter.bi_size, next_dun); +} +EXPORT_SYMBOL_GPL(fscrypt_mergeable_extent_bio); + /** * fscrypt_mergeable_bio_bh() - test whether data can be added to a bio * @bio: the bio being built up diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index 92eca1400b2d..6d1f00be44f8 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -811,3 +811,158 @@ int fscrypt_drop_inode(struct inode *inode) return !is_master_key_secret_present(ci->ci_master_key); } EXPORT_SYMBOL_GPL(fscrypt_drop_inode); + +static struct fscrypt_extent_info * +setup_extent_info(struct inode *inode, const u8 nonce[FSCRYPT_FILE_NONCE_SIZE]) +{ + struct fscrypt_extent_info *ei; + struct fscrypt_inode_info *ci; + struct fscrypt_master_key *mk; + u8 derived_key[FSCRYPT_MAX_KEY_SIZE]; + int err; + + ci = inode->i_crypt_info; + mk = ci->ci_master_key; + if (!mk) + return ERR_PTR(-ENOKEY); + + ei = kmem_cache_zalloc(fscrypt_extent_info_cachep, GFP_KERNEL); + if (!ei) + return ERR_PTR(-ENOMEM); + + refcount_set(&ei->refs, 1); + memcpy(ei->nonce, nonce, FSCRYPT_FILE_NONCE_SIZE); + ei->sb = inode->i_sb; + + down_read(&mk->mk_sem); + /* + * We specifically don't do is_master_key_secret_present() here because + * if the inode is open and has a reference on the master key then it + * should be available for us to use. + */ + + err = fscrypt_hkdf_expand(&mk->mk_secret.hkdf, + HKDF_CONTEXT_PER_FILE_ENC_KEY, ei->nonce, + FSCRYPT_FILE_NONCE_SIZE, derived_key, + ci->ci_mode->keysize); + if (err) + goto out_free; + + err = fscrypt_prepare_inline_crypt_key(&ei->prep_key, derived_key, ci); + memzero_explicit(derived_key, ci->ci_mode->keysize); + if (err) + goto out_free; + up_read(&mk->mk_sem); + return ei; +out_free: + up_read(&mk->mk_sem); + memzero_explicit(ei, sizeof(*ei)); + kmem_cache_free(fscrypt_extent_info_cachep, ei); + return ERR_PTR(err); +} + +/** + * fscrypt_prepare_new_extent() - prepare to create a new extent for a file + * @inode: the possibly-encrypted inode + * + * If the inode is encrypted, setup the fscrypt_extent_info for a new extent. + * This will include the nonce and the derived key necessary for the extent to + * be encrypted. This is only meant to be used with inline crypto. + * + * This doesn't persist the new extents encryption context, this is done later + * by calling fscrypt_set_extent_context(). + * + * Return: The newly allocated fscrypt_extent_info on success, -EOPNOTSUPP if + * we're not encrypted, or another -errno code + */ +struct fscrypt_extent_info *fscrypt_prepare_new_extent(struct inode *inode) +{ + u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; + + if (!fscrypt_inode_uses_inline_crypto(inode)) + return ERR_PTR(-EOPNOTSUPP); + + get_random_bytes(nonce, FSCRYPT_FILE_NONCE_SIZE); + return setup_extent_info(inode, nonce); +} +EXPORT_SYMBOL_GPL(fscrypt_prepare_new_extent); + +/** + * fscrypt_load_extent_info() - create an fscrypt_extent_info from the context + * @inode: the inode + * @ctx: the context buffer + * @ctx_size: the size of the context buffer + * + * Create the file_extent_info and derive the key based on the + * fscrypt_extent_context buffer that is probided. + * + * Return: The newly allocated fscrypt_extent_info on success, -EOPNOTSUPP if + * we're not encrypted, or another -errno code + */ +struct fscrypt_extent_info *fscrypt_load_extent_info(struct inode *inode, + u8 *ctx, size_t ctx_size) +{ + struct fscrypt_extent_context extent_ctx; + const struct fscrypt_inode_info *ci = inode->i_crypt_info; + const struct fscrypt_policy_v2 *policy = &ci->ci_policy.v2; + + if (!fscrypt_inode_uses_inline_crypto(inode)) + return ERR_PTR(-EOPNOTSUPP); + if (ctx_size < sizeof(extent_ctx)) + return ERR_PTR(-EINVAL); + + memcpy(&extent_ctx, ctx, sizeof(extent_ctx)); + + /* + * For now we need to validate that the master key for the inode matches + * the extent. + */ + if (memcmp(extent_ctx.master_key_identifier, + policy->master_key_identifier, + sizeof(extent_ctx.master_key_identifier))) + return ERR_PTR(-EINVAL); + + return setup_extent_info(inode, extent_ctx.nonce); +} +EXPORT_SYMBOL(fscrypt_load_extent_info); + +/** + * fscrypt_put_extent_info() - free the extent_info fscrypt data + * @ei: the extent_info being evicted + * + * Drop a reference and possibly free the fscrypt_extent_info. + * + * Note this will unload the key from the block layer, which takes the crypto + * profile semaphore to unload the key. Make sure you're not dropping this in a + * context that can't sleep. + */ +void fscrypt_put_extent_info(struct fscrypt_extent_info *ei) +{ + if (!ei) + return; + + if (!refcount_dec_and_test(&ei->refs)) + return; + + fscrypt_destroy_prepared_key(ei->sb, &ei->prep_key); + memzero_explicit(ei, sizeof(*ei)); + kmem_cache_free(fscrypt_extent_info_cachep, ei); +} +EXPORT_SYMBOL_GPL(fscrypt_put_extent_info); + +/** + * fscrypt_get_extent_info() - get a ref on the fscrypt extent info + * @ei: the extent_info to get. + * + * Get a reference on the fscrypt_extent_info. + * + * Return: the ei with an extra ref, NULL if there was no ei passed in. + */ +struct fscrypt_extent_info *fscrypt_get_extent_info(struct fscrypt_extent_info *ei) +{ + if (!ei) + return NULL; + refcount_inc(&ei->refs); + return ei; +} +EXPORT_SYMBOL_GPL(fscrypt_get_extent_info); diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index 701259991277..4729f21e21d8 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -789,6 +789,53 @@ int fscrypt_set_context(struct inode *inode, void *fs_data) } EXPORT_SYMBOL_GPL(fscrypt_set_context); +/** + * fscrypt_set_extent_context() - Set the fscrypt extent context of a new extent + * @inode: the inode this extent belongs to + * @ei: the fscrypt_extent_info for the given extent + * @buf: the buffer to copy the fscrypt extent context into + * + * This should be called after fscrypt_prepare_new_extent(), using the + * fscrypt_extent_info that was created at that point. + * + * Return: the size of the fscrypt_extent_context, errno if the inode has the + * wrong policy version. + */ +ssize_t fscrypt_set_extent_context(struct inode *inode, + struct fscrypt_extent_info *ei, u8 *buf) +{ + struct fscrypt_extent_context *ctx = (struct fscrypt_extent_context *)buf; + const struct fscrypt_inode_info *ci = inode->i_crypt_info; + + if (ci->ci_policy.version != 2) + return -EINVAL; + + ctx->version = 1; + memcpy(ctx->master_key_identifier, + ci->ci_policy.v2.master_key_identifier, + sizeof(ctx->master_key_identifier)); + memcpy(ctx->nonce, ei->nonce, FSCRYPT_FILE_NONCE_SIZE); + return sizeof(struct fscrypt_extent_context); +} +EXPORT_SYMBOL_GPL(fscrypt_set_extent_context); + +/** + * fscrypt_extent_context_size() - Return the size of the on-disk extent context + * @inode: the inode this extent belongs to. + * + * Return the size of the extent context for this inode. Since there is only + * one extent context version currently this is just the size of the extent + * context if the inode is encrypted. + */ +size_t fscrypt_extent_context_size(struct inode *inode) +{ + if (!IS_ENCRYPTED(inode)) + return 0; + + return sizeof(struct fscrypt_extent_context); +} +EXPORT_SYMBOL_GPL(fscrypt_extent_context_size); + /** * fscrypt_parse_test_dummy_encryption() - parse the test_dummy_encryption mount option * @param: the mount option diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 12f9e455d569..ea8fdc6f3b83 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -32,6 +32,7 @@ union fscrypt_policy; struct fscrypt_inode_info; +struct fscrypt_extent_info; struct fs_parameter; struct seq_file; @@ -97,6 +98,14 @@ struct fscrypt_operations { */ unsigned int supports_subblock_data_units : 1; + /* + * If set then extent based encryption will be used for this file + * system, and fs/crypto/ will enforce limits on the policies that are + * allowed to be chosen. Currently this means only plain v2 policies + * are supported. + */ + unsigned int has_per_extent_encryption : 1; + /* * This field exists only for backwards compatibility reasons and should * only be set by the filesystems that are setting it already. It @@ -308,6 +317,11 @@ int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg); int fscrypt_has_permitted_context(struct inode *parent, struct inode *child); int fscrypt_context_for_new_inode(void *ctx, struct inode *inode); int fscrypt_set_context(struct inode *inode, void *fs_data); +ssize_t fscrypt_set_extent_context(struct inode *inode, + struct fscrypt_extent_info *ei, u8 *buf); +struct fscrypt_extent_info *fscrypt_load_extent_info(struct inode *inode, + u8 *ctx, size_t ctx_size); +size_t fscrypt_extent_context_size(struct inode *inode); struct fscrypt_dummy_policy { const union fscrypt_policy *policy; @@ -344,6 +358,9 @@ int fscrypt_prepare_new_inode(struct inode *dir, struct inode *inode, void fscrypt_put_encryption_info(struct inode *inode); void fscrypt_free_inode(struct inode *inode); int fscrypt_drop_inode(struct inode *inode); +struct fscrypt_extent_info *fscrypt_prepare_new_extent(struct inode *inode); +void fscrypt_put_extent_info(struct fscrypt_extent_info *ei); +struct fscrypt_extent_info *fscrypt_get_extent_info(struct fscrypt_extent_info *ei); /* fname.c */ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname, @@ -555,6 +572,24 @@ fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy) { } +static inline ssize_t +fscrypt_set_extent_context(struct inode *inode, struct fscrypt_extent_info *ei, + u8 *buf) +{ + return -EOPNOTSUPP; +} + +static inline struct fscrypt_extent_info * +fscrypt_load_extent_info(struct inode *inode, u8 *ctx, size_t ctx_size) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline size_t fscrypt_extent_context_size(struct inode *inode) +{ + return 0; +} + /* keyring.c */ static inline void fscrypt_destroy_keyring(struct super_block *sb) { @@ -607,6 +642,20 @@ static inline int fscrypt_drop_inode(struct inode *inode) return 0; } +static inline struct fscrypt_extent_info * +fscrypt_prepare_new_extent(struct inode *inode) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline void fscrypt_put_extent_info(struct fscrypt_extent_info *ei) { } + +static inline struct fscrypt_extent_info * +fscrypt_get_extent_info(struct fscrypt_extent_info *ei) +{ + return ei; +} + /* fname.c */ static inline int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname, @@ -788,6 +837,11 @@ void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, u64 first_lblk, gfp_t gfp_mask); +void fscrypt_set_bio_crypt_ctx_from_extent(struct bio *bio, + const struct inode *inode, + const struct fscrypt_extent_info *ei, + u64 first_lblk, gfp_t gfp_mask); + void fscrypt_set_bio_crypt_ctx_bh(struct bio *bio, const struct buffer_head *first_bh, gfp_t gfp_mask); @@ -798,6 +852,10 @@ bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, bool fscrypt_mergeable_bio_bh(struct bio *bio, const struct buffer_head *next_bh); +bool fscrypt_mergeable_extent_bio(struct bio *bio, const struct inode *inode, + const struct fscrypt_extent_info *ei, + u64 next_lblk); + bool fscrypt_dio_supported(struct inode *inode); u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks); @@ -813,6 +871,11 @@ static inline void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, u64 first_lblk, gfp_t gfp_mask) { } +static inline void fscrypt_set_bio_crypt_ctx_from_extent(struct bio *bio, + const struct inode *inode, + const struct fscrypt_extent_info *ei, + u64 first_lblk, gfp_t gfp_mask) { } + static inline void fscrypt_set_bio_crypt_ctx_bh( struct bio *bio, const struct buffer_head *first_bh, @@ -825,6 +888,14 @@ static inline bool fscrypt_mergeable_bio(struct bio *bio, return true; } +static inline bool fscrypt_mergeable_extent_bio(struct bio *bio, + const struct inode *inode, + const struct fscrypt_extent_info *ei, + u64 next_lblk) +{ + return true; +} + static inline bool fscrypt_mergeable_bio_bh(struct bio *bio, const struct buffer_head *next_bh) { From patchwork Tue Oct 10 20:40:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416063 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 953ACCD6119 for ; Tue, 10 Oct 2023 20:41:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231450AbjJJUlQ (ORCPT ); Tue, 10 Oct 2023 16:41:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55258 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234473AbjJJUlN (ORCPT ); Tue, 10 Oct 2023 16:41:13 -0400 Received: from mail-yw1-x1132.google.com (mail-yw1-x1132.google.com [IPv6:2607:f8b0:4864:20::1132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D5EFFB7 for ; Tue, 10 Oct 2023 13:41:09 -0700 (PDT) Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-5a7ab31fb8bso22350277b3.1 for ; Tue, 10 Oct 2023 13:41:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970469; x=1697575269; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=jrb2x4Nys7RjPe3v/rGBGWIlt1Z2rhPrxm8XK7K5cwQ=; b=m15I01bX++RnRJ2N6taEInQ8ysuvzm5drw4IvDneNm0y35/ESqV4aFEvWWzL/Cm6RY GEAtzAR+9aj6ih/+RUbcPnvZj6oDGj7tCKb5ITIFxr44LlegRM4ff6cvNkIftoiBFT4c d2j6IeLh6bKT1tqJ7oPXFX2x9w2MdrwlPWNfr9n87RVs0i05LO2UEPMLad7bdQWAxmlE Vo2NuQ9TO2QMGlsSuENGttx29QRx+RDj8UlNVRel8G3HFEEuTdrBXNNdTlvvowRV37JE 8m+fkDb2bH2piMbXm7GrNTsAJloAEDTdTZFYWjKpyQB4qy5fWQpJWHWaAWaeMZGFvM+/ CpLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970469; x=1697575269; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jrb2x4Nys7RjPe3v/rGBGWIlt1Z2rhPrxm8XK7K5cwQ=; b=BxbQdGY+nwo+qynat20ojBRjLFlwHPqRuAAHP9/OrJHXaR5cojTZFsz4XS16GhbfaI G/SX7qBx8E+ZiXfpwF4YNDmRaO6h7A00ssLYivmNPXZM7hrHoHgmnFlCY6KSIfbqucx3 JjNbVEyYQ36cbspEbrvfb7260K/dpMFHqFAbgfKnw7A1ollQBAbbdW7SmWoR4qIJQAe8 +oUXkXcYm9HrZzZhk7bHVqd6N1Gk5AWz8WIwGNatn1j0xgAgLr98zguwXcXc/Aek4tH0 zo4tiz3f0hYSSars0KWBi636p7BdheStXMhjQZoFDT0gdlEGld/NpYmUhu3OG8kNuy4m GmbA== X-Gm-Message-State: AOJu0YzqUYzjehNjZDVIuMqJd3ASIuPtfy60dd67SG4toPOfhZlDPX3P LvxbtLWuM8x8eS0rp14tGTzBH5WQ/bKd0m2eG2VVXg== X-Google-Smtp-Source: AGHT+IEsUZ8erj5VJUQi36nUP18bhs4RN8p0sJyQDvO1xm2DGVPUtjgqSMHSC1IGo7/9xFp31iPXkA== X-Received: by 2002:a81:73c1:0:b0:59b:5d6b:5110 with SMTP id o184-20020a8173c1000000b0059b5d6b5110mr20946525ywc.21.1696970468986; Tue, 10 Oct 2023 13:41:08 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id d184-20020a0ddbc1000000b00586108dd8f5sm4608386ywe.18.2023.10.10.13.41.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:08 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 04/36] fscrypt: disable all but standard v2 policies for extent encryption Date: Tue, 10 Oct 2023 16:40:19 -0400 Message-ID: <39faa5d97713d44564249b50518c0212e5bf04cc.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org The different encryption related options for fscrypt are too numerous to support for extent based encryption. Support for a few of these options could possibly be added, but since they're niche options simply reject them for file systems using extent based encryption. Signed-off-by: Josef Bacik --- fs/crypto/policy.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index 4729f21e21d8..75a69f02f11d 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -209,6 +209,12 @@ static bool fscrypt_supported_v1_policy(const struct fscrypt_policy_v1 *policy, return false; } + if (inode->i_sb->s_cop->has_per_extent_encryption) { + fscrypt_warn(inode, + "v1 policies can't be used on file systems that use extent encryption"); + return false; + } + return true; } @@ -269,6 +275,12 @@ static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy, } } + if ((inode->i_sb->s_cop->has_per_extent_encryption) && count) { + fscrypt_warn(inode, + "Encryption flags aren't supported on file systems that use extent encryption"); + return false; + } + if ((policy->flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) && !supported_direct_key_modes(inode, policy->contents_encryption_mode, policy->filenames_encryption_mode)) From patchwork Tue Oct 10 20:40:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416065 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 0157ACD68E9 for ; Tue, 10 Oct 2023 20:41:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234483AbjJJUlR (ORCPT ); Tue, 10 Oct 2023 16:41:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55228 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234583AbjJJUlO (ORCPT ); Tue, 10 Oct 2023 16:41:14 -0400 Received: from mail-yw1-x112c.google.com (mail-yw1-x112c.google.com [IPv6:2607:f8b0:4864:20::112c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 41631D8 for ; Tue, 10 Oct 2023 13:41:11 -0700 (PDT) Received: by mail-yw1-x112c.google.com with SMTP id 00721157ae682-59b5484fbe6so75352327b3.1 for ; Tue, 10 Oct 2023 13:41:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970470; x=1697575270; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=3m4RAmLF+khaONHXt5qu//wFJJoUrRtGots1ic/eLAI=; b=WjfFi+gH5h5K1Rxx88fOl7il7cMo1NwVuHfhNO9uPV/j+y2+ahEQd4RjsgDL5154by RWeE+SibHed/VdWh/hho6I2YbWoyMVip28dIWPKHu174IYo2U/+z21MrZwuqWYp4EiVg 05Rr5czj4m+0KvVdJNfMUxT/xH0VzgKoO4r5Zr0oFpRAh1yTgNU/Sx6wZMAlDhODlFpc n8/5xsl5LbO18JHqI41LT3qyyoAXaOafyCKF0uktkzV3+rjU1VHgVQlcFXqflpZQgTve ICJTARlqXYiGTJ8mgVrXIKI3jGRY/Ez4M1a0ITVB/tuX9nyC2U/aL3mv6UCdLu2Wy32C bxIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970470; x=1697575270; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3m4RAmLF+khaONHXt5qu//wFJJoUrRtGots1ic/eLAI=; b=j+pWnO7NIRFE6DAMI1o63ymQe6ut8cUdOFj/ARLfb9RPabdcd4LDG1PWoRyGnSarWp 0vcZ/6WBL2PjTPcWZx00TjHrQ2ECzWJOE6tfl+0SjJn9IR2GnQyNyqDuSeEsgZt6BLNC 4Fq3go8VZH/pzri+JnMzM5op6gDi7V05OlcbLh2ASOeZC2I62EfnnZV1NwMg41B1vS2H XOxHXGGZkZZxo0ReLT4mAKxqZNfbiRz3L9awhw7Qj+cZBeGMwBolAv3ZF2eQH5RHIwc0 UQQkv0gaYIChIFLzl8uC52+nr7PZ2z4hrgE9DYQtDh1tWMTlCvo4BqywYxjBkFtb8SG3 errQ== X-Gm-Message-State: AOJu0YwaL5T/owsL8d166ltJIRht6QQaaj+UCvdYqlB0cx2TUgyXpJdH n5LW0v9pLIQ1BQgOTs5hXSVGuCT3zkzy7DivZVG0cA== X-Google-Smtp-Source: AGHT+IEouGSIjN904f72tEDHIxSSZumqXFfqa+Z9ibdW067FA51KO6BL+bO0SLL2rzK/kWN9sdei7g== X-Received: by 2002:a81:4e4a:0:b0:5a7:ca59:82b9 with SMTP id c71-20020a814e4a000000b005a7ca5982b9mr2301640ywb.16.1696970470319; Tue, 10 Oct 2023 13:41:10 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id n184-20020a0de4c1000000b005a4d922cf77sm4656731ywe.119.2023.10.10.13.41.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:09 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 05/36] blk-crypto: add a process bio callback Date: Tue, 10 Oct 2023 16:40:20 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Btrfs does checksumming, and the checksums need to match the bytes on disk. In order to facilitate this add a process bio callback for the blk-crypto layer. This allows the file system to specify a callback and then can process the encrypted bio as necessary. For btrfs, writes will have the checksums calculated and saved into our relevant data structures for storage once the write completes. For reads we will validate the checksums match what is on disk and error out if there is a mismatch. This is incompatible with native encryption obviously, so make sure we don't use native encryption if this callback is set. Signed-off-by: Josef Bacik --- block/blk-crypto-fallback.c | 28 ++++++++++++++++++++++++++++ block/blk-crypto-profile.c | 2 ++ block/blk-crypto.c | 6 +++++- fs/crypto/inline_crypt.c | 3 ++- include/linux/blk-crypto-profile.h | 7 +++++++ include/linux/blk-crypto.h | 9 +++++++-- include/linux/fscrypt.h | 14 ++++++++++++++ 7 files changed, 65 insertions(+), 4 deletions(-) diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c index e6468eab2681..8b4a83534127 100644 --- a/block/blk-crypto-fallback.c +++ b/block/blk-crypto-fallback.c @@ -346,6 +346,15 @@ static bool blk_crypto_fallback_encrypt_bio(struct bio **bio_ptr) } } + /* Process the encrypted bio before we submit it. */ + if (bc->bc_key->crypto_cfg.process_bio) { + blk_st = bc->bc_key->crypto_cfg.process_bio(src_bio, enc_bio); + if (blk_st != BLK_STS_OK) { + src_bio->bi_status = blk_st; + goto out_free_bounce_pages; + } + } + enc_bio->bi_private = src_bio; enc_bio->bi_end_io = blk_crypto_fallback_encrypt_endio; *bio_ptr = enc_bio; @@ -391,6 +400,24 @@ static void blk_crypto_fallback_decrypt_bio(struct work_struct *work) unsigned int i; blk_status_t blk_st; + /* + * Process the bio first before trying to decrypt. + * + * NOTE: btrfs expects that this bio is the same that was submitted. If + * at any point this changes we will need to update process_bio to take + * f_ctx->crypt_iter in order to make sure we can iterate the pages for + * checksumming. We're currently saving this in our btrfs_bio, so this + * works, but if at any point in the future we start allocating a bounce + * bio or something we need to update this callback. + */ + if (bc->bc_key->crypto_cfg.process_bio) { + blk_st = bc->bc_key->crypto_cfg.process_bio(bio, bio); + if (blk_st != BLK_STS_OK) { + bio->bi_status = blk_st; + goto out_no_keyslot; + } + } + /* * Get a blk-crypto-fallback keyslot that contains a crypto_skcipher for * this bio's algorithm and key. @@ -560,6 +587,7 @@ static int blk_crypto_fallback_init(void) blk_crypto_fallback_profile->ll_ops = blk_crypto_fallback_ll_ops; blk_crypto_fallback_profile->max_dun_bytes_supported = BLK_CRYPTO_MAX_IV_SIZE; + blk_crypto_fallback_profile->process_bio_supported = true; /* All blk-crypto modes have a crypto API fallback. */ for (i = 0; i < BLK_ENCRYPTION_MODE_MAX; i++) diff --git a/block/blk-crypto-profile.c b/block/blk-crypto-profile.c index 7fabc883e39f..640cf2ea3fcc 100644 --- a/block/blk-crypto-profile.c +++ b/block/blk-crypto-profile.c @@ -352,6 +352,8 @@ bool __blk_crypto_cfg_supported(struct blk_crypto_profile *profile, return false; if (profile->max_dun_bytes_supported < cfg->dun_bytes) return false; + if (cfg->process_bio && !profile->process_bio_supported) + return false; return true; } diff --git a/block/blk-crypto.c b/block/blk-crypto.c index 4d760b092deb..50556952df19 100644 --- a/block/blk-crypto.c +++ b/block/blk-crypto.c @@ -321,6 +321,8 @@ int __blk_crypto_rq_bio_prep(struct request *rq, struct bio *bio, * @dun_bytes: number of bytes that will be used to specify the DUN when this * key is used * @data_unit_size: the data unit size to use for en/decryption + * @process_bio: the call back if the upper layer needs to process the encrypted + * bio * * Return: 0 on success, -errno on failure. The caller is responsible for * zeroizing both blk_key and raw_key when done with them. @@ -328,7 +330,8 @@ int __blk_crypto_rq_bio_prep(struct request *rq, struct bio *bio, int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key, enum blk_crypto_mode_num crypto_mode, unsigned int dun_bytes, - unsigned int data_unit_size) + unsigned int data_unit_size, + blk_crypto_process_bio_t process_bio) { const struct blk_crypto_mode *mode; @@ -350,6 +353,7 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key, blk_key->crypto_cfg.crypto_mode = crypto_mode; blk_key->crypto_cfg.dun_bytes = dun_bytes; blk_key->crypto_cfg.data_unit_size = data_unit_size; + blk_key->crypto_cfg.process_bio = process_bio; blk_key->data_unit_size_bits = ilog2(data_unit_size); blk_key->size = mode->keysize; memcpy(blk_key->raw, raw_key, mode->keysize); diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index 4eeb75410ba8..57776c548a06 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -168,7 +168,8 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, err = blk_crypto_init_key(blk_key, raw_key, crypto_mode, fscrypt_get_dun_bytes(ci), - 1U << ci->ci_data_unit_bits); + 1U << ci->ci_data_unit_bits, + sb->s_cop->process_bio); if (err) { fscrypt_err(inode, "error %d initializing blk-crypto key", err); goto fail; diff --git a/include/linux/blk-crypto-profile.h b/include/linux/blk-crypto-profile.h index 90ab33cb5d0e..3c002e85631a 100644 --- a/include/linux/blk-crypto-profile.h +++ b/include/linux/blk-crypto-profile.h @@ -100,6 +100,13 @@ struct blk_crypto_profile { */ struct device *dev; + /** + * @process_bio_supported: Some things, like btrfs, require the + * encrypted data for checksumming. Drivers set this to true if they can + * handle the process_bio() callback. + */ + bool process_bio_supported; + /* private: The following fields shouldn't be accessed by drivers. */ /* Number of keyslots, or 0 if not applicable */ diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h index 5e5822c18ee4..194c1d727013 100644 --- a/include/linux/blk-crypto.h +++ b/include/linux/blk-crypto.h @@ -6,7 +6,7 @@ #ifndef __LINUX_BLK_CRYPTO_H #define __LINUX_BLK_CRYPTO_H -#include +#include enum blk_crypto_mode_num { BLK_ENCRYPTION_MODE_INVALID, @@ -17,6 +17,9 @@ enum blk_crypto_mode_num { BLK_ENCRYPTION_MODE_MAX, }; +typedef blk_status_t (blk_crypto_process_bio_t)(struct bio *orig_bio, + struct bio *enc_bio); + #define BLK_CRYPTO_MAX_KEY_SIZE 64 /** * struct blk_crypto_config - an inline encryption key's crypto configuration @@ -31,6 +34,7 @@ struct blk_crypto_config { enum blk_crypto_mode_num crypto_mode; unsigned int data_unit_size; unsigned int dun_bytes; + blk_crypto_process_bio_t *process_bio; }; /** @@ -90,7 +94,8 @@ bool bio_crypt_dun_is_contiguous(const struct bio_crypt_ctx *bc, int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key, enum blk_crypto_mode_num crypto_mode, unsigned int dun_bytes, - unsigned int data_unit_size); + unsigned int data_unit_size, + blk_crypto_process_bio_t process_bio); int blk_crypto_start_using_key(struct block_device *bdev, const struct blk_crypto_key *key); diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index ea8fdc6f3b83..a3576da6a9fa 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -16,6 +16,7 @@ #include #include #include +#include #include /* @@ -199,6 +200,19 @@ struct fscrypt_operations { */ struct block_device **(*get_devices)(struct super_block *sb, unsigned int *num_devs); + + /* + * A callback if the file system requires the ability to process the + * encrypted bio. + * + * @orig_bio: the original bio submitted. + * @enc_bio: the encrypted bio. + * + * For writes the enc_bio will be different from the orig_bio, for reads + * they will be the same. For reads we get the bio before it is + * decrypted, for writes we get the bio before it is submitted. + */ + blk_crypto_process_bio_t *process_bio; }; static inline struct fscrypt_inode_info * From patchwork Tue Oct 10 20:40:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416066 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 78122CD8CBE for ; Tue, 10 Oct 2023 20:41:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234550AbjJJUlS (ORCPT ); Tue, 10 Oct 2023 16:41:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55284 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234632AbjJJUlP (ORCPT ); Tue, 10 Oct 2023 16:41:15 -0400 Received: from mail-yw1-x1130.google.com (mail-yw1-x1130.google.com [IPv6:2607:f8b0:4864:20::1130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CE1EDE0 for ; Tue, 10 Oct 2023 13:41:12 -0700 (PDT) Received: by mail-yw1-x1130.google.com with SMTP id 00721157ae682-5a7be88e9ccso14561807b3.2 for ; Tue, 10 Oct 2023 13:41:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970472; x=1697575272; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=3ubwOKPnw/IU4g90S+kgqMqAvosFRnP9dYqQa/ogHNg=; b=IsgsZQ53c2ojlz4XL8cwdY0o08WZpPXIKBe0B1nn+50H16Sh3BBg2Shl/YhN5QltyM YuHIcONRdMn/rQmIJ5MamwgOOhpWK6AEJoTcWHgQJIY0FaBzawfanoWdRZ/oqr8wfQbB PFBFM7UP0JSXdn3rBlT9vjglFIxBIkwCk3tJtyA6xdGiBsNJ3IpLfaLnWxZqAsA6LB9L 4r5HuQlehIjPNg4JfQtnkAfLBDx5oSAoSPJhusCcTXBJSsRk/XyV+NpuH/rVh6OEIdKi 3FTu76qTbwmUB+78UdO2lytbsYBVzccuZObr1k1M/shqeeuOrzhksYIq+5/4ahs93krf PPIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970472; x=1697575272; 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=3ubwOKPnw/IU4g90S+kgqMqAvosFRnP9dYqQa/ogHNg=; b=QHzS27JDDiuhMh8T5RwH+8N1dujai51TC+UcdQvveoVUwiibyIezB6TQ8T1WSEqEQm z3V5JkWh5df9/Er7SkZ6FRtzRZsIdbRKO2t3yB3kuFnUne4w+NdJ0TZesru9+UFkKSgb 455ExAkavR1J3xq9MSToj1S+f7t3u+lZWA8PhI/MlFjzi8FYJqqPx85hyDUkLFwiHV5S ZJ3/CAWOF1F1XGap92JqSzNL0qoHjAKTd5CG/hefQzfmKH4MsEIZHnnEL+4fw4jIO6CG kTrHho1gwTzpVYTyTSdbbVF8XXgUH8rbr52Z3jH18QaVGyQWQNt8W2QaU1D9mFbAPXBr efXQ== X-Gm-Message-State: AOJu0YzEgmX4uKJeaR91wn2bY3ury+L9WzF7NNLQZ4L9ayKbH0kpmMhl eHM4kvgXij9yglrXLlIbeYxqzJxF3E2bW7s6MwI3Mg== X-Google-Smtp-Source: AGHT+IH0MlH/PDspUNysTV3KeSuwCl0LUpu4ueM813c521XL7wiLcvRf96YhXEAhQolyRKkNPb4LdQ== X-Received: by 2002:a81:a156:0:b0:5a7:dbf4:6a1a with SMTP id y83-20020a81a156000000b005a7dbf46a1amr350771ywg.7.1696970471523; Tue, 10 Oct 2023 13:41:11 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id v203-20020a8148d4000000b005a7c00bdc79sm696290ywa.49.2023.10.10.13.41.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:11 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH v2 06/36] fscrypt: expose fscrypt_nokey_name Date: Tue, 10 Oct 2023 16:40:21 -0400 Message-ID: <5f7c3adb304bc3b5263af215f6b476275fdecc47.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Omar Sandoval btrfs stores its data structures, including filenames in directories, in its own buffer implementation, struct extent_buffer, composed of several non-contiguous pages. We could copy filenames into a temporary buffer and use fscrypt_match_name() against that buffer, such extensive memcpying would be expensive. Instead, exposing fscrypt_nokey_name as in this change allows btrfs to recapitulate fscrypt_match_name() using methods on struct extent_buffer instead of dealing with a raw byte array. Signed-off-by: Omar Sandoval Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/crypto/fname.c | 39 +-------------------------------------- include/linux/fscrypt.h | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 7b3fc189593a..5607ee52703e 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include "fscrypt_private.h" @@ -26,43 +25,7 @@ #define FSCRYPT_FNAME_MIN_MSG_LEN 16 /* - * struct fscrypt_nokey_name - identifier for directory entry when key is absent - * - * When userspace lists an encrypted directory without access to the key, the - * filesystem must present a unique "no-key name" for each filename that allows - * it to find the directory entry again if requested. Naively, that would just - * mean using the ciphertext filenames. However, since the ciphertext filenames - * can contain illegal characters ('\0' and '/'), they must be encoded in some - * way. We use base64url. But that can cause names to exceed NAME_MAX (255 - * bytes), so we also need to use a strong hash to abbreviate long names. - * - * The filesystem may also need another kind of hash, the "dirhash", to quickly - * find the directory entry. Since filesystems normally compute the dirhash - * over the on-disk filename (i.e. the ciphertext), it's not computable from - * no-key names that abbreviate the ciphertext using the strong hash to fit in - * NAME_MAX. It's also not computable if it's a keyed hash taken over the - * plaintext (but it may still be available in the on-disk directory entry); - * casefolded directories use this type of dirhash. At least in these cases, - * each no-key name must include the name's dirhash too. - * - * To meet all these requirements, we base64url-encode the following - * variable-length structure. It contains the dirhash, or 0's if the filesystem - * didn't provide one; up to 149 bytes of the ciphertext name; and for - * ciphertexts longer than 149 bytes, also the SHA-256 of the remaining bytes. - * - * This ensures that each no-key name contains everything needed to find the - * directory entry again, contains only legal characters, doesn't exceed - * NAME_MAX, is unambiguous unless there's a SHA-256 collision, and that we only - * take the performance hit of SHA-256 on very long filenames (which are rare). - */ -struct fscrypt_nokey_name { - u32 dirhash[2]; - u8 bytes[149]; - u8 sha256[SHA256_DIGEST_SIZE]; -}; /* 189 bytes => 252 bytes base64url-encoded, which is <= NAME_MAX (255) */ - -/* - * Decoded size of max-size no-key name, i.e. a name that was abbreviated using + * Decoded size of max-size nokey name, i.e. a name that was abbreviated using * the strong hash and thus includes the 'sha256' field. This isn't simply * sizeof(struct fscrypt_nokey_name), as the padding at the end isn't included. */ diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index a3576da6a9fa..9a7cd1e2146e 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -17,6 +17,7 @@ #include #include #include +#include #include /* @@ -56,6 +57,42 @@ struct fscrypt_name { #define fname_name(p) ((p)->disk_name.name) #define fname_len(p) ((p)->disk_name.len) +/* + * struct fscrypt_nokey_name - identifier for directory entry when key is absent + * + * When userspace lists an encrypted directory without access to the key, the + * filesystem must present a unique "no-key name" for each filename that allows + * it to find the directory entry again if requested. Naively, that would just + * mean using the ciphertext filenames. However, since the ciphertext filenames + * can contain illegal characters ('\0' and '/'), they must be encoded in some + * way. We use base64url. But that can cause names to exceed NAME_MAX (255 + * bytes), so we also need to use a strong hash to abbreviate long names. + * + * The filesystem may also need another kind of hash, the "dirhash", to quickly + * find the directory entry. Since filesystems normally compute the dirhash + * over the on-disk filename (i.e. the ciphertext), it's not computable from + * no-key names that abbreviate the ciphertext using the strong hash to fit in + * NAME_MAX. It's also not computable if it's a keyed hash taken over the + * plaintext (but it may still be available in the on-disk directory entry); + * casefolded directories use this type of dirhash. At least in these cases, + * each no-key name must include the name's dirhash too. + * + * To meet all these requirements, we base64url-encode the following + * variable-length structure. It contains the dirhash, or 0's if the filesystem + * didn't provide one; up to 149 bytes of the ciphertext name; and for + * ciphertexts longer than 149 bytes, also the SHA-256 of the remaining bytes. + * + * This ensures that each no-key name contains everything needed to find the + * directory entry again, contains only legal characters, doesn't exceed + * NAME_MAX, is unambiguous unless there's a SHA-256 collision, and that we only + * take the performance hit of SHA-256 on very long filenames (which are rare). + */ +struct fscrypt_nokey_name { + u32 dirhash[2]; + u8 bytes[149]; + u8 sha256[SHA256_DIGEST_SIZE]; +}; /* 189 bytes => 252 bytes base64url-encoded, which is <= NAME_MAX (255) */ + /* Maximum value for the third parameter of fscrypt_operations.set_context(). */ #define FSCRYPT_SET_CONTEXT_MAX_SIZE 40 From patchwork Tue Oct 10 20:40:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416068 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 3CB0BCD6119 for ; Tue, 10 Oct 2023 20:41:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343647AbjJJUlU (ORCPT ); Tue, 10 Oct 2023 16:41:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234442AbjJJUlP (ORCPT ); Tue, 10 Oct 2023 16:41:15 -0400 Received: from mail-yw1-x1132.google.com (mail-yw1-x1132.google.com [IPv6:2607:f8b0:4864:20::1132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E3B891 for ; Tue, 10 Oct 2023 13:41:13 -0700 (PDT) Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-59bebd5bdadso75469567b3.0 for ; Tue, 10 Oct 2023 13:41:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970472; x=1697575272; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=04NXAXYAL76rZFvqx8617y1QivsQaz2o0HkmETeNnJo=; b=lM7P5Us7VcNlJkQwcpe0kT7qPTAi32j9o+e5Z8XCWMTd410DKf5bjw6OlKq+BpnVmo f7QIp7P8/+PLr6pR5DbGZpjovCQ/SDVhdZltsO0HJutfAf+waf3SZardf9TnYlYuixEu o+drhTwQed7kmDkCNNQHmB/ISW++a6h4vsmQRK0Vc2LFnbfuduWQn2D/WjxnkxhzU3Yu BauHWhoHRNh/Ns9sISO/Da11RiRUNiZZCkVYwRdizLR9N4V0HqxAT5Y5fRsBjpPzkE+I 46XCVXU87T/IeH/MNW/s6TYFd8k1gyf34LhH3g0A6ctlhEq9Q2gGHBpqgjWVhADcPNs3 wCnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970472; x=1697575272; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=04NXAXYAL76rZFvqx8617y1QivsQaz2o0HkmETeNnJo=; b=wddHGzEkdfHbcU1RlmwdORBw5ocZN+e0EfMN4t0r7maTJHNeVu0jytYaebHw6DM+1R Hdu1m+PwK9M5rMwJEuwtsZWA6NF0hARa7y0cC5s1MEivL79R5w5r3pQTXl+8OUHMcYFF CqEUg7v2B7ZHMh9/bqqtHIkt9dwfT6AkeITYfB1jihT7Wk5AOIFvOM9r/QHd1t5cfKwG voJRck0y6483BJChOs2GZqwbHfA8TBP5xTgh9UxVvR3nF0FXS5MgTijHKwf5i8gO14I5 x9OLMHFZLXNrpBYCJB3uLkPwFLJDZiPlKyKdXWS2Q5ER1FQbpAWUdfyQrzIPJqVIl7eJ j1xA== X-Gm-Message-State: AOJu0YxTKn4lIgI4eMYyvTTINR5EGZ3KTadgYDNHOaRINpolOt85RwWg PHqUSyTEuP/fPI9xWiBKMQ5xJdvv6fTg4ZuL0lFeig== X-Google-Smtp-Source: AGHT+IGmi7RnyAArKPVXwSMJyCrhSIl3U3g2YRLot+FS8OSdQ1I1a+5v9lOo+SGVn0zVU+Ma7bA0ww== X-Received: by 2002:a0d:cac5:0:b0:59f:5895:6e38 with SMTP id m188-20020a0dcac5000000b0059f58956e38mr21172770ywd.4.1696970472539; Tue, 10 Oct 2023 13:41:12 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id c65-20020a0df344000000b005925765aa30sm4697647ywf.135.2023.10.10.13.41.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:12 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 07/36] fscrypt: add documentation about extent encryption Date: Tue, 10 Oct 2023 16:40:22 -0400 Message-ID: <68d59d78499743cecf1cdde9d77bfc6fbe1e6a0c.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Add a couple of sections to the fscrypt documentation about per-extent encryption. Signed-off-by: Josef Bacik --- Documentation/filesystems/fscrypt.rst | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index 28700fb41a00..6235b1caec2d 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -256,6 +256,21 @@ alternative master keys or to support rotating master keys. Instead, the master keys may be wrapped in userspace, e.g. as is done by the `fscrypt `_ tool. +Per-extent encryption keys +-------------------------- + +For certain file systems, such as btrfs, it's desired to derive a +per-extent encryption key. This is to enable features such as snapshots +and reflink, where you could have different inodes pointing at the same +extent. When a new extent is created fscrypt randomly generates a +16-byte nonce and the file system stores it along side the extent. +Then, it uses a KDF (as described in `Key derivation function`_) to +derive the extent's key from the master key and nonce. + +Currently the inode's master key and encryption policy must match the +extent, so you cannot share extents between inodes that were encrypted +differently. + DIRECT_KEY policies ------------------- @@ -1394,6 +1409,27 @@ by the kernel and is used as KDF input or as a tweak to cause different files to be encrypted differently; see `Per-file encryption keys`_ and `DIRECT_KEY policies`_. +Extent encryption context +------------------------- + +The extent encryption context mirrors the important parts of the above +`Encryption context`_, with a few ommisions. The struct is defined as +follows:: + + struct fscrypt_extent_context { + u8 version; + u8 encryption_mode; + u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; + u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; + }; + +Currently all fields much match the containing inode's encryption +context, with the exception of the nonce. + +Additionally extent encryption is only supported with +FSCRYPT_EXTENT_CONTEXT_V2 using the standard policy, all other policies +are disallowed. + Data path changes ----------------- From patchwork Tue Oct 10 20:40:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416067 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 3A254CD690D for ; Tue, 10 Oct 2023 20:41:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234623AbjJJUlU (ORCPT ); Tue, 10 Oct 2023 16:41:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55258 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234455AbjJJUlQ (ORCPT ); Tue, 10 Oct 2023 16:41:16 -0400 Received: from mail-yw1-x1131.google.com (mail-yw1-x1131.google.com [IPv6:2607:f8b0:4864:20::1131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ABDC09E for ; Tue, 10 Oct 2023 13:41:14 -0700 (PDT) Received: by mail-yw1-x1131.google.com with SMTP id 00721157ae682-5a7c011e113so13938817b3.1 for ; Tue, 10 Oct 2023 13:41:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970473; x=1697575273; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=gnxchsTqt7xlkIIa+flWeo9ILMxv8/p1t4FXazb249Y=; b=YxaSsmyz87izCljeWQWbJIRmkYKLwGfCDc4paEZLkpl30VQJfyAp4/nMxhilTY8XkL e4FABn52fCZvfsYH3VvGGoOKAsnF7zSVlB7M77j2G+LVszqy4nO1v5QCrdQgtAEDQWRH MCVwKvT1K3bQJKk7cDVac9JPMWPQpHg0h1rboXyLONjaPuYLZn8SEr65nNk6QPKkI1lM q4/u0+7r30WgtWUBE8DUO39VqFRtwgYWI+/JLXijVHps1+ziRwnMyWjdPNsOunzr02yi 6gvkBSnrMtIrd8Uqqc9mfsFA5p5M3wjJbRdX0C9kWdChfZbyklAPcn5Nuil4CoWz53/V GOYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970473; x=1697575273; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gnxchsTqt7xlkIIa+flWeo9ILMxv8/p1t4FXazb249Y=; b=VFvqNOvxvmCiU5dSAvBL/DhBFhRkVIM+xdTcCDu/HPED6tYJ3Q57zs995JYnmvXYWX F8hUv3yyM3S1VO0s83Ehvnv2S8JJWlRKAvsJDna5Xko6TJPdKBmBVKsFywRXKdyjBBxb kiFmNPs3zd83+PKdx67ke78Qoc0R5MKaU4QXkiY2eIrRYo1kjZfoUgyX+Zue2H0YIWjM WISWmWcKYteItkLU3zn4riNHA/KrJbEOP3ZWkM1Rj+nLgEIV6EOUJl5zEhPTLJOebm4F yRXK0hWSyRav+odIVqLsZtzUo5uaA5XvHw/MIpp/tzIDprsvKcE2Gt5OCK0c8lAoO72R twSA== X-Gm-Message-State: AOJu0YzpA6ZR0B7Cd0AQD5wgJsl87VOjQF1GhpvCWZ7oLgItFI0n7CIa VDOAPogeDfji1w3PqrkrzBYMoa/84VesCDeU9L71UQ== X-Google-Smtp-Source: AGHT+IEL7uLXgLh7+c0J/e4v1Krpm32gxaFvmrrmYabG8AJ596LCVEdVrofQHNhkUSM5CPz7d2FKVA== X-Received: by 2002:a0d:dfc6:0:b0:57a:2e83:4daf with SMTP id i189-20020a0ddfc6000000b0057a2e834dafmr19660246ywe.32.1696970473563; Tue, 10 Oct 2023 13:41:13 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id m73-20020a0dca4c000000b005a7db2a0dddsm101985ywd.3.2023.10.10.13.41.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:13 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 08/36] btrfs: add infrastructure for safe em freeing Date: Tue, 10 Oct 2023 16:40:23 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org When we add fscrypt support we're going to have fscrypt objects hanging off of extent_maps. This includes a block key, which if we're the last one freeing the key we may have to unregister it from the block layer. This requires taking a semaphore in the block layer, which means we can't free em's under the extent map tree lock. Thankfully we only do this in two places, one where we're dropping a range of extent maps, and when we're freeing logged extents. Add a free_extent_map_safe() which will add the em to a list in the em_tree if we free'd the object. Currently this is unconditional but will be changed to conditional on the fscrypt object we will add in a later patch. To process these delayed objects add a free_pending_extent_maps() that is called after the lock has been dropped on the em_tree. This will process the extent maps on the freed list and do the appropriate freeing work in a safe manner. Signed-off-by: Josef Bacik --- fs/btrfs/extent_map.c | 80 ++++++++++++++++++++++++++++++++++++++++--- fs/btrfs/extent_map.h | 10 ++++++ fs/btrfs/tree-log.c | 6 ++-- 3 files changed, 89 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index a6d8368ed0ed..af5ff6b10865 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -35,7 +35,9 @@ void __cold extent_map_exit(void) void extent_map_tree_init(struct extent_map_tree *tree) { tree->map = RB_ROOT_CACHED; + tree->flags = 0; INIT_LIST_HEAD(&tree->modified_extents); + INIT_LIST_HEAD(&tree->freed_extents); rwlock_init(&tree->lock); } @@ -53,9 +55,17 @@ struct extent_map *alloc_extent_map(void) em->compress_type = BTRFS_COMPRESS_NONE; refcount_set(&em->refs, 1); INIT_LIST_HEAD(&em->list); + INIT_LIST_HEAD(&em->free_list); return em; } +static void __free_extent_map(struct extent_map *em) +{ + if (test_bit(EXTENT_FLAG_FS_MAPPING, &em->flags)) + kfree(em->map_lookup); + kmem_cache_free(extent_map_cache, em); +} + /* * Drop the reference out on @em by one and free the structure if the reference * count hits zero. @@ -67,12 +77,69 @@ void free_extent_map(struct extent_map *em) if (refcount_dec_and_test(&em->refs)) { WARN_ON(extent_map_in_tree(em)); WARN_ON(!list_empty(&em->list)); - if (test_bit(EXTENT_FLAG_FS_MAPPING, &em->flags)) - kfree(em->map_lookup); - kmem_cache_free(extent_map_cache, em); + __free_extent_map(em); } } +/* + * Drop a ref for the extent map in the given tree. + * + * @tree: tree that the em is a part of. + * @em: the em to drop the reference to. + * + * Drop the reference count on @em by one, if the reference count hits 0 and + * there is an object on the em that can't be safely freed in the current + * context (if we are holding the extent_map_tree->lock for example), then add + * it to the freed_extents list on the extent_map_tree for later processing. + * + * This must be followed by a free_pending_extent_maps() to clear the pending + * frees. + */ +void free_extent_map_safe(struct extent_map_tree *tree, + struct extent_map *em) +{ + lockdep_assert_held_write(&tree->lock); + + if (!em) + return; + + if (refcount_dec_and_test(&em->refs)) { + WARN_ON(extent_map_in_tree(em)); + WARN_ON(!list_empty(&em->list)); + list_add_tail(&em->free_list, &tree->freed_extents); + set_bit(EXTENT_MAP_TREE_PENDING_FREES, &tree->flags); + } +} + +/* + * Free the em objects that exist on the em tree + * + * @tree: the tree to free the objects from. + * + * If there are any objects on the em->freed_extents list go ahead and free them + * here in a safe way. This is to be coupled with any uses of + * free_extent_map_safe(). + */ +void free_pending_extent_maps(struct extent_map_tree *tree) +{ + struct extent_map *em; + + /* Avoid taking the write lock if we don't have any pending frees. */ + if (!test_and_clear_bit(EXTENT_MAP_TREE_PENDING_FREES, &tree->flags)) + return; + + write_lock(&tree->lock); + while ((em = list_first_entry_or_null(&tree->freed_extents, + struct extent_map, free_list))) { + list_del_init(&em->free_list); + write_unlock(&tree->lock); + __free_extent_map(em); + cond_resched(); + write_lock(&tree->lock); + } + write_unlock(&tree->lock); +} + /* Do the math around the end of an extent, handling wrapping. */ static u64 range_end(u64 start, u64 len) { @@ -684,10 +751,12 @@ static void drop_all_extent_maps_fast(struct extent_map_tree *tree) clear_bit(EXTENT_FLAG_PINNED, &em->flags); clear_bit(EXTENT_FLAG_LOGGING, &em->flags); remove_extent_mapping(tree, em); - free_extent_map(em); + free_extent_map_safe(tree, em); cond_resched_rwlock_write(&tree->lock); } write_unlock(&tree->lock); + + free_pending_extent_maps(tree); } /* @@ -908,13 +977,14 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end, free_extent_map(em); next: /* Once for us (for our lookup reference). */ - free_extent_map(em); + free_extent_map_safe(em_tree, em); em = next_em; } write_unlock(&em_tree->lock); + free_pending_extent_maps(em_tree); free_extent_map(split); free_extent_map(split2); } diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index 35d27c756e08..2093720271ea 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h @@ -55,11 +55,18 @@ struct extent_map { refcount_t refs; unsigned int compress_type; struct list_head list; + struct list_head free_list; +}; + +enum extent_map_flags { + EXTENT_MAP_TREE_PENDING_FREES, }; struct extent_map_tree { struct rb_root_cached map; + unsigned long flags; struct list_head modified_extents; + struct list_head freed_extents; rwlock_t lock; }; @@ -95,6 +102,9 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre, struct extent_map *alloc_extent_map(void); void free_extent_map(struct extent_map *em); +void free_extent_map_safe(struct extent_map_tree *tree, + struct extent_map *em); +void free_pending_extent_maps(struct extent_map_tree *tree); int __init extent_map_init(void); void __cold extent_map_exit(void); int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen); diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 8b3893c01734..d3803db10939 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4884,7 +4884,7 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, */ if (ret) { clear_em_logging(tree, em); - free_extent_map(em); + free_extent_map_safe(tree, em); continue; } @@ -4893,11 +4893,13 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, ret = log_one_extent(trans, inode, em, path, ctx); write_lock(&tree->lock); clear_em_logging(tree, em); - free_extent_map(em); + free_extent_map_safe(tree, em); } WARN_ON(!list_empty(&extents)); write_unlock(&tree->lock); + free_pending_extent_maps(tree); + if (!ret) ret = btrfs_log_prealloc_extents(trans, inode, path); if (ret) From patchwork Tue Oct 10 20:40:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416069 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 A0A1ACD6115 for ; Tue, 10 Oct 2023 20:41:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234411AbjJJUlW (ORCPT ); Tue, 10 Oct 2023 16:41:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33418 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234475AbjJJUlR (ORCPT ); Tue, 10 Oct 2023 16:41:17 -0400 Received: from mail-yw1-x112c.google.com (mail-yw1-x112c.google.com [IPv6:2607:f8b0:4864:20::112c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7B2ABBA for ; Tue, 10 Oct 2023 13:41:15 -0700 (PDT) Received: by mail-yw1-x112c.google.com with SMTP id 00721157ae682-5a7ab31fb8bso22351497b3.1 for ; Tue, 10 Oct 2023 13:41:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970474; x=1697575274; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+KUH5mNaG/0p3sTE3eYcJAqpZYp281vwXEU6Fc+b6FA=; b=MmEi2Bkd4s74MRjhtIe9mifO0KP1gY1hkG0hopRTxIdzxllbREKwWP2ADJyzrjuf3R +QNyD3SgoQfV5YaLX5Ctfqpo2Id4axgXXKvjV54yKYGnbnsXG791Tz0BWr5kP0W3v3qR 2ZxzdPfy7Z/9cHotxJ02aSbtqIT75LsDEHXM384a5MVWc2SUikdnWjIPIQ/BxSsFmqd/ BQxapjemMKR1RSDyPdJsUa9ozCFDK+fNf+qdLtz07uo1cvHKN2EzTVVpRK1a77EdO8RK WgQuDw02KptqUMuRnp5SdJ6pdMPGQD5qI1LA3sLIMZEvApvdwROFdEoNN6SB8jjgmE2K WJDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970474; x=1697575274; 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=+KUH5mNaG/0p3sTE3eYcJAqpZYp281vwXEU6Fc+b6FA=; b=GrJqCVvoRKfEZVIq2GSt3iWAL901GT55qacAFZevEuiwU3gxX+mx1GHc3JhRV9/ibx iKpSbIwq6pe0f21dJTV3vpJS7ag2tx7Kc+vla4TXeg/FVIFOL19Xvahw9OZG9XNMOT0B sd1rTaKoEVUr8WBLt4qgvrYKr3qTRYQHT9DcMWiwDydnBB8vvwuA0gR263/v5tbYEKM8 ViSTqIdK+JTPCTv/k7fUk2r1Uyq56Fs6SH3C6LZSxxG75sSj8JmDS+YRliNz2L+IJMGE fCp2FAfQqPQ5xqVQxFlZzfWvFcKIKuPN9lkWN9rgFTq7UvpAkawtllPXR57Uso077j24 5PDw== X-Gm-Message-State: AOJu0YxoTIzq6k2OdTbAVlye+5R8uy1KEsquUmAkUSVQDQgRulE5+v16 GGwgyXOTIgjQdVcmzT3VT6I09UfjWX4t37gLKjLWOg== X-Google-Smtp-Source: AGHT+IHC9JiRGUt26OePCahGfMDDSIiFv4sUcCxpJvzEUqoZ3GRPMxdbMObItrQ/CkLQU5uAfJFHGg== X-Received: by 2002:a0d:f003:0:b0:59b:4f2d:231 with SMTP id z3-20020a0df003000000b0059b4f2d0231mr21085500ywe.45.1696970474597; Tue, 10 Oct 2023 13:41:14 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id s67-20020a815e46000000b0059b50f126fbsm4676785ywb.114.2023.10.10.13.41.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:14 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH v2 09/36] btrfs: disable various operations on encrypted inodes Date: Tue, 10 Oct 2023 16:40:24 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Omar Sandoval Initially, only normal data extents will be encrypted. This change forbids various other bits: - allows reflinking only if both inodes have the same encryption status - disable inline data on encrypted inodes Signed-off-by: Omar Sandoval Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/inode.c | 3 ++- fs/btrfs/reflink.c | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index c9317c047587..4806ff34224a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -630,7 +630,8 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size, * compressed) data fits in a leaf and the configured maximum inline * size. */ - if (size < i_size_read(&inode->vfs_inode) || + if (IS_ENCRYPTED(&inode->vfs_inode) || + size < i_size_read(&inode->vfs_inode) || size > fs_info->sectorsize || data_len > BTRFS_MAX_INLINE_DATA_SIZE(fs_info) || data_len > fs_info->max_inline) diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c index fabd856e5079..3c66630d87ee 100644 --- a/fs/btrfs/reflink.c +++ b/fs/btrfs/reflink.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include "ctree.h" #include "fs.h" @@ -809,6 +810,12 @@ static int btrfs_remap_file_range_prep(struct file *file_in, loff_t pos_in, ASSERT(inode_in->i_sb == inode_out->i_sb); } + /* + * Can only reflink encrypted files if both files are encrypted. + */ + if (IS_ENCRYPTED(inode_in) != IS_ENCRYPTED(inode_out)) + return -EINVAL; + /* Don't make the dst file partly checksummed */ if ((BTRFS_I(inode_in)->flags & BTRFS_INODE_NODATASUM) != (BTRFS_I(inode_out)->flags & BTRFS_INODE_NODATASUM)) { From patchwork Tue Oct 10 20:40:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416070 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 B2E80CD68ED for ; Tue, 10 Oct 2023 20:41:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343793AbjJJUlW (ORCPT ); Tue, 10 Oct 2023 16:41:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33448 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234546AbjJJUlS (ORCPT ); Tue, 10 Oct 2023 16:41:18 -0400 Received: from mail-yw1-x1132.google.com (mail-yw1-x1132.google.com [IPv6:2607:f8b0:4864:20::1132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A6FCE94 for ; Tue, 10 Oct 2023 13:41:16 -0700 (PDT) Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-579de633419so74993277b3.3 for ; Tue, 10 Oct 2023 13:41:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970475; x=1697575275; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1X/0Zt7z+oOh2YdMAkIlfw4aC9CST8nDgU19CDUdTeo=; b=teVsTdd4szHuSRdAaNWifrVhPc0k+riHYOoxOIcXixJ1Pi3Td8JeeeCXNo4q9g5WUn v1AKOcL2oFVDu9/8hxxFVtbIRuqpUoQsoNQzTZVcu9ssfciuMfaDx3JEKgLZARSmr6Yt JbmPBz8CAp6q7Op9jn2+UXVkiBZGqNb+b4I3DGV774kVSXdU+/dFkAY6uQDwa1QuU5Z6 8Tx00Zq6u5vUYat5llAyLrRANOrrQqMOn/MKcB8/D+c4uLtoKzunrelxVxiZ4whDSBMz yv6/ro5N+jE7wepdeNgiVWcX3wf6KR+JqX3l7v4ohjZ2tZOML2LpT4GFMErikp88/FOd FeJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970475; x=1697575275; 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=1X/0Zt7z+oOh2YdMAkIlfw4aC9CST8nDgU19CDUdTeo=; b=TM7yABnTeTpz6hx50pCzpbFxuOPHyFwomWoJ3zoyB18NLgT9xUgbkC1bquNN2MJvq+ 84Opv0Mz5EsTxjDvp4IHX2ipGLGJIVjY0E9LYK8UT6s3IDwOCR2ecxPorSdy6OGV4LEu P51NMj4HuwIDYZcUF+OGdng1XzuxeImzJztLVi0uBpLahEJWpbG47jg+76Tl/F8le1JV rmPaJSzDzUP5tG1DLp4RosrIznfAx0Ua4DyrIKmq/Pw2JFuZosDlwwtwMyeqMdgsgcjX KMI8cBEyBqf08SAG8HieNMwDYgmVjejpBMnnB43FUV2DTIjWm5fkT+89i9EkBG1cj/y2 6Iag== X-Gm-Message-State: AOJu0Yz3Wlt/PEowwmnm0V9OZ88FiBGRrff4Kn07iBNSqQ4SW3Xwy26o bVlvcfDmUdaS+kwj+68W2xFsLaRw8uljnde3n7D/SQ== X-Google-Smtp-Source: AGHT+IF2iWI7A9wE0CIU+MsdZuyW9o5G9Md2jSIowPav1/vMVNXMclVs/CcYmtHAA5wT5BpHhVF6Aw== X-Received: by 2002:a0d:d546:0:b0:58f:a19f:2b79 with SMTP id x67-20020a0dd546000000b0058fa19f2b79mr20759539ywd.9.1696970475587; Tue, 10 Oct 2023 13:41:15 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id x132-20020a817c8a000000b005925c896bc3sm4700587ywc.53.2023.10.10.13.41.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:15 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Sweet Tea Dorminy Subject: [PATCH v2 10/36] btrfs: disable verity on encrypted inodes Date: Tue, 10 Oct 2023 16:40:25 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Sweet Tea Dorminy Right now there isn't a way to encrypt things that aren't either filenames in directories or data on blocks on disk with extent encryption, so for now, disable verity usage with encryption on btrfs. Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/verity.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/btrfs/verity.c b/fs/btrfs/verity.c index 66e2270b0dae..92536913df04 100644 --- a/fs/btrfs/verity.c +++ b/fs/btrfs/verity.c @@ -588,6 +588,9 @@ static int btrfs_begin_enable_verity(struct file *filp) ASSERT(inode_is_locked(file_inode(filp))); + if (IS_ENCRYPTED(&inode->vfs_inode)) + return -EINVAL; + if (test_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags)) return -EBUSY; From patchwork Tue Oct 10 20:40:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416072 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 5292ACD690D for ; Tue, 10 Oct 2023 20:41:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234442AbjJJUlY (ORCPT ); Tue, 10 Oct 2023 16:41:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33448 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234488AbjJJUlU (ORCPT ); Tue, 10 Oct 2023 16:41:20 -0400 Received: from mail-yw1-x112f.google.com (mail-yw1-x112f.google.com [IPv6:2607:f8b0:4864:20::112f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7C689CC for ; Tue, 10 Oct 2023 13:41:17 -0700 (PDT) Received: by mail-yw1-x112f.google.com with SMTP id 00721157ae682-5a7ab31fb8bso22351917b3.1 for ; Tue, 10 Oct 2023 13:41:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970476; x=1697575276; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=LWBLB7/SL6mg27umr/DaJRM9A5t8J/exWvm1C6z+lX4=; b=a7dinp+pH4YrPdYCyzd5PGGwvUqHAwtyBOSnEXNj4EZ2zDNIrdQw6vEbiWzfhpuqbU /7723cLzH8dbVWfXaVNJeksc2/t4ESYPY0B6cBjdiovhdeG9uUNsWo9ff4t+Np9V6Oz7 cQzWRsYlMRxu4J+PRdUfT/syiBnjxl04sJAUOOIM5ZBJdvtbQvYnZb6sijfvCqtM9TjS HdOhBEM26o8pAUtidNfEcJOBgCcTBdY7XSL/rzmTRbK2cJvZGUIcIDnaEjQPSfUITbFA yUQ9aeMNconbbrixdngOgiN46Z95SiFlqrwarjIVT6lfmMetpJF8pbWA+3RovGvQ7JMH nSAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970476; x=1697575276; 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=LWBLB7/SL6mg27umr/DaJRM9A5t8J/exWvm1C6z+lX4=; b=OACm+ZODWnN4Bcf6dQNlFCu+/kvlXkpGdOUYMzwXjGOCkQYnPLgDPIZDwM210vwSgm WrRWZ7eee1QvcIgG1iFes/r0aJkgDeiSwpmeyC6a9Ai7YIXlcgPrFLsxapJ8SDGl1kfH UFNgEKA1caIuB7wY6x5WF0v4iGYO+Ghbd0IXWZXNlQ+D5xALVsPHFraM9h68VO9EKxiy qvuaKHgNRWFDbkbn+9vAVbeOc+q7Ef+hIlSMaikKpLpks1pIt1wmKwavp+j0AObuKhil 4r8mR2CWM0WLi4q+JxnPBehZpajyD7MTNzQ6Qe6i0ptNuADiqvjFtC/ISR5s7NMQCEPp Xxdw== X-Gm-Message-State: AOJu0YzBZO7tZOaQEi8+cMu2ZPBKngxawDdEVHEnYbbiaSTx4N6gAlUO pFIS/YX3oOGOyuR2XMJt0FqGfrP2WTaFNHJZavrd0g== X-Google-Smtp-Source: AGHT+IHb3Kr69Mm+5lWsQJAVRtKaeAjxkqvsiFnq7vGez3v5E6/xySKWQHL/Dhl6qEKkXk9mddhKRg== X-Received: by 2002:a81:6dca:0:b0:5a7:ba09:52c7 with SMTP id i193-20020a816dca000000b005a7ba0952c7mr4089896ywc.11.1696970476529; Tue, 10 Oct 2023 13:41:16 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id n75-20020a0dcb4e000000b005a1d51ce1aasm4662902ywd.25.2023.10.10.13.41.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:16 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH v2 11/36] btrfs: start using fscrypt hooks Date: Tue, 10 Oct 2023 16:40:26 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Omar Sandoval In order to appropriately encrypt, create, open, rename, and various symlink operations must call fscrypt hooks. These determine whether the inode should be encrypted and do other preparatory actions. The superblock must have fscrypt operations registered, so implement the minimal set also, and introduce the new fscrypt.[ch] files to hold the fscrypt-specific functionality. Signed-off-by: Omar Sandoval Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/Makefile | 1 + fs/btrfs/btrfs_inode.h | 1 + fs/btrfs/file.c | 3 ++ fs/btrfs/fscrypt.c | 7 +++ fs/btrfs/fscrypt.h | 10 ++++ fs/btrfs/inode.c | 110 ++++++++++++++++++++++++++++++++++------- fs/btrfs/super.c | 2 + 7 files changed, 116 insertions(+), 18 deletions(-) create mode 100644 fs/btrfs/fscrypt.c create mode 100644 fs/btrfs/fscrypt.h diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index 525af975f61c..6e51d054c17a 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile @@ -39,6 +39,7 @@ btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o btrfs-$(CONFIG_BTRFS_FS_REF_VERIFY) += ref-verify.o btrfs-$(CONFIG_BLK_DEV_ZONED) += zoned.o btrfs-$(CONFIG_FS_VERITY) += verity.o +btrfs-$(CONFIG_FS_ENCRYPTION) += fscrypt.o btrfs-$(CONFIG_BTRFS_FS_RUN_SANITY_TESTS) += tests/free-space-tests.o \ tests/extent-buffer-tests.o tests/btrfs-tests.o \ diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index bebb5921b922..052072373078 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -455,6 +455,7 @@ struct btrfs_new_inode_args { struct posix_acl *default_acl; struct posix_acl *acl; struct fscrypt_name fname; + bool encrypt; }; int btrfs_new_inode_prepare(struct btrfs_new_inode_args *args, diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 92419cb8508a..26905b77c7e8 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -3709,6 +3709,9 @@ static int btrfs_file_open(struct inode *inode, struct file *filp) filp->f_mode |= FMODE_NOWAIT | FMODE_BUF_RASYNC | FMODE_BUF_WASYNC | FMODE_CAN_ODIRECT; + ret = fscrypt_file_open(inode, filp); + if (ret) + return ret; ret = fsverity_file_open(inode, filp); if (ret) diff --git a/fs/btrfs/fscrypt.c b/fs/btrfs/fscrypt.c new file mode 100644 index 000000000000..48ab99dfe48d --- /dev/null +++ b/fs/btrfs/fscrypt.c @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "ctree.h" +#include "fscrypt.h" + +const struct fscrypt_operations btrfs_fscrypt_ops = { +}; diff --git a/fs/btrfs/fscrypt.h b/fs/btrfs/fscrypt.h new file mode 100644 index 000000000000..7f4e6888bd43 --- /dev/null +++ b/fs/btrfs/fscrypt.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef BTRFS_FSCRYPT_H +#define BTRFS_FSCRYPT_H + +#include + +extern const struct fscrypt_operations btrfs_fscrypt_ops; + +#endif /* BTRFS_FSCRYPT_H */ diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4806ff34224a..b92da4a4ed21 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5053,6 +5053,10 @@ static int btrfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, if (err) return err; + err = fscrypt_prepare_setattr(dentry, attr); + if (err) + return err; + if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { err = btrfs_setsize(inode, attr); if (err) @@ -5207,11 +5211,8 @@ void btrfs_evict_inode(struct inode *inode) trace_btrfs_inode_evict(inode); - if (!root) { - fsverity_cleanup_inode(inode); - clear_inode(inode); - return; - } + if (!root) + goto cleanup; evict_inode_truncate_pages(inode); @@ -5311,6 +5312,9 @@ void btrfs_evict_inode(struct inode *inode) * to retry these periodically in the future. */ btrfs_remove_delayed_node(BTRFS_I(inode)); + +cleanup: + fscrypt_put_encryption_info(inode); fsverity_cleanup_inode(inode); clear_inode(inode); } @@ -6096,6 +6100,12 @@ int btrfs_new_inode_prepare(struct btrfs_new_inode_args *args, return ret; } + ret = fscrypt_prepare_new_inode(dir, inode, &args->encrypt); + if (ret) { + fscrypt_free_filename(&args->fname); + return ret; + } + /* 1 to add inode item */ *trans_num_items = 1; /* 1 to add compression property */ @@ -6569,9 +6579,13 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, if (inode->i_nlink >= BTRFS_LINK_MAX) return -EMLINK; + err = fscrypt_prepare_link(old_dentry, dir, dentry); + if (err) + return err; + err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &fname); if (err) - goto fail; + return err; err = btrfs_set_inode_index(BTRFS_I(dir), &index); if (err) @@ -8519,6 +8533,7 @@ void btrfs_test_destroy_inode(struct inode *inode) void btrfs_free_inode(struct inode *inode) { + fscrypt_free_inode(inode); kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode)); } @@ -8589,8 +8604,7 @@ int btrfs_drop_inode(struct inode *inode) /* the snap/subvol tree is on deleting */ if (btrfs_root_refs(&root->root_item) == 0) return 1; - else - return generic_drop_inode(inode); + return generic_drop_inode(inode) || fscrypt_drop_inode(inode); } static void init_once(void *foo) @@ -9170,6 +9184,11 @@ static int btrfs_rename2(struct mnt_idmap *idmap, struct inode *old_dir, if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT)) return -EINVAL; + ret = fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry, + flags); + if (ret) + return ret; + if (flags & RENAME_EXCHANGE) ret = btrfs_rename_exchange(old_dir, old_dentry, new_dir, new_dentry); @@ -9384,15 +9403,31 @@ static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir, }; unsigned int trans_num_items; int err; - int name_len; int datasize; unsigned long ptr; struct btrfs_file_extent_item *ei; struct extent_buffer *leaf; + struct fscrypt_str disk_link; + size_t max_len; + u32 name_len = strlen(symname); - name_len = strlen(symname); - if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(fs_info)) - return -ENAMETOOLONG; + /* + * BTRFS_MAX_INLINE_DATA_SIZE() isn't actually telling the truth, we + * actually limit inline data extents to + * min(BTRFS_MAX_INLINE_DATA_SIZE(), sectorsize), so adjust max_len + * given this wonderful bit of inconsistency. + */ + max_len = min_t(size_t, BTRFS_MAX_INLINE_DATA_SIZE(fs_info), + fs_info->sectorsize); + + /* + * fscrypt sets disk_link.len to be len + 1, including a NUL terminator, but we + * don't store that '\0' character. + */ + err = fscrypt_prepare_symlink(dir, symname, name_len, max_len + 1, + &disk_link); + if (err) + return err; inode = new_inode(dir->i_sb); if (!inode) @@ -9401,8 +9436,8 @@ static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir, inode->i_op = &btrfs_symlink_inode_operations; inode_nohighmem(inode); inode->i_mapping->a_ops = &btrfs_aops; - btrfs_i_size_write(BTRFS_I(inode), name_len); - inode_set_bytes(inode, name_len); + btrfs_i_size_write(BTRFS_I(inode), disk_link.len - 1); + inode_set_bytes(inode, disk_link.len - 1); new_inode_args.inode = inode; err = btrfs_new_inode_prepare(&new_inode_args, &trans_num_items); @@ -9429,10 +9464,23 @@ static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir, inode = NULL; goto out; } + + if (IS_ENCRYPTED(inode)) { + err = fscrypt_encrypt_symlink(inode, symname, name_len, + &disk_link); + if (err) { + btrfs_abort_transaction(trans, err); + btrfs_free_path(path); + discard_new_inode(inode); + inode = NULL; + goto out; + } + } + key.objectid = btrfs_ino(BTRFS_I(inode)); key.offset = 0; key.type = BTRFS_EXTENT_DATA_KEY; - datasize = btrfs_file_extent_calc_inline_size(name_len); + datasize = btrfs_file_extent_calc_inline_size(disk_link.len - 1); err = btrfs_insert_empty_item(trans, root, path, &key, datasize); if (err) { @@ -9451,10 +9499,10 @@ static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir, btrfs_set_file_extent_encryption(leaf, ei, 0); btrfs_set_file_extent_compression(leaf, ei, 0); btrfs_set_file_extent_other_encoding(leaf, ei, 0); - btrfs_set_file_extent_ram_bytes(leaf, ei, name_len); + btrfs_set_file_extent_ram_bytes(leaf, ei, disk_link.len - 1); ptr = btrfs_file_extent_inline_start(ei); - write_extent_buffer(leaf, symname, ptr, name_len); + write_extent_buffer(leaf, disk_link.name, ptr, disk_link.len - 1); btrfs_mark_buffer_dirty(trans, leaf); btrfs_free_path(path); @@ -9471,6 +9519,29 @@ static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir, return err; } +static const char *btrfs_get_link(struct dentry *dentry, struct inode *inode, + struct delayed_call *done) +{ + struct page *cpage; + const char *paddr; + struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + + if (!IS_ENCRYPTED(inode)) + return page_get_link(dentry, inode, done); + + if (!dentry) + return ERR_PTR(-ECHILD); + + cpage = read_mapping_page(inode->i_mapping, 0, NULL); + if (IS_ERR(cpage)) + return ERR_CAST(cpage); + + paddr = fscrypt_get_symlink(inode, page_address(cpage), + BTRFS_MAX_INLINE_DATA_SIZE(fs_info), done); + put_page(cpage); + return paddr; +} + static struct btrfs_trans_handle *insert_prealloc_file_extent( struct btrfs_trans_handle *trans_in, struct btrfs_inode *inode, @@ -10949,7 +11020,7 @@ static const struct inode_operations btrfs_special_inode_operations = { .update_time = btrfs_update_time, }; static const struct inode_operations btrfs_symlink_inode_operations = { - .get_link = page_get_link, + .get_link = btrfs_get_link, .getattr = btrfs_getattr, .setattr = btrfs_setattr, .permission = btrfs_permission, @@ -10959,4 +11030,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { const struct dentry_operations btrfs_dentry_operations = { .d_delete = btrfs_dentry_delete, +#ifdef CONFIG_FS_ENCRYPTION + .d_revalidate = fscrypt_d_revalidate, +#endif }; diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 08761a5c9cc3..0d88f871ba09 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -49,6 +49,7 @@ #include "tests/btrfs-tests.h" #include "block-group.h" #include "discard.h" +#include "fscrypt.h" #include "qgroup.h" #include "raid56.h" #include "fs.h" @@ -1103,6 +1104,7 @@ static int btrfs_fill_super(struct super_block *sb, sb->s_vop = &btrfs_verityops; #endif sb->s_xattr = btrfs_xattr_handlers; + fscrypt_set_ops(sb, &btrfs_fscrypt_ops); sb->s_time_gran = 1; #ifdef CONFIG_BTRFS_FS_POSIX_ACL sb->s_flags |= SB_POSIXACL; From patchwork Tue Oct 10 20:40:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416073 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 1F0FBCD8CBE for ; Tue, 10 Oct 2023 20:41:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234630AbjJJUl1 (ORCPT ); Tue, 10 Oct 2023 16:41:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33448 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343768AbjJJUlV (ORCPT ); Tue, 10 Oct 2023 16:41:21 -0400 Received: from mail-yb1-xb2f.google.com (mail-yb1-xb2f.google.com [IPv6:2607:f8b0:4864:20::b2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BAC34AF for ; Tue, 10 Oct 2023 13:41:18 -0700 (PDT) Received: by mail-yb1-xb2f.google.com with SMTP id 3f1490d57ef6-d84d883c1b6so246268276.0 for ; Tue, 10 Oct 2023 13:41:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970477; x=1697575277; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SUVuCMhgLp9ZG1FCOJMjkYEGr1CrEBEZ7HiAZ8GmnT4=; b=KOSpINjMt8VtZYzpKiKfwt2ZYFAxOpe2jWSPot3ynzn3VKCHNOdTNveu7IfuAMnqC1 fKkwYouMMiD8boMBgn5we3LJrx22z79ZigVW1GTS5s8+eczO6CnM04kNupE+FfekyVvL LNd8AVpdYSx6ssBpi4quBX8VU9uoNrCa/MFyo+ak+eRjGlGaMgu+VdSWR5iLmfT8F2LH AxOBIsejY1lCRWYWrXmiTb6q+j0LNDEgyf+R0lRgdV/yoTRwEMQj6SaR0+XSoXbDLvFE 5ulDWOWRg97uAPtXPbRpNqqORF5UqbrF+Cr6BoKDAeBdtjJTTsGk5HECLKde40Zgmr0x cdCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970477; x=1697575277; 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=SUVuCMhgLp9ZG1FCOJMjkYEGr1CrEBEZ7HiAZ8GmnT4=; b=MjJI2VshSx2msiNNr4b9gOUdyIUtqjg0nmuHGLvcjKVGwysGJBiPZv2GPE8BET7JNU hK8CrIBd8qxEAH3O5pnhPxvtLNPjaNSbC1VB5INFNeccE5NZ0hzLW1Eu5ShleS9ykhRG wUGb+UMGOyYuGQ7i+hPERyPrFI3gY+iu5rHQYNpp1gdyzOg+ta0TEHAwGY+FvWcqEO2Z fD+rclBH6xOLCiDKtRQ4UAVnUPAa1rbC0v2I6D2VGrjRvEl19J4V0U7zMeF6rRtyisYh MlbwIInuTrp8RFGm8ApBosalPo8wzJv9EAft5VjbaUtcaF/T8QpvnMr47NMqCvuPMO/k uvKQ== X-Gm-Message-State: AOJu0YwSEgoK9OlvTYm4vYRKYQ6OZPyEPFVw3oNKe/P+FFFvLSMSdJih yF/+ynjEooycqb+7C9Ui4l4P+LtmzMiLnOngWa83dQ== X-Google-Smtp-Source: AGHT+IE89btaHf6z2ZMQE2ILWZRDm5s3O/k1UVn5Kq4F0TibN8tlNSZJsKyYxZR2oLNbBY9fO+GTjw== X-Received: by 2002:a25:8503:0:b0:d9a:4cc0:a90c with SMTP id w3-20020a258503000000b00d9a4cc0a90cmr2718555ybk.15.1696970477649; Tue, 10 Oct 2023 13:41:17 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id c201-20020a25c0d2000000b00d9a4aad7f40sm881827ybf.24.2023.10.10.13.41.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:17 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH v2 12/36] btrfs: add inode encryption contexts Date: Tue, 10 Oct 2023 16:40:27 -0400 Message-ID: <2aa2bc594a95829503338d7345c41bae2030bfd3.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Omar Sandoval In order to store encryption information for directories, symlinks, etc., fscrypt stores a context item with each encrypted non-regular inode. fscrypt provides an arbitrary blob for the filesystem to store, and it does not clearly fit into an existing structure, so this goes in a new item type. Signed-off-by: Omar Sandoval Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/fscrypt.c | 117 ++++++++++++++++++++++++++++++++ fs/btrfs/fscrypt.h | 2 + fs/btrfs/inode.c | 19 ++++++ fs/btrfs/ioctl.c | 8 ++- include/uapi/linux/btrfs_tree.h | 10 +++ 5 files changed, 154 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/fscrypt.c b/fs/btrfs/fscrypt.c index 48ab99dfe48d..0e4011d6b1cd 100644 --- a/fs/btrfs/fscrypt.c +++ b/fs/btrfs/fscrypt.c @@ -1,7 +1,124 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include "ctree.h" +#include "accessors.h" +#include "btrfs_inode.h" +#include "disk-io.h" +#include "fs.h" #include "fscrypt.h" +#include "ioctl.h" +#include "messages.h" +#include "transaction.h" +#include "xattr.h" + +static int btrfs_fscrypt_get_context(struct inode *inode, void *ctx, size_t len) +{ + struct btrfs_key key = { + .objectid = btrfs_ino(BTRFS_I(inode)), + .type = BTRFS_FSCRYPT_CTX_ITEM_KEY, + .offset = 0, + }; + struct btrfs_path *path; + struct extent_buffer *leaf; + unsigned long ptr; + int ret; + + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + ret = btrfs_search_slot(NULL, BTRFS_I(inode)->root, &key, path, 0, 0); + if (ret) { + len = -ENOENT; + goto out; + } + + leaf = path->nodes[0]; + ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); + /* fscrypt provides max context length, but it could be less */ + len = min_t(size_t, len, btrfs_item_size(leaf, path->slots[0])); + read_extent_buffer(leaf, ctx, ptr, len); + +out: + btrfs_free_path(path); + return len; +} + +static int btrfs_fscrypt_set_context(struct inode *inode, const void *ctx, + size_t len, void *fs_data) +{ + struct btrfs_trans_handle *trans = fs_data; + struct btrfs_key key = { + .objectid = btrfs_ino(BTRFS_I(inode)), + .type = BTRFS_FSCRYPT_CTX_ITEM_KEY, + .offset = 0, + }; + struct btrfs_path *path = NULL; + struct extent_buffer *leaf; + unsigned long ptr; + int ret; + + if (!trans) + trans = btrfs_start_transaction(BTRFS_I(inode)->root, 2); + if (IS_ERR(trans)) + return PTR_ERR(trans); + + path = btrfs_alloc_path(); + if (!path) { + ret = -ENOMEM; + goto out_err; + } + + ret = btrfs_search_slot(trans, BTRFS_I(inode)->root, &key, path, 0, 1); + if (ret < 0) + goto out_err; + + if (ret > 0) { + btrfs_release_path(path); + ret = btrfs_insert_empty_item(trans, BTRFS_I(inode)->root, path, &key, len); + if (ret) + goto out_err; + } + + leaf = path->nodes[0]; + ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); + + len = min_t(size_t, len, btrfs_item_size(leaf, path->slots[0])); + write_extent_buffer(leaf, ctx, ptr, len); + btrfs_mark_buffer_dirty(trans, leaf); + btrfs_release_path(path); + + if (fs_data) + return ret; + + BTRFS_I(inode)->flags |= BTRFS_INODE_ENCRYPT; + btrfs_sync_inode_flags_to_i_flags(inode); + inode_inc_iversion(inode); + inode_set_ctime_current(inode); + ret = btrfs_update_inode(trans, BTRFS_I(inode)); + if (ret) + goto out_abort; + btrfs_free_path(path); + btrfs_end_transaction(trans); + return 0; +out_abort: + btrfs_abort_transaction(trans, ret); +out_err: + if (!fs_data) + btrfs_end_transaction(trans); + btrfs_free_path(path); + return ret; +} + +static bool btrfs_fscrypt_empty_dir(struct inode *inode) +{ + return inode->i_size == BTRFS_EMPTY_DIR_SIZE; +} const struct fscrypt_operations btrfs_fscrypt_ops = { + .get_context = btrfs_fscrypt_get_context, + .set_context = btrfs_fscrypt_set_context, + .empty_dir = btrfs_fscrypt_empty_dir, }; diff --git a/fs/btrfs/fscrypt.h b/fs/btrfs/fscrypt.h index 7f4e6888bd43..80adb7e56826 100644 --- a/fs/btrfs/fscrypt.h +++ b/fs/btrfs/fscrypt.h @@ -5,6 +5,8 @@ #include +#include "fs.h" + extern const struct fscrypt_operations btrfs_fscrypt_ops; #endif /* BTRFS_FSCRYPT_H */ diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b92da4a4ed21..a316128b3069 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -62,6 +62,7 @@ #include "defrag.h" #include "dir-item.h" #include "file-item.h" +#include "fscrypt.h" #include "uuid-tree.h" #include "ioctl.h" #include "file.h" @@ -6087,6 +6088,9 @@ int btrfs_new_inode_prepare(struct btrfs_new_inode_args *args, struct inode *inode = args->inode; int ret; + if (fscrypt_is_nokey_name(args->dentry)) + return -ENOKEY; + if (!args->orphan) { ret = fscrypt_setup_filename(dir, &args->dentry->d_name, 0, &args->fname); @@ -6122,6 +6126,9 @@ int btrfs_new_inode_prepare(struct btrfs_new_inode_args *args, if (dir->i_security) (*trans_num_items)++; #endif + /* 1 to add fscrypt item */ + if (args->encrypt) + (*trans_num_items)++; if (args->orphan) { /* 1 to add orphan item */ (*trans_num_items)++; @@ -6299,6 +6306,11 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, inode->i_atime = inode->i_mtime; BTRFS_I(inode)->i_otime = inode->i_mtime; + if (args->encrypt) { + BTRFS_I(inode)->flags |= BTRFS_INODE_ENCRYPT; + btrfs_sync_inode_flags_to_i_flags(inode); + } + /* * We're going to fill the inode item now, so at this point the inode * must be fully initialized. @@ -6373,6 +6385,13 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, goto discard; } } + if (args->encrypt) { + ret = fscrypt_set_context(inode, trans); + if (ret) { + btrfs_abort_transaction(trans, ret); + goto discard; + } + } inode_tree_add(BTRFS_I(inode)); diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 89cd212735ea..1f1506280619 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -156,6 +156,8 @@ static unsigned int btrfs_inode_flags_to_fsflags(struct btrfs_inode *binode) iflags |= FS_DIRSYNC_FL; if (flags & BTRFS_INODE_NODATACOW) iflags |= FS_NOCOW_FL; + if (flags & BTRFS_INODE_ENCRYPT) + iflags |= FS_ENCRYPT_FL; if (ro_flags & BTRFS_INODE_RO_VERITY) iflags |= FS_VERITY_FL; @@ -185,12 +187,14 @@ void btrfs_sync_inode_flags_to_i_flags(struct inode *inode) new_fl |= S_NOATIME; if (binode->flags & BTRFS_INODE_DIRSYNC) new_fl |= S_DIRSYNC; + if (binode->flags & BTRFS_INODE_ENCRYPT) + new_fl |= S_ENCRYPTED; if (binode->ro_flags & BTRFS_INODE_RO_VERITY) new_fl |= S_VERITY; set_mask_bits(&inode->i_flags, S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC | - S_VERITY, new_fl); + S_VERITY | S_ENCRYPTED, new_fl); } /* @@ -203,7 +207,7 @@ static int check_fsflags(unsigned int old_flags, unsigned int flags) FS_NOATIME_FL | FS_NODUMP_FL | \ FS_SYNC_FL | FS_DIRSYNC_FL | \ FS_NOCOMP_FL | FS_COMPR_FL | - FS_NOCOW_FL)) + FS_NOCOW_FL | FS_ENCRYPT_FL)) return -EOPNOTSUPP; /* COMPR and NOCOMP on new/old are valid */ diff --git a/include/uapi/linux/btrfs_tree.h b/include/uapi/linux/btrfs_tree.h index c25fc9614594..ef796a3cf387 100644 --- a/include/uapi/linux/btrfs_tree.h +++ b/include/uapi/linux/btrfs_tree.h @@ -164,6 +164,8 @@ #define BTRFS_VERITY_DESC_ITEM_KEY 36 #define BTRFS_VERITY_MERKLE_ITEM_KEY 37 +#define BTRFS_FSCRYPT_CTX_ITEM_KEY 41 + #define BTRFS_ORPHAN_ITEM_KEY 48 /* reserve 2-15 close to the inode for later flexibility */ @@ -416,6 +418,7 @@ static inline __u8 btrfs_dir_flags_to_ftype(__u8 flags) #define BTRFS_INODE_NOATIME (1U << 9) #define BTRFS_INODE_DIRSYNC (1U << 10) #define BTRFS_INODE_COMPRESS (1U << 11) +#define BTRFS_INODE_ENCRYPT (1U << 12) #define BTRFS_INODE_ROOT_ITEM_INIT (1U << 31) @@ -432,6 +435,7 @@ static inline __u8 btrfs_dir_flags_to_ftype(__u8 flags) BTRFS_INODE_NOATIME | \ BTRFS_INODE_DIRSYNC | \ BTRFS_INODE_COMPRESS | \ + BTRFS_INODE_ENCRYPT | \ BTRFS_INODE_ROOT_ITEM_INIT) #define BTRFS_INODE_RO_VERITY (1U << 0) @@ -1061,6 +1065,12 @@ enum { BTRFS_NR_FILE_EXTENT_TYPES = 3, }; +enum { + BTRFS_ENCRYPTION_NONE, + BTRFS_ENCRYPTION_FSCRYPT, + BTRFS_NR_ENCRYPTION_TYPES, +}; + struct btrfs_file_extent_item { /* * transaction id that created this extent From patchwork Tue Oct 10 20:40:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416071 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 2CFB7CD6119 for ; Tue, 10 Oct 2023 20:41:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343770AbjJJUlZ (ORCPT ); Tue, 10 Oct 2023 16:41:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33442 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343780AbjJJUlW (ORCPT ); Tue, 10 Oct 2023 16:41:22 -0400 Received: from mail-yw1-x112e.google.com (mail-yw1-x112e.google.com [IPv6:2607:f8b0:4864:20::112e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC6CCDA for ; Tue, 10 Oct 2023 13:41:19 -0700 (PDT) Received: by mail-yw1-x112e.google.com with SMTP id 00721157ae682-59f6441215dso75757347b3.2 for ; Tue, 10 Oct 2023 13:41:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970479; x=1697575279; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SlmN2ch9baX8IZyM28LiaPpdp2pXGpixSS5OJltBALc=; b=k9nLHT4L6iPjqh8Y1F0CQkvJ/Hsyq1hyFka1onCldQI9p0C4SjJyVAxdnkzWmHFsp6 3a5CTFRsiaOwPEbgExXxZYX+cHDMPXnzxNRBeiPOC+L5IjbeYAgR5PLlTusssZiOlGdp kGJMP7BermmqSasw/6Epk3RuwYC9g0j3scpAT49bgLzrvsN4ln6MvrKy5Yz1e2vfnaKz RL2OAScX0gW65eGJ1QOQhGm8hUSpnTUuzIii0y68DccD0WONFZ8hwXWo8Wgx3tMIILzq HiTslKw9xUps4nZVsC3G5E4r6xuqL5cOWVDiQzv1JNAP1rVRBabw3q4YYWQn9T1wFPil sxig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970479; x=1697575279; 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=SlmN2ch9baX8IZyM28LiaPpdp2pXGpixSS5OJltBALc=; b=IKdNJUMmzyjCQ6Ektce9h9QTJeAMTotMNrIXKtERVQ77NrGYHS8k9smQDigNWEzpkX 9U4jcN1GPH5Dve5hovWDYRDZAIhj+YLydkIPMFq3GeW3AZWpGW4SIR6WDja3yP93GQZ/ 2LSqC+MIJSC1vEfNU644j3elIHOh5z2Qew+Gis+t6k9I0ohQV3/PjxRVc6JodSocc45N fCekmRcXYZEnNQN8zcowaufk3tM5sSd0F4yN/RZrEBCjZHZes4tFOabDNTD3fVrQQzOZ H1+ueMBRMTiXim3aTTLw+02APJpuAIGLWxpDTqRVAfD4juV6PEFu8t2n0oluHxS53YoG HyjA== X-Gm-Message-State: AOJu0YxQmT7F4Rk30WRLlpOefm6wwxVoQRx+FV4YEROR5/4UwmifT3TF zOAiwO/2bg2Clw60kMXiyeXOZ73MgHzSBFIsukh0DQ== X-Google-Smtp-Source: AGHT+IHAa6+/r7bIvaeYU3BVjfbRQwVyiROgPjJ+6sqmGPSFggul8YnsYIEAc0rrxKA8oF3Ppi4C0g== X-Received: by 2002:a81:7103:0:b0:59b:586c:c65e with SMTP id m3-20020a817103000000b0059b586cc65emr23052765ywc.36.1696970478797; Tue, 10 Oct 2023 13:41:18 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id p6-20020a0dff06000000b0059c8387f673sm4698455ywf.51.2023.10.10.13.41.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:18 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH v2 13/36] btrfs: add new FEATURE_INCOMPAT_ENCRYPT flag Date: Tue, 10 Oct 2023 16:40:28 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Omar Sandoval As encrypted files will be incompatible with older filesystem versions, new filesystems should be created with an incompat flag for fscrypt, which will gate access to the encryption ioctls. Signed-off-by: Omar Sandoval Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/fs.h | 3 ++- fs/btrfs/super.c | 5 +++++ fs/btrfs/sysfs.c | 6 ++++++ include/uapi/linux/btrfs.h | 1 + 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h index 318df6f9d9cb..4a3b1bb61849 100644 --- a/fs/btrfs/fs.h +++ b/fs/btrfs/fs.h @@ -231,7 +231,8 @@ enum { #define BTRFS_FEATURE_INCOMPAT_SUPP \ (BTRFS_FEATURE_INCOMPAT_SUPP_STABLE | \ BTRFS_FEATURE_INCOMPAT_RAID_STRIPE_TREE | \ - BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2) + BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2 | \ + BTRFS_FEATURE_INCOMPAT_ENCRYPT) #else diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 0d88f871ba09..bacf5c4f2a5c 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -2383,6 +2383,11 @@ static int __init btrfs_print_mod_info(void) ", fsverity=yes" #else ", fsverity=no" +#endif +#ifdef CONFIG_FS_ENCRYPTION + ", fscrypt=yes" +#else + ", fscrypt=no" #endif ; pr_info("Btrfs loaded%s\n", options); diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index e6b51fb3ddc1..4ece703d9d5f 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -304,6 +304,9 @@ BTRFS_FEAT_ATTR_INCOMPAT(raid_stripe_tree, RAID_STRIPE_TREE); #ifdef CONFIG_FS_VERITY BTRFS_FEAT_ATTR_COMPAT_RO(verity, VERITY); #endif +#ifdef CONFIG_FS_ENCRYPTION +BTRFS_FEAT_ATTR_INCOMPAT(encryption, ENCRYPT); +#endif /* CONFIG_FS_ENCRYPTION */ /* * Features which depend on feature bits and may differ between each fs. @@ -336,6 +339,9 @@ static struct attribute *btrfs_supported_feature_attrs[] = { #ifdef CONFIG_FS_VERITY BTRFS_FEAT_ATTR_PTR(verity), #endif +#ifdef CONFIG_FS_ENCRYPTION + BTRFS_FEAT_ATTR_PTR(encryption), +#endif /* CONFIG_FS_ENCRYPTION */ NULL }; diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index 7c29d82db9ee..6a0f4c0e4096 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -334,6 +334,7 @@ struct btrfs_ioctl_fs_info_args { #define BTRFS_FEATURE_INCOMPAT_ZONED (1ULL << 12) #define BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2 (1ULL << 13) #define BTRFS_FEATURE_INCOMPAT_RAID_STRIPE_TREE (1ULL << 14) +#define BTRFS_FEATURE_INCOMPAT_ENCRYPT (1ULL << 15) #define BTRFS_FEATURE_INCOMPAT_SIMPLE_QUOTA (1ULL << 16) struct btrfs_ioctl_feature_flags { From patchwork Tue Oct 10 20:40:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416081 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 33886CD8CBF for ; Tue, 10 Oct 2023 20:41:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234733AbjJJUlk (ORCPT ); Tue, 10 Oct 2023 16:41:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343904AbjJJUl1 (ORCPT ); Tue, 10 Oct 2023 16:41:27 -0400 Received: from mail-yw1-x1130.google.com (mail-yw1-x1130.google.com [IPv6:2607:f8b0:4864:20::1130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 762ACDE for ; Tue, 10 Oct 2023 13:41:21 -0700 (PDT) Received: by mail-yw1-x1130.google.com with SMTP id 00721157ae682-5a7af45084eso22083637b3.0 for ; Tue, 10 Oct 2023 13:41:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970480; x=1697575280; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=k1H0ZoXH6Hs9lCRcgtceOUWp+6nVz4CvIT45bBq5+EY=; b=VG0wkzql0LY9Yb1VUGmtfNN7pPNsoWhLQmew30R8qUgn3IYuCD1qH2n1cqRQKXeTjv 0e7lqNEgMVYyjOZbz9n8yrY0UgLH2YM+I1gvxbYMKKHmla7VEPg2iHXq4CzNJ/N79cV1 H4dXNWySjx+IdGigZ1Kot7G8Sb+Y+vvfNK4MUC2SREO6BidAhKRb/nZx3tJSy1KaM8QL rpFWOqzQ36sQvP/UOvtN0vdjzykATLoS8FAcJBLcIvOQe+Ttsg1xqQ7I7Jr+u1nXPFro Zd13FmWkZkqZAkCK+7NRRsiBl/eOrFQ/sL/m/rtJMwrPNNm/Bxi+x7/WqVgZrlVXRjMX z3AQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970480; x=1697575280; 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=k1H0ZoXH6Hs9lCRcgtceOUWp+6nVz4CvIT45bBq5+EY=; b=nvNGNGHmgYSULMvqUXiTsQk7TrcE5tggN3KgZUgaz2x/jI8LR214XgS+go9wccIy9U h3vRlm0QiMexq8e0a8ee1Ex3yUUfDcm4Zt7c8rXzp8acqlM+Fingc6YAfbZE1OiYfilf JUc4o8G6uC/HXK1Ft9w6aI9jH2x3baGvFc4grB3FHR/KgxRKlOuNtpYyJ5MroioslBON yHShNy7Ei2LJa6Ha3r57P5FRGgKxGvCGHofJqgPvsnj7TaMkiu2FFBIB44bkxB5zXhf9 WaoTnSyUNXBY5GHaf5rjeiTuQzIVXC2Pv7NRpZi4PTfv/+bkiUbbKzozNtH77L2OYvI5 Tt1w== X-Gm-Message-State: AOJu0YwOhcCjwethvc6Mo4mhAlKtlpk61B/4sOQj8NTW5f+jFoB28S9d Qd53QFXPuH61JjGMLm91ZX4s8Dfu2+L9JLwiX82XNg== X-Google-Smtp-Source: AGHT+IEnb0Ct3gbhOwMHSDEn9MaCo5EVQbuQIAToimDJi7ArVs6tZUAfltehB/BvVi0bI4YCWdS49g== X-Received: by 2002:a0d:dfd7:0:b0:5a7:d938:c5e2 with SMTP id i206-20020a0ddfd7000000b005a7d938c5e2mr882555ywe.14.1696970480006; Tue, 10 Oct 2023 13:41:20 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id ex5-20020a05690c2fc500b005a7a4e3816esm1213707ywb.89.2023.10.10.13.41.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:19 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH v2 14/36] btrfs: adapt readdir for encrypted and nokey names Date: Tue, 10 Oct 2023 16:40:29 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Omar Sandoval Deleting an encrypted file must always be permitted, even if the user does not have the appropriate key. Therefore, for listing an encrypted directory, so-called 'nokey' names are provided, and these nokey names must be sufficient to look up and delete the appropriate encrypted files. See 'struct fscrypt_nokey_name' for more information on the format of these names. The first part of supporting nokey names is allowing lookups by nokey name. Only a few entry points need to support these: deleting a directory, file, or subvolume -- each of these call fscrypt_setup_filename() with a '1' argument, indicating that the key is not required and therefore a nokey name may be provided. If a nokey name is provided, the fscrypt_name returned by fscrypt_setup_filename() will not have its disk_name field populated, but will have various other fields set. This change alters the relevant codepaths to pass a complete fscrypt_name anywhere that it might contain a nokey name. When it does contain a nokey name, the first time the name is successfully matched to a stored name populates the disk name field of the fscrypt_name, allowing the caller to use the normal disk name codepaths afterward. Otherwise, the matching functionality is in close analogue to the function fscrypt_match_name(). Functions where most callers are providing a fscrypt_str are duplicated and adapted for a fscrypt_name, and functions where most callers are providing a fscrypt_name are changed to so require at all callsites. Signed-off-by: Omar Sandoval Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/btrfs_inode.h | 2 +- fs/btrfs/delayed-inode.c | 29 ++++++- fs/btrfs/delayed-inode.h | 6 +- fs/btrfs/dir-item.c | 77 ++++++++++++++++--- fs/btrfs/dir-item.h | 11 ++- fs/btrfs/extent_io.c | 18 +++++ fs/btrfs/extent_io.h | 3 + fs/btrfs/fscrypt.c | 34 +++++++++ fs/btrfs/fscrypt.h | 19 +++++ fs/btrfs/inode.c | 158 ++++++++++++++++++++++++++------------- fs/btrfs/root-tree.c | 8 +- fs/btrfs/root-tree.h | 2 +- fs/btrfs/tree-log.c | 3 +- 13 files changed, 297 insertions(+), 73 deletions(-) diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 052072373078..f6ffebeb2c8d 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -428,7 +428,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry); int btrfs_set_inode_index(struct btrfs_inode *dir, u64 *index); int btrfs_unlink_inode(struct btrfs_trans_handle *trans, struct btrfs_inode *dir, struct btrfs_inode *inode, - const struct fscrypt_str *name); + struct fscrypt_name *name); int btrfs_add_link(struct btrfs_trans_handle *trans, struct btrfs_inode *parent_inode, struct btrfs_inode *inode, const struct fscrypt_str *name, int add_backref, u64 index); diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 35d7616615c1..43b5fb3fce27 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c @@ -1762,7 +1762,9 @@ int btrfs_should_delete_dir_index(struct list_head *del_list, /* * Read dir info stored in the delayed tree. */ -int btrfs_readdir_delayed_dir_index(struct dir_context *ctx, +int btrfs_readdir_delayed_dir_index(struct inode *inode, + struct fscrypt_str *fstr, + struct dir_context *ctx, struct list_head *ins_list) { struct btrfs_dir_item *di; @@ -1772,6 +1774,7 @@ int btrfs_readdir_delayed_dir_index(struct dir_context *ctx, int name_len; int over = 0; unsigned char d_type; + size_t fstr_len = fstr->len; /* * Changing the data of the delayed item is impossible. So @@ -1796,8 +1799,28 @@ int btrfs_readdir_delayed_dir_index(struct dir_context *ctx, d_type = fs_ftype_to_dtype(btrfs_dir_flags_to_ftype(di->type)); btrfs_disk_key_to_cpu(&location, &di->location); - over = !dir_emit(ctx, name, name_len, - location.objectid, d_type); + if (di->type & BTRFS_FT_ENCRYPTED) { + int ret; + struct fscrypt_str iname = FSTR_INIT(name, name_len); + + fstr->len = fstr_len; + /* + * The hash is only used when the encryption key is not + * available. But if we have delayed insertions, then we + * must have the encryption key available or we wouldn't + * have been able to create entries in the directory. + * So, we don't calculate the hash. + */ + ret = fscrypt_fname_disk_to_usr(inode, 0, 0, &iname, + fstr); + if (ret) + return ret; + over = !dir_emit(ctx, fstr->name, fstr->len, + location.objectid, d_type); + } else { + over = !dir_emit(ctx, name, name_len, location.objectid, + d_type); + } if (refcount_dec_and_test(&curr->refs)) kfree(curr); diff --git a/fs/btrfs/delayed-inode.h b/fs/btrfs/delayed-inode.h index d050e572c7f9..6fe2c7607c8b 100644 --- a/fs/btrfs/delayed-inode.h +++ b/fs/btrfs/delayed-inode.h @@ -16,6 +16,8 @@ #include #include "ctree.h" +struct fscrypt_str; + enum btrfs_delayed_item_type { BTRFS_DELAYED_INSERTION_ITEM, BTRFS_DELAYED_DELETION_ITEM @@ -155,7 +157,9 @@ void btrfs_readdir_put_delayed_items(struct inode *inode, struct list_head *del_list); int btrfs_should_delete_dir_index(struct list_head *del_list, u64 index); -int btrfs_readdir_delayed_dir_index(struct dir_context *ctx, +int btrfs_readdir_delayed_dir_index(struct inode *inode, + struct fscrypt_str *fstr, + struct dir_context *ctx, struct list_head *ins_list); /* Used during directory logging. */ diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index 9c07d5c3e5ad..a64cfddff7f0 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c @@ -6,6 +6,7 @@ #include "messages.h" #include "ctree.h" #include "disk-io.h" +#include "fscrypt.h" #include "transaction.h" #include "accessors.h" #include "dir-item.h" @@ -230,6 +231,47 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, return di; } +/* + * Lookup for a directory item by fscrypt_name. + * + * @trans: The transaction handle to use. + * @root: The root of the target tree. + * @path: Path to use for the search. + * @dir: The inode number (objectid) of the directory. + * @name: The fscrypt_name associated to the directory entry + * @mod: Used to indicate if the tree search is meant for a read only + * lookup or for a deletion lookup, so its value should be 0 or + * -1, respectively. + * + * Returns: NULL if the dir item does not exists, an error pointer if an error + * happened, or a pointer to a dir item if a dir item exists for the given name. + */ +struct btrfs_dir_item *btrfs_lookup_dir_item_fname(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, u64 dir, + struct fscrypt_name *name, int mod) +{ + struct btrfs_key key; + struct btrfs_dir_item *di = NULL; + int ret = 0; + + key.objectid = dir; + key.type = BTRFS_DIR_ITEM_KEY; + key.offset = btrfs_name_hash(name->disk_name.name, name->disk_name.len); + /* XXX get the right hash for no-key names */ + + ret = btrfs_search_slot(trans, root, &key, path, mod, -mod); + if (ret == 0) + di = btrfs_match_dir_item_fname(root->fs_info, path, name); + + if (ret == -ENOENT || (di && IS_ERR(di) && PTR_ERR(di) == -ENOENT)) + return NULL; + if (ret < 0) + di = ERR_PTR(ret); + + return di; +} + int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir, const struct fscrypt_str *name) { @@ -287,9 +329,9 @@ int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir, } /* - * Lookup for a directory index item by name and index number. + * Lookup for a directory index item by fscrypt_name and index number. * - * @trans: The transaction handle to use. Can be NULL if @mod is 0. + * @trans: The transaction handle to use. * @root: The root of the target tree. * @path: Path to use for the search. * @dir: The inode number (objectid) of the directory. @@ -327,7 +369,7 @@ btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans, struct btrfs_dir_item * btrfs_search_dir_index_item(struct btrfs_root *root, struct btrfs_path *path, - u64 dirid, const struct fscrypt_str *name) + u64 dirid, struct fscrypt_name *name) { struct btrfs_dir_item *di; struct btrfs_key key; @@ -340,9 +382,7 @@ btrfs_search_dir_index_item(struct btrfs_root *root, struct btrfs_path *path, btrfs_for_each_slot(root, &key, &key, path, ret) { if (key.objectid != dirid || key.type != BTRFS_DIR_INDEX_KEY) break; - - di = btrfs_match_dir_item_name(root->fs_info, path, - name->name, name->len); + di = btrfs_match_dir_item_fname(root->fs_info, path, name); if (di) return di; } @@ -378,9 +418,9 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, * this walks through all the entries in a dir item and finds one * for a specific name. */ -struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_fs_info *fs_info, - struct btrfs_path *path, - const char *name, int name_len) +struct btrfs_dir_item *btrfs_match_dir_item_fname(struct btrfs_fs_info *fs_info, + struct btrfs_path *path, + struct fscrypt_name *name) { struct btrfs_dir_item *dir_item; unsigned long name_ptr; @@ -399,8 +439,8 @@ struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_fs_info *fs_info, btrfs_dir_data_len(leaf, dir_item); name_ptr = (unsigned long)(dir_item + 1); - if (btrfs_dir_name_len(leaf, dir_item) == name_len && - memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) + if (btrfs_fscrypt_match_name(name, leaf, name_ptr, + btrfs_dir_name_len(leaf, dir_item))) return dir_item; cur += this_len; @@ -410,6 +450,21 @@ struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_fs_info *fs_info, return NULL; } +/* + * helper function to look at the directory item pointed to by 'path' + * this walks through all the entries in a dir item and finds one + * for a specific name. + */ +struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_fs_info *fs_info, + struct btrfs_path *path, + const char *name, int name_len) +{ + struct fscrypt_name fname = { + .disk_name = FSTR_INIT((char *) name, name_len) + }; + return btrfs_match_dir_item_fname(fs_info, path, &fname); +} + /* * given a pointer into a directory item, delete it. This * handles items that have more than one entry in them. diff --git a/fs/btrfs/dir-item.h b/fs/btrfs/dir-item.h index e40a226373d7..1d6ab8c3b879 100644 --- a/fs/btrfs/dir-item.h +++ b/fs/btrfs/dir-item.h @@ -6,6 +6,7 @@ #include struct fscrypt_str; +struct fscrypt_name; int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir, const struct fscrypt_str *name); @@ -16,6 +17,11 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, u64 dir, const struct fscrypt_str *name, int mod); +struct btrfs_dir_item *btrfs_lookup_dir_item_fname( + struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, u64 dir, + struct fscrypt_name *name, int mod); struct btrfs_dir_item *btrfs_lookup_dir_index_item( struct btrfs_trans_handle *trans, struct btrfs_root *root, @@ -23,7 +29,7 @@ struct btrfs_dir_item *btrfs_lookup_dir_index_item( u64 index, const struct fscrypt_str *name, int mod); struct btrfs_dir_item *btrfs_search_dir_index_item(struct btrfs_root *root, struct btrfs_path *path, u64 dirid, - const struct fscrypt_str *name); + struct fscrypt_name *name); int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, @@ -42,6 +48,9 @@ struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_fs_info *fs_info, struct btrfs_path *path, const char *name, int name_len); +struct btrfs_dir_item *btrfs_match_dir_item_fname(struct btrfs_fs_info *fs_info, + struct btrfs_path *path, + struct fscrypt_name *name); static inline u64 btrfs_name_hash(const char *name, int len) { diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 6d5c50c0b9ce..c4265826278d 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -4135,6 +4135,24 @@ static void assert_eb_page_uptodate(const struct extent_buffer *eb, } } +/* Take a sha256 of a portion of an extent buffer. */ +void extent_buffer_sha256(const struct extent_buffer *eb, + unsigned long start, + unsigned long len, u8 *out) +{ + void *eb_addr = btrfs_get_eb_addr(eb); + + if (check_eb_range(eb, start, len)) + return; + + /* + * TODO: This should maybe be using the crypto API, not the fallback, + * but fscrypt uses the fallback and this is only used in emulation of + * fscrypt's buffer sha256 method. + */ + sha256(eb_addr + start, len, out); +} + void write_extent_buffer(const struct extent_buffer *eb, const void *srcv, unsigned long start, unsigned long len) { diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 368ffe00c326..b30b3448b1fb 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -254,6 +254,9 @@ static inline int extent_buffer_uptodate(const struct extent_buffer *eb) int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv, unsigned long start, unsigned long len); +void extent_buffer_sha256(const struct extent_buffer *eb, + unsigned long start, + unsigned long len, u8 *out); void read_extent_buffer(const struct extent_buffer *eb, void *dst, unsigned long start, unsigned long len); diff --git a/fs/btrfs/fscrypt.c b/fs/btrfs/fscrypt.c index 0e4011d6b1cd..6a4e4f63a660 100644 --- a/fs/btrfs/fscrypt.c +++ b/fs/btrfs/fscrypt.c @@ -5,13 +5,47 @@ #include "accessors.h" #include "btrfs_inode.h" #include "disk-io.h" +#include "ioctl.h" #include "fs.h" #include "fscrypt.h" #include "ioctl.h" #include "messages.h" +#include "root-tree.h" #include "transaction.h" #include "xattr.h" +/* + * This function is extremely similar to fscrypt_match_name() but uses an + * extent_buffer. + */ +bool btrfs_fscrypt_match_name(struct fscrypt_name *fname, + struct extent_buffer *leaf, unsigned long de_name, + u32 de_name_len) +{ + const struct fscrypt_nokey_name *nokey_name = + (const struct fscrypt_nokey_name *)fname->crypto_buf.name; + u8 digest[SHA256_DIGEST_SIZE]; + + if (likely(fname->disk_name.name)) { + if (de_name_len != fname->disk_name.len) + return false; + return !memcmp_extent_buffer(leaf, fname->disk_name.name, + de_name, de_name_len); + } + + if (de_name_len <= sizeof(nokey_name->bytes)) + return false; + + if (memcmp_extent_buffer(leaf, nokey_name->bytes, de_name, + sizeof(nokey_name->bytes))) + return false; + + extent_buffer_sha256(leaf, de_name + sizeof(nokey_name->bytes), + de_name_len - sizeof(nokey_name->bytes), digest); + + return !memcmp(digest, nokey_name->sha256, sizeof(digest)); +} + static int btrfs_fscrypt_get_context(struct inode *inode, void *ctx, size_t len) { struct btrfs_key key = { diff --git a/fs/btrfs/fscrypt.h b/fs/btrfs/fscrypt.h index 80adb7e56826..1647bbbcd609 100644 --- a/fs/btrfs/fscrypt.h +++ b/fs/btrfs/fscrypt.h @@ -4,9 +4,28 @@ #define BTRFS_FSCRYPT_H #include +#include "extent_io.h" #include "fs.h" +#ifdef CONFIG_FS_ENCRYPTION +bool btrfs_fscrypt_match_name(struct fscrypt_name *fname, + struct extent_buffer *leaf, + unsigned long de_name, u32 de_name_len); + +#else +static inline bool btrfs_fscrypt_match_name(struct fscrypt_name *fname, + struct extent_buffer *leaf, + unsigned long de_name, + u32 de_name_len) +{ + if (de_name_len != fname_len(fname)) + return false; + return !memcmp_extent_buffer(leaf, fname->disk_name.name, de_name, + de_name_len); +} +#endif /* CONFIG_FS_ENCRYPTION */ + extern const struct fscrypt_operations btrfs_fscrypt_ops; #endif /* BTRFS_FSCRYPT_H */ diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a316128b3069..e5b52edcb042 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4048,7 +4048,7 @@ int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans, static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, struct btrfs_inode *dir, struct btrfs_inode *inode, - const struct fscrypt_str *name, + struct fscrypt_name *name, struct btrfs_rename_ctx *rename_ctx) { struct btrfs_root *root = dir->root; @@ -4066,7 +4066,7 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, goto out; } - di = btrfs_lookup_dir_item(trans, root, path, dir_ino, name, -1); + di = btrfs_lookup_dir_item_fname(trans, root, path, dir_ino, name, -1); if (IS_ERR_OR_NULL(di)) { ret = di ? PTR_ERR(di) : -ENOENT; goto err; @@ -4094,11 +4094,14 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, } } - ret = btrfs_del_inode_ref(trans, root, name, ino, dir_ino, &index); + ret = btrfs_del_inode_ref(trans, root, &name->disk_name, ino, dir_ino, + &index); if (ret) { + /* This should print a base-64 encoded name if relevant? */ btrfs_info(fs_info, "failed to delete reference to %.*s, inode %llu parent %llu", - name->len, name->name, ino, dir_ino); + name->disk_name.len, name->disk_name.name, ino, + dir_ino); btrfs_abort_transaction(trans, ret); goto err; } @@ -4119,8 +4122,10 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, * operations on the log tree, increasing latency for applications. */ if (!rename_ctx) { - btrfs_del_inode_ref_in_log(trans, root, name, inode, dir_ino); - btrfs_del_dir_entries_in_log(trans, root, name, dir, index); + btrfs_del_inode_ref_in_log(trans, root, &name->disk_name, + inode, dir_ino); + btrfs_del_dir_entries_in_log(trans, root, &name->disk_name, + dir, index); } /* @@ -4138,7 +4143,7 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, if (ret) goto out; - btrfs_i_size_write(dir, dir->vfs_inode.i_size - name->len * 2); + btrfs_i_size_write(dir, dir->vfs_inode.i_size - name->disk_name.len * 2); inode_inc_iversion(&inode->vfs_inode); inode_inc_iversion(&dir->vfs_inode); inode_set_ctime_current(&inode->vfs_inode); @@ -4150,7 +4155,7 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, int btrfs_unlink_inode(struct btrfs_trans_handle *trans, struct btrfs_inode *dir, struct btrfs_inode *inode, - const struct fscrypt_str *name) + struct fscrypt_name *name) { int ret; @@ -4201,7 +4206,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) false); ret = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(d_inode(dentry)), - &fname.disk_name); + &fname); if (ret) goto end_trans; @@ -4238,8 +4243,6 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, if (ret) return ret; - /* This needs to handle no-key deletions later on */ - if (btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID) { objectid = inode->root->root_key.objectid; } else if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) { @@ -4256,8 +4259,8 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, goto out; } - di = btrfs_lookup_dir_item(trans, root, path, dir_ino, - &fname.disk_name, -1); + di = btrfs_lookup_dir_item_fname(trans, root, path, dir_ino, + &fname, -1); if (IS_ERR_OR_NULL(di)) { ret = di ? PTR_ERR(di) : -ENOENT; goto out; @@ -4283,7 +4286,7 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, * call btrfs_del_root_ref, and it _shouldn't_ fail. */ if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) { - di = btrfs_search_dir_index_item(root, path, dir_ino, &fname.disk_name); + di = btrfs_search_dir_index_item(root, path, dir_ino, &fname); if (IS_ERR_OR_NULL(di)) { if (!di) ret = -ENOENT; @@ -4300,7 +4303,7 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, } else { ret = btrfs_del_root_ref(trans, objectid, root->root_key.objectid, dir_ino, - &index, &fname.disk_name); + &index, &fname); if (ret) { btrfs_abort_transaction(trans, ret); goto out; @@ -4623,7 +4626,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) /* now the directory is empty */ err = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(d_inode(dentry)), - &fname.disk_name); + &fname); if (!err) { btrfs_i_size_write(BTRFS_I(inode), 0); /* @@ -5327,32 +5330,23 @@ void btrfs_evict_inode(struct inode *inode) * If no dir entries were found, returns -ENOENT. * If found a corrupted location in dir entry, returns -EUCLEAN. */ -static int btrfs_inode_by_name(struct btrfs_inode *dir, struct dentry *dentry, +static int btrfs_inode_by_name(struct btrfs_inode *dir, + struct fscrypt_name *fname, struct btrfs_key *location, u8 *type) { struct btrfs_dir_item *di; struct btrfs_path *path; struct btrfs_root *root = dir->root; int ret = 0; - struct fscrypt_name fname; path = btrfs_alloc_path(); if (!path) return -ENOMEM; - ret = fscrypt_setup_filename(&dir->vfs_inode, &dentry->d_name, 1, &fname); - if (ret < 0) - goto out; - /* - * fscrypt_setup_filename() should never return a positive value, but - * gcc on sparc/parisc thinks it can, so assert that doesn't happen. - */ - ASSERT(ret == 0); - /* This needs to handle no-key deletions later on */ - di = btrfs_lookup_dir_item(NULL, root, path, btrfs_ino(dir), - &fname.disk_name, 0); + di = btrfs_lookup_dir_item_fname(NULL, root, path, btrfs_ino(dir), + fname, 0); if (IS_ERR_OR_NULL(di)) { ret = di ? PTR_ERR(di) : -ENOENT; goto out; @@ -5364,13 +5358,13 @@ static int btrfs_inode_by_name(struct btrfs_inode *dir, struct dentry *dentry, ret = -EUCLEAN; btrfs_warn(root->fs_info, "%s gets something invalid in DIR_ITEM (name %s, directory ino %llu, location(%llu %u %llu))", - __func__, fname.disk_name.name, btrfs_ino(dir), - location->objectid, location->type, location->offset); + __func__, fname->usr_fname->name, + btrfs_ino(dir), location->objectid, + location->type, location->offset); } if (!ret) *type = btrfs_dir_ftype(path->nodes[0], di); out: - fscrypt_free_filename(&fname); btrfs_free_path(path); return ret; } @@ -5643,20 +5637,27 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_root *sub_root = root; struct btrfs_key location; + struct fscrypt_name fname; u8 di_type = 0; int ret = 0; if (dentry->d_name.len > BTRFS_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); - ret = btrfs_inode_by_name(BTRFS_I(dir), dentry, &location, &di_type); - if (ret < 0) + ret = fscrypt_prepare_lookup(dir, dentry, &fname); + if (ret) return ERR_PTR(ret); + ret = btrfs_inode_by_name(BTRFS_I(dir), &fname, &location, &di_type); + if (ret < 0) { + inode = ERR_PTR(ret); + goto cleanup; + } + if (location.type == BTRFS_INODE_ITEM_KEY) { inode = btrfs_iget(dir->i_sb, location.objectid, root); if (IS_ERR(inode)) - return inode; + goto cleanup; /* Do extra check against inode mode with di_type */ if (btrfs_inode_type(inode) != di_type) { @@ -5665,9 +5666,10 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) inode->i_mode, btrfs_inode_type(inode), di_type); iput(inode); - return ERR_PTR(-EUCLEAN); + inode = ERR_PTR(-EUCLEAN); + goto cleanup; } - return inode; + goto cleanup; } ret = fixup_tree_root_location(fs_info, BTRFS_I(dir), dentry, @@ -5682,7 +5684,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) btrfs_put_root(sub_root); if (IS_ERR(inode)) - return inode; + goto cleanup; down_read(&fs_info->cleanup_work_sem); if (!sb_rdonly(inode->i_sb)) @@ -5694,6 +5696,8 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) } } +cleanup: + fscrypt_free_filename(&fname); return inode; } @@ -5882,18 +5886,32 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) LIST_HEAD(del_list); int ret; char *name_ptr; - int name_len; + u32 name_len; int entries = 0; int total_len = 0; bool put = false; struct btrfs_key location; + struct fscrypt_str fstr = FSTR_INIT(NULL, 0); + u32 fstr_len = 0; if (!dir_emit_dots(file, ctx)) return 0; + if (BTRFS_I(inode)->flags & BTRFS_INODE_ENCRYPT) { + ret = fscrypt_prepare_readdir(inode); + if (ret) + return ret; + ret = fscrypt_fname_alloc_buffer(BTRFS_NAME_LEN, &fstr); + if (ret) + return ret; + fstr_len = fstr.len; + } + path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + if (!path) { + ret = -ENOMEM; + goto err_fstr; + } addr = private->filldir_buf; path->reada = READA_FORWARD; @@ -5910,6 +5928,7 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) struct dir_entry *entry; struct extent_buffer *leaf = path->nodes[0]; u8 ftype; + u32 nokey_len; if (found_key.objectid != key.objectid) break; @@ -5923,8 +5942,13 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) continue; di = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); name_len = btrfs_dir_name_len(leaf, di); - if ((total_len + sizeof(struct dir_entry) + name_len) >= - PAGE_SIZE) { + nokey_len = DIV_ROUND_UP(name_len * 4, 3); + /* + * If name is encrypted, and we don't have the key, we could + * need up to 4/3rds the bytes to print it. + */ + if ((total_len + sizeof(struct dir_entry) + nokey_len) + >= PAGE_SIZE) { btrfs_release_path(path); ret = btrfs_filldir(private->filldir_buf, entries, ctx); if (ret) @@ -5938,8 +5962,36 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) ftype = btrfs_dir_flags_to_ftype(btrfs_dir_flags(leaf, di)); entry = addr; name_ptr = (char *)(entry + 1); - read_extent_buffer(leaf, name_ptr, - (unsigned long)(di + 1), name_len); + if (btrfs_dir_flags(leaf, di) & BTRFS_FT_ENCRYPTED) { + struct fscrypt_str oname = FSTR_INIT(name_ptr, + nokey_len); + u32 hash = 0, minor_hash = 0; + + read_extent_buffer(leaf, fstr.name, + (unsigned long)(di + 1), name_len); + fstr.len = name_len; + /* + * We're iterating through DIR_INDEX items, so we don't + * have the DIR_ITEM hash handy. Only compute it if + * we'll need it -- the nokey name stores it, so that + * we can look up the appropriate item by nokey name + * later on. + */ + if (!fscrypt_has_encryption_key(inode)) { + u64 name_hash = btrfs_name_hash(fstr.name, + fstr.len); + hash = name_hash; + minor_hash = name_hash >> 32; + } + ret = fscrypt_fname_disk_to_usr(inode, hash, minor_hash, + &fstr, &oname); + if (ret) + goto err; + name_len = oname.len; + } else { + read_extent_buffer(leaf, name_ptr, + (unsigned long)(di + 1), name_len); + } put_unaligned(name_len, &entry->name_len); put_unaligned(fs_ftype_to_dtype(ftype), &entry->type); btrfs_dir_item_key_to_cpu(leaf, di, &location); @@ -5959,7 +6011,8 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) if (ret) goto nopos; - ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list); + fstr.len = fstr_len; + ret = btrfs_readdir_delayed_dir_index(inode, &fstr, ctx, &ins_list); if (ret) goto nopos; @@ -5990,6 +6043,8 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) if (put) btrfs_readdir_put_delayed_items(inode, &ins_list, &del_list); btrfs_free_path(path); +err_fstr: + fscrypt_fname_free_buffer(&fstr); return ret; } @@ -6440,6 +6495,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, struct btrfs_root *root = parent_inode->root; u64 ino = btrfs_ino(inode); u64 parent_ino = btrfs_ino(parent_inode); + struct fscrypt_name fname = { .disk_name = *name }; if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) { memcpy(&key, &inode->root->root_key, sizeof(key)); @@ -6495,7 +6551,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, int err; err = btrfs_del_root_ref(trans, key.objectid, root->root_key.objectid, parent_ino, - &local_index, name); + &local_index, &fname); if (err) btrfs_abort_transaction(trans, err); } else if (add_backref) { @@ -8863,7 +8919,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, } else { /* src is an inode */ ret = __btrfs_unlink_inode(trans, BTRFS_I(old_dir), BTRFS_I(old_dentry->d_inode), - old_name, &old_rename_ctx); + &old_fname, &old_rename_ctx); if (!ret) ret = btrfs_update_inode(trans, BTRFS_I(old_inode)); } @@ -8878,7 +8934,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, } else { /* dest is an inode */ ret = __btrfs_unlink_inode(trans, BTRFS_I(new_dir), BTRFS_I(new_dentry->d_inode), - new_name, &new_rename_ctx); + &new_fname, &new_rename_ctx); if (!ret) ret = btrfs_update_inode(trans, BTRFS_I(new_inode)); } @@ -9123,7 +9179,7 @@ static int btrfs_rename(struct mnt_idmap *idmap, } else { ret = __btrfs_unlink_inode(trans, BTRFS_I(old_dir), BTRFS_I(d_inode(old_dentry)), - &old_fname.disk_name, &rename_ctx); + &old_fname, &rename_ctx); if (!ret) ret = btrfs_update_inode(trans, BTRFS_I(old_inode)); } @@ -9141,7 +9197,7 @@ static int btrfs_rename(struct mnt_idmap *idmap, } else { ret = btrfs_unlink_inode(trans, BTRFS_I(new_dir), BTRFS_I(d_inode(new_dentry)), - &new_fname.disk_name); + &new_fname); } if (!ret && new_inode->i_nlink == 0) ret = btrfs_orphan_add(trans, diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 603ad1459368..d131934123f5 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c @@ -10,6 +10,7 @@ #include "messages.h" #include "transaction.h" #include "disk-io.h" +#include "fscrypt.h" #include "print-tree.h" #include "qgroup.h" #include "space-info.h" @@ -334,7 +335,7 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id, u64 ref_id, u64 dirid, u64 *sequence, - const struct fscrypt_str *name) + struct fscrypt_name *name) { struct btrfs_root *tree_root = trans->fs_info->tree_root; struct btrfs_path *path; @@ -356,13 +357,14 @@ int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id, if (ret < 0) { goto out; } else if (ret == 0) { + u32 name_len; leaf = path->nodes[0]; ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref); ptr = (unsigned long)(ref + 1); + name_len = btrfs_root_ref_name_len(leaf, ref); if ((btrfs_root_ref_dirid(leaf, ref) != dirid) || - (btrfs_root_ref_name_len(leaf, ref) != name->len) || - memcmp_extent_buffer(leaf, name->name, ptr, name->len)) { + !btrfs_fscrypt_match_name(name, leaf, ptr, name_len)) { ret = -ENOENT; goto out; } diff --git a/fs/btrfs/root-tree.h b/fs/btrfs/root-tree.h index 8b2c3859e464..5ba7b36cf826 100644 --- a/fs/btrfs/root-tree.h +++ b/fs/btrfs/root-tree.h @@ -15,7 +15,7 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans, u64 root_id, const struct fscrypt_str *name); int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id, u64 ref_id, u64 dirid, u64 *sequence, - const struct fscrypt_str *name); + struct fscrypt_name *name); int btrfs_del_root(struct btrfs_trans_handle *trans, const struct btrfs_key *key); int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, const struct btrfs_key *key, diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index d3803db10939..c1fd4ef2dd8b 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -901,9 +901,10 @@ static int unlink_inode_for_log_replay(struct btrfs_trans_handle *trans, struct btrfs_inode *inode, const struct fscrypt_str *name) { + struct fscrypt_name fname = { .disk_name = *name, }; int ret; - ret = btrfs_unlink_inode(trans, dir, inode, name); + ret = btrfs_unlink_inode(trans, dir, inode, &fname); if (ret) return ret; /* From patchwork Tue Oct 10 20:40:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416074 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 0B427CD6115 for ; Tue, 10 Oct 2023 20:41:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234652AbjJJUl3 (ORCPT ); Tue, 10 Oct 2023 16:41:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33478 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234455AbjJJUl0 (ORCPT ); Tue, 10 Oct 2023 16:41:26 -0400 Received: from mail-yw1-x1135.google.com (mail-yw1-x1135.google.com [IPv6:2607:f8b0:4864:20::1135]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 709F7B7 for ; Tue, 10 Oct 2023 13:41:22 -0700 (PDT) Received: by mail-yw1-x1135.google.com with SMTP id 00721157ae682-5a7ac4c3666so22887597b3.3 for ; Tue, 10 Oct 2023 13:41:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970481; x=1697575281; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nGaKZfQ8xEUtcj2BvoUGwcXV31Q0VFKb7VLEms82qyQ=; b=v+12unYu8g6cI/P3RKUDnW31FYjwKlbnTb0IrxmO/udAA3btF88eB1rHBRdxhpERTo adrzkWk0c96n/vGDwOw21HjzlSHmeBLsmOe/nTAAShkCZKnkTwMc+QLer9luJyLurTAr HqsKG6xjRWAmW0zH5bHRKMiPdfs5T4IBwJGPE7Acd3apLVCtnOX97XSaXRBPr6jD58Sk 9BiuUZLo6KSDU2q1AUVhH+1Xsz6TD4d9bXku5wmuqSE/2DBzJ3qC1yHkxlpXWnSfepyw 4Z08/6lM2ifAHRc30DaqUN9wDF1MAfoLEddU7msZ/Ld/25buYNv/lyw+XmNRsDdXrzBO bd0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970481; x=1697575281; 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=nGaKZfQ8xEUtcj2BvoUGwcXV31Q0VFKb7VLEms82qyQ=; b=Aaorm1RiWB/GTMPkZ/qR6FA2DpvK8lHJmov6A6vO+z1WHZg3iywxPsdYIHTTm0oKo+ 7MnRjruZeCPlNhkyT+KXCXZyWMZoUYInDMf6Oz7Xye5is0HV2wauOHHtx1xSMXcviigj 9o2tyPpWKILcHTJBly/7fq6UYQMnMkOyRUxfTZCLOfoc5yD7rx/NaFmoNcOtQ8Xo8Yxd BLjyHXt8/QBuDA1bu2tLcD3a828Z7O8NdiAeDIRtt5602Q62sLWaEo4i3RBJRmCNmege j+sSkRGEyBRuajWq1d5iy3rUF+Gm18NcIVWv7evacDljY0v6us/0N4LhQjHWSozAENQh rpKw== X-Gm-Message-State: AOJu0YydQT+TdnfzBJc2hTcih6lL0yQItO9y3NC/rNnfs15W77UKCw1Q Z/gc3KlP6viXqveb81TTYBmN+B04iZ+mKHMNTZ+S/w== X-Google-Smtp-Source: AGHT+IHeEj663skje7rfY8kWno/+5dW68lLPSD/+JCkdZB2lrebxfySWJGa4nOxiXvR4HoXr8G6Ejw== X-Received: by 2002:a81:ac20:0:b0:5a7:b900:a373 with SMTP id k32-20020a81ac20000000b005a7b900a373mr4067162ywh.0.1696970481246; Tue, 10 Oct 2023 13:41:21 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id q2-20020a819902000000b0059bc0d766f8sm1084022ywg.34.2023.10.10.13.41.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:20 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Sweet Tea Dorminy Subject: [PATCH v2 15/36] btrfs: handle nokey names. Date: Tue, 10 Oct 2023 16:40:30 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Sweet Tea Dorminy For encrypted or unencrypted names, we calculate the offset for the dir item by hashing the name for the dir item. However, this doesn't work for a long nokey name, where we do not have the complete ciphertext. Instead, fscrypt stores the filesystem-provided hash in the nokey name, and we can extract it from the fscrypt_name structure in such a case. Additionally, for nokey names, if we find the nokey name on disk we can update the fscrypt_name with the disk name, so add that to searching for diritems. Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/dir-item.c | 37 +++++++++++++++++++++++++++++++++++-- fs/btrfs/fscrypt.c | 27 +++++++++++++++++++++++++++ fs/btrfs/fscrypt.h | 11 +++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index a64cfddff7f0..897fb5477369 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c @@ -231,6 +231,28 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, return di; } +/* + * If appropriate, populate the disk name for a fscrypt_name looked up without + * a key. + * + * @path: The path to the extent buffer in which the name was found. + * @di: The dir item corresponding. + * @fname: The fscrypt_name to perhaps populate. + * + * Returns: 0 if the name is already populated or the dir item doesn't exist + * or the name was successfully populated, else an error code. + */ +static int ensure_disk_name_from_dir_item(struct btrfs_path *path, + struct btrfs_dir_item *di, + struct fscrypt_name *name) +{ + if (name->disk_name.name || !di) + return 0; + + return btrfs_fscrypt_get_disk_name(path->nodes[0], di, + &name->disk_name); +} + /* * Lookup for a directory item by fscrypt_name. * @@ -257,8 +279,12 @@ struct btrfs_dir_item *btrfs_lookup_dir_item_fname(struct btrfs_trans_handle *tr key.objectid = dir; key.type = BTRFS_DIR_ITEM_KEY; - key.offset = btrfs_name_hash(name->disk_name.name, name->disk_name.len); - /* XXX get the right hash for no-key names */ + + if (!name->disk_name.name) + key.offset = name->hash | ((u64)name->minor_hash << 32); + else + key.offset = btrfs_name_hash(name->disk_name.name, + name->disk_name.len); ret = btrfs_search_slot(trans, root, &key, path, mod, -mod); if (ret == 0) @@ -266,6 +292,8 @@ struct btrfs_dir_item *btrfs_lookup_dir_item_fname(struct btrfs_trans_handle *tr if (ret == -ENOENT || (di && IS_ERR(di) && PTR_ERR(di) == -ENOENT)) return NULL; + if (ret == 0) + ret = ensure_disk_name_from_dir_item(path, di, name); if (ret < 0) di = ERR_PTR(ret); @@ -382,7 +410,12 @@ btrfs_search_dir_index_item(struct btrfs_root *root, struct btrfs_path *path, btrfs_for_each_slot(root, &key, &key, path, ret) { if (key.objectid != dirid || key.type != BTRFS_DIR_INDEX_KEY) break; + di = btrfs_match_dir_item_fname(root->fs_info, path, name); + if (di) + ret = ensure_disk_name_from_dir_item(path, di, name); + if (ret) + break; if (di) return di; } diff --git a/fs/btrfs/fscrypt.c b/fs/btrfs/fscrypt.c index 6a4e4f63a660..9103da28af7e 100644 --- a/fs/btrfs/fscrypt.c +++ b/fs/btrfs/fscrypt.c @@ -14,6 +14,33 @@ #include "transaction.h" #include "xattr.h" +/* + * From a given location in a leaf, read a name into a qstr (usually a + * fscrypt_name's disk_name), allocating the required buffer. Used for + * nokey names. + */ +int btrfs_fscrypt_get_disk_name(struct extent_buffer *leaf, + struct btrfs_dir_item *dir_item, + struct fscrypt_str *name) +{ + unsigned long de_name_len = btrfs_dir_name_len(leaf, dir_item); + unsigned long de_name = (unsigned long)(dir_item + 1); + /* + * For no-key names, we use this opportunity to find the disk + * name, so future searches don't need to deal with nokey names + * and we know what the encrypted size is. + */ + name->name = kmalloc(de_name_len, GFP_NOFS); + + if (!name->name) + return -ENOMEM; + + read_extent_buffer(leaf, name->name, de_name, de_name_len); + + name->len = de_name_len; + return 0; +} + /* * This function is extremely similar to fscrypt_match_name() but uses an * extent_buffer. diff --git a/fs/btrfs/fscrypt.h b/fs/btrfs/fscrypt.h index 1647bbbcd609..c08fd52c99b4 100644 --- a/fs/btrfs/fscrypt.h +++ b/fs/btrfs/fscrypt.h @@ -9,11 +9,22 @@ #include "fs.h" #ifdef CONFIG_FS_ENCRYPTION +int btrfs_fscrypt_get_disk_name(struct extent_buffer *leaf, + struct btrfs_dir_item *di, + struct fscrypt_str *qstr); + bool btrfs_fscrypt_match_name(struct fscrypt_name *fname, struct extent_buffer *leaf, unsigned long de_name, u32 de_name_len); #else +static inline int btrfs_fscrypt_get_disk_name(struct extent_buffer *leaf, + struct btrfs_dir_item *di, + struct fscrypt_str *qstr) +{ + return 0; +} + static inline bool btrfs_fscrypt_match_name(struct fscrypt_name *fname, struct extent_buffer *leaf, unsigned long de_name, From patchwork Tue Oct 10 20:40:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416075 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 A9A2ECD8CBF for ; Tue, 10 Oct 2023 20:41:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234455AbjJJUlb (ORCPT ); Tue, 10 Oct 2023 16:41:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33448 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343780AbjJJUl1 (ORCPT ); Tue, 10 Oct 2023 16:41:27 -0400 Received: from mail-yw1-x1133.google.com (mail-yw1-x1133.google.com [IPv6:2607:f8b0:4864:20::1133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 41716B9 for ; Tue, 10 Oct 2023 13:41:23 -0700 (PDT) Received: by mail-yw1-x1133.google.com with SMTP id 00721157ae682-5a7be61fe74so15049427b3.2 for ; Tue, 10 Oct 2023 13:41:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970482; x=1697575282; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SgLb5y9ux6Y3nH3Dpo6jruzdTCArFvbtPwPabW0o0qU=; b=2Iu0cM8G9QNZ8DoQmhBTP0J+823ugjyqTenoB9xu5A/DYaPOont2cSXwjVcIlOtKzC O5wuwepD8ibSHGzAzB/1v9dNymNJwfxJcDx0MkXuxqIJBCD9l2Wd99oxY5q5AP4D9h6v Qm+IuOYiKy22JckzYPiKTiJ9k8rY+gLkeLkbR3qrY6ZOi3AWfBiTD+lL8Tjba5KCpEdr P1m814xJk0OQIW0ub6HU5GzZsuLHQFY6aFbISTKJ/WM3kwR73YYPAtiVgq5YOGrvgUVC GaEz895+B9Iqwbnp8PXgzx1gdCDTBkP2fdFaB9MEHZdya95NN1SgZ6p0d0spXLzWSbK+ KOZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970482; x=1697575282; 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=SgLb5y9ux6Y3nH3Dpo6jruzdTCArFvbtPwPabW0o0qU=; b=kvHf0pZ6vOTG8P5v56nKWgz0oRXfadgRGw8fHGEInxkbUtaVO97he5HfVPF1cc2fAv +bd1CMcWYaRqojSkXOzQSHTOeRtmfwMMiRC0bpnUGHzRh3j5KHweJhAdUT3pyoWKAJ/x RU2/mkBEytUC4k46tLYtPQC0wtxHh0ZWRHrDoJNgdSSVX4m5DGyUMi9x25yutgRPnmbx 6IG31cMrRTyiu66OFijOSO0BoHWW2lyu9jOWoprrQN1a+u8QQLk7PVs8Nc/PcLZAeWCy 8StmwKQkZYE7I1QnzaMQp0DNVHwoEdKaEuIh9n8OkeOUT4DA9/ezFPt2QHMjf/lwZFvn FxRQ== X-Gm-Message-State: AOJu0Yw670e9AE+TPvWKoEc+I6KcDHU0FPMzsKs8+KbEKM/2ldHR7OfF y1kDR8zZznW+dHrPqWgwZ2Flox5h58zxpi/jNbvEvg== X-Google-Smtp-Source: AGHT+IHYW6Z9cFRYt8h0d7OoJLV4IK4K2kTHi6uHVrPXFZJKKfKaqyzfW7wtSaTlT2rqqqoFYHU/tQ== X-Received: by 2002:a81:c246:0:b0:57a:8ecb:11ad with SMTP id t6-20020a81c246000000b0057a8ecb11admr22346857ywg.43.1696970482248; Tue, 10 Oct 2023 13:41:22 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id q6-20020a815c06000000b00592548b2c47sm4655990ywb.80.2023.10.10.13.41.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:21 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH v2 16/36] btrfs: implement fscrypt ioctls Date: Tue, 10 Oct 2023 16:40:31 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Omar Sandoval These ioctls allow encryption to actually be used. The set_encryption_policy ioctl is the thing which actually turns on encryption, and therefore sets the ENCRYPT flag in the superblock. This prevents the filesystem from being loaded on older kernels. fscrypt provides CONFIG_FS_ENCRYPTION-disabled versions of all these functions which just return -EOPNOTSUPP, so the ioctls don't need to be compiled out if CONFIG_FS_ENCRYPTION isn't enabled. We could instead gate this ioctl on the superblock having the flag set, if we wanted to require mkfs with the encrypt flag in order to have a filesystem with any encryption. Signed-off-by: Omar Sandoval Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/ioctl.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 1f1506280619..5938adb64409 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4575,6 +4575,34 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_get_fslabel(fs_info, argp); case FS_IOC_SETFSLABEL: return btrfs_ioctl_set_fslabel(file, argp); + case FS_IOC_SET_ENCRYPTION_POLICY: { + if (!IS_ENABLED(CONFIG_FS_ENCRYPTION)) + return -EOPNOTSUPP; + if (sb_rdonly(fs_info->sb)) + return -EROFS; + /* + * If we crash before we commit, nothing encrypted could have + * been written so it doesn't matter whether the encrypted + * state persists. + */ + btrfs_set_fs_incompat(fs_info, ENCRYPT); + return fscrypt_ioctl_set_policy(file, (const void __user *)arg); + } + case FS_IOC_GET_ENCRYPTION_POLICY: + return fscrypt_ioctl_get_policy(file, (void __user *)arg); + case FS_IOC_GET_ENCRYPTION_POLICY_EX: + return fscrypt_ioctl_get_policy_ex(file, (void __user *)arg); + case FS_IOC_ADD_ENCRYPTION_KEY: + return fscrypt_ioctl_add_key(file, (void __user *)arg); + case FS_IOC_REMOVE_ENCRYPTION_KEY: + return fscrypt_ioctl_remove_key(file, (void __user *)arg); + case FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS: + return fscrypt_ioctl_remove_key_all_users(file, + (void __user *)arg); + case FS_IOC_GET_ENCRYPTION_KEY_STATUS: + return fscrypt_ioctl_get_key_status(file, (void __user *)arg); + case FS_IOC_GET_ENCRYPTION_NONCE: + return fscrypt_ioctl_get_nonce(file, (void __user *)arg); case FITRIM: return btrfs_ioctl_fitrim(fs_info, argp); case BTRFS_IOC_SNAP_CREATE: From patchwork Tue Oct 10 20:40:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416076 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 99140CD68E9 for ; Tue, 10 Oct 2023 20:41:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234685AbjJJUlc (ORCPT ); Tue, 10 Oct 2023 16:41:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42336 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343846AbjJJUl1 (ORCPT ); Tue, 10 Oct 2023 16:41:27 -0400 Received: from mail-yb1-xb31.google.com (mail-yb1-xb31.google.com [IPv6:2607:f8b0:4864:20::b31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 526EA9E for ; Tue, 10 Oct 2023 13:41:24 -0700 (PDT) Received: by mail-yb1-xb31.google.com with SMTP id 3f1490d57ef6-d865854ef96so6544883276.2 for ; Tue, 10 Oct 2023 13:41:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970483; x=1697575283; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=87dZSqgSaXj4ytyfF35JvwlP3e7S7MAiVwyt9dp8ebs=; b=anLPh7C0zTh6PUt7uDdSzRPQQ1dfTi3gtjx1BQHP0erMnM4O3DSuKHRzOPyFsdYFdT s24WgR72H7ZOyN3L3uEQbCB+qWkXD1OaGWwzs+e6MmA9ioio8xaDCkmf90H5H9nqEnvT UbJwcxmiFgc1SBr3XBSw6PqFjRKpapiI99f6HaxMEev54BrIdrKoz35CLlli8anD+b3T q7+vyjc6yFwSaAxO/6j63TrySOKb4s8vBfjxSW/EwKGuMyxE7DdjzSLQXJOE2dyJbvPL RoGdi4SiNLU0xJjsDUSvj5NgUsiIN4vW6b67BHGQFWusg/oRGDbSJubTTx8yjtZSBKYS 1I+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970483; x=1697575283; 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=87dZSqgSaXj4ytyfF35JvwlP3e7S7MAiVwyt9dp8ebs=; b=Z+ueANSD0E+fJTA7vjFAv7BW8tbZrZa2o5fQEdCEmbvOc7+nLf2UszPQg9nWMLKA0o 279hSsqpwcJ/BzOcCgWsWOq2es0CUi35vKW9WZFQ3XLxOvFYkCAvK0pbz1S3hYlIgYbx kn/MXDxLrwkHdQ8ByhV5AP057LKUgl2X7T/HPdBuLT/iT8NSff7rWBSTPuvzxt8wNSqn iBz7/DHdZXFWBs7mqiM13zPHtO2KQf04VlTn5PY58QDCLlF4KN+3UuXPM3zDWXAjBJQ3 /lyJXdNuLuG0eaI1wmXfdGGfw19weJ6R3p4+TqSIrXQS6FRrVYecddtMMVPUqcJn/OZL ic+w== X-Gm-Message-State: AOJu0YwpjhEC7KI9h6nChfhDku22t4Vyj4ijTigjNXyIWK2BJ26YhOeg SnigQVs5GYiK7tBfKiojQ/KwVQeN6t/W7SHCTeYDmg== X-Google-Smtp-Source: AGHT+IEdXg62sV/IhuhsQeH2LWLtqloAx6ZlMUY4+WBDUwliy0+jchyIbbiCbelWWs7f96gcvCkxgA== X-Received: by 2002:a25:70c3:0:b0:d84:b0f8:916 with SMTP id l186-20020a2570c3000000b00d84b0f80916mr18298740ybc.64.1696970483230; Tue, 10 Oct 2023 13:41:23 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id j200-20020a2523d1000000b00d9a58aa5806sm709462ybj.25.2023.10.10.13.41.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:22 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Sweet Tea Dorminy Subject: [PATCH v2 17/36] btrfs: add encryption to CONFIG_BTRFS_DEBUG Date: Tue, 10 Oct 2023 16:40:32 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Sweet Tea Dorminy Since encryption is currently under BTRFS_DEBUG, this adds its dependencies: inline encryption from fscrypt, and the inline encryption fallback path from the block layer. Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/ioctl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 5938adb64409..c56986031870 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4575,6 +4575,7 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_get_fslabel(fs_info, argp); case FS_IOC_SETFSLABEL: return btrfs_ioctl_set_fslabel(file, argp); +#ifdef CONFIG_BTRFS_DEBUG case FS_IOC_SET_ENCRYPTION_POLICY: { if (!IS_ENABLED(CONFIG_FS_ENCRYPTION)) return -EOPNOTSUPP; @@ -4603,6 +4604,7 @@ long btrfs_ioctl(struct file *file, unsigned int return fscrypt_ioctl_get_key_status(file, (void __user *)arg); case FS_IOC_GET_ENCRYPTION_NONCE: return fscrypt_ioctl_get_nonce(file, (void __user *)arg); +#endif /* CONFIG_BTRFS_DEBUG */ case FITRIM: return btrfs_ioctl_fitrim(fs_info, argp); case BTRFS_IOC_SNAP_CREATE: From patchwork Tue Oct 10 20:40:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416077 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 34841CD8CB9 for ; Tue, 10 Oct 2023 20:41:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234700AbjJJUld (ORCPT ); Tue, 10 Oct 2023 16:41:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33532 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343944AbjJJUl2 (ORCPT ); Tue, 10 Oct 2023 16:41:28 -0400 Received: from mail-yw1-x112f.google.com (mail-yw1-x112f.google.com [IPv6:2607:f8b0:4864:20::112f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA0DAB6 for ; Tue, 10 Oct 2023 13:41:25 -0700 (PDT) Received: by mail-yw1-x112f.google.com with SMTP id 00721157ae682-59e88a28b98so2347627b3.1 for ; Tue, 10 Oct 2023 13:41:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970484; x=1697575284; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Cn/5d23+Piiaq9wfrRh434zM+tA72DN+x3v+pwhuqj8=; b=zmFAfCyBFhEb3caIdmOULX0jWmJlK1g3XB/Srysh+2LNbdvha5aFMWGly+7i3/oz3x DvQfY9TAjWyPDovBHUTedxUHHnDwec/VLC0OBurBevGG3pSNHxeawRxsS4ZO59baMyp1 3/aw/FgQrDpR77GCRAFP2I3JhvVem522xJ9plBL8CkhAZj5gT4T9HbKQmrc1a97+k1eC /BfO2QAqP5kQ/scHieIpnmQK3bH3PzSCBx8Zxib+KSLVdsuefR2qtG1Uq3+Ulvk1ur4L 8kjgPHjcs1w0W9SlGoXJvR1wnYV8Xawv82HnlV9clUsHp2niPgUuuiD0Ww+y7wmsMSId 7JgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970484; x=1697575284; 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=Cn/5d23+Piiaq9wfrRh434zM+tA72DN+x3v+pwhuqj8=; b=DtQ7TBFA1bEO/TmjNDgK2XTlsnehVGwbpJzsqfBtMme4m6LTPvSC9uzV1vfCWbDzDW X35WHnGwfghSahq/nQbWyNsYC1GrdsvC7Mz8uBSo93feHuCmzAVL6rOBrUy9FPqSRo2a iX16HQ3aavbMxZpDuRY8uvOzMTQODKY6Tak7LPKhkg/hxAFtvThM9k7tgUtEdV2AqJBI DeUgNx/CFhh3ihmE9u1KMH9XYCIT3L+A1zf7fkhdGKLqA2OYowve0bMBIqtMonbkEBCc t5/m0Q+RCSnPzNTPQPsKSeyTA6G6l3hCKRYaNMonE1GJ24hZRL9Ru6fs0UlzRO/FsNnA b7jQ== X-Gm-Message-State: AOJu0YxvZb/3VVL7nAR6vXxGP7T+/jnIjqAbhbL7EftARuZFZPu0KDiA 1wyknTwYLqA0BiI/5SlhaA8aamGO2/t/XZhrKdRfYQ== X-Google-Smtp-Source: AGHT+IE+pTDSAYCF/HlGbl+2jDt61Pxzj8VSRBlo6mYOzIJvcDB5o257HarTdfcxopAfSRtHDcz1+Q== X-Received: by 2002:a0d:e813:0:b0:59f:699b:c3b3 with SMTP id r19-20020a0de813000000b0059f699bc3b3mr10419621ywe.0.1696970484152; Tue, 10 Oct 2023 13:41:24 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id g68-20020a0df647000000b0059f766f9750sm4674820ywf.124.2023.10.10.13.41.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:23 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Sweet Tea Dorminy Subject: [PATCH v2 18/36] btrfs: add get_devices hook for fscrypt Date: Tue, 10 Oct 2023 16:40:33 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Sweet Tea Dorminy Since extent encryption requires inline encryption, even though we expect to use the inlinecrypt software fallback most of the time, we need to enumerate all the devices in use by btrfs. Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/fscrypt.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/fs/btrfs/fscrypt.c b/fs/btrfs/fscrypt.c index 9103da28af7e..2d037b105b5f 100644 --- a/fs/btrfs/fscrypt.c +++ b/fs/btrfs/fscrypt.c @@ -11,7 +11,9 @@ #include "ioctl.h" #include "messages.h" #include "root-tree.h" +#include "super.h" #include "transaction.h" +#include "volumes.h" #include "xattr.h" /* @@ -178,8 +180,43 @@ static bool btrfs_fscrypt_empty_dir(struct inode *inode) return inode->i_size == BTRFS_EMPTY_DIR_SIZE; } +static struct block_device **btrfs_fscrypt_get_devices(struct super_block *sb, + unsigned int *num_devs) +{ + struct btrfs_fs_info *fs_info = btrfs_sb(sb); + struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; + int nr_devices = fs_devices->open_devices; + struct block_device **devs; + struct btrfs_device *device; + int i = 0; + + devs = kmalloc_array(nr_devices, sizeof(*devs), GFP_NOFS | GFP_NOWAIT); + if (!devs) + return ERR_PTR(-ENOMEM); + + rcu_read_lock(); + list_for_each_entry_rcu(device, &fs_devices->devices, dev_list) { + if (!test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, + &device->dev_state) || + !device->bdev || + test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state)) + continue; + + devs[i++] = device->bdev; + + if (i >= nr_devices) + break; + + } + rcu_read_unlock(); + + *num_devs = i; + return devs; +} + const struct fscrypt_operations btrfs_fscrypt_ops = { .get_context = btrfs_fscrypt_get_context, .set_context = btrfs_fscrypt_set_context, .empty_dir = btrfs_fscrypt_empty_dir, + .get_devices = btrfs_fscrypt_get_devices, }; From patchwork Tue Oct 10 20:40:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416078 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 B8B66CD8CBE for ; Tue, 10 Oct 2023 20:41:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234709AbjJJUle (ORCPT ); Tue, 10 Oct 2023 16:41:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42432 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343969AbjJJUl3 (ORCPT ); Tue, 10 Oct 2023 16:41:29 -0400 Received: from mail-yw1-x1132.google.com (mail-yw1-x1132.google.com [IPv6:2607:f8b0:4864:20::1132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D8130F0 for ; Tue, 10 Oct 2023 13:41:26 -0700 (PDT) Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-5a7c08b7744so13833137b3.3 for ; Tue, 10 Oct 2023 13:41:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970485; x=1697575285; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ncefcNQo/6u3yr6RKhoA0m0GLVQ1MY8hnt6OMBhNPts=; b=lXPtO989sSG987fR0CX+DyfFgw7plP9LQGDEeyL2IIiippkZ8Hn0pP7IirtdYQeuYs Ra8QnhAISzBiVDkPGLL11s8uptCWjoPer/PwoGCxpL4iD9mmQkd7sQQFARkTwhUv4l16 tPf8lShwNsWhuXBVIh217L/nwNxqZl0qRHzHe7LvplN5VHf4bClZhstPHrzTyeWC+lSK Q6vWzCZrgw1qNEULfPcQYi4U2TYju/T5yfoDQy3eedBxTYRDk3C8GiTA+q7NHMFFNk/o F8VVSusQX7hAUU+qCCWeHt4BAzgTA3NaHa6iyCDQqCB48rNLR8kPWPoAQmDf/w+rlmRr 6jlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970485; x=1697575285; 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=ncefcNQo/6u3yr6RKhoA0m0GLVQ1MY8hnt6OMBhNPts=; b=SbYcId68LtpgIBzbhG7hSva8JwtOyjHMv/XkLqMxgmo0q3Bzyw9vXRDiByk+YEd/JO tFzAXXYwYbF8Xqideko9V5NB1DOeYPDkKorq0yRK9kLKxgTLoU4Npub8dOzRXW6gridy sU/uW4hgH8FBs/lAv/h84ftsJkz0P7xBTnEKJyeF4HVd7wHVtk8yZjDsdqyF4kTJObEW HouGQQa7krJABxaOHIzLf4w1VPOfHs6u6+yTcIUprXbxrlov3jyP/7BFxVy/EGAaY2XK pJiB6afpErde7yekBl3ETMpJFO4twQJfZ8Y2Ue8QkSk/Vn7CVLs4yisABX1ALHzgHyzs /kPg== X-Gm-Message-State: AOJu0YwJwa2Ib2IeGbcBe/y0PqbHLyQvcRYIahdJ0+LB6vuH8Y43+7SZ WZXHSBP30QfnVWqhQSHgd2I0MjPabacxBlLhazc2aQ== X-Google-Smtp-Source: AGHT+IGI47BK/YNWxhDw3A3V3kdysgH8sid6WO69cVWJTKj4MpY2+819JDrDUgrEwfmMQeKrDmj00w== X-Received: by 2002:a81:8284:0:b0:59b:c0d7:6766 with SMTP id s126-20020a818284000000b0059bc0d76766mr21450605ywf.37.1696970485395; Tue, 10 Oct 2023 13:41:25 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id r5-20020a814405000000b0059bc980b1eesm958495ywa.6.2023.10.10.13.41.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:24 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Sweet Tea Dorminy Subject: [PATCH v2 19/36] btrfs: turn on inlinecrypt mount option for encrypt Date: Tue, 10 Oct 2023 16:40:34 -0400 Message-ID: <65b4dedde4b0e52b7e1d7980e4b205ab8b313939.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Sweet Tea Dorminy fscrypt's extent encryption requires the use of inline encryption or the software fallback that the block layer provides; it is rather complicated to allow software encryption with extent encryption due to the timing of memory allocations. Thus, if btrfs has ever had a encrypted file, or when encryption is enabled on a directory, update the mount flags to include inlinecrypt. Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/ioctl.c | 3 +++ fs/btrfs/super.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index c56986031870..69ab0d7e393f 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4587,6 +4587,9 @@ long btrfs_ioctl(struct file *file, unsigned int * state persists. */ btrfs_set_fs_incompat(fs_info, ENCRYPT); + if (!(inode->i_sb->s_flags & SB_INLINECRYPT)) { + inode->i_sb->s_flags |= SB_INLINECRYPT; + } return fscrypt_ioctl_set_policy(file, (const void __user *)arg); } case FS_IOC_GET_ENCRYPTION_POLICY: diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index bacf5c4f2a5c..224760cc72b6 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1124,6 +1124,16 @@ static int btrfs_fill_super(struct super_block *sb, return err; } + if (btrfs_fs_incompat(fs_info, ENCRYPT)) { + if (IS_ENABLED(CONFIG_FS_ENCRYPTION_INLINE_CRYPT)) { + sb->s_flags |= SB_INLINECRYPT; + } else { + btrfs_err(fs_info, "encryption not supported"); + err = -EINVAL; + goto fail_close; + } + } + inode = btrfs_iget(sb, BTRFS_FIRST_FREE_OBJECTID, fs_info->fs_root); if (IS_ERR(inode)) { err = PTR_ERR(inode); From patchwork Tue Oct 10 20:40:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416079 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 567A2CD6119 for ; Tue, 10 Oct 2023 20:41:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234711AbjJJUlf (ORCPT ); Tue, 10 Oct 2023 16:41:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33504 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234632AbjJJUl3 (ORCPT ); Tue, 10 Oct 2023 16:41:29 -0400 Received: from mail-yw1-x1136.google.com (mail-yw1-x1136.google.com [IPv6:2607:f8b0:4864:20::1136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9CA28AF for ; Tue, 10 Oct 2023 13:41:27 -0700 (PDT) Received: by mail-yw1-x1136.google.com with SMTP id 00721157ae682-5a7c7262d5eso11150727b3.1 for ; Tue, 10 Oct 2023 13:41:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970486; x=1697575286; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=q5MCWk661EZR0yQflHwRp7j11F40Rg/sD7ho8oSo4N0=; b=Qgr/udq7+iOfiXo2yHTPfN1kYbHpo62fIE6U7xmjpg573B7ddb6J+QA3nBdvQ2EYJb SepmsDJ3XH1RIjJmJLeQwnIRFvsIOLfye8fiCHURJxvOdiiDY9oEibTYBY7i0t4C9TcC YZ2MF4hF58Olg1gBOZkjK0kB+MvF5PKJMNfTnvotxFTyKVOezPWsF3QxjKgUKXAo5fV+ X7I/sWbcFKBUr4aZ7KW9TF4IKceueGnRjJQalokZyX2bj7Z5RUJkwcYxE4EBHxJNEWSr M6IdZjAV43Bd0ZslzTmL+1rDgTAoFxXLIFvi8g0k6wiD9Q5S8NsodMi6VGI3d3mF2bY7 3+Eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970486; x=1697575286; 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=q5MCWk661EZR0yQflHwRp7j11F40Rg/sD7ho8oSo4N0=; b=HWQo1LllgW6K1qnSxqW9/MKAjoO1ee6W0ws8C7wn/kE+Sg5j/jk5yVb1KkCEsldwR1 dayWfGQMJRsCfhfdWAOTR//u7jiHIJ/GErACia5t35/vHGkY0FkzxTbxu6MN49wbh0yT IMX5yGtuLfCOC/SgpULJznosImO0ODrpHt0PvRlo3s7Hce6TVGmxW3rSJu3vgi5FmPcj KIUa6aKr7maPbjJx4snSTU7E4XuyJmYzGhQg0YXc9Z5DUiQzOaigCX3DgL7X8FAP2jR2 UBpy0yYh+Oz3RqL2p7jCIVG8qE9jG/cE06c1SHu+delpz6eRRAvBSzPcMc0IaLSH8x5C ftJQ== X-Gm-Message-State: AOJu0Ywu/IJNrGvageDqe9/FcxDpmU6Gx9H0OrI1gTrGyFD4UWbnAfOO qJeivcIUgbCqodoKOnv3utIYoo6LEaXhXms1kNlgyA== X-Google-Smtp-Source: AGHT+IHGeF/oL94akgLlXxtzH+SovNmE9PJgEqpnpaHqTPMtKnGFsY+2TBxuAcy8OlF653cQwb3M/w== X-Received: by 2002:a81:5254:0:b0:5a7:c92b:f49 with SMTP id g81-20020a815254000000b005a7c92b0f49mr2149709ywb.21.1696970486493; Tue, 10 Oct 2023 13:41:26 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id u7-20020a814707000000b005a23fc389d8sm4591665ywa.103.2023.10.10.13.41.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:26 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Sweet Tea Dorminy Subject: [PATCH v2 20/36] btrfs: set file extent encryption excplicitly Date: Tue, 10 Oct 2023 16:40:35 -0400 Message-ID: <51d5438ae7f0dc2bae5e3126c7e061680aa69ad0.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Sweet Tea Dorminy This puts the long-preserved 1-byte encryption field to work, storing whether the extent is encrypted. Update the tree-checker to allow for the encryption bit to be set to our valid types. Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/accessors.h | 2 ++ fs/btrfs/inode.c | 8 ++++++-- fs/btrfs/tree-checker.c | 8 +++++--- fs/btrfs/tree-log.c | 2 ++ include/uapi/linux/btrfs_tree.h | 8 +++++++- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/accessors.h b/fs/btrfs/accessors.h index aa0844535644..5aaf204fa55f 100644 --- a/fs/btrfs/accessors.h +++ b/fs/btrfs/accessors.h @@ -949,6 +949,8 @@ BTRFS_SETGET_STACK_FUNCS(stack_file_extent_disk_num_bytes, struct btrfs_file_extent_item, disk_num_bytes, 64); BTRFS_SETGET_STACK_FUNCS(stack_file_extent_compression, struct btrfs_file_extent_item, compression, 8); +BTRFS_SETGET_STACK_FUNCS(stack_file_extent_encryption, + struct btrfs_file_extent_item, encryption, 8); BTRFS_SETGET_FUNCS(file_extent_type, struct btrfs_file_extent_item, type, 8); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e5b52edcb042..9cb8b82ff8be 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2992,7 +2992,9 @@ static int insert_ordered_extent_file_extent(struct btrfs_trans_handle *trans, btrfs_set_stack_file_extent_num_bytes(&stack_fi, num_bytes); btrfs_set_stack_file_extent_ram_bytes(&stack_fi, ram_bytes); btrfs_set_stack_file_extent_compression(&stack_fi, oe->compress_type); - /* Encryption and other encoding is reserved and all 0 */ + btrfs_set_stack_file_extent_encryption(&stack_fi, + BTRFS_ENCRYPTION_NONE); + /* Other encoding is reserved and always 0 */ /* * For delalloc, when completing an ordered extent we update the inode's @@ -9640,7 +9642,9 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( btrfs_set_stack_file_extent_num_bytes(&stack_fi, len); btrfs_set_stack_file_extent_ram_bytes(&stack_fi, len); btrfs_set_stack_file_extent_compression(&stack_fi, BTRFS_COMPRESS_NONE); - /* Encryption and other encoding is reserved and all 0 */ + btrfs_set_stack_file_extent_encryption(&stack_fi, + BTRFS_ENCRYPTION_NONE); + /* Other encoding is reserved and always 0 */ qgroup_released = btrfs_qgroup_release_data(inode, file_offset, len); if (qgroup_released < 0) diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index a416cbea75d1..825b235927c6 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c @@ -210,6 +210,7 @@ static int check_extent_data_item(struct extent_buffer *leaf, u32 sectorsize = fs_info->sectorsize; u32 item_size = btrfs_item_size(leaf, slot); u64 extent_end; + u8 policy; if (unlikely(!IS_ALIGNED(key->offset, sectorsize))) { file_extent_err(leaf, slot, @@ -261,10 +262,11 @@ static int check_extent_data_item(struct extent_buffer *leaf, BTRFS_NR_COMPRESS_TYPES - 1); return -EUCLEAN; } - if (unlikely(btrfs_file_extent_encryption(leaf, fi))) { + policy = btrfs_file_extent_encryption(leaf, fi); + if (unlikely(policy >= BTRFS_NR_ENCRYPTION_TYPES)) { file_extent_err(leaf, slot, - "invalid encryption for file extent, have %u expect 0", - btrfs_file_extent_encryption(leaf, fi)); + "invalid encryption for file extent, have %u expect range [0, %u]", + policy, BTRFS_NR_ENCRYPTION_TYPES - 1); return -EUCLEAN; } if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) { diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index c1fd4ef2dd8b..404577383513 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4628,6 +4628,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans, u64 extent_offset = em->start - em->orig_start; u64 block_len; int ret; + u8 encryption = BTRFS_ENCRYPTION_NONE; btrfs_set_stack_file_extent_generation(&fi, trans->transid); if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) @@ -4649,6 +4650,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans, btrfs_set_stack_file_extent_num_bytes(&fi, em->len); btrfs_set_stack_file_extent_ram_bytes(&fi, em->ram_bytes); btrfs_set_stack_file_extent_compression(&fi, em->compress_type); + btrfs_set_stack_file_extent_encryption(&fi, encryption); ret = log_extent_csums(trans, inode, log, em, ctx); if (ret) diff --git a/include/uapi/linux/btrfs_tree.h b/include/uapi/linux/btrfs_tree.h index ef796a3cf387..e5a4ba9573a0 100644 --- a/include/uapi/linux/btrfs_tree.h +++ b/include/uapi/linux/btrfs_tree.h @@ -1093,8 +1093,14 @@ struct btrfs_file_extent_item { * but not for stat. */ __u8 compression; + + /* + * Type of encryption in use. Unencrypted value is 0. + */ __u8 encryption; - __le16 other_encoding; /* spare for later use */ + + /* spare for later use */ + __le16 other_encoding; /* are we inline data or a real extent? */ __u8 type; From patchwork Tue Oct 10 20:40:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416082 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 D9074CD8CB9 for ; Tue, 10 Oct 2023 20:41:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234380AbjJJUll (ORCPT ); Tue, 10 Oct 2023 16:41:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343870AbjJJUlb (ORCPT ); Tue, 10 Oct 2023 16:41:31 -0400 Received: from mail-yw1-x112d.google.com (mail-yw1-x112d.google.com [IPv6:2607:f8b0:4864:20::112d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18CDBB7 for ; Tue, 10 Oct 2023 13:41:29 -0700 (PDT) Received: by mail-yw1-x112d.google.com with SMTP id 00721157ae682-5a7cc03dee5so10200247b3.3 for ; Tue, 10 Oct 2023 13:41:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970488; x=1697575288; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1EC2BrZuJgY6Pyv2LPz1FwiqkAGFlRQStgxYqSpmtjY=; b=KciDVe0BmNdpsSYiITSIC1t46vSHpqOLYnXmQKolLUv8q5hLck0kvE3Ts3v/5NuiRj VAAdjB/5byZifwSVkIzO7saBtqtFYi61/1YqNKzI7gci+RpjOQMFarIoE3XVYwr33lJ3 UeBpIbQFkX9zbKp/MpvZpLX/ko+hnh+vsIef/ImUHArGAblHFeCG6sP5DtAOsEY5/s63 c8ZPa2i9Q/DjuW3qJNeUHYlQYEtvewG9JKAP+GXxU3JX6Ttjde2Hsu7sv5JJXuBRAsTc 0uPokunc6sQTQdlDQw305D1dZ2iU+2I6e55l7qX57bFLLFh/J+bwKbl+Gm0FtdSYgx0k YgQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970488; x=1697575288; 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=1EC2BrZuJgY6Pyv2LPz1FwiqkAGFlRQStgxYqSpmtjY=; b=KBuv6KCEOWiTF1p8Zatw458eDNGMKnJBDMr9ihYwjTl6zBeUt80t1hK/gK8XqPVDPl g8PCVAntFvEQ3HAnLU8JpQjx87alQqDgpWFykFTCnvcdhfP0Z3WCd0VqpYlNK9OFusfe i8SVJFULfCjo9kqzaDKuII6yx3luA3rWufGmTYrXjMh6c6I4e5+z9H8vUUscT+hbn04i qZ3K2IYMdishfzBW1Tj5Z85FBxtp89i7eThlv0nNj9+/b0xuQihmjsIvGNlic25pOQ3c 8x2r5JT+MPDZIU8FFwOsczsoMX7kf/TVOhVFBg4KvmYUwUKBxNtC4kkz+LCBItCjbs6/ rJtA== X-Gm-Message-State: AOJu0YwLxHvqjt+yN/Zz7ht1cQe/KI712QLKPTeBWKSQ40MzuFqq4Wg6 61XSZNu+Hm6Jyprril0/3sgKjq3Gx8VimAvAugy4gA== X-Google-Smtp-Source: AGHT+IFZBWYMLQeNss3gw/Ul9R7Tza2pWdWzmtSWr0lxioEjdRkFxCn3chbdc9TMwYm6u6KbmN8wTg== X-Received: by 2002:a0d:d40d:0:b0:5a7:c1f1:24b with SMTP id w13-20020a0dd40d000000b005a7c1f1024bmr3132014ywd.22.1696970488166; Tue, 10 Oct 2023 13:41:28 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id fd13-20020a05690c318d00b0058c8b1ddcc1sm1025429ywb.15.2023.10.10.13.41.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:27 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Sweet Tea Dorminy Subject: [PATCH v2 21/36] btrfs: add fscrypt_info and encryption_type to extent_map Date: Tue, 10 Oct 2023 16:40:36 -0400 Message-ID: <4cd0e0a3fee883dde7a1127dc0c602b610687216.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Sweet Tea Dorminy Each extent_map will end up with a pointer to its associated fscrypt_info if any, which should have the same lifetime as the extent_map. We are also going to need to track the encryption_type for the file extent items. Add the fscrypt_info to the extent_map, and the subsequent code for transferring it in the split and merge cases, as well as the code necessary to free them. A future patch will add the code to load them as appropriate. Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/extent_map.c | 32 +++++++++++++++++++++++++++++--- fs/btrfs/extent_map.h | 2 ++ fs/btrfs/file-item.c | 1 + fs/btrfs/inode.c | 1 + 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index af5ff6b10865..8c8023388758 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -61,6 +61,7 @@ struct extent_map *alloc_extent_map(void) static void __free_extent_map(struct extent_map *em) { + fscrypt_put_extent_info(em->fscrypt_info); if (test_bit(EXTENT_FLAG_FS_MAPPING, &em->flags)) kfree(em->map_lookup); kmem_cache_free(extent_map_cache, em); @@ -103,12 +104,24 @@ void free_extent_map_safe(struct extent_map_tree *tree, if (!em) return; - if (refcount_dec_and_test(&em->refs)) { - WARN_ON(extent_map_in_tree(em)); - WARN_ON(!list_empty(&em->list)); + if (!refcount_dec_and_test(&em->refs)) + return; + + WARN_ON(extent_map_in_tree(em)); + WARN_ON(!list_empty(&em->list)); + + /* + * We could take a lock freeing the fscrypt_info, so add this to the + * list of freed_extents to be freed later. + */ + if (em->fscrypt_info) { list_add_tail(&em->free_list, &tree->freed_extents); set_bit(EXTENT_MAP_TREE_PENDING_FREES, &tree->flags); + return; } + + /* Nothing scary here, just free the object. */ + __free_extent_map(em); } /* @@ -274,6 +287,12 @@ static int mergable_maps(struct extent_map *prev, struct extent_map *next) if (!list_empty(&prev->list) || !list_empty(&next->list)) return 0; + /* + * Don't merge adjacent encrypted maps. + */ + if (prev->fscrypt_info || next->fscrypt_info) + return 0; + ASSERT(next->block_start != EXTENT_MAP_DELALLOC && prev->block_start != EXTENT_MAP_DELALLOC); @@ -884,6 +903,8 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end, split->generation = gen; split->flags = flags; split->compress_type = em->compress_type; + split->fscrypt_info = + fscrypt_get_extent_info(em->fscrypt_info); replace_extent_mapping(em_tree, em, split, modified); free_extent_map(split); split = split2; @@ -925,6 +946,8 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end, split->orig_block_len = 0; } + split->fscrypt_info = + fscrypt_get_extent_info(em->fscrypt_info); if (extent_map_in_tree(em)) { replace_extent_mapping(em_tree, em, split, modified); @@ -1087,6 +1110,7 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre, split_pre->flags = flags; split_pre->compress_type = em->compress_type; split_pre->generation = em->generation; + split_pre->fscrypt_info = fscrypt_get_extent_info(em->fscrypt_info); replace_extent_mapping(em_tree, em, split_pre, 1); @@ -1106,6 +1130,8 @@ int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre, split_mid->flags = flags; split_mid->compress_type = em->compress_type; split_mid->generation = em->generation; + split_mid->fscrypt_info = fscrypt_get_extent_info(em->fscrypt_info); + add_extent_mapping(em_tree, split_mid, 1); /* Once for us */ diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index 2093720271ea..2d618e61ceb5 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h @@ -50,10 +50,12 @@ struct extent_map { */ u64 generation; unsigned long flags; + struct fscrypt_extent_info *fscrypt_info; /* Used for chunk mappings, flag EXTENT_FLAG_FS_MAPPING must be set */ struct map_lookup *map_lookup; refcount_t refs; unsigned int compress_type; + unsigned int encryption_type; struct list_head list; struct list_head free_list; }; diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index 45cae356e89b..26f35c1baedc 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c @@ -1305,6 +1305,7 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode, if (type == BTRFS_FILE_EXTENT_PREALLOC) set_bit(EXTENT_FLAG_PREALLOC, &em->flags); } + em->encryption_type = btrfs_file_extent_encryption(leaf, fi); } else if (type == BTRFS_FILE_EXTENT_INLINE) { em->block_start = EXTENT_MAP_INLINE; em->start = extent_start; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9cb8b82ff8be..19087fd68cfe 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7348,6 +7348,7 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start, set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); em->compress_type = compress_type; } + em->encryption_type = BTRFS_ENCRYPTION_NONE; ret = btrfs_replace_extent_map_range(inode, em, true); if (ret) { From patchwork Tue Oct 10 20:40:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416080 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 5AAB0CD6119 for ; Tue, 10 Oct 2023 20:41:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343763AbjJJUlm (ORCPT ); Tue, 10 Oct 2023 16:41:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343877AbjJJUlb (ORCPT ); Tue, 10 Oct 2023 16:41:31 -0400 Received: from mail-yw1-x1129.google.com (mail-yw1-x1129.google.com [IPv6:2607:f8b0:4864:20::1129]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 343E0CF for ; Tue, 10 Oct 2023 13:41:30 -0700 (PDT) Received: by mail-yw1-x1129.google.com with SMTP id 00721157ae682-5a7a80a96dbso2372217b3.0 for ; Tue, 10 Oct 2023 13:41:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970489; x=1697575289; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=2ArA+KNwLCyPHyCWg2jFGlY7QnT4oxTkF7KGMAsgrns=; b=o2WL9M6vvqd7ihKlp6i8le3L2CKa/M/xEZz9f+WL0MXJwELDCjxT8tYS0Zv/tPZN1Z suvZL6ouyf0CJ1o77TNYilL0e5ZYEQr5JL4lIP6x/mggNmSh8frRqzWH5aXViLEP6uNr zSLNrHA9OWRyrTIvpbA31jAqJvtU33GvB5t07XBzahE0Pw0L3+VU7Cr8mBeaANopdqbo X2+6Ek4VHZhaPyzM6cO9f0BHWTwYXTBkOiKiFyBQ50Kb2sAhcQKhT4VamC1Jb8n6uxEr 6P4qPDDNdc7pCO3haJIDqaDdPKCiG0bcsuEVkKTXTAMMv7lViKC3hq1X2jgaUJU21jOw GQTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970489; x=1697575289; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2ArA+KNwLCyPHyCWg2jFGlY7QnT4oxTkF7KGMAsgrns=; b=vJT5wlhix7n7N7nvS65E1b58ca5kKxRqOA7odffJGxyCA/jD/QjWATzAt4kMmWT//7 5U6OV0UpDBCgAMZgarKuCeFypcnWyZwKnB3ksftzia9rR6EJvJP/ynhOY8rDAts1xv9M SXvf7KF/aHY7NaB0bTOdqaH8lExfxlipOuFEHiigfK2cJHM1O5c+CPVftiufS9igz9qC jyTWUxxyuB1Xj5yazsV9C30uLGtYtD9jI5qNuTNy8aIV4kDH4Zhh5Valhl2xNWZ94zK9 4EKSfs1BqZjF/vw/sEaZ7/+odyLSHm01eYldhSrigMPWn+acZnPSMXjoiyyujTQKZxBH BizA== X-Gm-Message-State: AOJu0YyuXYhtI602ciO8pd32nDnrkg8KgmixYEU6Ysj4Tm8q1kUxfpew T+EDIEIBDd+PqIMUKs7t/DJDkeyW2DiHJhdE4PuzOw== X-Google-Smtp-Source: AGHT+IGUwHW7MYnoeP/dUvp25r3xI4PmEhHYpQU8QAPvDlaswQa2zIfybQy44nS3z71zlssTqD9QZQ== X-Received: by 2002:a0d:d6d6:0:b0:5a7:bfc6:96aa with SMTP id y205-20020a0dd6d6000000b005a7bfc696aamr2241530ywd.7.1696970489302; Tue, 10 Oct 2023 13:41:29 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id w1-20020a81a201000000b005837633d9cbsm4555416ywg.64.2023.10.10.13.41.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:28 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 22/36] btrfs: add fscrypt_info and encryption_type to ordered_extent Date: Tue, 10 Oct 2023 16:40:37 -0400 Message-ID: <4e70e172d8acb37626497837f5105eaa0ef94b9c.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org We're going to need these to update the file extent items once the writes are complete. Add them and add the pieces necessary to assign them and free everything. Signed-off-by: Josef Bacik --- fs/btrfs/ordered-data.c | 2 ++ fs/btrfs/ordered-data.h | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 574e8a55e24a..27350dd50828 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -181,6 +181,7 @@ static struct btrfs_ordered_extent *alloc_ordered_extent( entry->bytes_left = num_bytes; entry->inode = igrab(&inode->vfs_inode); entry->compress_type = compress_type; + entry->encryption_type = BTRFS_ENCRYPTION_NONE; entry->truncated_len = (u64)-1; entry->qgroup_rsv = ret; entry->flags = flags; @@ -564,6 +565,7 @@ void btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry) list_del(&sum->list); kvfree(sum); } + fscrypt_put_extent_info(entry->fscrypt_info); kmem_cache_free(btrfs_ordered_extent_cache, entry); } } diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index 567a6d3d4712..cc422bdb5363 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -115,6 +115,9 @@ struct btrfs_ordered_extent { /* compression algorithm */ int compress_type; + /* encryption mode */ + int encryption_type; + /* Qgroup reserved space */ int qgroup_rsv; @@ -124,6 +127,9 @@ struct btrfs_ordered_extent { /* the inode we belong to */ struct inode *inode; + /* the fscrypt_info for this extent, if necessary */ + struct fscrypt_extent_info *fscrypt_info; + /* list of checksums for insertion when the extent io is done */ struct list_head list; From patchwork Tue Oct 10 20:40:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416083 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 C1B56CD690D for ; Tue, 10 Oct 2023 20:41:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343964AbjJJUlp (ORCPT ); Tue, 10 Oct 2023 16:41:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42410 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234697AbjJJUld (ORCPT ); Tue, 10 Oct 2023 16:41:33 -0400 Received: from mail-yw1-x112c.google.com (mail-yw1-x112c.google.com [IPv6:2607:f8b0:4864:20::112c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6144FD8 for ; Tue, 10 Oct 2023 13:41:31 -0700 (PDT) Received: by mail-yw1-x112c.google.com with SMTP id 00721157ae682-5a7c7262d5eso11151337b3.1 for ; Tue, 10 Oct 2023 13:41:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970490; x=1697575290; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ERZNY9yAu05NkeMS9bd2xgIAJNON/dSqVc7gEbsmsV8=; b=cPUh2c1HVZOVUdL8SOt6cfyx2mY2M3UXb1ecxW3dmIWdRG152mvXN4AeFWDyqGYpgh KcU2ILgCODxQ4D5rbx+2AHHCs4O/VfsS/USzUhFuSBSMoFhY795llZ9YH6jQpwqcejft RzYGoY5KwZ1lE7EIqaTzprD5T4DYs/igzImvWoHPdJg0PdPcPk6QaVtoxlI172r4miun 70Hi/XneHNjcLVFlIRaAW3dubTv3GzWutmq4GeU+8AvvmGAQk+SefdtzYRIHQp8vguqI B/Q8fuRXbkmui8mLjy3Te/Vjw0nRWB8XdDQOxEMPvj4KldF5+Z7TzOU9k45HNJNzhLGb uYeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970490; x=1697575290; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ERZNY9yAu05NkeMS9bd2xgIAJNON/dSqVc7gEbsmsV8=; b=MXCq5gsMbGCECCzCSbYFJq4xnIDCdHkU5e4gquuhpRf+6c+zksrXQg3ef2ZKCEA+ZZ Ou/MQOs/pqA1dUQFgq1cKAWrrkzXqRhPK6/Qlh+x7kLXkk+WPBgqSIZXNAIoIa9qCPDY cOKb6V6CiffGaYO6cY8M/104lIKG4TK0WKaycl7aqJ3tJZRimifm8sETvBC/Y2k0VFh0 ehRNmVR154RS3ET85A4UWYs5fhE36CqceiNQcNDykSbqDa7z0LiU6ARwOGfMsUN/M1HR mN70nXMYWG4WrECHqT+ZVfGQbBIeGUaNRNIY9nwcg7EKprEwq5aWrGLlTMh4ODMyFb1E Szew== X-Gm-Message-State: AOJu0Yw/EPSFsrAKB2Lh429vDI9rAkE8Asf1dEbrgUQsT+nw36hUT60e g+y5f7GvygjsIgYZyL7ZeDXSwjM2wafg8v5jhIjovg== X-Google-Smtp-Source: AGHT+IF7/z/S168KAzn9DO55LFcQQlzXi4bySDC4Vlz/fRLEbLWZbWGDIwM/gnSuSecVPQ7Fzk/OHA== X-Received: by 2002:a81:8482:0:b0:5a7:bc79:9618 with SMTP id u124-20020a818482000000b005a7bc799618mr3229187ywf.12.1696970490302; Tue, 10 Oct 2023 13:41:30 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id u66-20020a818445000000b00577269ba9e9sm4629194ywf.86.2023.10.10.13.41.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:30 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 23/36] btrfs: plumb through setting the fscrypt_info for ordered extents Date: Tue, 10 Oct 2023 16:40:38 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org We're going to be getting fscrypt_info from the extent maps, update the helpers to take an fscrypt_info argument and use that to set the encryption type on the ordered extent. Signed-off-by: Josef Bacik --- fs/btrfs/inode.c | 20 +++++++++++--------- fs/btrfs/ordered-data.c | 32 ++++++++++++++++++++------------ fs/btrfs/ordered-data.h | 9 +++++---- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 19087fd68cfe..a1fa5b6f3790 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1162,7 +1162,8 @@ static void submit_one_async_extent(struct async_chunk *async_chunk, } free_extent_map(em); - ordered = btrfs_alloc_ordered_extent(inode, start, /* file_offset */ + ordered = btrfs_alloc_ordered_extent(inode, NULL, + start, /* file_offset */ async_extent->ram_size, /* num_bytes */ async_extent->ram_size, /* ram_bytes */ ins.objectid, /* disk_bytenr */ @@ -1425,9 +1426,10 @@ static noinline int cow_file_range(struct btrfs_inode *inode, } free_extent_map(em); - ordered = btrfs_alloc_ordered_extent(inode, start, ram_size, - ram_size, ins.objectid, cur_alloc_size, - 0, 1 << BTRFS_ORDERED_REGULAR, + ordered = btrfs_alloc_ordered_extent(inode, NULL, + start, ram_size, ram_size, ins.objectid, + cur_alloc_size, 0, + 1 << BTRFS_ORDERED_REGULAR, BTRFS_COMPRESS_NONE); if (IS_ERR(ordered)) { ret = PTR_ERR(ordered); @@ -2158,7 +2160,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode, free_extent_map(em); } - ordered = btrfs_alloc_ordered_extent(inode, cur_offset, + ordered = btrfs_alloc_ordered_extent(inode, NULL, cur_offset, nocow_args.num_bytes, nocow_args.num_bytes, nocow_args.disk_bytenr, nocow_args.num_bytes, 0, is_prealloc @@ -7040,7 +7042,7 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode, if (IS_ERR(em)) goto out; } - ordered = btrfs_alloc_ordered_extent(inode, start, len, len, + ordered = btrfs_alloc_ordered_extent(inode, NULL, start, len, len, block_start, block_len, 0, (1 << type) | (1 << BTRFS_ORDERED_DIRECT), @@ -10512,9 +10514,9 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, } free_extent_map(em); - ordered = btrfs_alloc_ordered_extent(inode, start, num_bytes, ram_bytes, - ins.objectid, ins.offset, - encoded->unencoded_offset, + ordered = btrfs_alloc_ordered_extent(inode, NULL, start, + num_bytes, ram_bytes, ins.objectid, + ins.offset, encoded->unencoded_offset, (1 << BTRFS_ORDERED_ENCODED) | (1 << BTRFS_ORDERED_COMPRESSED), compression); diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 27350dd50828..ee3138a6d11e 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -146,9 +146,11 @@ static inline struct rb_node *ordered_tree_search(struct btrfs_inode *inode, } static struct btrfs_ordered_extent *alloc_ordered_extent( - struct btrfs_inode *inode, u64 file_offset, u64 num_bytes, - u64 ram_bytes, u64 disk_bytenr, u64 disk_num_bytes, - u64 offset, unsigned long flags, int compress_type) + struct btrfs_inode *inode, + struct fscrypt_extent_info *fscrypt_info, + u64 file_offset, u64 num_bytes, u64 ram_bytes, + u64 disk_bytenr, u64 disk_num_bytes, u64 offset, + unsigned long flags, int compress_type) { struct btrfs_ordered_extent *entry; int ret; @@ -181,10 +183,12 @@ static struct btrfs_ordered_extent *alloc_ordered_extent( entry->bytes_left = num_bytes; entry->inode = igrab(&inode->vfs_inode); entry->compress_type = compress_type; - entry->encryption_type = BTRFS_ENCRYPTION_NONE; entry->truncated_len = (u64)-1; entry->qgroup_rsv = ret; entry->flags = flags; + entry->fscrypt_info = fscrypt_get_extent_info(fscrypt_info); + entry->encryption_type = entry->fscrypt_info ? + BTRFS_ENCRYPTION_FSCRYPT : BTRFS_ENCRYPTION_NONE; refcount_set(&entry->refs, 1); init_waitqueue_head(&entry->wait); INIT_LIST_HEAD(&entry->list); @@ -247,6 +251,7 @@ static void insert_ordered_extent(struct btrfs_ordered_extent *entry) * Add an ordered extent to the per-inode tree. * * @inode: Inode that this extent is for. + * @fscrypt_info: The fscrypt_extent_info for this extent, if necessary. * @file_offset: Logical offset in file where the extent starts. * @num_bytes: Logical length of extent in file. * @ram_bytes: Full length of unencoded data. @@ -263,17 +268,19 @@ static void insert_ordered_extent(struct btrfs_ordered_extent *entry) * Return: the new ordered extent or error pointer. */ struct btrfs_ordered_extent *btrfs_alloc_ordered_extent( - struct btrfs_inode *inode, u64 file_offset, - u64 num_bytes, u64 ram_bytes, u64 disk_bytenr, - u64 disk_num_bytes, u64 offset, unsigned long flags, - int compress_type) + struct btrfs_inode *inode, + struct fscrypt_extent_info *fscrypt_info, + u64 file_offset, u64 num_bytes, u64 ram_bytes, + u64 disk_bytenr, u64 disk_num_bytes, u64 offset, + unsigned long flags, int compress_type) { struct btrfs_ordered_extent *entry; ASSERT((flags & ~BTRFS_ORDERED_TYPE_FLAGS) == 0); - entry = alloc_ordered_extent(inode, file_offset, num_bytes, ram_bytes, - disk_bytenr, disk_num_bytes, offset, flags, + entry = alloc_ordered_extent(inode, fscrypt_info, file_offset, + num_bytes, ram_bytes, disk_bytenr, + disk_num_bytes, offset, flags, compress_type); if (!IS_ERR(entry)) insert_ordered_extent(entry); @@ -1166,8 +1173,9 @@ struct btrfs_ordered_extent *btrfs_split_ordered_extent( if (WARN_ON_ONCE(ordered->disk_num_bytes != ordered->num_bytes)) return ERR_PTR(-EINVAL); - new = alloc_ordered_extent(inode, file_offset, len, len, disk_bytenr, - len, 0, flags, ordered->compress_type); + new = alloc_ordered_extent(inode, ordered->fscrypt_info, file_offset, + len, len, disk_bytenr, len, 0, flags, + ordered->compress_type); if (IS_ERR(new)) return new; diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index cc422bdb5363..767efcd74bee 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -170,10 +170,11 @@ bool btrfs_dec_test_ordered_pending(struct btrfs_inode *inode, struct btrfs_ordered_extent **cached, u64 file_offset, u64 io_size); struct btrfs_ordered_extent *btrfs_alloc_ordered_extent( - struct btrfs_inode *inode, u64 file_offset, - u64 num_bytes, u64 ram_bytes, u64 disk_bytenr, - u64 disk_num_bytes, u64 offset, unsigned long flags, - int compress_type); + struct btrfs_inode *inode, + struct fscrypt_extent_info *fscrypt_info, + u64 file_offset, u64 num_bytes, u64 ram_bytes, + u64 disk_bytenr, u64 disk_num_bytes, u64 offset, + unsigned long flags, int compress_type); void btrfs_add_ordered_sum(struct btrfs_ordered_extent *entry, struct btrfs_ordered_sum *sum); struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct btrfs_inode *inode, From patchwork Tue Oct 10 20:40:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416088 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 9777FCD8CBF for ; Tue, 10 Oct 2023 20:41:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344078AbjJJUlw (ORCPT ); Tue, 10 Oct 2023 16:41:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42336 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234658AbjJJUle (ORCPT ); Tue, 10 Oct 2023 16:41:34 -0400 Received: from mail-yw1-x112b.google.com (mail-yw1-x112b.google.com [IPv6:2607:f8b0:4864:20::112b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7A43599 for ; Tue, 10 Oct 2023 13:41:32 -0700 (PDT) Received: by mail-yw1-x112b.google.com with SMTP id 00721157ae682-5a7be61fe74so15051037b3.2 for ; Tue, 10 Oct 2023 13:41:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970491; x=1697575291; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=sdhOZSbLFAWHbBthhX//NAxRHhPvITLPW+kiDV9DiQg=; b=sp6CPy/26n8gHxHHSCotJawUvMkZy6hWKQR+AhonHZYtDuUxYg7mdUfqCAfzhQl9LN GmhKsU2TY65KrxsR2rtnWrrlQBCcZwOWTI829yt11u6t3cnmCEOAvOAto8iJLEfzKtuj D9GMQPjBomF9CCwhtWdvgESqJRQHgWdVUV774isGY+ir9hI+tRWc5EPLb0/JYG+w6aMp 8nu4NgQHCL4wAfZVuIyjXIMYpA3tTBnPeURoeQ+LSmF38OZ6+F5wZJjDiZ7da7x54pbf e7SOPe/CtvqgvkX17M7EhNXEvKoxZFfQMIZVJF7v5d8pxv9C14BbvG05dFZWf94W1uyt Frrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970491; x=1697575291; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sdhOZSbLFAWHbBthhX//NAxRHhPvITLPW+kiDV9DiQg=; b=K3HvqDU0PHlil4Xe9pXVRHgf3rEa1JxtB2AJml9NDTYYQe4l+fxEhXt7U7wBwk9u0x Gs49CF2cFGVMyKn3MzZtMCQNCtA+CItkA3e87uX32E/ex/S6hpbKzvyN8i0oSZjxMVFi Nzi1OtsHRUgGNSynPOQbnppBoNX2G+5ieaSj3TVBYVFuDsIdOUxt8cT83N/VUL7KCJVM v0z4lHOlJgKJvWuh1UVoE0Z0Y3MKSdrZlVMt+8wHldPhwwGp6bKeK+81QEgOy0yVJUrc 1Wqp1UCwObRtUZlbMY5jcyci3HC48h/YVyiZ/2dnOMDALoj8KcFQu+cLefG6+ANBp2b1 rdKg== X-Gm-Message-State: AOJu0YxLxnygl9y5A5cchoyCHSUZ4AZEAagWpa3jXNxGkSi633ECkAy1 V5FDb37XsQAw4/n3u/fRaMh7v68OVAvUnottphLd2w== X-Google-Smtp-Source: AGHT+IHnTLGLwEyh2iAbLqOo80QF5NP0kF4Lmdo9qoe7odEnvcx6u3ZFvtjfAR8OxuNM5M7rwGKwug== X-Received: by 2002:a05:690c:250e:b0:5a7:a959:338 with SMTP id dt14-20020a05690c250e00b005a7a9590338mr4624617ywb.13.1696970491555; Tue, 10 Oct 2023 13:41:31 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id z17-20020a0dd711000000b0057087e7691bsm472534ywd.56.2023.10.10.13.41.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:31 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 24/36] btrfs: populate the ordered_extent with the fscrypt context Date: Tue, 10 Oct 2023 16:40:39 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org The fscrypt_extent_info will be tied to the extent_map lifetime, so it will be created when we create the IO em, or it'll already exist in the NOCOW case. Use this fscrypt_info when creating the ordered extent to make sure everything is passed through properly. Signed-off-by: Josef Bacik --- fs/btrfs/inode.c | 62 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a1fa5b6f3790..7d859e327485 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1160,9 +1160,8 @@ static void submit_one_async_extent(struct async_chunk *async_chunk, ret = PTR_ERR(em); goto out_free_reserve; } - free_extent_map(em); - ordered = btrfs_alloc_ordered_extent(inode, NULL, + ordered = btrfs_alloc_ordered_extent(inode, em->fscrypt_info, start, /* file_offset */ async_extent->ram_size, /* num_bytes */ async_extent->ram_size, /* ram_bytes */ @@ -1171,6 +1170,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk, 0, /* offset */ 1 << BTRFS_ORDERED_COMPRESSED, async_extent->compress_type); + free_extent_map(em); if (IS_ERR(ordered)) { btrfs_drop_extent_map_range(inode, start, end, false); ret = PTR_ERR(ordered); @@ -1424,13 +1424,13 @@ static noinline int cow_file_range(struct btrfs_inode *inode, ret = PTR_ERR(em); goto out_reserve; } - free_extent_map(em); - ordered = btrfs_alloc_ordered_extent(inode, NULL, + ordered = btrfs_alloc_ordered_extent(inode, em->fscrypt_info, start, ram_size, ram_size, ins.objectid, cur_alloc_size, 0, 1 << BTRFS_ORDERED_REGULAR, BTRFS_COMPRESS_NONE); + free_extent_map(em); if (IS_ERR(ordered)) { ret = PTR_ERR(ordered); goto out_drop_extent_cache; @@ -2003,6 +2003,8 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode, struct btrfs_key found_key; struct btrfs_file_extent_item *fi; struct extent_buffer *leaf; + struct extent_map *em = NULL; + struct fscrypt_extent_info *fscrypt_info = NULL; u64 extent_end; u64 ram_bytes; u64 nocow_end; @@ -2143,7 +2145,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode, is_prealloc = extent_type == BTRFS_FILE_EXTENT_PREALLOC; if (is_prealloc) { u64 orig_start = found_key.offset - nocow_args.extent_offset; - struct extent_map *em; em = create_io_em(inode, cur_offset, nocow_args.num_bytes, orig_start, @@ -2157,16 +2158,32 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode, ret = PTR_ERR(em); goto error; } - free_extent_map(em); + fscrypt_info = em->fscrypt_info; + } else if (IS_ENCRYPTED(&inode->vfs_inode)) { + /* + * We only want to do this lookup if we're encrypted, + * otherwise fsrypt_info will be null and we can avoid + * this lookup. + */ + em = btrfs_get_extent(inode, NULL, 0, cur_offset, + nocow_args.num_bytes); + if (IS_ERR(em)) { + btrfs_dec_nocow_writers(nocow_bg); + ret = PTR_ERR(em); + goto error; + } + fscrypt_info = em->fscrypt_info; } - ordered = btrfs_alloc_ordered_extent(inode, NULL, cur_offset, - nocow_args.num_bytes, nocow_args.num_bytes, - nocow_args.disk_bytenr, nocow_args.num_bytes, 0, + ordered = btrfs_alloc_ordered_extent(inode, fscrypt_info, + cur_offset, nocow_args.num_bytes, + nocow_args.num_bytes, nocow_args.disk_bytenr, + nocow_args.num_bytes, 0, is_prealloc ? (1 << BTRFS_ORDERED_PREALLOC) : (1 << BTRFS_ORDERED_NOCOW), BTRFS_COMPRESS_NONE); + free_extent_map(em); btrfs_dec_nocow_writers(nocow_bg); if (IS_ERR(ordered)) { if (is_prealloc) { @@ -7022,6 +7039,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode, struct btrfs_dio_data *dio_data, + struct extent_map *orig_em, const u64 start, const u64 len, const u64 orig_start, @@ -7033,6 +7051,7 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode, { struct extent_map *em = NULL; struct btrfs_ordered_extent *ordered; + struct fscrypt_extent_info *fscrypt_info = NULL; if (type != BTRFS_ORDERED_NOCOW) { em = create_io_em(inode, start, len, orig_start, block_start, @@ -7041,9 +7060,13 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode, type); if (IS_ERR(em)) goto out; + fscrypt_info = em->fscrypt_info; + } else { + fscrypt_info = orig_em->fscrypt_info; } - ordered = btrfs_alloc_ordered_extent(inode, NULL, start, len, len, - block_start, block_len, 0, + + ordered = btrfs_alloc_ordered_extent(inode, fscrypt_info, start, len, + len, block_start, block_len, 0, (1 << type) | (1 << BTRFS_ORDERED_DIRECT), BTRFS_COMPRESS_NONE); @@ -7080,9 +7103,10 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode, if (ret) return ERR_PTR(ret); - em = btrfs_create_dio_extent(inode, dio_data, start, ins.offset, start, - ins.objectid, ins.offset, ins.offset, - ins.offset, BTRFS_ORDERED_REGULAR); + em = btrfs_create_dio_extent(inode, dio_data, NULL, start, ins.offset, + start, ins.objectid, ins.offset, + ins.offset, ins.offset, + BTRFS_ORDERED_REGULAR); btrfs_dec_block_group_reservations(fs_info, ins.objectid); if (IS_ERR(em)) btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset, @@ -7426,9 +7450,9 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map, } space_reserved = true; - em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, len, - orig_start, block_start, - len, orig_block_len, + em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, em, + start, len, orig_start, + block_start, len, orig_block_len, ram_bytes, type); btrfs_dec_nocow_writers(bg); if (type == BTRFS_ORDERED_PREALLOC) { @@ -10512,14 +10536,14 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, ret = PTR_ERR(em); goto out_free_reserved; } - free_extent_map(em); - ordered = btrfs_alloc_ordered_extent(inode, NULL, start, + ordered = btrfs_alloc_ordered_extent(inode, em->fscrypt_info, start, num_bytes, ram_bytes, ins.objectid, ins.offset, encoded->unencoded_offset, (1 << BTRFS_ORDERED_ENCODED) | (1 << BTRFS_ORDERED_COMPRESSED), compression); + free_extent_map(em); if (IS_ERR(ordered)) { btrfs_drop_extent_map_range(inode, start, end, false); ret = PTR_ERR(ordered); From patchwork Tue Oct 10 20:40:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416085 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 09E84CD6119 for ; Tue, 10 Oct 2023 20:41:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344040AbjJJUlt (ORCPT ); Tue, 10 Oct 2023 16:41:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234732AbjJJUlk (ORCPT ); Tue, 10 Oct 2023 16:41:40 -0400 Received: from mail-yb1-xb2e.google.com (mail-yb1-xb2e.google.com [IPv6:2607:f8b0:4864:20::b2e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 75016E0 for ; Tue, 10 Oct 2023 13:41:33 -0700 (PDT) Received: by mail-yb1-xb2e.google.com with SMTP id 3f1490d57ef6-d9a6b21d1daso1113735276.3 for ; Tue, 10 Oct 2023 13:41:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970492; x=1697575292; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=i20kOvsTj8UHy3VlsyWZ2ukU/TrpdD90cKWJsB2jbGw=; b=tKaYImHr/Wz1mFkxnqK8G5u50El9N79yut+Rm1gV0Sr8yqK7ZPUqoX+Xfw0bvXPwYf JT2KSvRrFvgBytUuUMgV5h9GHjTNSVIBTXhqusHL366RKyE8hEIx6jqdQIF4F10F7Nz+ QSJCecy6tonNO+dgcCuMvDFjzxxVxcbGgim2bc8ng16/0eJd17oVkciCe3howb7g8zAj NNaR9HiArTANgqNL1bySjA5WAICDUo2nyBQyqCRl+ml+9UmpHRLyN3KcwZbgtuAvjrwW i6Ewh/NPvsY9G1TLtAtehIxAK/4vJSkz1kzQBeqq7L1W/k/NdLXALkGgbZ8AWTPpZbQh /2zA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970492; x=1697575292; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=i20kOvsTj8UHy3VlsyWZ2ukU/TrpdD90cKWJsB2jbGw=; b=JgAaQraWYmwmoaptFsbKY9HS10wj+369DrBD2UilolhgzxrT7kjSr9eudc9Ii9ICse VaVQA49KFCx64lbbWtmY2qiVx1XarKIkKWVSDcRtFbwNisRdpiTii7eSfulJpSt6eZi/ LQ2Qo6WkMsAjaG8r6YExeEA+1Io+RlGngIuoSREZCzO+Uy/wQhzmF8PuPI6AAbQ2H7Cu xpdPFQ4brXHx3B2J2Z8qGDMSC/6EQmHFOHaXMoUDFOUJuen8EgWr22PCtkemg3jcDJBT gK2RD+Y+UqAbS+R2qjo+vRmQZ+RFzbVzuQ7Ozl8x5mx3Fn+vCQIzZcaidr8dVvUYii8R aZ+Q== X-Gm-Message-State: AOJu0Yy9w3b2I+Fdbi+8bFwrKpkIK4jpfA23nZBY2f8QsiP798ZssGsi E4HhPp0ZrmDjTbtNR3Nu9gx4xmWLoAcuEh3a63u03g== X-Google-Smtp-Source: AGHT+IF6/P0RC5ugj8FbxDoA6rzOYfZdz//IF5d8Y8n8HFMre6qnLlII9u3DC5bRx1NPrUOd5hh7SA== X-Received: by 2002:a25:654:0:b0:d81:599f:a538 with SMTP id 81-20020a250654000000b00d81599fa538mr16230001ybg.51.1696970492507; Tue, 10 Oct 2023 13:41:32 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id y7-20020a25ad07000000b00c64533e4e20sm502675ybi.33.2023.10.10.13.41.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:32 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 25/36] btrfs: keep track of fscrypt info and orig_start for dio reads Date: Tue, 10 Oct 2023 16:40:40 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org We keep track of this information in the ordered extent for writes, but we need it for reads as well. Add fscrypt_extent_info and orig_start to the dio_data so we can populate this on reads. This will be used later when we attach the fscrypt context to the bios. Signed-off-by: Josef Bacik --- fs/btrfs/inode.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 7d859e327485..d20ccfc5038f 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -83,6 +83,8 @@ struct btrfs_dio_data { ssize_t submitted; struct extent_changeset *data_reserved; struct btrfs_ordered_extent *ordered; + struct fscrypt_extent_info *fscrypt_info; + u64 orig_start; bool data_space_reserved; bool nocow_done; }; @@ -7727,6 +7729,10 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start, release_len); } } else { + dio_data->fscrypt_info = + fscrypt_get_extent_info(em->fscrypt_info); + dio_data->orig_start = em->orig_start; + /* * We need to unlock only the end area that we aren't using. * The rest is going to be unlocked by the endio routine. @@ -7808,6 +7814,11 @@ static int btrfs_dio_iomap_end(struct inode *inode, loff_t pos, loff_t length, dio_data->ordered = NULL; } + if (dio_data->fscrypt_info) { + fscrypt_put_extent_info(dio_data->fscrypt_info); + dio_data->fscrypt_info = NULL; + } + if (write) extent_changeset_free(dio_data->data_reserved); return ret; From patchwork Tue Oct 10 20:40:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416087 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 006C1CD8CB9 for ; Tue, 10 Oct 2023 20:41:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343823AbjJJUlv (ORCPT ); Tue, 10 Oct 2023 16:41:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45850 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234666AbjJJUlg (ORCPT ); Tue, 10 Oct 2023 16:41:36 -0400 Received: from mail-yw1-x112f.google.com (mail-yw1-x112f.google.com [IPv6:2607:f8b0:4864:20::112f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C682BA for ; Tue, 10 Oct 2023 13:41:34 -0700 (PDT) Received: by mail-yw1-x112f.google.com with SMTP id 00721157ae682-579de633419so74996277b3.3 for ; Tue, 10 Oct 2023 13:41:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970493; x=1697575293; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=NKfV0mKcd78LD0F5M7sHTMzeB633X8okqEPfgdPomZI=; b=wSeLYH8qSOP8DCgeRHGEdi+ovvHZlRPviKh3ftbSPwBVFZxdAGj8QdRBMTuiX7z8xu Y7GLI4KR5c3Qx+DUWwEKa1nqyM5CMwhqmZb865TTYnWkqHwysjkYliqiggKB7M8Akbdb 6AqLMX8/HyE9Mb1ZmibMKjGSaEnGvm1OwBw33gDw7yI0KfBC+k4lFSFZTUsrVPpOeGjQ Zfmd+Q7T/tGo40AwUDnFm1zxT3/xogf2OtY9oh3whw9RlSDZBLjgnEUY3SGhgTCCD2dH gZQ76oZDrFQZUG3ZZh93b+t4RPX47B1goBtqPNQ/57g7V7apqOl3eIfyYPe0myh4ap/u zXXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970493; x=1697575293; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NKfV0mKcd78LD0F5M7sHTMzeB633X8okqEPfgdPomZI=; b=fz4YgCtFxnvQrmiC51itUQ+gQU8TcSDa3RPTeHcTHgnoG5XVNF0B1QnarpTiY3derc iY1r90uK4yZ5Te1Nrwu5D0lo7HP5t4EQ+x0Zyi54SWU9laP8Wxs0q2IICZ6Ku3odqMel AF//YhyuI7vNbk5JRCsCiRc2CrERvcm4ZQqRGQThujku2JYZDbYVUcd2NMh5piD+T5cG 9yggwGPzqdv7oTxoIKjMo/Epei+/9xsU5YF/dUh5lM3CdIxU5dsHVOTRakwBaZHGN56d rl6BpOLAnJfSdXuloQFj64hgaiDr9E5X72+/a0tAPYD4E37tnNQFhFXut1I/GQ0fq6gB 2REQ== X-Gm-Message-State: AOJu0YyUhjTenlbLmYLSmJvOrNMu6xQQBtzY+QGWZ0ssOYn/PSqKdKfk qM+GneHC333MxoK3uoxJVqq0FlyRViMhmYQnBVq9Ew== X-Google-Smtp-Source: AGHT+IGzD8eE4ccFpvq+0Zb1MfG2ccpgcstraFCLPGLBmuyH6GgOZaY66pNZKwrTU6ioTPzfgJHHaA== X-Received: by 2002:a0d:d546:0:b0:58f:a19f:2b79 with SMTP id x67-20020a0dd546000000b0058fa19f2b79mr20760135ywd.9.1696970493506; Tue, 10 Oct 2023 13:41:33 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id ex5-20020a05690c2fc500b005a7a4e3816esm1213834ywb.89.2023.10.10.13.41.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:33 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 26/36] btrfs: add an optional encryption context to the end of file extents Date: Tue, 10 Oct 2023 16:40:41 -0400 Message-ID: <8f92ec76d56b2a4c56e34a91c6afdfdb5fc9fa45.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org The fscrypt encryption context can be extended to include different things in the future. To facilitate future expansion add an optional btrfs_encryption_info to the end of the file extent. This will hold the size of the context and then will have the binary context tacked onto the end of the extent item. Add the appropriate accessors to make it easy to read this information if we have encryption set, and then update the tree-checker to validate that if this is indeed set properly that the size matches properly. Signed-off-by: Josef Bacik --- fs/btrfs/accessors.h | 48 +++++++++++++++++++++++++++ fs/btrfs/tree-checker.c | 58 ++++++++++++++++++++++++++++----- include/uapi/linux/btrfs_tree.h | 17 +++++++++- 3 files changed, 113 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/accessors.h b/fs/btrfs/accessors.h index 5aaf204fa55f..a54a4671bd15 100644 --- a/fs/btrfs/accessors.h +++ b/fs/btrfs/accessors.h @@ -932,6 +932,10 @@ BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block, BTRFS_SETGET_STACK_FUNCS(super_nr_global_roots, struct btrfs_super_block, nr_global_roots, 64); +/* struct btrfs_file_extent_encryption_info */ +BTRFS_SETGET_FUNCS(encryption_info_size, struct btrfs_encryption_info, size, + 32); + /* struct btrfs_file_extent_item */ BTRFS_SETGET_STACK_FUNCS(stack_file_extent_type, struct btrfs_file_extent_item, type, 8); @@ -973,6 +977,50 @@ BTRFS_SETGET_FUNCS(file_extent_encryption, struct btrfs_file_extent_item, BTRFS_SETGET_FUNCS(file_extent_other_encoding, struct btrfs_file_extent_item, other_encoding, 16); +static inline struct btrfs_encryption_info *btrfs_file_extent_encryption_info( + const struct btrfs_file_extent_item *ei) +{ + unsigned long offset = (unsigned long)ei; + + offset += offsetof(struct btrfs_file_extent_item, encryption_info); + return (struct btrfs_encryption_info *)offset; +} + +static inline unsigned long btrfs_file_extent_encryption_ctx_offset( + const struct btrfs_file_extent_item *ei) +{ + unsigned long offset = (unsigned long)ei; + + offset += offsetof(struct btrfs_file_extent_item, encryption_info); + return offset + offsetof(struct btrfs_encryption_info, context); +} + +static inline u32 btrfs_file_extent_encryption_ctx_size( + const struct extent_buffer *eb, + const struct btrfs_file_extent_item *ei) +{ + return btrfs_encryption_info_size(eb, + btrfs_file_extent_encryption_info(ei)); +} + +static inline void btrfs_set_file_extent_encryption_ctx_size( + const struct extent_buffer *eb, + struct btrfs_file_extent_item *ei, + u32 val) +{ + btrfs_set_encryption_info_size(eb, + btrfs_file_extent_encryption_info(ei), + val); +} + +static inline u32 btrfs_file_extent_encryption_info_size( + const struct extent_buffer *eb, + const struct btrfs_file_extent_item *ei) +{ + return btrfs_encryption_info_size(eb, + btrfs_file_extent_encryption_info(ei)); +} + /* btrfs_qgroup_status_item */ BTRFS_SETGET_FUNCS(qgroup_status_generation, struct btrfs_qgroup_status_item, generation, 64); diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index 825b235927c6..0b671c1e96f1 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c @@ -211,6 +211,7 @@ static int check_extent_data_item(struct extent_buffer *leaf, u32 item_size = btrfs_item_size(leaf, slot); u64 extent_end; u8 policy; + u8 fe_type; if (unlikely(!IS_ALIGNED(key->offset, sectorsize))) { file_extent_err(leaf, slot, @@ -241,12 +242,12 @@ static int check_extent_data_item(struct extent_buffer *leaf, SZ_4K); return -EUCLEAN; } - if (unlikely(btrfs_file_extent_type(leaf, fi) >= - BTRFS_NR_FILE_EXTENT_TYPES)) { + + fe_type = btrfs_file_extent_type(leaf, fi); + if (unlikely(fe_type >= BTRFS_NR_FILE_EXTENT_TYPES)) { file_extent_err(leaf, slot, "invalid type for file extent, have %u expect range [0, %u]", - btrfs_file_extent_type(leaf, fi), - BTRFS_NR_FILE_EXTENT_TYPES - 1); + fe_type, BTRFS_NR_FILE_EXTENT_TYPES - 1); return -EUCLEAN; } @@ -295,12 +296,51 @@ static int check_extent_data_item(struct extent_buffer *leaf, return 0; } - /* Regular or preallocated extent has fixed item size */ - if (unlikely(item_size != sizeof(*fi))) { - file_extent_err(leaf, slot, + if (policy == BTRFS_ENCRYPTION_FSCRYPT) { + size_t fe_size = sizeof(*fi) + + sizeof(struct btrfs_encryption_info); + u32 ctxsize; + + if (unlikely(item_size < fe_size)) { + file_extent_err(leaf, slot, + "invalid item size for encrypted file extent, have %u expect = %zu + size of u32", + item_size, sizeof(*fi)); + return -EUCLEAN; + } + + ctxsize = btrfs_file_extent_encryption_info_size(leaf, fi); + if (unlikely(item_size != (fe_size + ctxsize))) { + file_extent_err(leaf, slot, + "invalid item size for encrypted file extent, have %u expect = %zu + context of size %u", + item_size, fe_size, ctxsize); + return -EUCLEAN; + } + + if (unlikely(ctxsize > BTRFS_MAX_EXTENT_CTX_SIZE)) { + file_extent_err(leaf, slot, + "invalid file extent context size, have %u expect a maximum of %u", + ctxsize, BTRFS_MAX_EXTENT_CTX_SIZE); + return -EUCLEAN; + } + + /* + * Only regular and prealloc extents should have an encryption + * context. + */ + if (unlikely(fe_type != BTRFS_FILE_EXTENT_REG && + fe_type != BTRFS_FILE_EXTENT_PREALLOC)) { + file_extent_err(leaf, slot, + "invalid type for encrypted file extent, have %u", + btrfs_file_extent_type(leaf, fi)); + return -EUCLEAN; + } + } else { + if (unlikely(item_size != sizeof(*fi))) { + file_extent_err(leaf, slot, "invalid item size for reg/prealloc file extent, have %u expect %zu", - item_size, sizeof(*fi)); - return -EUCLEAN; + item_size, sizeof(*fi)); + return -EUCLEAN; + } } if (unlikely(CHECK_FE_ALIGNED(leaf, slot, fi, ram_bytes, sectorsize) || CHECK_FE_ALIGNED(leaf, slot, fi, disk_bytenr, sectorsize) || diff --git a/include/uapi/linux/btrfs_tree.h b/include/uapi/linux/btrfs_tree.h index e5a4ba9573a0..98f29f36a359 100644 --- a/include/uapi/linux/btrfs_tree.h +++ b/include/uapi/linux/btrfs_tree.h @@ -1065,12 +1065,24 @@ enum { BTRFS_NR_FILE_EXTENT_TYPES = 3, }; +/* + * Currently just the FSCRYPT_SET_CONTEXT_MAX_SIZE, which is larger than the + * current extent context size from fscrypt, so this should give us plenty of + * breathing room for expansion later. + */ +#define BTRFS_MAX_EXTENT_CTX_SIZE 40 + enum { BTRFS_ENCRYPTION_NONE, BTRFS_ENCRYPTION_FSCRYPT, BTRFS_NR_ENCRYPTION_TYPES, }; +struct btrfs_encryption_info { + __le32 size; + __u8 context[0]; +}; + struct btrfs_file_extent_item { /* * transaction id that created this extent @@ -1126,7 +1138,10 @@ struct btrfs_file_extent_item { * always reflects the size uncompressed and without encoding. */ __le64 num_bytes; - + /* + * the encryption info, if any + */ + struct btrfs_encryption_info encryption_info[0]; } __attribute__ ((__packed__)); struct btrfs_csum_item { From patchwork Tue Oct 10 20:40:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416086 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 A33BDCD8CBE for ; Tue, 10 Oct 2023 20:41:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344051AbjJJUlu (ORCPT ); Tue, 10 Oct 2023 16:41:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234734AbjJJUlk (ORCPT ); Tue, 10 Oct 2023 16:41:40 -0400 Received: from mail-yb1-xb31.google.com (mail-yb1-xb31.google.com [IPv6:2607:f8b0:4864:20::b31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 34E23DA for ; Tue, 10 Oct 2023 13:41:36 -0700 (PDT) Received: by mail-yb1-xb31.google.com with SMTP id 3f1490d57ef6-d8198ca891fso6716525276.1 for ; Tue, 10 Oct 2023 13:41:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970495; x=1697575295; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=pxrkS5UiXrc0n0rxCHTTgd+SaI48QgT778UJ2JdcUoc=; b=ZKu85XztR2MxehnDv+bQwFaZzVtelMFPYztILSTQbwvM8MFzrk/7A0hSDKCVBwIUGd MJgCskUvo7vosHmCFxKhJU8A/zc5GMUENYXyoSrKczqtisNpUNjnpafDepymLkZK/CWJ AjqRnzeE6ogSNJ+2YDpSWyptIsRCQ2YTfMa+zrFAEsgwEEbPevhQXLnt3bYiE/OtHQEU /2X7ncA+KJOba7cg2kTLth4tMvujEEyv0oqhlBun+CEfwdmXR3YWpJziNg0sII8eBDF8 dJHDM24VRcGv8CkQA0dRmRiU8UtrjGTf3hk0i8Qjy+SxqpbItRc4X7hEZP5KL3z8eK9i d91Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970495; x=1697575295; 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=pxrkS5UiXrc0n0rxCHTTgd+SaI48QgT778UJ2JdcUoc=; b=UvujiEe1rXIziasUULGSe8KnWGfFXEXEugZ5Hkr3Q9B8qkeovdOlPmcghDIa6Fj15t 3YiSy2UhwpJnq8wW1rG+c9+9KgK79mpLxBGCyuoFAbyKoHfYDaByQZ7eZZZJOrtzLV9Z qZvlq/1GSVcMQutos3ScUOhkHoMh6b8lxe20gHCZdRtwgLCQFaHj8UzFpsaS/uClVBe+ aOjANIVwNJMuOCH5WN0o0l5xUq6xhUkwEhGdhLn456vuaDPNARKgR7tn1s79UHEpwsXP 3C92ZmVechwb6grbEvG+9VZPHAZQelP6Bwfiq9VySCDx0B9F41YnNPioekkUb8WvSjgW 5JpQ== X-Gm-Message-State: AOJu0YyHFvH56ftbObolmLSFMv9/RfkxkE0rxHtluoDh18TayElNQNIi Q1zc3UpS5aRCQMnPD7RUhWcPLnvub7/8dly23u34Dw== X-Google-Smtp-Source: AGHT+IEvwB9TR/VgtI7glsdPaSaAMuutYDc8yNBocBVvlHJ46htbAIjgQrGl6TEyZT1PjNBmYaI7RA== X-Received: by 2002:a25:d15:0:b0:d9a:6301:c82b with SMTP id 21-20020a250d15000000b00d9a6301c82bmr2610951ybn.13.1696970495234; Tue, 10 Oct 2023 13:41:35 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id l199-20020a2525d0000000b00d8144f0b287sm808525ybl.63.2023.10.10.13.41.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:34 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Cc: Sweet Tea Dorminy Subject: [PATCH v2 27/36] btrfs: explicitly track file extent length for replace and drop Date: Tue, 10 Oct 2023 16:40:42 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Sweet Tea Dorminy With the advent of storing fscrypt contexts with each encrypted extent, extents will have a variable length depending on encryption status. Make sure the replace and drop file extent item helpers encode this information so that everything gets updated properly. Signed-off-by: Sweet Tea Dorminy Signed-off-by: Josef Bacik --- fs/btrfs/ctree.h | 2 ++ fs/btrfs/file.c | 4 ++-- fs/btrfs/inode.c | 7 +++++-- fs/btrfs/reflink.c | 1 + fs/btrfs/tree-log.c | 5 +++-- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index c8f1d2d7c46c..e5879bd7f2f7 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -372,6 +372,8 @@ struct btrfs_replace_extent_info { u64 file_offset; /* Pointer to a file extent item of type regular or prealloc. */ char *extent_buf; + /* The length of @extent_buf */ + u32 extent_buf_size; /* * Set to true when attempting to replace a file range with a new extent * described by this structure, set to false when attempting to clone an diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 26905b77c7e8..a19ac854e07f 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2261,14 +2261,14 @@ static int btrfs_insert_replace_extent(struct btrfs_trans_handle *trans, key.type = BTRFS_EXTENT_DATA_KEY; key.offset = extent_info->file_offset; ret = btrfs_insert_empty_item(trans, root, path, &key, - sizeof(struct btrfs_file_extent_item)); + extent_info->extent_buf_size); if (ret) return ret; leaf = path->nodes[0]; slot = path->slots[0]; write_extent_buffer(leaf, extent_info->extent_buf, btrfs_item_ptr_offset(leaf, slot), - sizeof(struct btrfs_file_extent_item)); + extent_info->extent_buf_size); extent = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); ASSERT(btrfs_file_extent_type(leaf, extent) != BTRFS_FILE_EXTENT_INLINE); btrfs_set_file_extent_offset(leaf, extent, extent_info->data_offset); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d20ccfc5038f..03bc9f41bd33 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2898,6 +2898,7 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, u64 num_bytes = btrfs_stack_file_extent_num_bytes(stack_fi); u64 ram_bytes = btrfs_stack_file_extent_ram_bytes(stack_fi); struct btrfs_drop_extents_args drop_args = { 0 }; + size_t fscrypt_context_size = 0; int ret; path = btrfs_alloc_path(); @@ -2917,7 +2918,7 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, drop_args.start = file_pos; drop_args.end = file_pos + num_bytes; drop_args.replace_extent = true; - drop_args.extent_item_size = sizeof(*stack_fi); + drop_args.extent_item_size = sizeof(*stack_fi) + fscrypt_context_size; ret = btrfs_drop_extents(trans, root, inode, &drop_args); if (ret) goto out; @@ -2928,7 +2929,7 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, ins.type = BTRFS_EXTENT_DATA_KEY; ret = btrfs_insert_empty_item(trans, root, path, &ins, - sizeof(*stack_fi)); + sizeof(*stack_fi) + fscrypt_context_size); if (ret) goto out; } @@ -9671,6 +9672,7 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( u64 len = ins->offset; int qgroup_released; int ret; + size_t fscrypt_context_size = 0; memset(&stack_fi, 0, sizeof(stack_fi)); @@ -9703,6 +9705,7 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( extent_info.data_len = len; extent_info.file_offset = file_offset; extent_info.extent_buf = (char *)&stack_fi; + extent_info.extent_buf_size = sizeof(stack_fi) + fscrypt_context_size; extent_info.is_new_extent = true; extent_info.update_times = true; extent_info.qgroup_reserved = qgroup_released; diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c index 3c66630d87ee..f5440ae447a4 100644 --- a/fs/btrfs/reflink.c +++ b/fs/btrfs/reflink.c @@ -500,6 +500,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, clone_info.data_len = datal; clone_info.file_offset = new_key.offset; clone_info.extent_buf = buf; + clone_info.extent_buf_size = size; clone_info.is_new_extent = false; clone_info.update_times = !no_time_update; ret = btrfs_replace_file_extents(BTRFS_I(inode), path, diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 404577383513..6cdb924944d1 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4628,6 +4628,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans, u64 extent_offset = em->start - em->orig_start; u64 block_len; int ret; + size_t fscrypt_context_size = 0; u8 encryption = BTRFS_ENCRYPTION_NONE; btrfs_set_stack_file_extent_generation(&fi, trans->transid); @@ -4670,7 +4671,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans, drop_args.start = em->start; drop_args.end = em->start + em->len; drop_args.replace_extent = true; - drop_args.extent_item_size = sizeof(fi); + drop_args.extent_item_size = sizeof(fi) + fscrypt_context_size; ret = btrfs_drop_extents(trans, log, inode, &drop_args); if (ret) return ret; @@ -4682,7 +4683,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans, key.offset = em->start; ret = btrfs_insert_empty_item(trans, log, path, &key, - sizeof(fi)); + sizeof(fi) + fscrypt_context_size); if (ret) return ret; } From patchwork Tue Oct 10 20:40:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416084 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 F1299CD8CBF for ; Tue, 10 Oct 2023 20:41:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343941AbjJJUls (ORCPT ); Tue, 10 Oct 2023 16:41:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42404 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234745AbjJJUll (ORCPT ); Tue, 10 Oct 2023 16:41:41 -0400 Received: from mail-yw1-x1135.google.com (mail-yw1-x1135.google.com [IPv6:2607:f8b0:4864:20::1135]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 51BA4F1 for ; Tue, 10 Oct 2023 13:41:37 -0700 (PDT) Received: by mail-yw1-x1135.google.com with SMTP id 00721157ae682-5a2536adaf3so75234617b3.2 for ; Tue, 10 Oct 2023 13:41:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970496; x=1697575296; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=UDlZH9qthcW82Qll/N8PtWNZ+HAtcElgL4HleKPl0K8=; b=OfjMT72y9sTlQD5vC8E7t/FmzGMKx7jvZt6u2cg/pHZhg4NhByCfaZY2L1vKHFRUlx 0uabjOIE8pmM8gto/EW202BLCYgf/nkOf79JMzvL6cA1InwqcGXduWuw0d2A234UXaiX r3eNuXV6XU2yl26YnbBtwvkGiWq7C2e5P/JHHgeMlNEozNOGD6s7wfvszDrSRR25fS1k xhn1zCwQxac0UuRPwkIPAqiXhY3uwJJPY+rpOOx0HKkhUsh5asuRKMH7a0C6EZTJSdHC xKqlWGcGx2YNQXaYZengPiVQfr3qovXhmtqUm+x7FE1QYLbM/KJ+unqWZlXlpK1s8MNy n/9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970496; x=1697575296; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UDlZH9qthcW82Qll/N8PtWNZ+HAtcElgL4HleKPl0K8=; b=d+/kl7ItyY/vHwaGNoLP26hckwmZwteytAq1efE+PBvaHrpibt7OHX6pEFabwoRXVp mhKPOa1WR/urZvdfd/gOtmujSwfEhhUqNOjWLaFrPEEccJTM0xjMsRbCAWvoiB8Y1Yfr 1o21G7u79+riWxJp05cCySdgjiCq0Su+Rr25lSkChN6llJH/LIzFLHX0FPDQNWt0PWwi L4h8Sj0+UiikUWBD5qIEqj2CJIFtIDt2RxSNEsIizRosOmDlyP+P7d7qVVfU804PJqAu CEvmo33HXSyP6Ld2hFE2wRSTlnlQ9snlpV7O4H4Ts5WzFotS3tuwKk/sCLlkwfUD8tmY KaDA== X-Gm-Message-State: AOJu0Yyd2MuF3h9pFJhcSWxWgMWbw89u6xNzqxnNIPC8K4KVnyS6Wdmx EYLoe3+7gf8zy0VLb9+ZuJ2ioIzTVYURcHPVB6ljsg== X-Google-Smtp-Source: AGHT+IFbidE243+FsCFNoU0+NDimYRSNe0NqDe1FQUB69Xp0KLGt12SaQc4Z5+m710j4wTVvELOuEA== X-Received: by 2002:a0d:cbd3:0:b0:578:5e60:dcc9 with SMTP id n202-20020a0dcbd3000000b005785e60dcc9mr19163026ywd.10.1696970496405; Tue, 10 Oct 2023 13:41:36 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id j131-20020a816e89000000b005956b451fb8sm4616426ywc.100.2023.10.10.13.41.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:35 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 28/36] btrfs: pass through fscrypt_extent_info to the file extent helpers Date: Tue, 10 Oct 2023 16:40:43 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Now that we have the fscrypt_extnet_info in all of the supporting structures, pass this through and set the file extent encryption bit accordingly from the supporting structures. In subsequent patches code will be added to populate these appropriately. Signed-off-by: Josef Bacik --- fs/btrfs/inode.c | 18 +++++++++++------- fs/btrfs/tree-log.c | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 03bc9f41bd33..87b38be47d0b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2882,7 +2882,9 @@ int btrfs_writepage_cow_fixup(struct page *page) } static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, - struct btrfs_inode *inode, u64 file_pos, + struct btrfs_inode *inode, + struct fscrypt_extent_info *fscrypt_info, + u64 file_pos, struct btrfs_file_extent_item *stack_fi, const bool update_inode_bytes, u64 qgroup_reserved) @@ -3014,8 +3016,7 @@ static int insert_ordered_extent_file_extent(struct btrfs_trans_handle *trans, btrfs_set_stack_file_extent_num_bytes(&stack_fi, num_bytes); btrfs_set_stack_file_extent_ram_bytes(&stack_fi, ram_bytes); btrfs_set_stack_file_extent_compression(&stack_fi, oe->compress_type); - btrfs_set_stack_file_extent_encryption(&stack_fi, - BTRFS_ENCRYPTION_NONE); + btrfs_set_stack_file_extent_encryption(&stack_fi, oe->encryption_type); /* Other encoding is reserved and always 0 */ /* @@ -3029,8 +3030,9 @@ static int insert_ordered_extent_file_extent(struct btrfs_trans_handle *trans, test_bit(BTRFS_ORDERED_TRUNCATED, &oe->flags); return insert_reserved_file_extent(trans, BTRFS_I(oe->inode), - oe->file_offset, &stack_fi, - update_inode_bytes, oe->qgroup_rsv); + oe->fscrypt_info, oe->file_offset, + &stack_fi, update_inode_bytes, + oe->qgroup_rsv); } /* @@ -9662,6 +9664,7 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( struct btrfs_trans_handle *trans_in, struct btrfs_inode *inode, struct btrfs_key *ins, + struct fscrypt_extent_info *fscrypt_info, u64 file_offset) { struct btrfs_file_extent_item stack_fi; @@ -9683,6 +9686,7 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( btrfs_set_stack_file_extent_ram_bytes(&stack_fi, len); btrfs_set_stack_file_extent_compression(&stack_fi, BTRFS_COMPRESS_NONE); btrfs_set_stack_file_extent_encryption(&stack_fi, + fscrypt_info ? BTRFS_ENCRYPTION_FSCRYPT : BTRFS_ENCRYPTION_NONE); /* Other encoding is reserved and always 0 */ @@ -9691,7 +9695,7 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( return ERR_PTR(qgroup_released); if (trans) { - ret = insert_reserved_file_extent(trans, inode, + ret = insert_reserved_file_extent(trans, inode, fscrypt_info, file_offset, &stack_fi, true, qgroup_released); if (ret) @@ -9785,7 +9789,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, last_alloc = ins.offset; trans = insert_prealloc_file_extent(trans, BTRFS_I(inode), - &ins, cur_offset); + &ins, NULL, cur_offset); /* * Now that we inserted the prealloc extent we can finally * decrement the number of reservations in the block group. diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 6cdb924944d1..85267cf1f372 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4629,7 +4629,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans, u64 block_len; int ret; size_t fscrypt_context_size = 0; - u8 encryption = BTRFS_ENCRYPTION_NONE; + u8 encryption = em->encryption_type; btrfs_set_stack_file_extent_generation(&fi, trans->transid); if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) From patchwork Tue Oct 10 20:40:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416089 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 91F35CD6115 for ; Tue, 10 Oct 2023 20:41:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230189AbjJJUlx (ORCPT ); Tue, 10 Oct 2023 16:41:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33442 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234750AbjJJUll (ORCPT ); Tue, 10 Oct 2023 16:41:41 -0400 Received: from mail-yw1-x1131.google.com (mail-yw1-x1131.google.com [IPv6:2607:f8b0:4864:20::1131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F3D53FD for ; Tue, 10 Oct 2023 13:41:38 -0700 (PDT) Received: by mail-yw1-x1131.google.com with SMTP id 00721157ae682-5a7be88e9ccso14566317b3.2 for ; Tue, 10 Oct 2023 13:41:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970497; x=1697575297; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=qMKykqBQS3RwEEufY+WMuQHq/EYaymfByQ3Narp/qxc=; b=Pf6sO2Q8PbPLwXjPDfItr2/XiXAiSYTSmX1/ppJ8y9kuMaQBJ65oIRI2u1uRbmeuac 4Z3vz1HNiQ7BMc997V5OHwpfUUtE/TwrlG3NdhQl5Nvla5bkbfNsZ0HnfeDZ1TANxQ9K rm3+RrWSiTWqrblMqgAOgaeweaWUUcYntkffgPhwKXVuF+RBPGHdX5CXozBFHHYqTu/b 0dv3zmTGg3LGW9+adu6RGf3QTFSH/YGZPWmiRTlmmp94gkjtf1Y9YtzkOoEKyQog3K+y 3yEarudlPP7kNJrgtqExtv4k8RHspW9UuxUu1pSSBTa20HFbuyBxcIO10yK7N2eXBm9G AsAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970497; x=1697575297; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qMKykqBQS3RwEEufY+WMuQHq/EYaymfByQ3Narp/qxc=; b=aeV4FF3Rf91L22pHOZtXpSxvOPKUzJnWSMvxmIfvmo7LmYArJGHWCS3zPj/ZArgkhS wgpdH4LHOdn2Rneaq8KWs3/BiiLX62isFSDcxjLEBsa39AMmD+7h/W5cbjGya8LmP4tl TQ9YO/2h8JM3NqKMryep5HbAFbXCjn8Q/pOQv7LU8jO3DQhqiLct6Bs5teBOGrMC7xVX Sd4YFB78WBhKtCdhmgeLIkRhJ29DmvrDuLgl6QcxXVdFgxB8kDw0vW2bNGpDtJ3i0A7r EJRnM/+SpgO9A/UlklNC6mFnS8gDWB/w7b9Im069YTdwKnboSEmlZuZ6J5Z4ku6/ZZv7 VykQ== X-Gm-Message-State: AOJu0YzVZ11A1fjRKXPHQMpNqqlH9LsaYL8yPyFmoNuP5aa/ip3K+73w +kyM2+AZXuWu2VctztK7II2r1aKMy8ssY6qJtsSA1g== X-Google-Smtp-Source: AGHT+IETd3bX/He5a3vC5KS58JgFRitZ1HZTBIPqZbrgbbwE0f9wBdGtCYbfHzTtf7J3O+rl/SIdtQ== X-Received: by 2002:a0d:e607:0:b0:5a1:c610:1154 with SMTP id p7-20020a0de607000000b005a1c6101154mr20541272ywe.10.1696970497546; Tue, 10 Oct 2023 13:41:37 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id y129-20020a0def87000000b00582fae92aa7sm4650659ywe.93.2023.10.10.13.41.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:37 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 29/36] btrfs: pass the fscrypt_info through the replace extent infrastructure Date: Tue, 10 Oct 2023 16:40:44 -0400 Message-ID: <3b71dffa339c14a6c973ed5a29a5ca4b879ce847.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Prealloc uses the btrfs_replace_file_extents() infrastructure to insert its new extents. We need to set the fscrypt context on these extents, so pass this through the btrfs_replace_extent_info so it can be used in a later patch when we hook in this infrastructure. Signed-off-by: Josef Bacik --- fs/btrfs/ctree.h | 2 ++ fs/btrfs/inode.c | 1 + 2 files changed, 3 insertions(+) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index e5879bd7f2f7..f5367091c0cd 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -374,6 +374,8 @@ struct btrfs_replace_extent_info { char *extent_buf; /* The length of @extent_buf */ u32 extent_buf_size; + /* The fscrypt_extent_info for a new extent. */ + struct fscrypt_extent_info *fscrypt_info; /* * Set to true when attempting to replace a file range with a new extent * described by this structure, set to false when attempting to clone an diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 87b38be47d0b..99fb5a613fb8 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -9714,6 +9714,7 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( extent_info.update_times = true; extent_info.qgroup_reserved = qgroup_released; extent_info.insertions = 0; + extent_info.fscrypt_info = fscrypt_info; path = btrfs_alloc_path(); if (!path) { From patchwork Tue Oct 10 20:40:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416096 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 7D3D9CD80DE for ; Tue, 10 Oct 2023 20:42:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343901AbjJJUmC (ORCPT ); Tue, 10 Oct 2023 16:42:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45968 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234758AbjJJUlm (ORCPT ); Tue, 10 Oct 2023 16:41:42 -0400 Received: from mail-yb1-xb2e.google.com (mail-yb1-xb2e.google.com [IPv6:2607:f8b0:4864:20::b2e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A203FFE for ; Tue, 10 Oct 2023 13:41:39 -0700 (PDT) Received: by mail-yb1-xb2e.google.com with SMTP id 3f1490d57ef6-d862533ea85so7169448276.0 for ; Tue, 10 Oct 2023 13:41:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970498; x=1697575298; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=s/HPcvQgEQLN74gCQGGFfy6grnvrJeKxxUOAvtKfy8E=; b=UVMDTTaPTIBlm64+xdUOPFYtq7OROAe8pTT7UuwS5pUm4XKBRms4vxv30QSvMEtCgw SM2JVPINvK2RloJ7jCF029IRn+k1If5VBHRc+mtgHYjG/V9swlGs1x7CSGcFrETTbLgs 6xVLzida3UKCwv2nwj+3HRsnAXiRj46YzDI+CRcJ8K2zj+prxZKEPssCCLgVK3x5WWWb k+hlkxIZeIePXn0z+uIWBKbUoq0nBVNgQIpVWrD2wWRyB0tL8ZFJEfxK9V/rDsEoJD5e 7w+mWB3J58rD646cJc6HQ7zcTpUrltff3W5fiG2K2qEykg9cMQvjaU5a0G++CJ0kJdqN CrmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970498; x=1697575298; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=s/HPcvQgEQLN74gCQGGFfy6grnvrJeKxxUOAvtKfy8E=; b=EjXvKmztEHtQSQcUaMn2ZeGG29702IKJBnxUS6MgeOXwRMtNlgJYpNTI9e5mCCRWfi c34kN9BAC2xjEVJtA9+4PxV2JK+/X2xgbHvdbmK7Fm+wc9UIA213hRu+kEBkRQSQheGy rjRlTuLHMnFfE2HZvrS9qPWwz/HQoZP19GcYyJtwtH0stc54pRJsGNxDazNyGXRfPz/K C7za7oPv+UvJPCV4Sl6Ledy3R1FfElfIg/P2/RuUxvt0IT8FKykkz4mgZo0+8YqM+yWq Vvy/02nrcT7wXMGafbufsxkFPx56sGANDPndBquG35rRCvnJNYX44WNkVjORaevuCTGZ Y+BQ== X-Gm-Message-State: AOJu0YxVjkQEtwfgbuo3nWS6ipgPsEmRySVayiuO0B5nEMSUcAhf6CAm Y0JR+kb9t7eE0/v5MualkpiCOTx3FqzrbOTslkWKZw== X-Google-Smtp-Source: AGHT+IELyLYpfVjCINwoiBUvjKFSBlcQLItvygadkhKBOxzWrGAHM1WF4gTAuU+dInHTmAa0fNfmMA== X-Received: by 2002:a5b:70d:0:b0:d78:341d:e475 with SMTP id g13-20020a5b070d000000b00d78341de475mr17410348ybq.44.1696970498616; Tue, 10 Oct 2023 13:41:38 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id d82-20020a254f55000000b00d728a2738f1sm3961935ybb.61.2023.10.10.13.41.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:38 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 30/36] btrfs: implement the fscrypt extent encryption hooks Date: Tue, 10 Oct 2023 16:40:45 -0400 Message-ID: <303db92bcd9f80f9e32b028a5d5477339b08e68f.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org This patch implements the necessary hooks from fscrypt to support per-extent encryption. There's two main entry points btrfs_fscrypt_load_extent_info btrfs_fscrypt_save_extent_info btrfs_fscrypt_load_extent_info gets called when we create the extent maps from the file extent item at btrfs_get_extent() time. We read the extent context, and pass it into fscrypt to create the appropriate fscrypt_extent_info structure. This is then used on the bio's to make sure the encryption is done properly. btrfs_fscrypt_save_extent_info is used to generate the fscrypt context from fscrypt and save it into the file extent item when we create a new file extent item. Signed-off-by: Josef Bacik --- fs/btrfs/defrag.c | 10 ++++++++- fs/btrfs/file-item.c | 11 +++++++++- fs/btrfs/file-item.h | 5 ++++- fs/btrfs/file.c | 9 ++++++++ fs/btrfs/fscrypt.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/fscrypt.h | 31 ++++++++++++++++++++++++++++ fs/btrfs/inode.c | 22 +++++++++++++++++++- fs/btrfs/tree-log.c | 10 +++++++++ 8 files changed, 143 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c index 5244561e2016..f3b7438ddbc7 100644 --- a/fs/btrfs/defrag.c +++ b/fs/btrfs/defrag.c @@ -16,6 +16,7 @@ #include "defrag.h" #include "file-item.h" #include "super.h" +#include "fscrypt.h" static struct kmem_cache *btrfs_inode_defrag_cachep; @@ -631,9 +632,12 @@ static struct extent_map *defrag_get_extent(struct btrfs_inode *inode, struct btrfs_path path = { 0 }; struct extent_map *em; struct btrfs_key key; + struct btrfs_fscrypt_ctx ctx; u64 ino = btrfs_ino(inode); int ret; + ctx.size = 0; + em = alloc_extent_map(); if (!em) { ret = -ENOMEM; @@ -728,7 +732,7 @@ static struct extent_map *defrag_get_extent(struct btrfs_inode *inode, goto next; /* Now this extent covers @start, convert it to em */ - btrfs_extent_item_to_extent_map(inode, &path, fi, em); + btrfs_extent_item_to_extent_map(inode, &path, fi, em, &ctx); break; next: ret = btrfs_next_item(root, &path); @@ -738,6 +742,10 @@ static struct extent_map *defrag_get_extent(struct btrfs_inode *inode, goto not_found; } btrfs_release_path(&path); + + ret = btrfs_fscrypt_load_extent_info(inode, em, &ctx); + if (ret) + goto err; return em; not_found: diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index 26f35c1baedc..35036fab58c4 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c @@ -21,6 +21,7 @@ #include "accessors.h" #include "file-item.h" #include "super.h" +#include "fscrypt.h" #define __MAX_CSUM_ITEMS(r, size) ((unsigned long)(((BTRFS_LEAF_DATA_SIZE(r) - \ sizeof(struct btrfs_item) * 2) / \ @@ -1264,7 +1265,8 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode, const struct btrfs_path *path, struct btrfs_file_extent_item *fi, - struct extent_map *em) + struct extent_map *em, + struct btrfs_fscrypt_ctx *ctx) { struct btrfs_fs_info *fs_info = inode->root->fs_info; struct btrfs_root *root = inode->root; @@ -1306,6 +1308,13 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode, set_bit(EXTENT_FLAG_PREALLOC, &em->flags); } em->encryption_type = btrfs_file_extent_encryption(leaf, fi); + if (em->encryption_type != BTRFS_ENCRYPTION_NONE) { + ctx->size = + btrfs_file_extent_encryption_ctx_size(leaf, fi); + read_extent_buffer(leaf, ctx->ctx, + btrfs_file_extent_encryption_ctx_offset(fi), + ctx->size); + } } else if (type == BTRFS_FILE_EXTENT_INLINE) { em->block_start = EXTENT_MAP_INLINE; em->start = extent_start; diff --git a/fs/btrfs/file-item.h b/fs/btrfs/file-item.h index 04bd2d34efb1..bb79014024bd 100644 --- a/fs/btrfs/file-item.h +++ b/fs/btrfs/file-item.h @@ -5,6 +5,8 @@ #include "accessors.h" +struct btrfs_fscrypt_ctx; + #define BTRFS_FILE_EXTENT_INLINE_DATA_START \ (offsetof(struct btrfs_file_extent_item, disk_bytenr)) @@ -63,7 +65,8 @@ int btrfs_lookup_csums_bitmap(struct btrfs_root *root, struct btrfs_path *path, void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode, const struct btrfs_path *path, struct btrfs_file_extent_item *fi, - struct extent_map *em); + struct extent_map *em, + struct btrfs_fscrypt_ctx *ctx); int btrfs_inode_clear_file_extent_range(struct btrfs_inode *inode, u64 start, u64 len); int btrfs_inode_set_file_extent_range(struct btrfs_inode *inode, u64 start, u64 len); diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index a19ac854e07f..be35cdd129b3 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -38,6 +38,7 @@ #include "ioctl.h" #include "file.h" #include "super.h" +#include "fscrypt.h" /* simple helper to fault in pages and copy. This should go away * and be replaced with calls into generic code. @@ -2275,6 +2276,14 @@ static int btrfs_insert_replace_extent(struct btrfs_trans_handle *trans, btrfs_set_file_extent_num_bytes(leaf, extent, replace_len); if (extent_info->is_new_extent) btrfs_set_file_extent_generation(leaf, extent, trans->transid); + if (extent_info->fscrypt_info) { + ret = btrfs_fscrypt_save_extent_info(inode, path, + extent_info->fscrypt_info); + if (ret) { + btrfs_release_path(path); + return ret; + } + } btrfs_mark_buffer_dirty(trans, leaf); btrfs_release_path(path); diff --git a/fs/btrfs/fscrypt.c b/fs/btrfs/fscrypt.c index 2d037b105b5f..7a7272cb83ec 100644 --- a/fs/btrfs/fscrypt.c +++ b/fs/btrfs/fscrypt.c @@ -214,7 +214,56 @@ static struct block_device **btrfs_fscrypt_get_devices(struct super_block *sb, return devs; } +int btrfs_fscrypt_load_extent_info(struct btrfs_inode *inode, + struct extent_map *em, + struct btrfs_fscrypt_ctx *ctx) +{ + struct fscrypt_extent_info *info; + unsigned long nofs_flag; + + if (ctx->size == 0) + return 0; + + nofs_flag = memalloc_nofs_save(); + info = fscrypt_load_extent_info(&inode->vfs_inode, ctx->ctx, ctx->size); + memalloc_nofs_restore(nofs_flag); + if (IS_ERR(info)) + return PTR_ERR(info); + em->fscrypt_info = info; + return 0; +} + +int btrfs_fscrypt_save_extent_info(struct btrfs_inode *inode, + struct btrfs_path *path, + struct fscrypt_extent_info *info) +{ + struct btrfs_file_extent_item *ei; + u8 ctx[BTRFS_MAX_EXTENT_CTX_SIZE]; + ssize_t ctx_size; + + ei = btrfs_item_ptr(path->nodes[0], path->slots[0], + struct btrfs_file_extent_item); + + ctx_size = fscrypt_set_extent_context(&inode->vfs_inode, info, ctx); + if (ctx_size < 0) { + btrfs_err_rl(inode->root->fs_info, "invalid encrypt context\n"); + return (int)ctx_size; + } + write_extent_buffer(path->nodes[0], ctx, + btrfs_file_extent_encryption_ctx_offset(ei), + ctx_size); + btrfs_set_file_extent_encryption_ctx_size(path->nodes[0], ei, ctx_size); + return 0; +} + +size_t btrfs_fscrypt_extent_context_size(struct btrfs_inode *inode) +{ + return sizeof(struct btrfs_encryption_info) + + fscrypt_extent_context_size(&inode->vfs_inode); +} + const struct fscrypt_operations btrfs_fscrypt_ops = { + .has_per_extent_encryption = 1, .get_context = btrfs_fscrypt_get_context, .set_context = btrfs_fscrypt_set_context, .empty_dir = btrfs_fscrypt_empty_dir, diff --git a/fs/btrfs/fscrypt.h b/fs/btrfs/fscrypt.h index c08fd52c99b4..2882a4a9d978 100644 --- a/fs/btrfs/fscrypt.h +++ b/fs/btrfs/fscrypt.h @@ -8,6 +8,11 @@ #include "fs.h" +struct btrfs_fscrypt_ctx { + u8 ctx[BTRFS_MAX_EXTENT_CTX_SIZE]; + size_t size; +}; + #ifdef CONFIG_FS_ENCRYPTION int btrfs_fscrypt_get_disk_name(struct extent_buffer *leaf, struct btrfs_dir_item *di, @@ -16,8 +21,29 @@ int btrfs_fscrypt_get_disk_name(struct extent_buffer *leaf, bool btrfs_fscrypt_match_name(struct fscrypt_name *fname, struct extent_buffer *leaf, unsigned long de_name, u32 de_name_len); +int btrfs_fscrypt_load_extent_info(struct btrfs_inode *inode, + struct extent_map *em, + struct btrfs_fscrypt_ctx *ctx); +int btrfs_fscrypt_save_extent_info(struct btrfs_inode *inode, + struct btrfs_path *path, + struct fscrypt_extent_info *fi); +size_t btrfs_fscrypt_extent_context_size(struct btrfs_inode *inode); #else +static inline int btrfs_fscrypt_save_extent_info(struct btrfs_inode *inode, + struct btrfs_path *path, + struct fscrypt_extent_info *fi) +{ + return 0; +} + +static inline int btrfs_fscrypt_load_extent_info(struct btrfs_inode *inode, + struct extent_map *em, + struct btrfs_fscrypt_ctx *ctx) +{ + return 0; +} + static inline int btrfs_fscrypt_get_disk_name(struct extent_buffer *leaf, struct btrfs_dir_item *di, struct fscrypt_str *qstr) @@ -35,6 +61,11 @@ static inline bool btrfs_fscrypt_match_name(struct fscrypt_name *fname, return !memcmp_extent_buffer(leaf, fname->disk_name.name, de_name, de_name_len); } + +static inline size_t btrfs_fscrypt_extent_context_size(struct btrfs_inode *inode) +{ + return 0; +} #endif /* CONFIG_FS_ENCRYPTION */ extern const struct fscrypt_operations btrfs_fscrypt_ops; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 99fb5a613fb8..4f23c3af60be 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2903,6 +2903,9 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, size_t fscrypt_context_size = 0; int ret; + if (btrfs_stack_file_extent_encryption(stack_fi)) + fscrypt_context_size = btrfs_fscrypt_extent_context_size(inode); + path = btrfs_alloc_path(); if (!path) return -ENOMEM; @@ -2941,6 +2944,12 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, btrfs_item_ptr_offset(leaf, path->slots[0]), sizeof(struct btrfs_file_extent_item)); + if (fscrypt_context_size) { + ret = btrfs_fscrypt_save_extent_info(inode, path, fscrypt_info); + if (ret) + goto out; + } + btrfs_mark_buffer_dirty(trans, leaf); btrfs_release_path(path); @@ -6865,6 +6874,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, struct btrfs_key found_key; struct extent_map *em = NULL; struct extent_map_tree *em_tree = &inode->extent_tree; + struct btrfs_fscrypt_ctx ctx; read_lock(&em_tree->lock); em = lookup_extent_mapping(em_tree, start, len); @@ -6878,6 +6888,9 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, else goto out; } + + ctx.size = 0; + em = alloc_extent_map(); if (!em) { ret = -ENOMEM; @@ -6982,7 +6995,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, goto insert; } - btrfs_extent_item_to_extent_map(inode, path, item, em); + btrfs_extent_item_to_extent_map(inode, path, item, em, &ctx); if (extent_type == BTRFS_FILE_EXTENT_REG || extent_type == BTRFS_FILE_EXTENT_PREALLOC) { @@ -7027,6 +7040,10 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, goto out; } + ret = btrfs_fscrypt_load_extent_info(inode, em, &ctx); + if (ret) + goto out; + write_lock(&em_tree->lock); ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, start, len); write_unlock(&em_tree->lock); @@ -9703,6 +9720,9 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( return trans; } + if (fscrypt_info) + fscrypt_context_size = btrfs_fscrypt_extent_context_size(inode); + extent_info.disk_offset = start; extent_info.disk_len = len; extent_info.data_offset = 0; diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 85267cf1f372..1082e1d7fd84 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -30,6 +30,7 @@ #include "file.h" #include "orphan.h" #include "tree-checker.h" +#include "fscrypt.h" #define MAX_CONFLICT_INODES 10 @@ -4631,6 +4632,9 @@ static int log_one_extent(struct btrfs_trans_handle *trans, size_t fscrypt_context_size = 0; u8 encryption = em->encryption_type; + if (encryption) + fscrypt_context_size = btrfs_fscrypt_extent_context_size(inode); + btrfs_set_stack_file_extent_generation(&fi, trans->transid); if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) btrfs_set_stack_file_extent_type(&fi, BTRFS_FILE_EXTENT_PREALLOC); @@ -4691,6 +4695,12 @@ static int log_one_extent(struct btrfs_trans_handle *trans, write_extent_buffer(leaf, &fi, btrfs_item_ptr_offset(leaf, path->slots[0]), sizeof(fi)); + if (fscrypt_context_size) { + ret = btrfs_fscrypt_save_extent_info(inode, path, + em->fscrypt_info); + if (ret) + return ret; + } btrfs_mark_buffer_dirty(trans, leaf); btrfs_release_path(path); From patchwork Tue Oct 10 20:40:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416095 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 A823ECD68E9 for ; Tue, 10 Oct 2023 20:42:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343827AbjJJUmB (ORCPT ); Tue, 10 Oct 2023 16:42:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42486 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234759AbjJJUlm (ORCPT ); Tue, 10 Oct 2023 16:41:42 -0400 Received: from mail-yw1-x112e.google.com (mail-yw1-x112e.google.com [IPv6:2607:f8b0:4864:20::112e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C0E3F100 for ; Tue, 10 Oct 2023 13:41:40 -0700 (PDT) Received: by mail-yw1-x112e.google.com with SMTP id 00721157ae682-5a7dd65052aso1311437b3.0 for ; Tue, 10 Oct 2023 13:41:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970500; x=1697575300; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=/lG6cmi+XemzHTouP6yyHX+TZQxYU9G/Ow3oUnVe924=; b=F+/9Adi+b3GzspzkQb5Byi98CWzU6LKQgV929RyssnxlDgvMFngGZSoTqanWlTefrz zoECQYkFbfuuCSKowrf5tcjaSLc3kz8xwFhQbrd3ZZ8G42qjNuBw2HXUaZvnxcT3NSgQ 21B54bPsfvBu+vpW7Pjl2+E4XkPu6HAcegkyRSw3Dq/bHegLw94x7Zz0NR22UpKvBSyU alkOdTEmCMZ5kHHua/yMMsdKWTnMepKU+/ZFTO5sdAePGF0Tu0jvJH4VLLGHprxqOX24 4laSW8n0qHdUCOen3gto0BN1vp5+Ozhx1Y7sNXZ270yrDf/caLLRaT31zHPzEPcSV0EM zM1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970500; x=1697575300; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/lG6cmi+XemzHTouP6yyHX+TZQxYU9G/Ow3oUnVe924=; b=aXmORLoOyyLXhBLl6hGhtrGMbB6LHtv2WIaKaSQAmjRlUwexYIrWQMOjFkiOra6zbT o2cmwndMHHuw20XTSVNfJIbUmoYdUURoFJ+xQqvo1QoyjYNXVKjyaz+fk6gFGZ75R5mK 2qgJYkrPjXKiiaDDMPBP5oRSe8arWSAiMErIMMdGjqLjzN/1qgmdac+STJR/RFu2i2f8 H+u0GxLmHhBeMN348PWqd0t5SaSGXzgsPrCpN3ka8J/cWrYqDFITrynVIai96oKNFRKr BZc3HhQOzIaxg3LSe/9Aa3vgjgP25LQKd4Ie/M+DRTjDaNU3zgA+myHyNfZNrD5kHhBi N4YQ== X-Gm-Message-State: AOJu0YzFTTGq6fMYhq/n89PG8EmSDAvJM3rN8v5B1z/kfEtSTJ8jtAc9 Z4bNQlyqO0P2FxJqJYuW1cPRASgQCFJJieOwUrxSJA== X-Google-Smtp-Source: AGHT+IGXe9amKvpJyO5M8/JuTI+aDqvTaDKYFnIZP/ZdjePk0VuktS4VhqLJ94oENqhSEDYviaFwBw== X-Received: by 2002:a0d:d7d1:0:b0:5a7:cff3:e407 with SMTP id z200-20020a0dd7d1000000b005a7cff3e407mr1876485ywd.31.1696970499900; Tue, 10 Oct 2023 13:41:39 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id d68-20020a0df447000000b0059f5d686479sm4671247ywf.16.2023.10.10.13.41.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:39 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 31/36] btrfs: setup fscrypt_extent_info for new extents Date: Tue, 10 Oct 2023 16:40:46 -0400 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org New extents for encrypted inodes must have a fscrypt_extent_info, which has the necessary keys and does all the registration at the block layer for them. This is passed through all of the infrastructure we've previously added to make sure the context gets saved properly with the file extents. Signed-off-by: Josef Bacik --- fs/btrfs/inode.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4f23c3af60be..b0109b313217 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7396,7 +7396,20 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start, set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); em->compress_type = compress_type; } - em->encryption_type = BTRFS_ENCRYPTION_NONE; + + if (IS_ENCRYPTED(&inode->vfs_inode)) { + struct fscrypt_extent_info *fscrypt_info; + + em->encryption_type = BTRFS_ENCRYPTION_FSCRYPT; + fscrypt_info = fscrypt_prepare_new_extent(&inode->vfs_inode); + if (IS_ERR(fscrypt_info)) { + free_extent_map(em); + return ERR_CAST(fscrypt_info); + } + em->fscrypt_info = fscrypt_info; + } else { + em->encryption_type = BTRFS_ENCRYPTION_NONE; + } ret = btrfs_replace_extent_map_range(inode, em, true); if (ret) { @@ -9785,6 +9798,9 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, if (trans) own_trans = false; while (num_bytes > 0) { + struct fscrypt_extent_info *fscrypt_info = NULL; + int encryption_type = BTRFS_ENCRYPTION_NONE; + cur_bytes = min_t(u64, num_bytes, SZ_256M); cur_bytes = max(cur_bytes, min_size); /* @@ -9799,6 +9815,20 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, if (ret) break; + if (IS_ENCRYPTED(inode)) { + fscrypt_info = fscrypt_prepare_new_extent(inode); + if (IS_ERR(fscrypt_info)) { + btrfs_dec_block_group_reservations(fs_info, + ins.objectid); + btrfs_free_reserved_extent(fs_info, + ins.objectid, + ins.offset, 0); + ret = PTR_ERR(fscrypt_info); + break; + } + encryption_type = BTRFS_ENCRYPTION_FSCRYPT; + } + /* * We've reserved this space, and thus converted it from * ->bytes_may_use to ->bytes_reserved. Any error that happens @@ -9810,7 +9840,8 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, last_alloc = ins.offset; trans = insert_prealloc_file_extent(trans, BTRFS_I(inode), - &ins, NULL, cur_offset); + &ins, fscrypt_info, + cur_offset); /* * Now that we inserted the prealloc extent we can finally * decrement the number of reservations in the block group. @@ -9820,6 +9851,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, btrfs_dec_block_group_reservations(fs_info, ins.objectid); if (IS_ERR(trans)) { ret = PTR_ERR(trans); + fscrypt_put_extent_info(fscrypt_info); btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset, 0); break; @@ -9827,6 +9859,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, em = alloc_extent_map(); if (!em) { + fscrypt_put_extent_info(fscrypt_info); btrfs_drop_extent_map_range(BTRFS_I(inode), cur_offset, cur_offset + ins.offset - 1, false); btrfs_set_inode_full_sync(BTRFS_I(inode)); @@ -9842,6 +9875,8 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, em->ram_bytes = ins.offset; set_bit(EXTENT_FLAG_PREALLOC, &em->flags); em->generation = trans->transid; + em->fscrypt_info = fscrypt_info; + em->encryption_type = encryption_type; ret = btrfs_replace_extent_map_range(BTRFS_I(inode), em, true); free_extent_map(em); From patchwork Tue Oct 10 20:40:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416090 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 BFCE5CD68E9 for ; Tue, 10 Oct 2023 20:41:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234278AbjJJUly (ORCPT ); Tue, 10 Oct 2023 16:41:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42432 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343877AbjJJUln (ORCPT ); Tue, 10 Oct 2023 16:41:43 -0400 Received: from mail-yw1-x1129.google.com (mail-yw1-x1129.google.com [IPv6:2607:f8b0:4864:20::1129]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F2161CA for ; Tue, 10 Oct 2023 13:41:41 -0700 (PDT) Received: by mail-yw1-x1129.google.com with SMTP id 00721157ae682-5a7b91faf40so19284437b3.1 for ; Tue, 10 Oct 2023 13:41:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970501; x=1697575301; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=OVSFcN3hgU5Wv+MUFYElNWnOc10PkPLhn8pZyce9ayk=; b=MQkaJjHVyeC3YpmxIk6vzp10P0zI1eKIcPFXu8gTCu4xIs4Xm7p1MjPvKUnnPtRyDJ Pbg0iVWBzYUaEdMKWII/sRQPbjwjzt0YJ1LUMcoAk8HUphGh4f9JXgisw67RhfqbiOka JrynA/xJc5yVXSZSD3vF1LdDzHlhQAj/RCN6WWtXnIbFTcNw0HFapmr9+h85G8mOAe/8 u7VtIAnXCIvMGvwksbPR9iMtwHf8CTuW3zsfFLnzkYdBr4YEDhtJsrGCC2Q7VIOzO/sW 0Qx4+qG+LZpzUyeq87wyfcig+MU7mCsW83HtUW/Awj0JLgHXPY1zbtEvdyqIcO6Ekhzz 91vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970501; x=1697575301; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=OVSFcN3hgU5Wv+MUFYElNWnOc10PkPLhn8pZyce9ayk=; b=QTIcRsG0vA98TFNaYw7zTvEP1THvejexfxvApW7EqmNrOqf8Pfs5z0mcCVj++f0BP+ Q8FHSTVyZKPNIFZxoHc2+pvmki/7/4VRNwH8ZgE+6TmQ+5A8srYodwbzI1oRANIpvAJM JTbt00MFh4UXVnmLvMaQ2AgCk4VJxoN1uhtlgLityle4v9/0NigU8rLHzT3/S9+6+GnO Bg9ci624/yPFytZvtMRJH3a2nQS3OHKtUn3/Ygb3LK0DIBnhxhj8JotYsuwohCqwFUn1 3bBS3iENJZCLn37wvY/0VhGiZ6uKLF+BoOuhLtxPNcSFMSuxKGvNzTBSNjA72NFOt56J kG5w== X-Gm-Message-State: AOJu0Yxr6EttAJRe03yafHd2P6rQH3Xz1w/ItcFQw1f84ydHOCRWAG+E MYTUJz/vApTJh3YlUCRnt5IiG2DJHNlVhPE7T6XOpA== X-Google-Smtp-Source: AGHT+IFxqFG1nuO6v6ew4CA8tSwiCEkkYfTfNpr0c4G8Olk77UVSxpRA3usPMHl69BNp/UO+Uaz7sA== X-Received: by 2002:a81:7242:0:b0:589:e4aa:7b67 with SMTP id n63-20020a817242000000b00589e4aa7b67mr20852904ywc.41.1696970501001; Tue, 10 Oct 2023 13:41:41 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id s67-20020a815e46000000b0059b50f126fbsm4677065ywb.114.2023.10.10.13.41.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:40 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 32/36] btrfs: populate ordered_extent with the orig offset Date: Tue, 10 Oct 2023 16:40:47 -0400 Message-ID: <4aa3a98fb50a0f124b50235b5edc1c58908ebd0a.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org For extent encryption we have to use a logical block nr as input for the IV. For btrfs we're using the offset into the extent we're operating on. For most ordered extents this is the same as the file_offset, however for prealloc and NOCOW we have to use the original offset. Add this as an argument and plumb it through everywhere, this will be used when setting up the bio. Signed-off-by: Josef Bacik --- fs/btrfs/inode.c | 15 ++++++++++----- fs/btrfs/ordered-data.c | 22 ++++++++++++---------- fs/btrfs/ordered-data.h | 12 +++++++++--- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b0109b313217..1b844a27a0d1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1165,6 +1165,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk, ordered = btrfs_alloc_ordered_extent(inode, em->fscrypt_info, start, /* file_offset */ + start, /* orig_start */ async_extent->ram_size, /* num_bytes */ async_extent->ram_size, /* ram_bytes */ ins.objectid, /* disk_bytenr */ @@ -1428,8 +1429,8 @@ static noinline int cow_file_range(struct btrfs_inode *inode, } ordered = btrfs_alloc_ordered_extent(inode, em->fscrypt_info, - start, ram_size, ram_size, ins.objectid, - cur_alloc_size, 0, + start, start, ram_size, ram_size, + ins.objectid, cur_alloc_size, 0, 1 << BTRFS_ORDERED_REGULAR, BTRFS_COMPRESS_NONE); free_extent_map(em); @@ -2178,7 +2179,9 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode, } ordered = btrfs_alloc_ordered_extent(inode, fscrypt_info, - cur_offset, nocow_args.num_bytes, + cur_offset, + found_key.offset - nocow_args.extent_offset, + nocow_args.num_bytes, nocow_args.num_bytes, nocow_args.disk_bytenr, nocow_args.num_bytes, 0, is_prealloc @@ -7087,8 +7090,9 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode, fscrypt_info = orig_em->fscrypt_info; } - ordered = btrfs_alloc_ordered_extent(inode, fscrypt_info, start, len, - len, block_start, block_len, 0, + ordered = btrfs_alloc_ordered_extent(inode, fscrypt_info, start, + orig_start, len, len, block_start, + block_len, 0, (1 << type) | (1 << BTRFS_ORDERED_DIRECT), BTRFS_COMPRESS_NONE); @@ -10612,6 +10616,7 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, } ordered = btrfs_alloc_ordered_extent(inode, em->fscrypt_info, start, + start - encoded->unencoded_offset, num_bytes, ram_bytes, ins.objectid, ins.offset, encoded->unencoded_offset, (1 << BTRFS_ORDERED_ENCODED) | diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index ee3138a6d11e..75eb42b5c95b 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -148,9 +148,9 @@ static inline struct rb_node *ordered_tree_search(struct btrfs_inode *inode, static struct btrfs_ordered_extent *alloc_ordered_extent( struct btrfs_inode *inode, struct fscrypt_extent_info *fscrypt_info, - u64 file_offset, u64 num_bytes, u64 ram_bytes, - u64 disk_bytenr, u64 disk_num_bytes, u64 offset, - unsigned long flags, int compress_type) + u64 file_offset, u64 orig_offset, u64 num_bytes, + u64 ram_bytes, u64 disk_bytenr, u64 disk_num_bytes, + u64 offset, unsigned long flags, int compress_type) { struct btrfs_ordered_extent *entry; int ret; @@ -175,6 +175,7 @@ static struct btrfs_ordered_extent *alloc_ordered_extent( return ERR_PTR(-ENOMEM); entry->file_offset = file_offset; + entry->orig_offset = orig_offset; entry->num_bytes = num_bytes; entry->ram_bytes = ram_bytes; entry->disk_bytenr = disk_bytenr; @@ -253,6 +254,7 @@ static void insert_ordered_extent(struct btrfs_ordered_extent *entry) * @inode: Inode that this extent is for. * @fscrypt_info: The fscrypt_extent_info for this extent, if necessary. * @file_offset: Logical offset in file where the extent starts. + * @orig_offset: Logical offset of the original extent (PREALLOC or NOCOW) * @num_bytes: Logical length of extent in file. * @ram_bytes: Full length of unencoded data. * @disk_bytenr: Offset of extent on disk. @@ -270,17 +272,17 @@ static void insert_ordered_extent(struct btrfs_ordered_extent *entry) struct btrfs_ordered_extent *btrfs_alloc_ordered_extent( struct btrfs_inode *inode, struct fscrypt_extent_info *fscrypt_info, - u64 file_offset, u64 num_bytes, u64 ram_bytes, - u64 disk_bytenr, u64 disk_num_bytes, u64 offset, - unsigned long flags, int compress_type) + u64 file_offset, u64 orig_offset, u64 num_bytes, + u64 ram_bytes, u64 disk_bytenr, u64 disk_num_bytes, + u64 offset, unsigned long flags, int compress_type) { struct btrfs_ordered_extent *entry; ASSERT((flags & ~BTRFS_ORDERED_TYPE_FLAGS) == 0); entry = alloc_ordered_extent(inode, fscrypt_info, file_offset, - num_bytes, ram_bytes, disk_bytenr, - disk_num_bytes, offset, flags, + orig_offset, num_bytes, ram_bytes, + disk_bytenr, disk_num_bytes, offset, flags, compress_type); if (!IS_ERR(entry)) insert_ordered_extent(entry); @@ -1174,8 +1176,8 @@ struct btrfs_ordered_extent *btrfs_split_ordered_extent( return ERR_PTR(-EINVAL); new = alloc_ordered_extent(inode, ordered->fscrypt_info, file_offset, - len, len, disk_bytenr, len, 0, flags, - ordered->compress_type); + ordered->orig_offset, len, len, disk_bytenr, + len, 0, flags, ordered->compress_type); if (IS_ERR(new)) return new; diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index 767efcd74bee..af8b51c255ee 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -83,6 +83,12 @@ struct btrfs_ordered_extent { /* logical offset in the file */ u64 file_offset; + /* + * The original logical offset of the extent, this is for NOCOW and + * PREALLOC extents, otherwise it'll be the same as file_offset. + */ + u64 orig_offset; + /* * These fields directly correspond to the same fields in * btrfs_file_extent_item. @@ -172,9 +178,9 @@ bool btrfs_dec_test_ordered_pending(struct btrfs_inode *inode, struct btrfs_ordered_extent *btrfs_alloc_ordered_extent( struct btrfs_inode *inode, struct fscrypt_extent_info *fscrypt_info, - u64 file_offset, u64 num_bytes, u64 ram_bytes, - u64 disk_bytenr, u64 disk_num_bytes, u64 offset, - unsigned long flags, int compress_type); + u64 file_offset, u64 orig_offset, u64 num_bytes, + u64 ram_bytes, u64 disk_bytenr, u64 disk_num_bytes, + u64 offset, unsigned long flags, int compress_type); void btrfs_add_ordered_sum(struct btrfs_ordered_extent *entry, struct btrfs_ordered_sum *sum); struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct btrfs_inode *inode, From patchwork Tue Oct 10 20:40:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416092 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 13102CD68ED for ; Tue, 10 Oct 2023 20:41:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343877AbjJJUl5 (ORCPT ); Tue, 10 Oct 2023 16:41:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42360 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234481AbjJJUlp (ORCPT ); Tue, 10 Oct 2023 16:41:45 -0400 Received: from mail-yw1-x112e.google.com (mail-yw1-x112e.google.com [IPv6:2607:f8b0:4864:20::112e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EA27EC4 for ; Tue, 10 Oct 2023 13:41:42 -0700 (PDT) Received: by mail-yw1-x112e.google.com with SMTP id 00721157ae682-5a1ec43870cso76020747b3.0 for ; Tue, 10 Oct 2023 13:41:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970502; x=1697575302; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=S7o7qRJqT7WXIHnR39I2blCqbRVV+PPhUWMOckSNH4U=; b=vM+pPHIXQtZuKbji5vowhecXexz6KycDpHdi2gvrUae+3st2fjCu1EhUC51j4n2pQf BVcyXUeMQ7MEVcPF/3uho68LpMppfpfuE6MxJdtaM4towevnGJNIdYxwbqZC4iKQ+ley hpZTKmfTdnSXEdzq1u97O4tNdqB1sbpaiTVbR/ic5rH7+r2CqGH7SBw+42DgubmJ5N1f 1rjZxJFiOyn1PecufmqEyf1uwxoooCe7ly635VBsX9Lx994xee3jtP0ug7XlSVOBFVwb zhr4+M4A+zpYEhFXLtJo9MzUbrMhWOeCb89vG601w/Xe1QVwModgRnAps01lef/CNy3d 6WmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970502; x=1697575302; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=S7o7qRJqT7WXIHnR39I2blCqbRVV+PPhUWMOckSNH4U=; b=cxegDR97zmz2VKACJZdKMgca6xQSsD0Rj0TozqDETf2Qp5RmmAvLRx5HyKxZKtRPkU jFMy9xbO1md9UqM6noR3JYvhS6FfFqlldO6X+Kqx6RJWdeqR5akTO99BQHgCPn9epP1f 3lnVnuzydwfK7v/eczW0InBBdfpUOR5pozXAJozYowFZcXvhoZC070fmXJ/OYM414S2w agRYMNeyW6cCMWt3E436AiQJGos8Joa182vu7Tiv9ONM50qtj2ZO7dm/O81nru7BvxhE K3whD57bQzGwb2TrRJjh7aTeKHi3VLUYfVErDcTShMAY7L8+/JsyCQROa/EdFvVgkHi6 gpOQ== X-Gm-Message-State: AOJu0YyEGTXbMSeCPq7mfKR64WHHNLKhRgXk6WLk6gN0mF9lBk4gBjLN vNsZnH+wqMmXE4PFCP2I9id5cLr58XaLzThqzeVa1Q== X-Google-Smtp-Source: AGHT+IF56fOXVijiTvVq7mGk6XMP5ct7mplE+soyERrKF85z3nWuaShbfnhDav7lNYWAoe69p25SRQ== X-Received: by 2002:a81:5bd5:0:b0:589:f9f0:2e8c with SMTP id p204-20020a815bd5000000b00589f9f02e8cmr19088355ywb.48.1696970501984; Tue, 10 Oct 2023 13:41:41 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id o140-20020a0dcc92000000b005a7c829dda2sm484413ywd.84.2023.10.10.13.41.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:41 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 33/36] btrfs: set the bio fscrypt context when applicable Date: Tue, 10 Oct 2023 16:40:48 -0400 Message-ID: <64e97e21c9aa1a1c48252142c6e02297324d2558.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org Now that we have the fscrypt_info plumbed through everywhere, add the code to setup the bio encryption context from the extent context. We use the per-extent fscrypt_extent_info for encryption/decryption. We use the offset into the extent as the lblk for fscrypt. So the start of the extent has the lblk of 0, 4k into the extent has the lblk of 4k, etc. This is done to allow things like relocation to continue to work properly. Signed-off-by: Josef Bacik --- fs/btrfs/compression.c | 6 ++++ fs/btrfs/extent_io.c | 63 +++++++++++++++++++++++++++++++++++++++++- fs/btrfs/fscrypt.c | 36 ++++++++++++++++++++++++ fs/btrfs/fscrypt.h | 22 +++++++++++++++ fs/btrfs/inode.c | 10 +++++++ 5 files changed, 136 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 19b22b4653c8..3f586ee40b94 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -36,6 +36,7 @@ #include "zoned.h" #include "file-item.h" #include "super.h" +#include "fscrypt.h" static struct bio_set btrfs_compressed_bioset; @@ -301,6 +302,9 @@ void btrfs_submit_compressed_write(struct btrfs_ordered_extent *ordered, cb->bbio.ordered = ordered; btrfs_add_compressed_bio_pages(cb); + btrfs_set_bio_crypt_ctx_from_extent(&cb->bbio.bio, inode, + ordered->fscrypt_info, 0); + btrfs_submit_bio(&cb->bbio, 0); } @@ -504,6 +508,8 @@ void btrfs_submit_compressed_read(struct btrfs_bio *bbio) cb->compress_type = em->compress_type; cb->orig_bbio = bbio; + btrfs_set_bio_crypt_ctx_from_extent(&cb->bbio.bio, inode, + em->fscrypt_info, 0); free_extent_map(em); cb->nr_pages = DIV_ROUND_UP(compressed_len, PAGE_SIZE); diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index c4265826278d..2251417106ea 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -37,6 +37,7 @@ #include "dev-replace.h" #include "super.h" #include "transaction.h" +#include "fscrypt.h" static struct kmem_cache *extent_buffer_cache; @@ -103,6 +104,10 @@ struct btrfs_bio_ctrl { blk_opf_t opf; btrfs_bio_end_io_t end_io_func; struct writeback_control *wbc; + + /* This is set for reads and we have encryption. */ + struct fscrypt_extent_info *fscrypt_info; + u64 orig_start; }; static void submit_one_bio(struct btrfs_bio_ctrl *bio_ctrl) @@ -707,10 +712,31 @@ static bool btrfs_bio_is_contig(struct btrfs_bio_ctrl *bio_ctrl, struct page *page, u64 disk_bytenr, unsigned int pg_offset) { - struct bio *bio = &bio_ctrl->bbio->bio; + struct inode *inode = page->mapping->host; + struct btrfs_bio *bbio = bio_ctrl->bbio; + struct bio *bio = &bbio->bio; struct bio_vec *bvec = bio_last_bvec_all(bio); const sector_t sector = disk_bytenr >> SECTOR_SHIFT; + if (IS_ENCRYPTED(inode)) { + u64 file_offset = page_offset(page) + pg_offset; + u64 offset = 0; + struct fscrypt_extent_info *fscrypt_info = NULL; + + /* bio_ctrl->fscrypt_info is only set in the READ case. */ + if (bio_ctrl->fscrypt_info) { + offset = file_offset - bio_ctrl->orig_start; + fscrypt_info = bio_ctrl->fscrypt_info; + } else if (bbio->ordered) { + fscrypt_info = bbio->ordered->fscrypt_info; + offset = file_offset - bbio->ordered->orig_offset; + } + + if (!btrfs_mergeable_encrypted_bio(bio, inode, fscrypt_info, + offset)) + return false; + } + if (bio_ctrl->compress_type != BTRFS_COMPRESS_NONE) { /* * For compression, all IO should have its logical bytenr set @@ -741,6 +767,8 @@ static void alloc_new_bio(struct btrfs_inode *inode, { struct btrfs_fs_info *fs_info = inode->root->fs_info; struct btrfs_bio *bbio; + struct fscrypt_extent_info *fscrypt_info = NULL; + u64 offset = 0; bbio = btrfs_bio_alloc(BIO_MAX_VECS, bio_ctrl->opf, fs_info, bio_ctrl->end_io_func, NULL); @@ -760,6 +788,8 @@ static void alloc_new_bio(struct btrfs_inode *inode, ordered->file_offset + ordered->disk_num_bytes - file_offset); bbio->ordered = ordered; + fscrypt_info = ordered->fscrypt_info; + offset = file_offset - ordered->orig_offset; } /* @@ -770,7 +800,13 @@ static void alloc_new_bio(struct btrfs_inode *inode, */ bio_set_dev(&bbio->bio, fs_info->fs_devices->latest_dev->bdev); wbc_init_bio(bio_ctrl->wbc, &bbio->bio); + } else { + fscrypt_info = bio_ctrl->fscrypt_info; + offset = file_offset - bio_ctrl->orig_start; } + + btrfs_set_bio_crypt_ctx_from_extent(&bbio->bio, inode, fscrypt_info, + offset); } /* @@ -1004,6 +1040,8 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, bool force_bio_submit = false; u64 disk_bytenr; + bio_ctrl->fscrypt_info = NULL; + ASSERT(IS_ALIGNED(cur, fs_info->sectorsize)); if (cur >= last_byte) { iosize = PAGE_SIZE - pg_offset; @@ -1078,6 +1116,22 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, if (prev_em_start) *prev_em_start = em->start; + /* + * We use the extent offset for the IV when decrypting the page, + * so we have to set the extent_offset based on the orig_start + * for this extent. Also save the fscrypt_info so the bio ctx + * can be set properly. If this inode isn't encrypted this + * won't do anything. + * + * If we're compressed we'll handle all of this in + * btrfs_submit_compressed_read. + */ + if (compress_type == BTRFS_COMPRESS_NONE) { + bio_ctrl->orig_start = em->orig_start; + bio_ctrl->fscrypt_info = + fscrypt_get_extent_info(em->fscrypt_info); + } + free_extent_map(em); em = NULL; @@ -1089,6 +1143,9 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, end_page_read(page, true, cur, iosize); cur = cur + iosize; pg_offset += iosize; + + /* This shouldn't be set, but clear it just in case. */ + fscrypt_put_extent_info(bio_ctrl->fscrypt_info); continue; } /* the get_extent function already copied into the page */ @@ -1097,6 +1154,9 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, end_page_read(page, true, cur, iosize); cur = cur + iosize; pg_offset += iosize; + + /* This shouldn't be set, but clear it just in case. */ + fscrypt_put_extent_info(bio_ctrl->fscrypt_info); continue; } @@ -1109,6 +1169,7 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, submit_one_bio(bio_ctrl); submit_extent_page(bio_ctrl, disk_bytenr, page, iosize, pg_offset); + fscrypt_put_extent_info(bio_ctrl->fscrypt_info); cur = cur + iosize; pg_offset += iosize; } diff --git a/fs/btrfs/fscrypt.c b/fs/btrfs/fscrypt.c index 7a7272cb83ec..726cb6121934 100644 --- a/fs/btrfs/fscrypt.c +++ b/fs/btrfs/fscrypt.c @@ -262,6 +262,42 @@ size_t btrfs_fscrypt_extent_context_size(struct btrfs_inode *inode) fscrypt_extent_context_size(&inode->vfs_inode); } +void btrfs_set_bio_crypt_ctx_from_extent(struct bio *bio, + struct btrfs_inode *inode, + struct fscrypt_extent_info *fi, + u64 logical_offset) +{ + if (!fi) + return; + + /* + * fscrypt uses bytes >> s_blocksize_bits for the block numbers, so we + * have to adjust everything based on our sectorsize so that the DUN + * calculations are correct. + */ + logical_offset = div64_u64(logical_offset, + inode->root->fs_info->sectorsize); + fscrypt_set_bio_crypt_ctx_from_extent(bio, &inode->vfs_inode, fi, + logical_offset, GFP_NOFS); +} + +bool btrfs_mergeable_encrypted_bio(struct bio *bio, struct inode *inode, + struct fscrypt_extent_info *fi, + u64 logical_offset) +{ + if (!fi) + return true; + + /* + * fscrypt uses bytes >> s_blocksize_bits for the block numbers, so we + * have to adjust everything based on our sectorsize so that the DUN + * calculations are correct. + */ + logical_offset = div64_u64(logical_offset, + BTRFS_I(inode)->root->fs_info->sectorsize); + return fscrypt_mergeable_extent_bio(bio, inode, fi, logical_offset); +} + const struct fscrypt_operations btrfs_fscrypt_ops = { .has_per_extent_encryption = 1, .get_context = btrfs_fscrypt_get_context, diff --git a/fs/btrfs/fscrypt.h b/fs/btrfs/fscrypt.h index 2882a4a9d978..756375ade0b6 100644 --- a/fs/btrfs/fscrypt.h +++ b/fs/btrfs/fscrypt.h @@ -28,6 +28,13 @@ int btrfs_fscrypt_save_extent_info(struct btrfs_inode *inode, struct btrfs_path *path, struct fscrypt_extent_info *fi); size_t btrfs_fscrypt_extent_context_size(struct btrfs_inode *inode); +void btrfs_set_bio_crypt_ctx_from_extent(struct bio *bio, + struct btrfs_inode *inode, + struct fscrypt_extent_info *fi, + u64 logical_offset); +bool btrfs_mergeable_encrypted_bio(struct bio *bio, struct inode *inode, + struct fscrypt_extent_info *fi, + u64 logical_offset); #else static inline int btrfs_fscrypt_save_extent_info(struct btrfs_inode *inode, @@ -66,6 +73,21 @@ static inline size_t btrfs_fscrypt_extent_context_size(struct btrfs_inode *inode { return 0; } + +static inline void btrfs_set_bio_crypt_ctx_from_extent(struct bio *bio, + struct btrfs_inode *inode, + struct fscrypt_extent_info *fi, + u64 logical_offset) +{ +} + +static inline bool btrfs_mergeable_encrypted_bio(struct bio *bio, + struct inode *inode, + struct fscrypt_extent_info *fi, + u64 logical_offset) +{ + return true; +} #endif /* CONFIG_FS_ENCRYPTION */ extern const struct fscrypt_operations btrfs_fscrypt_ops; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 1b844a27a0d1..4f5bcfb5c0c1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7895,6 +7895,8 @@ static void btrfs_dio_submit_io(const struct iomap_iter *iter, struct bio *bio, struct btrfs_dio_private *dip = container_of(bbio, struct btrfs_dio_private, bbio); struct btrfs_dio_data *dio_data = iter->private; + struct fscrypt_extent_info *fscrypt_info = NULL; + u64 offset = 0; btrfs_bio_init(bbio, BTRFS_I(iter->inode)->root->fs_info, btrfs_dio_end_io, bio->bi_private); @@ -7916,6 +7918,9 @@ static void btrfs_dio_submit_io(const struct iomap_iter *iter, struct bio *bio, if (iter->flags & IOMAP_WRITE) { int ret; + offset = file_offset - dio_data->ordered->orig_offset; + fscrypt_info = dio_data->ordered->fscrypt_info; + ret = btrfs_extract_ordered_extent(bbio, dio_data->ordered); if (ret) { btrfs_finish_ordered_extent(dio_data->ordered, NULL, @@ -7925,8 +7930,13 @@ static void btrfs_dio_submit_io(const struct iomap_iter *iter, struct bio *bio, iomap_dio_bio_end_io(bio); return; } + } else { + fscrypt_info = dio_data->fscrypt_info; + offset = file_offset - dio_data->orig_start; } + btrfs_set_bio_crypt_ctx_from_extent(&bbio->bio, bbio->inode, + fscrypt_info, offset); btrfs_submit_bio(bbio, 0); } From patchwork Tue Oct 10 20:40:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416091 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 1C419CD80DE for ; Tue, 10 Oct 2023 20:41:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343745AbjJJUl4 (ORCPT ); Tue, 10 Oct 2023 16:41:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343991AbjJJUlq (ORCPT ); Tue, 10 Oct 2023 16:41:46 -0400 Received: from mail-yw1-x112e.google.com (mail-yw1-x112e.google.com [IPv6:2607:f8b0:4864:20::112e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A37A7BA for ; Tue, 10 Oct 2023 13:41:44 -0700 (PDT) Received: by mail-yw1-x112e.google.com with SMTP id 00721157ae682-579de633419so74998087b3.3 for ; Tue, 10 Oct 2023 13:41:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970503; x=1697575303; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=L4BaCdes/ph+FBDRPrYEBu7SdLjcMrWxDC5DvBg0S2c=; b=egYpJ/oT8YjKfmr1j3QA1LQIq+yYs5wdhHKnWoPE+rTmlI/be/v5bBspEttg3DetmU B46z7P64K9Elh0MktZafDJSMBNglIXtTAN6wJM7BsRhyTpVWdiKkqCWe2GJqrMgTa+8A vkTmTUvBDlnPEN8VZz0wqR82SRDO0wNCW4hjSGs9F3WcE88LWLOD903GzENUy13P/QAP aAFJL9ML6NyHMvjLLuNF31TOEmGTUTQU87OV+NM7Hv7pVzTC2/Gcgua7/PiSPU2nn8TE c4hCUsnvHNwNN997XjFjkwTR/0QzYMnZDoOprrcaUEuLmjci71X8Dgzj7sDdHrino9dK 9KWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970503; x=1697575303; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=L4BaCdes/ph+FBDRPrYEBu7SdLjcMrWxDC5DvBg0S2c=; b=DnGE6VlvWNa0vFuxgsyAfUbDFmWM4cYiztHtFUI6wX86OPvLZvFv8uxUvza0dPB0Uy n4oT6iGQI2Xlj+MWuTFTWw7Hn8THolMuyw27Lz9/9GLyAyyU5gQjV0r0W3vKb6J5e5Sa A884p1QKgI1FFoXNrds60mY3hQMsvvXtPuG4aM+yCcGVrh1VS/v+CbDS8CP80JxfWE1O MI36GjEpnHHkXjQm1FvNIZla4/l5D3PRe39fG2eaABGJHiTK4GUX5kUKpVDPMeTkwZk6 SZKrGbfKxQ/E2o3PJ6ntym6DpzmkrdSpekNBkDz9x+ZnmwCkXlMc3t19JorqA2nPwBUS US5Q== X-Gm-Message-State: AOJu0YyhxErmvUHnCvam8jsW7mhSrv9+OzoceZn6LxkxS4Z5/3Fq+JMl OpP+aDG+FfDh2sdTs6x91BS1iZ4/mFRtwQs0j1i/Rw== X-Google-Smtp-Source: AGHT+IGFFFqdGS+bEMrI8IIbPKrLa10j5ewUtMWPqPRYQCytN6foBRilPYIxmD8Hxi9PGHUSYl3Yww== X-Received: by 2002:a0d:c8c3:0:b0:59b:fb69:1639 with SMTP id k186-20020a0dc8c3000000b0059bfb691639mr18781097ywd.32.1696970503228; Tue, 10 Oct 2023 13:41:43 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id r70-20020a0de849000000b00570253fc3e5sm115304ywe.105.2023.10.10.13.41.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:42 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 34/36] btrfs: add a bio argument to btrfs_csum_one_bio Date: Tue, 10 Oct 2023 16:40:49 -0400 Message-ID: <837a5b3c1449c0d4f83fee09be721114398fa47d.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org We only ever needed the bbio in btrfs_csum_one_bio, since that has the bio embedded in it. However with encryption we'll have a different bio with the encrypted data in it, and the original bbio. Update btrfs_csum_one_bio to take the bio we're going to csum as an argument, which will allow us to csum the encrypted bio and stuff the csums into the corresponding bbio to be used later when the IO completes. Signed-off-by: Josef Bacik --- fs/btrfs/bio.c | 2 +- fs/btrfs/file-item.c | 3 +-- fs/btrfs/file-item.h | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c index 4f3b693a16b1..90e4d4709fa3 100644 --- a/fs/btrfs/bio.c +++ b/fs/btrfs/bio.c @@ -533,7 +533,7 @@ static blk_status_t btrfs_bio_csum(struct btrfs_bio *bbio) { if (bbio->bio.bi_opf & REQ_META) return btree_csum_one_bio(bbio); - return btrfs_csum_one_bio(bbio); + return btrfs_csum_one_bio(bbio, &bbio->bio); } /* diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index 35036fab58c4..d925d6d98bf4 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c @@ -730,13 +730,12 @@ int btrfs_lookup_csums_bitmap(struct btrfs_root *root, struct btrfs_path *path, /* * Calculate checksums of the data contained inside a bio. */ -blk_status_t btrfs_csum_one_bio(struct btrfs_bio *bbio) +blk_status_t btrfs_csum_one_bio(struct btrfs_bio *bbio, struct bio *bio) { struct btrfs_ordered_extent *ordered = bbio->ordered; struct btrfs_inode *inode = bbio->inode; struct btrfs_fs_info *fs_info = inode->root->fs_info; SHASH_DESC_ON_STACK(shash, fs_info->csum_shash); - struct bio *bio = &bbio->bio; struct btrfs_ordered_sum *sums; char *data; struct bvec_iter iter; diff --git a/fs/btrfs/file-item.h b/fs/btrfs/file-item.h index bb79014024bd..e52d5d71d533 100644 --- a/fs/btrfs/file-item.h +++ b/fs/btrfs/file-item.h @@ -51,7 +51,7 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans, int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_ordered_sum *sums); -blk_status_t btrfs_csum_one_bio(struct btrfs_bio *bbio); +blk_status_t btrfs_csum_one_bio(struct btrfs_bio *bbio, struct bio *bio); blk_status_t btrfs_alloc_dummy_sum(struct btrfs_bio *bbio); int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, struct list_head *list, int search_commit, From patchwork Tue Oct 10 20:40:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416093 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 86333CD690D for ; Tue, 10 Oct 2023 20:41:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234283AbjJJUl5 (ORCPT ); Tue, 10 Oct 2023 16:41:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45940 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343997AbjJJUlr (ORCPT ); Tue, 10 Oct 2023 16:41:47 -0400 Received: from mail-yw1-x1133.google.com (mail-yw1-x1133.google.com [IPv6:2607:f8b0:4864:20::1133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A7A22B7 for ; Tue, 10 Oct 2023 13:41:45 -0700 (PDT) Received: by mail-yw1-x1133.google.com with SMTP id 00721157ae682-5a7d532da4bso6611067b3.2 for ; Tue, 10 Oct 2023 13:41:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970504; x=1697575304; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=X6Ati+EqeLVccyZuz2RaSUk3+ioP3QFcOhWT02y0KiE=; b=zIcGb1SSsOLAMex5+HxLe4k9icFzdAyGnuHW5ZSjvz0At9zK5DferQL1LzHdr2zKDr SaVv9oivUky0t92kQT2PVNWTBfrvxclq3lGtGSjG3ZIKaRLbv17pmeN+zeT19ExYaiuq KKG9F+5Pi2kHKS3gD0COHkKSW7f6cumgo8qlPJeIKfRgwiMTYzXcfklUOKpTLIygpboN sRPX2PufDRYRtqcTJVllXlB0W/+aBzwDknWRD6ZoByKz4vsUQL4db1EbhoZAUjDRytQs Rp5On1ocgdEp8tuJ/P3Yb4EmfOa+V9ua7g+ThaEguH/94gTeh3LCapzNaqJq1lyW4c9j kNaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970504; x=1697575304; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=X6Ati+EqeLVccyZuz2RaSUk3+ioP3QFcOhWT02y0KiE=; b=LB8zEZAzP5qp4aaTpm49ODSIgl3J3I90xmUNH3CV/ezcwVMtRI7cjEhFaH/oqXggWa 78dZdQD1dbESRK/RSc6DOw+w2fi9xepuhpPysBycXAqU/K9BkOckgtAvSBHDbNm7ABHh CfmFZocR2JtqFrceh9wnODUK/NGYGKxOd9t3gV8wPRV7VU3a4up3z8NJs8nCjNusV6v2 /akwxCT2jobK9/9s0HUJh6olxzlqYok6KoI9thbrDTh1OP2WWC+93rjLeWgMA2VdYb+d 75PdawNwPurmBD91K55iRhTqDTYxLUk//rIJVElvRaHzGHia6M+3h2QP1mc6yIfrN6R/ Go1A== X-Gm-Message-State: AOJu0YyziRkl+Aad4XtkL3X+yPLc6t5MfLGfdxJJ6wlib/7JB/7SEi7x qlkg6nb3hF1twDch+/0dDk5qXCIhHSd9EEUd7nph8g== X-Google-Smtp-Source: AGHT+IFqKF/wsw+UCtf7hIO1uKFD9kz0EZod4dWmk76nppECHfp13oAGNwIV4c4UnsQ1Wr8Amy/sBg== X-Received: by 2002:a05:690c:3509:b0:5a7:dc7b:22 with SMTP id fq9-20020a05690c350900b005a7dc7b0022mr300048ywb.7.1696970504608; Tue, 10 Oct 2023 13:41:44 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id c65-20020a0df344000000b0059adc0c4392sm4607450ywf.140.2023.10.10.13.41.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:44 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 35/36] btrfs: add orig_logical to btrfs_bio Date: Tue, 10 Oct 2023 16:40:50 -0400 Message-ID: <972da3fc6287abc2b766fa12acf9aca61c00213a.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org When checksumming the encrypted bio on writes we need to know which logical address this checksum is for. At the point where we get the encrypted bio the bi_sector is the physical location on the target disk, so we need to save the original logical offset in the btrfs_bio. Then we can use this when csum'ing the bio instead of the bio->iter.bi_sector. Signed-off-by: Josef Bacik --- fs/btrfs/bio.c | 9 +++++++++ fs/btrfs/bio.h | 3 +++ fs/btrfs/file-item.c | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c index 90e4d4709fa3..7d6931e53beb 100644 --- a/fs/btrfs/bio.c +++ b/fs/btrfs/bio.c @@ -96,6 +96,7 @@ static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info, if (bbio_has_ordered_extent(bbio)) { refcount_inc(&orig_bbio->ordered->refs); bbio->ordered = orig_bbio->ordered; + orig_bbio->orig_logical += map_length; } atomic_inc(&orig_bbio->pending_ios); return bbio; @@ -674,6 +675,14 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num) goto fail; } + /* + * For fscrypt writes we will get the encrypted bio after we've remapped + * our bio to the physical disk location, so we need to save the + * original bytenr so we know what we're checksumming. + */ + if (bio_op(bio) == REQ_OP_WRITE && is_data_bbio(bbio)) + bbio->orig_logical = logical; + map_length = min(map_length, length); if (use_append) map_length = min(map_length, fs_info->max_zone_append_size); diff --git a/fs/btrfs/bio.h b/fs/btrfs/bio.h index ca79decee060..5d3f53dcd6d5 100644 --- a/fs/btrfs/bio.h +++ b/fs/btrfs/bio.h @@ -54,11 +54,14 @@ struct btrfs_bio { * - pointer to the checksums for this bio * - original physical address from the allocator * (for zone append only) + * - original logical address, used for checksumming fscrypt + * bios. */ struct { struct btrfs_ordered_extent *ordered; struct btrfs_ordered_sum *sums; u64 orig_physical; + u64 orig_logical; }; /* For metadata reads: parentness verification. */ diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index d925d6d98bf4..26e3bc602655 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c @@ -756,7 +756,7 @@ blk_status_t btrfs_csum_one_bio(struct btrfs_bio *bbio, struct bio *bio) sums->len = bio->bi_iter.bi_size; INIT_LIST_HEAD(&sums->list); - sums->logical = bio->bi_iter.bi_sector << SECTOR_SHIFT; + sums->logical = bbio->orig_logical; index = 0; shash->tfm = fs_info->csum_shash; From patchwork Tue Oct 10 20:40:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13416094 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 B5297E92FD2 for ; Tue, 10 Oct 2023 20:41:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343822AbjJJUl6 (ORCPT ); Tue, 10 Oct 2023 16:41:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344034AbjJJUlt (ORCPT ); Tue, 10 Oct 2023 16:41:49 -0400 Received: from mail-yw1-x1129.google.com (mail-yw1-x1129.google.com [IPv6:2607:f8b0:4864:20::1129]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E32F2D6 for ; Tue, 10 Oct 2023 13:41:46 -0700 (PDT) Received: by mail-yw1-x1129.google.com with SMTP id 00721157ae682-59f4f80d084so73974117b3.1 for ; Tue, 10 Oct 2023 13:41:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1696970506; x=1697575306; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=NRH4SLgwNgVi2hMAGAQpqfi8yk6Nkn1gVR1vo3W10g8=; b=jS9L0u0rpIn59onc2icUtpcZBz0U7iVFRDauvfKh/absB3yHypDAfjTZx+88fWhpZX /h/MS+3ThwXVEyAzZ8bMfwVFB6eQvbsOtM2ZHdFF9bx34lB9XrZVQ3jHxBsU3WT9msv8 TnQ044+m76o+KaFgL943Mx5HAcL8wnzHETwWY5/8NWgmaCk9GxH3cGay0UFxq0DSNCln 5fScWPtdxeyu4Spqt7sD+ajW79exS0yebNIor1rRc2bYUPSAP5BV3zeZORBdAbka3Sf+ xIfPEiUvNz3G6X+Ovd+QMoaafKBHoGek1qMBRNylrV74lhU8cWpe1qmdp3Y6VDcRDQpA vv/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696970506; x=1697575306; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NRH4SLgwNgVi2hMAGAQpqfi8yk6Nkn1gVR1vo3W10g8=; b=ajgoM18rg58VvkTzdxiZavBgYAs21R5ZeiLrDcZIiAJfGhq42IxSA5UFdFecLjLSRz 3ae9yQIGlv3E6EdSEI1vDavaS2Tk/3+tD3pBc+MghFDbPsWJwklzTU4zRqMGmmEh2yMS EN82bstLmX3TlqEzwIiOVriHeaMHqBuznn59X/tSrqQFIFdlvXNBwRiERvFd6rCjjWcI w7vvEX1t4M7xyp5SF1e3CUR040FSLFN3Fg+6UgTzbx1ckjVxue1dRYNrCP37LFhKB7tv 0GzwndpcSTJKoOmnwWM2tZDKdsx5jootODsuogWN42GRzL1Mep4zT5WbE6jC31Jdbkn+ VsNQ== X-Gm-Message-State: AOJu0Yy8ayRTaAn9mfSHlPmHCdEsqe2BX79Xce+gv/VN1Ot06SOoZRbF m/TzvON5n7KUsv7tTEPu3KMo++A0PL0TtFjVFAytKw== X-Google-Smtp-Source: AGHT+IHK2WU+sKiD+8oGs+u1Es2T9ACnf24UkZOfv55x1/n8ucve05NVQ4+qQcY+OlOk7onBfZfCog== X-Received: by 2002:a81:8d52:0:b0:5a5:575:b222 with SMTP id w18-20020a818d52000000b005a50575b222mr17801693ywj.23.1696970505933; Tue, 10 Oct 2023 13:41:45 -0700 (PDT) Received: from localhost (cpe-76-182-20-124.nc.res.rr.com. [76.182.20.124]) by smtp.gmail.com with ESMTPSA id t184-20020a8183c1000000b005a247c18403sm4737130ywf.37.2023.10.10.13.41.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Oct 2023 13:41:45 -0700 (PDT) From: Josef Bacik To: linux-fscrypt@vger.kernel.org, ebiggers@kernel.org, linux-btrfs@vger.kernel.org Subject: [PATCH v2 36/36] btrfs: implement process_bio cb for fscrypt Date: Tue, 10 Oct 2023 16:40:51 -0400 Message-ID: <8fe21ee6831aef28a58672f4cb273f5689471151.1696970227.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org We are going to be checksumming the encrypted data, so we have to implement the ->process_bio fscrypt callback. This will provide us with the original bio and the encrypted bio to do work on. For WRITE's this will happen after the encrypted bio has been encrypted. For READ's this will happen after the read has completed and before the decryption step is done. For write's this is straightforward, we can just pass in the encrypted bio to btrfs_csum_one_bio and then the csums will be added to the bbio as normal. For read's this is relatively straightforward, but requires some care. We assume (because that's how it works currently) that the encrypted bio match the original bio, this is important because we save the iter of the bio before we submit. If this changes in the future we'll need a hook to give us the bi_iter of the decryption bio before it's submitted. We check the csums before decryption. If it doesn't match we simply error out and we let the normal path handle the repair work. Signed-off-by: Josef Bacik --- fs/btrfs/bio.c | 34 +++++++++++++++++++++++++++++++++- fs/btrfs/bio.h | 3 +++ fs/btrfs/fscrypt.c | 19 +++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c index 7d6931e53beb..27ebf6373c8f 100644 --- a/fs/btrfs/bio.c +++ b/fs/btrfs/bio.c @@ -280,6 +280,34 @@ static struct btrfs_failed_bio *repair_one_sector(struct btrfs_bio *failed_bbio, return fbio; } +blk_status_t btrfs_check_encrypted_read_bio(struct btrfs_bio *bbio, + struct bio *enc_bio) +{ + struct btrfs_inode *inode = bbio->inode; + struct btrfs_fs_info *fs_info = inode->root->fs_info; + u32 sectorsize = fs_info->sectorsize; + struct bvec_iter iter = bbio->saved_iter; + struct btrfs_device *dev = bbio->bio.bi_private; + u32 offset = 0; + + /* + * We have to use a copy of iter in case there's an error, + * btrfs_check_read_bio will handle submitting the repair bios. + */ + while (iter.bi_size) { + struct bio_vec bv = bio_iter_iovec(enc_bio, iter); + + bv.bv_len = min(bv.bv_len, sectorsize); + if (!btrfs_data_csum_ok(bbio, dev, offset, &bv)) + return BLK_STS_IOERR; + bio_advance_iter_single(enc_bio, &iter, sectorsize); + offset += sectorsize; + } + + bbio->csum_done = true; + return BLK_STS_OK; +} + static void btrfs_check_read_bio(struct btrfs_bio *bbio, struct btrfs_device *dev) { struct btrfs_inode *inode = bbio->inode; @@ -305,6 +333,10 @@ static void btrfs_check_read_bio(struct btrfs_bio *bbio, struct btrfs_device *de /* Clear the I/O error. A failed repair will reset it. */ bbio->bio.bi_status = BLK_STS_OK; + /* This was an encrypted bio and we've already done the csum check. */ + if (status == BLK_STS_OK && bbio->csum_done) + goto out; + while (iter->bi_size) { struct bio_vec bv = bio_iter_iovec(&bbio->bio, *iter); @@ -315,7 +347,7 @@ static void btrfs_check_read_bio(struct btrfs_bio *bbio, struct btrfs_device *de bio_advance_iter_single(&bbio->bio, iter, sectorsize); offset += sectorsize; } - +out: if (bbio->csum != bbio->csum_inline) kfree(bbio->csum); diff --git a/fs/btrfs/bio.h b/fs/btrfs/bio.h index 5d3f53dcd6d5..393ef32f5321 100644 --- a/fs/btrfs/bio.h +++ b/fs/btrfs/bio.h @@ -45,6 +45,7 @@ struct btrfs_bio { struct { u8 *csum; u8 csum_inline[BTRFS_BIO_INLINE_CSUM_SIZE]; + bool csum_done; struct bvec_iter saved_iter; }; @@ -110,5 +111,7 @@ void btrfs_submit_repair_write(struct btrfs_bio *bbio, int mirror_num, bool dev_ int btrfs_repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start, u64 length, u64 logical, struct page *page, unsigned int pg_offset, int mirror_num); +blk_status_t btrfs_check_encrypted_read_bio(struct btrfs_bio *bbio, + struct bio *enc_bio); #endif diff --git a/fs/btrfs/fscrypt.c b/fs/btrfs/fscrypt.c index 726cb6121934..b7e92ee5e60b 100644 --- a/fs/btrfs/fscrypt.c +++ b/fs/btrfs/fscrypt.c @@ -15,6 +15,7 @@ #include "transaction.h" #include "volumes.h" #include "xattr.h" +#include "file-item.h" /* * From a given location in a leaf, read a name into a qstr (usually a @@ -214,6 +215,23 @@ static struct block_device **btrfs_fscrypt_get_devices(struct super_block *sb, return devs; } +static blk_status_t btrfs_process_encrypted_bio(struct bio *orig_bio, + struct bio *enc_bio) +{ + struct btrfs_bio *bbio = btrfs_bio(orig_bio); + + if (bio_op(orig_bio) == REQ_OP_READ) { + /* + * We have ->saved_iter based on the orig_bio, so if the block + * layer changes we need to notice this asap so we can update + * our code to handle the new world order. + */ + ASSERT(orig_bio == enc_bio); + return btrfs_check_encrypted_read_bio(bbio, enc_bio); + } + return btrfs_csum_one_bio(bbio, enc_bio); +} + int btrfs_fscrypt_load_extent_info(struct btrfs_inode *inode, struct extent_map *em, struct btrfs_fscrypt_ctx *ctx) @@ -304,4 +322,5 @@ const struct fscrypt_operations btrfs_fscrypt_ops = { .set_context = btrfs_fscrypt_set_context, .empty_dir = btrfs_fscrypt_empty_dir, .get_devices = btrfs_fscrypt_get_devices, + .process_bio = btrfs_process_encrypted_bio, };