1141085Simp/*-
285845Srwatson * Copyright (c) 1999-2001 Robert N. M. Watson
359241Srwatson * All rights reserved.
459241Srwatson *
585845Srwatson * This software was developed by Robert Watson for the TrustedBSD Project.
685845Srwatson *
759241Srwatson * Redistribution and use in source and binary forms, with or without
859241Srwatson * modification, are permitted provided that the following conditions
959241Srwatson * are met:
1059241Srwatson * 1. Redistributions of source code must retain the above copyright
1159241Srwatson *    notice, this list of conditions and the following disclaimer.
1259241Srwatson * 2. Redistributions in binary form must reproduce the above copyright
1359241Srwatson *    notice, this list of conditions and the following disclaimer in the
1459241Srwatson *    documentation and/or other materials provided with the distribution.
1559241Srwatson *
1659241Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1759241Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1859241Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1959241Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2059241Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2159241Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2259241Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2359241Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2459241Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2559241Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2659241Srwatson * SUCH DAMAGE.
2759241Srwatson *
2866616Srwatson * $FreeBSD$
2959241Srwatson */
3059241Srwatson/*
3185845Srwatson * Developed by the TrustedBSD Project.
3296755Strhodes * Support for extended filesystem attributes.
3359241Srwatson */
3459241Srwatson
3559241Srwatson#ifndef _UFS_UFS_EXTATTR_H_
3659241Srwatson#define	_UFS_UFS_EXTATTR_H_
3759241Srwatson
3859400Srwatson#define	UFS_EXTATTR_MAGIC		0x00b5d5ec
3965377Srwatson#define	UFS_EXTATTR_VERSION		0x00000003
4059400Srwatson#define	UFS_EXTATTR_FSROOTSUBDIR	".attribute"
4174404Srwatson#define	UFS_EXTATTR_SUBDIR_SYSTEM	"system"
4274404Srwatson#define	UFS_EXTATTR_SUBDIR_USER		"user"
4359400Srwatson#define	UFS_EXTATTR_MAXEXTATTRNAME	65	/* including null */
4459241Srwatson
4559241Srwatson#define	UFS_EXTATTR_ATTR_FLAG_INUSE	0x00000001	/* attr has been set */
4659241Srwatson#define	UFS_EXTATTR_PERM_KERNEL		0x00000000
4759241Srwatson#define	UFS_EXTATTR_PERM_ROOT		0x00000001
4859241Srwatson#define	UFS_EXTATTR_PERM_OWNER		0x00000002
4959241Srwatson#define	UFS_EXTATTR_PERM_ANYONE		0x00000003
5059241Srwatson
5159241Srwatson#define	UFS_EXTATTR_UEPM_INITIALIZED	0x00000001
5259241Srwatson#define	UFS_EXTATTR_UEPM_STARTED	0x00000002
5359241Srwatson
5459241Srwatson#define	UFS_EXTATTR_CMD_START		0x00000001
5559241Srwatson#define	UFS_EXTATTR_CMD_STOP		0x00000002
5659241Srwatson#define	UFS_EXTATTR_CMD_ENABLE		0x00000003
5759241Srwatson#define	UFS_EXTATTR_CMD_DISABLE		0x00000004
5859241Srwatson
5959241Srwatsonstruct ufs_extattr_fileheader {
6059400Srwatson	u_int	uef_magic;	/* magic number for sanity checking */
6159400Srwatson	u_int	uef_version;	/* version of attribute file */
6259241Srwatson	u_int	uef_size;	/* size of attributes, w/o header */
6359241Srwatson};
6459241Srwatson
6559241Srwatsonstruct ufs_extattr_header {
6659241Srwatson	u_int	ueh_flags;	/* flags for attribute */
6759241Srwatson	u_int	ueh_len;	/* local defined length; <= uef_size */
6859388Srwatson	u_int32_t	ueh_i_gen;	/* generation number for sanity */
6959241Srwatson	/* data follows the header */
7059241Srwatson};
7159241Srwatson
72167259Smckusick/*
73167259Smckusick * This structure defines the required fields of an extended-attribute header.
74167259Smckusick */
75167259Smckusickstruct extattr {
76167259Smckusick	int32_t	ea_length;	    /* length of this attribute */
77167259Smckusick	int8_t	ea_namespace;	    /* name space of this attribute */
78167259Smckusick	int8_t	ea_contentpadlen;   /* bytes of padding at end of attribute */
79167259Smckusick	int8_t	ea_namelength;	    /* length of attribute name */
80167259Smckusick	char	ea_name[1];	    /* null-terminated attribute name */
81167259Smckusick	/* extended attribute content follows */
82167259Smckusick};
83167259Smckusick
84167259Smckusick/*
85167259Smckusick * These macros are used to access and manipulate an extended attribute:
86167259Smckusick *
87167259Smckusick * EXTATTR_NEXT(eap) returns a pointer to the next extended attribute
88167259Smckusick *	following eap.
89167259Smckusick * EXTATTR_CONTENT(eap) returns a pointer to the extended attribute
90167259Smckusick *	content referenced by eap.
91167259Smckusick * EXTATTR_CONTENT_SIZE(eap) returns the size of the extended attribute
92167259Smckusick *	content referenced by eap.
93167259Smckusick * EXTATTR_SET_LENGTHS(eap, contentsize) called after initializing the
94167259Smckusick *	attribute name to calculate and set the ea_length, ea_namelength,
95167259Smckusick *	and ea_contentpadlen fields of the extended attribute structure.
96167259Smckusick */
97167259Smckusick#define EXTATTR_NEXT(eap) \
98167259Smckusick	((struct extattr *)(((void *)(eap)) + (eap)->ea_length))
99167259Smckusick#define EXTATTR_CONTENT(eap) (((void *)(eap)) + EXTATTR_BASE_LENGTH(eap))
100167259Smckusick#define EXTATTR_CONTENT_SIZE(eap) \
101167259Smckusick	((eap)->ea_length - EXTATTR_BASE_LENGTH(eap) - (eap)->ea_contentpadlen)
102167259Smckusick#define EXTATTR_BASE_LENGTH(eap) \
103167259Smckusick	((sizeof(struct extattr) + (eap)->ea_namelength + 7) & ~7)
104167259Smckusick#define EXTATTR_SET_LENGTHS(eap, contentsize) do { \
105167259Smckusick	KASSERT(((eap)->ea_name[0] != 0), \
106167259Smckusick		("Must initialize name before setting lengths")); \
107167259Smckusick	(eap)->ea_namelength = strlen((eap)->ea_name); \
108167259Smckusick	(eap)->ea_contentpadlen = ((contentsize) % 8) ? \
109167259Smckusick		8 - ((contentsize) % 8) : 0; \
110167259Smckusick	(eap)->ea_length = EXTATTR_BASE_LENGTH(eap) + \
111167259Smckusick		(contentsize) + (eap)->ea_contentpadlen; \
112167259Smckusick} while (0)
113167259Smckusick
11459241Srwatson#ifdef _KERNEL
11559241Srwatson
116176797Srwatson#include <sys/_sx.h>
117176797Srwatson
11859241Srwatsonstruct vnode;
11960938SjakeLIST_HEAD(ufs_extattr_list_head, ufs_extattr_list_entry);
12059241Srwatsonstruct ufs_extattr_list_entry {
12174273Srwatson	LIST_ENTRY(ufs_extattr_list_entry)	uele_entries;
12274273Srwatson	struct ufs_extattr_fileheader		uele_fileheader;
12374437Srwatson	int	uele_attrnamespace;
12459241Srwatson	char	uele_attrname[UFS_EXTATTR_MAXEXTATTRNAME];
12559241Srwatson	struct vnode	*uele_backing_vnode;
12659241Srwatson};
12759241Srwatson
12859241Srwatsonstruct ucred;
12959241Srwatsonstruct ufs_extattr_per_mount {
130176797Srwatson	struct sx	uepm_lock;
13159241Srwatson	struct ufs_extattr_list_head	uepm_list;
13259241Srwatson	struct ucred	*uepm_ucred;
13359241Srwatson	int	uepm_flags;
13459241Srwatson};
13559241Srwatson
13659241Srwatsonvoid	ufs_extattr_uepm_init(struct ufs_extattr_per_mount *uepm);
13766616Srwatsonvoid	ufs_extattr_uepm_destroy(struct ufs_extattr_per_mount *uepm);
13883366Sjulianint	ufs_extattr_start(struct mount *mp, struct thread *td);
13983366Sjulianint	ufs_extattr_autostart(struct mount *mp, struct thread *td);
14083366Sjulianint	ufs_extattr_stop(struct mount *mp, struct thread *td);
14174273Srwatsonint	ufs_extattrctl(struct mount *mp, int cmd, struct vnode *filename,
142191990Sattilio	    int attrnamespace, const char *attrname);
14395974Sphkint	ufs_getextattr(struct vop_getextattr_args *ap);
144118131Srwatsonint	ufs_deleteextattr(struct vop_deleteextattr_args *ap);
14595974Sphkint	ufs_setextattr(struct vop_setextattr_args *ap);
14683366Sjulianvoid	ufs_extattr_vnode_inactive(struct vnode *vp, struct thread *td);
14759241Srwatson
148167259Smckusick#else
149167259Smckusick
150167259Smckusick/* User-level definition of KASSERT for macros above */
151167259Smckusick#define KASSERT(cond, str) do { \
152167259Smckusick        if (!(cond)) { printf("panic: "); printf(str); printf("\n"); exit(1); }\
153167259Smckusick} while (0)
154167259Smckusick
15559241Srwatson#endif /* !_KERNEL */
15659241Srwatson
15759241Srwatson#endif /* !_UFS_UFS_EXTATTR_H_ */
158