F2FS currently disables inline data for encrypted regular files because the
inline payload is stored in the inode block and does not go through the
regular bio-based fscrypt path.  This wastes space for small encrypted
files on Android devices using F2FS inlinecrypt.

This series adds an encrypted_inline_data on-disk feature for F2FS.
With this feature enabled, encrypted regular files may keep small contents
in the inode block.  The inline payload is encrypted before being stored in
the inode and decrypted back into page-cache plaintext on read.

The fscrypt changes are scoped to filesystem-managed data-unit crypto.
F2FS first asks fscrypt whether the inode's key/policy supports this path.
It prepares the software transform only when encrypted inline payloads are
read or written.  Raw-key inlinecrypt support is limited to per-mode
policies (DIRECT_KEY, IV_INO_LBLK_64, and IV_INO_LBLK_32).  Per-file
inlinecrypt keys are not supported for encrypted inline data, to avoid
per-file software tfm memory growth.  Hardware-wrapped keys are not
supported for encrypted inline data.

I tested this on an Android F2FS /data device with inlinecrypt.  The
workload created 10000 encrypted files under the same fscrypt policy.

  Size  encrypted inline_data  Inline sample  fs_used_delta_kb  Avg B/file
  1K    enabled                200/200        46344             4745.63
  4K    enabled                0/200          85280             8732.67
  1K    disabled               0/200          88808             9093.94
  4K    disabled               0/200          80728             8266.55

For the 1K workload, encrypted inline data saved 42464 KiB for 10000 files,
about 4348 bytes per file, or a 47.8% reduction in filesystem used space.
A raw inode check of a sampled file confirmed that the inline region did
not contain plaintext.  The 4K control workload did not retain inline data,
as expected.

This is Android-focused, but the use case is meaningful in practice.  Real
phones can have more than 200000 encrypted files smaller than 4K under
/data.  Avoiding one 4K data block for a large fraction of those files can
save several hundred MiB, and in some cases close to 1GiB.

If keeping this limited to raw-key inlinecrypt is not the right tradeoff,
I'd appreciate suggestions on how encrypted inline data could be supported
with hardware-wrapped keys.

Changes in v2:
- Split fscrypt capability checking from software transform preparation.
- Limit raw-key inlinecrypt support to per-mode policies; per-file
  inlinecrypt keys and hardware-wrapped keys are unsupported.
- Use one data-unit helper and process inline payloads by fscrypt data-unit
  size.
- Update F2FS inline-data paths and documentation.

LiaoYuanhong-vivo (3):
  fscrypt: prepare software keys for filesystem-managed data units
  f2fs: support encrypted inline data
  Documentation: f2fs: document encrypted inline data

 Documentation/ABI/testing/sysfs-fs-f2fs |   5 +-
 Documentation/filesystems/f2fs.rst      |  34 +++++
 fs/crypto/crypto.c                      |  43 ++++++
 fs/crypto/fscrypt_private.h             |   3 +-
 fs/crypto/keysetup.c                    | 167 ++++++++++++++++++++++++
 fs/f2fs/Kconfig                         |  14 ++
 fs/f2fs/data.c                          |   8 +-
 fs/f2fs/f2fs.h                          |  37 +++++-
 fs/f2fs/file.c                          |  24 +++-
 fs/f2fs/inline.c                        | 131 +++++++++++++++++--
 fs/f2fs/super.c                         |  12 ++
 fs/f2fs/sysfs.c                         |   8 ++
 include/linux/fscrypt.h                 |  24 ++++
 13 files changed, 487 insertions(+), 23 deletions(-)

-- 
2.34.1

Reply via email to