From patchwork Tue Sep 26 18:01: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: 13399475 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 D6237E7E65D for ; Tue, 26 Sep 2023 18:03:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235397AbjIZSDY (ORCPT ); Tue, 26 Sep 2023 14:03:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43280 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234339AbjIZSDX (ORCPT ); Tue, 26 Sep 2023 14:03:23 -0400 Received: from mail-ot1-x32e.google.com (mail-ot1-x32e.google.com [IPv6:2607:f8b0:4864:20::32e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13AE2199 for ; Tue, 26 Sep 2023 11:03:14 -0700 (PDT) Received: by mail-ot1-x32e.google.com with SMTP id 46e09a7af769-6bf04263dc8so5515088a34.3 for ; Tue, 26 Sep 2023 11:03:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751393; x=1696356193; 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=xKZ5KfwvQoxFHfRHO1WFFlTbBPmuwahyDG9auSiXsjM=; b=ynQhLCMjXNCQeUnC810RI97DTAq/EHZt2R1LZP8ZcY8qWdkQq5ZT9+aygzgsHb7CSZ oBoq27WHsWtRncZbGrQigE9BulM2N7G2TAPnVE5Yz6PLwAu087xkGDXuAfoyi+boRty5 3gcz9AMf5XjImr75kXLKCTcpgMH9xlPynMKde9Ux8xkfFZ2JGxKq1i0+QpUNigMxpFo6 IqKTmbANnUn2nvX4RZpxsod+unVf+ZyYWt0pebtdhf7KB7SaRk4eR45j4G2VNeWVf/xU wK9ra0a8oUrpMuZK3HziGUOy/YZnvyLv/s0EBvo6C0inI5Qjiif+9vZaZiOiT3Cx502T b5mA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751393; x=1696356193; 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=xKZ5KfwvQoxFHfRHO1WFFlTbBPmuwahyDG9auSiXsjM=; b=npW1pk2JpKUZiPeY4DHfV6BtuwLPrJeeYWjnVBhbYuMMLra7czZuduyet2pPYcx17D ksQrLRgq+sJO0GxpDsdFurTnmkaQ2WVuaTbaXi3QbD6oEI1Hr5zM9r7BoiBivb02WQBO 3IkVtrit5t9BgwMkxZuBM7RJPQUg3uvuvkeriEw3nDmVjxkqL77HmFJC9Zb9IOw0Jt3Y UaZBRAWSezGioqkyQKNqP3tGA7L/bBKd0WfQ6FS3n7xB6cMOcDYAC71ybqr3Leh5eKe5 CHnHB/ZvQWH9INTD9qnjsADzr6EVLzL1ZWzLh8kKeRHEzmVghxUuQZKHuNo1nxPg3d6F uZuw== X-Gm-Message-State: AOJu0YyO735fClkEjxcsboqAUnCidJ9m6nrEK04OYz94j1Yo5Lbxc0Ld o+4EXvs3KwsJyyGLTI3a3H27D3Fn6WX386xf79tMiQ== X-Google-Smtp-Source: AGHT+IGjrkxbjPFYMIdAUxBq4wNzJxt3EKLTWe/x4WjDT1VgCLriwqXj7Ot5CeQJFDv5Ficc+g/kIg== X-Received: by 2002:a05:6358:704:b0:143:61d:ffd3 with SMTP id e4-20020a056358070400b00143061dffd3mr11961363rwj.4.1695751392827; Tue, 26 Sep 2023 11:03: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 r18-20020a0cb292000000b0065b18f18709sm1528486qve.78.2023.09.26.11.03.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:12 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 01/35] fscrypt: rename fscrypt_info => fscrypt_inode_info Date: Tue, 26 Sep 2023 14:01:27 -0400 Message-ID: <14be416567dcea0096cb0d840f96fad4853dbe8c.1695750478.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-btrfs@vger.kernel.org We are going to track per-extent information, so it'll be necessary to distinguish between inode infos and extent infos. Rename fscrypt_info to fscrypt_inode_info, adjusting any lines that now exceed 80 characters. Signed-off-by: Josef Bacik --- fs/crypto/crypto.c | 13 ++++++------ fs/crypto/fname.c | 6 +++--- fs/crypto/fscrypt_private.h | 42 ++++++++++++++++++++----------------- fs/crypto/hooks.c | 2 +- fs/crypto/inline_crypt.c | 13 ++++++------ fs/crypto/keyring.c | 4 ++-- fs/crypto/keysetup.c | 38 +++++++++++++++++---------------- fs/crypto/keysetup_v1.c | 14 +++++++------ fs/crypto/policy.c | 11 +++++----- include/linux/fs.h | 4 ++-- include/linux/fscrypt.h | 6 +++--- 11 files changed, 82 insertions(+), 71 deletions(-) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 6a837e4b80dc..2b2bb5740322 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -39,7 +39,7 @@ static mempool_t *fscrypt_bounce_page_pool = NULL; static struct workqueue_struct *fscrypt_read_workqueue; static DEFINE_MUTEX(fscrypt_init_mutex); -struct kmem_cache *fscrypt_info_cachep; +struct kmem_cache *fscrypt_inode_info_cachep; void fscrypt_enqueue_decrypt_work(struct work_struct *work) { @@ -78,7 +78,7 @@ EXPORT_SYMBOL(fscrypt_free_bounce_page); * simply contain the lblk_num (e.g., IV_INO_LBLK_32). */ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num, - const struct fscrypt_info *ci) + const struct fscrypt_inode_info *ci) { u8 flags = fscrypt_policy_flags(&ci->ci_policy); @@ -107,7 +107,7 @@ int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, struct skcipher_request *req = NULL; DECLARE_CRYPTO_WAIT(wait); struct scatterlist dst, src; - struct fscrypt_info *ci = inode->i_crypt_info; + struct fscrypt_inode_info *ci = inode->i_crypt_info; struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; int res = 0; @@ -391,8 +391,9 @@ static int __init fscrypt_init(void) if (!fscrypt_read_workqueue) goto fail; - fscrypt_info_cachep = KMEM_CACHE(fscrypt_info, SLAB_RECLAIM_ACCOUNT); - if (!fscrypt_info_cachep) + fscrypt_inode_info_cachep = KMEM_CACHE(fscrypt_inode_info, + SLAB_RECLAIM_ACCOUNT); + if (!fscrypt_inode_info_cachep) goto fail_free_queue; err = fscrypt_init_keyring(); @@ -402,7 +403,7 @@ static int __init fscrypt_init(void) return 0; fail_free_info: - kmem_cache_destroy(fscrypt_info_cachep); + kmem_cache_destroy(fscrypt_inode_info_cachep); fail_free_queue: destroy_workqueue(fscrypt_read_workqueue); fail: diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 6eae3f12ad50..7b3fc189593a 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -100,7 +100,7 @@ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname, { struct skcipher_request *req = NULL; DECLARE_CRYPTO_WAIT(wait); - const struct fscrypt_info *ci = inode->i_crypt_info; + const struct fscrypt_inode_info *ci = inode->i_crypt_info; struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; union fscrypt_iv iv; struct scatterlist sg; @@ -157,7 +157,7 @@ static int fname_decrypt(const struct inode *inode, struct skcipher_request *req = NULL; DECLARE_CRYPTO_WAIT(wait); struct scatterlist src_sg, dst_sg; - const struct fscrypt_info *ci = inode->i_crypt_info; + const struct fscrypt_inode_info *ci = inode->i_crypt_info; struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; union fscrypt_iv iv; int res; @@ -568,7 +568,7 @@ EXPORT_SYMBOL_GPL(fscrypt_match_name); */ u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name) { - const struct fscrypt_info *ci = dir->i_crypt_info; + const struct fscrypt_inode_info *ci = dir->i_crypt_info; WARN_ON_ONCE(!ci->ci_dirhash_key_initialized); diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index 2d63da48635a..b982073d1fe2 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -189,18 +189,21 @@ struct fscrypt_prepared_key { }; /* - * fscrypt_info - the "encryption key" for an inode + * fscrypt_inode_info - the "encryption key" for an inode * * When an encrypted file's key is made available, an instance of this struct is * allocated and stored in ->i_crypt_info. Once created, it remains until the * inode is evicted. */ -struct fscrypt_info { +struct fscrypt_inode_info { /* The key in a form prepared for actual encryption/decryption */ struct fscrypt_prepared_key ci_enc_key; - /* True if ci_enc_key should be freed when this fscrypt_info is freed */ + /* + * True if ci_enc_key should be freed when this fscrypt_inode_info is + * freed + */ bool ci_owns_key; #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT @@ -263,7 +266,7 @@ typedef enum { } fscrypt_direction_t; /* crypto.c */ -extern struct kmem_cache *fscrypt_info_cachep; +extern struct kmem_cache *fscrypt_inode_info_cachep; int fscrypt_initialize(struct super_block *sb); int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, u64 lblk_num, struct page *src_page, @@ -294,7 +297,7 @@ union fscrypt_iv { }; void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num, - const struct fscrypt_info *ci); + const struct fscrypt_inode_info *ci); /* fname.c */ bool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy, @@ -332,17 +335,17 @@ void fscrypt_destroy_hkdf(struct fscrypt_hkdf *hkdf); /* inline_crypt.c */ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT -int fscrypt_select_encryption_impl(struct fscrypt_info *ci); +int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci); static inline bool -fscrypt_using_inline_encryption(const struct fscrypt_info *ci) +fscrypt_using_inline_encryption(const struct fscrypt_inode_info *ci) { return ci->ci_inlinecrypt; } int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, const u8 *raw_key, - const struct fscrypt_info *ci); + const struct fscrypt_inode_info *ci); void fscrypt_destroy_inline_crypt_key(struct super_block *sb, struct fscrypt_prepared_key *prep_key); @@ -353,7 +356,7 @@ void fscrypt_destroy_inline_crypt_key(struct super_block *sb, */ static inline bool fscrypt_is_key_prepared(struct fscrypt_prepared_key *prep_key, - const struct fscrypt_info *ci) + const struct fscrypt_inode_info *ci) { /* * The two smp_load_acquire()'s here pair with the smp_store_release()'s @@ -370,13 +373,13 @@ fscrypt_is_key_prepared(struct fscrypt_prepared_key *prep_key, #else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ -static inline int fscrypt_select_encryption_impl(struct fscrypt_info *ci) +static inline int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci) { return 0; } static inline bool -fscrypt_using_inline_encryption(const struct fscrypt_info *ci) +fscrypt_using_inline_encryption(const struct fscrypt_inode_info *ci) { return false; } @@ -384,7 +387,7 @@ fscrypt_using_inline_encryption(const struct fscrypt_info *ci) static inline int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, const u8 *raw_key, - const struct fscrypt_info *ci) + const struct fscrypt_inode_info *ci) { WARN_ON_ONCE(1); return -EOPNOTSUPP; @@ -398,7 +401,7 @@ fscrypt_destroy_inline_crypt_key(struct super_block *sb, static inline bool fscrypt_is_key_prepared(struct fscrypt_prepared_key *prep_key, - const struct fscrypt_info *ci) + const struct fscrypt_inode_info *ci) { return smp_load_acquire(&prep_key->tfm) != NULL; } @@ -598,17 +601,18 @@ struct fscrypt_mode { extern struct fscrypt_mode fscrypt_modes[]; int fscrypt_prepare_key(struct fscrypt_prepared_key *prep_key, - const u8 *raw_key, const struct fscrypt_info *ci); + const u8 *raw_key, const struct fscrypt_inode_info *ci); void fscrypt_destroy_prepared_key(struct super_block *sb, struct fscrypt_prepared_key *prep_key); -int fscrypt_set_per_file_enc_key(struct fscrypt_info *ci, const u8 *raw_key); +int fscrypt_set_per_file_enc_key(struct fscrypt_inode_info *ci, + const u8 *raw_key); -int fscrypt_derive_dirhash_key(struct fscrypt_info *ci, +int fscrypt_derive_dirhash_key(struct fscrypt_inode_info *ci, const struct fscrypt_master_key *mk); -void fscrypt_hash_inode_number(struct fscrypt_info *ci, +void fscrypt_hash_inode_number(struct fscrypt_inode_info *ci, const struct fscrypt_master_key *mk); int fscrypt_get_encryption_info(struct inode *inode, bool allow_unsupported); @@ -643,10 +647,10 @@ static inline int fscrypt_require_key(struct inode *inode) void fscrypt_put_direct_key(struct fscrypt_direct_key *dk); -int fscrypt_setup_v1_file_key(struct fscrypt_info *ci, +int fscrypt_setup_v1_file_key(struct fscrypt_inode_info *ci, const u8 *raw_master_key); -int fscrypt_setup_v1_file_key_via_subscribed_keyrings(struct fscrypt_info *ci); +int fscrypt_setup_v1_file_key_via_subscribed_keyrings(struct fscrypt_inode_info *ci); /* policy.c */ diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c index 6238dbcadcad..85d2975b69b7 100644 --- a/fs/crypto/hooks.c +++ b/fs/crypto/hooks.c @@ -169,7 +169,7 @@ EXPORT_SYMBOL_GPL(__fscrypt_prepare_setattr); int fscrypt_prepare_setflags(struct inode *inode, unsigned int oldflags, unsigned int flags) { - struct fscrypt_info *ci; + struct fscrypt_inode_info *ci; struct fscrypt_master_key *mk; int err; diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index 8bfb3ce86476..3cfb04b8b64f 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -39,7 +39,7 @@ static struct block_device **fscrypt_get_devices(struct super_block *sb, return devs; } -static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci) +static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_inode_info *ci) { struct super_block *sb = ci->ci_inode->i_sb; unsigned int flags = fscrypt_policy_flags(&ci->ci_policy); @@ -90,7 +90,7 @@ static void fscrypt_log_blk_crypto_impl(struct fscrypt_mode *mode, } /* Enable inline encryption for this file if supported. */ -int fscrypt_select_encryption_impl(struct fscrypt_info *ci) +int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci) { const struct inode *inode = ci->ci_inode; struct super_block *sb = inode->i_sb; @@ -152,7 +152,7 @@ int fscrypt_select_encryption_impl(struct fscrypt_info *ci) int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, const u8 *raw_key, - const struct fscrypt_info *ci) + const struct fscrypt_inode_info *ci) { const struct inode *inode = ci->ci_inode; struct super_block *sb = inode->i_sb; @@ -232,7 +232,8 @@ bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode) } EXPORT_SYMBOL_GPL(__fscrypt_inode_uses_inline_crypto); -static void fscrypt_generate_dun(const struct fscrypt_info *ci, u64 lblk_num, +static void fscrypt_generate_dun(const struct fscrypt_inode_info *ci, + u64 lblk_num, u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE]) { union fscrypt_iv iv; @@ -265,7 +266,7 @@ static void fscrypt_generate_dun(const struct fscrypt_info *ci, u64 lblk_num, void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, u64 first_lblk, gfp_t gfp_mask) { - const struct fscrypt_info *ci; + const struct fscrypt_inode_info *ci; u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE]; if (!fscrypt_inode_uses_inline_crypto(inode)) @@ -456,7 +457,7 @@ EXPORT_SYMBOL_GPL(fscrypt_dio_supported); */ u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks) { - const struct fscrypt_info *ci; + const struct fscrypt_inode_info *ci; u32 dun; if (!fscrypt_inode_uses_inline_crypto(inode)) diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index 7cbb1fd872ac..a51fa6a33de1 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -867,7 +867,7 @@ static void shrink_dcache_inode(struct inode *inode) static void evict_dentries_for_decrypted_inodes(struct fscrypt_master_key *mk) { - struct fscrypt_info *ci; + struct fscrypt_inode_info *ci; struct inode *inode; struct inode *toput_inode = NULL; @@ -917,7 +917,7 @@ static int check_for_busy_inodes(struct super_block *sb, /* select an example file to show for debugging purposes */ struct inode *inode = list_first_entry(&mk->mk_decrypted_inodes, - struct fscrypt_info, + struct fscrypt_inode_info, ci_master_key_link)->ci_inode; ino = inode->i_ino; } diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index 361f41ef46c7..cbcbe582737e 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -148,7 +148,7 @@ fscrypt_allocate_skcipher(struct fscrypt_mode *mode, const u8 *raw_key, * and IV generation method (@ci->ci_policy.flags). */ int fscrypt_prepare_key(struct fscrypt_prepared_key *prep_key, - const u8 *raw_key, const struct fscrypt_info *ci) + const u8 *raw_key, const struct fscrypt_inode_info *ci) { struct crypto_skcipher *tfm; @@ -178,13 +178,14 @@ void fscrypt_destroy_prepared_key(struct super_block *sb, } /* Given a per-file encryption key, set up the file's crypto transform object */ -int fscrypt_set_per_file_enc_key(struct fscrypt_info *ci, const u8 *raw_key) +int fscrypt_set_per_file_enc_key(struct fscrypt_inode_info *ci, + const u8 *raw_key) { ci->ci_owns_key = true; return fscrypt_prepare_key(&ci->ci_enc_key, raw_key, ci); } -static int setup_per_mode_enc_key(struct fscrypt_info *ci, +static int setup_per_mode_enc_key(struct fscrypt_inode_info *ci, struct fscrypt_master_key *mk, struct fscrypt_prepared_key *keys, u8 hkdf_context, bool include_fs_uuid) @@ -265,7 +266,7 @@ static int fscrypt_derive_siphash_key(const struct fscrypt_master_key *mk, return 0; } -int fscrypt_derive_dirhash_key(struct fscrypt_info *ci, +int fscrypt_derive_dirhash_key(struct fscrypt_inode_info *ci, const struct fscrypt_master_key *mk) { int err; @@ -279,7 +280,7 @@ int fscrypt_derive_dirhash_key(struct fscrypt_info *ci, return 0; } -void fscrypt_hash_inode_number(struct fscrypt_info *ci, +void fscrypt_hash_inode_number(struct fscrypt_inode_info *ci, const struct fscrypt_master_key *mk) { WARN_ON_ONCE(ci->ci_inode->i_ino == 0); @@ -289,7 +290,7 @@ void fscrypt_hash_inode_number(struct fscrypt_info *ci, &mk->mk_ino_hash_key); } -static int fscrypt_setup_iv_ino_lblk_32_key(struct fscrypt_info *ci, +static int fscrypt_setup_iv_ino_lblk_32_key(struct fscrypt_inode_info *ci, struct fscrypt_master_key *mk) { int err; @@ -329,7 +330,7 @@ static int fscrypt_setup_iv_ino_lblk_32_key(struct fscrypt_info *ci, return 0; } -static int fscrypt_setup_v2_file_key(struct fscrypt_info *ci, +static int fscrypt_setup_v2_file_key(struct fscrypt_inode_info *ci, struct fscrypt_master_key *mk, bool need_dirhash_key) { @@ -404,7 +405,7 @@ static int fscrypt_setup_v2_file_key(struct fscrypt_info *ci, * still allow 512-bit master keys if the user chooses to use them, though.) */ static bool fscrypt_valid_master_key_size(const struct fscrypt_master_key *mk, - const struct fscrypt_info *ci) + const struct fscrypt_inode_info *ci) { unsigned int min_keysize; @@ -430,11 +431,12 @@ static bool fscrypt_valid_master_key_size(const struct fscrypt_master_key *mk, * * If the master key is found in the filesystem-level keyring, then it is * returned in *mk_ret with its semaphore read-locked. This is needed to ensure - * that only one task links the fscrypt_info into ->mk_decrypted_inodes (as - * multiple tasks may race to create an fscrypt_info for the same inode), and to - * synchronize the master key being removed with a new inode starting to use it. + * that only one task links the fscrypt_inode_info into ->mk_decrypted_inodes + * (as multiple tasks may race to create an fscrypt_inode_info for the same + * inode), and to synchronize the master key being removed with a new inode + * starting to use it. */ -static int setup_file_encryption_key(struct fscrypt_info *ci, +static int setup_file_encryption_key(struct fscrypt_inode_info *ci, bool need_dirhash_key, struct fscrypt_master_key **mk_ret) { @@ -519,7 +521,7 @@ static int setup_file_encryption_key(struct fscrypt_info *ci, return err; } -static void put_crypt_info(struct fscrypt_info *ci) +static void put_crypt_info(struct fscrypt_inode_info *ci) { struct fscrypt_master_key *mk; @@ -546,7 +548,7 @@ static void put_crypt_info(struct fscrypt_info *ci) fscrypt_put_master_key_activeref(ci->ci_inode->i_sb, mk); } memzero_explicit(ci, sizeof(*ci)); - kmem_cache_free(fscrypt_info_cachep, ci); + kmem_cache_free(fscrypt_inode_info_cachep, ci); } static int @@ -555,7 +557,7 @@ fscrypt_setup_encryption_info(struct inode *inode, const u8 nonce[FSCRYPT_FILE_NONCE_SIZE], bool need_dirhash_key) { - struct fscrypt_info *crypt_info; + struct fscrypt_inode_info *crypt_info; struct fscrypt_mode *mode; struct fscrypt_master_key *mk = NULL; int res; @@ -564,7 +566,7 @@ fscrypt_setup_encryption_info(struct inode *inode, if (res) return res; - crypt_info = kmem_cache_zalloc(fscrypt_info_cachep, GFP_KERNEL); + crypt_info = kmem_cache_zalloc(fscrypt_inode_info_cachep, GFP_KERNEL); if (!crypt_info) return -ENOMEM; @@ -735,7 +737,7 @@ EXPORT_SYMBOL_GPL(fscrypt_prepare_new_inode); * fscrypt_put_encryption_info() - free most of an inode's fscrypt data * @inode: an inode being evicted * - * Free the inode's fscrypt_info. Filesystems must call this when the inode is + * Free the inode's fscrypt_inode_info. Filesystems must call this when the inode is * being evicted. An RCU grace period need not have elapsed yet. */ void fscrypt_put_encryption_info(struct inode *inode) @@ -773,7 +775,7 @@ EXPORT_SYMBOL(fscrypt_free_inode); */ int fscrypt_drop_inode(struct inode *inode) { - const struct fscrypt_info *ci = fscrypt_get_info(inode); + const struct fscrypt_inode_info *ci = fscrypt_get_info(inode); /* * If ci is NULL, then the inode doesn't have an encryption key set up diff --git a/fs/crypto/keysetup_v1.c b/fs/crypto/keysetup_v1.c index 75dabd9b27f9..b1e36494facf 100644 --- a/fs/crypto/keysetup_v1.c +++ b/fs/crypto/keysetup_v1.c @@ -178,7 +178,8 @@ void fscrypt_put_direct_key(struct fscrypt_direct_key *dk) */ static struct fscrypt_direct_key * find_or_insert_direct_key(struct fscrypt_direct_key *to_insert, - const u8 *raw_key, const struct fscrypt_info *ci) + const u8 *raw_key, + const struct fscrypt_inode_info *ci) { unsigned long hash_key; struct fscrypt_direct_key *dk; @@ -218,7 +219,7 @@ find_or_insert_direct_key(struct fscrypt_direct_key *to_insert, /* Prepare to encrypt directly using the master key in the given mode */ static struct fscrypt_direct_key * -fscrypt_get_direct_key(const struct fscrypt_info *ci, const u8 *raw_key) +fscrypt_get_direct_key(const struct fscrypt_inode_info *ci, const u8 *raw_key) { struct fscrypt_direct_key *dk; int err; @@ -250,7 +251,7 @@ fscrypt_get_direct_key(const struct fscrypt_info *ci, const u8 *raw_key) } /* v1 policy, DIRECT_KEY: use the master key directly */ -static int setup_v1_file_key_direct(struct fscrypt_info *ci, +static int setup_v1_file_key_direct(struct fscrypt_inode_info *ci, const u8 *raw_master_key) { struct fscrypt_direct_key *dk; @@ -264,7 +265,7 @@ static int setup_v1_file_key_direct(struct fscrypt_info *ci, } /* v1 policy, !DIRECT_KEY: derive the file's encryption key */ -static int setup_v1_file_key_derived(struct fscrypt_info *ci, +static int setup_v1_file_key_derived(struct fscrypt_inode_info *ci, const u8 *raw_master_key) { u8 *derived_key; @@ -289,7 +290,8 @@ static int setup_v1_file_key_derived(struct fscrypt_info *ci, return err; } -int fscrypt_setup_v1_file_key(struct fscrypt_info *ci, const u8 *raw_master_key) +int fscrypt_setup_v1_file_key(struct fscrypt_inode_info *ci, + const u8 *raw_master_key) { if (ci->ci_policy.v1.flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) return setup_v1_file_key_direct(ci, raw_master_key); @@ -297,7 +299,7 @@ int fscrypt_setup_v1_file_key(struct fscrypt_info *ci, const u8 *raw_master_key) return setup_v1_file_key_derived(ci, raw_master_key); } -int fscrypt_setup_v1_file_key_via_subscribed_keyrings(struct fscrypt_info *ci) +int fscrypt_setup_v1_file_key_via_subscribed_keyrings(struct fscrypt_inode_info *ci) { struct key *key; const struct fscrypt_key *payload; diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index f4456ecb3f87..aa94bfe6c172 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -405,7 +405,7 @@ int fscrypt_policy_from_context(union fscrypt_policy *policy_u, /* Retrieve an inode's encryption policy */ static int fscrypt_get_policy(struct inode *inode, union fscrypt_policy *policy) { - const struct fscrypt_info *ci; + const struct fscrypt_inode_info *ci; union fscrypt_context ctx; int ret; @@ -647,8 +647,9 @@ int fscrypt_has_permitted_context(struct inode *parent, struct inode *child) /* * Both parent and child are encrypted, so verify they use the same - * encryption policy. Compare the fscrypt_info structs if the keys are - * available, otherwise retrieve and compare the fscrypt_contexts. + * encryption policy. Compare the fscrypt_inode_info structs if the + * keys are available, otherwise retrieve and compare the + * fscrypt_contexts. * * Note that the fscrypt_context retrieval will be required frequently * when accessing an encrypted directory tree without the key. @@ -717,7 +718,7 @@ const union fscrypt_policy *fscrypt_policy_to_inherit(struct inode *dir) */ int fscrypt_context_for_new_inode(void *ctx, struct inode *inode) { - struct fscrypt_info *ci = inode->i_crypt_info; + struct fscrypt_inode_info *ci = inode->i_crypt_info; BUILD_BUG_ON(sizeof(union fscrypt_context) != FSCRYPT_SET_CONTEXT_MAX_SIZE); @@ -742,7 +743,7 @@ EXPORT_SYMBOL_GPL(fscrypt_context_for_new_inode); */ int fscrypt_set_context(struct inode *inode, void *fs_data) { - struct fscrypt_info *ci = inode->i_crypt_info; + struct fscrypt_inode_info *ci = inode->i_crypt_info; union fscrypt_context ctx; int ctxsize; diff --git a/include/linux/fs.h b/include/linux/fs.h index b528f063e8ff..a3df96736473 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -67,7 +67,7 @@ struct swap_info_struct; struct seq_file; struct workqueue_struct; struct iov_iter; -struct fscrypt_info; +struct fscrypt_inode_info; struct fscrypt_operations; struct fsverity_info; struct fsverity_operations; @@ -738,7 +738,7 @@ struct inode { #endif #ifdef CONFIG_FS_ENCRYPTION - struct fscrypt_info *i_crypt_info; + struct fscrypt_inode_info *i_crypt_info; #endif #ifdef CONFIG_FS_VERITY diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index c895b12737a1..ece426ac1d73 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -31,7 +31,7 @@ #define FSCRYPT_CONTENTS_ALIGNMENT 16 union fscrypt_policy; -struct fscrypt_info; +struct fscrypt_inode_info; struct fs_parameter; struct seq_file; @@ -178,7 +178,7 @@ struct fscrypt_operations { unsigned int *num_devs); }; -static inline struct fscrypt_info *fscrypt_get_info(const struct inode *inode) +static inline struct fscrypt_inode_info *fscrypt_get_info(const struct inode *inode) { /* * Pairs with the cmpxchg_release() in fscrypt_setup_encryption_info(). @@ -390,7 +390,7 @@ static inline void fscrypt_set_ops(struct super_block *sb, } #else /* !CONFIG_FS_ENCRYPTION */ -static inline struct fscrypt_info *fscrypt_get_info(const struct inode *inode) +static inline struct fscrypt_inode_info *fscrypt_get_info(const struct inode *inode) { return NULL; } From patchwork Tue Sep 26 18:01: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: 13399476 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 54478E7E65F for ; Tue, 26 Sep 2023 18:03:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235404AbjIZSD2 (ORCPT ); Tue, 26 Sep 2023 14:03:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235301AbjIZSD1 (ORCPT ); Tue, 26 Sep 2023 14:03:27 -0400 Received: from mail-qk1-x72b.google.com (mail-qk1-x72b.google.com [IPv6:2607:f8b0:4864:20::72b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 49F19124 for ; Tue, 26 Sep 2023 11:03:17 -0700 (PDT) Received: by mail-qk1-x72b.google.com with SMTP id af79cd13be357-7740c8509c8so547510885a.3 for ; Tue, 26 Sep 2023 11:03:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751396; x=1696356196; 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=qHTfmhZkLVoy1LsAIrl2EgcMX1KOx4Ne7j6F4pFm9/g=; b=IQ7l3oOXKJ2oEM0H0/jeAtl/b3C0DJt6MOfTBJF6rAI+1gpdCmg17oEayrbDCHxj91 qupPsXvo+CIzxu4mEHmKP1n+upMERi34DEFLYq+CfUbceajtAxBQbE7huCPo4OMUbOMS r4Nba2x/p2i6N7A12/E7ssiZ4/hr64WVXjyxfxwKbatoZJkWoR+Wl0ZjgMazor26OIBk ZzocMoS4k5urgaJ0NHQC5KVHWbl7UE4ufU+6CwRruz59YNGymCBGJKqH/92fYAkgrYDx d9Bcb2wX5sdyfYmOAgvFz0tNO7U8KUljpcquMxghIhvaQ7isyx/cO//QruySLZCQN163 eXug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751396; x=1696356196; 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=qHTfmhZkLVoy1LsAIrl2EgcMX1KOx4Ne7j6F4pFm9/g=; b=b+MqSZO/SClo+Xz7XWW19m/dtebfNGhT152h5z591UfT9wmm98s93mSoZoBY8EgKPy A/6kgZdON9yZOcNYkjbShFA5N07+ipYHwRJdP4WwwBWJtN+qxfKAZqUunSCNg+uCEZHn //Swl14dM/EAcRUtgYpHOjBG5sVg2UBwhya5L9qnjIGBiNGP2eeoOTyVwidOwKvUdwNH 0Oq0NBAxMZI9pRHb/b9IZXvd9y+YYvrrkhVoqg1vvEFiRaSlc0O0dMWlX0Dhk+/qTwxY SIfVWxpklDVslduPTD7rizWhnwXQhlUrePurWgEpqOKkhK8q24IMWR7Cyohu4ZCpLzka dIbg== X-Gm-Message-State: AOJu0YwZNiXuuuLlVkpTfelhqVjSIR+jfszm/FsnHRUgNrpPv0+1aPZW oFvqqn5vlZiyKvIuWfIWjP39UbyVw78tzm/hLjrrSA== X-Google-Smtp-Source: AGHT+IHSQ679CijQOpdFJJbHD/hIB54OkkfKZd2ZBRuSrpjRwQ7W7lq4cVz0Gc2XAbRZz3qc72bdYA== X-Received: by 2002:a05:620a:1998:b0:76f:24d2:e232 with SMTP id bm24-20020a05620a199800b0076f24d2e232mr10717412qkb.47.1695751396025; Tue, 26 Sep 2023 11:03: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 c26-20020a05620a11ba00b0076cb1eff83csm4899171qkk.5.2023.09.26.11.03.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:15 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 02/35] fscrypt: add per-extent encryption support Date: Tue, 26 Sep 2023 14:01:28 -0400 Message-ID: <3e82fb910f3f66bc0af854948c18a7cf476bbb1a.1695750478.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-btrfs@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 | 45 +++++++++++ fs/crypto/inline_crypt.c | 84 ++++++++++++++++++++ fs/crypto/keysetup.c | 152 ++++++++++++++++++++++++++++++++++++ fs/crypto/policy.c | 47 +++++++++++ include/linux/fscrypt.h | 66 ++++++++++++++++ 6 files changed, 403 insertions(+), 1 deletion(-) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 2b2bb5740322..e3ba06cb4082 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) { @@ -396,12 +397,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_info; + err = fscrypt_init_keyring(); if (err) - goto fail_free_info; + goto fail_free_extent_info; return 0; +fail_free_extent_info: + kmem_cache_destroy(fscrypt_extent_info_cachep); fail_free_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 b982073d1fe2..a7e902813cde 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 @@ -52,6 +54,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 * @@ -260,6 +284,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, @@ -267,6 +310,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_block(const struct inode *inode, fscrypt_direction_t rw, u64 lblk_num, struct page *src_page, @@ -326,6 +370,7 @@ int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 *master_key, #define HKDF_CONTEXT_DIRHASH_KEY 5 /* info=file_nonce */ #define HKDF_CONTEXT_IV_INO_LBLK_32_KEY 6 /* info=mode_num||fs_uuid */ #define HKDF_CONTEXT_INODE_HASH_KEY 7 /* info= */ +#define HKDF_CONTEXT_PER_EXTENT_ENC_KEY 8 /* info=extent_nonce */ int fscrypt_hkdf_expand(const struct fscrypt_hkdf *hkdf, u8 context, const u8 *info, unsigned int infolen, diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index 3cfb04b8b64f..21e1851d4ba7 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -278,6 +278,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, @@ -369,6 +403,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 cbcbe582737e..55716ed03478 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -806,3 +806,155 @@ int fscrypt_drop_inode(struct inode *inode) return !is_master_key_secret_present(&ci->ci_master_key->mk_secret); } 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; + + 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; + + mk = ci->ci_master_key; + down_read(&mk->mk_sem); + if (!is_master_key_secret_present(&mk->mk_secret)) { + err = -ENOKEY; + goto out_free; + } + + err = fscrypt_hkdf_expand(&mk->mk_secret.hkdf, + HKDF_CONTEXT_PER_EXTENT_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 aa94bfe6c172..8b8da04068b8 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -763,6 +763,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 ece426ac1d73..266416742c72 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; @@ -66,6 +67,9 @@ struct fscrypt_name { */ #define FS_CFLG_OWN_PAGES (1U << 1) +/* If set, the file system is using extent based encryption. */ +#define FS_CFLG_EXTENT_ENCRYPTION (1U << 2) + /* Crypto operations for filesystems */ struct fscrypt_operations { @@ -293,6 +297,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; @@ -329,6 +338,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, @@ -539,6 +551,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) { @@ -591,6 +621,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, @@ -772,6 +816,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); @@ -782,6 +831,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); @@ -797,6 +850,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, @@ -809,6 +867,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 Sep 26 18:01: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: 13399474 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 EA024E7E654 for ; Tue, 26 Sep 2023 18:03:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235391AbjIZSDZ (ORCPT ); Tue, 26 Sep 2023 14:03:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235395AbjIZSDY (ORCPT ); Tue, 26 Sep 2023 14:03:24 -0400 Received: from mail-qk1-x72a.google.com (mail-qk1-x72a.google.com [IPv6:2607:f8b0:4864:20::72a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0D242136 for ; Tue, 26 Sep 2023 11:03:18 -0700 (PDT) Received: by mail-qk1-x72a.google.com with SMTP id af79cd13be357-7741b18a06aso552473885a.1 for ; Tue, 26 Sep 2023 11:03:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751397; x=1696356197; 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=HEpmLdsd71BpfsLvuAMqA7qaAsmnnp9uGs4TsFTYoJo=; b=dIRJlr/og8wRBSOw7jq66Uqs+QFeqZRIqJjFUjIiT8oWyeHM+d/LEj4sb65aFKrnQU eIDjYlSJydx1Tkjf5FqiQQtL8daYg2X6xLqHrGyx0arfkj+BDSoNZsOLzYmV2hH7dcYf ea/+2MtYSfk4L/XpLNKIdt/fp1aaqmKBicvaB9IfivoT8kjv0vwikWxhDkAZpWbemY/a LyFQt4hw5Le62cDmuAYhUfUI+WjIi12OFzRbfKNTsgmDFNX3HX240Wv2aMB3jG726pvF KjdL/sB+VC27giyshXilgHIun1BiIbjqU9RvbZNhP4UUKy2EzKa8IjatrGzxgsoZkTVa mt7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751397; x=1696356197; 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=HEpmLdsd71BpfsLvuAMqA7qaAsmnnp9uGs4TsFTYoJo=; b=s4AkCP2TbkgtMEys5J0iIFlia9BOWKu7aOTeqtBILwXmPhjtaoxQIbKQy1WKD0gwX8 VaVzCuSM5u0e5zk9aysw8sffi1layUZTxs3soQIiF+xkuCVBhLZIywTIMwnlbm0+4BlO 9v3b5IzaBix6iN9mJByh9adZnhYi8O0AVtnujJXgKhXtV06QGAMmS21uE/CVm89qElUr FwTtb0KPrSX12MwEf5OmOUfaMIpYwQdfUhA9V7h0MiGAcKKYrMYdnxLpaT7fk9ulLm4L u5Hf0FRmrQTx4HmKMVbDo/4axlaMSSxgFnTtLQiRC+5yQ/sPHI3G+YfXtspmuUXuq0p2 7Q9Q== X-Gm-Message-State: AOJu0YzWMVYlQZnV4OkosXfT0/sj5Bc2KqI/6FtVGbmvpfqSF5SWvpQT w3oh3QK6FLZSpWivrjHNNF+fPjAYoHc1oRK2b2tc3Q== X-Google-Smtp-Source: AGHT+IF0mKQpS6T1d8wH4tTeSy6fbusjTkiYCZU8OiOcNlGtAJV5M3Poeik33Kjjt4TwbPof9fL2YA== X-Received: by 2002:a05:620a:1424:b0:76d:2725:f36f with SMTP id k4-20020a05620a142400b0076d2725f36fmr9709782qkj.71.1695751397077; Tue, 26 Sep 2023 11:03: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 a14-20020a05620a124e00b00767dc4c539bsm4943739qkl.44.2023.09.26.11.03.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:16 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 03/35] fscrypt: disable all but standard v2 policies for extent encryption Date: Tue, 26 Sep 2023 14:01: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-btrfs@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 8b8da04068b8..38807d0ee742 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -198,6 +198,12 @@ static bool fscrypt_supported_v1_policy(const struct fscrypt_policy_v1 *policy, return false; } + if (inode->i_sb->s_cop->flags & FS_CFLG_EXTENT_ENCRYPTION) { + fscrypt_warn(inode, + "v1 policies can't be used on file systems that use extent encryption"); + return false; + } + return true; } @@ -233,6 +239,12 @@ static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy, return false; } + if ((inode->i_sb->s_cop->flags & FS_CFLG_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 Sep 26 18:01: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: 13399479 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 89CA6E7E65A for ; Tue, 26 Sep 2023 18:03:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235408AbjIZSD3 (ORCPT ); Tue, 26 Sep 2023 14:03:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43434 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235405AbjIZSD2 (ORCPT ); Tue, 26 Sep 2023 14:03:28 -0400 Received: from mail-qv1-xf2d.google.com (mail-qv1-xf2d.google.com [IPv6:2607:f8b0:4864:20::f2d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3814213A for ; Tue, 26 Sep 2023 11:03:19 -0700 (PDT) Received: by mail-qv1-xf2d.google.com with SMTP id 6a1803df08f44-6563c23b356so50295676d6.2 for ; Tue, 26 Sep 2023 11:03:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751398; x=1696356198; 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=DhsoYdqKEB57sdkiaORFFDDcmRQ6FJWpxL8kkDS6WVQ=; b=Im6S7c71oJsLzI4NS1mhHn9J1chKXXCjAIQudkQtxw1C28no8eLnFqMlfLJUWAgOSK qSo1G0PUb33zbiQPiIkYL1xUI2DaAoh9i1Epbg9x4XBwK/H8EIM4qEMImvoUwLHAFl2a dW9yBXQVU+hIaR2ZKA3XxdQvqK5ojkiMgRynNtCfgtfpMqCmZ5oT/4A19KpUdQuaVvAr c0cFVHFC5zYBTW/0SvRbbIKI+uPVz+Raub3vfel92GlQxBvugKm/8mzbHYoPFVd0sGZt lVXFIWg7gf6dDFjHQQyZUhTh5y7hg+BB7052BbYvKaT6AcjMFJBkon9tRj+gIcSjyfzV ssrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751398; x=1696356198; 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=DhsoYdqKEB57sdkiaORFFDDcmRQ6FJWpxL8kkDS6WVQ=; b=epioIEugvyuTDJTr1fey9D1sdFBGuXPt4yFX4KcO0qGNQmtpePWSpMKy432ikDd2s+ KAr+pxgAg/13oX7Pg92MJKVUEb7G1DKUw24gozniVV0kUIRFKD0SaX6UgsMX14TeUZ6V pohy/6fo1OSZjEN7cX1RISh71NPgftVBkYsHc15W1C+QW+6lnTG8MSR44IqvVdMCrr5J eCT9WkFJboZ5QIR7j6bR5fi0rkwzfwOiAXOkbvAHOC4vD+SC6lc89/jHinhrhFgVM3NI eb9z0epV3xoCvkytZ75qTApLh9RgeVQ9PRgdjso5M3uMjjWqE4/yWL0g+BsoybbmNLTQ 8GjQ== X-Gm-Message-State: AOJu0YzkTxIMx/VhGIV8XcnAkk/+Mcf6teYbgQdqBBnYOhymBmu4N3jg v2cwkke57tUhjJF9hLnHSWp2m+CB/XOslZJp3FvYng== X-Google-Smtp-Source: AGHT+IHy5RadIV1+96HKk2bhm02XovrnSBxIzx4KZIeJBwaSN4keOhNX+CxgEyeCcXakspT4kZaAQQ== X-Received: by 2002:a05:6214:2267:b0:656:1cee:d1d with SMTP id gs7-20020a056214226700b006561cee0d1dmr15793152qvb.11.1695751398132; Tue, 26 Sep 2023 11:03: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 e14-20020a0ce3ce000000b0065b0771f2edsm2454602qvl.136.2023.09.26.11.03.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:17 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 04/35] blk-crypto: add a process bio callback Date: Tue, 26 Sep 2023 14:01:30 -0400 Message-ID: <78be341377e7f0fb0ead3d5167be44ca0c87a944.1695750478.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-btrfs@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 21e1851d4ba7..a66a555d84ee 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, return -ENOMEM; err = blk_crypto_init_key(blk_key, raw_key, crypto_mode, - fscrypt_get_dun_bytes(ci), sb->s_blocksize); + fscrypt_get_dun_bytes(ci), sb->s_blocksize, + 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 266416742c72..07493ad2588b 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -16,6 +16,7 @@ #include #include #include +#include #include /* @@ -180,6 +181,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 *fscrypt_get_info(const struct inode *inode) From patchwork Tue Sep 26 18:01: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: 13399477 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 3EF1CE8181A for ; Tue, 26 Sep 2023 18:03:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235412AbjIZSD3 (ORCPT ); Tue, 26 Sep 2023 14:03:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43440 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235402AbjIZSD2 (ORCPT ); Tue, 26 Sep 2023 14:03:28 -0400 Received: from mail-ot1-x335.google.com (mail-ot1-x335.google.com [IPv6:2607:f8b0:4864:20::335]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3C54F194 for ; Tue, 26 Sep 2023 11:03:20 -0700 (PDT) Received: by mail-ot1-x335.google.com with SMTP id 46e09a7af769-6c4cbab83aaso4462223a34.1 for ; Tue, 26 Sep 2023 11:03:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751399; x=1696356199; 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=myCIPHzyNpBOvcVkJC2tcaUDQBmAcGT4ntRHF6CAG2Q=; b=PKr2jF+aTS7QKck4YBjXmELd0IonZD8UnEI3H6BYHM+YUi7hvznAyHqeF5ET5OtYbl 6bAosxADyKtkjtLeBVNjcmxa4zpHxZt2/OyRnlnurTGzdRGPXZo8zGORCbWtP+ODD0uK LRHCoN03DTcTq5RrlAJ0kWjyz5KLUNj8VgRk3bFq/o2q3TXFI7kPNDojXWUYMapB7OOz dDpPjD+YvjE8uzu5KuTsSs7g2MUGNiYWZ8cVxfVhUcndMlYVE0cZTZmUNJZNq41/r3J8 iuQggHp/sCK1IfoTnMdVd0rMnycGzYnky8TrPbaIGWE9dNZs3d9rKZ4s2wkZ9HSC1/ey bL2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751399; x=1696356199; 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=myCIPHzyNpBOvcVkJC2tcaUDQBmAcGT4ntRHF6CAG2Q=; b=r+Iu2U8bLAAaIqGeS9quqofjX7kXamiCgX6Ljilsndc3XrmVx6z+w0TBgEIwj8ix11 /lbX/0c95Vs6jROjHlBUyzan5DSucxIN0j5EDv3jSJVO+HS3Xv8DO1ALRvmiLnKG62nY k8i/s+HzyCycRlGMyuicjBx40cisE8VXXIQh93U9tgp1MMyia43/vjgN7E/n3janv/nj ersO/yG6ly6yu5jJ3NvFCX1fOqVO2Rz/LanPcKWiBKAcaidybk/d3BlyxrjW0U7FoR4i NybRhRtjHUEtp17GqyS7OlQH47kiRRvaY9vUcCkOVpSqBprG+8LW+rDlztTO2QymBgYi Ib2Q== X-Gm-Message-State: AOJu0YwOTrsl7pDojSLvvtnNUnHwEQsE7AzLnKHPukQ8mB6keKfEiItA wcmLwqyDp+wx+DMB6b0nILyLvWr8c5nyzkTOf3zXDA== X-Google-Smtp-Source: AGHT+IHvt82gmLlmiZ6OkuSubOdiMVUWAVbjntRU0qeCeZkB5mUCczZLR3bdNVNjIsQClTLSurTZJA== X-Received: by 2002:a05:6830:20c7:b0:6bc:9078:81c8 with SMTP id z7-20020a05683020c700b006bc907881c8mr11125113otq.20.1695751399248; Tue, 26 Sep 2023 11:03:19 -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 mn12-20020a0562145ecc00b0065af252fe88sm3567618qvb.63.2023.09.26.11.03.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:18 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH 05/35] fscrypt: expose fscrypt_nokey_name Date: Tue, 26 Sep 2023 14:01:31 -0400 Message-ID: <5f28dbfb50cf7a7beca6f0ca2f27ffe2c9366038.1695750478.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-btrfs@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 07493ad2588b..44dc10837499 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 Sep 26 18:01: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: 13399478 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 9A925E7E654 for ; Tue, 26 Sep 2023 18:03:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235402AbjIZSD3 (ORCPT ); Tue, 26 Sep 2023 14:03:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235406AbjIZSD2 (ORCPT ); Tue, 26 Sep 2023 14:03:28 -0400 Received: from mail-qv1-xf2a.google.com (mail-qv1-xf2a.google.com [IPv6:2607:f8b0:4864:20::f2a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9827F19E for ; Tue, 26 Sep 2023 11:03:21 -0700 (PDT) Received: by mail-qv1-xf2a.google.com with SMTP id 6a1803df08f44-65afd746330so30529296d6.3 for ; Tue, 26 Sep 2023 11:03:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751400; x=1696356200; 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=ZQ+glbh3WDNJDZmVH3FQJ5H+z2bjYTLVZgaDFi04Qw0=; b=agnLSMLDpmxiOGaTroiEEOEr3EUzBgptjq49ShrQY5DPpES+j0jY2wHANu/F4tAknH Z5GTFju0bHD8jQjJ7B0+3jLNfVvutAVCI9pAsLjqWe6cyKuj78X3O7ANisie47rb4kT5 MebSpRua+3YJqENBW/ButkQQHPmSKXuUNBhI0E/I6j/tODx7C7E9zwQ4AITLxzPpRgS2 M12T+/862a/iYSrizbvBt0yPljSHeMGy3k3LOxYJAssmvV3OnjlYGzRA+jQcVl1q7sEW tnYJ+hZCz7oJWxbsqEhmn32afDVqPF5yAulOnt9cG3lWhXWGPrUgH7Ann7r6cDKSxme7 ZKoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751400; x=1696356200; 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=ZQ+glbh3WDNJDZmVH3FQJ5H+z2bjYTLVZgaDFi04Qw0=; b=B8sVuXK7l5/VJyWgAtEx6eb6iMENdckl0itGfLKpfyewhIomNWITB55jDZRA0aXkN0 wyJRgtBQWUYHS7NENQJRSyRCq5pcRfSoEBir9S6o7gfWKgWcjiTIJgufJAuWe7eHLRZr 0e2OWL2fcPQ7ri15cyMv25QWK6xYR5+Km8XJBPcveEgo8wqbah1ZGoXtrb1pLNQA4GPp vgzJ44+ufKxzZnVxKbMx+wt9lkKOu5CDGReTW6rGMp0prOUT7T8a3nS7Qi85GPB7ZMX2 Yyppl1so42w3gTy3Nzz9FCQILZSlTxEfsPNURTPZ1wfpIDYAVibzcxPAH0VVqYfWwvgh CIfQ== X-Gm-Message-State: AOJu0YzsTiJqX0FCIu3g/H8MLiQM1P5OZxm1VYF7E1uV63KOogWHYA9w CMarZTlHLEQz2zoupGM3iZOLMOFE8qr355wfiI99gw== X-Google-Smtp-Source: AGHT+IET3lpee/aysQzVIayOhVk8cRngwDrCawKohmO5XD5Ik4CvYNwMMYAVXSTGfWpMqnC3L8S3lw== X-Received: by 2002:a05:6214:a63:b0:656:25a5:7060 with SMTP id ef3-20020a0562140a6300b0065625a57060mr9886946qvb.59.1695751400378; Tue, 26 Sep 2023 11:03: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 u18-20020a0cb412000000b0065896b9fb15sm1676173qve.29.2023.09.26.11.03.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:20 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 06/35] fscrypt: add documentation about extent encryption Date: Tue, 26 Sep 2023 14:01: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-btrfs@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 a624e92f2687..9981eaf61f32 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 ------------------- @@ -1339,6 +1354,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 Sep 26 18:01: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: 13399481 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 4CD63EE0205 for ; Tue, 26 Sep 2023 18:03:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235428AbjIZSDc (ORCPT ); Tue, 26 Sep 2023 14:03:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43470 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235405AbjIZSDa (ORCPT ); Tue, 26 Sep 2023 14:03:30 -0400 Received: from mail-vk1-xa30.google.com (mail-vk1-xa30.google.com [IPv6:2607:f8b0:4864:20::a30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B505A10A for ; Tue, 26 Sep 2023 11:03:22 -0700 (PDT) Received: by mail-vk1-xa30.google.com with SMTP id 71dfb90a1353d-49a319c9e17so1901616e0c.1 for ; Tue, 26 Sep 2023 11:03:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751401; x=1696356201; 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=j7RxghLOy6rRzt/rT5VjJx2/IyUKbya008SIuzU+uYo=; b=CuYshcPBSXpK5R1JB+o/iIZ4/jRwFxtl40XVuYcPZb4qrZL9KAEH+lnVLNtWRO7Nni jNh/Szt4xKNOQWk/iVhhNVIxb2sFAVF54R0tCe4di77unYFPzkuxRgnkgBfnUlj/RJYd duFUSHIbYsQbnJeqhrneOWnPoCfuE6IYb+1Y7sg0ogpvve3DbxzflxOUpfLrbBTjTnak Yb7rfDt2f9cPkyZLc8q0rXnWndqex4q8sLrF6KhqY4a9HAChgeD0PFrPr4y4FciyH8xK C2O9wWr41vS/SK9nZEvszGIH1UnhxXZLBYqyQVG8ZWmqeFac/0mlUupT1bSNirEMCONL y0rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751401; x=1696356201; 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=j7RxghLOy6rRzt/rT5VjJx2/IyUKbya008SIuzU+uYo=; b=VZYfMXgieqxk7sLm9gk/xDL/LqLCo/I6di3h8XoegAtIofBJo4F+XMM35bUAjpS96o rixxm9NOBzYN97sDYfrQYIoUmruUTHKY7ajUjlnzZJdr0JzWlcjtNjPYi5W0zvVQk9CV Z+rlGGphx8231wNtJ4TAfz3nc2VbLEgIlDfAQO/2Gs9Nr3ointc3jVtb3uyNKDOZ0J3D R0ibCdPH/pP/Ls3MNqPko3phuDFuIX+yPcEu8wF/qu9Nikx2Q98bsMGf9NmhsNc3yrr5 oqCp27mA4Pe3Q2/E71bOMj56i/x8Yr7INOgcul2CohPXrDE59fJdwNNhzrdHmQGBS67L Q7wQ== X-Gm-Message-State: AOJu0Yw69NlgIVdcIcYjv5Aogm41QtYY673im0uo+SB84LS5n9I6lB5J kDYNWAe8/+duuVgYsZkLmk+AktjGuOGvv+yGe77UjA== X-Google-Smtp-Source: AGHT+IEBUCwZa7YczuFBjeuEPic4b/05oZxUfyX0O2eDASOgnNpTTjxcVN8P864sB1nKF9d3IokTOg== X-Received: by 2002:a67:fa10:0:b0:44d:5435:a3e with SMTP id i16-20020a67fa10000000b0044d54350a3emr6242999vsq.9.1695751401502; Tue, 26 Sep 2023 11:03: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 t6-20020a0cde06000000b0065b2167fd63sm1111707qvk.65.2023.09.26.11.03.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:21 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 07/35] btrfs: add infrastructure for safe em freeing Date: Tue, 26 Sep 2023 14:01: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-btrfs@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 6b98e0dbc0a4..c4d8900f91bb 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4886,7 +4886,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; } @@ -4895,11 +4895,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 Sep 26 18:01: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: 13399480 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 19C53EE020B for ; Tue, 26 Sep 2023 18:03:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235439AbjIZSDc (ORCPT ); Tue, 26 Sep 2023 14:03:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235432AbjIZSDb (ORCPT ); Tue, 26 Sep 2023 14:03:31 -0400 Received: from mail-qk1-x72f.google.com (mail-qk1-x72f.google.com [IPv6:2607:f8b0:4864:20::72f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 00B1913A for ; Tue, 26 Sep 2023 11:03:23 -0700 (PDT) Received: by mail-qk1-x72f.google.com with SMTP id af79cd13be357-7741c5bac51so464075885a.1 for ; Tue, 26 Sep 2023 11:03:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751403; x=1696356203; 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=mvUgsr/82Ad7po+7Bh9YYtXxzP0gfJA3GRIgY9dfAeo=; b=iLsZMBwlqpUhxyoQdJYEUp9M+vlbmFa+IZ7mRNZyR4jxXgTnWe9VoOoT1sImyx0CGu 1RYyWu/5GftaL9mISAEt9+O+jbG0td2PMGbLZCwZBs9sYYknK/1TOAXdIxnMmHmQ/laY 3JzbbGldcd/dC6lVaf0vsHGCjYtKUY/LwuWqMbAb1ZYWFXiRUggNs1AHGOwSNR+Lk5Xa /J52zi+t0ZzxSRpirBS0YAy/IM9AxFxPj2HotIhbFvLxgThiKhG+YCsnRaEzviRd33x0 E/YsJpelhIOK7CoHd0Uq8YvHPtUN179beNWYeh0aZ06XINMDb6CjaahCFXYpNWjrX0Xw ljnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751403; x=1696356203; 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=mvUgsr/82Ad7po+7Bh9YYtXxzP0gfJA3GRIgY9dfAeo=; b=d1FPMAT0JV5R7Nnux8ppDv+e/tSuj6w11Z8pJXT14hPyUIIMn63fcEZpFKatpoc8Ui foAy9DUE91mN+Dv5uoCdksvoEYUN+Kh2m37XVHg8HLfpC1YTuTEsbx8tnxYPPcBQTKJ6 cEWYhbSqDYyevP1Prl56qU9Ifhjy9iSUkr+iIktoYAPK+vaOMQxGxJi6hh6YNf3AXc7L n60EIhtcptAj0GDWCMc6uXRN76uod6GVSSK/DggKQQWM9sYnPUPKL57ok0JadrHgO4If 4bYUc5fPR5aA8fnm+IHx7xvzL52ICZ99K5NdNbk1m7CceC7RjqwV4JlZHbSImFxAFzxg jlvg== X-Gm-Message-State: AOJu0YwSTcTbpqyVVqXTnqLN0AopGD+yN6lqLdmydb9RGT7da5N36q8U DQ3psHb3MPxwC3ax25vVC3vr30l7tkd1eDtKcqD48Q== X-Google-Smtp-Source: AGHT+IEYeHPXf3QIxe/GVAvfnuEqDK1wXoiieUM37Xo4d063NQugH/UxgIQmqwE0WwURZVtFCGLlFQ== X-Received: by 2002:a05:620a:288d:b0:76c:e7b7:1d9d with SMTP id j13-20020a05620a288d00b0076ce7b71d9dmr10200605qkp.27.1695751402655; Tue, 26 Sep 2023 11:03: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 oq36-20020a05620a612400b0076ef004f659sm4950020qkn.1.2023.09.26.11.03.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:22 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH 08/35] btrfs: disable various operations on encrypted inodes Date: Tue, 26 Sep 2023 14:01:34 -0400 Message-ID: <18da950f00bca068377700367d6b0bc091f72fdf.1695750478.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-btrfs@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 52576deda654..6cba648d5656 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 Sep 26 18:01: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: 13399482 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 2775FE7D27E for ; Tue, 26 Sep 2023 18:03:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235444AbjIZSDd (ORCPT ); Tue, 26 Sep 2023 14:03:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235438AbjIZSDb (ORCPT ); Tue, 26 Sep 2023 14:03:31 -0400 Received: from mail-qt1-x82d.google.com (mail-qt1-x82d.google.com [IPv6:2607:f8b0:4864:20::82d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E99DA19E for ; Tue, 26 Sep 2023 11:03:24 -0700 (PDT) Received: by mail-qt1-x82d.google.com with SMTP id d75a77b69052e-4180adafdc6so44463291cf.2 for ; Tue, 26 Sep 2023 11:03:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751404; x=1696356204; 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=WLNpH+i55iMeC2wrjZcx7lyoHFaw+oHCxkqfbX3Ca9UW4rdeN962wVVj3rhkeO89Pi /xH/FH0YTUpXKU9xUP5n0/aV050hPwfs6fJRWidOxNVZUfEu5UTTuZsyfCo9JFEeUqDt TF1RgiCrYAM3BRGvyacTDCML33qDvRzPuCjsGfa6Or60IynKfQlC+khjkzMokg3lsIMP qWL5vydJV4TgJAoei3AX34fiW40cMd4GeBa+hxLLWkS6CedLoBMdEqcyquQ6r8iK7INU ENwCZFHaRolxyFjd9CJ0rdPUqWgFuMNti0mvS0WN2BfrrlSwwtLSw73Z9LbwAnXusHs6 SAcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751404; x=1696356204; 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=a+B6DCTCFrOW/B9s8FryIIRh2Ktg+KfZw136SgxAy7hCsKdGn+jX7jLvxI+dqmu/ml P9UxeCHQdO9IWc917E4AigKig6OOaIaYtPQHRb7pKJrpod+gxoNzMJvsucwff48ijO2x D0NQ7Tcbgz+jnrwKw4rUNVFsHVGQSKZyQIVoy2Z8OxAa17AMFwm2UitUIKlme7cgyhbu 3WKi9K0B98D0K00jlnzJ0ozkMLOjEMlLDstYotGt/4i7pd8yR5MtPIIQ12s+g8jUwwLJ 64h4Qxb7JFmWpZaDpDLhJyoSH1h29Q1SI/I03aZUMoDSGuEZyAzLM+VnheGk0MmivS2p XZ2w== X-Gm-Message-State: AOJu0Yw5Y1y7s+X3Z1hWdfVXtVO85razrnHdIppQ40k0iowsDEx6yedn RrFxgK0OIVYxdUkLOu5pbHZ/0/3wW9tDNacYWO64Xw== X-Google-Smtp-Source: AGHT+IH6PNxwFL432DfaPRHZ68/+mdDkldoTR7HOMu7wPlfBa0i9UL0sFgc9BGkEzDV/1Dz8YKKvjQ== X-Received: by 2002:a05:622a:1819:b0:419:51d1:5456 with SMTP id t25-20020a05622a181900b0041951d15456mr2166009qtc.22.1695751403859; Tue, 26 Sep 2023 11:03: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 fe12-20020a05622a4d4c00b004109928c607sm4825887qtb.43.2023.09.26.11.03.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:23 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Sweet Tea Dorminy Subject: [PATCH 09/35] btrfs: disable verity on encrypted inodes Date: Tue, 26 Sep 2023 14:01:35 -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-btrfs@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 Sep 26 18:01: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: 13399483 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 86E58E7D0C4 for ; Tue, 26 Sep 2023 18:03:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235440AbjIZSDg (ORCPT ); Tue, 26 Sep 2023 14:03:36 -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 S235434AbjIZSDd (ORCPT ); Tue, 26 Sep 2023 14:03:33 -0400 Received: from mail-ua1-x935.google.com (mail-ua1-x935.google.com [IPv6:2607:f8b0:4864:20::935]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 113D7FC for ; Tue, 26 Sep 2023 11:03:26 -0700 (PDT) Received: by mail-ua1-x935.google.com with SMTP id a1e0cc1a2514c-7ae1a075fc5so458900241.3 for ; Tue, 26 Sep 2023 11:03:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751405; x=1696356205; 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=mj45JvCGm6oPGv3Q2LGRn7WpwS9RJ12csfoZzcyCuA4=; b=RcU2HA1aPmR+61HYfCQxDu1O9RUmw90w3lBKUhZq+LnwmM5YEpFhV7iyIEV2Y+/P47 JPHu6U2ve/nmpy0lBZMD0+g9jWto3PgdkDg4HDoABSCb2js9yX+FSp10P2NHbBTqz37m hgZGFoXynOnuMjnj+Co9DmSzxHLV19rr3jHZmVG8zAeIPBZwr0TfvIIP3A5pNJ92tM/2 VaV5ZX8Gl23NTY6z9Fl5Z1Khpkkg9m3hm4xIzo9E9lqOQypQc/pTIML9RG6ppKuUYO8r lEzAPccpRa62PMGDqqzVR6+NrTRFlkDmpRBNxWfJDirB777OxYDdOqAABHzZfiCrDBvj wEyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751405; x=1696356205; 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=mj45JvCGm6oPGv3Q2LGRn7WpwS9RJ12csfoZzcyCuA4=; b=wDTispsbkOfR8PA1JUE8KcyNP6WWBbqMmQI+qam2fyT2FKyvZcJzWYlhujquIdCcQq EtOdY5krFvvp7LKD1zLgHkNxUun5e1jyTunE8OB1YPUK/X7W1+s66ksuFF5R6VbXAnMs hlAkGDNFf7YZ9aPk+9l5Ckm0IlNOsNuSZ4y0zAX9VZAFYwHcFGJpUJosJhhaAQlVRf2V /aAe5xHYBB99bp6JB+0R9mKmntvIw+/ZkbsXH0VYx2+RIZkNrpMvl4UwieQhGCG5w2Bj l250yDOSB95KCTJsbqe3JY9gQ4kRgpq68p6wtwSZxXwWVNUSGNhomhrKwT+1pBBTD4jp I66g== X-Gm-Message-State: AOJu0YwY84IgXcU162lDaiyPldUOKQAxeHZtx6enOvCiw1i5DTw6JM2/ e9r93fFkWlXcOx+USsUWDOVCGkSZOvoYK8CXOAddjg== X-Google-Smtp-Source: AGHT+IH9+OxW+A2/4vNYUoP/9oYocjKtTNI4SCFsaaz2RpomeE7/zHRJ+GOjuX4BXpURZVCUkWM4/A== X-Received: by 2002:a67:f319:0:b0:452:88da:2e1f with SMTP id p25-20020a67f319000000b0045288da2e1fmr7749126vsf.21.1695751404839; Tue, 26 Sep 2023 11:03: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 n11-20020a0cdc8b000000b0065b2be40d58sm589802qvk.25.2023.09.26.11.03.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:24 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH 10/35] btrfs: start using fscrypt hooks Date: Tue, 26 Sep 2023 14:01:36 -0400 Message-ID: <912762ca48efcc684cd5cdde99b5a78cd25f1078.1695750478.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-btrfs@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. Also add the key prefix for fscrypt v1 keys. 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 | 8 +++ fs/btrfs/fscrypt.h | 10 ++++ fs/btrfs/inode.c | 110 ++++++++++++++++++++++++++++++++++------- fs/btrfs/super.c | 2 + 7 files changed, 117 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 f2c928345d53..68ebb6096822 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -449,6 +449,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 004c53482f05..8dcc5ae9c9e1 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -3710,6 +3710,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..3a53dc59c1e4 --- /dev/null +++ b/fs/btrfs/fscrypt.c @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "ctree.h" +#include "fscrypt.h" + +const struct fscrypt_operations btrfs_fscrypt_ops = { + .key_prefix = "btrfs:" +}; 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 6cba648d5656..94c2e13934aa 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5054,6 +5054,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) @@ -5208,11 +5212,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); @@ -5312,6 +5313,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); } @@ -6097,6 +6101,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 */ @@ -6570,9 +6580,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 c41ed5a78ea4..21c5358e9202 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" @@ -1099,6 +1100,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 Sep 26 18:01: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: 13399484 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 D7272E7E65E for ; Tue, 26 Sep 2023 18:03:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235450AbjIZSDg (ORCPT ); Tue, 26 Sep 2023 14:03:36 -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 S235451AbjIZSDe (ORCPT ); Tue, 26 Sep 2023 14:03:34 -0400 Received: from mail-oi1-x22c.google.com (mail-oi1-x22c.google.com [IPv6:2607:f8b0:4864:20::22c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F3CD412A for ; Tue, 26 Sep 2023 11:03:26 -0700 (PDT) Received: by mail-oi1-x22c.google.com with SMTP id 5614622812f47-3ae5ee80dc9so428574b6e.1 for ; Tue, 26 Sep 2023 11:03:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751406; x=1696356206; 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=p1oF8D6L/zHs8JV0l5iOpfWZ1vQXVlP5otOIE5LnMVE=; b=uX7g8ZQ3lnbNw6chreWxDqPww3T2Ts5r/2GdiXdTbm8TRDJGYOdyZlcE+Xk7m+Vwqp 50mftHtddI9Y3WbY/eGNvVYJFVyHfIoy5in5DdRfTc4JGV74eZ8lYhvqv7ehVcrj1849 0mym5SyKUyHTQQSQGINDDiEKFpm83nizdXF29ewfFObQrZlN2EXi07L5DXlyZR49tW6q stS8X32FIU/gwUOpwBIsHuQP+krNaZa1wvklJddprx6JP2bcXqumNh8LSc5poEaEFpVH YxQ38HzawNdtU/MeneHTSffwo6vv/yD2NGCkNZMHaTxdLj678bzynyhYXktnl+gifX1v ziEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751406; x=1696356206; 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=p1oF8D6L/zHs8JV0l5iOpfWZ1vQXVlP5otOIE5LnMVE=; b=vw6Bw8CQqaDevVcU3KYDc4NsMFF2O7f136STYDoC3FSu0nhAvzU4vybHqPDO2fpsYH gL73+MmTKH/vXv+1llao6aX3xn38VFBePUMGX66Ekn4dofutBnHKxuRmAKpLow/hEARV fWcXeP3WkC4wH1flHu2vS215+PhbXCLPxrQpBo27nM991/NevQ800E4RBvh2YZtisyjs BJrL1wfXvSnHPgFXR3ZnOsGqDr0vSvuSCeR8fi4FO87XrlrmBD0UBil1hqkoYy9aUli2 NBMyVUElNKPNRdBoLwke2EO3eSjrlnjW8WKsc9J+Iyp21PgiNBbpedl4VpGKe9TPgS7u XMvA== X-Gm-Message-State: AOJu0Ywd3+olcFjAC4NLvAoMFn+j/g1MDhUMIv/B8goYIDWKi/7YNOEj koL/GyhvF8ZRqrdmYSm9urxd7+GNyiAiMyFWMdWRcA== X-Google-Smtp-Source: AGHT+IE9G2kim/Fm7GXGKvUV65dCaozCBClwU0UxSEyCH8yfAi4XApfUvUvpfOHVs2DDnjSFZ4yo5w== X-Received: by 2002:a05:6808:44:b0:3a9:c2fe:335c with SMTP id v4-20020a056808004400b003a9c2fe335cmr12831537oic.52.1695751406058; Tue, 26 Sep 2023 11:03: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 he21-20020a05622a601500b004120ae42859sm2851021qtb.90.2023.09.26.11.03.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:25 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH 11/35] btrfs: add inode encryption contexts Date: Tue, 26 Sep 2023 14:01:37 -0400 Message-ID: <914073e0c170f945d3b77d2311027c8e1399ef8d.1695750478.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-btrfs@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 3a53dc59c1e4..bb3a83d01032 100644 --- a/fs/btrfs/fscrypt.c +++ b/fs/btrfs/fscrypt.c @@ -1,8 +1,125 @@ // 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, .key_prefix = "btrfs:" }; 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 94c2e13934aa..f261113e7242 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" @@ -6088,6 +6089,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); @@ -6123,6 +6127,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)++; @@ -6300,6 +6307,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. @@ -6374,6 +6386,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 9c05216de36a..ae674c823d14 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 9fafcaebf44d..50c9e01a3cb4 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) @@ -1063,6 +1067,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 Sep 26 18:01: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: 13399485 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 15387E7E65A for ; Tue, 26 Sep 2023 18:03:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235460AbjIZSDi (ORCPT ); Tue, 26 Sep 2023 14:03:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55246 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235432AbjIZSDf (ORCPT ); Tue, 26 Sep 2023 14:03:35 -0400 Received: from mail-qk1-x72d.google.com (mail-qk1-x72d.google.com [IPv6:2607:f8b0:4864:20::72d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 249A713A for ; Tue, 26 Sep 2023 11:03:28 -0700 (PDT) Received: by mail-qk1-x72d.google.com with SMTP id af79cd13be357-77428510fe7so287795185a.1 for ; Tue, 26 Sep 2023 11:03:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751407; x=1696356207; 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=FAYbZn+3zKESj4+tPdu4mLEyDQiSn3GiMVrnztvdQzY=; b=XB6aQRLJv6iyEAFhPfXbHHCMvIDsWdM0m+rk9hl7KPXkjGoi67O4WwzmayPcf7o0f+ UkbB6xn8cS6hyFAsAT93ZwVZo2gKGxnOtnS3zAlUN/bWaHOkE/mhcaQpVXKguSJPimZ/ 0T/LiugeOPhS1zYbX+NfPolu5J/EcNKYO0t9/C7Ik+wi34P+xljv33MSDH6Co+gsVbTe 13zoHnKpJADo3ONVflxO6qYQ9KQp0VBVbybL+w6V1sbqTzmwj2wflF568+yzmYziI2Cb ivD8xGmuULN2K8fKXjtdP7vDB1JGMbJ3fvxoDHKGWaTmxz47CKuL6zmX3HEIHlceCOqP PisA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751407; x=1696356207; 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=FAYbZn+3zKESj4+tPdu4mLEyDQiSn3GiMVrnztvdQzY=; b=HM2m+wxrEE6Ls1zqSa9ojUCqprY2TndeSjHI7J1ySkcDDzJdRp7JWWa8jaI+aY704s AjGkSH/NRZOL9vzZ3O1/pluPKzeauFvT8VMABzGeYH6A6sUKfJmWgr0Kza4RuI6jgyJW Cx5mLgvx/GeU3Xx9dTVa3+2uzDjz08qaO7b9az+7GX1eMvBSOiHu8s8Pdxtty7W3WoQa tT2YatBfIo4lnGcQvnbXqM9zByon7JwhNmjqOZkvvXJ8EemPePDf0Gu0FcxwP7OZBpqS V3KzoPrNCh+wnxJ+ckNKomRO4hcUrKIJON3ggSqA9C/+Vr9r2XUQGVHZU3dc2RwowHiz Ka9g== X-Gm-Message-State: AOJu0YwTm8LaSEDQ3DOUsw9KASRTCXitMPECusI/RiRkb15uode1LQW0 GZ7+C9QWmDDHbP2Pg9sMZCSX0ZjPNUOjzYBjZ+iORg== X-Google-Smtp-Source: AGHT+IEbYaO+ZErI7gGdpQz7QomtAVCxiQZR0dsAkeisyHYT6gd2TPyQzGCwmAS8C1wREeXEz/SpfQ== X-Received: by 2002:a05:620a:1a1d:b0:76f:1614:577a with SMTP id bk29-20020a05620a1a1d00b0076f1614577amr4035271qkb.5.1695751407125; Tue, 26 Sep 2023 11:03:27 -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 e14-20020a0ce3ce000000b0065b0771f2edsm2454746qvl.136.2023.09.26.11.03.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:26 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH 12/35] btrfs: add new FEATURE_INCOMPAT_ENCRYPT flag Date: Tue, 26 Sep 2023 14:01:38 -0400 Message-ID: <98060c8ad3a994a78872f85e0cacce0842c7c0b6.1695750478.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-btrfs@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 25a43ca4e0dd..cb2b0d442de8 100644 --- a/fs/btrfs/fs.h +++ b/fs/btrfs/fs.h @@ -232,7 +232,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 21c5358e9202..2b5d60cb7fed 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -2378,6 +2378,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 143f0553714b..409244b569a5 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -305,6 +305,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. @@ -338,6 +341,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 e2c106bb0586..3ff21c95e1bb 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -341,6 +341,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 Sep 26 18:01: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: 13399491 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 14D86E8181A for ; Tue, 26 Sep 2023 18:03:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235478AbjIZSDk (ORCPT ); Tue, 26 Sep 2023 14:03:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55288 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235465AbjIZSDi (ORCPT ); Tue, 26 Sep 2023 14:03:38 -0400 Received: from mail-qk1-x731.google.com (mail-qk1-x731.google.com [IPv6:2607:f8b0:4864:20::731]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B229010A for ; Tue, 26 Sep 2023 11:03:29 -0700 (PDT) Received: by mail-qk1-x731.google.com with SMTP id af79cd13be357-7740729ae12so621015585a.1 for ; Tue, 26 Sep 2023 11:03:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751408; x=1696356208; 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=wbh7VV9KbEE9zbDAudiIoyZIp5Pe92r58y3UHja/Zl8=; b=Hqq842PvBUKHBPGAk/SVcK9POvz5jNBhZ7OF4ogb5RKKQ/TaRwWy3cn5GbTqpsdABK dzk3hsCJ3Lg7VNjmqFiYG6FZc8q7yPRVKG6TiLJTYHL+kiJJMB39FXM9/Nv8x25Pwmnx nos+HbJl4dr20yJ8Dn0TiK18U5rE5Vcs85j8oOnH4HOzTfNO7WB51lmXeqCdEDBu7rxX ubbWYEMvIlY9reu3pJS86Wyc7IyTyJPB6p6840mQ1oqmMsAt0amnX4s9lT2BL2kVNuZM tk7SmoMDnIYvAlyDTBbnnXOG+5P5tTUIaRXgWoXH3ryeywXG9OKdFIwqtybVoy6AUNNc /vlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751408; x=1696356208; 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=wbh7VV9KbEE9zbDAudiIoyZIp5Pe92r58y3UHja/Zl8=; b=W7cjG0Uqieb7jd4kLkRbYMFXTdW3yWe4W/BzzWSHMuvr/aA9F5B9uIePP70/RTJHa5 3A80PJ3AIsb0vCxSuC1Cm7hL4QC0Xab+ObJylR0BMac1MSnb4uIhKzIwzr2OJ7dTdfH8 h0paZ+mgda9WeV9BwCZlXDmW1+WG0PkZoiXbA0LkHlnfNiie//V/gQ9buKZB5DPmQWnm mPzw4QW4HD7ItbYyzfLOu8mR/QB414sbXIfVkN5CpgtD9Wyuz/QvqiZ9NOgVw15g1aNc 6DXNKsymLvZPpaLSrVRvvkhwTJp4DkIwoV71IHQLR7+Z33ZJXwm5M8h2AUZWoadUNEFU 4ypQ== X-Gm-Message-State: AOJu0Yzq/NKOrRjNSnd0KaGB4p1AgCFBEVVa8uj73TsC09PoPsgpxOQr KSOhZCdkOsHlPkx9NopImMRSVugAnCwfEIU1FC/JGA== X-Google-Smtp-Source: AGHT+IH1YfpzNgpQqpAdLjIKF3TAodD88ca4tiqM1nQ2LHrja+NT/kdHlMGVAu/7J8b11tUVJuJWjw== X-Received: by 2002:a05:620a:2ac8:b0:76f:1d96:4eb5 with SMTP id bn8-20020a05620a2ac800b0076f1d964eb5mr11308516qkb.36.1695751408247; Tue, 26 Sep 2023 11:03: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 e12-20020a05620a12cc00b00767d6ec578csm2031929qkl.20.2023.09.26.11.03.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:27 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH 13/35] btrfs: adapt readdir for encrypted and nokey names Date: Tue, 26 Sep 2023 14:01: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-btrfs@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 68ebb6096822..93390f12a4ef 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -422,7 +422,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 90369d132d4f..121746b7ce95 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 bb3a83d01032..588966f0414f 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 f261113e7242..ccbaeea68e2e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4049,7 +4049,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; @@ -4067,7 +4067,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; @@ -4095,11 +4095,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; } @@ -4120,8 +4123,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); } /* @@ -4139,7 +4144,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); @@ -4151,7 +4156,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; @@ -4202,7 +4207,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; @@ -4239,8 +4244,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) { @@ -4257,8 +4260,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; @@ -4284,7 +4287,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; @@ -4301,7 +4304,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; @@ -4624,7 +4627,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); /* @@ -5328,32 +5331,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; @@ -5365,13 +5359,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; } @@ -5644,20 +5638,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) { @@ -5666,9 +5667,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, @@ -5683,7 +5685,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)) @@ -5695,6 +5697,8 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) } } +cleanup: + fscrypt_free_filename(&fname); return inode; } @@ -5883,18 +5887,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; @@ -5911,6 +5929,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; @@ -5924,8 +5943,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) @@ -5939,8 +5963,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); @@ -5960,7 +6012,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; @@ -5991,6 +6044,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; } @@ -6441,6 +6496,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)); @@ -6496,7 +6552,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 c4d8900f91bb..cc262305f4c5 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 Sep 26 18:01: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: 13399486 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 0722CE7E62B for ; Tue, 26 Sep 2023 18:03:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235470AbjIZSDj (ORCPT ); Tue, 26 Sep 2023 14:03:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55270 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235455AbjIZSDi (ORCPT ); Tue, 26 Sep 2023 14:03:38 -0400 Received: from mail-qk1-x72c.google.com (mail-qk1-x72c.google.com [IPv6:2607:f8b0:4864:20::72c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6EE8B120 for ; Tue, 26 Sep 2023 11:03:30 -0700 (PDT) Received: by mail-qk1-x72c.google.com with SMTP id af79cd13be357-77409065623so557827585a.0 for ; Tue, 26 Sep 2023 11:03:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751409; x=1696356209; 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=TmXdaeI9xeYx0BBBrgcCT3hL6DULvaaya1NKFl2gOGI=; b=csRuL6/ie428vpSapLOzr+l0UYLQlXakH3ZxA9deziGbpNwS7DWSrEHjwnPEiHHQ2y sjvg0SP5f5i071bT9Yc7T4LEFUOEua77LlneovAhpKujYFQQt47jIwEOFS0BKFbLaPaG m/heSHxmLQD86b0YNtv/TXN3+zl95JdziebJmtIEhbC+u3ekzq9rKbYTvx406f01vUuj gq3X0pjl+5jYLhnDOAx2Vj89EvpRMGurtAtl98vvsVMoyW6RUU+oha9+DqtNNhvNO6OE 1fRvC0YQSyxZcNzhbmPDE8ziR1plRQvtVrn3HEjO+MJGIJZ8SacohWpkjjlGizC4tfmN ATnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751409; x=1696356209; 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=TmXdaeI9xeYx0BBBrgcCT3hL6DULvaaya1NKFl2gOGI=; b=A9Kb/mZDu49076idsIaQU3TcomyH+01EYa0uj0ke2tSW9FnE/M1/JvaU3daATe8mMl PvuQELi93hOgniED/k3lSl3RIv8lVvoz3OTeJUiHwhaWwtevfAL7CSOIVIPvmpIXQ0E5 WeeFj29Lpeu4HbN7bxS/7zyt8AYoF+SPYx/Rlpqaq1+RlIs6IWh0CgwU2ACtIba2LpZp kOiX1Lowa6GADDqE6nz8/NFPRZQjtpbjUvLB0EUnGRx0mKy0VkAj1ZfoNQCejOfr0Apr wkS9Tv7zNES9IkhSI1bhKczp+wrCsdec6v8ZNCD6AXLxTKpTj6F7y+sguCKcd5uoetk0 3eQw== X-Gm-Message-State: AOJu0YzsssROUYZ8813xZviITy1HnkxJy99RMJWn87Q6XaPj7T9IHzf1 EGxxSaiq+DivPeUuf0mGnnfiJoPFUFPXJOB8hvU5tA== X-Google-Smtp-Source: AGHT+IH1VMMScr8itd/IGkf3v0WELyvvY4Zwh7Pl69hBp/W0isHpKhJUjVz+ZrvF1jBH1iF3em4LZw== X-Received: by 2002:a05:620a:a1e:b0:774:20bb:2473 with SMTP id i30-20020a05620a0a1e00b0077420bb2473mr8947961qka.25.1695751409393; Tue, 26 Sep 2023 11:03: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 cx18-20020a05620a51d200b007742c2ad7dfsm2497732qkb.73.2023.09.26.11.03.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:29 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Sweet Tea Dorminy Subject: [PATCH 14/35] btrfs: handle nokey names. Date: Tue, 26 Sep 2023 14:01:40 -0400 Message-ID: <705b288d259f0fde3949334250378c620ab84953.1695750478.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-btrfs@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 588966f0414f..254e48005aec 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 Sep 26 18:01: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: 13399487 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 B0343E7D27E for ; Tue, 26 Sep 2023 18:03:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235469AbjIZSDl (ORCPT ); Tue, 26 Sep 2023 14:03:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55318 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235466AbjIZSDi (ORCPT ); Tue, 26 Sep 2023 14:03:38 -0400 Received: from mail-qk1-x72c.google.com (mail-qk1-x72c.google.com [IPv6:2607:f8b0:4864:20::72c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ABDDA12A for ; Tue, 26 Sep 2023 11:03:31 -0700 (PDT) Received: by mail-qk1-x72c.google.com with SMTP id af79cd13be357-7740d57e9f3so561384585a.3 for ; Tue, 26 Sep 2023 11:03:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751410; x=1696356210; 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=NtWGC2dr4Dt18NXh3XbNn734FYbuI4TsF3KP5ThfnrU=; b=FuTaIINx90YcGXaXRierRNtlcwjW13mASR3wXUdskSmcRdPy0sVdyjjeFKQ9CUW0Mp dz+qPj5+Z4aW/A32YYGD/X9nBjM2TPHo4rMmZLu4ubEXCh+5tyydxDfhQe6D36lPLAIU /1QTuLIG3dC02pnbHsVSzQiIxGDJlx9ixGS8e2vGUDO+L62AuFQ6rJJJ/CBjG62BEGO7 XI1Tf+g/4q9WVdJMyWIIZEKO8nuNM5leAnLOkMWsVAwJQao+p3hSqtbQPPYrUmIbNmLy gj33eUf/xWdoNDXQVQUO2f3IFHvjEkL39UjfW4c+KsndbGS+Ge7h6bJJ96Ca45vk7cYa lrwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751410; x=1696356210; 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=NtWGC2dr4Dt18NXh3XbNn734FYbuI4TsF3KP5ThfnrU=; b=kFvfmlCW22y8qOhRcGuAruupUyLH2QGAqO+hIqwZAKPY2uI4PIyAUlV6pbid3BofYz GJLx1Hv7oa1r/z/ntrfUvHOmE0KrQZSywEm83JH8DhYV/9Tcd2GbnMK49/SaFVie5yTt 8Q4/xnuyynLa/40glrwfyNp6iVLIg7pVbpdbXEk7/jj1a8nJpIwC6Flj0xWgeIr2L0xK dYsZmMc5qH7Ysn9r0KQjD3PO8mqvoayjd9E5xt2c7Jmk8W5PZk+4rbOlrjXtM/O9t4kx VTJ1j1TMNGAxEWfwzHQvktzcU71v7nGO5sv9HvQn6TbV5+8Zb21Ro4kvVXrZq6mQlavQ Lp0A== X-Gm-Message-State: AOJu0YyyjawjVSIACwUNflJJXWqfROc55Lekh7aIwA9t6T5YBgYgBHgP NPtpNYZ+HsKxjgUPlzVLYNLY3FNnpW+x9CLJ3z43yQ== X-Google-Smtp-Source: AGHT+IHMhr0lo610U2KNalLhILcJvuImx6f7yCcB+LJfP81hTll4FSKpP9VQXOcxOrV2NSVp2yLC5g== X-Received: by 2002:a05:620a:751:b0:76c:b8b0:769d with SMTP id i17-20020a05620a075100b0076cb8b0769dmr10085224qki.39.1695751410676; Tue, 26 Sep 2023 11:03: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 i17-20020ae9ee11000000b00767d8e12ce3sm4917933qkg.49.2023.09.26.11.03.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:30 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Omar Sandoval , Sweet Tea Dorminy Subject: [PATCH 15/35] btrfs: implement fscrypt ioctls Date: Tue, 26 Sep 2023 14:01:41 -0400 Message-ID: <9faf5ac92793fa1459aded3c23076c667f404f29.1695750478.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-btrfs@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 ae674c823d14..ddc2d2c7fc7f 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4587,6 +4587,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 Sep 26 18:01: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: 13399488 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 B8227EE0205 for ; Tue, 26 Sep 2023 18:03:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234911AbjIZSDm (ORCPT ); Tue, 26 Sep 2023 14:03:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235471AbjIZSDj (ORCPT ); Tue, 26 Sep 2023 14:03:39 -0400 Received: from mail-qk1-x72c.google.com (mail-qk1-x72c.google.com [IPv6:2607:f8b0:4864:20::72c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A9B2B136 for ; Tue, 26 Sep 2023 11:03:32 -0700 (PDT) Received: by mail-qk1-x72c.google.com with SMTP id af79cd13be357-77433e7a876so284184785a.3 for ; Tue, 26 Sep 2023 11:03:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751411; x=1696356211; 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=vFmLojnAQHX9YXUek43MmCebXJuRqe4GXtQt5j98L5c=; b=PfBq3zaZ0pBC1BrJyRE9dW5sYMqAeiiHWww56Dp6EH40n6Ck2eFifE81k0Z1XBxclK 5Ip427Pne1SRRqDncudKBWY/x4kJ0wXuS197uugNB47oNIFtyfcZvCU0HBcxuP8boSD3 e/ZN/BM4kx/0OYgsN8BLb+91LvSgQD0kX5GHuRiJN4QWFQ0uaHMDMrUB5R6XiqkcvP6p 7v/I8mhMuVlx+H8upcFH3I1hWLrR4Px2XeXQyxBFTyKrXzNj7p1DMa2eV2j/CXHXYcb1 FmQpMyXD+v7MLPkdMfU9KL3rSC1ldKDs34t5K6yz9rh/6z/XR3A+6dpwExaHuuxXtvbS wMGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751411; x=1696356211; 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=vFmLojnAQHX9YXUek43MmCebXJuRqe4GXtQt5j98L5c=; b=cLMDn7BKOd1fUJwcQSXtQtzKDQm36uTR1NoGXZ332RjwhRebVqUxegeOjapqaADuv6 RYOkHg7TFu5ogu42Si4GLpv7evEJwGzv9v4dMmz/DlTxOgnR8/IpTRJv8tRJVC5zBOqJ PO+6AnxdlodEVJ+PmDZp9ZKiXuCe44JDk6h2VLOapJN75O2WicqY0YqVsYLONyBx6kTE PIudOb1naSrGeDu0MICwIKno4xf2qz284nVUJK4s9O3ZqxFiPKIdERvS39VXTO8bh27T HilOGZ6QDsHs02vuZyxto8eyViGF/SKt6gKv7M2KTReAW5AzNjQPTJm/30zbhMF2mo1L +ULw== X-Gm-Message-State: AOJu0Yxqym+BxIX0V/c478u0lmQz66ewbD+PsHoWaoRVddRNadIhe980 nNF+RHN/jCMD4slcTqwIU5Mc8OWJs4GXI46goF43pg== X-Google-Smtp-Source: AGHT+IF0jSltUuviG8KvY1FN5h0GExlxFexp4nMp13D6VaWn7ON/O1uWrDh6lZh+i7fEv1MXko7mZA== X-Received: by 2002:a05:620a:1a87:b0:76f:f64:58bf with SMTP id bl7-20020a05620a1a8700b0076f0f6458bfmr12674146qkb.18.1695751411725; Tue, 26 Sep 2023 11:03: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 e15-20020a05620a12cf00b007756d233fbdsm379708qkl.37.2023.09.26.11.03.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:31 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Sweet Tea Dorminy Subject: [PATCH 16/35] btrfs: add encryption to CONFIG_BTRFS_DEBUG Date: Tue, 26 Sep 2023 14:01:42 -0400 Message-ID: <1b65ae762b4039cada3f29b996de690b34aad0c1.1695750478.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-btrfs@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 ddc2d2c7fc7f..8e5f9dbb547a 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4587,6 +4587,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; @@ -4615,6 +4616,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 Sep 26 18:01: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: 13399489 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 932A5E7D0C4 for ; Tue, 26 Sep 2023 18:03:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235484AbjIZSDn (ORCPT ); Tue, 26 Sep 2023 14:03:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55352 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235480AbjIZSDk (ORCPT ); Tue, 26 Sep 2023 14:03:40 -0400 Received: from mail-qt1-x82b.google.com (mail-qt1-x82b.google.com [IPv6:2607:f8b0:4864:20::82b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B318E10A for ; Tue, 26 Sep 2023 11:03:33 -0700 (PDT) Received: by mail-qt1-x82b.google.com with SMTP id d75a77b69052e-418201cb9e9so20202281cf.0 for ; Tue, 26 Sep 2023 11:03:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751412; x=1696356212; 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=x1ut1eGlCPCmMqejgBLg5HxIEK1EjS+ponZAJUh/G80=; b=Uks2nXAmEsqrJQh8sVM19oeXDuI7hcFAsG5HTKABJvy+uuVfuQUv+Vz8aqt9n5/Kp2 iv9PxhkAiLSy5kpbNKlC3wHL2NqoVDvaJaOVvv781BkM6Z8SxNP40xf063hDWnmIiGDg 2oSXDfPfhyLsdOUUUgN5t38C6tgHzrYToEnR3HCq7ZAoWDzHsZy9eCTovSax/lsasSSz yIpRruE/BcSlYRT1Cc93EN6x4EQEE9xchhjkkWwN7ayFYeMQVkuoSTzLglEhkjnh8lOz JgdFwtfrqPtUNZ56wHTXpr51Cy5UZ3yUrYedfJT9RDNOQ+a2Kri0lOpBNmg2451w6Nrn 7UWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751412; x=1696356212; 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=x1ut1eGlCPCmMqejgBLg5HxIEK1EjS+ponZAJUh/G80=; b=NxfT+/IzfJpsilkEOUxqS5oGQxlvlpWAKIe9eq9gAUnUY55EAp4bkTntGD4ey3PbAp feP7VTOx/1+iZGXMRX8Tl4Xg6GHj4fJAMlxPi79cn+IUhLuQ3c1VhZBcpxenpQDgEhi2 TlID5FPWMzx4ZgBA/9qjIEnXz0ffYm31wyDnPIOh5WQ8mOq4zRkuo+JMuwH+Kox1Ij+y lFu1own3MFMB61Nwnjfj54jzL6MPy1achrjFYYyaQzIjYAb2PMHb+alyEutl3UQkis1B QR29EwMafCeYlUhLVSwIjnLYfavqfS6GB6J3Kh/r5+fqGYNMc/PiB6F4WX7eCsRaY1vY XR+w== X-Gm-Message-State: AOJu0YzN9MGWcLGtvq1QkQtSvwbYlWQKjWH3wDisU/TLJUGJkXRcLB/Y 4p6iDiIZ6X60HKJ8FNc7hUAZAAemOOAinYOjr431DQ== X-Google-Smtp-Source: AGHT+IGDD3CLb6BKRvIxHljcisUPwdgauW3IXylDs1wlrx2+biHroD+EcrAiMFJi2EDWZyxRJJeRjA== X-Received: by 2002:a05:622a:182:b0:417:a209:c250 with SMTP id s2-20020a05622a018200b00417a209c250mr12291473qtw.36.1695751412714; Tue, 26 Sep 2023 11:03: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 jx18-20020a05622a811200b004180fb5c6adsm2631371qtb.25.2023.09.26.11.03.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:32 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Sweet Tea Dorminy Subject: [PATCH 17/35] btrfs: add get_devices hook for fscrypt Date: Tue, 26 Sep 2023 14:01:43 -0400 Message-ID: <5d485b376693246af86f30f859efabc62e5e37af.1695750478.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-btrfs@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 254e48005aec..4fe0a8804ac5 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,9 +180,44 @@ 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, .key_prefix = "btrfs:" }; From patchwork Tue Sep 26 18:01: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: 13399493 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 48EB0EE020B for ; Tue, 26 Sep 2023 18:03:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235486AbjIZSDn (ORCPT ); Tue, 26 Sep 2023 14:03:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33660 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235476AbjIZSDl (ORCPT ); Tue, 26 Sep 2023 14:03:41 -0400 Received: from mail-qt1-x82e.google.com (mail-qt1-x82e.google.com [IPv6:2607:f8b0:4864:20::82e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EDC4E11F for ; Tue, 26 Sep 2023 11:03:34 -0700 (PDT) Received: by mail-qt1-x82e.google.com with SMTP id d75a77b69052e-41820eecff2so19631741cf.1 for ; Tue, 26 Sep 2023 11:03:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751414; x=1696356214; 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=9KLmh2uaP15Sf9VJ5dLtRkPlzZHoo+djMGrpIoeSOJk=; b=shf1DcHi9otxTUCLdnixnQHt2PLxxOP76AMPtM61f9ri8ZwhBzEMbyZaQOaPCzzSWG 5kNyvzlII5cvi27IlmgoAzSsBTWlWFu59d2X8vpiJeSQnC72R3/wAHVVs9mbRvgnKBkS F52gMfUXGzKTx98MA9tUyF+g2rb1ABFBJ9yBtWhDUtXqAGI+YRJPM5CzRGan86obGScc HsBHmaSz6tHRwWfZrGGGnBLUAbzmzdeSa6O+AtaMKqtZR9xzxaS8biIGlpHDLeEzckWL 2nCt8FPM6gGRtBMMpWptKOuvLzpuUAMqd0foJ96y5zUJ1QWeTDobErMNA/kVl1Rq2hMb lyrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751414; x=1696356214; 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=9KLmh2uaP15Sf9VJ5dLtRkPlzZHoo+djMGrpIoeSOJk=; b=UE/AZi+GHxpJ81w/Kc848/QRCzRUtRDkxalZxQAjyrzOGbd+caCTC0Xnw6MdD1T588 u1NMQ5OaOuwa36fWHxv6xLLU/cJefLWMmceeVGL0E+hp1zG9chMyxZx6XlzfoWqGyuGf GI1Wp+IK7P/izYeK1tL6PQApBe5VyxqSBYyMtF4TG/CXkwKBcOOLYekM6KsTC/hZx8lx 8gdpYPODj8NPdmPIAYF0hjpr0yQL2smPXfIWzP8VdtTZOZLKBNq4rADA8YrE3683hLVw c8rQLuoXVpYOk2rw5ds0kF9lVkrDvsN0AjUt5WcD4esHb9oy+olXIt+7OSUM5ZkoBBcy SdSQ== X-Gm-Message-State: AOJu0Yw0iGd9FFLAeIOxctRT1TwPiZBGvh/GBRvg9DEmvdSvPgPT0ilw sfawktrYWOFeTSob5aWZurETKVvTx+TEhzDGv1MqzQ== X-Google-Smtp-Source: AGHT+IEXrkR7x9Pl2saCQ8KSIwNXmAj6BRTstm+LKNEDSuk08JhC7QykpQg3Fx5yvNLDXUu/U6NaCA== X-Received: by 2002:a05:622a:34a:b0:417:fe9c:6dce with SMTP id r10-20020a05622a034a00b00417fe9c6dcemr12030385qtw.25.1695751413829; Tue, 26 Sep 2023 11:03: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 fp6-20020a05622a508600b004181aa90b46sm1671764qtb.89.2023.09.26.11.03.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:33 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Sweet Tea Dorminy Subject: [PATCH 18/35] btrfs: turn on inlinecrypt mount option for encrypt Date: Tue, 26 Sep 2023 14:01:44 -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-btrfs@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 8e5f9dbb547a..33bf4d9416a9 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4599,6 +4599,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 2b5d60cb7fed..a8a609f4a9f4 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1120,6 +1120,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 Sep 26 18:01: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: 13399492 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 175F8EEB563 for ; Tue, 26 Sep 2023 18:03:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235490AbjIZSDo (ORCPT ); Tue, 26 Sep 2023 14:03:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33686 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235483AbjIZSDm (ORCPT ); Tue, 26 Sep 2023 14:03:42 -0400 Received: from mail-qk1-x735.google.com (mail-qk1-x735.google.com [IPv6:2607:f8b0:4864:20::735]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A9A610A for ; Tue, 26 Sep 2023 11:03:36 -0700 (PDT) Received: by mail-qk1-x735.google.com with SMTP id af79cd13be357-7741c5bac51so464102785a.1 for ; Tue, 26 Sep 2023 11:03:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751415; x=1696356215; 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=w8WS35cLh6qwSpXHQaQofYAl31yNr6wevnopqXm/zJU=; b=KPxVnay9LNLGFNcDprER6uvHl9N5+5pMvqH4BCBbyPT2cMJqp0SaZuuKYRYgu/xq3v 9K8XUfN4HUHnTc6Zaty0duSxjOskoZpp/ExZINJNBsP1JlPO/9/ZyjLtmwpY/5OPGVmd kLXn94jV1OF3ELPm5SqPgkTP1r6QT5VWwrPtviVjMjZo+zOU4GLcZWqvzrwBREBW7aD7 WXaZD7MDaUNq+Li8FMcms5yk0B8g0TJQEgEs8RqWmZHZFLzjkW47tDnpX9jRht44VXzi 7OpuLPcW17Zve55WktOA8uKLqY3AzdboOLbzgEyq4lI90gw7DyJ57P1D8v9zyYhM4w8a ej1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751415; x=1696356215; 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=w8WS35cLh6qwSpXHQaQofYAl31yNr6wevnopqXm/zJU=; b=uaSNu7LSYAsfcbiAl9UsQ5bzNQ0pM42iBbKENGROUUiwFMf8yTkWZLPQ3BrFpa1pXh PQaX9ECRUIGbzBwTakgCcPDnd4Dd3r5vw7rGF7/IgIgjWZlkm/e8x3ehDmCg0yWgXGyu 4r+0NgLtsYfPcKlZqeCggJ85pYN7QioCi0t9fkd0F59X+po+UMKfVUC2iDtzoUv5VVX+ WiBv/ZTJVYNTv/+LJHsM7vpTtaInwtwLUV5RQXYLvUoSkeVo1i4V4hCwxw01FLK2KGeu 6zj458eEvXndd0wgKFKD1Okn3mu5GGWIHWuwNmJ/XLMsApqCbn23dP/VHKVXuoDaNvzD qnsQ== X-Gm-Message-State: AOJu0YyFmn9ZOjdI7GL8R2lmlqDQM84SwMQaCXRTc/ARoruirAZ4Xk8C aLOeG5gbmzsE222n5L5yAQTWIRykv+aAzaZkVBwvBA== X-Google-Smtp-Source: AGHT+IFq0+UjXQqxQTELcq/6vffor5tzyIqIwNieYH/OAfGp/n/hGfspIQeg2WD2vGjrplarzJH5UA== X-Received: by 2002:a05:620a:4629:b0:773:bdb3:1318 with SMTP id br41-20020a05620a462900b00773bdb31318mr10395401qkb.15.1695751415046; Tue, 26 Sep 2023 11:03: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 c7-20020a05620a164700b0076d08d5f93asm4920623qko.60.2023.09.26.11.03.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:34 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Sweet Tea Dorminy Subject: [PATCH 19/35] btrfs: set file extent encryption excplicitly Date: Tue, 26 Sep 2023 14:01:45 -0400 Message-ID: <2c6e10642b211a7a6fb20234273a7c627c5c0b44.1695750478.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-btrfs@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 b780d9087490..5627f13a3d3e 100644 --- a/fs/btrfs/accessors.h +++ b/fs/btrfs/accessors.h @@ -951,6 +951,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 ccbaeea68e2e..db053b392d26 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2993,7 +2993,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 1f2c389b0bfa..c2afdf65c2bf 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 cc262305f4c5..f6f45a0f1b1e 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4630,6 +4630,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)) @@ -4651,6 +4652,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 50c9e01a3cb4..dee650f0082c 100644 --- a/include/uapi/linux/btrfs_tree.h +++ b/include/uapi/linux/btrfs_tree.h @@ -1095,8 +1095,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 Sep 26 18:01: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: 13399490 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 A9AC9EED611 for ; Tue, 26 Sep 2023 18:03:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235497AbjIZSDp (ORCPT ); Tue, 26 Sep 2023 14:03:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33714 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235487AbjIZSDo (ORCPT ); Tue, 26 Sep 2023 14:03:44 -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 3768A126 for ; Tue, 26 Sep 2023 11:03:37 -0700 (PDT) Received: by mail-yw1-x112e.google.com with SMTP id 00721157ae682-59f4db9e11eso83362647b3.0 for ; Tue, 26 Sep 2023 11:03:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751416; x=1696356216; 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=XrbBTlq6SUEE2oe2Hsm17SMa27dUAmVsqmKO5cSW0nI=; b=cVcekEtcu3osW0EkmlVnfIsJerVPkJv+q2CryBeQ7Yz332XpViXCIzV2jVq2pRWqUR Db5rPhLWmg5Lg3+ncYZW0zThEbsBbvcsGLVYLtLwQnkmFecjTLKXO2Laj8Oa8o5WU9FR UNXrXltINjcPpWhSl3UNP9KhmJvy24fWAAKJ8fKApzV1blrAd4gvrsErDvj4DNcoHWml wQjfxwPRzdE+v7wIQwOQ9yPdEMJ0cSHyoh7U+N5mGVbPx0mLH48hBnspJaYt4wXaVd5O VZtHogCDwYbq3LRmJ8ZYQkYxPapWcy40KgxWAVDjSypv84LHRDXTpG6CmWyRVpAAr5pK 3MhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751416; x=1696356216; 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=XrbBTlq6SUEE2oe2Hsm17SMa27dUAmVsqmKO5cSW0nI=; b=pJP1ZeLwYtTudE6YgKuc2H78SJGKyWPJt/g9KDBcWUAyr6hSq4nATxkd8AhXh/VOuF A57X8dTTmIUDscYec68a+DQNTEWtro9UEHCp47glZb+iG+VYLwVxOxwMZr1vzL5qwZXc npcIQhx7EhjfljTUN6SWAKtW3U0BngR9u/dLZModQEo6f39g236cqpLzQnxSNQTtJJr8 Cu7fCuXUgsPaPahVn98HcMjTKB2uicDwxyG4R52LJyuqW8qBBzMM8ngxZyeBAVW89Hp3 qfhnRdiqHZTi7vvOdwGXWN+mBmV3nuaNf44UFsQstX/uke6Co3CsybQ93qHEugHHznHW 25Pw== X-Gm-Message-State: AOJu0Yz56dCv05qErcrXIyPues4whZFElFY0/8t2mlCvzphzBcBE95fD WpZFhRkb5hLc5LaIh8nLdCB4xur3LPBVZasJqnnihA== X-Google-Smtp-Source: AGHT+IGq4cwIQizmr1i34EBsuDl/BhdizoBqq/+aVOodsyyyccHlPmrF0VYCfaBwxCEGXTo03/8w5A== X-Received: by 2002:a0d:ff06:0:b0:599:da80:e1e6 with SMTP id p6-20020a0dff06000000b00599da80e1e6mr11433800ywf.34.1695751416085; Tue, 26 Sep 2023 11:03: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 r16-20020a0ccc10000000b0065b151d5d12sm1732425qvk.126.2023.09.26.11.03.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:35 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Sweet Tea Dorminy Subject: [PATCH 20/35] btrfs: add fscrypt_info and encryption_type to extent_map Date: Tue, 26 Sep 2023 14:01: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-btrfs@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 db053b392d26..d26062b67211 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7350,6 +7350,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 Sep 26 18:01: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: 13399494 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 045B4E7E65F for ; Tue, 26 Sep 2023 18:03:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235483AbjIZSDr (ORCPT ); Tue, 26 Sep 2023 14:03:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33794 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235482AbjIZSDp (ORCPT ); Tue, 26 Sep 2023 14:03:45 -0400 Received: from mail-qv1-xf31.google.com (mail-qv1-xf31.google.com [IPv6:2607:f8b0:4864:20::f31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82AD219F for ; Tue, 26 Sep 2023 11:03:38 -0700 (PDT) Received: by mail-qv1-xf31.google.com with SMTP id 6a1803df08f44-65b051a28b3so31676796d6.2 for ; Tue, 26 Sep 2023 11:03:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751417; x=1696356217; 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=aMVZOqD5qMhAARWUPM9bumwM6QRjAQ+JBEENF8lhuIs=; b=eBx6fdTxUa1Q+Vmi6yML2Ohg7PDzxfwCO8K689z0nsYBP2GFUMO3qLGJVHjLphW0ro pL7tKN+E+7bN25kXHNNcTdQiK6VVgZQkWArkoxtzZZzi2pO9+6r2tcnRoPHm5gDP+TmU QxKTjx0b5IGf7ReeXG+k6eZrmxkFVptBMcmM4A3H26Q+eN2gpQirJqEOuPcMAnHokJpI W5R0NoTRY33wlHWbdFfGpLZNkRLeaUgy4ZmulJ7TzBWQQV8sEf+icoFrPmxgZNvRTpdL vx89+8BlQkkdyVCRerwkD8/kM9wh/CPPHL5xP0m0OazwZa3dQePrF2oYGfAb9rSzH1Qj QHRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751417; x=1696356217; 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=aMVZOqD5qMhAARWUPM9bumwM6QRjAQ+JBEENF8lhuIs=; b=X2Jw0ZmiqTFzWJgjwPbdc1LBBueiepLxmfs3UNdfzrdMVlM1DSvp5k2/sIShnyquvQ 4B/fm0F/dL4BgAtPGynCbbybbKn6HthxfohZFhfQFea+DpNt8UwfptWZhXqGQmDbcki9 lkdVksIwgo9z9s1jim0F1bs/dlyBT55JUjp2DIcjPBagpb2IyH0aI+FEYUFxcatxTGYh IiuUy9nduAMBqCjwNdOBvw7LyXLK8C3Yddad+FrEpE52K9/HRg8b6Kknq7GOJy0VN9Zw meWzf9Tcx6pnD1jfrgdNxmHv4KsZMpxzJphX4ERZMOitHXdbBa+G5VeJtPIUKEoyiK57 c7BQ== X-Gm-Message-State: AOJu0Yw9lT5aIgsBna4fPMulDc7uJNIoEtkhHU6wcraEtlNmgmM3J6IS B19PYWdnS9G+GTAsAFy7izGUHTNkqo3ZpuBQoG9x9Q== X-Google-Smtp-Source: AGHT+IGkbl+aPJ9BFcngOs3WUasdj0u/1uUNnx3vaBJ9ZrmuA25de+95BHcI3QUOql1n+cL9d7ZTnQ== X-Received: by 2002:a05:6214:5191:b0:656:de90:3135 with SMTP id kl17-20020a056214519100b00656de903135mr14335917qvb.7.1695751417304; Tue, 26 Sep 2023 11:03: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 c2-20020a05620a134200b007743360b3fasm1872163qkl.34.2023.09.26.11.03.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:37 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 21/35] btrfs: add fscrypt_info and encryption_type to ordered_extent Date: Tue, 26 Sep 2023 14:01:47 -0400 Message-ID: <47feb58788c2adb906a6df4c7994058a4e7d2d75.1695750478.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-btrfs@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 b133ea0bc459..d33a780d9893 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -182,6 +182,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; @@ -568,6 +569,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 1c51ac57e5df..607814876f1f 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -122,6 +122,9 @@ struct btrfs_ordered_extent { /* compression algorithm */ int compress_type; + /* encryption mode */ + int encryption_type; + /* Qgroup reserved space */ int qgroup_rsv; @@ -131,6 +134,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 Sep 26 18:01: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: 13399495 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 47708E7E654 for ; Tue, 26 Sep 2023 18:03:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235503AbjIZSDs (ORCPT ); Tue, 26 Sep 2023 14:03:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235498AbjIZSDr (ORCPT ); Tue, 26 Sep 2023 14:03:47 -0400 Received: from mail-qt1-x834.google.com (mail-qt1-x834.google.com [IPv6:2607:f8b0:4864:20::834]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 80E22BF for ; Tue, 26 Sep 2023 11:03:39 -0700 (PDT) Received: by mail-qt1-x834.google.com with SMTP id d75a77b69052e-4195035800fso10455311cf.3 for ; Tue, 26 Sep 2023 11:03:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751418; x=1696356218; 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=77x/Hy1aSzyf/SlLhZmkO/V30ynvClbK7xoDUcF2W5s=; b=0VBAH2Tm8BVRv6DUR8CEzhhGr8VferJtF47VeS11Kk6OmC98gUlMdWl1ovIHWPMoj5 7vo3Cr7FreJKm5Rw9Vv/IOSDYOnWqJooOD4z3jgYL2P1LiQ2hfRxIldVrFowmmWrzvpT Sdol5NjXfiAHIrL30D4gL6/gmwLhnn8creuPoYzJ3C4GLTKkxO8zrSJvwDl4pmIXAoAW 6PH6l4NUORFz0+b/6x2p7Jyl9k6PSKp4wW3Lg1AQSFqaTsnYJ6I4pPlXvfRPOkXYxe5M HgHlc6KKDbb6/wEkSQlprBs1dHgv7NHrn+pi6kM9IRpyz/vWXi8GiXoESQEiXWWOB6Jf 2qHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751418; x=1696356218; 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=77x/Hy1aSzyf/SlLhZmkO/V30ynvClbK7xoDUcF2W5s=; b=xAm1vHBRpjdqzdubUKaxZZTjPiNF91hdGGOpdEVlT/g4DuZnzIc1FeIyOrl0yNeLRi ObJOMAk48NdhS3nuGWhAt2iAiI6NFOlPapDXZpmSWl1B2WWGkXI4zFziZVsXVaeT9Pgu 4qITnODSgXBCPrtDXjrhU0A6rWxXng8App/R9dkFEtCRI5sd33Nn2weeuvHRH1UU3r7+ FaQArSAP/2Tdv3Z15uvoV6HSYFvoqC7h9jeV/FjVW/NakR/cLYhdnXq6meV5zkd2+ze8 coYBUxCm48K8i1XO9eQQUSE19D/RcQSn1mr1a/Sd/tfexmJ7uoGsABc05KuW3a7Ny/dk 5R0w== X-Gm-Message-State: AOJu0YyK9XqK2eyQ3yZnH6HYBUenSdRIAxgjIyIDXMWsAOAr6vmDddXC iDDUUjMdMBmXkzIz95m8imgJajgyOaO8QNJfsAS/SA== X-Google-Smtp-Source: AGHT+IHXxVEDQL63ZZ4XYwuRIYCyejbJDJImvvzOr0EYvSkZb+OQhvwjEXuep6HaxRpuGCYFc2Kl2w== X-Received: by 2002:ac8:1381:0:b0:418:1d4f:995c with SMTP id h1-20020ac81381000000b004181d4f995cmr4101881qtj.55.1695751418334; Tue, 26 Sep 2023 11:03: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 ex14-20020a05622a518e00b0041815bcea29sm2048234qtb.19.2023.09.26.11.03.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:38 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 22/35] btrfs: plumb through setting the fscrypt_info for ordered extents Date: Tue, 26 Sep 2023 14:01:48 -0400 Message-ID: <2364da0114abd49fe4aa6c1722174bad7d61a2e0.1695750478.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-btrfs@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 d26062b67211..903ec2d460f5 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 @@ -7041,7 +7043,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 d33a780d9893..81b0fe575011 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -147,9 +147,11 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree, } 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; @@ -182,10 +184,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); @@ -248,6 +252,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. @@ -264,17 +269,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); @@ -1181,8 +1188,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 607814876f1f..e19e62d5171a 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -185,10 +185,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 Sep 26 18:01: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: 13399496 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 17ABFE7D0C4 for ; Tue, 26 Sep 2023 18:03:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235502AbjIZSDt (ORCPT ); Tue, 26 Sep 2023 14:03:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33794 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235487AbjIZSDr (ORCPT ); Tue, 26 Sep 2023 14:03:47 -0400 Received: from mail-qv1-xf2a.google.com (mail-qv1-xf2a.google.com [IPv6:2607:f8b0:4864:20::f2a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9899510A for ; Tue, 26 Sep 2023 11:03:40 -0700 (PDT) Received: by mail-qv1-xf2a.google.com with SMTP id 6a1803df08f44-65b0383f618so30993286d6.1 for ; Tue, 26 Sep 2023 11:03:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751419; x=1696356219; 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=rBWLpxPh19X73dPFX8Yn4lHS0AwxjYc36S4EI8tWcB4=; b=Z11TucYEmFYrAcLd+ZvbfTrC33gK40vfWXC/FazykUVYGrQBrIwmrEKGaU+NqOVADy YcRcFhJw8U9VZx6Z5X92zJIM6p8Hy2s6gxNYjWrelNjGm7CavvX7s+6Pxqh9tQezWOqY ZBkoPs2AbgV35SdbVU70jVVkfyfQxsJPPKJYqpHKlOOU22FxR4BXyHRvxfPR4mmEF2wM bmne9qyxRpOF7xPcTIkpWonfggTznjwqsIJcDAmmFDpVAzcMa2p9lAkJee4mk8LgWqFN ZPGjDxgZ0KyULQZuI2KzSFr8PNtC3Gao8qi8wvDAPK7tK7qnO5KyK8uLbV2hM4MCUSLl Vbvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751419; x=1696356219; 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=rBWLpxPh19X73dPFX8Yn4lHS0AwxjYc36S4EI8tWcB4=; b=pv4vZx8SU+eJ00lfW0lhNFBTRaMYzMZFJ53pJDI+ZJ9n44cwHhiFT/Aib03+pCBgPp d1k/tcmXnKq2bFO80i9x+4xcnJv2Ql8mop5FTV8yq8/iLeHSk5Nw0uTHWoZv7xpuCL01 XIAH191771qTkoU/h6PCyhmXHCzuW8cYBDF6UoaOL0WTgVrdw8Awuc0IVbAjOODeps38 SM6lI6ld4Cbm/baIaJ3gvsjnYfJrwUdRLyyVugblgZw/TTjQ6rCPFQHY9FOqDzmaQVkx lMypYv9NLZn394+xgEph3bWqFxyZJZmjpZPUq5XzZk8O+bcDwxrHfpW9L19hTOSKFE0O imow== X-Gm-Message-State: AOJu0Yy2tJ5wRHTvpOXAQjJsW0Vx4YEBgBlFFLwtk++fSnGIwSiiRs8O AyYEMkf/jeZq0XpO7BPExGEFsemxI/ENiMKIYVynFg== X-Google-Smtp-Source: AGHT+IG7IzD1KAhaf6wk7yK22JmzPdW2RnO3UPwRzAYWcFaxLgMqt4hbuOT0nHwoYJ4K5KjnodLxCw== X-Received: by 2002:a0c:e183:0:b0:64f:67ae:a132 with SMTP id p3-20020a0ce183000000b0064f67aea132mr8431970qvl.23.1695751419456; Tue, 26 Sep 2023 11:03: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 o8-20020a0ce408000000b0065b1c26c89asm1365734qvl.145.2023.09.26.11.03.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:39 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 23/35] btrfs: populate the ordered_extent with the fscrypt context Date: Tue, 26 Sep 2023 14:01:49 -0400 Message-ID: <6efdb68cb164a54bb2b05a096cc8a3c793bfb1af.1695750478.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-btrfs@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 903ec2d460f5..19831291fb54 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) { @@ -7023,6 +7040,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, @@ -7034,6 +7052,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, @@ -7042,9 +7061,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); @@ -7081,9 +7104,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, @@ -7428,9 +7452,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 Sep 26 18:01: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: 13399497 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 74D49E7E65A for ; Tue, 26 Sep 2023 18:03:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235498AbjIZSDu (ORCPT ); Tue, 26 Sep 2023 14:03:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33822 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235482AbjIZSDs (ORCPT ); Tue, 26 Sep 2023 14:03:48 -0400 Received: from mail-qv1-xf2f.google.com (mail-qv1-xf2f.google.com [IPv6:2607:f8b0:4864:20::f2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A56A112A for ; Tue, 26 Sep 2023 11:03:41 -0700 (PDT) Received: by mail-qv1-xf2f.google.com with SMTP id 6a1803df08f44-64cca551ae2so55217726d6.0 for ; Tue, 26 Sep 2023 11:03:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751420; x=1696356220; 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=D//MPuNLkzciDWq9dR0jaALrWtf+3iz7sP2AlyCcVRQ=; b=KMQwh9l9axjwB8mxld6xIyW6q/O9O5mHNIWvQvB3EcighyRUuDI8LAgBDUJzvyEnmN fBuuU/TBGGGiurPVZDyRUud8CZA+2oTql6WwrQbZTIq60pUNKy+y9DXjbW9my9m949ev 5PBc9z0SFd8hiLTBcSBrh1tKGETR5d8JwemZFrMyGnE0AxbhhWavJ94kT5J17/ZhkMim RiDUH8srVLGxlJUgNfUEEI9bm8TtR6cJki7PGejN4jDUKNwsWcDQJC1djFPwLSk+MDhU OzvSNZtfUw8XtsPGtYYrSYtshZGm8M3LkYsiDU7nL8qbpdEY7zswyMY97uzV6i5Quy61 ch+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751420; x=1696356220; 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=D//MPuNLkzciDWq9dR0jaALrWtf+3iz7sP2AlyCcVRQ=; b=K2CqXORpMTv1Us805zynCALufe2BKfu3OwWSKlujxzmLyOaM/cf6mG2qKcJCWJhDjQ Ng3S7ai0eBl+9PekHkUC+iSsBLP0E9V9fzfIU20eh1/U+Fp1MgY0SfO9HB4T60HpR3Zh /nRY1QmF/XXbhvdODG2vURKG9ji6JRklStWPe1Orvclmt3OrhM06i9GJz9vAgRI2zcYp necNxQ4tdQnSGidoPmQO4ybHq6tLdKRvL3aJNMg7HSJQNChWC6xkHykb0qQWTypVRof8 GHFnOouFRzUvKhQXWOI5pMgULeKTMwr6jWVe63aF+4bOb51g/+obvb+snXTbnbG101jD aDNw== X-Gm-Message-State: AOJu0Yyht6vSPWArAuB8MiEP7R290NtDUET02HEpBzAMoU6MvsJe5pQ8 PQ+BrsjqKFwcLKwiyw4wYadKKW+IdpYiBXHoUxUwJw== X-Google-Smtp-Source: AGHT+IHeHyWXXybZzqU0PeU94MZuzH8je++ilLv7T7ADS8MV7IzztIR/78JpnKNOKFTrstDNb/kijg== X-Received: by 2002:a05:6214:f04:b0:655:d6af:1c32 with SMTP id gw4-20020a0562140f0400b00655d6af1c32mr13956040qvb.15.1695751420545; Tue, 26 Sep 2023 11:03:40 -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 c20-20020a0ce154000000b0065b31dfdf70sm279665qvl.11.2023.09.26.11.03.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:40 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 24/35] btrfs: keep track of fscrypt info and orig_start for dio reads Date: Tue, 26 Sep 2023 14:01:50 -0400 Message-ID: <9428dcaea310bb715222e231b71e5ea39ea5d383.1695750478.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-btrfs@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 19831291fb54..89cb09a40f58 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; }; @@ -7729,6 +7731,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. @@ -7810,6 +7816,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 Sep 26 18:01: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: 13399499 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 294C4E7E654 for ; Tue, 26 Sep 2023 18:03:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235510AbjIZSDz (ORCPT ); Tue, 26 Sep 2023 14:03:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57810 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235476AbjIZSDw (ORCPT ); Tue, 26 Sep 2023 14:03:52 -0400 Received: from mail-qt1-x834.google.com (mail-qt1-x834.google.com [IPv6:2607:f8b0:4864:20::834]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 78BB112A for ; Tue, 26 Sep 2023 11:03:43 -0700 (PDT) Received: by mail-qt1-x834.google.com with SMTP id d75a77b69052e-417f1eac78dso54471641cf.2 for ; Tue, 26 Sep 2023 11:03:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751422; x=1696356222; 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=DRKZzy6fAzE+FLjFaVzJb4Ci7b8/zie5hfsfMucJOQc=; b=yBHIBmB6GV1pMeMk8Up2yVvmCuaKy2rSToa/jsvO/G7DqynVUQPuvxQF/nKTPYt3NJ mMIpup3y2gdoRexPgqL3erMjXpfpYFS/3d8tHPpNQbGZ0ygTM4Lm60z+HvE7Iq0SqmAi MtD12IjYe2iDfrQNsO8S9yTmsxpiH/i0grx9tm5l2+cA9Vphr0CCUN9snosPm9SCzCDc sf5857Q5LlSQxsBdjYSVw9mkBEdBFvm0o37vbWjK+U8ER30qJ/B6uZ18u7bLURgiJto1 qS/2twgZ9wX77hRFc57rtk0LO6MypuijAk/zCt8dSIR0AE+LluJZhArMFe67nWSH4TNO X/Vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751422; x=1696356222; 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=DRKZzy6fAzE+FLjFaVzJb4Ci7b8/zie5hfsfMucJOQc=; b=vZ9tP9/XwueAsTm67j1e1zCEdud+s009ek0pz0yEKW/mmBEwFweHMgOBsVzFJzgbA5 P84ztOmih1q/6x7sWyBWQS+ifLpwRuvZrt64r+3bEqAJOKDARxswSxRsaSlV6AWuQfEg MwlyyrcaxK4WodwHzF/im08VRQP/3XnEDdXd6CLs4pIcY/DBE0ILUs/pP+rh0JnIvHMb T+Gcda3CgeK8eg72s4hAiaLlt2fdwkNhEcpBDT0xNwm1Ui3SEJV/8dQfwOqJJeZxzeVo N8Ei8Mdl0IPKrPaKKsBWHBoD8ULqYhiILifg37XiWHJ9vMYdG/Z+A6pNPknNXVH0RlPA tYtA== X-Gm-Message-State: AOJu0YyzaoE7/1ns5uXpJjFdUdakiyH84n+nr3bOuurCMo6HGN7H8FRa seLxK2qxg90FvgoYhKWhz5LBPMI2gT8nRaf1gDFTHQ== X-Google-Smtp-Source: AGHT+IGGa1wNABYl8BdVeILE7yPoKsOqH3jgC1N060dV3OkODJYsuhtp3DZLUzCXUL0yY7e2gkpAIA== X-Received: by 2002:a05:622a:1913:b0:417:914a:104d with SMTP id w19-20020a05622a191300b00417914a104dmr15198508qtc.49.1695751421627; Tue, 26 Sep 2023 11:03: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 t16-20020ac85310000000b00405553305casm4798417qtn.86.2023.09.26.11.03.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:41 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 25/35] btrfs: add an optional encryption context to the end of file extents Date: Tue, 26 Sep 2023 14:01:51 -0400 Message-ID: <80494ada394d2a9ffeee2e4864cea194d9a75d9b.1695750478.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-btrfs@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 5627f13a3d3e..3e6c81449ce7 100644 --- a/fs/btrfs/accessors.h +++ b/fs/btrfs/accessors.h @@ -934,6 +934,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); @@ -975,6 +979,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 c2afdf65c2bf..7fe6210c243a 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 dee650f0082c..5d9563fb6e7f 100644 --- a/include/uapi/linux/btrfs_tree.h +++ b/include/uapi/linux/btrfs_tree.h @@ -1067,12 +1067,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 @@ -1128,7 +1140,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 Sep 26 18:01:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13399498 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 A7644E7E65D for ; Tue, 26 Sep 2023 18:03:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235518AbjIZSDx (ORCPT ); Tue, 26 Sep 2023 14:03:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57826 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235505AbjIZSDw (ORCPT ); Tue, 26 Sep 2023 14:03:52 -0400 Received: from mail-qk1-x72d.google.com (mail-qk1-x72d.google.com [IPv6:2607:f8b0:4864:20::72d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C9BF8139 for ; Tue, 26 Sep 2023 11:03:43 -0700 (PDT) Received: by mail-qk1-x72d.google.com with SMTP id af79cd13be357-7740c8509c8so547569085a.3 for ; Tue, 26 Sep 2023 11:03:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751423; x=1696356223; 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=OwrRby3JuIEpR+SgdzK5LtEWcKJElnROXAnAJyrScoA=; b=eqBXkP409BcBlLZz3fFrS4uMew8J9OZ4EkXa6WTTcC2H8sCxc3UAFfJjewUplddroj sU/p2lKgS/4EneUlu1qUx12NabQRHRaHldJa4p9aOQ9az2hEHYPa3i/nMmZ5+Qhizi6P PFhSmQsrd0/w0KNDQ047BbeMCM1HovsznG2mm4RlcuSmVf7je9+91qvW180BBQZqWxbr Pg+GUO3KE4ZSk6xBvg/5Ub3Tq7Ppu1o1ar5pVPfbRfVzg3TLPI+ZnHANncJvue0HB/uw cJm8iXIbJIYxcc6RXh1w5Pww5e0Ma7UBLpZsjNj+ksX8CMLGXu7rQE5dmBB93zHMCXPa rIpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751423; x=1696356223; 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=OwrRby3JuIEpR+SgdzK5LtEWcKJElnROXAnAJyrScoA=; b=tLecVNtPiBA+zRoKqI+8Pm+abEOZpJvBlhcYN6TEPXF4fFQnxsU03f2AjLFvOqr6iZ lfuzqWiedbRlaqokJQBgRm5eHYWpU6gJGhvRngSahUy5c7+uESLN06YFUD+lLHVLHnKN CGRssAjapX7lUWPcuSiwIDWmzMz399D5Lwl0uUOpjyJ5W/x2qapXNXtdrZLg/6p3NwbK qyg0D1I/J1iinQm8xXWBrv+vvjw9NWyYfLSp+vkyEWY7Gt2f0/1fgNYdO+RvUoCE/vAF rekhZazZ9u9nXPmrWXpnXO4xIX6fjCjpwpn5hFU3uWZbiIo7a9BJ9HkaDnTPymnDVcWF c52w== X-Gm-Message-State: AOJu0YzPIAlJ9aRdZJ4O/vrdgJpdZ3s4qxAs1w0YHOGpbguum5ckU92N dFFGG95B+z/rrSBZmlrc/dc8nxNV+Ms+ZTkJjYP64Q== X-Google-Smtp-Source: AGHT+IFj6ikmk5dC+Oqkr7M9gXs4XiIq6UIM/mXgwpr2f/nYv65aT34BqgU13jj4cpkx2rg3+Jfqzw== X-Received: by 2002:a0c:f1cd:0:b0:647:406b:4b06 with SMTP id u13-20020a0cf1cd000000b00647406b4b06mr9147405qvl.57.1695751422707; Tue, 26 Sep 2023 11:03:42 -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 b19-20020a0ccd13000000b00646e0411e8csm2210298qvm.30.2023.09.26.11.03.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:42 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Cc: Sweet Tea Dorminy Subject: [PATCH 26/35] btrfs: explicitly track file extent length for replace and drop Date: Tue, 26 Sep 2023 14:01:52 -0400 Message-ID: <37a0e86c3fd7e96ccee4d72e30f2a9dbaff653c4.1695750478.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-btrfs@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 2758fbae7e39..5b0cccdab92a 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -339,6 +339,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 8dcc5ae9c9e1..70a801b90d13 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2262,14 +2262,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 89cb09a40f58..6a835967684d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2899,6 +2899,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(); @@ -2918,7 +2919,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; @@ -2929,7 +2930,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 f6f45a0f1b1e..d659547c9900 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4630,6 +4630,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); @@ -4672,7 +4673,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; @@ -4684,7 +4685,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 Sep 26 18:01:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13399500 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 85487E7D0C4 for ; Tue, 26 Sep 2023 18:03:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235537AbjIZSD4 (ORCPT ); Tue, 26 Sep 2023 14:03:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57878 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235507AbjIZSDw (ORCPT ); Tue, 26 Sep 2023 14:03:52 -0400 Received: from mail-qk1-x729.google.com (mail-qk1-x729.google.com [IPv6:2607:f8b0:4864:20::729]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 03E06199 for ; Tue, 26 Sep 2023 11:03:45 -0700 (PDT) Received: by mail-qk1-x729.google.com with SMTP id af79cd13be357-77411614b57so563399585a.0 for ; Tue, 26 Sep 2023 11:03:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751424; x=1696356224; 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=iU+yqzE93SLheknXkqHCW6CWGb25h7xURuXQP4ILGfc=; b=FitFNo7z0c+sdDn5Hu4ZCk76uiOYriw0lfd9CliCHSIM65Xp83asNgKnVY/2FO5Str yspbLHvVQ6TBYneV/9R7hpwp6EjMMPgGWf29rGlGcCQAqe2hWLy1GfDMIcvhyFlD3oYa E66RDPPRW4Vcq15rjRvh3G3H2BxFP8LA2idbrj3/XnMqjHQhVgfGeuFYOWkaMFt6OBqV oqaGALyADmfd+2VfKKI/GwBZQ1kebKMQOkKyU3tetGC4l31SfoOO0Cdy5L1YqzPIHTj+ peKI30zxKBr9yLYvOchIwCzkxBah2wA8D7Qj52AH2TjBYQgXSZ/bwSRTmV8q4qmMzm2R Ly8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751424; x=1696356224; 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=iU+yqzE93SLheknXkqHCW6CWGb25h7xURuXQP4ILGfc=; b=X/6BzTjgMC/JOWUhdM6N8FhpYzatcuJR1l196GhUtMpB2jD2EEihoOTPOzAq9iUDym x0MUpFnW+ZFO7OZPdVdJAanDkjS/qCi4H29fyFdy2v3Y22LNAphnlvcgOnwHZt9bgnM1 gWD3VIHgCq8nZ27K4+0AJGy3rG0auhYkEIQnrpskaB9O6uGpGijljXV+RB9x3y784R3S F1fazkyZda6HXnF9UJJZ4PDkDyKHKMyPh1qu3iZHXSWUBhO9qmwwT5qZg+8gEu3BXeqf 4vmx7ZuttUh4v+Scsm4yNU+2eGwpZ9+Tsle2OW1MHALjG1RljVO1N3mHdigRjHWc/hHB 5VrA== X-Gm-Message-State: AOJu0YwwK2mBhJ5S5G1/mq4l/oJOFlM6HTWLNrTYMAuAojD9LopX6RHN Dp0dFqoP7ONdUioQbf4ezK1bvpzFSQ3tylTaaow6RQ== X-Google-Smtp-Source: AGHT+IGI5tYeGzJTzE1gjCvkgwROGvRINBt7eG7oMlPlbIY45mUT3z5P+P1AsXhjzCy9duz8r7Bq7g== X-Received: by 2002:a05:620a:4488:b0:770:ff48:e23c with SMTP id x8-20020a05620a448800b00770ff48e23cmr13366758qkp.57.1695751423938; Tue, 26 Sep 2023 11:03: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 c24-20020ae9e218000000b007682af2c8aasm4899509qkc.126.2023.09.26.11.03.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:43 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 27/35] btrfs: pass through fscrypt_extent_info to the file extent helpers Date: Tue, 26 Sep 2023 14:01:53 -0400 Message-ID: <6e5e0cd828e4756620cddd30727ceb557e6e3532.1695750478.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-btrfs@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 6a835967684d..fdb7c9e1c210 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2883,7 +2883,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) @@ -3015,8 +3017,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 */ /* @@ -3030,8 +3031,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 d659547c9900..40dd5c652f0e 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -4631,7 +4631,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 Sep 26 18:01:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13399501 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 7C790E7D27E for ; Tue, 26 Sep 2023 18:03:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235508AbjIZSD5 (ORCPT ); Tue, 26 Sep 2023 14:03:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57840 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235517AbjIZSDx (ORCPT ); Tue, 26 Sep 2023 14:03:53 -0400 Received: from mail-vs1-xe29.google.com (mail-vs1-xe29.google.com [IPv6:2607:f8b0:4864:20::e29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A8431A5 for ; Tue, 26 Sep 2023 11:03:46 -0700 (PDT) Received: by mail-vs1-xe29.google.com with SMTP id ada2fe7eead31-4526a936dcaso3893040137.2 for ; Tue, 26 Sep 2023 11:03:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751425; x=1696356225; 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=vFj/KXZDVq4ZgILGaKQJTaXcPhA9Md3ogicPK2eeNiE=; b=h7SPIUK/hoH12qIw3XXXSlOqWZpuV3PHUxsgXAdMpz+77nxuGgFkY8KN3cVKJNKb1N LePDIi9b4C1kRkT4p26ZAOjJ6mlt3p+m0ZkJqsh0NMdTOHKqChSpDKHN+e7qWLNpACMd CogLLLNDJHSBGDhvsdlFevp3xheg9iDeox1vzjRId0esb7dPoJH4L/5uTJsraPIYfEeS nlxsXZA3OiQtce7essgfTUHaCjBnDkhi7TCDc/+ajIV++Hz1lJDFgcp20DnKu661QOg6 6HckKnY/CtAHQN65zzUs4DM40mKyxHsgJyvLotXANR9hkk4x2Hh0rOJarzZ7Qgt5/UhV YO8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751425; x=1696356225; 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=vFj/KXZDVq4ZgILGaKQJTaXcPhA9Md3ogicPK2eeNiE=; b=OSbtUrUjmgfQWgskaEGnhc5pF5Wrsij9DWuhFMGuT9vJKElb6A9tmR8X+jUN+ef2/1 jguMngwgjQ2Vm07Oo2chZYtczoS3uWZRs9fXRumCLCjSoaMUCk46Ffme8rIWiWja+dWe 6m5LgUQ7Xyh9rvYPZPhw6VOgY2nu3/ucbsZov/BLDz/qLfYNEHB8N9mi+/bGcmNeaBvA Nv/oPinC2TBl6E6Ix8hFiGw6fu82N+8FA4u4PXaF+Iqm2qXwYVRDzV8h8FraYXdq3QjU j7wBWOv++bA7ZA0X2wHMg4RJ/s3B14MKpOlquG363ISBs3zXBonT4PuN9Q2hv/VCXLCf kNtQ== X-Gm-Message-State: AOJu0YxXp8OPt96m+5H/7ZqWUVgBum+OSVEPO7eAU2uSaB38Afxawdpe aSyD7u6q7GUcYIghEwcARZb4pF3isPF02Tww79EaJA== X-Google-Smtp-Source: AGHT+IFGyPT8yrsuFzbajp6fqV2z/XBGH+EMZKsoYCnVhGAqX2SReSuEb7gPZwSZY96mZVE54W/aWQ== X-Received: by 2002:a05:6102:3bd5:b0:44d:4f8f:d8e5 with SMTP id a21-20020a0561023bd500b0044d4f8fd8e5mr7915250vsv.20.1695751425158; Tue, 26 Sep 2023 11:03: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 j3-20020a0ceb03000000b006590d020260sm5212490qvp.98.2023.09.26.11.03.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:44 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 28/35] btrfs: pass the fscrypt_info through the replace extent infrastructure Date: Tue, 26 Sep 2023 14:01:54 -0400 Message-ID: <75b7606b13b59f6ded03e547b11c230593d7403e.1695750478.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-btrfs@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 5b0cccdab92a..b4437c1a9f22 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -341,6 +341,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 fdb7c9e1c210..ee1ac2718ce3 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 Sep 26 18:01:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13399502 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 D9044E7E65D for ; Tue, 26 Sep 2023 18:03:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235512AbjIZSD7 (ORCPT ); Tue, 26 Sep 2023 14:03:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57810 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235513AbjIZSDz (ORCPT ); Tue, 26 Sep 2023 14:03:55 -0400 Received: from mail-qk1-x72e.google.com (mail-qk1-x72e.google.com [IPv6:2607:f8b0:4864:20::72e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7845310A for ; Tue, 26 Sep 2023 11:03:47 -0700 (PDT) Received: by mail-qk1-x72e.google.com with SMTP id af79cd13be357-77063481352so505723985a.1 for ; Tue, 26 Sep 2023 11:03:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751426; x=1696356226; 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=bqALhv+rQtbM8yoJCJKQcN6vl5pfWsVzXsIxDvCiSdk=; b=r3St7zAp9xIDt76AiFO+l0hms3YtLM2lQLCfm1tiF32zqx9+YmsT8+jhgusDMS/7Lj YaHoHxWWeH+xiYIG6Mg3EJJ9q/iaq3p/xy1NJ4C00TYfsgeaFJiFGKgpyNCTxxp0nHbU Xot2yBY7yN1Ws3wHZ2UgD2Sr/tvUSrAvmWONNh059GVhHNGbfCQNnGHpQ4xWFXwCX5bd ZpC9jATbn1PrckloBp+RvLSDzh2WGhnv6g5s3wttza+W1+XwtWDyEbrv5JUjBoPAhPfM 8lGfKXhEamhbhjaOj7pmGSJmPv3JiNyoL8JMFgwwYiqtVLwL5rn+7FVU1WQFKWL/ZC1w IRLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751426; x=1696356226; 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=bqALhv+rQtbM8yoJCJKQcN6vl5pfWsVzXsIxDvCiSdk=; b=Fx6gzplc9ubjCy+T1ZPNFBsc1CqK0S7UqEQGlBG//wzWNrrWGqHZO0rQNIlkHwlzbV 914azfHAX8MMym/UxsFTiikCLc7kjLM2IOIY6K4isOLDzSCaKMH2BM0JB3IIjVLZJspi 8qBQdARLst9ZTo3N+5HF413/iyYPvOJ4LgE6zzqE42SSc3JWWUN/gvK36kBB8UPTf7B+ wAmz+hDwiYUF6VJnbH5on3HjbiydywGWMOFDqWkBb3Q2iC5sDUOvJctYBJGCFWmdOiS7 rzVOu1jJVA58ccD+jvARj53/tR4cAHNbBykGxuWMFiRGmVRXYMVTdqeFZUPxrONw435N Lsgg== X-Gm-Message-State: AOJu0YwRwCx7qfZq0id4gAFCN6H9vTgPqPiNZPB1ua5PP4g1FVySQful oKDAB7nMykLZrbsLPhPINHlue7oXSZo4ddk1gUYi4A== X-Google-Smtp-Source: AGHT+IHOsnCmLSXsQAIrasctTyBr1q92rLgOAiziVKfb+pAXMfiKg3tNYc/+H+O9voytfYCNQyv0Hg== X-Received: by 2002:a05:620a:269b:b0:773:cd76:fa37 with SMTP id c27-20020a05620a269b00b00773cd76fa37mr3533760qkp.23.1695751426344; Tue, 26 Sep 2023 11:03:46 -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 u25-20020ae9c019000000b0076f18be9a64sm2291063qkk.81.2023.09.26.11.03.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:45 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 29/35] btrfs: implement the fscrypt extent encryption hooks Date: Tue, 26 Sep 2023 14:01:55 -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-btrfs@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 | 48 ++++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/fscrypt.h | 31 ++++++++++++++++++++++++++++ fs/btrfs/inode.c | 22 +++++++++++++++++++- fs/btrfs/tree-log.c | 10 +++++++++ 8 files changed, 142 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c index dde70f358d6f..ec438961eedb 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; @@ -526,9 +527,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; @@ -623,7 +627,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); @@ -633,6 +637,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 70a801b90d13..edd37aa91a02 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. @@ -2276,6 +2277,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 4fe0a8804ac5..7f53bfa621e1 100644 --- a/fs/btrfs/fscrypt.c +++ b/fs/btrfs/fscrypt.c @@ -214,6 +214,54 @@ 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 = { .get_context = btrfs_fscrypt_get_context, .set_context = btrfs_fscrypt_set_context, 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 ee1ac2718ce3..9414991d6b6b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2904,6 +2904,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; @@ -2942,6 +2945,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); @@ -6866,6 +6875,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); @@ -6879,6 +6889,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; @@ -6983,7 +6996,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) { @@ -7028,6 +7041,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 40dd5c652f0e..5200da6f5be3 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 @@ -4633,6 +4634,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); @@ -4693,6 +4697,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 Sep 26 18:01:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13399503 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 50A0CE7E654 for ; Tue, 26 Sep 2023 18:03:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235525AbjIZSEA (ORCPT ); Tue, 26 Sep 2023 14:04:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57944 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235528AbjIZSDz (ORCPT ); Tue, 26 Sep 2023 14:03:55 -0400 Received: from mail-vk1-xa2f.google.com (mail-vk1-xa2f.google.com [IPv6:2607:f8b0:4864:20::a2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8AA9B194 for ; Tue, 26 Sep 2023 11:03:48 -0700 (PDT) Received: by mail-vk1-xa2f.google.com with SMTP id 71dfb90a1353d-495c9eb8911so3447048e0c.2 for ; Tue, 26 Sep 2023 11:03:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751427; x=1696356227; 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=ooLPADEkYYZeyiiszR+3TpFJaY39zdcW3+I7UXRUGU0=; b=OtKDdWVY+4xIQ8qZBxEVJjQnCmOBJ/9zay1WPUWnMsbgbg3/BkEcZwf4yFXkk7u5r6 gGeaznGmwudFlC1S7Rl7EInhri17D4KBHTOMJbD4+gBbwmYdgIjFdkfs7r7P69V7s66K vc1untpWVTSrRVrc9Eba6ig3krzaqPYeDPUiqvFcOUtljjA4oMBsIgONNGuU2ax+I2Mx hcpmd42wTqw59fMH/viNnMH5fymywYMteVU4TbYpuj6LU5tBa0epudGv2WZVVCnjcB8P Twp502RyL2PnY0tBBm0w6yp56dysmzBTK2L+ShaiYzBIr4Mv2Oc8pVjSUW56F6PBfu7P oYSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751427; x=1696356227; 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=ooLPADEkYYZeyiiszR+3TpFJaY39zdcW3+I7UXRUGU0=; b=Kfyw2YjfHkH4RRsHZz/HDAJOG+DHy9hH8pTsUE3+luXZq8PM8gsYBzUsCik9oa5YUB EXeyh+44wFvK68fvGlC96LQ+38qI8NzmtA9gyFeQ7bOm5q6f7ObZVMoB8r7LbEPWLxA/ fFBT8xVHWe0dgbSw+R8JyJg+A0C0Rz7b3oF3OpWO4NMnz5L+QGbsUF9V1ToJ6h5kbc4Y IqZFlisyiflzqweSrF57pBBjjGQv/Pbew6IJ7+JXnqNpFsLodImzhgtcBOWhbm4b0bn6 H4m1NGzCkt/2x83tckRpe8JqzJ0hEwQs4TWclEW6RokIq0yAsE7h7aLYEBkXSk5rNmdr IXxQ== X-Gm-Message-State: AOJu0YxYHAx83dZrMoza/yZWQEvmiBCUamN89lJ9B3N+21O941gAJPBj 7fd2ueTAeR6YTUwCbEwtamDOTHYVWQVVujiCEfJBlQ== X-Google-Smtp-Source: AGHT+IH+BXG3yeuqTTz9jzHfssXZbvrO/BzPzJh3nbUSTyvQu6lv9ZdLNv4vW+bnZGyWpZk9SNaC/Q== X-Received: by 2002:a1f:2354:0:b0:49a:4de8:af2b with SMTP id j81-20020a1f2354000000b0049a4de8af2bmr4776083vkj.9.1695751427477; Tue, 26 Sep 2023 11:03:47 -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 w8-20020ac843c8000000b00418122186ccsm2367002qtn.12.2023.09.26.11.03.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:47 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 30/35] btrfs: setup fscrypt_extent_info for new extents Date: Tue, 26 Sep 2023 14:01:56 -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-btrfs@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 9414991d6b6b..aa536b838ce3 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7398,7 +7398,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 Sep 26 18:01:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13399504 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 5A510E7D0C4 for ; Tue, 26 Sep 2023 18:03:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235527AbjIZSEB (ORCPT ); Tue, 26 Sep 2023 14:04:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57868 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235534AbjIZSD4 (ORCPT ); Tue, 26 Sep 2023 14:03:56 -0400 Received: from mail-qk1-x72b.google.com (mail-qk1-x72b.google.com [IPv6:2607:f8b0:4864:20::72b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7A8021AD for ; Tue, 26 Sep 2023 11:03:49 -0700 (PDT) Received: by mail-qk1-x72b.google.com with SMTP id af79cd13be357-77433e7a876so284214785a.3 for ; Tue, 26 Sep 2023 11:03:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751428; x=1696356228; 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=YYIX+c2fQ98et4rIeSj9uRudNCLedogSC1IKEMT/vkU=; b=AXaM9Zoo5iVmGF5Hztgf4mUyXLOnhgVfePVL3dQoebDotmowCHDG3/u5PQ4liqybXe ahaYc8yQEMWiSJgyaZK78jMvFdfa0Ki3Mqk5kvW2Bv6nzpnq/Q1fBVZ8hswGNTwyWcEV QUdod8Xg0BsZsCcdCSBdywpKnYrkh7HzkjVj131weYm4B2yKXJ1+q8LBwTFz80ikLs5V N4nQWAUYtb8s2kB1ontUK0Rl+HehMazDJDe7M7dRzD0owUZQbNheU28gTnwTaAAw+Dbk AsrczO+MhyQqYRh0Tavr8qjYBEbL+kp7S16mDEVZUChf5CvqUeZD5TFhsnmMk8cd9sbM 7Gfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751428; x=1696356228; 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=YYIX+c2fQ98et4rIeSj9uRudNCLedogSC1IKEMT/vkU=; b=hgxku4NNpFiTkgN9rY1vR+FrWmT9ifo0wwVI6w7lMOCZ5t/KDgWQ06U/94jQyzlVpY pKSh+lpBWPNWG5j2HBi9+0S7Kki0EoAYbHM5IXqQIDqVXcrCvNQlja63wWJ70awm+gSU kDqN12N+zP7i9I97zyR9RTBqYqP+YUD7x+muJyWtXGJ2aiUytRc7qdWcxprJTmwzQCrS g3KLL4fAwA0tVf1nrrne277Lbxymq4w0XDXA+US/6cnVN2S0CcXXBUDTrmGYXMgdxtRr tbMu+a8ISlLZEuEIExyOYTdgK8ESzzuWwZjmBV2JBNZ/485EQcoXZ8+MnWVIGC2v44f0 strA== X-Gm-Message-State: AOJu0YzCbCEbyYpURCVaYQSGWXAXyJQlfZ6CEuzb1IPuKSXhPdHf4QOZ 9w1LpL5iMi9MJ5QbHcTR2R6AO0VpxGWhQBgftMXtUA== X-Google-Smtp-Source: AGHT+IFbBQKizNLvutZheH7/xaSd402GHHQvyARQNgJDnK3y/f9dJI5eNZZ6+Z1cyini9bwV08bf+Q== X-Received: by 2002:a05:620a:4445:b0:76f:2899:3a96 with SMTP id w5-20020a05620a444500b0076f28993a96mr13057192qkp.0.1695751428513; Tue, 26 Sep 2023 11:03:48 -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 br30-20020a05620a461e00b0076f124abe4dsm4532196qkb.77.2023.09.26.11.03.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:48 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 31/35] btrfs: populate ordered_extent with the orig offset Date: Tue, 26 Sep 2023 14:01:57 -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-btrfs@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 aa536b838ce3..14420683651a 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 @@ -7088,8 +7091,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 81b0fe575011..172a6ca38987 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -149,9 +149,9 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree, 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; @@ -176,6 +176,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; @@ -254,6 +255,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. @@ -271,17 +273,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); @@ -1189,8 +1191,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 e19e62d5171a..b5b969716d13 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -90,6 +90,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. @@ -187,9 +193,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 Sep 26 18:01:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13399505 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 1ABC1E8181A for ; Tue, 26 Sep 2023 18:03:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235499AbjIZSEC (ORCPT ); Tue, 26 Sep 2023 14:04:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57840 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235516AbjIZSD6 (ORCPT ); Tue, 26 Sep 2023 14:03:58 -0400 Received: from mail-qv1-xf36.google.com (mail-qv1-xf36.google.com [IPv6:2607:f8b0:4864:20::f36]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC6491A7 for ; Tue, 26 Sep 2023 11:03:50 -0700 (PDT) Received: by mail-qv1-xf36.google.com with SMTP id 6a1803df08f44-65b0ffbf36aso24281506d6.1 for ; Tue, 26 Sep 2023 11:03:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751429; x=1696356229; 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=wN/XVw9o4Zo7vsDD0QhSsMXlcdq0/KPnE8JijB7sQ2s=; b=Qmccs+bsXIIa6BT7uMZh5w1ceJUYoURCIBHTPoETUKsSzp7tcFnectcSbz5BuWQRWQ 3bqHVzc9oTMd52Y7DZmIySTVB8B9wcoIZtrK4mu++ZWn7Dkh4GGevbNQuodeNQXZvPMA wfUB4E63w5Rww+JP5URPv8BoDuEXaVkOI1SvvSn5korcm9u/G94chHV6aoBAYXrrLPuV fI6QETyALkghkTJK3c6RES2TQJCADUIL5W3BaTjXZlAMPUZDJVqtgNzE8rpkYL65AH6R WKMmxxlwrfc0iuJEV3km91QRHs/4y9wrxtl7SutaVyo9a9oKrICP46SdnvXU2bMVFwPH yzuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751429; x=1696356229; 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=wN/XVw9o4Zo7vsDD0QhSsMXlcdq0/KPnE8JijB7sQ2s=; b=PFOr5WKUmIGaOZRnIoNI6WoVQBwBXzrNwi1io8aE/L04HFO5Wr8u+sCsoaGIOOqx9v 75FTAtgjDx82U2mSUff1Z5e0cvXvlI7GQPXe1POfn/wZ/Z8R7yLVnMYmZIgVMVpoCORc VcOnKoqpVDaiOpbastyRSEjsFsF/IJjj+BZioDu+/gJJQ7iBIXO6K5yrnJgCg0LVYksg l+nOU2tdRDlRquVDMXZpt6lyyf3DgqEKNvm/Rj5fYKk3TnYuu0wbgiGJlEe6nUe+ci8S /D2WYDu9cODjSaWXCPnDVYfhrLCJteF+5q4eUpqC220sc6hLZ6lxiGG+/iwakUrKw/zw uvjQ== X-Gm-Message-State: AOJu0YyI4XYHyHsBKsgb97QmVY/2a1a1UWjNumAsj0y3yqtvtpg479Rl 5aHECxpu4LpGbHLBSYLSiztjCuz+AIOra1qiwgpRCg== X-Google-Smtp-Source: AGHT+IFBsrjztBuowqWrYLdHz9sbNV/3ClTZLqmOtXuVYsTxfL/bnH18f6ot/UVCKk/iLcrM9pw/0w== X-Received: by 2002:a05:6214:daf:b0:656:52a3:44f5 with SMTP id h15-20020a0562140daf00b0065652a344f5mr10984302qvh.57.1695751429548; Tue, 26 Sep 2023 11:03:49 -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 d7-20020a0ce447000000b0065b0fa22667sm2062531qvm.81.2023.09.26.11.03.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:49 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 32/35] btrfs: set the bio fscrypt context when applicable Date: Tue, 26 Sep 2023 14:01:58 -0400 Message-ID: <09bfd8c789f9e6aceb1a0a86fa8b29110ad12dc4.1695750478.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-btrfs@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 121746b7ce95..49f6bbe3b75b 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 7f53bfa621e1..1c690fcd0693 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 = { .get_context = btrfs_fscrypt_get_context, .set_context = btrfs_fscrypt_set_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 14420683651a..fbcabc9a79fe 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7897,6 +7897,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); @@ -7918,6 +7920,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, @@ -7927,8 +7932,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 Sep 26 18:01:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13399506 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 2976CE7E65E for ; Tue, 26 Sep 2023 18:03:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235522AbjIZSED (ORCPT ); Tue, 26 Sep 2023 14:04:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57868 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235517AbjIZSEA (ORCPT ); Tue, 26 Sep 2023 14:04:00 -0400 Received: from mail-qv1-xf2f.google.com (mail-qv1-xf2f.google.com [IPv6:2607:f8b0:4864:20::f2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BC22D10A for ; Tue, 26 Sep 2023 11:03:51 -0700 (PDT) Received: by mail-qv1-xf2f.google.com with SMTP id 6a1803df08f44-65b07651b97so30594856d6.1 for ; Tue, 26 Sep 2023 11:03:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751430; x=1696356230; 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=0kZoUKyT26+RFVBhvO6XNArPmlBF4XrA3IREAALxZBUGpoDsBzZYMo1mv5YCxdugAt gKC3RCHBLj+ZVTmMxeg2/HS/WkWY11Oezit/PfhQumNDCtQh+GSd1/J8mzqTBhTs6IBv M6+qfVpAwuBARwkJBj8z4ffKxoBSBlF7JEVCGL5YPnmVA5IlsOqbms3GxGEKaJ8vzC3K YQVh/tnPtzDE2UTLoLA3iEVX/oVQOTQ2bBL/I8EnbV0VJ6AJpuE0lmIda+W/CHRNSArw spU/1SNvGpeXfp3gzAge5vzI9p/XxTBFn6NDjR+AoNWUJ9ZoHE4loDRV6SAnXTEZGkkW tYtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751430; x=1696356230; 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=w3a9alJmZNpd+ovEsPXGofq/LIrz0WzD156ijU4Dnq/Ufxbju9fuyFiZU4d5wyRQD6 lzLyzmQiLeIDDKNNif9BMxxaxb5qRrn8+sTyhfFN/H9GIUVelgkMOEoty+R/GyfHs5mz f04KhnQA76z+IX0FCpEozKElnJbnvEBED0FlQDb8OVbyjnw8iPmoupAqX3iOJbf8s6Nt xmCqbP8ZVZ8m/nDqzz5vigfiWwjcWw51z3ynejhsr1a1Hc0JLXp4vKvmIwdwORAovI0T Hnca+FS1hYoz4q66f42zP+32zoQUqqiV1pi2qIHGzNzEQdBxv6HuCBNDu32RlKte9IRU R+CQ== X-Gm-Message-State: AOJu0Yz1QYun69ZKGZ27OZ7EWP42oYphJPNBeh4vC6JhA8vvmZoCBqpS re2ypw5t+9ZM8FR8t4F2vDHOtwCot/M4F0K7V/at1A== X-Google-Smtp-Source: AGHT+IHh/9A5aVRflC7yv5D8ZGje9VJPvMlKVGnnlxuMjX80+rsaMTgsqP1l95FD9hZ9j3Of+oni4A== X-Received: by 2002:a05:6214:4c1b:b0:656:51ed:b9e8 with SMTP id qh27-20020a0562144c1b00b0065651edb9e8mr9821932qvb.34.1695751430642; Tue, 26 Sep 2023 11:03:50 -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 br30-20020a05620a461e00b0077411a459a8sm4494766qkb.4.2023.09.26.11.03.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:50 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 33/35] btrfs: add a bio argument to btrfs_csum_one_bio Date: Tue, 26 Sep 2023 14:01:59 -0400 Message-ID: <079f9a864fd440c7b286a154cd10e1381070b6d5.1695750478.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-btrfs@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 Sep 26 18:02:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13399507 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 8A290E7E654 for ; Tue, 26 Sep 2023 18:04:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235532AbjIZSEE (ORCPT ); Tue, 26 Sep 2023 14:04:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235524AbjIZSD7 (ORCPT ); Tue, 26 Sep 2023 14:03:59 -0400 Received: from mail-qt1-x82a.google.com (mail-qt1-x82a.google.com [IPv6:2607:f8b0:4864:20::82a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C2F3A12A for ; Tue, 26 Sep 2023 11:03:52 -0700 (PDT) Received: by mail-qt1-x82a.google.com with SMTP id d75a77b69052e-41959feaae2so2918911cf.0 for ; Tue, 26 Sep 2023 11:03:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751432; x=1696356232; 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=3WAbG2vDA8H7dKaf19YaKMFPBc6e4tXuTFZj7/UA+5f3NlcdQe8dC2NLfZvc3mEh+o JLKOfh3DD4i2ZU3DrZABCwrGz9OPhhbvGl49SD1tw2/vkO84jQQB4O+FES6+7U2isZqa m0mWP0Ex/iT8APCe6sjk4mSOUid9VRxWQ82R+kWc42L7GvN92HPhRi47xiUcNm04W2qx mVeKQhhGzYrxYLiuS7sDwzYKNjBEzWDEtekLzWnaExW/8FXFeFnyZFZfPF9QsVkPhy6S 7m1kJ9VRJhQvvstkpDOVCvHeI/mMp9W/pxsTIAhUoMCyFsJ5fVA8oEQ/Nu4+oev8ZTE1 1RUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751432; x=1696356232; 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=I3HmQvKoJi0F+QMc1wQKFjkdFYQUfd6e/rh0mKe2KCMOY3gvikADmiSnMpHZzWdCdb uJ5Ci+BDbBT79LDGy0UyxZnkATRCUDVnI9XD2YW3cRHWuHBAzpANXmPG7MKsZs5k/1+x PCmQQ8whHzvpHj8DNvWz/iU3sRIX6Q+wf5xz3VpsKZ6qZQXlf4xsiZuZLtj4TfL3JFVa LfBlcZe88Puc4w26of6SKl+CW9VUk71JfU9zb3ie8xkLPI+NefDLmm69dd/SCCe4FQ0E jxOiHx/Gv7cUSvbb5Jm46UNxaSQT2i8BVR9xfBqPxBCN6EspRTCfGHIzdEuY11v9DndX R0TQ== X-Gm-Message-State: AOJu0YxIVtlg4VAbjbp9R6KBLN/c5Rwo54LhHCK05Ksvjj4a/uP23qQ+ YKbEKq5uVErxMJlf9l3cQ+IklS8vL7OIFCwsUTLNIQ== X-Google-Smtp-Source: AGHT+IHxHPofgTlk9TRSv29aYPre8S3krhnfYT4B//B01U8HprHN27b3ssd+/qdfng7V63uUJuuUyw== X-Received: by 2002:a05:622a:5215:b0:418:11de:ce1 with SMTP id dq21-20020a05622a521500b0041811de0ce1mr7415059qtb.24.1695751431704; Tue, 26 Sep 2023 11:03:51 -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 c1-20020ac84e01000000b00403ad6ec2e8sm2417849qtw.26.2023.09.26.11.03.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:51 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 34/35] btrfs: add orig_logical to btrfs_bio Date: Tue, 26 Sep 2023 14:02:00 -0400 Message-ID: <949cdb4e3ecfaf623716a7ceb76e46a203051311.1695750478.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-btrfs@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 Sep 26 18:02:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 13399508 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 566A3E7E62B for ; Tue, 26 Sep 2023 18:04:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235530AbjIZSEG (ORCPT ); Tue, 26 Sep 2023 14:04:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58018 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235531AbjIZSEB (ORCPT ); Tue, 26 Sep 2023 14:04:01 -0400 Received: from mail-qk1-x72e.google.com (mail-qk1-x72e.google.com [IPv6:2607:f8b0:4864:20::72e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CFA9D194 for ; Tue, 26 Sep 2023 11:03:53 -0700 (PDT) Received: by mail-qk1-x72e.google.com with SMTP id af79cd13be357-7740cd2e38dso580582685a.0 for ; Tue, 26 Sep 2023 11:03:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20230601.gappssmtp.com; s=20230601; t=1695751433; x=1696356233; 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=Edbq5tgXOIRcyTqEQ3s+ivFN/ofXmWB8jAzJZRGyEco=; b=S3A6RtZWCH9RAqJBsQ94bM9Ezz6+UlK4DSWCv2DQ4H4scIo+RFRevU4hlENp8Y5L9/ mW9uF2g/5/9F5noxb0cGNPjoL0kMRLXHvFDESoV1nAzNHttt2ThWlzCqh/x8BOPEV2PM GVpiynledX8WxoYu+YLXrVJ76bZMm3YUFL6TSWE//5U2fFtzSVd70BakUaf1b2L+cDrX /G9K1GdcSM9QF+SyS8XdEx3tTtITWBC8p/AnU+tzNQKHKSIG+nYViTaS5r5crYpPda3l tTd0fGBC5skfe8GWHQWd9D/gglimrp8l1oE+VgO9v1XBOhkUZRI1eoTQKyPwJDhzafWo SnuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695751433; x=1696356233; 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=Edbq5tgXOIRcyTqEQ3s+ivFN/ofXmWB8jAzJZRGyEco=; b=MIOSphkd3x7YOfdxWeTfNlryy+Hd4gXDkJ/GBTWQRdx5VFBB4zTM/W0Zq3unYsurCP AJoBK+Du6bBxK/Qiep5BhvoUektbLGOlIZJoBB0O7czirzLVmeA0NHYgUmcT5kwdg8ge jajcMoBcDmi3YHS8yK1h1QHSDZTfvR8NrKkczOzzRJul6phAiNOsjWTAhNcBwnO2zcCx B0Pdr7gsZvmLi8+DoRvt5EWzOxpuKDPCFuMu+SgMac2AA1L89Iua0F12NM4FtT2YrrLF eOXQSa/P7DWuv0pYLTLIVQitp9OoIN651Id80L8ShvgZup2eOYHSDaeJXyVCtOvM/Q46 5NoQ== X-Gm-Message-State: AOJu0Yyu18cef/49V/CCg6JAgStSzicwCzHLfhxjoO3wyWl5p8FsXbLk mXTdZwFWZoj5gBoOwLf1xmxCc76HS2oJNAY4qCzyTQ== X-Google-Smtp-Source: AGHT+IHDrHahEEBgahtYUOMFgx+xXjeJpicmNK5aAUPE19vkE8UYrdymV6HCUUQUXhctdptuIwZAcw== X-Received: by 2002:a0c:ec89:0:b0:656:3352:831e with SMTP id u9-20020a0cec89000000b006563352831emr11007859qvo.31.1695751432745; Tue, 26 Sep 2023 11:03:52 -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 q7-20020a0cf5c7000000b00656506a1881sm5305554qvm.74.2023.09.26.11.03.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 11:03:52 -0700 (PDT) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com, ebiggers@kernel.org, linux-fscrypt@vger.kernel.org, ngompa13@gmail.com Subject: [PATCH 35/35] btrfs: implement process_bio cb for fscrypt Date: Tue, 26 Sep 2023 14:02:01 -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-btrfs@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 1c690fcd0693..b2dfc26221e7 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) @@ -303,5 +321,6 @@ 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, .key_prefix = "btrfs:" };