| /** |
| * xattr.h |
| * |
| * Many parts of codes are copied from Linux kernel/fs/f2fs. |
| * |
| * Copyright (C) 2015 Huawei Ltd. |
| * Witten by: |
| * Hou Pengyang <houpengyang@huawei.com> |
| * Liu Shuoran <liushuoran@huawei.com> |
| * Jaegeuk Kim <jaegeuk@kernel.org> |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| */ |
| #ifndef _XATTR_H_ |
| #define _XATTR_H_ |
| |
| #include "f2fs.h" |
| #ifdef HAVE_SYS_XATTR_H |
| #include <sys/xattr.h> |
| #endif |
| |
| struct f2fs_xattr_header { |
| __le32 h_magic; /* magic number for identification */ |
| __le32 h_refcount; /* reference count */ |
| __u32 h_sloadd[4]; /* zero right now */ |
| }; |
| |
| struct f2fs_xattr_entry { |
| __u8 e_name_index; |
| __u8 e_name_len; |
| __le16 e_value_size; /* size of attribute value */ |
| char e_name[0]; /* attribute name */ |
| }; |
| |
| #define FSCRYPT_CONTEXT_V1 1 |
| #define FSCRYPT_CONTEXT_V2 2 |
| #ifndef FSCRYPT_KEY_DESCRIPTOR_SIZE |
| #define FSCRYPT_KEY_DESCRIPTOR_SIZE 8 |
| #endif |
| #ifndef FSCRYPT_KEY_IDENTIFIER_SIZE |
| #define FSCRYPT_KEY_IDENTIFIER_SIZE 16 |
| #endif |
| #define FSCRYPT_FILE_NONCE_SIZE 16 |
| #define F2FS_XATTR_NAME_ENCRYPTION_CONTEXT "c" |
| |
| struct fscrypt_context_v1 { |
| u8 version; /* FSCRYPT_CONTEXT_V1 */ |
| u8 contents_encryption_mode; |
| u8 filenames_encryption_mode; |
| u8 flags; |
| u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; |
| u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; |
| }; |
| |
| struct fscrypt_context_v2 { |
| u8 version; /* FSCRYPT_CONTEXT_V2 */ |
| u8 contents_encryption_mode; |
| u8 filenames_encryption_mode; |
| u8 flags; |
| u8 __reserved[4]; |
| u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; |
| u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; |
| }; |
| |
| union fscrypt_context { |
| u8 version; |
| struct fscrypt_context_v1 v1; |
| struct fscrypt_context_v2 v2; |
| }; |
| |
| static_assert(sizeof(struct fscrypt_context_v1) == 28, ""); |
| static_assert(sizeof(struct fscrypt_context_v2) == 40, ""); |
| |
| /* |
| * Return the size expected for the given fscrypt_context based on its version |
| * number, or 0 if the context version is unrecognized. |
| */ |
| static inline int fscrypt_context_size(const union fscrypt_context *ctx) |
| { |
| switch (ctx->version) { |
| case FSCRYPT_CONTEXT_V1: |
| return sizeof(ctx->v1); |
| case FSCRYPT_CONTEXT_V2: |
| return sizeof(ctx->v2); |
| default: |
| MSG(0, "Unsupported fscrypt_context format!\n"); |
| } |
| return 0; |
| } |
| |
| struct fsverity_descriptor_location { |
| __le32 version; |
| __le32 size; |
| __le64 pos; |
| }; |
| |
| static_assert(sizeof(struct fsverity_descriptor_location) == 16, ""); |
| |
| #define F2FS_ACL_VERSION 0x0001 |
| |
| struct f2fs_acl_entry { |
| __le16 e_tag; |
| __le16 e_perm; |
| __le32 e_id; |
| }; |
| |
| struct f2fs_acl_entry_short { |
| __le16 e_tag; |
| __le16 e_perm; |
| }; |
| |
| struct f2fs_acl_header { |
| __le32 a_version; |
| }; |
| |
| static inline int f2fs_acl_count(int size) |
| { |
| ssize_t s; |
| size -= sizeof(struct f2fs_acl_header); |
| s = size - 4 * sizeof(struct f2fs_acl_entry_short); |
| if (s < 0) { |
| if (size % sizeof(struct f2fs_acl_entry_short)) |
| return -1; |
| return size / sizeof(struct f2fs_acl_entry_short); |
| } else { |
| if (s % sizeof(struct f2fs_acl_entry)) |
| return -1; |
| return s / sizeof(struct f2fs_acl_entry) + 4; |
| } |
| } |
| |
| #ifndef XATTR_USER_PREFIX |
| #define XATTR_USER_PREFIX "user." |
| #endif |
| #ifndef XATTR_SECURITY_PREFIX |
| #define XATTR_SECURITY_PREFIX "security." |
| #endif |
| #ifndef XATTR_TRUSTED_PREFIX |
| #define XATTR_TRUSTED_PREFIX "trusted." |
| #endif |
| |
| #ifndef XATTR_CREATE |
| #define XATTR_CREATE 0x1 |
| #endif |
| #ifndef XATTR_REPLACE |
| #define XATTR_REPLACE 0x2 |
| #endif |
| |
| #define XATTR_ROUND (3) |
| |
| #define XATTR_SELINUX_SUFFIX "selinux" |
| #define F2FS_XATTR_INDEX_USER 1 |
| #define F2FS_XATTR_INDEX_POSIX_ACL_ACCESS 2 |
| #define F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT 3 |
| #define F2FS_XATTR_INDEX_TRUSTED 4 |
| #define F2FS_XATTR_INDEX_LUSTRE 5 |
| #define F2FS_XATTR_INDEX_SECURITY 6 |
| #define F2FS_XATTR_INDEX_ENCRYPTION 9 |
| #define F2FS_XATTR_INDEX_VERITY 11 |
| |
| #define F2FS_XATTR_NAME_VERITY "v" |
| |
| #define IS_XATTR_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) |
| |
| #define XATTR_HDR(ptr) ((struct f2fs_xattr_header *)(ptr)) |
| #define XATTR_ENTRY(ptr) ((struct f2fs_xattr_entry *)(ptr)) |
| #define F2FS_XATTR_MAGIC 0xF2F52011 |
| |
| #define XATTR_NEXT_ENTRY(entry) ((struct f2fs_xattr_entry *) ((char *)(entry) +\ |
| ENTRY_SIZE(entry))) |
| #define XATTR_FIRST_ENTRY(ptr) (XATTR_ENTRY(XATTR_HDR(ptr) + 1)) |
| |
| #define XATTR_ALIGN(size) ((size + XATTR_ROUND) & ~XATTR_ROUND) |
| |
| #define ENTRY_SIZE(entry) (XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) + \ |
| entry->e_name_len + le16_to_cpu(entry->e_value_size))) |
| |
| #define list_for_each_xattr(entry, addr) \ |
| for (entry = XATTR_FIRST_ENTRY(addr); \ |
| !IS_XATTR_LAST_ENTRY(entry); \ |
| entry = XATTR_NEXT_ENTRY(entry)) |
| |
| #define VALID_XATTR_BLOCK_SIZE (F2FS_BLKSIZE - sizeof(struct node_footer)) |
| |
| #define XATTR_SIZE(i) ((le32_to_cpu((i)->i_xattr_nid) ? \ |
| VALID_XATTR_BLOCK_SIZE : 0) + \ |
| (inline_xattr_size(i))) |
| |
| #define MIN_OFFSET XATTR_ALIGN(F2FS_BLKSIZE - \ |
| sizeof(struct node_footer) - sizeof(__u32)) |
| |
| #define MAX_VALUE_LEN (MIN_OFFSET - \ |
| sizeof(struct f2fs_xattr_header) - \ |
| sizeof(struct f2fs_xattr_entry)) |
| |
| #define MAX_INLINE_XATTR_SIZE \ |
| (DEF_ADDRS_PER_INODE - \ |
| F2FS_TOTAL_EXTRA_ATTR_SIZE / sizeof(__le32) - \ |
| DEF_INLINE_RESERVED_SIZE - \ |
| MIN_INLINE_DENTRY_SIZE / sizeof(__le32)) |
| #endif |