1/*
2 * Copyright 2001-2009, Axel Dörfler, axeld@pinc-software.de.
3 * This file may be used under the terms of the MIT License.
4 */
5#ifndef UTILITY_H
6#define UTILITY_H
7
8
9#include "system_dependencies.h"
10
11#include "bfs.h"
12
13
14enum inode_type {
15	S_DIRECTORY		= S_IFDIR,
16	S_FILE			= S_IFREG,
17	S_SYMLINK		= S_IFLNK,
18
19	S_INDEX_TYPES	= (S_STR_INDEX | S_INT_INDEX | S_UINT_INDEX
20						| S_LONG_LONG_INDEX | S_ULONG_LONG_INDEX
21						| S_FLOAT_INDEX | S_DOUBLE_INDEX),
22
23	S_EXTENDED_TYPES = (S_ATTR_DIR | S_ATTR | S_INDEX_DIR)
24};
25
26
27/*!	\a to must be a power of 2.
28*/
29template<typename IntType, typename RoundType>
30inline IntType
31round_up(const IntType& value, const RoundType& to)
32{
33	return (value + (to - 1)) & ~((IntType)to - 1);
34}
35
36
37/*!	\a to must be a power of 2.
38*/
39template<typename IntType, typename RoundType>
40inline IntType
41round_down(const IntType& value, const RoundType& to)
42{
43	return value & ~((IntType)to - 1);
44}
45
46
47inline int32
48divide_roundup(int32 num, int32 divisor)
49{
50	return (num + divisor - 1) / divisor;
51}
52
53
54inline int64
55divide_roundup(int64 num, int32 divisor)
56{
57	return (num + divisor - 1) / divisor;
58}
59
60
61inline int
62get_shift(uint64 i)
63{
64	int c;
65	c = 0;
66	while (i > 1) {
67		i >>= 1;
68		c++;
69	}
70	return c;
71}
72
73
74inline int32
75runs_per_block(uint32 blockSize)
76{
77#ifdef _BOOT_MODE
78	using namespace BFS;
79#endif
80
81	return blockSize / sizeof(struct block_run);
82}
83
84
85inline int32
86double_indirect_max_direct_size(uint32 baseLength, uint32 blockSize)
87{
88	return baseLength * blockSize;
89}
90
91
92inline int32
93double_indirect_max_indirect_size(uint32 baseLength, uint32 blockSize)
94{
95	return baseLength * double_indirect_max_direct_size(baseLength, blockSize)
96		* runs_per_block(blockSize);
97}
98
99
100inline void
101get_double_indirect_sizes(uint32 baseLength, uint32 blockSize,
102	int32& runsPerBlock, int32& directSize, int32& indirectSize)
103{
104	runsPerBlock = runs_per_block(blockSize);
105	directSize = double_indirect_max_direct_size(baseLength, blockSize);
106	indirectSize = baseLength * directSize * runsPerBlock;
107}
108
109
110inline uint32
111key_align(uint32 data)
112{
113	// rounds up to the next off_t boundary
114	return (data + sizeof(off_t) - 1) & ~(sizeof(off_t) - 1);
115}
116
117
118inline bool
119is_index(int mode)
120{
121	return (mode & (S_EXTENDED_TYPES | 0777)) == S_INDEX_DIR;
122		// That's a stupid check, but the only method to differentiate the
123		// index root from an index.
124}
125
126
127inline bool
128is_directory(int mode)
129{
130	return (mode & (S_EXTENDED_TYPES | S_IFDIR)) == S_IFDIR;
131}
132
133
134/*!	Converts the open mode, the open flags given to bfs_open(), into
135	access modes, e.g. since O_RDONLY requires read access to the
136	file, it will be converted to R_OK.
137*/
138inline int
139open_mode_to_access(int openMode)
140{
141	openMode &= O_RWMASK;
142	if (openMode == O_RDONLY)
143		return R_OK;
144	if (openMode == O_WRONLY)
145		return W_OK;
146
147	return R_OK | W_OK;
148}
149
150#endif	// UTILITY_H
151