2
* Copyright (c) 2011 Martin Sucha
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
9
* - Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
* - The name of the author may not be used to endorse or promote products
15
* derived from this software without specific prior written permission.
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
/** @addtogroup libext2
37
#include "libext2_inode.h"
38
#include "libext2_superblock.h"
39
#include <byteorder.h>
43
* Get mode stored in the inode
45
* @param inode pointer to inode
47
uint32_t ext2_inode_get_mode(ext2_superblock_t *sb, ext2_inode_t *inode)
49
if (ext2_superblock_get_os(sb) == EXT2_SUPERBLOCK_OS_HURD) {
50
return ((uint32_t)uint16_t_le2host(inode->mode_high)) << 16 |
51
((uint32_t)uint16_t_le2host(inode->mode));
53
return uint16_t_le2host(inode->mode);
57
* Check whether inode is of given type
59
* @param sb pointer to superblock structure
60
* @param inode pointer to inode
61
* @param type EXT2_INODE_MODE_TYPE_* constant to check
63
bool ext2_inode_is_type(ext2_superblock_t *sb, ext2_inode_t *inode, uint32_t type)
65
uint32_t mode = ext2_inode_get_mode(sb, inode);
66
return (mode & EXT2_INODE_MODE_TYPE_MASK) == type;
70
* Get uid this inode is belonging to
72
* @param inode pointer to inode
74
uint32_t ext2_inode_get_user_id(ext2_superblock_t *sb, ext2_inode_t *inode)
76
uint32_t os = ext2_superblock_get_os(sb);
77
if (os == EXT2_SUPERBLOCK_OS_LINUX || os == EXT2_SUPERBLOCK_OS_HURD) {
78
return ((uint32_t)uint16_t_le2host(inode->user_id_high)) << 16 |
79
((uint32_t)uint16_t_le2host(inode->user_id));
81
return uint16_t_le2host(inode->user_id);
87
* For regular files in revision 1 and later, the high 32 bits of
88
* file size are stored in inode->size_high and are 0 otherwise
90
* @param inode pointer to inode
92
uint64_t ext2_inode_get_size(ext2_superblock_t *sb, ext2_inode_t *inode)
94
uint32_t major_rev = ext2_superblock_get_rev_major(sb);
96
if (major_rev > 0 && ext2_inode_is_type(sb, inode, EXT2_INODE_MODE_FILE)) {
97
return ((uint64_t)uint32_t_le2host(inode->size_high)) << 32 |
98
((uint64_t)uint32_t_le2host(inode->size));
100
return uint32_t_le2host(inode->size);
104
* Get gid this inode belongs to
106
* For Linux and Hurd, the high 16 bits are stored in OS dependent part
109
* @param inode pointer to inode
111
uint32_t ext2_inode_get_group_id(ext2_superblock_t *sb, ext2_inode_t *inode)
113
uint32_t os = ext2_superblock_get_os(sb);
114
if (os == EXT2_SUPERBLOCK_OS_LINUX || os == EXT2_SUPERBLOCK_OS_HURD) {
115
return ((uint32_t)uint16_t_le2host(inode->group_id_high)) << 16 |
116
((uint32_t)uint16_t_le2host(inode->group_id));
118
return uint16_t_le2host(inode->group_id);
122
* Get usage count (i.e. hard link count)
123
* A value of 1 is common, while 0 means that the inode should be freed
125
* @param inode pointer to inode
127
uint16_t ext2_inode_get_usage_count(ext2_inode_t *inode)
129
return uint16_t_le2host(inode->usage_count);
133
* Get number of 512-byte data blocks allocated for contents of the file
134
* represented by this inode.
135
* This should be multiple of block size unless fragments are used.
137
* @param inode pointer to inode
139
uint32_t ext2_inode_get_reserved_512_blocks(ext2_inode_t *inode)
141
return uint32_t_le2host(inode->reserved_512_blocks);
145
* Get number of blocks allocated for contents of the file
146
* represented by this inode.
148
* @param inode pointer to inode
150
uint32_t ext2_inode_get_reserved_blocks(ext2_superblock_t *sb,
153
return ext2_inode_get_reserved_512_blocks(inode) /
154
(ext2_superblock_get_block_size(sb) / 512);
160
* @param inode pointer to inode
162
uint32_t ext2_inode_get_flags(ext2_inode_t *inode) {
163
return uint32_t_le2host(inode->flags);
167
* Get direct block ID
169
* @param inode pointer to inode
170
* @param idx Index to block. Valid values are 0 <= idx < 12
172
uint32_t ext2_inode_get_direct_block(ext2_inode_t *inode, uint8_t idx)
174
assert(idx < EXT2_INODE_DIRECT_BLOCKS);
175
return uint32_t_le2host(inode->direct_blocks[idx]);
179
* Get indirect block ID
181
* @param inode pointer to inode
182
* @param idx Indirection level. Valid values are 0 <= idx < 3, where 0 is
183
* singly-indirect block and 2 is triply-indirect-block
185
uint32_t ext2_inode_get_indirect_block(ext2_inode_t *inode, uint8_t idx)
188
return uint32_t_le2host(inode->indirect_blocks[idx]);