* [PATCH 00/12] fstests: introduce fscrypt support for btrfs
@ 2026-07-24 13:33 Daniel Vacek
2026-07-24 13:33 ` [PATCH 01/12] common/encrypt: separate data and inode nonces Daniel Vacek
` (12 more replies)
0 siblings, 13 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt
This is a rebase and cleanup of older patches [0] from Sweet Tea and Josef
fixed to work with the recent kernel and btrfs-progs changes.
[0] https://github.com/btrfs/fstests/tree/fscrypt (227ac42)
Daniel Vacek (1):
fscrypt-crypt-util: add support for per extent KDF
Josef Bacik (4):
fstests: properly test for v1 encryption policies in encrypt tests
fstests: split generic/580 into two tests
fstests: split generic/581 into two tests
fstests: split generic/613 into two tests
Sweet Tea Dorminy (7):
common/encrypt: separate data and inode nonces
common/encrypt: add btrfs to get_encryption_*nonce
common/encrypt: add btrfs to get_ciphertext_filename
common/encrypt: enable making a encrypted btrfs filesystem
common/verity: explicitly don't allow btrfs encryption
btrfs: add simple test of reflink of encrypted data
btrfs: test snapshotting encrypted subvol
common/encrypt | 94 ++++++++++++++++++++++++----
common/verity | 4 ++
src/fscrypt-crypt-util.c | 12 +++-
tests/btrfs/613 | 54 ++++++++++++++++
tests/btrfs/613.out | 13 ++++
tests/btrfs/614 | 73 ++++++++++++++++++++++
tests/btrfs/614.out | 111 ++++++++++++++++++++++++++++++++
tests/f2fs/002 | 2 +-
tests/generic/580 | 118 +++++++++++++++-------------------
tests/generic/580.out | 40 ------------
tests/generic/581 | 89 +-------------------------
tests/generic/581.out | 50 ---------------
tests/generic/593 | 1 +
tests/generic/613 | 24 +++----
tests/generic/613.out | 5 +-
tests/generic/798 | 77 +++++++++++++++++++++++
tests/generic/798.out | 44 +++++++++++++
tests/generic/799 | 132 +++++++++++++++++++++++++++++++++++++++
tests/generic/799.out | 51 +++++++++++++++
tests/generic/800 | 115 ++++++++++++++++++++++++++++++++++
tests/generic/800.out | 14 +++++
21 files changed, 845 insertions(+), 278 deletions(-)
create mode 100755 tests/btrfs/613
create mode 100644 tests/btrfs/613.out
create mode 100755 tests/btrfs/614
create mode 100644 tests/btrfs/614.out
create mode 100755 tests/generic/798
create mode 100644 tests/generic/798.out
create mode 100755 tests/generic/799
create mode 100644 tests/generic/799.out
create mode 100755 tests/generic/800
create mode 100644 tests/generic/800.out
--
2.53.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 01/12] common/encrypt: separate data and inode nonces
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
@ 2026-07-24 13:33 ` Daniel Vacek
2026-07-24 13:33 ` [PATCH 02/12] common/encrypt: add btrfs to get_encryption_*nonce Daniel Vacek
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt,
Sweet Tea Dorminy
From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
btrfs will have different inode and data nonces, so we need to be
specific about which nonce each use needs. For now, there is no
difference in the two functions.
Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
common/encrypt | 33 ++++++++++++++++++++++++++-------
tests/f2fs/002 | 2 +-
tests/generic/613 | 4 ++--
3 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/common/encrypt b/common/encrypt
index c9e0853d..8f664518 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -548,7 +548,7 @@ _add_fscrypt_provisioning_key()
# Retrieve the encryption nonce of the given inode as a hex string. The nonce
# was randomly generated by the filesystem and isn't exposed directly to
# userspace. But it can be read using the filesystem's debugging tools.
-_get_encryption_nonce()
+_get_encryption_file_nonce()
{
local device=$1
local inode=$2
@@ -592,15 +592,34 @@ _get_encryption_nonce()
}'
;;
*)
- _fail "_get_encryption_nonce() isn't implemented on $FSTYP"
+ _fail "_get_encryption_file_nonce() isn't implemented on $FSTYP"
;;
esac
}
-# Require support for _get_encryption_nonce()
+# Retrieve the encryption nonce used to encrypt the data of the given inode as
+# a hex string. The nonce was randomly generated by the filesystem and isn't
+# exposed directly to userspace. But it can be read using the filesystem's
+# debugging tools.
+_get_encryption_data_nonce()
+{
+ local device=$1
+ local inode=$2
+
+ case $FSTYP in
+ ext4|f2fs)
+ _get_encryption_file_nonce $device $inode
+ ;;
+ *)
+ _fail "_get_encryption_data_nonce() isn't implemented on $FSTYP"
+ ;;
+ esac
+}
+
+# Require support for _get_encryption_*nonce()
_require_get_encryption_nonce_support()
{
- echo "Checking for _get_encryption_nonce() support for $FSTYP" >> $seqres.full
+ echo "Checking for _get_encryption_*nonce() support for $FSTYP" >> $seqres.full
case $FSTYP in
ext4)
_require_command "$DEBUGFS_PROG" debugfs
@@ -614,7 +633,7 @@ _require_get_encryption_nonce_support()
# the test fail in that case, as it was an f2fs-tools bug...
;;
*)
- _notrun "_get_encryption_nonce() isn't implemented on $FSTYP"
+ _notrun "_get_encryption_*nonce() isn't implemented on $FSTYP"
;;
esac
}
@@ -827,7 +846,7 @@ _do_verify_ciphertext_for_encryption_policy()
echo "Verifying encrypted file contents" >> $seqres.full
for f in "${test_contents_files[@]}"; do
read -r src inode blocklist <<< "$f"
- nonce=$(_get_encryption_nonce $SCRATCH_DEV $inode)
+ nonce=$(_get_encryption_data_nonce $SCRATCH_DEV $inode)
_dump_ciphertext_blocks $SCRATCH_DEV $blocklist > $tmp.actual_contents
$crypt_contents_cmd $contents_encryption_mode $raw_key_hex \
--file-nonce=$nonce --inode-number=$inode \
@@ -846,7 +865,7 @@ _do_verify_ciphertext_for_encryption_policy()
echo "Verifying encrypted file names" >> $seqres.full
for f in "${test_filenames_files[@]}"; do
read -r name inode dir_inode padding <<< "$f"
- nonce=$(_get_encryption_nonce $SCRATCH_DEV $dir_inode)
+ nonce=$(_get_encryption_file_nonce $SCRATCH_DEV $dir_inode)
_get_ciphertext_filename $SCRATCH_DEV $inode $dir_inode \
> $tmp.actual_name
echo -n "$name" | \
diff --git a/tests/f2fs/002 b/tests/f2fs/002
index d2f6e413..ec83c81b 100755
--- a/tests/f2fs/002
+++ b/tests/f2fs/002
@@ -126,7 +126,7 @@ blocklist=$(_get_ciphertext_block_list $file)
_scratch_unmount
echo -e "\n# Getting file's encryption nonce"
-nonce=$(_get_encryption_nonce $SCRATCH_DEV $inode)
+nonce=$(_get_encryption_data_nonce $SCRATCH_DEV $inode)
echo -e "\n# Dumping the file's raw data"
_dump_ciphertext_blocks $SCRATCH_DEV $blocklist > $tmp.raw
diff --git a/tests/generic/613 b/tests/generic/613
index 499af18e..6a120c13 100755
--- a/tests/generic/613
+++ b/tests/generic/613
@@ -66,10 +66,10 @@ echo -e "\n# Getting encryption nonces from inodes"
echo -n > $tmp.nonces_hex
echo -n > $tmp.nonces_bin
for inode in "${inodes[@]}"; do
- nonce=$(_get_encryption_nonce $SCRATCH_DEV $inode)
+ nonce=$(_get_encryption_data_nonce $SCRATCH_DEV $inode)
if (( ${#nonce} != 32 )) || [ -n "$(echo "$nonce" | tr -d 0-9a-fA-F)" ]
then
- _fail "Expected nonce to be 16 bytes (32 hex characters), but got \"$nonce\""
+ _fail "Expected nonce for inode $inode to be 16 bytes (32 hex characters), but got \"$nonce\""
fi
echo $nonce >> $tmp.nonces_hex
echo -ne "$(echo $nonce | sed 's/[0-9a-fA-F]\{2\}/\\x\0/g')" \
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 02/12] common/encrypt: add btrfs to get_encryption_*nonce
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
2026-07-24 13:33 ` [PATCH 01/12] common/encrypt: separate data and inode nonces Daniel Vacek
@ 2026-07-24 13:33 ` Daniel Vacek
2026-07-24 13:33 ` [PATCH 03/12] common/encrypt: add btrfs to get_ciphertext_filename Daniel Vacek
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt,
Sweet Tea Dorminy
From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Add the modes of getting the encryption nonces, either inode or extent,
to the various get_encryption_nonce functions. For now, no encrypt test
makes a file with more than one extent, so we can just grab the first
extent's nonce for the data nonce; when we write a bigger file test,
we'll need to change that.
v1:
* adapt to the new on-disk format (btrfs-progs dump-tree changed).
- use simple sed substitution to get the raw nonce
Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
common/encrypt | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/common/encrypt b/common/encrypt
index 8f664518..29293ea4 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -591,6 +591,16 @@ _get_encryption_file_nonce()
found = 0;
}'
;;
+ btrfs)
+ # Retrieve the fscrypt context for an inode as a hex string.
+ # btrfs prints these like:
+ #
+ # item 21 key (258 FSCRYPT_INODE_CTX 0) itemoff 15081 itemsize 40
+ # value: 020104000000000026845b8fc4d86191a06600879b25a852818ab722beec5fc403df968bf2e03af5
+ #
+ $BTRFS_UTIL_PROG inspect-internal dump-tree $device | \
+ sed -n "/key ($inode FSCRYPT_INODE_CTX 0)/{n;s/.*value: .*\([0-9a-f]\{32\}\)$/\1/p}"
+ ;;
*)
_fail "_get_encryption_file_nonce() isn't implemented on $FSTYP"
;;
@@ -610,6 +620,16 @@ _get_encryption_data_nonce()
ext4|f2fs)
_get_encryption_file_nonce $device $inode
;;
+ btrfs)
+ # Retrieve the encryption IV of the first file extent in an inode as a hex
+ # string. btrfs prints the extent fscrypt context like:
+ #
+ # item 22 key (258 FSCRYPT_CTX 0) itemoff 15047 itemsize 34
+ # value: 010126845b8fc4d86191a06600879b25a852729c4e35b33e29d171a0c96b9eed33d9
+ #
+ $BTRFS_UTIL_PROG inspect-internal dump-tree $device | \
+ sed -n "/key ($inode FSCRYPT_CTX 0)/{n;s/.*value: .*\([0-9a-f]\{32\}\)$/\1/p}"
+ ;;
*)
_fail "_get_encryption_data_nonce() isn't implemented on $FSTYP"
;;
@@ -632,6 +652,9 @@ _require_get_encryption_nonce_support()
# Otherwise the xattr is incorrectly parsed as v1. But just let
# the test fail in that case, as it was an f2fs-tools bug...
;;
+ btrfs)
+ _require_command "$BTRFS_UTIL_PROG" btrfs
+ ;;
*)
_notrun "_get_encryption_*nonce() isn't implemented on $FSTYP"
;;
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 03/12] common/encrypt: add btrfs to get_ciphertext_filename
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
2026-07-24 13:33 ` [PATCH 01/12] common/encrypt: separate data and inode nonces Daniel Vacek
2026-07-24 13:33 ` [PATCH 02/12] common/encrypt: add btrfs to get_encryption_*nonce Daniel Vacek
@ 2026-07-24 13:33 ` Daniel Vacek
2026-07-24 13:33 ` [PATCH 04/12] common/encrypt: enable making a encrypted btrfs filesystem Daniel Vacek
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt,
Sweet Tea Dorminy
From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Add the relevant call to get an encrypted filename from btrfs.
v1:
* fix reading of the encrypted name
- use simple sed substitutions and consume escapes using printf
Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
common/encrypt | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/common/encrypt b/common/encrypt
index 29293ea4..8a0aaf1a 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -713,6 +713,20 @@ _get_ciphertext_filename()
print STDERR "Invalid base64-encoded string!\n";
}'
;;
+ btrfs)
+ # Extract the filename from the inode_ref object, similar to:
+ #
+ # item 20 key (258 INODE_REF 257) itemoff 15121 itemsize 26
+ # index 2 namelen 16 name: v\354\301\231\214\341+\335A\002\216\3405eFz
+ #
+ $BTRFS_UTIL_PROG inspect-internal dump-tree $device | \
+ sed -n "/ key ($inode INODE_REF $dir_inode) / { n
+ s/.*name: //
+ s/%/%%/g
+ s/\\\\ / /g
+ p; q }" | tr -d \\n | \
+ xargs -0 printf
+ ;;
*)
_fail "_get_ciphertext_filename() isn't implemented on $FSTYP"
;;
@@ -767,6 +781,9 @@ _require_get_ciphertext_filename_support()
_notrun "dump.f2fs (f2fs-tools) is too old; doesn't support showing unambiguous on-disk filenames"
fi
;;
+ btrfs)
+ _require_command "$BTRFS_UTIL_PROG" btrfs
+ ;;
*)
_notrun "_get_ciphertext_filename() isn't implemented on $FSTYP"
;;
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 04/12] common/encrypt: enable making a encrypted btrfs filesystem
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
` (2 preceding siblings ...)
2026-07-24 13:33 ` [PATCH 03/12] common/encrypt: add btrfs to get_ciphertext_filename Daniel Vacek
@ 2026-07-24 13:33 ` Daniel Vacek
2026-07-24 13:33 ` [PATCH 05/12] common/verity: explicitly don't allow btrfs encryption Daniel Vacek
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt,
Sweet Tea Dorminy
From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
common/encrypt | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/common/encrypt b/common/encrypt
index 8a0aaf1a..81c3d032 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -195,6 +195,9 @@ _scratch_mkfs_encrypted()
# erase the UBI volume; reformated automatically on next mount
$UBIUPDATEVOL_PROG ${SCRATCH_DEV} -t
;;
+ btrfs)
+ _scratch_mkfs
+ ;;
ceph)
_scratch_cleanup_files
;;
@@ -210,6 +213,9 @@ _scratch_mkfs_sized_encrypted()
ext4|f2fs)
MKFS_OPTIONS="$MKFS_OPTIONS -O encrypt" _scratch_mkfs_sized $*
;;
+ btrfs)
+ _scratch_mkfs_sized $*
+ ;;
*)
_notrun "Filesystem $FSTYP not supported in _scratch_mkfs_sized_encrypted"
;;
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 05/12] common/verity: explicitly don't allow btrfs encryption
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
` (3 preceding siblings ...)
2026-07-24 13:33 ` [PATCH 04/12] common/encrypt: enable making a encrypted btrfs filesystem Daniel Vacek
@ 2026-07-24 13:33 ` Daniel Vacek
2026-07-24 13:33 ` [PATCH 06/12] btrfs: add simple test of reflink of encrypted data Daniel Vacek
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt,
Sweet Tea Dorminy
From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Currently btrfs encryption doesn't support verity, but it is planned to
one day. To be explicit about the lack of support, add a custom error
message to the combination.
Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
common/verity | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/common/verity b/common/verity
index 11e839d2..a857619f 100644
--- a/common/verity
+++ b/common/verity
@@ -224,6 +224,10 @@ _scratch_mkfs_encrypted_verity()
# features with -O. Instead -O must be supplied multiple times.
_scratch_mkfs -O encrypt -O verity
;;
+ btrfs)
+ # currently verity + encryption is not supported
+ _notrun "btrfs doesn't currently support verity + encryption"
+ ;;
*)
_notrun "$FSTYP not supported in _scratch_mkfs_encrypted_verity"
;;
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 06/12] btrfs: add simple test of reflink of encrypted data
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
` (4 preceding siblings ...)
2026-07-24 13:33 ` [PATCH 05/12] common/verity: explicitly don't allow btrfs encryption Daniel Vacek
@ 2026-07-24 13:33 ` Daniel Vacek
2026-07-24 13:33 ` [PATCH 07/12] btrfs: test snapshotting encrypted subvol Daniel Vacek
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt,
Sweet Tea Dorminy
From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Make sure that we succeed at reflinking encrypted data.
Test deliberately numbered with a high number so it won't conflict with
tests between now and merge.
v1:
An array overflow bug in btrfs_check_encrypted_read_bio() was hidden
during fscrypt v6 32/43 patch development until the file size was
extended to more than 144k (16k + 64k + >64k a.k.a. BTRFS_MAX_BLOCKSIZE
- it was 33k before).
We simply needed more pages in the game to run out of the array.
Even-though the bug was fixed in v7, it may be useful to keep this
test checking, just to be sure nothing similar happens in the future.
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
tests/btrfs/613 | 54 +++++++++++++++++++++++++++++++++++++++++++++
tests/btrfs/613.out | 13 +++++++++++
2 files changed, 67 insertions(+)
create mode 100755 tests/btrfs/613
create mode 100644 tests/btrfs/613.out
diff --git a/tests/btrfs/613 b/tests/btrfs/613
new file mode 100755
index 00000000..fddb9243
--- /dev/null
+++ b/tests/btrfs/613
@@ -0,0 +1,54 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2023 Meta Platforms, Inc. All Rights Reserved.
+#
+# FS QA Test 613
+#
+# Check if reflinking one encrypted file on btrfs succeeds.
+#
+. ./common/preamble
+_begin_fstest auto encrypt
+
+# Import common functions.
+. ./common/encrypt
+. ./common/filter
+. ./common/reflink
+
+_require_test
+_require_scratch
+_require_cp_reflink
+_require_scratch_encryption -v 2
+_require_command "$KEYCTL_PROG" keyctl
+
+_scratch_mkfs_encrypted &>> $seqres.full
+_scratch_mount
+
+dir=$SCRATCH_MNT/dir
+mkdir $dir
+_set_encpolicy $dir $TEST_KEY_IDENTIFIER
+_add_enckey $SCRATCH_MNT "$TEST_RAW_KEY"
+echo "Creating and reflinking a file"
+$XFS_IO_PROG -t -f -c "pwrite 0 145k" $dir/test > /dev/null
+cp --reflink=always $dir/test $dir/test2
+
+echo "Can't reflink encrypted and unencrypted"
+cp --reflink=always $dir/test $SCRATCH_MNT/fail |& _filter_scratch
+
+echo "Diffing the file and its copy"
+diff $dir/test $dir/test2
+
+echo "Verifying the files are reflinked"
+_verify_reflink $dir/test $dir/test2
+
+echo "Diffing the files after remount"
+_scratch_cycle_mount
+_add_enckey $SCRATCH_MNT "$TEST_RAW_KEY"
+diff $dir/test $dir/test2
+
+echo "Diffing the files after key remove"
+_rm_enckey $SCRATCH_MNT $TEST_KEY_IDENTIFIER
+diff $dir/test $dir/test2 |& _filter_scratch
+
+# success, all done
+status=0
+exit
diff --git a/tests/btrfs/613.out b/tests/btrfs/613.out
new file mode 100644
index 00000000..4895d6dd
--- /dev/null
+++ b/tests/btrfs/613.out
@@ -0,0 +1,13 @@
+QA output created by 613
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+Creating and reflinking a file
+Can't reflink encrypted and unencrypted
+cp: failed to clone 'SCRATCH_MNT/fail' from 'SCRATCH_MNT/dir/test': Invalid argument
+Diffing the file and its copy
+Verifying the files are reflinked
+Diffing the files after remount
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+Diffing the files after key remove
+Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+diff: SCRATCH_MNT/dir/test: No such file or directory
+diff: SCRATCH_MNT/dir/test2: No such file or directory
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 07/12] btrfs: test snapshotting encrypted subvol
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
` (5 preceding siblings ...)
2026-07-24 13:33 ` [PATCH 06/12] btrfs: add simple test of reflink of encrypted data Daniel Vacek
@ 2026-07-24 13:33 ` Daniel Vacek
2026-07-24 13:33 ` [PATCH 08/12] fstests: properly test for v1 encryption policies in encrypt tests Daniel Vacek
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt,
Sweet Tea Dorminy
From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Make sure that snapshots of encrypted data are readable and writeable.
Test deliberately high-numbered to not conflict.
Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
tests/btrfs/614 | 73 +++++++++++++++++++++++++++++
tests/btrfs/614.out | 111 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 184 insertions(+)
create mode 100755 tests/btrfs/614
create mode 100644 tests/btrfs/614.out
diff --git a/tests/btrfs/614 b/tests/btrfs/614
new file mode 100755
index 00000000..840c3b8d
--- /dev/null
+++ b/tests/btrfs/614
@@ -0,0 +1,73 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2023 Meta Platforms, Inc. All Rights Reserved.
+#
+# FS QA Test 614
+#
+# Try taking a snapshot of an encrypted subvolume. Make sure the snapshot is
+# still readable. Rewrite part of the subvol with the same data; make sure it's
+# still readable.
+#
+. ./common/preamble
+_begin_fstest auto encrypt
+
+# Import common functions.
+. ./common/encrypt
+. ./common/filter
+
+_require_test
+_require_scratch
+_require_scratch_encryption -v 2
+_require_command "$KEYCTL_PROG" keyctl
+
+_scratch_mkfs_encrypted &>> $seqres.full
+_scratch_mount
+
+udir=$SCRATCH_MNT/reference
+dir=$SCRATCH_MNT/subvol
+dir2=$SCRATCH_MNT/subvol2
+$BTRFS_UTIL_PROG subvolume create $dir >> $seqres.full
+mkdir $udir
+
+_set_encpolicy $dir $TEST_KEY_IDENTIFIER
+_add_enckey $SCRATCH_MNT "$TEST_RAW_KEY"
+
+# get files with lots of extents by using backwards writes.
+for j in `seq 0 50`; do
+ for i in `seq 20 -1 1`; do
+ $XFS_IO_PROG -f -d -c "pwrite $(($i * 4096)) 4096" \
+ $dir/foo-$j >> $seqres.full | _filter_xfs_io
+ $XFS_IO_PROG -f -d -c "pwrite $(($i * 4096)) 4096" \
+ $udir/foo-$j >> $seqres.full | _filter_xfs_io
+ done
+done
+
+$BTRFS_UTIL_PROG subvolume snapshot $dir $dir2 | _filter_scratch
+
+_scratch_remount
+_add_enckey $SCRATCH_MNT "$TEST_RAW_KEY"
+sleep 30
+echo "Diffing $dir and $dir2"
+diff $dir $dir2
+
+echo "Rewriting $dir2 partly"
+# rewrite half of each file in the snapshot
+for j in `seq 0 50`; do
+ for i in `seq 10 -1 1`; do
+ $XFS_IO_PROG -f -d -c "pwrite $(($i * 4096)) 4096" \
+ $dir2/foo-$j >> $seqres.full | _filter_xfs_io
+ done
+done
+
+echo "Diffing $dir and $dir2"
+diff $dir $dir2
+
+echo "Dropping key and diffing"
+_rm_enckey $SCRATCH_MNT $TEST_KEY_IDENTIFIER
+diff $dir $dir2 |& _filter_scratch | _filter_nokey_filenames
+
+$BTRFS_UTIL_PROG subvolume delete $dir > /dev/null 2>&1
+
+# success, all done
+status=0
+exit
diff --git a/tests/btrfs/614.out b/tests/btrfs/614.out
new file mode 100644
index 00000000..bd95b67a
--- /dev/null
+++ b/tests/btrfs/614.out
@@ -0,0 +1,111 @@
+QA output created by 614
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+Create snapshot of 'SCRATCH_MNT/subvol' in 'SCRATCH_MNT/subvol2'
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+Diffing /mnt/scratch/subvol and /mnt/scratch/subvol2
+Rewriting /mnt/scratch/subvol2 partly
+Diffing /mnt/scratch/subvol and /mnt/scratch/subvol2
+Dropping key and diffing
+Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
+NOKEY_NAME: NOKEY_NAME/NOKEY_NAME/NOKEY_NAME: NOKEY_NAME NOKEY_NAME NOKEY_NAME NOKEY_NAME
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 08/12] fstests: properly test for v1 encryption policies in encrypt tests
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
` (6 preceding siblings ...)
2026-07-24 13:33 ` [PATCH 07/12] btrfs: test snapshotting encrypted subvol Daniel Vacek
@ 2026-07-24 13:33 ` Daniel Vacek
2026-07-24 13:33 ` [PATCH 09/12] fstests: split generic/580 into two tests Daniel Vacek
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt, Josef Bacik
From: Josef Bacik <josef@toxicpanda.com>
With btrfs adding fscrypt support we're limiting the usage to plain
v2 policies only. This means we need to update the _require's for
generic/593 that tests both v1 and v2 policies. The other sort of
tests will be split into two tests in later patches.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
common/encrypt | 2 ++
tests/generic/593 | 1 +
2 files changed, 3 insertions(+)
diff --git a/common/encrypt b/common/encrypt
index 81c3d032..4c3fd904 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -68,6 +68,8 @@ _require_scratch_encryption()
# policy required by the test.
if [ $# -ne 0 ]; then
_require_encryption_policy_support $SCRATCH_MNT "$@"
+ else
+ _require_encryption_policy_support $SCRATCH_MNT -v 1
fi
_scratch_unmount
diff --git a/tests/generic/593 b/tests/generic/593
index 05f868f9..a80c28f2 100755
--- a/tests/generic/593
+++ b/tests/generic/593
@@ -15,6 +15,7 @@ _begin_fstest auto quick encrypt
. ./common/filter
. ./common/encrypt
+_require_scratch_encryption -v 1
_require_scratch_encryption -v 2
_require_command "$KEYCTL_PROG" keyctl
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 09/12] fstests: split generic/580 into two tests
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
` (7 preceding siblings ...)
2026-07-24 13:33 ` [PATCH 08/12] fstests: properly test for v1 encryption policies in encrypt tests Daniel Vacek
@ 2026-07-24 13:33 ` Daniel Vacek
2026-07-24 13:33 ` [PATCH 10/12] fstests: split generic/581 " Daniel Vacek
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt, Josef Bacik
From: Josef Bacik <josef@toxicpanda.com>
generic/580 tests both v1 and v2 encryption policies, however btrfs only
supports v2 policies. Split this into two tests so that we can get the
v2 coverage for btrfs.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
tests/generic/580 | 118 ++++++++++++++++++------------------------
tests/generic/580.out | 40 --------------
tests/generic/798 | 77 +++++++++++++++++++++++++++
tests/generic/798.out | 44 ++++++++++++++++
4 files changed, 171 insertions(+), 108 deletions(-)
create mode 100755 tests/generic/798
create mode 100644 tests/generic/798.out
diff --git a/tests/generic/580 b/tests/generic/580
index eff3f210..848d083b 100755
--- a/tests/generic/580
+++ b/tests/generic/580
@@ -5,7 +5,7 @@
# FS QA Test generic/580
#
# Basic test of the fscrypt filesystem-level encryption keyring
-# and v2 encryption policies.
+# policy.
#
. ./common/preamble
@@ -16,80 +16,62 @@ echo
. ./common/filter
. ./common/encrypt
-_require_scratch_encryption -v 2
+_require_scratch_encryption
_scratch_mkfs_encrypted &>> $seqres.full
_scratch_mount
-test_with_policy_version()
-{
- local vers=$1
-
- if (( vers == 1 )); then
- local keyspec=$TEST_KEY_DESCRIPTOR
- local add_enckey_args="-d $keyspec"
- else
- local keyspec=$TEST_KEY_IDENTIFIER
- local add_enckey_args=""
- fi
-
- mkdir $dir
- echo "# Setting v$vers encryption policy"
- _set_encpolicy $dir $keyspec
- echo "# Getting v$vers encryption policy"
- _get_encpolicy $dir | _filter_scratch
- if (( vers == 1 )); then
- echo "# Getting v1 encryption policy using old ioctl"
- _get_encpolicy $dir -1 | _filter_scratch
- fi
- echo "# Trying to create file without key added yet"
- $XFS_IO_PROG -f $dir/file |& _filter_scratch
- echo "# Getting encryption key status"
- _enckey_status $SCRATCH_MNT $keyspec
- echo "# Adding encryption key"
- _add_enckey $SCRATCH_MNT "$TEST_RAW_KEY" $add_enckey_args
- echo "# Creating encrypted file"
- echo contents > $dir/file
- echo "# Getting encryption key status"
- _enckey_status $SCRATCH_MNT $keyspec
- echo "# Removing encryption key"
- _rm_enckey $SCRATCH_MNT $keyspec
- echo "# Getting encryption key status"
- _enckey_status $SCRATCH_MNT $keyspec
- echo "# Verifying that the encrypted directory was \"locked\""
- cat $dir/file |& _filter_scratch
- cat "$(find $dir -type f)" |& _filter_scratch | cut -d ' ' -f3-
-
- # Test removing key with a file open.
- echo "# Re-adding encryption key"
- _add_enckey $SCRATCH_MNT "$TEST_RAW_KEY" $add_enckey_args
- echo "# Creating another encrypted file"
- echo foo > $dir/file2
- echo "# Removing key while an encrypted file is open"
- exec 3< $dir/file
- _rm_enckey $SCRATCH_MNT $keyspec
- echo "# Non-open file should have been evicted"
- cat $dir/file2 |& _filter_scratch
- echo "# Open file shouldn't have been evicted"
- cat $dir/file
- echo "# Key should be in \"incompletely removed\" state"
- _enckey_status $SCRATCH_MNT $keyspec
- echo "# Closing file and removing key for real now"
- exec 3<&-
- _rm_enckey $SCRATCH_MNT $keyspec
- cat $dir/file |& _filter_scratch
-
- echo "# Cleaning up"
- rm -rf $dir
- _scratch_cycle_mount # Clear all keys
- echo
-}
-
dir=$SCRATCH_MNT/dir
+keyspec=$TEST_KEY_DESCRIPTOR
+
+mkdir $dir
+echo "# Setting v1 encryption policy"
+_set_encpolicy $dir $keyspec
+echo "# Getting v1 encryption policy"
+_get_encpolicy $dir | _filter_scratch
+echo "# Getting v1 encryption policy using old ioctl"
+_get_encpolicy $dir -1 | _filter_scratch
+echo "# Trying to create file without key added yet"
+$XFS_IO_PROG -f $dir/file |& _filter_scratch
+echo "# Getting encryption key status"
+_enckey_status $SCRATCH_MNT $keyspec
+echo "# Adding encryption key"
+_add_enckey $SCRATCH_MNT "$TEST_RAW_KEY" -d $keyspec
+echo "# Creating encrypted file"
+echo contents > $dir/file
+echo "# Getting encryption key status"
+_enckey_status $SCRATCH_MNT $keyspec
+echo "# Removing encryption key"
+_rm_enckey $SCRATCH_MNT $keyspec
+echo "# Getting encryption key status"
+_enckey_status $SCRATCH_MNT $keyspec
+echo "# Verifying that the encrypted directory was \"locked\""
+cat $dir/file |& _filter_scratch
+cat "$(find $dir -type f)" |& _filter_scratch | cut -d ' ' -f3-
-test_with_policy_version 1
+# Test removing key with a file open.
+echo "# Re-adding encryption key"
+_add_enckey $SCRATCH_MNT "$TEST_RAW_KEY" -d $keyspec
+echo "# Creating another encrypted file"
+echo foo > $dir/file2
+echo "# Removing key while an encrypted file is open"
+exec 3< $dir/file
+_rm_enckey $SCRATCH_MNT $keyspec
+echo "# Non-open file should have been evicted"
+cat $dir/file2 |& _filter_scratch
+echo "# Open file shouldn't have been evicted"
+cat $dir/file
+echo "# Key should be in \"incompletely removed\" state"
+_enckey_status $SCRATCH_MNT $keyspec
+echo "# Closing file and removing key for real now"
+exec 3<&-
+_rm_enckey $SCRATCH_MNT $keyspec
+cat $dir/file |& _filter_scratch
-test_with_policy_version 2
+echo "# Cleaning up"
+rm -rf $dir
+_scratch_cycle_mount # Clear all keys
+echo
echo "# Trying to remove absent key"
_rm_enckey $SCRATCH_MNT abcdabcdabcdabcd
diff --git a/tests/generic/580.out b/tests/generic/580.out
index 989d4514..f2f4d490 100644
--- a/tests/generic/580.out
+++ b/tests/generic/580.out
@@ -47,45 +47,5 @@ Removed encryption key with descriptor 0000111122223333
cat: SCRATCH_MNT/dir/file: No such file or directory
# Cleaning up
-# Setting v2 encryption policy
-# Getting v2 encryption policy
-Encryption policy for SCRATCH_MNT/dir:
- Policy version: 2
- Master key identifier: 69b2f6edeee720cce0577937eb8a6751
- Contents encryption mode: 1 (AES-256-XTS)
- Filenames encryption mode: 4 (AES-256-CTS)
- Flags: 0x02
-# Trying to create file without key added yet
-SCRATCH_MNT/dir/file: Required key not available
-# Getting encryption key status
-Absent
-# Adding encryption key
-Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
-# Creating encrypted file
-# Getting encryption key status
-Present (user_count=1, added_by_self)
-# Removing encryption key
-Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
-# Getting encryption key status
-Absent
-# Verifying that the encrypted directory was "locked"
-cat: SCRATCH_MNT/dir/file: No such file or directory
-Required key not available
-# Re-adding encryption key
-Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
-# Creating another encrypted file
-# Removing key while an encrypted file is open
-Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751, but files still busy
-# Non-open file should have been evicted
-cat: SCRATCH_MNT/dir/file2: Required key not available
-# Open file shouldn't have been evicted
-contents
-# Key should be in "incompletely removed" state
-Incompletely removed
-# Closing file and removing key for real now
-Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
-cat: SCRATCH_MNT/dir/file: No such file or directory
-# Cleaning up
-
# Trying to remove absent key
Error removing encryption key: Required key not available
diff --git a/tests/generic/798 b/tests/generic/798
new file mode 100755
index 00000000..e2bbaade
--- /dev/null
+++ b/tests/generic/798
@@ -0,0 +1,77 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# FS QA Test generic/798
+#
+# A v2 only version of generic/580
+
+. ./common/preamble
+_begin_fstest auto quick encrypt
+echo
+
+# Import common functions.
+. ./common/filter
+. ./common/encrypt
+
+_require_scratch_encryption -v 2
+
+_scratch_mkfs_encrypted &>> $seqres.full
+_scratch_mount
+
+keyspec=$TEST_KEY_IDENTIFIER
+dir=$SCRATCH_MNT/dir
+
+mkdir $dir
+echo "# Setting v2 encryption policy"
+_set_encpolicy $dir $keyspec
+echo "# Getting v2 encryption policy"
+_get_encpolicy $dir | _filter_scratch
+echo "# Trying to create file without key added yet"
+$XFS_IO_PROG -f $dir/file |& _filter_scratch
+echo "# Getting encryption key status"
+_enckey_status $SCRATCH_MNT $keyspec
+echo "# Adding encryption key"
+_add_enckey $SCRATCH_MNT "$TEST_RAW_KEY"
+echo "# Creating encrypted file"
+echo contents > $dir/file
+echo "# Getting encryption key status"
+_enckey_status $SCRATCH_MNT $keyspec
+echo "# Removing encryption key"
+_rm_enckey $SCRATCH_MNT $keyspec
+echo "# Getting encryption key status"
+_enckey_status $SCRATCH_MNT $keyspec
+echo "# Verifying that the encrypted directory was \"locked\""
+cat $dir/file |& _filter_scratch
+cat "$(find $dir -type f)" |& _filter_scratch | cut -d ' ' -f3-
+
+# Test removing key with a file open.
+echo "# Re-adding encryption key"
+_add_enckey $SCRATCH_MNT "$TEST_RAW_KEY"
+echo "# Creating another encrypted file"
+echo foo > $dir/file2
+echo "# Removing key while an encrypted file is open"
+exec 3< $dir/file
+_rm_enckey $SCRATCH_MNT $keyspec
+echo "# Non-open file should have been evicted"
+cat $dir/file2 |& _filter_scratch
+echo "# Open file shouldn't have been evicted"
+cat $dir/file
+echo "# Key should be in \"incompletely removed\" state"
+_enckey_status $SCRATCH_MNT $keyspec
+echo "# Closing file and removing key for real now"
+exec 3<&-
+_rm_enckey $SCRATCH_MNT $keyspec
+cat $dir/file |& _filter_scratch
+
+echo "# Cleaning up"
+rm -rf $dir
+_scratch_cycle_mount # Clear all keys
+echo
+
+echo "# Trying to remove absent key"
+_rm_enckey $SCRATCH_MNT abcdabcdabcdabcd
+
+# success, all done
+status=0
+exit
+
diff --git a/tests/generic/798.out b/tests/generic/798.out
new file mode 100644
index 00000000..b1f64e29
--- /dev/null
+++ b/tests/generic/798.out
@@ -0,0 +1,44 @@
+QA output created by 798
+
+# Setting v2 encryption policy
+# Getting v2 encryption policy
+Encryption policy for SCRATCH_MNT/dir:
+ Policy version: 2
+ Master key identifier: 69b2f6edeee720cce0577937eb8a6751
+ Contents encryption mode: 1 (AES-256-XTS)
+ Filenames encryption mode: 4 (AES-256-CTS)
+ Flags: 0x02
+# Trying to create file without key added yet
+SCRATCH_MNT/dir/file: Required key not available
+# Getting encryption key status
+Absent
+# Adding encryption key
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Creating encrypted file
+# Getting encryption key status
+Present (user_count=1, added_by_self)
+# Removing encryption key
+Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Getting encryption key status
+Absent
+# Verifying that the encrypted directory was "locked"
+cat: SCRATCH_MNT/dir/file: No such file or directory
+Required key not available
+# Re-adding encryption key
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Creating another encrypted file
+# Removing key while an encrypted file is open
+Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751, but files still busy
+# Non-open file should have been evicted
+cat: SCRATCH_MNT/dir/file2: Required key not available
+# Open file shouldn't have been evicted
+contents
+# Key should be in "incompletely removed" state
+Incompletely removed
+# Closing file and removing key for real now
+Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+cat: SCRATCH_MNT/dir/file: No such file or directory
+# Cleaning up
+
+# Trying to remove absent key
+Error removing encryption key: Required key not available
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 10/12] fstests: split generic/581 into two tests
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
` (8 preceding siblings ...)
2026-07-24 13:33 ` [PATCH 09/12] fstests: split generic/580 into two tests Daniel Vacek
@ 2026-07-24 13:33 ` Daniel Vacek
2026-07-24 13:33 ` [PATCH 11/12] fstests: split generic/613 " Daniel Vacek
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt, Josef Bacik
From: Josef Bacik <josef@toxicpanda.com>
generic/581 is mostly a v2 policy test, but it does do some quick checks
of v1 policies as a normal user. Split the v1 and v2 related parts
into two different tests so that the v2 part can get properly tested for
btrfs file systems, which only support v2 policies.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
tests/generic/581 | 89 +---------------------------
tests/generic/581.out | 50 ----------------
tests/generic/799 | 132 ++++++++++++++++++++++++++++++++++++++++++
tests/generic/799.out | 51 ++++++++++++++++
4 files changed, 185 insertions(+), 137 deletions(-)
create mode 100755 tests/generic/799
create mode 100644 tests/generic/799.out
diff --git a/tests/generic/581 b/tests/generic/581
index 2773c910..d39cee24 100755
--- a/tests/generic/581
+++ b/tests/generic/581
@@ -4,8 +4,7 @@
#
# FS QA Test No. generic/581
#
-# Test non-root use of the fscrypt filesystem-level encryption keyring
-# and v2 encryption policies.
+# Test non-root use of the fscrypt filesystem-level encryption keyring policy.
#
. ./common/preamble
@@ -29,7 +28,7 @@ _cleanup()
. ./common/encrypt
_require_user
-_require_scratch_encryption -v 2
+_require_scratch_encryption
_scratch_mkfs_encrypted &>> $seqres.full
_scratch_mount
@@ -56,90 +55,6 @@ echo "# Adding v1 policy key as regular user (should fail with EACCES)"
_user_do_add_enckey $SCRATCH_MNT "$raw_key" -d $keydesc
rm -rf $dir
-echo
-_user_do "mkdir $dir"
-
-echo "# Setting v2 policy as regular user without key already added (should fail with ENOKEY)"
-_user_do_set_encpolicy $dir $keyid |& _filter_scratch
-
-echo "# Adding v2 policy key as regular user (should succeed)"
-_user_do_add_enckey $SCRATCH_MNT "$raw_key"
-
-echo "# Setting v2 policy as regular user with key added (should succeed)"
-_user_do_set_encpolicy $dir $keyid
-
-echo "# Getting v2 policy as regular user (should succeed)"
-_user_do_get_encpolicy $dir | _filter_scratch
-
-echo "# Creating encrypted file as regular user (should succeed)"
-_user_do "echo contents > $dir/file"
-
-echo "# Removing v2 policy key as regular user (should succeed)"
-_user_do_rm_enckey $SCRATCH_MNT $keyid
-
-_scratch_cycle_mount # Clear all keys
-
-# Wait for any invalidated keys to be garbage-collected.
-i=0
-while grep -E -q '^[0-9a-f]+ [^ ]*i[^ ]*' /proc/keys; do
- if ((++i >= 20)); then
- echo "Timed out waiting for invalidated keys to be GC'ed" >> $seqres.full
- break
- fi
- sleep 0.5
-done
-
-# Set the user key quota to the fsgqa user's current number of keys plus 5.
-orig_keys=$(_user_do "awk '/^[[:space:]]*$(id -u fsgqa):/{print \$4}' /proc/key-users | cut -d/ -f1")
-: ${orig_keys:=0}
-echo "orig_keys=$orig_keys" >> $seqres.full
-orig_maxkeys=$(</proc/sys/kernel/keys/maxkeys)
-keys_to_add=5
-echo $((orig_keys + keys_to_add)) > /proc/sys/kernel/keys/maxkeys
-
-echo
-echo "# Testing user key quota"
-for i in `seq $((keys_to_add + 1))`; do
- rand_raw_key=$(_generate_raw_encryption_key)
- _user_do_add_enckey $SCRATCH_MNT "$rand_raw_key" \
- | sed 's/ with identifier .*$//'
-done
-
-# Restore the original key quota.
-echo "$orig_maxkeys" > /proc/sys/kernel/keys/maxkeys
-
-rm -rf $dir
-echo
-_user_do "mkdir $dir"
-_scratch_cycle_mount # Clear all keys
-
-# Test multiple users adding the same key.
-echo "# Adding key as root"
-_add_enckey $SCRATCH_MNT "$raw_key"
-echo "# Getting key status as regular user"
-_user_do_enckey_status $SCRATCH_MNT $keyid
-echo "# Removing key only added by another user (should fail with ENOKEY)"
-_user_do_rm_enckey $SCRATCH_MNT $keyid
-echo "# Setting v2 encryption policy with key only added by another user (should fail with ENOKEY)"
-_user_do_set_encpolicy $dir $keyid |& _filter_scratch
-echo "# Adding second user of key"
-_user_do_add_enckey $SCRATCH_MNT "$raw_key"
-echo "# Getting key status as regular user"
-_user_do_enckey_status $SCRATCH_MNT $keyid
-echo "# Setting v2 encryption policy as regular user"
-_user_do_set_encpolicy $dir $keyid
-echo "# Removing this user's claim to the key"
-_user_do_rm_enckey $SCRATCH_MNT $keyid
-echo "# Getting key status as regular user"
-_user_do_enckey_status $SCRATCH_MNT $keyid
-echo "# Adding back second user of key"
-_user_do_add_enckey $SCRATCH_MNT "$raw_key"
-echo "# Remove key for \"all users\", as regular user (should fail with EACCES)"
-_user_do_rm_enckey $SCRATCH_MNT $keyid -a |& _filter_scratch
-_enckey_status $SCRATCH_MNT $keyid
-echo "# Remove key for \"all users\", as root"
-_rm_enckey $SCRATCH_MNT $keyid -a
-_enckey_status $SCRATCH_MNT $keyid
# success, all done
status=0
diff --git a/tests/generic/581.out b/tests/generic/581.out
index b3f7d889..a8cb96a8 100644
--- a/tests/generic/581.out
+++ b/tests/generic/581.out
@@ -10,53 +10,3 @@ Encryption policy for SCRATCH_MNT/dir:
Flags: 0x02
# Adding v1 policy key as regular user (should fail with EACCES)
Permission denied
-
-# Setting v2 policy as regular user without key already added (should fail with ENOKEY)
-SCRATCH_MNT/dir: failed to set encryption policy: Required key not available
-# Adding v2 policy key as regular user (should succeed)
-Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
-# Setting v2 policy as regular user with key added (should succeed)
-# Getting v2 policy as regular user (should succeed)
-Encryption policy for SCRATCH_MNT/dir:
- Policy version: 2
- Master key identifier: 69b2f6edeee720cce0577937eb8a6751
- Contents encryption mode: 1 (AES-256-XTS)
- Filenames encryption mode: 4 (AES-256-CTS)
- Flags: 0x02
-# Creating encrypted file as regular user (should succeed)
-# Removing v2 policy key as regular user (should succeed)
-Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
-
-# Testing user key quota
-Added encryption key
-Added encryption key
-Added encryption key
-Added encryption key
-Added encryption key
-Error adding encryption key: Disk quota exceeded
-
-# Adding key as root
-Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
-# Getting key status as regular user
-Present (user_count=1)
-# Removing key only added by another user (should fail with ENOKEY)
-Error removing encryption key: Required key not available
-# Setting v2 encryption policy with key only added by another user (should fail with ENOKEY)
-SCRATCH_MNT/dir: failed to set encryption policy: Required key not available
-# Adding second user of key
-Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
-# Getting key status as regular user
-Present (user_count=2, added_by_self)
-# Setting v2 encryption policy as regular user
-# Removing this user's claim to the key
-Removed user's claim to encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
-# Getting key status as regular user
-Present (user_count=1)
-# Adding back second user of key
-Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
-# Remove key for "all users", as regular user (should fail with EACCES)
-Permission denied
-Present (user_count=2, added_by_self)
-# Remove key for "all users", as root
-Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
-Absent
diff --git a/tests/generic/799 b/tests/generic/799
new file mode 100755
index 00000000..ac2f6154
--- /dev/null
+++ b/tests/generic/799
@@ -0,0 +1,132 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright 2019 Google LLC
+#
+# FS QA Test No. generic/799
+#
+# Test non-root use of the fscrypt filesystem-level encryption v2 policy.
+#
+
+. ./common/preamble
+_begin_fstest auto quick encrypt
+echo
+
+orig_maxkeys=
+
+# Override the default cleanup function.
+_cleanup()
+{
+ cd /
+ rm -f $tmp.*
+ if [ -n "$orig_maxkeys" ]; then
+ echo "$orig_maxkeys" > /proc/sys/kernel/keys/maxkeys
+ fi
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/encrypt
+
+_require_user
+_require_scratch_encryption -v 2
+
+_scratch_mkfs_encrypted &>> $seqres.full
+_scratch_mount
+
+dir=$SCRATCH_MNT/dir
+
+raw_key=""
+for i in `seq 64`; do
+ raw_key+="\\x$(printf "%02x" $i)"
+done
+keydesc="0000111122223333"
+keyid="69b2f6edeee720cce0577937eb8a6751"
+chmod 777 $SCRATCH_MNT
+
+_user_do "mkdir $dir"
+
+echo "# Setting v2 policy as regular user without key already added (should fail with ENOKEY)"
+_user_do_set_encpolicy $dir $keyid |& _filter_scratch
+
+echo "# Adding v2 policy key as regular user (should succeed)"
+_user_do_add_enckey $SCRATCH_MNT "$raw_key"
+
+echo "# Setting v2 policy as regular user with key added (should succeed)"
+_user_do_set_encpolicy $dir $keyid
+
+echo "# Getting v2 policy as regular user (should succeed)"
+_user_do_get_encpolicy $dir | _filter_scratch
+
+echo "# Creating encrypted file as regular user (should succeed)"
+_user_do "echo contents > $dir/file"
+
+echo "# Removing v2 policy key as regular user (should succeed)"
+_user_do_rm_enckey $SCRATCH_MNT $keyid
+
+_scratch_cycle_mount # Clear all keys
+
+# Wait for any invalidated keys to be garbage-collected.
+i=0
+while grep -E -q '^[0-9a-f]+ [^ ]*i[^ ]*' /proc/keys; do
+ if ((++i >= 20)); then
+ echo "Timed out waiting for invalidated keys to be GC'ed" >> $seqres.full
+ break
+ fi
+ sleep 0.5
+done
+
+# Set the user key quota to the fsgqa user's current number of keys plus 5.
+orig_keys=$(_user_do "awk '/^[[:space:]]*$(id -u fsgqa):/{print \$4}' /proc/key-users | cut -d/ -f1")
+: ${orig_keys:=0}
+echo "orig_keys=$orig_keys" >> $seqres.full
+orig_maxkeys=$(</proc/sys/kernel/keys/maxkeys)
+keys_to_add=5
+echo $((orig_keys + keys_to_add)) > /proc/sys/kernel/keys/maxkeys
+
+echo
+echo "# Testing user key quota"
+for i in `seq $((keys_to_add + 1))`; do
+ rand_raw_key=$(_generate_raw_encryption_key)
+ _user_do_add_enckey $SCRATCH_MNT "$rand_raw_key" \
+ | sed 's/ with identifier .*$//'
+done
+
+# Restore the original key quota.
+echo "$orig_maxkeys" > /proc/sys/kernel/keys/maxkeys
+
+rm -rf $dir
+echo
+_user_do "mkdir $dir"
+_scratch_cycle_mount # Clear all keys
+
+# Test multiple users adding the same key.
+echo "# Adding key as root"
+_add_enckey $SCRATCH_MNT "$raw_key"
+echo "# Getting key status as regular user"
+_user_do_enckey_status $SCRATCH_MNT $keyid
+echo "# Removing key only added by another user (should fail with ENOKEY)"
+_user_do_rm_enckey $SCRATCH_MNT $keyid
+echo "# Setting v2 encryption policy with key only added by another user (should fail with ENOKEY)"
+_user_do_set_encpolicy $dir $keyid |& _filter_scratch
+echo "# Adding second user of key"
+_user_do_add_enckey $SCRATCH_MNT "$raw_key"
+echo "# Getting key status as regular user"
+_user_do_enckey_status $SCRATCH_MNT $keyid
+echo "# Setting v2 encryption policy as regular user"
+_user_do_set_encpolicy $dir $keyid
+echo "# Removing this user's claim to the key"
+_user_do_rm_enckey $SCRATCH_MNT $keyid
+echo "# Getting key status as regular user"
+_user_do_enckey_status $SCRATCH_MNT $keyid
+echo "# Adding back second user of key"
+_user_do_add_enckey $SCRATCH_MNT "$raw_key"
+echo "# Remove key for \"all users\", as regular user (should fail with EACCES)"
+_user_do_rm_enckey $SCRATCH_MNT $keyid -a |& _filter_scratch
+_enckey_status $SCRATCH_MNT $keyid
+echo "# Remove key for \"all users\", as root"
+_rm_enckey $SCRATCH_MNT $keyid -a
+_enckey_status $SCRATCH_MNT $keyid
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/799.out b/tests/generic/799.out
new file mode 100644
index 00000000..4e32a33c
--- /dev/null
+++ b/tests/generic/799.out
@@ -0,0 +1,51 @@
+QA output created by 799
+
+# Setting v2 policy as regular user without key already added (should fail with ENOKEY)
+SCRATCH_MNT/dir: failed to set encryption policy: Required key not available
+# Adding v2 policy key as regular user (should succeed)
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Setting v2 policy as regular user with key added (should succeed)
+# Getting v2 policy as regular user (should succeed)
+Encryption policy for SCRATCH_MNT/dir:
+ Policy version: 2
+ Master key identifier: 69b2f6edeee720cce0577937eb8a6751
+ Contents encryption mode: 1 (AES-256-XTS)
+ Filenames encryption mode: 4 (AES-256-CTS)
+ Flags: 0x02
+# Creating encrypted file as regular user (should succeed)
+# Removing v2 policy key as regular user (should succeed)
+Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+
+# Testing user key quota
+Added encryption key
+Added encryption key
+Added encryption key
+Added encryption key
+Added encryption key
+Error adding encryption key: Disk quota exceeded
+
+# Adding key as root
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Getting key status as regular user
+Present (user_count=1)
+# Removing key only added by another user (should fail with ENOKEY)
+Error removing encryption key: Required key not available
+# Setting v2 encryption policy with key only added by another user (should fail with ENOKEY)
+SCRATCH_MNT/dir: failed to set encryption policy: Required key not available
+# Adding second user of key
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Getting key status as regular user
+Present (user_count=2, added_by_self)
+# Setting v2 encryption policy as regular user
+# Removing this user's claim to the key
+Removed user's claim to encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Getting key status as regular user
+Present (user_count=1)
+# Adding back second user of key
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Remove key for "all users", as regular user (should fail with EACCES)
+Permission denied
+Present (user_count=2, added_by_self)
+# Remove key for "all users", as root
+Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+Absent
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 11/12] fstests: split generic/613 into two tests
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
` (9 preceding siblings ...)
2026-07-24 13:33 ` [PATCH 10/12] fstests: split generic/581 " Daniel Vacek
@ 2026-07-24 13:33 ` Daniel Vacek
2026-07-24 13:33 ` [PATCH 12/12] fscrypt-crypt-util: add support for per extent KDF Daniel Vacek
2026-07-28 3:19 ` [PATCH 00/12] fstests: introduce fscrypt support for btrfs Christoph Hellwig
12 siblings, 0 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt, Josef Bacik
From: Josef Bacik <josef@toxicpanda.com>
generic/613 tests v1 and v2 policies, but btrfs can only support v2
policies. Split this into two different tests, 613 which will only test
v1 policies, and then 800 which will test v2 policies.
The 800 test will also add checks for the per-extent nonces to validate
they're all sufficiently random.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
tests/generic/613 | 20 ++------
tests/generic/613.out | 5 +-
tests/generic/800 | 115 ++++++++++++++++++++++++++++++++++++++++++
tests/generic/800.out | 14 +++++
4 files changed, 136 insertions(+), 18 deletions(-)
create mode 100755 tests/generic/800
create mode 100644 tests/generic/800.out
diff --git a/tests/generic/613 b/tests/generic/613
index 6a120c13..aee9f4db 100755
--- a/tests/generic/613
+++ b/tests/generic/613
@@ -20,22 +20,21 @@ _begin_fstest auto quick encrypt
. ./common/filter
. ./common/encrypt
-_require_scratch_encryption -v 2
+_require_scratch_encryption
_require_get_encryption_nonce_support
_require_command "$XZ_PROG" xz
_scratch_mkfs_encrypted &>> $seqres.full
_scratch_mount
-echo -e "\n# Adding encryption keys"
-_add_enckey $SCRATCH_MNT "$TEST_RAW_KEY"
+echo -e "\n# Adding encryption key"
_add_enckey $SCRATCH_MNT "$TEST_RAW_KEY" -d $TEST_KEY_DESCRIPTOR
# Create a bunch of encrypted files and directories -- enough for the uniqueness
# and randomness tests to be meaningful, but not so many that this test takes a
-# long time. Test using both v1 and v2 encryption policies, and for each of
-# those test the case of an encryption policy that is assigned to an empty
-# directory as well as the case of a file created in an encrypted directory.
+# long time. Test using the v1 encryption policy, test the case of an
+# encryption policy that is assigned to an empty directory as well as the case
+# of a file created in an encrypted directory.
echo -e "\n# Creating encrypted files and directories"
inodes=()
for i in {1..50}; do
@@ -43,20 +42,11 @@ for i in {1..50}; do
mkdir $dir
inodes+=("$(stat -c %i $dir)")
_set_encpolicy $dir $TEST_KEY_DESCRIPTOR
-
- dir=$SCRATCH_MNT/v2_policy_dir_$i
- mkdir $dir
- inodes+=("$(stat -c %i $dir)")
- _set_encpolicy $dir $TEST_KEY_IDENTIFIER
done
for i in {1..50}; do
file=$SCRATCH_MNT/v1_policy_dir_1/$i
touch $file
inodes+=("$(stat -c %i $file)")
-
- file=$SCRATCH_MNT/v2_policy_dir_1/$i
- touch $file
- inodes+=("$(stat -c %i $file)")
done
_scratch_unmount
diff --git a/tests/generic/613.out b/tests/generic/613.out
index 203a64f2..4a218d03 100644
--- a/tests/generic/613.out
+++ b/tests/generic/613.out
@@ -1,7 +1,6 @@
QA output created by 613
-# Adding encryption keys
-Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Adding encryption key
Added encryption key with descriptor 0000111122223333
# Creating encrypted files and directories
@@ -12,5 +11,5 @@ Added encryption key with descriptor 0000111122223333
Listing non-unique nonces:
# Verifying randomness of nonces
-Uncompressed size is 3200 bytes
+Uncompressed size is 1600 bytes
Nonces are incompressible, as expected
diff --git a/tests/generic/800 b/tests/generic/800
new file mode 100755
index 00000000..18377da4
--- /dev/null
+++ b/tests/generic/800
@@ -0,0 +1,115 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright 2023 Meta
+#
+# FS QA Test No. 800
+#
+# A variation of generic/613 that only tests v2, and checks data nonces for any
+# file system that supporst per-extent encryption.
+#
+# Test that encryption nonces are unique and random, where randomness is
+# approximated as "incompressible by the xz program".
+#
+# An encryption nonce is the 16-byte value that the filesystem generates for
+# each encrypted file. These nonces must be unique in order to cause different
+# files to be encrypted differently, which is an important security property.
+# In practice, they need to be random to achieve that; and it's easy enough to
+# test for both uniqueness and randomness, so we test for both.
+#
+. ./common/preamble
+_begin_fstest auto quick encrypt
+
+# Import common functions.
+. ./common/filter
+. ./common/encrypt
+
+_require_scratch_encryption -v 2
+_require_get_encryption_nonce_support
+_require_command "$XZ_PROG" xz
+
+_check_nonce()
+{
+ local nonce=$1
+
+ if (( ${#nonce} != 32 )) || [ -n "$(echo "$nonce" | tr -d 0-9a-fA-F)" ]
+ then
+ _fail "Expected nonce for inode $inode to be 16 bytes (32 hex characters), but got \"$nonce\""
+ fi
+}
+
+_scratch_mkfs_encrypted &>> $seqres.full
+_scratch_mount
+
+echo -e "\n# Adding encryption key"
+_add_enckey $SCRATCH_MNT "$TEST_RAW_KEY"
+
+# Create a bunch of encrypted files and directories -- enough for the uniqueness
+# and randomness tests to be meaningful, but not so many that this test takes a
+# long time. Test using the v2 encryption policy, test the case of an
+# encryption policy that is assigned to an empty directory as well as the case
+# of a file created in an encrypted directory.
+echo -e "\n# Creating encrypted files and directories"
+inodes=()
+for i in {1..50}; do
+ dir=$SCRATCH_MNT/v2_policy_dir_$i
+ mkdir $dir
+ inodes+=("$(stat -c %i $dir)")
+ _set_encpolicy $dir $TEST_KEY_IDENTIFIER
+done
+for i in {1..50}; do
+ file=$SCRATCH_MNT/v2_policy_dir_1/$i
+ $XFS_IO_PROG -f -c "pwrite 0 1m" $file > /dev/null
+ inodes+=("$(stat -c %i $file)")
+done
+_scratch_unmount
+
+# Build files that contain all the nonces. nonces_hex contains them in hex, one
+# per line. nonces_bin contains them in binary, all concatenated.
+echo -e "\n# Getting encryption nonces from inodes"
+echo -n > $tmp.nonces_hex
+echo -n > $tmp.nonces_bin
+for inode in "${inodes[@]}"; do
+ inode_nonce=$(_get_encryption_file_nonce $SCRATCH_DEV $inode)
+ _check_nonce $inode_nonce
+
+ echo $inode_nonce >> $tmp.nonces_hex
+ echo -ne "$(echo $inode_nonce | sed 's/[0-9a-fA-F]\{2\}/\\x\0/g')" \
+ >> $tmp.nonces_bin
+
+ data_nonce=$(_get_encryption_data_nonce $SCRATCH_DEV $inode)
+
+ # If the inode is empty we won't have a data nonce
+ [ "$data_nonce" = "" ] && continue
+
+ # If the inode nonce and data nonce are the same continue
+ [ "$inode_nonce" = "$data_nonce" ] && continue
+
+ _check_nonce $data_nonce
+
+ echo $data_nonce >> $tmp.nonces_hex
+ echo -ne "$(echo $data_nonce | sed 's/[0-9a-fA-F]\{2\}/\\x\0/g')" \
+ >> $tmp.nonces_bin
+done
+
+# Verify the uniqueness and randomness of the nonces. In theory randomness
+# implies uniqueness here, but it's easy enough to explicitly test for both.
+
+echo -e "\n# Verifying uniqueness of nonces"
+echo "Listing non-unique nonces:"
+sort < $tmp.nonces_hex | uniq -d
+
+echo -e "\n# Verifying randomness of nonces"
+uncompressed_size=$(stat -c %s $tmp.nonces_bin)
+echo "Uncompressed size is $uncompressed_size bytes" >> $seqres.full
+compressed_size=$($XZ_PROG -c < $tmp.nonces_bin | wc -c)
+echo "Compressed size is $compressed_size bytes" >> $seqres.full
+# The xz format has 60 bytes of overhead. Go a bit lower to avoid flakiness.
+if (( compressed_size >= uncompressed_size + 55 )); then
+ echo "Nonces are incompressible, as expected"
+else
+ _fail "Nonces are compressible (non-random); compressed $uncompressed_size => $compressed_size bytes!"
+fi
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/800.out b/tests/generic/800.out
new file mode 100644
index 00000000..5c477654
--- /dev/null
+++ b/tests/generic/800.out
@@ -0,0 +1,14 @@
+QA output created by 800
+
+# Adding encryption key
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+
+# Creating encrypted files and directories
+
+# Getting encryption nonces from inodes
+
+# Verifying uniqueness of nonces
+Listing non-unique nonces:
+
+# Verifying randomness of nonces
+Nonces are incompressible, as expected
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 12/12] fscrypt-crypt-util: add support for per extent KDF
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
` (10 preceding siblings ...)
2026-07-24 13:33 ` [PATCH 11/12] fstests: split generic/613 " Daniel Vacek
@ 2026-07-24 13:33 ` Daniel Vacek
2026-07-28 3:19 ` [PATCH 00/12] fstests: introduce fscrypt support for btrfs Christoph Hellwig
12 siblings, 0 replies; 14+ messages in thread
From: Daniel Vacek @ 2026-07-24 13:33 UTC (permalink / raw)
To: fstests
Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang, hch,
djwong, David Sterba, Daniel Vacek, linux-fscrypt
When deriving a key for extent, fscrypt uses different salt. Add the
support for this.
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
common/encrypt | 13 +++++++++----
src/fscrypt-crypt-util.c | 12 +++++++++++-
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/common/encrypt b/common/encrypt
index 4c3fd904..2485b69a 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -836,7 +836,7 @@ _do_verify_ciphertext_for_encryption_policy()
local blocksize=$(_get_block_size $SCRATCH_MNT)
local test_contents_files=()
local test_filenames_files=()
- local i src dir dst inode blocklist \
+ local i src dir dst inode blocklist context_per_extent \
padding_flag padding dir_inode len name f nonce decrypted_name
# Create files whose encrypted contents we'll verify. For each, save
@@ -891,19 +891,24 @@ _do_verify_ciphertext_for_encryption_policy()
# Now unmount the filesystem and verify the ciphertext we just wrote.
_scratch_unmount
+ case $FSTYP in
+ btrfs) context_per_extent=--context-per-extent;;
+ *) context_per_extent=;;
+ esac
+
echo "Verifying encrypted file contents" >> $seqres.full
for f in "${test_contents_files[@]}"; do
read -r src inode blocklist <<< "$f"
nonce=$(_get_encryption_data_nonce $SCRATCH_DEV $inode)
_dump_ciphertext_blocks $SCRATCH_DEV $blocklist > $tmp.actual_contents
$crypt_contents_cmd $contents_encryption_mode $raw_key_hex \
- --file-nonce=$nonce --inode-number=$inode \
- < $src > $tmp.expected_contents
+ --file-nonce=$nonce $context_per_extent --inode-number=$inode \
+ < $src > $tmp.expected_contents
if ! cmp $tmp.expected_contents $tmp.actual_contents; then
_fail "Expected encrypted contents != actual encrypted contents. File: $f"
fi
$crypt_contents_cmd $contents_encryption_mode $raw_key_hex \
- --decrypt --file-nonce=$nonce --inode-number=$inode \
+ --decrypt --file-nonce=$nonce $context_per_extent --inode-number=$inode \
< $tmp.actual_contents > $tmp.decrypted_contents
if ! cmp $src $tmp.decrypted_contents; then
_fail "Contents decryption sanity check failed. File: $f"
diff --git a/src/fscrypt-crypt-util.c b/src/fscrypt-crypt-util.c
index f51b3669..1403edb5 100644
--- a/src/fscrypt-crypt-util.c
+++ b/src/fscrypt-crypt-util.c
@@ -75,6 +75,7 @@ static void usage(FILE *fp)
" replicate the en/decryption that is done when\n"
" the filesystem is given a hardware-wrapped key.\n"
" --file-nonce=NONCE File's nonce as a 32-character hex string\n"
+" --context-per-extent Derive the key for per extent context.\n"
" --fs-uuid=UUID The filesystem UUID as a 32-character hex string.\n"
" Required for --iv-ino-lblk-32 and\n"
" --iv-ino-lblk-64; otherwise is unused.\n"
@@ -2162,6 +2163,7 @@ struct key_and_iv_params {
bool direct_key;
bool iv_ino_lblk_64;
bool iv_ino_lblk_32;
+ bool context_per_extent;
u64 data_unit_index;
u64 inode_number;
u8 fs_uuid[UUID_SIZE];
@@ -2176,6 +2178,7 @@ struct key_and_iv_params {
#define HKDF_CONTEXT_IV_INO_LBLK_32_KEY 6
#define HKDF_CONTEXT_INODE_HASH_KEY 7
#define HKDF_CONTEXT_KEY_IDENTIFIER_FOR_HW_WRAPPED_KEY 8
+#define HKDF_CONTEXT_PER_EXTENT_ENC_KEY 9
/* Hash the file's inode number using SipHash keyed by a derived key */
static u32 hash_inode_number(const struct key_and_iv_params *params)
@@ -2366,7 +2369,9 @@ static void derive_real_key(const struct key_and_iv_params *params,
} else {
if (!params->file_nonce_specified)
die("--kdf=HKDF-SHA512 requires --file-nonce or --iv-ino-lblk-{64,32}");
- info[infolen++] = HKDF_CONTEXT_PER_FILE_ENC_KEY;
+ info[infolen++] = params->context_per_extent?
+ HKDF_CONTEXT_PER_EXTENT_ENC_KEY:
+ HKDF_CONTEXT_PER_FILE_ENC_KEY;
memcpy(&info[infolen], params->file_nonce,
FILE_NONCE_SIZE);
infolen += FILE_NONCE_SIZE;
@@ -2481,6 +2486,7 @@ enum {
OPT_DUMP_KEY_IDENTIFIER,
OPT_ENABLE_HW_KDF,
OPT_FILE_NONCE,
+ OPT_CONTEXT_PER_EXTENT,
OPT_FS_UUID,
OPT_HELP,
OPT_INODE_NUMBER,
@@ -2500,6 +2506,7 @@ static const struct option longopts[] = {
{ "dump-key-identifier", no_argument, NULL, OPT_DUMP_KEY_IDENTIFIER },
{ "enable-hw-kdf", no_argument, NULL, OPT_ENABLE_HW_KDF },
{ "file-nonce", required_argument, NULL, OPT_FILE_NONCE },
+ { "context-per-extent", no_argument, NULL, OPT_CONTEXT_PER_EXTENT },
{ "fs-uuid", required_argument, NULL, OPT_FS_UUID },
{ "help", no_argument, NULL, OPT_HELP },
{ "inode-number", required_argument, NULL, OPT_INODE_NUMBER },
@@ -2572,6 +2579,9 @@ int main(int argc, char *argv[])
die("Invalid file nonce: %s", optarg);
params.file_nonce_specified = true;
break;
+ case OPT_CONTEXT_PER_EXTENT:
+ params.context_per_extent = true;
+ break;
case OPT_FS_UUID:
if (hex2bin(optarg, params.fs_uuid, UUID_SIZE)
!= UUID_SIZE)
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 00/12] fstests: introduce fscrypt support for btrfs
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
` (11 preceding siblings ...)
2026-07-24 13:33 ` [PATCH 12/12] fscrypt-crypt-util: add support for per extent KDF Daniel Vacek
@ 2026-07-28 3:19 ` Christoph Hellwig
12 siblings, 0 replies; 14+ messages in thread
From: Christoph Hellwig @ 2026-07-28 3:19 UTC (permalink / raw)
To: Daniel Vacek
Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel,
zlang, hch, djwong, David Sterba, linux-fscrypt
On Fri, Jul 24, 2026 at 03:33:16PM +0200, Daniel Vacek wrote:
> This is a rebase and cleanup of older patches [0] from Sweet Tea and Josef
> fixed to work with the recent kernel and btrfs-progs changes.
I'm not sure if you post this just for reference or what the intent here
is, especially with a cover letter like this that doesn't have much
information.
Before we doing anything for the btrfs-specific fscrypt changes in
xfstests, those changes should be accepted upstream first.
Maybe some thing like splitting tests might make sense without that,
but then it should be posted separately.
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-07-28 3:19 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
2026-07-24 13:33 ` [PATCH 01/12] common/encrypt: separate data and inode nonces Daniel Vacek
2026-07-24 13:33 ` [PATCH 02/12] common/encrypt: add btrfs to get_encryption_*nonce Daniel Vacek
2026-07-24 13:33 ` [PATCH 03/12] common/encrypt: add btrfs to get_ciphertext_filename Daniel Vacek
2026-07-24 13:33 ` [PATCH 04/12] common/encrypt: enable making a encrypted btrfs filesystem Daniel Vacek
2026-07-24 13:33 ` [PATCH 05/12] common/verity: explicitly don't allow btrfs encryption Daniel Vacek
2026-07-24 13:33 ` [PATCH 06/12] btrfs: add simple test of reflink of encrypted data Daniel Vacek
2026-07-24 13:33 ` [PATCH 07/12] btrfs: test snapshotting encrypted subvol Daniel Vacek
2026-07-24 13:33 ` [PATCH 08/12] fstests: properly test for v1 encryption policies in encrypt tests Daniel Vacek
2026-07-24 13:33 ` [PATCH 09/12] fstests: split generic/580 into two tests Daniel Vacek
2026-07-24 13:33 ` [PATCH 10/12] fstests: split generic/581 " Daniel Vacek
2026-07-24 13:33 ` [PATCH 11/12] fstests: split generic/613 " Daniel Vacek
2026-07-24 13:33 ` [PATCH 12/12] fscrypt-crypt-util: add support for per extent KDF Daniel Vacek
2026-07-28 3:19 ` [PATCH 00/12] fstests: introduce fscrypt support for btrfs Christoph Hellwig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox