Commit b1d682f1 authored by Simon Weber's avatar Simon Weber Committed by Theodore Ts'o
Browse files

ext4: fix journal credit check when setting fscrypt context



Fix an issue arising when ext4 features has_journal, ea_inode, and encrypt
are activated simultaneously, leading to ENOSPC when creating an encrypted
file.

Fix by passing XATTR_CREATE flag to xattr_set_handle function if a handle
is specified, i.e., when the function is called in the control flow of
creating a new inode. This aligns the number of jbd2 credits set_handle
checks for with the number allocated for creating a new inode.

ext4_set_context must not be called with a non-null handle (fs_data) if
fscrypt context xattr is not guaranteed to not exist yet. The only other
usage of this function currently is when handling the ioctl
FS_IOC_SET_ENCRYPTION_POLICY, which calls it with fs_data=NULL.

Fixes: c1a5d5f6 ("ext4: improve journal credit handling in set xattr paths")

Co-developed-by: default avatarAnthony Durrer <anthonydev@fastmail.com>
Signed-off-by: default avatarAnthony Durrer <anthonydev@fastmail.com>
Signed-off-by: default avatarSimon Weber <simon.weber.39@gmail.com>
Reviewed-by: default avatarEric Biggers <ebiggers@kernel.org>
Link: https://patch.msgid.link/20260207100148.724275-4-simon.weber.39@gmail.com


Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org
parent ed9356a3
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -163,10 +163,17 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
	 */

	if (handle) {
		/*
		 * Since the inode is new it is ok to pass the
		 * XATTR_CREATE flag. This is necessary to match the
		 * remaining journal credits check in the set_handle
		 * function with the credits allocated for the new
		 * inode.
		 */
		res = ext4_xattr_set_handle(handle, inode,
					    EXT4_XATTR_INDEX_ENCRYPTION,
					    EXT4_XATTR_NAME_ENCRYPTION_CONTEXT,
					    ctx, len, 0);
					    ctx, len, XATTR_CREATE);
		if (!res) {
			ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
			ext4_clear_inode_state(inode,