@@ -32,6 +32,7 @@
static int ll_get_context(struct inode *inode, void *ctx, size_t len)
{
struct dentry *dentry;
+ int rc;
if (hlist_empty(&inode->i_dentry))
return -ENODATA;
@@ -39,8 +40,13 @@ static int ll_get_context(struct inode *inode, void *ctx, size_t len)
hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias)
break;
- return __vfs_getxattr(dentry, inode, LL_XATTR_NAME_ENCRYPTION_CONTEXT,
- ctx, len);
+ rc = __vfs_getxattr(dentry, inode, LL_XATTR_NAME_ENCRYPTION_CONTEXT,
+ ctx, len);
+
+ /* used as encryption unit size */
+ if (S_ISREG(inode->i_mode))
+ inode->i_blkbits = LUSTRE_ENCRYPTION_BLOCKBITS;
+ return rc;
}
static int ll_set_context(struct inode *inode, const void *ctx, size_t len,
@@ -714,6 +714,12 @@ int ll_file_open(struct inode *inode, struct file *file)
it = file->private_data; /* XXX: compat macro */
file->private_data = NULL; /* prevent ll_local_open assertion */
+ if (S_ISREG(inode->i_mode)) {
+ rc = llcrypt_file_open(inode, file);
+ if (rc)
+ goto out_nofiledata;
+ }
+
fd = ll_file_data_get();
if (!fd) {
rc = -ENOMEM;
@@ -1865,6 +1865,7 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
const char *obd_name = cli->cl_import->imp_obd->obd_name;
struct ost_body *body;
u32 client_cksum = 0;
+ struct inode *inode;
if (rc < 0 && rc != -EDQUOT) {
DEBUG_REQ(D_INFO, req, "Failed request: rc = %d", rc);
@@ -2055,6 +2056,36 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
} else {
rc = 0;
}
+
+ inode = page2inode(aa->aa_ppga[0]->pg);
+ if (inode && IS_ENCRYPTED(inode)) {
+ int idx;
+
+ if (!llcrypt_has_encryption_key(inode)) {
+ CDEBUG(D_SEC, "no enc key for ino %lu\n", inode->i_ino);
+ goto out;
+ }
+ for (idx = 0; idx < aa->aa_page_count; idx++) {
+ struct brw_page *pg = aa->aa_ppga[idx];
+ u64 *p, *q;
+
+ /* do not decrypt if page is all 0s */
+ p = q = page_address(pg->pg);
+ while (p - q < PAGE_SIZE / sizeof(*p)) {
+ if (*p != 0)
+ break;
+ p++;
+ }
+ if (p - q == PAGE_SIZE / sizeof(*p))
+ continue;
+
+ rc = llcrypt_decrypt_pagecache_blocks(pg->pg,
+ PAGE_SIZE, 0);
+ if (rc)
+ goto out;
+ }
+ }
+
out:
if (rc >= 0)
lustre_get_wire_obdo(&req->rq_import->imp_connect_data,