Viewing: ext4-enc-flag.patch

commit 4231fab66eab3e984499bf0c6bd4514692a409fa
Author:     Sebastien Buisson <sbuisson@ddn.com>
AuthorDate: Thu Jan 6 14:19:02 2022 -0700
LU-13717 sec: make client encryption compatible with ext4

In order to benefit from encrypted file handling implemented in
e2fsprogs, we need to adjust the way Lustre deals with encryption
context of files.

First, the encryption context needs to be stored in an xattr named
"encryption.c" instead of "security.c". But neither llite nor ldiskfs
has an xattr handler for this "encryption." xattr type. So we need
to export ldiskfs_xattr_get and ldiskfs_xattr_set_handle symbols for
this to work.

Second, we set the LDISKFS_ENCRYPT_FL flag on files for which we set
the 'encryption.c' xattr. But we just keep this flag for on-disk
inodes, and make sure the flag is cleared for in-memory inodes.
The purpose is to help e2fsprogs with encrypted files handling, while
not disturbing Lustre server side with the encryption flag (servers
are not supposed to know about it for Lustre client-side encryption).

To maintain compatibility with 2.14 in which encryption context is
stored in "security.c" xattr, we try to fetch enc context from this
xattr if getting it from "encryption.c" fails. On client side, in all
cases everything looks like encryption context is stored in
"encryption.c".

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Li Dongyang <dongyangli@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Change-Id: I784ec530f0dfdd2743169ba2326ff6c5cdd4e85a
Reviewed-on: https://review.whamcloud.com/45211

diff -wur a/fs/ext4/ext4.h b/fs/ext4/ext4.h
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1154,6 +1154,9 @@ struct ext4_inode_info {
 #define EXT4_MOUNT_DISCARD		0x40000000 /* Issue DISCARD requests */
 #define EXT4_MOUNT_INIT_INODE_TABLE	0x80000000 /* Initialize uninitialized itables */
 
+/* we know this is a Lustre mount thanks to the DIRDATA flag */
+#define IS_LUSTRE_MOUNT(sb)	test_opt((sb), DIRDATA)
+
 /*
  * Mount flags set either automatically (could not be set by mount option)
  * based on per file system feature or property or in special cases such as
diff -wur a/fs/ext4/inode.c b/fs/ext4/inode.c
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4766,8 +4766,9 @@ void ext4_set_inode_flags(struct inod
 		new_fl |= S_DIRSYNC;
 	if (ext4_should_use_dax(inode))
 		new_fl |= S_DAX;
-	if (flags & EXT4_ENCRYPT_FL)
+	if (flags & EXT4_ENCRYPT_FL &&
+	    unlikely(!IS_LUSTRE_MOUNT(inode->i_sb)))
 		new_fl |= S_ENCRYPTED;
 	if (flags & EXT4_CASEFOLD_FL)
 		new_fl |= S_CASEFOLD;
 	if (flags & EXT4_VERITY_FL)
@@ -5753,8 +5757,9 @@ int ext4_getattr(const struct path *p
 		stat->attributes |= STATX_ATTR_APPEND;
 	if (flags & EXT4_COMPR_FL)
 		stat->attributes |= STATX_ATTR_COMPRESSED;
-	if (flags & EXT4_ENCRYPT_FL)
+	if (flags & EXT4_ENCRYPT_FL &&
+	    unlikely(!IS_LUSTRE_MOUNT(inode->i_sb)))
 		stat->attributes |= STATX_ATTR_ENCRYPTED;
 	if (flags & EXT4_IMMUTABLE_FL)
 		stat->attributes |= STATX_ATTR_IMMUTABLE;
 	if (flags & EXT4_NODUMP_FL)
diff -wur a/fs/ext4/xattr.c b/fs/ext4/xattr.c
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -654,6 +654,7 @@
 	up_read(&EXT4_I(inode)->xattr_sem);
 	return error;
 }
+EXPORT_SYMBOL(ext4_xattr_get);
 
 static int
 ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
@@ -2413,12 +2415,19 @@
 			ext4_handle_sync(handle);
 	}
 
+	if (!error && name_index == EXT4_XATTR_INDEX_ENCRYPTION &&
+	    strcmp(name, "c") == 0) {
+		EXT4_I(inode)->i_flags |= EXT4_ENCRYPT_FL;
+		mark_inode_dirty(inode);
+	}
+
 cleanup:
 	brelse(is.iloc.bh);
 	brelse(bs.bh);
 	ext4_write_unlock_xattr(inode, &no_expand);
 	return error;
 }
+EXPORT_SYMBOL(ext4_xattr_set_handle);
 
 int ext4_xattr_set_credits(struct inode *inode, size_t value_len,
 			    bool is_create, int *credits)