125 |
pupa_uint32_t indir_block; |
pupa_uint32_t indir_block; |
126 |
pupa_uint32_t double_indir_block; |
pupa_uint32_t double_indir_block; |
127 |
pupa_uint32_t tripple_indir_block; |
pupa_uint32_t tripple_indir_block; |
128 |
}; |
} blocks; |
129 |
char symlink[60]; |
char symlink[60]; |
130 |
}; |
}; |
131 |
pupa_uint32_t version; |
pupa_uint32_t version; |
181 |
|
|
182 |
/* Direct blocks. */ |
/* Direct blocks. */ |
183 |
if (fileblock < INDIRECT_BLOCKS) |
if (fileblock < INDIRECT_BLOCKS) |
184 |
blknr = pupa_le_to_cpu32 (inode->dir_blocks[fileblock]); |
blknr = pupa_le_to_cpu32 (inode->blocks.dir_blocks[fileblock]); |
185 |
/* Indirect. */ |
/* Indirect. */ |
186 |
else if (fileblock < INDIRECT_BLOCKS + EXT2_BLOCK_SIZE (data) / 4) |
else if (fileblock < INDIRECT_BLOCKS + EXT2_BLOCK_SIZE (data) / 4) |
187 |
{ |
{ |
188 |
pupa_uint32_t indir[EXT2_BLOCK_SIZE (data) / 4]; |
pupa_uint32_t indir[EXT2_BLOCK_SIZE (data) / 4]; |
189 |
|
|
190 |
if (pupa_disk_read (data->disk, pupa_le_to_cpu32 (inode->indir_block) |
if (pupa_disk_read (data->disk, |
191 |
|
pupa_le_to_cpu32 (inode->blocks.indir_block) |
192 |
<< LOG2_EXT2_BLOCK_SIZE (data), |
<< LOG2_EXT2_BLOCK_SIZE (data), |
193 |
0, EXT2_BLOCK_SIZE (data), (char *) indir)) |
0, EXT2_BLOCK_SIZE (data), (char *) indir)) |
194 |
return pupa_errno; |
return pupa_errno; |
205 |
pupa_uint32_t indir[EXT2_BLOCK_SIZE (data) / 4]; |
pupa_uint32_t indir[EXT2_BLOCK_SIZE (data) / 4]; |
206 |
|
|
207 |
if (pupa_disk_read (data->disk, |
if (pupa_disk_read (data->disk, |
208 |
pupa_le_to_cpu32 (inode->double_indir_block) |
pupa_le_to_cpu32 (inode->blocks.double_indir_block) |
209 |
<< LOG2_EXT2_BLOCK_SIZE (data), |
<< LOG2_EXT2_BLOCK_SIZE (data), |
210 |
0, EXT2_BLOCK_SIZE (data), (char *) indir)) |
0, EXT2_BLOCK_SIZE (data), (char *) indir)) |
211 |
return pupa_errno; |
return pupa_errno; |
234 |
|
|
235 |
/* Read LEN bytes from the file described by DATA starting with byte |
/* Read LEN bytes from the file described by DATA starting with byte |
236 |
POS. Return the amount of read bytes in READ. */ |
POS. Return the amount of read bytes in READ. */ |
237 |
static pupa_err_t |
static pupa_ssize_t |
238 |
pupa_ext2_read_file (struct pupa_ext2_data *data, int pos, |
pupa_ext2_read_file (struct pupa_ext2_data *data, int pos, |
239 |
unsigned int len, char *buf) |
unsigned int len, char *buf) |
240 |
{ |
{ |
252 |
{ |
{ |
253 |
int blknr; |
int blknr; |
254 |
int blockoff = pos % EXT2_BLOCK_SIZE (data); |
int blockoff = pos % EXT2_BLOCK_SIZE (data); |
255 |
int blockend = (len + pos) % EXT2_BLOCK_SIZE (data); |
int blockend = EXT2_BLOCK_SIZE (data); |
256 |
|
|
257 |
int skipfirst = 0; |
int skipfirst = 0; |
258 |
|
|
259 |
pupa_ext2_get_file_block (data, i, &blknr); |
pupa_ext2_get_file_block (data, i, &blknr); |
260 |
if (pupa_errno) |
if (pupa_errno) |
261 |
return pupa_errno; |
return -1; |
262 |
|
|
263 |
blknr = blknr << LOG2_EXT2_BLOCK_SIZE (data); |
blknr = blknr << LOG2_EXT2_BLOCK_SIZE (data); |
264 |
|
|
265 |
|
/* Last block. */ |
266 |
|
if (i == blockcnt - 1) |
267 |
|
blockend = (len + pos) % EXT2_BLOCK_SIZE (data); |
268 |
|
|
269 |
/* First block. */ |
/* First block. */ |
270 |
if (i == pos / EXT2_BLOCK_SIZE (data)) |
if (i == pos / EXT2_BLOCK_SIZE (data)) |
271 |
skipfirst = blockoff; |
{ |
272 |
|
skipfirst = blockoff; |
273 |
if (!blockend) |
blockend -= skipfirst; |
274 |
blockend = EXT2_BLOCK_SIZE (data); |
} |
|
|
|
|
blockend -= skipfirst; |
|
275 |
|
|
276 |
/* If the block number is 0 this block is not stored on disk but |
/* If the block number is 0 this block is not stored on disk but |
277 |
is zero filled instead. */ |
is zero filled instead. */ |
280 |
pupa_disk_read (data->disk, blknr, skipfirst, |
pupa_disk_read (data->disk, blknr, skipfirst, |
281 |
blockend, buf); |
blockend, buf); |
282 |
if (pupa_errno) |
if (pupa_errno) |
283 |
return pupa_errno; |
return -1; |
284 |
} |
} |
285 |
else |
else |
286 |
pupa_memset (buf, EXT2_BLOCK_SIZE (data) - skipfirst, 0); |
pupa_memset (buf, EXT2_BLOCK_SIZE (data) - skipfirst, 0); |