static int ll_get_context(struct inode *inode, void *ctx, size_t len)
{
struct dentry *dentry = d_find_any_alias(inode);
+ struct lu_env *env;
+ __u16 refcheck;
int rc;
+ env = cl_env_get(&refcheck);
+ if (IS_ERR(env))
+ return PTR_ERR(env);
+
+ /* Set lcc_getencctx=1 to allow this thread to read
+ * LL_XATTR_NAME_ENCRYPTION_CONTEXT xattr, as requested by llcrypt.
+ */
+ ll_cl_add(inode, env, NULL, LCC_RW);
+ ll_env_info(env)->lti_io_ctx.lcc_getencctx = 1;
+
rc = ll_vfs_getxattr(dentry, inode, LL_XATTR_NAME_ENCRYPTION_CONTEXT,
ctx, len);
+
+ ll_cl_remove(inode, env);
+ cl_env_put(env, &refcheck);
+
if (dentry)
dput(dentry);
return ll_set_encflags(inode, (void *)ctx, len, false);
}
+/**
+ * ll_file_open_encrypt() - overlay to llcrypt_file_open
+ * @inode: the inode being opened
+ * @filp: the struct file being set up
+ *
+ * This overlay function is necessary to handle encrypted file open without
+ * the key. We allow this access pattern to applications that know what they
+ * are doing, by using the specific flag O_FILE_ENC.
+ * This flag is only compatible with O_DIRECT IOs, to make sure ciphertext
+ * data is wiped from page cache once IOs are finished.
+ */
+int ll_file_open_encrypt(struct inode *inode, struct file *filp)
+{
+ int rc;
+
+ rc = llcrypt_file_open(inode, filp);
+ if (likely(rc != -ENOKEY))
+ return rc;
+
+ if (rc == -ENOKEY &&
+ (filp->f_flags & O_FILE_ENC) == O_FILE_ENC &&
+ filp->f_flags & O_DIRECT)
+ /* allow file open with O_FILE_ENC flag when we have O_DIRECT */
+ rc = 0;
+
+ return rc;
+}
+
void llcrypt_free_ctx(void *encctx, __u32 size)
{
if (encctx)
bool ll_sbi_has_test_dummy_encryption(struct ll_sb_info *sbi)
{
- return unlikely(sbi->ll_flags & LL_SBI_TEST_DUMMY_ENCRYPTION);
+ return unlikely(test_bit(LL_SBI_TEST_DUMMY_ENCRYPTION, sbi->ll_flags));
}
static bool ll_dummy_context(struct inode *inode)
bool ll_sbi_has_encrypt(struct ll_sb_info *sbi)
{
- return sbi->ll_flags & LL_SBI_ENCRYPT;
+ return test_bit(LL_SBI_ENCRYPT, sbi->ll_flags);
}
void ll_sbi_set_encrypt(struct ll_sb_info *sbi, bool set)
{
- if (set)
- sbi->ll_flags |= LL_SBI_ENCRYPT;
- else
- sbi->ll_flags &=
- ~(LL_SBI_ENCRYPT | LL_SBI_TEST_DUMMY_ENCRYPTION);
+ if (set) {
+ set_bit(LL_SBI_ENCRYPT, sbi->ll_flags);
+ } else {
+ clear_bit(LL_SBI_ENCRYPT, sbi->ll_flags);
+ clear_bit(LL_SBI_TEST_DUMMY_ENCRYPTION, sbi->ll_flags);
+ }
}
static bool ll_empty_dir(struct inode *inode)
fid->f_ver = 0;
}
rc = llcrypt_setup_filename(dir, &dname, lookup, fname);
+ if (rc == -ENOENT && lookup &&
+ !llcrypt_has_encryption_key(dir) &&
+ unlikely(filename_is_volatile(iname->name, iname->len, NULL))) {
+ /* For purpose of migration or mirroring without enc key, we
+ * allow lookup of volatile file without enc context.
+ */
+ memset(fname, 0, sizeof(struct llcrypt_name));
+ fname->disk_name.name = (unsigned char *)iname->name;
+ fname->disk_name.len = iname->len;
+ rc = 0;
+ }
if (rc)
return rc;
return 0;
}
+int ll_file_open_encrypt(struct inode *inode, struct file *filp)
+{
+ return llcrypt_file_open(inode, filp);
+}
+
void llcrypt_free_ctx(void *encctx, __u32 size)
{
}