[lustre-devel] [PATCH 18/18] lustre: sec: migrate/extend/split on encrypted file

James Simmons jsimmons at infradead.org
Mon Jul 19 05:32:13 PDT 2021


From: Sebastien Buisson <sbuisson at ddn.com>

lfs migrate/extend/split makes use of volatile files to swap layouts.
When operation is carried out on an encrypted file, the volatile file
must be assigned the same encryption context as the original file, so
that data moved/copied to different OSTs is identical to the original
file's.
Also update sanity-sec test_52 to exercise these commands.

WC-bug-id: https://jira.whamcloud.com/browse/LU-14677
Lustre-commit: 09c558d16f0a80f4 ("LU-14677 sec: migrate/extend/split on encrypted file")
Signed-off-by: Sebastien Buisson <sbuisson at ddn.com>
Reviewed-on: https://review.whamcloud.com/43878
Reviewed-by: Andreas Dilger <adilger at whamcloud.com>
Reviewed-by: Bobi Jam <bobijam at hotmail.com>
Reviewed-by: Oleg Drokin <green at whamcloud.com>
Signed-off-by: James Simmons <jsimmons at infradead.org>
---
 fs/lustre/include/lustre_crypto.h |   2 +
 fs/lustre/llite/llite_lib.c       |   6 +--
 fs/lustre/llite/namei.c           | 101 ++++++++++++++++++++++++++++++++++++--
 3 files changed, 102 insertions(+), 7 deletions(-)

diff --git a/fs/lustre/include/lustre_crypto.h b/fs/lustre/include/lustre_crypto.h
index b19bb420..6cc946d 100644
--- a/fs/lustre/include/lustre_crypto.h
+++ b/fs/lustre/include/lustre_crypto.h
@@ -58,6 +58,8 @@ static inline bool ll_sbi_has_encrypt(struct ll_sb_info *sbi)
 
 static inline void ll_sbi_set_encrypt(struct ll_sb_info *sbi, bool set) { }
 #endif
+/* sizeof(struct fscrypt_context_v2) = 40 */
+#define LLCRYPT_ENC_CTX_SIZE 40
 
 /* Encoding/decoding routines inspired from yEnc principles.
  * We just take care of a few critical characters:
diff --git a/fs/lustre/llite/llite_lib.c b/fs/lustre/llite/llite_lib.c
index 88a1d17..5610523 100644
--- a/fs/lustre/llite/llite_lib.c
+++ b/fs/lustre/llite/llite_lib.c
@@ -2063,8 +2063,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr,
 			 * it is necessary due to possible time
 			 * de-synchronization between MDT inode and OST objects
 			 */
-			if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode) &&
-			    attr->ia_valid & ATTR_SIZE) {
+			if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode)) {
 				xvalid |= OP_XVALID_FLAGS;
 				flags = LUSTRE_ENCRYPT_FL;
 				/* Call to ll_io_zero_page is not necessary if
@@ -2073,7 +2072,8 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr,
 				 * In case of Direct IO, all we need is to set
 				 * new size.
 				 */
-				if (attr->ia_size & ~PAGE_MASK &&
+				if (attr->ia_valid & ATTR_SIZE &&
+				    attr->ia_size & ~PAGE_MASK &&
 				    !(attr->ia_valid & ATTR_FILE &&
 				      attr->ia_file->f_flags & O_DIRECT)) {
 					pgoff_t offset;
diff --git a/fs/lustre/llite/namei.c b/fs/lustre/llite/namei.c
index f32aa14..5cc01f0 100644
--- a/fs/lustre/llite/namei.c
+++ b/fs/lustre/llite/namei.c
@@ -33,6 +33,7 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/file.h>
 #include <linux/quotaops.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
@@ -878,10 +879,102 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
 			*secctxlen = 0;
 	}
 	if (it->it_op & IT_CREAT && encrypt) {
-		rc = fscrypt_inherit_context(parent, NULL, op_data, false);
-		if (rc) {
-			retval = ERR_PTR(rc);
-			goto out;
+		/* Volatile file name may look like:
+		 * <parent>/LUSTRE_VOLATILE_HDR:<mdt_index>:<random>:fd=<fd>
+		 * where fd is opened descriptor of reference file.
+		 */
+		if (unlikely(filename_is_volatile(dentry->d_name.name,
+						  dentry->d_name.len, NULL))) {
+			int ctx_size = LLCRYPT_ENC_CTX_SIZE;
+			struct lustre_sb_info *lsi;
+			struct file *ref_file;
+			struct inode *ref_inode;
+			char *p, *q, *fd_str;
+			void *ctx;
+			int fd;
+
+			p = strnstr(dentry->d_name.name, ":fd=",
+				    dentry->d_name.len);
+			if (!p || strlen(p + 4) == 0) {
+				retval = ERR_PTR(-EINVAL);
+				goto out;
+			}
+
+			q = strchrnul(p + 4, ':');
+			fd_str = kstrndup(p + 4, q - p - 4, GFP_NOFS);
+			if (!fd_str) {
+				retval = ERR_PTR(-ENOMEM);
+				goto out;
+			}
+			rc = kstrtouint(fd_str, 10, &fd);
+			kfree(fd_str);
+			if (rc) {
+				rc = -EINVAL;
+				goto inherit;
+			}
+
+			ref_file = fget(fd);
+			if (!ref_file) {
+				rc = -EINVAL;
+				goto inherit;
+			}
+
+			ref_inode = file_inode(ref_file);
+			if (!ref_inode) {
+				fput(ref_file);
+				rc = -EINVAL;
+				goto inherit;
+			}
+
+			lsi = s2lsi(ref_inode->i_sb);
+
+getctx:
+			ctx = kzalloc(ctx_size, GFP_NOFS);
+			if (!ctx) {
+				retval = ERR_PTR(-ENOMEM);
+				goto out;
+			}
+
+#ifdef CONFIG_FS_ENCRYPTION
+			rc = ref_inode->i_sb->s_cop->get_context(ref_inode,
+								 ctx, ctx_size);
+#else
+			rc = -ENODATA;
+#endif
+			if (rc == -ERANGE) {
+				kfree(ctx);
+				ctx_size *= 2;
+				goto getctx;
+			}
+			fput(ref_file);
+			if (rc < 0) {
+				kfree(ctx);
+				goto inherit;
+			}
+
+			op_data->op_file_encctx_size = rc;
+			if (rc == ctx_size) {
+				op_data->op_file_encctx = ctx;
+			} else {
+				op_data->op_file_encctx = kzalloc(op_data->op_file_encctx_size,
+								  GFP_NOFS);
+				if (!op_data->op_file_encctx) {
+					kfree(ctx);
+					retval = ERR_PTR(-ENOMEM);
+					goto out;
+				}
+				memcpy(op_data->op_file_encctx, ctx,
+				       op_data->op_file_encctx_size);
+				kfree(ctx);
+			}
+		} else {
+inherit:
+			rc = fscrypt_inherit_context(parent, NULL, op_data,
+						     false);
+			if (rc) {
+				retval = ERR_PTR(rc);
+				goto out;
+			}
 		}
 		if (encctx)
 			*encctx = op_data->op_file_encctx;
-- 
1.8.3.1



More information about the lustre-devel mailing list