ext2.h revision 919f9c41
163db34c8SAxel Dörfler/*
2275463f4SAxel Dörfler * Copyright 2008-2010, Axel D��rfler, axeld@pinc-software.de.
363db34c8SAxel Dörfler * Distributed under the terms of the MIT License.
463db34c8SAxel Dörfler */
563db34c8SAxel Dörfler#ifndef EXT2_H
663db34c8SAxel Dörfler#define EXT2_H
763db34c8SAxel Dörfler
863db34c8SAxel Dörfler
90680840aSAxel Dörfler#include <sys/stat.h>
100680840aSAxel Dörfler
1163db34c8SAxel Dörfler#include <ByteOrder.h>
1263db34c8SAxel Dörfler#include <fs_interface.h>
13b026d219SFrançois Revol#include <KernelExport.h>
1463db34c8SAxel Dörfler
1563db34c8SAxel Dörfler
1663db34c8SAxel Dörfler#define EXT2_SUPER_BLOCK_OFFSET	1024
1763db34c8SAxel Dörfler
1863db34c8SAxel Dörflerstruct ext2_super_block {
1963db34c8SAxel Dörfler	uint32	num_inodes;
2063db34c8SAxel Dörfler	uint32	num_blocks;
2163db34c8SAxel Dörfler	uint32	reserved_blocks;
2263db34c8SAxel Dörfler	uint32	free_blocks;
2363db34c8SAxel Dörfler	uint32	free_inodes;
2463db34c8SAxel Dörfler	uint32	first_data_block;
2563db34c8SAxel Dörfler	uint32	block_shift;
2663db34c8SAxel Dörfler	uint32	fragment_shift;
2763db34c8SAxel Dörfler	uint32	blocks_per_group;
2863db34c8SAxel Dörfler	uint32	fragments_per_group;
2963db34c8SAxel Dörfler	uint32	inodes_per_group;
3063db34c8SAxel Dörfler	uint32	mount_time;
3163db34c8SAxel Dörfler	uint32	write_time;
3263db34c8SAxel Dörfler	uint16	mount_count;
3363db34c8SAxel Dörfler	uint16	max_mount_count;
3463db34c8SAxel Dörfler	uint16	magic;
3563db34c8SAxel Dörfler	uint16	state;
3663db34c8SAxel Dörfler	uint16	error_handling;
3763db34c8SAxel Dörfler	uint16	minor_revision_level;
3863db34c8SAxel Dörfler	uint32	last_check_time;
3963db34c8SAxel Dörfler	uint32	check_interval;
4063db34c8SAxel Dörfler	uint32	creator_os;
4163db34c8SAxel Dörfler	uint32	revision_level;
4263db34c8SAxel Dörfler	uint16	reserved_blocks_uid;
4363db34c8SAxel Dörfler	uint16	reserved_blocks_gid;
4463db34c8SAxel Dörfler	uint32	first_inode;
4563db34c8SAxel Dörfler	uint16	inode_size;
4663db34c8SAxel Dörfler	uint16	block_group;
4763db34c8SAxel Dörfler	uint32	compatible_features;
4863db34c8SAxel Dörfler	uint32	incompatible_features;
4913de3d07SAxel Dörfler	uint32	read_only_features;
5063db34c8SAxel Dörfler	uint8	uuid[16];
5163db34c8SAxel Dörfler	char	name[16];
5263db34c8SAxel Dörfler	char	last_mount_point[64];
5363db34c8SAxel Dörfler	uint32	algorithm_usage_bitmap;
5463db34c8SAxel Dörfler	uint8	preallocated_blocks;
5563db34c8SAxel Dörfler	uint8	preallocated_directory_blocks;
5663db34c8SAxel Dörfler	uint16	_padding;
5713de3d07SAxel Dörfler
5863db34c8SAxel Dörfler	// journaling ext3 support
5963db34c8SAxel Dörfler	uint8	journal_uuid[16];
6063db34c8SAxel Dörfler	uint32	journal_inode;
6163db34c8SAxel Dörfler	uint32	journal_device;
6263db34c8SAxel Dörfler	uint32	last_orphan;
6363db34c8SAxel Dörfler	uint32	hash_seed[4];
6463db34c8SAxel Dörfler	uint8	default_hash_version;
6563db34c8SAxel Dörfler	uint8	_reserved1;
6663db34c8SAxel Dörfler	uint16	_reserved2;
6763db34c8SAxel Dörfler	uint32	default_mount_options;
6863db34c8SAxel Dörfler	uint32	first_meta_block_group;
69275463f4SAxel Dörfler	uint32	fs_creation_time;
70275463f4SAxel Dörfler	uint32	journal_inode_backup[17];
71275463f4SAxel Dörfler
72275463f4SAxel Dörfler	// ext4 support
73275463f4SAxel Dörfler	uint32	num_blocks_hi;
74275463f4SAxel Dörfler	uint32	reserved_blocks_hi;
75275463f4SAxel Dörfler	uint32	free_blocks_hi;
76275463f4SAxel Dörfler	uint16	min_inode_size;
77275463f4SAxel Dörfler	uint16	want_inode_size;
78275463f4SAxel Dörfler	uint32	flags;
79275463f4SAxel Dörfler	uint16	raid_stride;
80275463f4SAxel Dörfler	uint16	mmp_interval;
81275463f4SAxel Dörfler	uint64	mmp_block;
82275463f4SAxel Dörfler	uint32	raid_stripe_width;
83275463f4SAxel Dörfler	uint8	groups_per_flex_shift;
84275463f4SAxel Dörfler	uint8	_reserved3;
85275463f4SAxel Dörfler	uint16	_reserved4;
86275463f4SAxel Dörfler	uint32	_reserved5[162];
8763db34c8SAxel Dörfler
8863db34c8SAxel Dörfler	uint16 Magic() const { return B_LENDIAN_TO_HOST_INT16(magic); }
89919f9c41SJérôme Duval	uint16 State() const { return B_LENDIAN_TO_HOST_INT16(state); }
90919f9c41SJérôme Duval	uint32 RevisionLevel() const { return B_LENDIAN_TO_HOST_INT16(revision_level); }
9163db34c8SAxel Dörfler	uint32 BlockShift() const { return B_LENDIAN_TO_HOST_INT32(block_shift) + 10; }
9263db34c8SAxel Dörfler	uint32 NumInodes() const { return B_LENDIAN_TO_HOST_INT32(num_inodes); }
9363db34c8SAxel Dörfler	uint32 NumBlocks() const { return B_LENDIAN_TO_HOST_INT32(num_blocks); }
9463db34c8SAxel Dörfler	uint32 FreeInodes() const { return B_LENDIAN_TO_HOST_INT32(free_inodes); }
9563db34c8SAxel Dörfler	uint32 FreeBlocks() const { return B_LENDIAN_TO_HOST_INT32(free_blocks); }
9663db34c8SAxel Dörfler	uint16 InodeSize() const { return B_LENDIAN_TO_HOST_INT16(inode_size); }
9763db34c8SAxel Dörfler	uint32 FirstDataBlock() const
9863db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(first_data_block); }
9963db34c8SAxel Dörfler	uint32 BlocksPerGroup() const
10063db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(blocks_per_group); }
10163db34c8SAxel Dörfler	uint32 InodesPerGroup() const
10263db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(inodes_per_group); }
10363db34c8SAxel Dörfler	uint32 FirstMetaBlockGroup() const
10463db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(first_meta_block_group); }
10563db34c8SAxel Dörfler	uint32 CompatibleFeatures() const
10663db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(compatible_features); }
10763db34c8SAxel Dörfler	uint32 ReadOnlyFeatures() const
10813de3d07SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(read_only_features); }
10963db34c8SAxel Dörfler	uint32 IncompatibleFeatures() const
11063db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(incompatible_features); }
111919f9c41SJérôme Duval	uint32 HashSeed(uint8 i) const
112919f9c41SJérôme Duval		{ return B_LENDIAN_TO_HOST_INT32(hash_seed[i]); }
11363db34c8SAxel Dörfler
11463db34c8SAxel Dörfler	bool IsValid();
11563db34c8SAxel Dörfler		// implemented in Volume.cpp
11663db34c8SAxel Dörfler} _PACKED;
11763db34c8SAxel Dörfler
11863db34c8SAxel Dörfler#define EXT2_OLD_REVISION		0
11963db34c8SAxel Dörfler#define EXT2_DYNAMIC_REVISION	1
12063db34c8SAxel Dörfler
121919f9c41SJérôme Duval#define EXT2_MAX_REVISION		EXT2_DYNAMIC_REVISION
122919f9c41SJérôme Duval
123919f9c41SJérôme Duval#define EXT2_FS_STATE_VALID		1	// File system was cleanly unmounted
124919f9c41SJérôme Duval#define EXT2_FS_STATE_ERROR		2	// File system has errors
125919f9c41SJérôme Duval#define EXT2_FS_STATE_ORPHAN	3	// Orphans are being recovered
126919f9c41SJérôme Duval
12763db34c8SAxel Dörfler// compatible features
128431a51ccSAxel Dörfler#define EXT2_FEATURE_DIRECTORY_PREALLOCATION	0x0001
129431a51ccSAxel Dörfler#define EXT2_FEATURE_IMAGIC_INODES				0x0002
130431a51ccSAxel Dörfler#define EXT2_FEATURE_HAS_JOURNAL				0x0004
131431a51ccSAxel Dörfler#define EXT2_FEATURE_EXT_ATTR					0x0008
132431a51ccSAxel Dörfler#define EXT2_FEATURE_RESIZE_INODE				0x0010
133431a51ccSAxel Dörfler#define EXT2_FEATURE_DIRECTORY_INDEX			0x0020
13463db34c8SAxel Dörfler
13563db34c8SAxel Dörfler// read-only compatible features
136431a51ccSAxel Dörfler#define EXT2_READ_ONLY_FEATURE_SPARSE_SUPER		0x0001
137431a51ccSAxel Dörfler#define	EXT2_READ_ONLY_FEATURE_LARGE_FILE		0x0002
138431a51ccSAxel Dörfler#define EXT2_READ_ONLY_FEATURE_BTREE_DIRECTORY	0x0004
13963db34c8SAxel Dörfler
14063db34c8SAxel Dörfler// incompatible features
141431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_COMPRESSION	0x0001
142431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_FILE_TYPE		0x0002
143431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_RECOVER		0x0004
144431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_JOURNAL		0x0008
145431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_META_GROUP	0x0010
146431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_EXTENTS		0x0040
147431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_64BIT			0x0080
148431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_MMP			0x0100
149431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_FLEX_GROUP	0x0200
15063db34c8SAxel Dörfler
15163db34c8SAxel Dörfler// states
15263db34c8SAxel Dörfler#define EXT2_STATE_VALID						0x01
15363db34c8SAxel Dörfler#define	EXT2_STATE_INVALID						0x02
15463db34c8SAxel Dörfler
15563db34c8SAxel Dörflerstruct ext2_block_group {
15663db34c8SAxel Dörfler	uint32	block_bitmap;
15763db34c8SAxel Dörfler	uint32	inode_bitmap;
15863db34c8SAxel Dörfler	uint32	inode_table;
15963db34c8SAxel Dörfler	uint16	free_blocks;
16063db34c8SAxel Dörfler	uint16	free_inodes;
16163db34c8SAxel Dörfler	uint16	used_directories;
16263db34c8SAxel Dörfler	uint16	_padding;
16363db34c8SAxel Dörfler	uint32	_reserved[3];
16463db34c8SAxel Dörfler
16563db34c8SAxel Dörfler	uint32 InodeTable() const
16663db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(inode_table); }
167bac6cc8aSAxel Dörfler} _PACKED;
16863db34c8SAxel Dörfler
16963db34c8SAxel Dörfler#define EXT2_DIRECT_BLOCKS			12
17063db34c8SAxel Dörfler#define EXT2_ROOT_NODE				2
17163db34c8SAxel Dörfler#define EXT2_SHORT_SYMLINK_LENGTH	60
17263db34c8SAxel Dörfler
173b7cb8f8cSAxel Dörflerstruct ext2_data_stream {
174b7cb8f8cSAxel Dörfler	uint32 direct[EXT2_DIRECT_BLOCKS];
175b7cb8f8cSAxel Dörfler	uint32 indirect;
176b7cb8f8cSAxel Dörfler	uint32 double_indirect;
177b7cb8f8cSAxel Dörfler	uint32 triple_indirect;
178bac6cc8aSAxel Dörfler} _PACKED;
179b7cb8f8cSAxel Dörfler
18063db34c8SAxel Dörflerstruct ext2_inode {
18163db34c8SAxel Dörfler	uint16	mode;
18263db34c8SAxel Dörfler	uint16	uid;
18363db34c8SAxel Dörfler	uint32	size;
18463db34c8SAxel Dörfler	uint32	access_time;
18563db34c8SAxel Dörfler	uint32	creation_time;
18663db34c8SAxel Dörfler	uint32	modification_time;
18763db34c8SAxel Dörfler	uint32	deletion_time;
18863db34c8SAxel Dörfler	uint16	gid;
18963db34c8SAxel Dörfler	uint16	num_links;
19063db34c8SAxel Dörfler	uint32	num_blocks;
19163db34c8SAxel Dörfler	uint32	flags;
19263db34c8SAxel Dörfler	uint32	_reserved1;
19363db34c8SAxel Dörfler	union {
194b7cb8f8cSAxel Dörfler		ext2_data_stream stream;
19563db34c8SAxel Dörfler		char symlink[EXT2_SHORT_SYMLINK_LENGTH];
196b7cb8f8cSAxel Dörfler	};
19763db34c8SAxel Dörfler	uint32	generation;
19863db34c8SAxel Dörfler	uint32	file_access_control;
1990680840aSAxel Dörfler	union {
2000680840aSAxel Dörfler		// for directories vs. files
2010680840aSAxel Dörfler		uint32	directory_access_control;
2020680840aSAxel Dörfler		uint32	size_high;
2030680840aSAxel Dörfler	};
20463db34c8SAxel Dörfler	uint32	fragment;
20563db34c8SAxel Dörfler	uint8	fragment_number;
20663db34c8SAxel Dörfler	uint8	fragment_size;
20763db34c8SAxel Dörfler	uint16	_padding;
20863db34c8SAxel Dörfler	uint16	uid_high;
20963db34c8SAxel Dörfler	uint16	gid_high;
21063db34c8SAxel Dörfler	uint32	_reserved2;
211275463f4SAxel Dörfler	uint16	extra_inode_size;
212275463f4SAxel Dörfler	uint16	_padding2;
21363db34c8SAxel Dörfler
21463db34c8SAxel Dörfler	uint16 Mode() const { return B_LENDIAN_TO_HOST_INT16(mode); }
21563db34c8SAxel Dörfler	uint32 Flags() const { return B_LENDIAN_TO_HOST_INT32(flags); }
2160680840aSAxel Dörfler	uint16 NumLinks() const { return B_LENDIAN_TO_HOST_INT16(num_links); }
21763db34c8SAxel Dörfler
21863db34c8SAxel Dörfler	time_t AccessTime() const { return B_LENDIAN_TO_HOST_INT32(access_time); }
21963db34c8SAxel Dörfler	time_t CreationTime() const { return B_LENDIAN_TO_HOST_INT32(creation_time); }
22063db34c8SAxel Dörfler	time_t ModificationTime() const { return B_LENDIAN_TO_HOST_INT32(modification_time); }
22163db34c8SAxel Dörfler	time_t DeletionTime() const { return B_LENDIAN_TO_HOST_INT32(deletion_time); }
22263db34c8SAxel Dörfler
2230680840aSAxel Dörfler	off_t Size() const
2240680840aSAxel Dörfler	{
2250680840aSAxel Dörfler		if (S_ISREG(Mode())) {
2260680840aSAxel Dörfler			return B_LENDIAN_TO_HOST_INT32(size)
2270680840aSAxel Dörfler				| ((off_t)B_LENDIAN_TO_HOST_INT32(size_high) << 32);
2280680840aSAxel Dörfler		}
2290680840aSAxel Dörfler
2300680840aSAxel Dörfler		return B_LENDIAN_TO_HOST_INT32(size);
2310680840aSAxel Dörfler	}
2320680840aSAxel Dörfler
233bac6cc8aSAxel Dörfler	uint32 UserID() const
23463db34c8SAxel Dörfler	{
23563db34c8SAxel Dörfler		return B_LENDIAN_TO_HOST_INT16(uid)
23663db34c8SAxel Dörfler			| (B_LENDIAN_TO_HOST_INT16(uid_high) << 16);
23763db34c8SAxel Dörfler	}
23863db34c8SAxel Dörfler
239bac6cc8aSAxel Dörfler	uint32 GroupID() const
24063db34c8SAxel Dörfler	{
24163db34c8SAxel Dörfler		return B_LENDIAN_TO_HOST_INT16(gid)
24263db34c8SAxel Dörfler			| (B_LENDIAN_TO_HOST_INT16(gid_high) << 16);
24363db34c8SAxel Dörfler	}
24463db34c8SAxel Dörfler} _PACKED;
24563db34c8SAxel Dörfler
24663db34c8SAxel Dörfler#define EXT2_SUPER_BLOCK_MAGIC			0xef53
24763db34c8SAxel Dörfler
24863db34c8SAxel Dörfler// flags
24963db34c8SAxel Dörfler#define EXT2_INODE_SECURE_DELETION		0x00000001
25063db34c8SAxel Dörfler#define EXT2_INODE_UNDELETE				0x00000002
25163db34c8SAxel Dörfler#define EXT2_INODE_COMPRESSED			0x00000004
25263db34c8SAxel Dörfler#define EXT2_INODE_SYNCHRONOUS			0x00000008
25363db34c8SAxel Dörfler#define EXT2_INODE_IMMUTABLE			0x00000010
25463db34c8SAxel Dörfler#define EXT2_INODE_APPEND_ONLY			0x00000020
25563db34c8SAxel Dörfler#define EXT2_INODE_NO_DUMP				0x00000040
25663db34c8SAxel Dörfler#define EXT2_INODE_NO_ACCESS_TIME		0x00000080
25763db34c8SAxel Dörfler#define EXT2_INODE_DIRTY				0x00000100
25863db34c8SAxel Dörfler#define EXT2_INODE_COMPRESSED_BLOCKS	0x00000200
25963db34c8SAxel Dörfler#define EXT2_INODE_DO_NOT_COMPRESS		0x00000400
26063db34c8SAxel Dörfler#define EXT2_INODE_COMPRESSION_ERROR	0x00000800
26163db34c8SAxel Dörfler#define EXT2_INODE_BTREE				0x00001000
262919f9c41SJérôme Duval#define EXT2_INODE_INDEXED				0x00001000
26363db34c8SAxel Dörfler
26463db34c8SAxel Dörfler#define EXT2_NAME_LENGTH	255
26563db34c8SAxel Dörfler
26663db34c8SAxel Dörflerstruct ext2_dir_entry {
26763db34c8SAxel Dörfler	uint32	inode_id;
26863db34c8SAxel Dörfler	uint16	length;
26963db34c8SAxel Dörfler	uint8	name_length;
27063db34c8SAxel Dörfler	uint8	file_type;
27163db34c8SAxel Dörfler	char	name[EXT2_NAME_LENGTH];
27263db34c8SAxel Dörfler
27363db34c8SAxel Dörfler	uint32 InodeID() const { return B_LENDIAN_TO_HOST_INT32(inode_id); }
27463db34c8SAxel Dörfler	uint16 Length() const { return B_LENDIAN_TO_HOST_INT16(length); }
27563db34c8SAxel Dörfler	uint8 NameLength() const { return name_length; }
27663db34c8SAxel Dörfler	uint8 FileType() const { return file_type; }
27763db34c8SAxel Dörfler
27863db34c8SAxel Dörfler	bool IsValid() const
27963db34c8SAxel Dörfler	{
28063db34c8SAxel Dörfler		return Length() > MinimumSize();
28163db34c8SAxel Dörfler			// There is no maximum size, as the last entry spans until the
28263db34c8SAxel Dörfler			// end of the block
28363db34c8SAxel Dörfler	}
28463db34c8SAxel Dörfler
28563db34c8SAxel Dörfler	static size_t MinimumSize()
28663db34c8SAxel Dörfler	{
28763db34c8SAxel Dörfler		return sizeof(ext2_dir_entry) - EXT2_NAME_LENGTH;
28863db34c8SAxel Dörfler	}
28963db34c8SAxel Dörfler} _PACKED;
29063db34c8SAxel Dörfler
29163db34c8SAxel Dörfler// file types
29263db34c8SAxel Dörfler#define EXT2_TYPE_UNKOWN		0
29363db34c8SAxel Dörfler#define EXT2_TYPE_FILE			1
29463db34c8SAxel Dörfler#define EXT2_TYPE_DIRECTORY		2
29563db34c8SAxel Dörfler#define EXT2_TYPE_CHAR_DEVICE	3
29663db34c8SAxel Dörfler#define EXT2_TYPE_BLOCK_DEVICE	4
29763db34c8SAxel Dörfler#define EXT2_TYPE_FIFO			5
29863db34c8SAxel Dörfler#define EXT2_TYPE_SOCKET		6
29963db34c8SAxel Dörfler#define EXT2_TYPE_SYMLINK		7
30063db34c8SAxel Dörfler
301b026d219SFrançois Revol#define EXT2_XATTR_MAGIC		0xea020000
302b026d219SFrançois Revol#define EXT2_XATTR_ROUND		((1 << 2) - 1)
303b026d219SFrançois Revol#define EXT2_XATTR_NAME_LENGTH	255
304b026d219SFrançois Revol
305b026d219SFrançois Revol#define EXT2_XATTR_INDEX_USER	1
306b026d219SFrançois Revol
307b026d219SFrançois Revolstruct ext2_xattr_header {
308b026d219SFrançois Revol	uint32	magic;
309b026d219SFrançois Revol	uint32	refcount;
310b026d219SFrançois Revol	uint32	blocks;		// must be 1 for ext2
311b026d219SFrançois Revol	uint32	hash;
312b026d219SFrançois Revol	uint32	reserved[4];	// zero
313b026d219SFrançois Revol
314b026d219SFrançois Revol	bool IsValid() const
315b026d219SFrançois Revol	{
316b026d219SFrançois Revol		return B_LENDIAN_TO_HOST_INT32(magic) == EXT2_XATTR_MAGIC
317b026d219SFrançois Revol			&& B_LENDIAN_TO_HOST_INT32(blocks) == 1
318b026d219SFrançois Revol			&& refcount <= 1024;
319b026d219SFrançois Revol	}
320b026d219SFrançois Revol
321b026d219SFrançois Revol	void Dump() const {
322919f9c41SJérôme Duval		for (unsigned int i = 0; i < Length(); i++)
323b026d219SFrançois Revol			dprintf("%02x ", ((uint8 *)this)[i]);
324b026d219SFrançois Revol		dprintf("\n");
325b026d219SFrançois Revol	}
326b026d219SFrançois Revol
327b026d219SFrançois Revol	static size_t Length()
328b026d219SFrançois Revol	{
329b026d219SFrançois Revol		return sizeof(ext2_xattr_header);
330b026d219SFrançois Revol	}
331b026d219SFrançois Revol};
332b026d219SFrançois Revol
333b026d219SFrançois Revolstruct ext2_xattr_entry {
334b026d219SFrançois Revol	uint8	name_length;
335b026d219SFrançois Revol	uint8	name_index;
336b026d219SFrançois Revol	uint16	value_offset;
337b026d219SFrançois Revol	uint32	value_block;	// must be zero for ext2
338b026d219SFrançois Revol	uint32	value_size;
339b026d219SFrançois Revol	uint32	hash;
340b026d219SFrançois Revol	char	name[EXT2_XATTR_NAME_LENGTH];
341b026d219SFrançois Revol
342b026d219SFrançois Revol	uint8 NameLength() const { return name_length; }
343b026d219SFrançois Revol	uint8 NameIndex() const { return name_index; }
344b026d219SFrançois Revol	uint16 ValueOffset() const { return
345b026d219SFrançois Revol			B_LENDIAN_TO_HOST_INT16(value_offset); }
346b026d219SFrançois Revol	uint32 ValueSize() const { return
347b026d219SFrançois Revol			B_LENDIAN_TO_HOST_INT32(value_size); }
348b026d219SFrançois Revol
349b026d219SFrançois Revol	// padded sizes
350b026d219SFrançois Revol	uint32 Length() const { return (MinimumSize() + NameLength()
351b026d219SFrançois Revol		+ EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND; }
352b026d219SFrançois Revol
353b026d219SFrançois Revol	bool IsValid() const
354b026d219SFrançois Revol	{
355b026d219SFrançois Revol		return NameLength() > 0 && value_block == 0;
356b026d219SFrançois Revol			// There is no maximum size, as the last entry spans until the
357b026d219SFrançois Revol			// end of the block
358b026d219SFrançois Revol	}
359b026d219SFrançois Revol
360b026d219SFrançois Revol	void Dump(bool full=false) const {
361919f9c41SJérôme Duval		for (unsigned int i = 0; i < (full ? sizeof(this) : MinimumSize()); i++)
362b026d219SFrançois Revol			dprintf("%02x ", ((uint8 *)this)[i]);
363b026d219SFrançois Revol		dprintf("\n");
364b026d219SFrançois Revol	}
365b026d219SFrançois Revol
366b026d219SFrançois Revol	static size_t MinimumSize()
367b026d219SFrançois Revol	{
368b026d219SFrançois Revol		return sizeof(ext2_xattr_entry) - EXT2_XATTR_NAME_LENGTH;
369b026d219SFrançois Revol	}
370b026d219SFrançois Revol} _PACKED;
371b026d219SFrançois Revol
372b026d219SFrançois Revol
37363db34c8SAxel Dörflerextern fs_volume_ops gExt2VolumeOps;
37463db34c8SAxel Dörflerextern fs_vnode_ops gExt2VnodeOps;
37563db34c8SAxel Dörfler
37663db34c8SAxel Dörfler#endif	// EXT2_H
377