Make type-dependent portion of inode an union

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-12-09 21:14:42 +01:00
parent 1fc7203971
commit 627a62fc70

View file

@ -75,13 +75,26 @@ struct grub_squash_inode
{ {
/* Same values as direlem types. */ /* Same values as direlem types. */
grub_uint16_t type; grub_uint16_t type;
grub_uint16_t dummy1[3]; grub_uint16_t dummy[3];
grub_uint32_t mtime; grub_uint32_t mtime;
grub_uint16_t dummy2[2]; union
grub_uint32_t chunk; {
grub_uint32_t fragment; struct {
grub_uint32_t offset; grub_uint16_t dummy[2];
grub_uint32_t size; grub_uint32_t chunk;
grub_uint32_t fragment;
grub_uint32_t offset;
grub_uint32_t size;
} file;
struct {
grub_uint16_t dummy1[2];
grub_uint32_t chunk;
grub_uint16_t dummy2[2];
grub_uint16_t size;
grub_uint16_t offset;
grub_uint16_t dummy3[2];
} dir;
};
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Chunk-based. */ /* Chunk-based. */
@ -245,12 +258,12 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
enum grub_fshelp_filetype filetype, enum grub_fshelp_filetype filetype,
grub_fshelp_node_t node)) grub_fshelp_node_t node))
{ {
grub_uint32_t off = grub_le_to_cpu32 (dir->ino.offset) >> 16; grub_uint32_t off = grub_le_to_cpu16 (dir->ino.dir.offset);
grub_uint32_t endoff; grub_uint32_t endoff;
unsigned i; unsigned i;
/* FIXME: why - 3 ? */ /* FIXME: why - 3 ? */
endoff = (grub_le_to_cpu32 (dir->ino.offset) & 0xffff) + off - 3; endoff = grub_le_to_cpu32 (dir->ino.dir.size) + off - 3;
while (off < endoff) while (off < endoff)
{ {
@ -259,7 +272,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
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) grub_le_to_cpu64 (dir->data->sb.diroffset)
+ grub_le_to_cpu32 (dir->ino.chunk), off); + grub_le_to_cpu32 (dir->ino.dir.chunk), off);
if (err) if (err)
return 0; return 0;
off += sizeof (dh); off += sizeof (dh);
@ -274,7 +287,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
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) grub_le_to_cpu64 (dir->data->sb.diroffset)
+ grub_le_to_cpu32 (dir->ino.chunk), off); + grub_le_to_cpu32 (dir->ino.dir.chunk), off);
if (err) if (err)
return 0; return 0;
off += sizeof (di); off += sizeof (di);
@ -292,7 +305,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
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) grub_le_to_cpu64 (dir->data->sb.diroffset)
+ grub_le_to_cpu32 (dir->ino.chunk), off); + grub_le_to_cpu32 (dir->ino.dir.chunk), off);
if (err) if (err)
return 0; return 0;
@ -395,7 +408,7 @@ grub_squash_open (struct grub_file *file, const char *name)
file->data = data; file->data = data;
data->ino = fdiro->ino; data->ino = fdiro->ino;
file->size = grub_le_to_cpu32 (fdiro->ino.size); file->size = grub_le_to_cpu32 (fdiro->ino.file.size);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@ -409,10 +422,10 @@ grub_squash_read_data (struct grub_squash_data *data,
grub_uint64_t a, b; grub_uint64_t a, b;
int compressed = 0; int compressed = 0;
if (grub_le_to_cpu16 (ino->fragment) == 0xffff) if (grub_le_to_cpu16 (ino->file.fragment) == 0xffff)
{ {
if (grub_le_to_cpu32 (ino->chunk)) if (grub_le_to_cpu32 (ino->file.chunk))
a = grub_le_to_cpu32 (ino->chunk); a = grub_le_to_cpu32 (ino->file.chunk);
else else
a = sizeof (struct grub_squash_super); a = sizeof (struct grub_squash_super);
compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_DATA); compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_DATA);
@ -422,14 +435,14 @@ grub_squash_read_data (struct grub_squash_data *data,
struct grub_squash_frag_desc frag; struct grub_squash_frag_desc frag;
err = read_chunk (disk, &frag, sizeof (frag), err = read_chunk (disk, &frag, sizeof (frag),
data->fragments, sizeof (frag) data->fragments, sizeof (frag)
* grub_le_to_cpu16 (ino->fragment)); * grub_le_to_cpu16 (ino->file.fragment));
if (err) if (err)
return -1; return -1;
a = grub_le_to_cpu64 (frag.offset) + grub_le_to_cpu32 (ino->chunk); a = grub_le_to_cpu64 (frag.offset) + grub_le_to_cpu32 (ino->file.chunk);
compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS); compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS);
} }
b = grub_le_to_cpu32 (data->ino.offset) + off; b = grub_le_to_cpu32 (data->ino.file.offset) + off;
/* FIXME: cache uncompressed chunks. */ /* FIXME: cache uncompressed chunks. */
if (compressed) if (compressed)