Honor chunk number for directories

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-12-09 02:48:59 +01:00
parent 0a040470e5
commit 7ed6c3e85f

View file

@ -52,7 +52,8 @@ struct grub_squash_super
grub_uint32_t creation_time; grub_uint32_t creation_time;
grub_uint32_t dummy2; grub_uint32_t dummy2;
grub_uint32_t dummy3[4]; grub_uint32_t dummy3[4];
grub_uint32_t root_ino; grub_uint16_t root_ino_offset;
grub_uint16_t root_ino_chunk;
grub_uint32_t dummy4; grub_uint32_t dummy4;
grub_uint64_t total_size; grub_uint64_t total_size;
grub_uint64_t exttbloffset; grub_uint64_t exttbloffset;
@ -71,11 +72,19 @@ struct grub_squash_inode
grub_uint16_t type; grub_uint16_t type;
grub_uint16_t dummy1[3]; grub_uint16_t dummy1[3];
grub_uint32_t mtime; grub_uint32_t mtime;
grub_uint16_t dummy2[6]; grub_uint16_t dummy2[2];
grub_uint16_t chunk;
grub_uint16_t dummy3[3];
grub_uint32_t offset; grub_uint32_t offset;
grub_uint32_t size; grub_uint32_t size;
} __attribute__ ((packed)); } __attribute__ ((packed));
static inline unsigned
decode_chunk_number (grub_uint16_t in)
{
return (grub_le_to_cpu16 (in) & 0xff) / 2;
}
/* Chunk-based. */ /* Chunk-based. */
struct grub_squash_dirent_header struct grub_squash_dirent_header
{ {
@ -102,8 +111,10 @@ struct grub_squash_dirent
static grub_err_t static grub_err_t
read_chunk (grub_disk_t disk, void *buf, grub_size_t len, read_chunk (grub_disk_t disk, void *buf, grub_size_t len,
grub_uint64_t chunk_start, grub_uint64_t offset) grub_uint64_t chunk, unsigned nchunk, grub_off_t offset)
{ {
grub_uint64_t chunk_start;
chunk_start = grub_le_to_cpu64 (chunk);
while (len > 0) while (len > 0)
{ {
grub_uint64_t csize; grub_uint64_t csize;
@ -116,9 +127,12 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len,
sizeof (d), &d); sizeof (d), &d);
if (err) if (err)
return err; return err;
if (offset < SQUASH_CHUNK_SIZE) if (!nchunk && offset < SQUASH_CHUNK_SIZE)
break; break;
offset -= SQUASH_CHUNK_SIZE; if (nchunk)
nchunk--;
else
offset -= SQUASH_CHUNK_SIZE;
chunk_start += 2 + (grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS); chunk_start += 2 + (grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS);
} }
@ -197,13 +211,15 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
/* FIXME: determine this. */ /* FIXME: determine this. */
unsigned numheaders = 1; unsigned numheaders = 1;
unsigned i, j; unsigned i, j;
for (j = 0; j < numheaders; j++) for (j = 0; j < numheaders; j++)
{ {
struct grub_squash_dirent_header dh; struct grub_squash_dirent_header dh;
grub_err_t err; grub_err_t err;
err = read_chunk (dir->data->disk, &dh, sizeof (dh), err = read_chunk (dir->data->disk, &dh, sizeof (dh),
grub_le_to_cpu64 (dir->data->sb.diroffset), off); dir->data->sb.diroffset,
decode_chunk_number (dir->ino.chunk), off);
if (err) if (err)
return 0; return 0;
off += sizeof (dh); off += sizeof (dh);
@ -217,14 +233,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
struct grub_squash_inode ino; struct grub_squash_inode ino;
err = read_chunk (dir->data->disk, &di, sizeof (di), err = read_chunk (dir->data->disk, &di, sizeof (di),
grub_le_to_cpu64 (dir->data->sb.diroffset), off); dir->data->sb.diroffset,
decode_chunk_number (dir->ino.chunk), off);
if (err) if (err)
return 0; return 0;
off += sizeof (di); off += sizeof (di);
err = read_chunk (dir->data->disk, &ino, sizeof (ino), err = read_chunk (dir->data->disk, &ino, sizeof (ino),
grub_le_to_cpu64 (dir->data->sb.inodeoffset), dir->data->sb.inodeoffset,
grub_le_to_cpu16 (di.ino)); 0,
grub_cpu_to_le16 (di.ino));
if (err) if (err)
return 0; return 0;
@ -233,7 +251,8 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
return 0; return 0;
err = read_chunk (dir->data->disk, buf, err = read_chunk (dir->data->disk, buf,
grub_le_to_cpu16 (di.namelen) + 1, grub_le_to_cpu16 (di.namelen) + 1,
grub_le_to_cpu64 (dir->data->sb.diroffset), off); dir->data->sb.diroffset,
decode_chunk_number (dir->ino.chunk), off);
if (err) if (err)
return 0; return 0;
@ -262,9 +281,10 @@ make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root)
grub_memset (root, 0, sizeof (*root)); grub_memset (root, 0, sizeof (*root));
root->data = data; root->data = data;
return read_chunk (data->disk, &root->ino, sizeof (root->ino), return read_chunk (data->disk, &root->ino, sizeof (root->ino),
grub_le_to_cpu64 (data->sb.inodeoffset), data->sb.inodeoffset,
grub_le_to_cpu32 (data->sb.root_ino)); decode_chunk_number (data->sb.root_ino_chunk),
grub_cpu_to_le16 (data->sb.root_ino_offset));
} }
static grub_err_t static grub_err_t