1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/ceph/ceph_debug.h>
3 #include <linux/xattr.h>
4 #include <linux/fscrypt.h>
9 static int ceph_crypt_get_context(struct inode *inode, void *ctx, size_t len)
11 struct ceph_inode_info *ci = ceph_inode(inode);
12 struct ceph_fscrypt_auth *cfa = (struct ceph_fscrypt_auth *)ci->fscrypt_auth;
15 /* Non existent or too short? */
16 if (!cfa || (ci->fscrypt_auth_len < (offsetof(struct ceph_fscrypt_auth, cfa_blob) + 1)))
19 /* Some format we don't recognize? */
20 if (le32_to_cpu(cfa->cfa_version) != CEPH_FSCRYPT_AUTH_VERSION)
23 ctxlen = le32_to_cpu(cfa->cfa_blob_len);
27 memcpy(ctx, cfa->cfa_blob, ctxlen);
31 static int ceph_crypt_set_context(struct inode *inode, const void *ctx,
32 size_t len, void *fs_data)
35 struct iattr attr = { };
36 struct ceph_iattr cia = { };
37 struct ceph_fscrypt_auth *cfa;
39 WARN_ON_ONCE(fs_data);
41 if (len > FSCRYPT_SET_CONTEXT_MAX_SIZE)
44 cfa = kzalloc(sizeof(*cfa), GFP_KERNEL);
48 cfa->cfa_version = cpu_to_le32(CEPH_FSCRYPT_AUTH_VERSION);
49 cfa->cfa_blob_len = cpu_to_le32(len);
50 memcpy(cfa->cfa_blob, ctx, len);
52 cia.fscrypt_auth = cfa;
54 ret = __ceph_setattr(inode, &attr, &cia);
56 inode_set_flags(inode, S_ENCRYPTED, S_ENCRYPTED);
57 kfree(cia.fscrypt_auth);
61 static bool ceph_crypt_empty_dir(struct inode *inode)
63 struct ceph_inode_info *ci = ceph_inode(inode);
65 return ci->i_rsubdirs + ci->i_rfiles == 1;
68 static struct fscrypt_operations ceph_fscrypt_ops = {
69 .get_context = ceph_crypt_get_context,
70 .set_context = ceph_crypt_set_context,
71 .empty_dir = ceph_crypt_empty_dir,
74 void ceph_fscrypt_set_ops(struct super_block *sb)
76 fscrypt_set_ops(sb, &ceph_fscrypt_ops);