From 27b2ed4395fee26da2309b2bc7c358653e43d14d Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 14 Jul 2020 09:31:24 -0700 Subject: [PATCH] ANDROID: update to latest fscrypt and UFS inline crypto patches Update to match the latest fscrypt and UFS inline encryption patches: fscrypt patches queued in fscrypt/master for 5.9: https://lore.kernel.org/r/20200702015607.1215430-2-satyat@google.com https://lore.kernel.org/r/20200702015607.1215430-3-satyat@google.com https://lore.kernel.org/r/20200702015607.1215430-4-satyat@google.com https://lore.kernel.org/r/20200702015607.1215430-5-satyat@google.com UFS patches queued in scsi/5.9/scsi-queue: https://lore.kernel.org/r/20200706200414.2027450-2-satyat@google.com https://lore.kernel.org/r/20200706200414.2027450-3-satyat@google.com https://lore.kernel.org/r/20200706200414.2027450-4-satyat@google.com fscrypt patches under discussion (direct I/O support): https://lore.kernel.org/r/20200709194751.2579207-2-satyat@google.com https://lore.kernel.org/r/20200709194751.2579207-3-satyat@google.com https://lore.kernel.org/r/20200709194751.2579207-4-satyat@google.com https://lore.kernel.org/r/20200709194751.2579207-5-satyat@google.com https://lore.kernel.org/r/20200709194751.2579207-6-satyat@google.com UFS patches under discussion (program_key variant op): https://lore.kernel.org/r/20200710072013.177481-5-ebiggers@kernel.org Bug: 137270441 Change-Id: I70c827b2106287f7296f5ed00717561f2d7e160a Signed-off-by: Eric Biggers --- Documentation/admin-guide/ext4.rst | 9 +++-- Documentation/filesystems/f2fs.rst | 10 +++-- Documentation/filesystems/fscrypt.rst | 3 ++ drivers/scsi/ufs/ufshcd-crypto.c | 56 ++++++++++++++------------- drivers/scsi/ufs/ufshcd-crypto.h | 41 ++++++++++++++------ drivers/scsi/ufs/ufshcd.c | 47 +++++++++++----------- drivers/scsi/ufs/ufshcd.h | 4 +- fs/crypto/fscrypt_private.h | 11 ++---- fs/crypto/inline_crypt.c | 15 ++++--- fs/ext4/super.c | 3 ++ fs/f2fs/data.c | 16 +++++--- fs/f2fs/super.c | 3 ++ fs/proc_namespace.c | 1 - 13 files changed, 124 insertions(+), 95 deletions(-) diff --git a/Documentation/admin-guide/ext4.rst b/Documentation/admin-guide/ext4.rst index ed997e376678..2162d7909970 100644 --- a/Documentation/admin-guide/ext4.rst +++ b/Documentation/admin-guide/ext4.rst @@ -396,10 +396,11 @@ When mounting an ext4 filesystem, the following option are accepted: incompatible with data=journal. inlinecrypt - Encrypt/decrypt the contents of encrypted files using the blk-crypto - framework rather than filesystem-layer encryption. This allows the use - of inline encryption hardware. The on-disk format is unaffected. For - more details, see Documentation/block/inline-encryption.rst. + When possible, encrypt/decrypt the contents of encrypted files using the + blk-crypto framework rather than filesystem-layer encryption. This + allows the use of inline encryption hardware. The on-disk format is + unaffected. For more details, see + Documentation/block/inline-encryption.rst. Data Mode ========= diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst index 4dc36143ff82..8b4fac44f4e1 100644 --- a/Documentation/filesystems/f2fs.rst +++ b/Documentation/filesystems/f2fs.rst @@ -259,11 +259,13 @@ compress_extension=%s Support adding specified extension, so that f2fs can enab these file by default rather than to enable it via ioctl. For other files, we can still enable compression via ioctl. inlinecrypt - Encrypt/decrypt the contents of encrypted files using the - blk-crypto framework rather than filesystem-layer encryption. - This allows the use of inline encryption hardware. The on-disk - format is unaffected. For more details, see + When possible, encrypt/decrypt the contents of encrypted + files using the blk-crypto framework rather than + filesystem-layer encryption. This allows the use of + inline encryption hardware. The on-disk format is + unaffected. For more details, see Documentation/block/inline-encryption.rst. +====================== ============================================================ Debugfs Entries =============== diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index f517af8ec11c..f5d8b0303ddf 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -1255,6 +1255,7 @@ f2fs encryption using `kvm-xfstests `_:: kvm-xfstests -c ext4,f2fs -g encrypt + kvm-xfstests -c ext4,f2fs -g encrypt -m inlinecrypt UBIFS encryption can also be tested this way, but it should be done in a separate command, and it takes some time for kvm-xfstests to set up @@ -1276,6 +1277,7 @@ This tests the encrypted I/O paths more thoroughly. To do this with kvm-xfstests, use the "encrypt" filesystem configuration:: kvm-xfstests -c ext4/encrypt,f2fs/encrypt -g auto + kvm-xfstests -c ext4/encrypt,f2fs/encrypt -g auto -m inlinecrypt Because this runs many more tests than "-g encrypt" does, it takes much longer to run; so also consider using `gce-xfstests @@ -1283,3 +1285,4 @@ much longer to run; so also consider using `gce-xfstests instead of kvm-xfstests:: gce-xfstests -c ext4/encrypt,f2fs/encrypt -g auto + gce-xfstests -c ext4/encrypt,f2fs/encrypt -g auto -m inlinecrypt diff --git a/drivers/scsi/ufs/ufshcd-crypto.c b/drivers/scsi/ufs/ufshcd-crypto.c index 9bb8251dd475..714075e327a6 100644 --- a/drivers/scsi/ufs/ufshcd-crypto.c +++ b/drivers/scsi/ufs/ufshcd-crypto.c @@ -18,16 +18,15 @@ static const struct ufs_crypto_alg_entry { }; static int ufshcd_program_key(struct ufs_hba *hba, - const union ufs_crypto_cfg_entry *cfg, - int slot) + const union ufs_crypto_cfg_entry *cfg, int slot) { int i; u32 slot_offset = hba->crypto_cfg_register + slot * sizeof(*cfg); - int err; + int err = 0; ufshcd_hold(hba, false); - if (hba->vops->program_key) { + if (hba->vops && hba->vops->program_key) { err = hba->vops->program_key(hba, cfg, slot); goto out; } @@ -44,7 +43,6 @@ static int ufshcd_program_key(struct ufs_hba *hba, /* Dword 16 must be written last */ ufshcd_writel(hba, le32_to_cpu(cfg->reg_val[16]), slot_offset + 16 * sizeof(cfg->reg_val[0])); - err = 0; out: ufshcd_release(hba); return err; @@ -93,22 +91,18 @@ static int ufshcd_crypto_keyslot_program(struct blk_keyslot_manager *ksm, err = ufshcd_program_key(hba, &cfg, slot); memzero_explicit(&cfg, sizeof(cfg)); - return err; } - -static void ufshcd_clear_keyslot(struct ufs_hba *hba, int slot) +static int ufshcd_clear_keyslot(struct ufs_hba *hba, int slot) { - union ufs_crypto_cfg_entry cfg = { 0 }; - int err; - /* * Clear the crypto cfg on the device. Clearing CFGE * might not be sufficient, so just clear the entire cfg. */ - err = ufshcd_program_key(hba, &cfg, slot); - WARN_ON_ONCE(err); + union ufs_crypto_cfg_entry cfg = { 0 }; + + return ufshcd_program_key(hba, &cfg, slot); } static int ufshcd_crypto_keyslot_evict(struct blk_keyslot_manager *ksm, @@ -117,9 +111,7 @@ static int ufshcd_crypto_keyslot_evict(struct blk_keyslot_manager *ksm, { struct ufs_hba *hba = container_of(ksm, struct ufs_hba, ksm); - ufshcd_clear_keyslot(hba, slot); - - return 0; + return ufshcd_clear_keyslot(hba, slot); } bool ufshcd_crypto_enable(struct ufs_hba *hba) @@ -153,18 +145,17 @@ ufshcd_find_blk_crypto_mode(union ufs_crypto_cap_entry cap) } /** - * ufshcd_hba_init_crypto - Read crypto capabilities, init crypto fields in hba + * ufshcd_hba_init_crypto_capabilities - Read crypto capabilities, init crypto + * fields in hba * @hba: Per adapter instance * * Return: 0 if crypto was initialized or is not supported, else a -errno value. */ -int ufshcd_hba_init_crypto(struct ufs_hba *hba) +int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba) { - int cap_idx = 0; + int cap_idx; int err = 0; enum blk_crypto_mode_num blk_mode_num; - int slot = 0; - int num_keyslots; /* * Don't use crypto if either the hardware doesn't advertise the @@ -188,8 +179,8 @@ int ufshcd_hba_init_crypto(struct ufs_hba *hba) } /* The actual number of configurations supported is (CFGC+1) */ - num_keyslots = hba->crypto_capabilities.config_count + 1; - err = blk_ksm_init(&hba->ksm, num_keyslots); + err = blk_ksm_init(&hba->ksm, + hba->crypto_capabilities.config_count + 1); if (err) goto out_free_caps; @@ -216,9 +207,6 @@ int ufshcd_hba_init_crypto(struct ufs_hba *hba) hba->crypto_cap_array[cap_idx].sdus_mask * 512; } - for (slot = 0; slot < num_keyslots; slot++) - ufshcd_clear_keyslot(hba, slot); - return 0; out_free_caps: @@ -229,6 +217,22 @@ out: return err; } +/** + * ufshcd_init_crypto - Initialize crypto hardware + * @hba: Per adapter instance + */ +void ufshcd_init_crypto(struct ufs_hba *hba) +{ + int slot; + + if (!(hba->caps & UFSHCD_CAP_CRYPTO)) + return; + + /* Clear all keyslots - the number of keyslots is (CFGC + 1) */ + for (slot = 0; slot < hba->crypto_capabilities.config_count + 1; slot++) + ufshcd_clear_keyslot(hba, slot); +} + void ufshcd_crypto_setup_rq_keyslot_manager(struct ufs_hba *hba, struct request_queue *q) { diff --git a/drivers/scsi/ufs/ufshcd-crypto.h b/drivers/scsi/ufs/ufshcd-crypto.h index 9578edb63e7b..d53851be5541 100644 --- a/drivers/scsi/ufs/ufshcd-crypto.h +++ b/drivers/scsi/ufs/ufshcd-crypto.h @@ -10,23 +10,35 @@ #include "ufshcd.h" #include "ufshci.h" -static inline void ufshcd_prepare_lrbp_crypto(struct ufs_hba *hba, - struct scsi_cmnd *cmd, +static inline void ufshcd_prepare_lrbp_crypto(struct request *rq, struct ufshcd_lrb *lrbp) { - struct request *rq = cmd->request; - - if (rq->crypt_keyslot) { - lrbp->crypto_key_slot = blk_ksm_get_slot_idx(rq->crypt_keyslot); - lrbp->data_unit_num = rq->crypt_ctx->bc_dun[0]; - } else { + if (!rq || !rq->crypt_keyslot) { lrbp->crypto_key_slot = -1; + return; + } + + lrbp->crypto_key_slot = blk_ksm_get_slot_idx(rq->crypt_keyslot); + lrbp->data_unit_num = rq->crypt_ctx->bc_dun[0]; +} + +static inline void +ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp, u32 *dword_0, + u32 *dword_1, u32 *dword_3) +{ + if (lrbp->crypto_key_slot >= 0) { + *dword_0 |= UTP_REQ_DESC_CRYPTO_ENABLE_CMD; + *dword_0 |= lrbp->crypto_key_slot; + *dword_1 = lower_32_bits(lrbp->data_unit_num); + *dword_3 = upper_32_bits(lrbp->data_unit_num); } } bool ufshcd_crypto_enable(struct ufs_hba *hba); -int ufshcd_hba_init_crypto(struct ufs_hba *hba); +int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba); + +void ufshcd_init_crypto(struct ufs_hba *hba); void ufshcd_crypto_setup_rq_keyslot_manager(struct ufs_hba *hba, struct request_queue *q); @@ -35,20 +47,25 @@ void ufshcd_crypto_destroy_keyslot_manager(struct ufs_hba *hba); #else /* CONFIG_SCSI_UFS_CRYPTO */ -static inline void ufshcd_prepare_lrbp_crypto(struct ufs_hba *hba, - struct scsi_cmnd *cmd, +static inline void ufshcd_prepare_lrbp_crypto(struct request *rq, struct ufshcd_lrb *lrbp) { } +static inline void +ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp, u32 *dword_0, + u32 *dword_1, u32 *dword_3) { } + static inline bool ufshcd_crypto_enable(struct ufs_hba *hba) { return false; } -static inline int ufshcd_hba_init_crypto(struct ufs_hba *hba) +static inline int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba) { return 0; } +static inline void ufshcd_init_crypto(struct ufs_hba *hba) { } + static inline void ufshcd_crypto_setup_rq_keyslot_manager(struct ufs_hba *hba, struct request_queue *q) { } diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 96be7f6e9134..4b27ba0ae123 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2002,15 +2002,26 @@ int ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) /** * ufshcd_hba_capabilities - Read controller capabilities * @hba: per adapter instance + * + * Return: 0 on success, negative on error. */ -static inline void ufshcd_hba_capabilities(struct ufs_hba *hba) +static inline int ufshcd_hba_capabilities(struct ufs_hba *hba) { + int err; + hba->capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES); /* nutrs and nutmrs are 0 based values */ hba->nutrs = (hba->capabilities & MASK_TRANSFER_REQUESTS_SLOTS) + 1; hba->nutmrs = ((hba->capabilities & MASK_TASK_MANAGEMENT_REQUEST_SLOTS) >> 16) + 1; + + /* Read crypto capabilities */ + err = ufshcd_hba_init_crypto_capabilities(hba); + if (err) + dev_err(hba->dev, "crypto setup failed\n"); + + return err; } /** @@ -2263,16 +2274,10 @@ static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, if (lrbp->intr_cmd) dword_0 |= UTP_REQ_DESC_INT_CMD; - /* Transfer request descriptor header fields */ -#ifdef CONFIG_SCSI_UFS_CRYPTO - if (lrbp->crypto_key_slot >= 0) { - dword_0 |= UTP_REQ_DESC_CRYPTO_ENABLE_CMD; - dword_0 |= lrbp->crypto_key_slot; - dword_1 = lower_32_bits(lrbp->data_unit_num); - dword_3 = upper_32_bits(lrbp->data_unit_num); - } -#endif /* CONFIG_SCSI_UFS_CRYPTO */ + /* Prepare crypto related dwords */ + ufshcd_prepare_req_desc_hdr_crypto(lrbp, &dword_0, &dword_1, &dword_3); + /* Transfer request descriptor header fields */ req_desc->header.dword_0 = cpu_to_le32(dword_0); req_desc->header.dword_1 = cpu_to_le32(dword_1); /* @@ -2539,7 +2544,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); lrbp->intr_cmd = !ufshcd_is_intr_aggr_allowed(hba) ? true : false; - ufshcd_prepare_lrbp_crypto(hba, cmd, lrbp); + ufshcd_prepare_lrbp_crypto(cmd->request, lrbp); lrbp->req_abort_skip = false; @@ -2574,9 +2579,7 @@ static int ufshcd_compose_dev_cmd(struct ufs_hba *hba, lrbp->task_tag = tag; lrbp->lun = 0; /* device management cmd is not specific to any LUN */ lrbp->intr_cmd = true; /* No interrupt aggregation */ -#ifdef CONFIG_SCSI_UFS_CRYPTO - lrbp->crypto_key_slot = -1; /* No crypto operations */ -#endif + ufshcd_prepare_lrbp_crypto(NULL, lrbp); hba->dev_cmd.type = cmd_type; return ufshcd_comp_devman_upiu(hba, lrbp); @@ -4827,6 +4830,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) case OCS_MISMATCH_RESP_UPIU_SIZE: case OCS_PEER_COMM_FAILURE: case OCS_FATAL_ERROR: + case OCS_DEVICE_FATAL_ERROR: case OCS_INVALID_CRYPTO_CONFIG: case OCS_GENERAL_CRYPTO_ERROR: default: @@ -6149,9 +6153,7 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, lrbp->task_tag = tag; lrbp->lun = 0; lrbp->intr_cmd = true; -#ifdef CONFIG_SCSI_UFS_CRYPTO - lrbp->crypto_key_slot = -1; /* No crypto operations */ -#endif + ufshcd_prepare_lrbp_crypto(NULL, lrbp); hba->dev_cmd.type = cmd_type; switch (hba->ufs_version) { @@ -8801,7 +8803,9 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) goto out_error; /* Read capabilities registers */ - ufshcd_hba_capabilities(hba); + err = ufshcd_hba_capabilities(hba); + if (err) + goto out_disable; /* Get UFS version supported by the controller */ hba->ufs_version = ufshcd_get_ufs_version(hba); @@ -8911,12 +8915,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) /* Reset the attached device */ ufshcd_vops_device_reset(hba); - /* Init crypto */ - err = ufshcd_hba_init_crypto(hba); - if (err) { - dev_err(hba->dev, "crypto setup failed\n"); - goto free_tmf_queue; - } + ufshcd_init_crypto(hba); /* Host controller enable */ err = ufshcd_hba_enable(hba); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index b448c9a2ff33..b811cc0fc57e 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -293,8 +293,6 @@ struct ufs_pwr_mode_info { struct ufs_pa_layer_attr info; }; -union ufs_crypto_cfg_entry; - /** * struct ufs_hba_variant_ops - variant specific callbacks * @name: variant name @@ -322,7 +320,7 @@ union ufs_crypto_cfg_entry; * @dbg_register_dump: used to dump controller debug information * @phy_initialization: used to initialize phys * @device_reset: called to issue a reset pulse on the UFS device - * @program_key: program an inline encryption key into a keyslot + * @program_key: program or evict an inline encryption key */ struct ufs_hba_variant_ops { const char *name; diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index 997cbaf9e01f..6c6431d1ffe3 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -192,12 +192,9 @@ struct fscrypt_prepared_key { struct fscrypt_info { /* The key in a form prepared for actual encryption/decryption */ - struct fscrypt_prepared_key ci_enc_key; + struct fscrypt_prepared_key ci_enc_key; - /* - * True if the ci_enc_key should be freed when this fscrypt_info is - * freed - */ + /* True if ci_enc_key should be freed when this fscrypt_info is freed */ bool ci_owns_key; #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT @@ -380,8 +377,8 @@ static inline int fscrypt_select_encryption_impl(struct fscrypt_info *ci, return 0; } -static inline bool fscrypt_using_inline_encryption( - const struct fscrypt_info *ci) +static inline bool +fscrypt_using_inline_encryption(const struct fscrypt_info *ci) { return false; } diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index 4ad0e76fe6c0..cfb11e84b174 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -79,7 +79,7 @@ int fscrypt_select_encryption_impl(struct fscrypt_info *ci, if (!fscrypt_needs_contents_encryption(inode)) return 0; - /* The crypto mode must be valid */ + /* The crypto mode must have a blk-crypto counterpart */ if (ci->ci_mode->blk_crypto_mode == BLK_ENCRYPTION_MODE_INVALID) return 0; @@ -101,8 +101,8 @@ int fscrypt_select_encryption_impl(struct fscrypt_info *ci, return 0; /* - * blk-crypto must support the crypto configuration we'll use for the - * inode on all devices in the sb + * On all the filesystem's devices, blk-crypto must support the crypto + * configuration that the file would use. */ crypto_cfg.crypto_mode = ci->ci_mode->blk_crypto_mode; crypto_cfg.data_unit_size = sb->s_blocksize; @@ -122,6 +122,7 @@ int fscrypt_select_encryption_impl(struct fscrypt_info *ci, ci->ci_inlinecrypt = true; out_free_devs: kfree(devs); + return 0; } @@ -336,7 +337,7 @@ EXPORT_SYMBOL_GPL(fscrypt_set_bio_crypt_ctx_bh); * * 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 logically contiguous data. + * 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. @@ -441,6 +442,8 @@ EXPORT_SYMBOL_GPL(fscrypt_dio_supported); * targeting @pos, in order to avoid crossing a data unit number (DUN) * discontinuity. This is only needed for certain IV generation methods. * + * This assumes block_size == PAGE_SIZE; see fscrypt_dio_supported(). + * * Return: the actual number of pages that can be submitted */ int fscrypt_limit_dio_pages(const struct inode *inode, loff_t pos, int nr_pages) @@ -458,10 +461,6 @@ int fscrypt_limit_dio_pages(const struct inode *inode, loff_t pos, int nr_pages) FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) return nr_pages; - /* - * fscrypt_select_encryption_impl() ensures that block_size == PAGE_SIZE - * when using FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32. - */ if (WARN_ON_ONCE(i_blocksize(inode) != PAGE_SIZE)) return 1; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 1d5dfc84b287..1a6d753b2da7 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2413,6 +2413,9 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb, fscrypt_show_test_dummy_encryption(seq, sep, sb); + if (sb->s_flags & SB_INLINECRYPT) + SEQ_OPTS_PUTS("inlinecrypt"); + if (test_opt(sb, DAX_ALWAYS)) { if (IS_EXT2_SB(sb)) SEQ_OPTS_PUTS("dax"); diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index b39ceb0eda17..d9436aa708b2 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -819,9 +819,10 @@ static int add_ipu_page(struct f2fs_io_info *fio, struct bio **bio, found = true; - if (page_is_mergeable(sbi, *bio, *fio->last_block, - fio->new_blkaddr) && - f2fs_crypt_mergeable_bio(*bio, + f2fs_bug_on(sbi, !page_is_mergeable(sbi, *bio, + *fio->last_block, + fio->new_blkaddr)); + if (f2fs_crypt_mergeable_bio(*bio, fio->page->mapping->host, fio->page->index, fio) && bio_add_page(*bio, page, PAGE_SIZE, 0) == @@ -830,7 +831,7 @@ static int add_ipu_page(struct f2fs_io_info *fio, struct bio **bio, break; } - /* page can't be merged into bio; submit the bio */ + /* page can't be merged into bio; submit the bio */ del_bio_entry(be); __submit_bio(sbi, *bio, DATA); break; @@ -915,6 +916,9 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio) trace_f2fs_submit_page_bio(page, fio); f2fs_trace_ios(fio, 0); + if (bio && !page_is_mergeable(fio->sbi, bio, *fio->last_block, + fio->new_blkaddr)) + f2fs_submit_merged_ipu_write(fio->sbi, &bio, NULL); alloc_new: if (!bio) { bio = __bio_alloc(fio, BIO_MAX_PAGES); @@ -981,7 +985,7 @@ next: (!io_is_mergeable(sbi, io->bio, io, fio, io->last_block_in_bio, fio->new_blkaddr) || !f2fs_crypt_mergeable_bio(io->bio, fio->page->mapping->host, - fio->page->index, fio))) + bio_page->index, fio))) __submit_merged_bio(io); alloc_new: if (io->bio == NULL) { @@ -994,7 +998,7 @@ alloc_new: } io->bio = __bio_alloc(fio, BIO_MAX_PAGES); f2fs_set_bio_crypt_ctx(io->bio, fio->page->mapping->host, - fio->page->index, fio, GFP_NOIO); + bio_page->index, fio, GFP_NOIO); io->fio = *fio; } diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index e81f50423ddf..ef35d6e36719 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1599,6 +1599,9 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) fscrypt_show_test_dummy_encryption(seq, ',', sbi->sb); + if (sbi->sb->s_flags & SB_INLINECRYPT) + seq_puts(seq, ",inlinecrypt"); + if (F2FS_OPTION(sbi).alloc_mode == ALLOC_MODE_DEFAULT) seq_printf(seq, ",alloc_mode=%s", "default"); else if (F2FS_OPTION(sbi).alloc_mode == ALLOC_MODE_REUSE) diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c index d124928539b5..f3878785aff1 100644 --- a/fs/proc_namespace.c +++ b/fs/proc_namespace.c @@ -49,7 +49,6 @@ static int show_sb_opts(struct seq_file *m, struct super_block *sb) { SB_DIRSYNC, ",dirsync" }, { SB_MANDLOCK, ",mand" }, { SB_LAZYTIME, ",lazytime" }, - { SB_INLINECRYPT, ",inlinecrypt" }, { 0, NULL } }; const struct proc_fs_opts *fs_infop;