blob: 95c11b46e02c1cbc914671867d8571b937d6bcd4 [file] [log] [blame]
/**
* sdp_xattr.c
*
* get/set sdp context to xattr
*/
#include "fscrypto_sdp_xattr_private.h"
#include <linux/xattr.h>
#define FSCRYPT_SDP_FS_TYPE_EXT4_STR "ext4"
#define FSCRYPT_SDP_FS_TYPE_F2FS_STR "f2fs"
#define FSCRYPT_SDP_XATTR_NAME_ENCRYPTION_SDP_CONTEXT "sdp"
//Must sync with ext4/xattr.h
#define FSCRYPT_SDP_EXT4_XATTR_INDEX_ENCRYPTION 9
extern int ext4_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t);
//Must sync with f2fs/xattr.h
#define FSCRYPT_SDP_F2FS_XATTR_INDEX_ENCRYPTION 9
#ifdef CONFIG_F2FS_FS_XATTR
extern int f2fs_setxattr(struct inode *, int, const char *,
const void *, size_t, struct page *, int);
extern int f2fs_getxattr(struct inode *, int, const char *, void *,
size_t, struct page *);
#else
static inline int f2fs_setxattr(struct inode *inode, int index,
const char *name, const void *value, size_t size,
struct page *page, int flags)
{
return -EOPNOTSUPP;
}
static inline int f2fs_getxattr(struct inode *inode, int index,
const char *name, void *buffer,
size_t buffer_size, struct page *dpage)
{
return -EOPNOTSUPP;
}
#endif
int fscrypt_sdp_get_context(struct inode *inode, void *ctx, size_t len)
{
const char *fs_type_name = inode->i_mapping->host->i_sb->s_type->name;
if (!strcmp(FSCRYPT_SDP_FS_TYPE_EXT4_STR, fs_type_name)) {
return ext4_xattr_get(inode, FSCRYPT_SDP_EXT4_XATTR_INDEX_ENCRYPTION,
FSCRYPT_SDP_XATTR_NAME_ENCRYPTION_SDP_CONTEXT, ctx, len);
} else if (!strcmp(FSCRYPT_SDP_FS_TYPE_F2FS_STR, fs_type_name)) {
return f2fs_getxattr(inode, FSCRYPT_SDP_F2FS_XATTR_INDEX_ENCRYPTION,
FSCRYPT_SDP_XATTR_NAME_ENCRYPTION_SDP_CONTEXT, ctx, len, NULL);
}
return -ENOTTY;
}
static int __fscrypt_sdp_set_context(struct inode *inode, void *ctx, size_t len, bool is_lock)
{
int retval = -ENOTTY;
const char *fs_type_name = inode->i_mapping->host->i_sb->s_type->name;
if (is_lock) inode_lock(inode);
if (!strcmp(FSCRYPT_SDP_FS_TYPE_EXT4_STR, fs_type_name)) {
retval = ext4_xattr_set(inode, FSCRYPT_SDP_EXT4_XATTR_INDEX_ENCRYPTION,
FSCRYPT_SDP_XATTR_NAME_ENCRYPTION_SDP_CONTEXT, ctx, len, 0);
} else if (!strcmp(FSCRYPT_SDP_FS_TYPE_F2FS_STR, fs_type_name)) {
retval = f2fs_setxattr(inode, FSCRYPT_SDP_F2FS_XATTR_INDEX_ENCRYPTION,
FSCRYPT_SDP_XATTR_NAME_ENCRYPTION_SDP_CONTEXT, ctx, len, 0, XATTR_CREATE);
}
if (is_lock) inode_unlock(inode);
return retval;
}
int fscrypt_sdp_set_context(struct inode *inode, void *ctx, size_t len)
{
return __fscrypt_sdp_set_context(inode, ctx, len, true);
}
int fscrypt_sdp_set_context_nolock(struct inode *inode, void *ctx, size_t len)
{
return __fscrypt_sdp_set_context(inode, ctx, len, false);
}