From: Sebastien Buisson Date: Mon, 14 Nov 2022 16:28:36 +0000 (+0100) Subject: LU-16310 sec: Lustre/HSM on enc file with enc key X-Git-Tag: 2.15.54~21 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=df7a8d92d2378e236ee83b559e7a1158f84e63f4;p=fs%2Flustre-release.git LU-16310 sec: Lustre/HSM on enc file with enc key Support for Lustre/HSM on encrypted files when the encryption key is available requires similar attention as with file migration. The volatile file used for HSM restore must have the same encryption context as the Lustre file being restored, so that file content remains accessible after the layout swap at the end of the restore procedure. Please note that using Lustre/HSM with the encryption key creates clear text copies of encrypted files on the HSM backend storage. Signed-off-by: Sebastien Buisson Change-Id: I99cba202cd2c7c747bbe5c4ec7d9208c7f6baf4b Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/49153 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin Reviewed-by: jsimmons Reviewed-by: Andreas Dilger Reviewed-by: Etienne AUJAMES --- diff --git a/lustre/llite/crypto.c b/lustre/llite/crypto.c index a832d4d..37a2153 100644 --- a/lustre/llite/crypto.c +++ b/lustre/llite/crypto.c @@ -270,7 +270,16 @@ int ll_setup_filename(struct inode *dir, const struct qstr *iname, fid->f_oid = 0; fid->f_ver = 0; } - rc = llcrypt_setup_filename(dir, &dname, lookup, fname); + if (unlikely(filename_is_volatile(iname->name, + iname->len, NULL))) { + /* keep volatile name as-is, matters for server side */ + memset(fname, 0, sizeof(struct llcrypt_name)); + fname->disk_name.name = (unsigned char *)iname->name; + fname->disk_name.len = iname->len; + rc = 0; + } else { + rc = llcrypt_setup_filename(dir, &dname, lookup, fname); + } if (rc == -ENOENT && lookup) { if (((is_root_inode(dir) && iname->len == strlen(dot_fscrypt_name) && diff --git a/lustre/utils/liblustreapi_hsm.c b/lustre/utils/liblustreapi_hsm.c index 374d03f..6c42607 100644 --- a/lustre/utils/liblustreapi_hsm.c +++ b/lustre/utils/liblustreapi_hsm.c @@ -1052,7 +1052,44 @@ static int create_restore_volatile(struct hsm_copyaction_private *hcp, snprintf(parent, sizeof(parent), "%s", ct->mnt); } - fd = llapi_create_volatile_idx(parent, mdt_index, open_flags); + if (hcp->source_fd < 0) { + fd = llapi_create_volatile_idx(parent, mdt_index, open_flags); + } else { + /* We need to insert source_fd in volatile file name, so open + * it manually. + */ + char file_path[PATH_MAX]; + unsigned int rnumber; + + do { + rnumber = random(); + if (mdt_index == -1) + rc = snprintf(file_path, sizeof(file_path), + "%s/"LUSTRE_VOLATILE_HDR"::%.4X:fd=%.2d", + parent, rnumber, hcp->source_fd); + else + rc = snprintf(file_path, sizeof(file_path), + "%s/"LUSTRE_VOLATILE_HDR":%.4X:%.4X:fd=%.2d", + parent, mdt_index, rnumber, hcp->source_fd); + if (rc < 0 || rc >= sizeof(file_path)) { + fd = -ENAMETOOLONG; + break; + } + + /* + * Either open O_WRONLY or O_RDWR, creating RDONLY + * is non-sensical here. + */ + if ((open_flags & O_ACCMODE) == O_RDONLY) + open_flags = O_RDWR | (open_flags & ~O_ACCMODE); + open_flags |= O_CREAT | O_EXCL | O_NOFOLLOW; + fd = open(file_path, open_flags, S_IRUSR | S_IWUSR); + if (fd < 0) + rc = -errno; + else + (void)unlink(file_path); + } while (fd < 0 && rc == -EEXIST); + } if (fd < 0) return fd; @@ -1130,8 +1167,26 @@ int llapi_hsm_action_begin(struct hsm_copyaction_private **phcp, if (rc < 0) goto err_out; + /* Use source_fd to store fd of Lustre file identified by fid. + * This fd is appended to volatile file name, useful in case + * of encrypted file in order to copy encryption context. + */ + hcp->source_fd = ct_open_by_fid(hcp->ct_priv, &hai->hai_dfid, + O_RDONLY | O_NOATIME | O_NOFOLLOW | O_NONBLOCK); + if (hcp->source_fd < 0) { + rc = hcp->source_fd; + goto err_out; + } + rc = create_restore_volatile(hcp, restore_mdt_index, restore_open_flags); + /* Now that volatile file has been created, + * source_fd can be closed. + */ + if (hcp->source_fd >= 0) { + close(hcp->source_fd); + hcp->source_fd = -1; + } if (rc < 0) goto err_out; } else if (hai->hai_action == HSMA_REMOVE) {