mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-06-09 23:36:03 +09:00
ext4: Fix handling of sparse files
A sparse file may have regions not mapped by any extents, at the start or at the end of the file, or anywhere between, thus not finding a matching extent region is never an error. Found by python filesystem tests. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
This commit is contained in:
parent
d8c1e0331a
commit
f81db56f2f
|
@ -1617,12 +1617,13 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
|
||||||
- get_fs()->dev_desc->log2blksz;
|
- get_fs()->dev_desc->log2blksz;
|
||||||
|
|
||||||
if (le32_to_cpu(inode->flags) & EXT4_EXTENTS_FL) {
|
if (le32_to_cpu(inode->flags) & EXT4_EXTENTS_FL) {
|
||||||
|
long int startblock, endblock;
|
||||||
char *buf = zalloc(blksz);
|
char *buf = zalloc(blksz);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
struct ext4_extent_header *ext_block;
|
struct ext4_extent_header *ext_block;
|
||||||
struct ext4_extent *extent;
|
struct ext4_extent *extent;
|
||||||
int i = -1;
|
int i;
|
||||||
ext_block =
|
ext_block =
|
||||||
ext4fs_get_extent_block(ext4fs_root, buf,
|
ext4fs_get_extent_block(ext4fs_root, buf,
|
||||||
(struct ext4_extent_header *)
|
(struct ext4_extent_header *)
|
||||||
|
@ -1636,28 +1637,26 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
|
||||||
|
|
||||||
extent = (struct ext4_extent *)(ext_block + 1);
|
extent = (struct ext4_extent *)(ext_block + 1);
|
||||||
|
|
||||||
do {
|
for (i = 0; i < le16_to_cpu(ext_block->eh_entries); i++) {
|
||||||
i++;
|
startblock = le32_to_cpu(extent[i].ee_block);
|
||||||
if (i >= le16_to_cpu(ext_block->eh_entries))
|
endblock = startblock + le16_to_cpu(extent[i].ee_len);
|
||||||
break;
|
|
||||||
} while (fileblock >= le32_to_cpu(extent[i].ee_block));
|
if (startblock > fileblock) {
|
||||||
if (--i >= 0) {
|
/* Sparse file */
|
||||||
fileblock -= le32_to_cpu(extent[i].ee_block);
|
|
||||||
if (fileblock >= le16_to_cpu(extent[i].ee_len)) {
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
start = le16_to_cpu(extent[i].ee_start_hi);
|
} else if (fileblock < endblock) {
|
||||||
start = (start << 32) +
|
start = le16_to_cpu(extent[i].ee_start_hi);
|
||||||
|
start = (start << 32) +
|
||||||
le32_to_cpu(extent[i].ee_start_lo);
|
le32_to_cpu(extent[i].ee_start_lo);
|
||||||
free(buf);
|
free(buf);
|
||||||
return fileblock + start;
|
return (fileblock - startblock) + start;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Extent Error\n");
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Direct blocks. */
|
/* Direct blocks. */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user