X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fllite%2Fcrypto.c;h=cc80aea8cfbd3ec1641aa944cb59ff10f683c37f;hb=fdbf2ffd41fa5660782d5ca8489ec2eb644c8113;hp=89917c71a553d31a713918b707dff77dcaf56e95;hpb=ed4a625d88567a2498c3fe32fd340ae7985e6ad0;p=fs%2Flustre-release.git diff --git a/lustre/llite/crypto.c b/lustre/llite/crypto.c index 89917c7..cc80aea 100644 --- a/lustre/llite/crypto.c +++ b/lustre/llite/crypto.c @@ -34,10 +34,26 @@ 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); @@ -115,6 +131,34 @@ static int ll_set_context(struct inode *inode, const void *ctx, size_t len, 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) @@ -123,7 +167,7 @@ void llcrypt_free_ctx(void *encctx, __u32 size) 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) @@ -135,16 +179,17 @@ 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) @@ -201,6 +246,17 @@ int ll_setup_filename(struct inode *dir, const struct qstr *iname, 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; @@ -401,6 +457,11 @@ int ll_set_encflags(struct inode *inode, void *encctx, __u32 encctxlen, 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) { }