1/**
2 * xattr.h
3 *
4 * Many parts of codes are copied from Linux kernel/fs/f2fs.
5 *
6 * Copyright (C) 2015 Huawei Ltd.
7 * Witten by:
8 *   Hou Pengyang <houpengyang@huawei.com>
9 *   Liu Shuoran <liushuoran@huawei.com>
10 *   Jaegeuk Kim <jaegeuk@kernel.org>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16#ifndef _XATTR_H_
17#define _XATTR_H_
18
19#include "f2fs.h"
20#ifdef HAVE_SYS_XATTR_H
21#include <sys/xattr.h>
22#endif
23
24struct f2fs_xattr_header {
25	__le32 h_magic;		/* magic number for identification */
26	__le32 h_refcount;	/* reference count */
27	__u32 h_sloadd[4];	/* zero right now */
28};
29
30struct f2fs_xattr_entry {
31	__u8 e_name_index;
32	__u8 e_name_len;
33	__le16 e_value_size;	/* size of attribute value */
34	char e_name[0];		/* attribute name */
35};
36
37#define FS_KEY_DESCRIPTOR_SIZE 8
38#define FS_KEY_DERIVATION_NONCE_SIZE 16
39
40struct fscrypt_context {
41	u8 format;
42	u8 contents_encryption_mode;
43	u8 filenames_encryption_mode;
44	u8 flags;
45	u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
46	u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
47} __attribute__((packed));
48
49#define F2FS_ACL_VERSION	0x0001
50
51struct f2fs_acl_entry {
52	__le16 e_tag;
53	__le16 e_perm;
54	__le32 e_id;
55};
56
57struct f2fs_acl_entry_short {
58	__le16 e_tag;
59	__le16 e_perm;
60};
61
62struct f2fs_acl_header {
63	__le32 a_version;
64};
65
66static inline int f2fs_acl_count(int size)
67{
68	ssize_t s;
69	size -= sizeof(struct f2fs_acl_header);
70	s = size - 4 * sizeof(struct f2fs_acl_entry_short);
71	if (s < 0) {
72		if (size % sizeof(struct f2fs_acl_entry_short))
73			return -1;
74		return size / sizeof(struct f2fs_acl_entry_short);
75	} else {
76		if (s % sizeof(struct f2fs_acl_entry))
77			return -1;
78		return s / sizeof(struct f2fs_acl_entry) + 4;
79	}
80}
81
82#ifndef XATTR_USER_PREFIX
83#define XATTR_USER_PREFIX	"user."
84#endif
85#ifndef XATTR_SECURITY_PREFIX
86#define XATTR_SECURITY_PREFIX	"security."
87#endif
88#ifndef XATTR_TRUSTED_PREFIX
89#define XATTR_TRUSTED_PREFIX	"trusted."
90#endif
91
92#ifndef XATTR_CREATE
93#define XATTR_CREATE 0x1
94#endif
95#ifndef XATTR_REPLACE
96#define XATTR_REPLACE 0x2
97#endif
98
99#define XATTR_ROUND	(3)
100
101#define XATTR_SELINUX_SUFFIX "selinux"
102#define F2FS_XATTR_INDEX_USER			1
103#define F2FS_XATTR_INDEX_POSIX_ACL_ACCESS	2
104#define F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT	3
105#define F2FS_XATTR_INDEX_TRUSTED		4
106#define F2FS_XATTR_INDEX_LUSTRE			5
107#define F2FS_XATTR_INDEX_SECURITY		6
108#define F2FS_XATTR_INDEX_ENCRYPTION		9
109
110#define IS_XATTR_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
111
112#define XATTR_HDR(ptr)		((struct f2fs_xattr_header *)(ptr))
113#define XATTR_ENTRY(ptr) 	((struct f2fs_xattr_entry *)(ptr))
114#define F2FS_XATTR_MAGIC	0xF2F52011
115
116#define XATTR_NEXT_ENTRY(entry) ((struct f2fs_xattr_entry *) ((char *)(entry) +\
117					ENTRY_SIZE(entry)))
118#define XATTR_FIRST_ENTRY(ptr)	(XATTR_ENTRY(XATTR_HDR(ptr) + 1))
119
120#define XATTR_ALIGN(size)	((size + XATTR_ROUND) & ~XATTR_ROUND)
121
122#define ENTRY_SIZE(entry) (XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) + \
123			entry->e_name_len + le16_to_cpu(entry->e_value_size)))
124
125#define list_for_each_xattr(entry, addr) \
126	for (entry = XATTR_FIRST_ENTRY(addr); \
127			!IS_XATTR_LAST_ENTRY(entry); \
128			entry = XATTR_NEXT_ENTRY(entry))
129
130#define MIN_OFFSET	XATTR_ALIGN(PAGE_SIZE -			\
131		sizeof(struct node_footer) - sizeof(__u32))
132
133#define MAX_VALUE_LEN	(MIN_OFFSET -				\
134		sizeof(struct f2fs_xattr_header) -		\
135		sizeof(struct f2fs_xattr_entry))
136
137#endif
138