ext2.h revision 21451bd3
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
16a1b0ec30SJérôme Duval//#define TRACE_EXT2
17a1b0ec30SJérôme Duval
1863db34c8SAxel Dörfler#define EXT2_SUPER_BLOCK_OFFSET	1024
1963db34c8SAxel Dörfler
2063db34c8SAxel Dörflerstruct ext2_super_block {
2163db34c8SAxel Dörfler	uint32	num_inodes;
2263db34c8SAxel Dörfler	uint32	num_blocks;
2363db34c8SAxel Dörfler	uint32	reserved_blocks;
2463db34c8SAxel Dörfler	uint32	free_blocks;
2563db34c8SAxel Dörfler	uint32	free_inodes;
2663db34c8SAxel Dörfler	uint32	first_data_block;
2763db34c8SAxel Dörfler	uint32	block_shift;
2863db34c8SAxel Dörfler	uint32	fragment_shift;
2963db34c8SAxel Dörfler	uint32	blocks_per_group;
3063db34c8SAxel Dörfler	uint32	fragments_per_group;
3163db34c8SAxel Dörfler	uint32	inodes_per_group;
3263db34c8SAxel Dörfler	uint32	mount_time;
3363db34c8SAxel Dörfler	uint32	write_time;
3463db34c8SAxel Dörfler	uint16	mount_count;
3563db34c8SAxel Dörfler	uint16	max_mount_count;
3663db34c8SAxel Dörfler	uint16	magic;
3763db34c8SAxel Dörfler	uint16	state;
3863db34c8SAxel Dörfler	uint16	error_handling;
3963db34c8SAxel Dörfler	uint16	minor_revision_level;
4063db34c8SAxel Dörfler	uint32	last_check_time;
4163db34c8SAxel Dörfler	uint32	check_interval;
4263db34c8SAxel Dörfler	uint32	creator_os;
4363db34c8SAxel Dörfler	uint32	revision_level;
4463db34c8SAxel Dörfler	uint16	reserved_blocks_uid;
4563db34c8SAxel Dörfler	uint16	reserved_blocks_gid;
4663db34c8SAxel Dörfler	uint32	first_inode;
4763db34c8SAxel Dörfler	uint16	inode_size;
4863db34c8SAxel Dörfler	uint16	block_group;
4963db34c8SAxel Dörfler	uint32	compatible_features;
5063db34c8SAxel Dörfler	uint32	incompatible_features;
5113de3d07SAxel Dörfler	uint32	read_only_features;
5263db34c8SAxel Dörfler	uint8	uuid[16];
5363db34c8SAxel Dörfler	char	name[16];
5463db34c8SAxel Dörfler	char	last_mount_point[64];
5563db34c8SAxel Dörfler	uint32	algorithm_usage_bitmap;
5663db34c8SAxel Dörfler	uint8	preallocated_blocks;
5763db34c8SAxel Dörfler	uint8	preallocated_directory_blocks;
5863db34c8SAxel Dörfler	uint16	_padding;
5913de3d07SAxel Dörfler
6063db34c8SAxel Dörfler	// journaling ext3 support
6163db34c8SAxel Dörfler	uint8	journal_uuid[16];
6263db34c8SAxel Dörfler	uint32	journal_inode;
6363db34c8SAxel Dörfler	uint32	journal_device;
6463db34c8SAxel Dörfler	uint32	last_orphan;
6563db34c8SAxel Dörfler	uint32	hash_seed[4];
6663db34c8SAxel Dörfler	uint8	default_hash_version;
6763db34c8SAxel Dörfler	uint8	_reserved1;
6821451bd3SJérôme Duval	uint16	group_descriptor_size;
6963db34c8SAxel Dörfler	uint32	default_mount_options;
7063db34c8SAxel Dörfler	uint32	first_meta_block_group;
71275463f4SAxel Dörfler	uint32	fs_creation_time;
72275463f4SAxel Dörfler	uint32	journal_inode_backup[17];
73275463f4SAxel Dörfler
74275463f4SAxel Dörfler	// ext4 support
75275463f4SAxel Dörfler	uint32	num_blocks_hi;
76275463f4SAxel Dörfler	uint32	reserved_blocks_hi;
77275463f4SAxel Dörfler	uint32	free_blocks_hi;
78275463f4SAxel Dörfler	uint16	min_inode_size;
79275463f4SAxel Dörfler	uint16	want_inode_size;
80275463f4SAxel Dörfler	uint32	flags;
81275463f4SAxel Dörfler	uint16	raid_stride;
82275463f4SAxel Dörfler	uint16	mmp_interval;
83275463f4SAxel Dörfler	uint64	mmp_block;
84275463f4SAxel Dörfler	uint32	raid_stripe_width;
85275463f4SAxel Dörfler	uint8	groups_per_flex_shift;
86275463f4SAxel Dörfler	uint8	_reserved3;
87275463f4SAxel Dörfler	uint16	_reserved4;
88275463f4SAxel Dörfler	uint32	_reserved5[162];
8963db34c8SAxel Dörfler
9063db34c8SAxel Dörfler	uint16 Magic() const { return B_LENDIAN_TO_HOST_INT16(magic); }
91919f9c41SJérôme Duval	uint16 State() const { return B_LENDIAN_TO_HOST_INT16(state); }
92919f9c41SJérôme Duval	uint32 RevisionLevel() const { return B_LENDIAN_TO_HOST_INT16(revision_level); }
9363db34c8SAxel Dörfler	uint32 BlockShift() const { return B_LENDIAN_TO_HOST_INT32(block_shift) + 10; }
9463db34c8SAxel Dörfler	uint32 NumInodes() const { return B_LENDIAN_TO_HOST_INT32(num_inodes); }
9563db34c8SAxel Dörfler	uint32 NumBlocks() const { return B_LENDIAN_TO_HOST_INT32(num_blocks); }
9663db34c8SAxel Dörfler	uint32 FreeInodes() const { return B_LENDIAN_TO_HOST_INT32(free_inodes); }
9763db34c8SAxel Dörfler	uint32 FreeBlocks() const { return B_LENDIAN_TO_HOST_INT32(free_blocks); }
9863db34c8SAxel Dörfler	uint16 InodeSize() const { return B_LENDIAN_TO_HOST_INT16(inode_size); }
9963db34c8SAxel Dörfler	uint32 FirstDataBlock() const
10063db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(first_data_block); }
10163db34c8SAxel Dörfler	uint32 BlocksPerGroup() const
10263db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(blocks_per_group); }
10363db34c8SAxel Dörfler	uint32 InodesPerGroup() const
10463db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(inodes_per_group); }
10563db34c8SAxel Dörfler	uint32 FirstMetaBlockGroup() const
10663db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(first_meta_block_group); }
10763db34c8SAxel Dörfler	uint32 CompatibleFeatures() const
10863db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(compatible_features); }
10963db34c8SAxel Dörfler	uint32 ReadOnlyFeatures() const
11013de3d07SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(read_only_features); }
11163db34c8SAxel Dörfler	uint32 IncompatibleFeatures() const
11263db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(incompatible_features); }
113a1b0ec30SJérôme Duval	ino_t  JournalInode() const
114a1b0ec30SJérôme Duval		{ return B_LENDIAN_TO_HOST_INT32(journal_inode); }
115a1b0ec30SJérôme Duval	ino_t  LastOrphan() const
116a1b0ec30SJérôme Duval		{ return (ino_t)B_LENDIAN_TO_HOST_INT32(last_orphan); }
117919f9c41SJérôme Duval	uint32 HashSeed(uint8 i) const
118919f9c41SJérôme Duval		{ return B_LENDIAN_TO_HOST_INT32(hash_seed[i]); }
11921451bd3SJérôme Duval	uint16 GroupDescriptorSize() const
12021451bd3SJérôme Duval		{ return B_LENDIAN_TO_HOST_INT16(group_descriptor_size); }
12163db34c8SAxel Dörfler
122a1b0ec30SJérôme Duval	void SetFreeInodes(uint32 freeInodes)
123a1b0ec30SJérôme Duval		{ free_inodes = B_HOST_TO_LENDIAN_INT32(freeInodes); }
124a1b0ec30SJérôme Duval	void SetFreeBlocks(uint32 freeBlocks)
125a1b0ec30SJérôme Duval		{ free_blocks = B_HOST_TO_LENDIAN_INT32(freeBlocks); }
126a1b0ec30SJérôme Duval	void SetLastOrphan(ino_t id)
127a1b0ec30SJérôme Duval		{ last_orphan = B_HOST_TO_LENDIAN_INT32((uint32)id); }
1287babd0d5SJérôme Duval	void SetReadOnlyFeatures(uint32 readOnlyFeatures) const
1297babd0d5SJérôme Duval		{ readOnlyFeatures = B_HOST_TO_LENDIAN_INT32(readOnlyFeatures); }
1307babd0d5SJérôme Duval
13163db34c8SAxel Dörfler	bool IsValid();
13263db34c8SAxel Dörfler		// implemented in Volume.cpp
13363db34c8SAxel Dörfler} _PACKED;
13463db34c8SAxel Dörfler
13563db34c8SAxel Dörfler#define EXT2_OLD_REVISION		0
13663db34c8SAxel Dörfler#define EXT2_DYNAMIC_REVISION	1
13763db34c8SAxel Dörfler
138919f9c41SJérôme Duval#define EXT2_MAX_REVISION		EXT2_DYNAMIC_REVISION
139919f9c41SJérôme Duval
140919f9c41SJérôme Duval#define EXT2_FS_STATE_VALID		1	// File system was cleanly unmounted
141919f9c41SJérôme Duval#define EXT2_FS_STATE_ERROR		2	// File system has errors
142919f9c41SJérôme Duval#define EXT2_FS_STATE_ORPHAN	3	// Orphans are being recovered
143919f9c41SJérôme Duval
14463db34c8SAxel Dörfler// compatible features
145431a51ccSAxel Dörfler#define EXT2_FEATURE_DIRECTORY_PREALLOCATION	0x0001
146431a51ccSAxel Dörfler#define EXT2_FEATURE_IMAGIC_INODES				0x0002
147431a51ccSAxel Dörfler#define EXT2_FEATURE_HAS_JOURNAL				0x0004
148431a51ccSAxel Dörfler#define EXT2_FEATURE_EXT_ATTR					0x0008
149431a51ccSAxel Dörfler#define EXT2_FEATURE_RESIZE_INODE				0x0010
150431a51ccSAxel Dörfler#define EXT2_FEATURE_DIRECTORY_INDEX			0x0020
15163db34c8SAxel Dörfler
15263db34c8SAxel Dörfler// read-only compatible features
153431a51ccSAxel Dörfler#define EXT2_READ_ONLY_FEATURE_SPARSE_SUPER		0x0001
1547babd0d5SJérôme Duval#define EXT2_READ_ONLY_FEATURE_LARGE_FILE		0x0002
155431a51ccSAxel Dörfler#define EXT2_READ_ONLY_FEATURE_BTREE_DIRECTORY	0x0004
156de66992bSJérôme Duval#define EXT2_READ_ONLY_FEATURE_HUGE_FILE		0x0008
15721451bd3SJérôme Duval#define EXT2_READ_ONLY_FEATURE_GDT_CSUM			0x0010
15821451bd3SJérôme Duval#define EXT2_READ_ONLY_FEATURE_DIR_NLINK		0x0020
15921451bd3SJérôme Duval#define EXT2_READ_ONLY_FEATURE_EXTRA_ISIZE		0x0040
16063db34c8SAxel Dörfler
16163db34c8SAxel Dörfler// incompatible features
162431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_COMPRESSION	0x0001
163431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_FILE_TYPE		0x0002
164431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_RECOVER		0x0004
165431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_JOURNAL		0x0008
166431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_META_GROUP	0x0010
167431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_EXTENTS		0x0040
168431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_64BIT			0x0080
169431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_MMP			0x0100
170431a51ccSAxel Dörfler#define EXT2_INCOMPATIBLE_FEATURE_FLEX_GROUP	0x0200
17163db34c8SAxel Dörfler
17263db34c8SAxel Dörfler// states
17363db34c8SAxel Dörfler#define EXT2_STATE_VALID						0x01
17463db34c8SAxel Dörfler#define	EXT2_STATE_INVALID						0x02
17563db34c8SAxel Dörfler
17663db34c8SAxel Dörflerstruct ext2_block_group {
17763db34c8SAxel Dörfler	uint32	block_bitmap;
17863db34c8SAxel Dörfler	uint32	inode_bitmap;
17963db34c8SAxel Dörfler	uint32	inode_table;
18063db34c8SAxel Dörfler	uint16	free_blocks;
18163db34c8SAxel Dörfler	uint16	free_inodes;
18263db34c8SAxel Dörfler	uint16	used_directories;
18363db34c8SAxel Dörfler	uint16	_padding;
18463db34c8SAxel Dörfler	uint32	_reserved[3];
18563db34c8SAxel Dörfler
186a1b0ec30SJérôme Duval	uint32	BlockBitmap() const
187a1b0ec30SJérôme Duval		{ return B_LENDIAN_TO_HOST_INT32(block_bitmap); }
188a1b0ec30SJérôme Duval	uint32	InodeBitmap() const
189a1b0ec30SJérôme Duval		{ return B_LENDIAN_TO_HOST_INT32(inode_bitmap); }
190a1b0ec30SJérôme Duval	uint32	InodeTable() const
19163db34c8SAxel Dörfler		{ return B_LENDIAN_TO_HOST_INT32(inode_table); }
192a1b0ec30SJérôme Duval	uint16	FreeBlocks() const
193a1b0ec30SJérôme Duval		{ return B_LENDIAN_TO_HOST_INT16(free_blocks); }
194a1b0ec30SJérôme Duval	uint16	FreeInodes() const
195a1b0ec30SJérôme Duval		{ return B_LENDIAN_TO_HOST_INT16(free_inodes); }
196a1b0ec30SJérôme Duval	uint16	UsedDirectories() const
197a1b0ec30SJérôme Duval		{ return B_LENDIAN_TO_HOST_INT16(used_directories); }
198a1b0ec30SJérôme Duval
199a1b0ec30SJérôme Duval	void	SetFreeBlocks(uint16 freeBlocks)
200a1b0ec30SJérôme Duval		{ free_blocks = B_HOST_TO_LENDIAN_INT16(freeBlocks); }
201a1b0ec30SJérôme Duval
202a1b0ec30SJérôme Duval	void	SetFreeInodes(uint16 freeInodes)
203a1b0ec30SJérôme Duval		{ free_inodes = B_HOST_TO_LENDIAN_INT16(freeInodes); }
204a1b0ec30SJérôme Duval
205a1b0ec30SJérôme Duval	void	SetUsedDirectories(uint16 usedDirectories)
206a1b0ec30SJérôme Duval		{ used_directories = B_HOST_TO_LENDIAN_INT16(usedDirectories); }
207bac6cc8aSAxel Dörfler} _PACKED;
20863db34c8SAxel Dörfler
20963db34c8SAxel Dörfler#define EXT2_DIRECT_BLOCKS			12
21063db34c8SAxel Dörfler#define EXT2_ROOT_NODE				2
21163db34c8SAxel Dörfler#define EXT2_SHORT_SYMLINK_LENGTH	60
21263db34c8SAxel Dörfler
213b7cb8f8cSAxel Dörflerstruct ext2_data_stream {
214b7cb8f8cSAxel Dörfler	uint32 direct[EXT2_DIRECT_BLOCKS];
215b7cb8f8cSAxel Dörfler	uint32 indirect;
216b7cb8f8cSAxel Dörfler	uint32 double_indirect;
217b7cb8f8cSAxel Dörfler	uint32 triple_indirect;
218bac6cc8aSAxel Dörfler} _PACKED;
219b7cb8f8cSAxel Dörfler
2206bfb10d3SJérôme Duval#define EXT2_INODE_NORMAL_SIZE		128
2216bfb10d3SJérôme Duval
22263db34c8SAxel Dörflerstruct ext2_inode {
22363db34c8SAxel Dörfler	uint16	mode;
22463db34c8SAxel Dörfler	uint16	uid;
22563db34c8SAxel Dörfler	uint32	size;
22663db34c8SAxel Dörfler	uint32	access_time;
2276bfb10d3SJérôme Duval	uint32	change_time;
22863db34c8SAxel Dörfler	uint32	modification_time;
22963db34c8SAxel Dörfler	uint32	deletion_time;
23063db34c8SAxel Dörfler	uint16	gid;
23163db34c8SAxel Dörfler	uint16	num_links;
23263db34c8SAxel Dörfler	uint32	num_blocks;
23363db34c8SAxel Dörfler	uint32	flags;
2346bfb10d3SJérôme Duval	uint32	version;
23563db34c8SAxel Dörfler	union {
236b7cb8f8cSAxel Dörfler		ext2_data_stream stream;
23763db34c8SAxel Dörfler		char symlink[EXT2_SHORT_SYMLINK_LENGTH];
238b7cb8f8cSAxel Dörfler	};
23963db34c8SAxel Dörfler	uint32	generation;
24063db34c8SAxel Dörfler	uint32	file_access_control;
2410680840aSAxel Dörfler	union {
2420680840aSAxel Dörfler		// for directories vs. files
2430680840aSAxel Dörfler		uint32	directory_access_control;
2440680840aSAxel Dörfler		uint32	size_high;
2450680840aSAxel Dörfler	};
24663db34c8SAxel Dörfler	uint32	fragment;
247de66992bSJérôme Duval	union {
248de66992bSJérôme Duval		struct {
249de66992bSJérôme Duval			uint8	fragment_number;
250de66992bSJérôme Duval			uint8	fragment_size;
251de66992bSJérôme Duval		};
252de66992bSJérôme Duval		uint16 num_blocks_high;
253de66992bSJérôme Duval	};
25463db34c8SAxel Dörfler	uint16	_padding;
25563db34c8SAxel Dörfler	uint16	uid_high;
25663db34c8SAxel Dörfler	uint16	gid_high;
25763db34c8SAxel Dörfler	uint32	_reserved2;
2586bfb10d3SJérôme Duval
2596bfb10d3SJérôme Duval	// extra attributes
260275463f4SAxel Dörfler	uint16	extra_inode_size;
261275463f4SAxel Dörfler	uint16	_padding2;
2626bfb10d3SJérôme Duval	uint32	change_time_extra;
2636bfb10d3SJérôme Duval	uint32	modification_time_extra;
2646bfb10d3SJérôme Duval	uint32	access_time_extra;
2656bfb10d3SJérôme Duval	uint32	creation_time;
2666bfb10d3SJérôme Duval	uint32	creation_time_extra;
2676bfb10d3SJérôme Duval	uint32	version_high;
26863db34c8SAxel Dörfler
26963db34c8SAxel Dörfler	uint16 Mode() const { return B_LENDIAN_TO_HOST_INT16(mode); }
27063db34c8SAxel Dörfler	uint32 Flags() const { return B_LENDIAN_TO_HOST_INT32(flags); }
2710680840aSAxel Dörfler	uint16 NumLinks() const { return B_LENDIAN_TO_HOST_INT16(num_links); }
272a1b0ec30SJérôme Duval	uint32 NumBlocks() const { return B_LENDIAN_TO_HOST_INT32(num_blocks); }
273de66992bSJérôme Duval	uint64 NumBlocks64() const { return B_LENDIAN_TO_HOST_INT32(num_blocks)
274de66992bSJérôme Duval		| ((uint64)B_LENDIAN_TO_HOST_INT32(num_blocks_high) << 32); }
27563db34c8SAxel Dörfler
2766bfb10d3SJérôme Duval	static void _DecodeTime(struct timespec *timespec, uint32 time,
2776bfb10d3SJérôme Duval		uint32 time_extra, bool extra)
2786bfb10d3SJérôme Duval	{
2796bfb10d3SJérôme Duval		timespec->tv_sec = B_LENDIAN_TO_HOST_INT32(time);
2806bfb10d3SJérôme Duval		if (extra && sizeof(timespec->tv_sec) > 4)
2816bfb10d3SJérôme Duval			timespec->tv_sec |=
2826bfb10d3SJérôme Duval				(uint64)(B_LENDIAN_TO_HOST_INT32(time_extra) & 0x2) << 32;
2836bfb10d3SJérôme Duval		if (extra)
2846bfb10d3SJérôme Duval			timespec->tv_nsec = B_LENDIAN_TO_HOST_INT32(time_extra) >> 2;
2856bfb10d3SJérôme Duval		else
2866bfb10d3SJérôme Duval			timespec->tv_nsec = 0;
2876bfb10d3SJérôme Duval	}
2886bfb10d3SJérôme Duval
2896bfb10d3SJérôme Duval	void GetModificationTime(struct timespec *timespec, bool extra) const
2906bfb10d3SJérôme Duval		{ _DecodeTime(timespec, modification_time, modification_time_extra,
2916bfb10d3SJérôme Duval			extra); }
2926bfb10d3SJérôme Duval	void GetAccessTime(struct timespec *timespec, bool extra) const
2936bfb10d3SJérôme Duval		{ _DecodeTime(timespec, access_time, access_time_extra, extra); }
2946bfb10d3SJérôme Duval	void GetChangeTime(struct timespec *timespec, bool extra) const
2956bfb10d3SJérôme Duval		{ _DecodeTime(timespec, change_time, change_time_extra, extra); }
2966bfb10d3SJérôme Duval	void GetCreationTime(struct timespec *timespec, bool extra) const
2976bfb10d3SJérôme Duval	{
2986bfb10d3SJérôme Duval		if (extra)
2996bfb10d3SJérôme Duval			_DecodeTime(timespec, creation_time, creation_time_extra, extra);
3006bfb10d3SJérôme Duval		else {
3016bfb10d3SJérôme Duval			timespec->tv_sec = 0;
3026bfb10d3SJérôme Duval			timespec->tv_nsec = 0;
3036bfb10d3SJérôme Duval		}
3046bfb10d3SJérôme Duval	}
3056bfb10d3SJérôme Duval	time_t DeletionTime() const
3066bfb10d3SJérôme Duval		{ return B_LENDIAN_TO_HOST_INT32(deletion_time); }
3076bfb10d3SJérôme Duval
3086bfb10d3SJérôme Duval	static uint32 _EncodeTime(const struct timespec *timespec)
3096bfb10d3SJérôme Duval	{
3106bfb10d3SJérôme Duval		uint32 time = (timespec->tv_nsec << 2) & 0xfffffffc;
3116bfb10d3SJérôme Duval		if (sizeof(timespec->tv_sec) > 4)
3126bfb10d3SJérôme Duval			time |= (uint64)timespec->tv_sec >> 32;
3136bfb10d3SJérôme Duval		return B_HOST_TO_LENDIAN_INT32(time);
3146bfb10d3SJérôme Duval	}
3156bfb10d3SJérôme Duval
3166bfb10d3SJérôme Duval	void SetModificationTime(const struct timespec *timespec, bool extra)
3176bfb10d3SJérôme Duval	{
3186bfb10d3SJérôme Duval		modification_time = B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_sec);
3196bfb10d3SJérôme Duval		if (extra)
3206bfb10d3SJérôme Duval			modification_time_extra = _EncodeTime(timespec);
3216bfb10d3SJérôme Duval	}
3226bfb10d3SJérôme Duval	void SetAccessTime(const struct timespec *timespec, bool extra)
3236bfb10d3SJérôme Duval	{
3246bfb10d3SJérôme Duval		access_time = B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_sec);
3256bfb10d3SJérôme Duval		if (extra)
3266bfb10d3SJérôme Duval			access_time_extra = _EncodeTime(timespec);
3276bfb10d3SJérôme Duval	}
3286bfb10d3SJérôme Duval	void SetChangeTime(const struct timespec *timespec, bool extra)
3296bfb10d3SJérôme Duval	{
3306bfb10d3SJérôme Duval		change_time = B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_sec);
3316bfb10d3SJérôme Duval		if (extra)
3326bfb10d3SJérôme Duval			change_time_extra = _EncodeTime(timespec);
3336bfb10d3SJérôme Duval	}
3346bfb10d3SJérôme Duval	void SetCreationTime(const struct timespec *timespec, bool extra)
3356bfb10d3SJérôme Duval	{
3366bfb10d3SJérôme Duval		if (extra) {
3376bfb10d3SJérôme Duval			creation_time = B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_sec);
3386bfb10d3SJérôme Duval			creation_time_extra =
3396bfb10d3SJérôme Duval				B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_nsec);
3406bfb10d3SJérôme Duval		}
3416bfb10d3SJérôme Duval	}
3426bfb10d3SJérôme Duval	void SetDeletionTime(time_t deletionTime)
3436bfb10d3SJérôme Duval	{
3446bfb10d3SJérôme Duval		deletion_time = B_HOST_TO_LENDIAN_INT32((uint32)deletionTime);
3456bfb10d3SJérôme Duval	}
34663db34c8SAxel Dörfler
3476bfb10d3SJérôme Duval	ino_t  NextOrphan() const { return (ino_t)DeletionTime(); }
3486bfb10d3SJérôme Duval
3490680840aSAxel Dörfler	off_t Size() const
3500680840aSAxel Dörfler	{
3510680840aSAxel Dörfler		if (S_ISREG(Mode())) {
3520680840aSAxel Dörfler			return B_LENDIAN_TO_HOST_INT32(size)
3530680840aSAxel Dörfler				| ((off_t)B_LENDIAN_TO_HOST_INT32(size_high) << 32);
3540680840aSAxel Dörfler		}
3550680840aSAxel Dörfler
3560680840aSAxel Dörfler		return B_LENDIAN_TO_HOST_INT32(size);
3570680840aSAxel Dörfler	}
3580680840aSAxel Dörfler
359db1b905eSJérôme Duval	uint32 ExtendedAttributesBlock() const
360db1b905eSJérôme Duval	{	return B_LENDIAN_TO_HOST_INT32(file_access_control);}
361db1b905eSJérôme Duval
3626bfb10d3SJérôme Duval	uint16 ExtraInodeSize() const
3636bfb10d3SJérôme Duval		{ return B_LENDIAN_TO_HOST_INT16(extra_inode_size); }
3646bfb10d3SJérôme Duval
365bac6cc8aSAxel Dörfler	uint32 UserID() const
36663db34c8SAxel Dörfler	{
36763db34c8SAxel Dörfler		return B_LENDIAN_TO_HOST_INT16(uid)
36863db34c8SAxel Dörfler			| (B_LENDIAN_TO_HOST_INT16(uid_high) << 16);
36963db34c8SAxel Dörfler	}
37063db34c8SAxel Dörfler
371bac6cc8aSAxel Dörfler	uint32 GroupID() const
37263db34c8SAxel Dörfler	{
37363db34c8SAxel Dörfler		return B_LENDIAN_TO_HOST_INT16(gid)
37463db34c8SAxel Dörfler			| (B_LENDIAN_TO_HOST_INT16(gid_high) << 16);
37563db34c8SAxel Dörfler	}
376a1b0ec30SJérôme Duval
377a1b0ec30SJérôme Duval	void SetMode(uint16 newMode)
378a1b0ec30SJérôme Duval	{
379a1b0ec30SJérôme Duval		mode = B_LENDIAN_TO_HOST_INT16(newMode);
380a1b0ec30SJérôme Duval	}
381a1b0ec30SJérôme Duval
382a1b0ec30SJérôme Duval	void UpdateMode(uint16 newMode, uint16 mask)
383a1b0ec30SJérôme Duval	{
384a1b0ec30SJérôme Duval		SetMode((Mode() & ~mask) | (newMode & mask));
385a1b0ec30SJérôme Duval	}
386a1b0ec30SJérôme Duval
387de66992bSJérôme Duval	void ClearFlag(uint32 mask)
388de66992bSJérôme Duval	{
389de66992bSJérôme Duval		flags &= ~B_HOST_TO_LENDIAN_INT32(mask);
390de66992bSJérôme Duval	}
391de66992bSJérôme Duval
392a1b0ec30SJérôme Duval	void SetFlag(uint32 mask)
393a1b0ec30SJérôme Duval	{
394a1b0ec30SJérôme Duval		flags |= B_HOST_TO_LENDIAN_INT32(mask);
395a1b0ec30SJérôme Duval	}
396a1b0ec30SJérôme Duval
397a1b0ec30SJérôme Duval	void SetFlags(uint32 newFlags)
398a1b0ec30SJérôme Duval	{
399a1b0ec30SJérôme Duval		flags = B_HOST_TO_LENDIAN_INT32(newFlags);
400a1b0ec30SJérôme Duval	}
401a1b0ec30SJérôme Duval
402a1b0ec30SJérôme Duval	void SetNumLinks(uint16 numLinks)
403a1b0ec30SJérôme Duval	{
404a1b0ec30SJérôme Duval		num_links = B_HOST_TO_LENDIAN_INT16(numLinks);
405a1b0ec30SJérôme Duval	}
406a1b0ec30SJérôme Duval
407a1b0ec30SJérôme Duval	void SetNumBlocks(uint32 numBlocks)
408a1b0ec30SJérôme Duval	{
409a1b0ec30SJérôme Duval		num_blocks = B_HOST_TO_LENDIAN_INT32(numBlocks);
410a1b0ec30SJérôme Duval	}
411a1b0ec30SJérôme Duval
412de66992bSJérôme Duval	void SetNumBlocks64(uint64 numBlocks)
413de66992bSJérôme Duval	{
414de66992bSJérôme Duval		num_blocks = B_HOST_TO_LENDIAN_INT32(numBlocks & 0xffffffff);
415de66992bSJérôme Duval		num_blocks_high = B_HOST_TO_LENDIAN_INT32(numBlocks >> 32);
416de66992bSJérôme Duval	}
417de66992bSJérôme Duval
418a1b0ec30SJérôme Duval	void SetNextOrphan(ino_t id)
419a1b0ec30SJérôme Duval	{
420a1b0ec30SJérôme Duval		deletion_time = B_HOST_TO_LENDIAN_INT32((uint32)id);
421a1b0ec30SJérôme Duval	}
422a1b0ec30SJérôme Duval
423a1b0ec30SJérôme Duval	void SetSize(off_t newSize)
424a1b0ec30SJérôme Duval	{
425a1b0ec30SJérôme Duval		size = B_HOST_TO_LENDIAN_INT32(newSize & 0xFFFFFFFF);
426a1b0ec30SJérôme Duval		if (S_ISREG(Mode()))
427a1b0ec30SJérôme Duval			size_high = B_HOST_TO_LENDIAN_INT32(newSize >> 32);
428a1b0ec30SJérôme Duval	}
429a1b0ec30SJérôme Duval
430a1b0ec30SJérôme Duval	void SetUserID(uint32 newUID)
431a1b0ec30SJérôme Duval	{
432a1b0ec30SJérôme Duval		uid = B_HOST_TO_LENDIAN_INT16(newUID & 0xFFFF);
433a1b0ec30SJérôme Duval		uid_high = B_HOST_TO_LENDIAN_INT16(newUID >> 16);
434a1b0ec30SJérôme Duval	}
435a1b0ec30SJérôme Duval
436a1b0ec30SJérôme Duval	void SetGroupID(uint32 newGID)
437a1b0ec30SJérôme Duval	{
438a1b0ec30SJérôme Duval		gid = B_HOST_TO_LENDIAN_INT16(newGID & 0xFFFF);
439a1b0ec30SJérôme Duval		gid_high = B_HOST_TO_LENDIAN_INT16(newGID >> 16);
440a1b0ec30SJérôme Duval	}
441a1b0ec30SJérôme Duval
442a1b0ec30SJérôme Duval	void SetExtendedAttributesBlock(uint32 block)
443a1b0ec30SJérôme Duval	{
444a1b0ec30SJérôme Duval		file_access_control = B_HOST_TO_LENDIAN_INT32(block);
445a1b0ec30SJérôme Duval	}
4466bfb10d3SJérôme Duval
4476bfb10d3SJérôme Duval	void SetExtraInodeSize(uint16 newSize)
4486bfb10d3SJérôme Duval	{
4496bfb10d3SJérôme Duval		extra_inode_size = B_HOST_TO_LENDIAN_INT16(newSize);
4506bfb10d3SJérôme Duval	}
45163db34c8SAxel Dörfler} _PACKED;
45263db34c8SAxel Dörfler
45363db34c8SAxel Dörfler#define EXT2_SUPER_BLOCK_MAGIC			0xef53
45463db34c8SAxel Dörfler
45563db34c8SAxel Dörfler// flags
45663db34c8SAxel Dörfler#define EXT2_INODE_SECURE_DELETION		0x00000001
45763db34c8SAxel Dörfler#define EXT2_INODE_UNDELETE				0x00000002
45863db34c8SAxel Dörfler#define EXT2_INODE_COMPRESSED			0x00000004
45963db34c8SAxel Dörfler#define EXT2_INODE_SYNCHRONOUS			0x00000008
46063db34c8SAxel Dörfler#define EXT2_INODE_IMMUTABLE			0x00000010
46163db34c8SAxel Dörfler#define EXT2_INODE_APPEND_ONLY			0x00000020
46263db34c8SAxel Dörfler#define EXT2_INODE_NO_DUMP				0x00000040
46363db34c8SAxel Dörfler#define EXT2_INODE_NO_ACCESS_TIME		0x00000080
46463db34c8SAxel Dörfler#define EXT2_INODE_DIRTY				0x00000100
46563db34c8SAxel Dörfler#define EXT2_INODE_COMPRESSED_BLOCKS	0x00000200
46663db34c8SAxel Dörfler#define EXT2_INODE_DO_NOT_COMPRESS		0x00000400
46763db34c8SAxel Dörfler#define EXT2_INODE_COMPRESSION_ERROR	0x00000800
46863db34c8SAxel Dörfler#define EXT2_INODE_BTREE				0x00001000
469919f9c41SJérôme Duval#define EXT2_INODE_INDEXED				0x00001000
470de66992bSJérôme Duval#define EXT2_INODE_HUGE_FILE			0x00040000
47163db34c8SAxel Dörfler
47263db34c8SAxel Dörfler#define EXT2_NAME_LENGTH	255
47363db34c8SAxel Dörfler
47463db34c8SAxel Dörflerstruct ext2_dir_entry {
47563db34c8SAxel Dörfler	uint32	inode_id;
47663db34c8SAxel Dörfler	uint16	length;
47763db34c8SAxel Dörfler	uint8	name_length;
47863db34c8SAxel Dörfler	uint8	file_type;
47963db34c8SAxel Dörfler	char	name[EXT2_NAME_LENGTH];
48063db34c8SAxel Dörfler
481