X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fllite%2Fcrypto.c;h=764c9edc9e2fabac3b18ffbe53b7b8c4a3b05d70;hb=f0736a6a52ed95814d2cac875caf34f7fc233bf3;hp=5ccbedf9fe1da1ac969ee356c28ae5d5449d926a;hpb=28be31137cd22223113e461f74098c92ba6d71e4;p=fs%2Flustre-release.git diff --git a/lustre/llite/crypto.c b/lustre/llite/crypto.c index 5ccbedf..764c9ed 100644 --- a/lustre/llite/crypto.c +++ b/lustre/llite/crypto.c @@ -32,64 +32,94 @@ static int ll_get_context(struct inode *inode, void *ctx, size_t len) { - struct dentry *dentry; + struct dentry *dentry = d_find_any_alias(inode); int rc; - if (hlist_empty(&inode->i_dentry)) - return -ENODATA; - - hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { - break; - } - rc = ll_vfs_getxattr(dentry, inode, LL_XATTR_NAME_ENCRYPTION_CONTEXT, ctx, len); + if (dentry) + dput(dentry); + /* used as encryption unit size */ + if (S_ISREG(inode->i_mode)) + inode->i_blkbits = LUSTRE_ENCRYPTION_BLOCKBITS; return rc; } +int ll_set_encflags(struct inode *inode, void *encctx, __u32 encctxlen, + bool preload) +{ + unsigned int ext_flags; + int rc = 0; + + /* used as encryption unit size */ + if (S_ISREG(inode->i_mode)) + inode->i_blkbits = LUSTRE_ENCRYPTION_BLOCKBITS; + ext_flags = ll_inode_to_ext_flags(inode->i_flags) | LUSTRE_ENCRYPT_FL; + ll_update_inode_flags(inode, ext_flags); + + if (encctx && encctxlen) + rc = ll_xattr_cache_insert(inode, + LL_XATTR_NAME_ENCRYPTION_CONTEXT, + encctx, encctxlen); + if (rc) + return rc; + + return preload ? llcrypt_get_encryption_info(inode) : 0; +} + +/* ll_set_context has 2 distinct behaviors, depending on the value of inode + * parameter: + * - inode is NULL: + * passed fs_data is a struct md_op_data *. We need to store enc ctx in + * op_data, so that it will be sent along to the server with the request that + * the caller is preparing, thus saving a setxattr request. + * - inode is not NULL: + * normal case in which passed fs_data is a struct dentry *, letting proceed + * with setxattr operation. + * This use case should only be used when explicitly setting a new encryption + * policy on an existing, empty directory. + */ static int ll_set_context(struct inode *inode, const void *ctx, size_t len, void *fs_data) { - unsigned int ext_flags; struct dentry *dentry; - struct md_op_data *op_data; - struct ptlrpc_request *req = NULL; int rc; - if (inode == NULL) - return 0; + if (inode == NULL) { + struct md_op_data *op_data = (struct md_op_data *)fs_data; - ext_flags = ll_inode_to_ext_flags(inode->i_flags) | LUSTRE_ENCRYPT_FL; - dentry = (struct dentry *)fs_data; + if (!op_data) + return -EINVAL; + + OBD_ALLOC(op_data->op_file_encctx, len); + if (op_data->op_file_encctx == NULL) + return -ENOMEM; + op_data->op_file_encctx_size = len; + memcpy(op_data->op_file_encctx, ctx, len); + return 0; + } /* Encrypting the root directory is not allowed */ if (inode->i_ino == inode->i_sb->s_root->d_inode->i_ino) return -EPERM; - op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0, - LUSTRE_OPC_ANY, NULL); - if (IS_ERR(op_data)) - return PTR_ERR(op_data); - - op_data->op_attr_flags = LUSTRE_ENCRYPT_FL; - op_data->op_xvalid |= OP_XVALID_FLAGS; - rc = md_setattr(ll_i2sbi(inode)->ll_md_exp, op_data, NULL, 0, &req); - ll_finish_md_op_data(op_data); - ptlrpc_req_finished(req); - if (rc) - return rc; - + dentry = (struct dentry *)fs_data; rc = ll_vfs_setxattr(dentry, inode, LL_XATTR_NAME_ENCRYPTION_CONTEXT, ctx, len, XATTR_CREATE); if (rc) return rc; - ll_update_inode_flags(inode, ext_flags); - return 0; + return ll_set_encflags(inode, (void *)ctx, len, false); } -inline bool ll_sbi_has_test_dummy_encryption(struct ll_sb_info *sbi) +void llcrypt_free_ctx(void *encctx, __u32 size) +{ + if (encctx) + OBD_FREE(encctx, size); +} + +bool ll_sbi_has_test_dummy_encryption(struct ll_sb_info *sbi) { return unlikely(sbi->ll_flags & LL_SBI_TEST_DUMMY_ENCRYPTION); } @@ -101,12 +131,12 @@ static bool ll_dummy_context(struct inode *inode) return sbi ? ll_sbi_has_test_dummy_encryption(sbi) : false; } -inline bool ll_sbi_has_encrypt(struct ll_sb_info *sbi) +bool ll_sbi_has_encrypt(struct ll_sb_info *sbi) { return sbi->ll_flags & LL_SBI_ENCRYPT; } -inline void ll_sbi_set_encrypt(struct ll_sb_info *sbi, bool set) +void ll_sbi_set_encrypt(struct ll_sb_info *sbi, bool set) { if (set) sbi->ll_flags |= LL_SBI_ENCRYPT; @@ -136,17 +166,27 @@ const struct llcrypt_operations lustre_cryptops = { .max_namelen = NAME_MAX, }; #else /* !HAVE_LUSTRE_CRYPTO */ -inline bool ll_sbi_has_test_dummy_encryption(struct ll_sb_info *sbi) +int ll_set_encflags(struct inode *inode, void *encctx, __u32 encctxlen, + bool preload) +{ + return 0; +} + +void llcrypt_free_ctx(void *encctx, __u32 size) +{ +} + +bool ll_sbi_has_test_dummy_encryption(struct ll_sb_info *sbi) { return false; } -inline bool ll_sbi_has_encrypt(struct ll_sb_info *sbi) +bool ll_sbi_has_encrypt(struct ll_sb_info *sbi) { return false; } -inline void ll_sbi_set_encrypt(struct ll_sb_info *sbi, bool set) +void ll_sbi_set_encrypt(struct ll_sb_info *sbi, bool set) { } #endif