/* squash4.c - SquashFS */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2010  Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/err.h>
#include <grub/file.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/disk.h>
#include <grub/dl.h>
#include <grub/types.h>
#include <grub/fshelp.h>
#include <grub/deflate.h>
#include <minilzo.h>

#include "xz.h"
#include "xz_stream.h"

GRUB_MOD_LICENSE ("GPLv3+");

/*
  object         format      Pointed by
  superblock     RAW         Fixed offset (0)
  data           RAW ?       Fixed offset (60)
  inode table    Chunk       superblock
  dir table      Chunk       superblock
  fragment table Chunk       unk1
  unk1           RAW, Chunk  superblock
  unk2           RAW         superblock
  UID/GID        Chunk       exttblptr
  exttblptr      RAW         superblock

  UID/GID table is the array ot uint32_t
  unk1 contains pointer to fragment table followed by some chunk.
  unk2 containts one uint64_t
*/

struct grub_squash_super
{
  grub_uint32_t magic;
#define SQUASH_MAGIC 0x73717368
  grub_uint32_t dummy1;
  grub_uint32_t creation_time;
  grub_uint32_t block_size;
  grub_uint32_t dummy2;
  grub_uint16_t compression;
  grub_uint16_t dummy3;
  grub_uint64_t dummy4;
  grub_uint16_t root_ino_offset;
  grub_uint32_t root_ino_chunk;
  grub_uint16_t dummy5;
  grub_uint64_t total_size;
  grub_uint64_t exttbloffset;
  grub_uint64_t dummy6;
  grub_uint64_t inodeoffset;
  grub_uint64_t diroffset;
  grub_uint64_t unk1offset;
  grub_uint64_t unk2offset;
} GRUB_PACKED;

/* Chunk-based */
struct grub_squash_inode
{
  /* Same values as direlem types. */
  grub_uint16_t type;
  grub_uint16_t dummy[3];
  grub_uint32_t mtime;
  grub_uint32_t dummy2;
  union
  {
    struct {
      grub_uint32_t chunk;
      grub_uint32_t fragment;
      grub_uint32_t offset;
      grub_uint32_t size;
      grub_uint32_t block_size[0];
    }  GRUB_PACKED file;
    struct {
      grub_uint64_t chunk;
      grub_uint64_t size;
      grub_uint32_t dummy1[3];
      grub_uint32_t fragment;
      grub_uint32_t offset;
      grub_uint32_t dummy3;
      grub_uint32_t block_size[0];
    }  GRUB_PACKED long_file;
    struct {
      grub_uint32_t chunk;
      grub_uint32_t dummy;
      grub_uint16_t size;
      grub_uint16_t offset;
    } GRUB_PACKED dir;
    struct {
      grub_uint32_t dummy1;
      grub_uint32_t size;
      grub_uint32_t chunk;
      grub_uint32_t dummy2;
      grub_uint16_t dummy3;
      grub_uint16_t offset;
    } GRUB_PACKED long_dir;
    struct {
      grub_uint32_t dummy;
      grub_uint32_t namelen;
      char name[0];
    } GRUB_PACKED symlink;
  }  GRUB_PACKED;
} GRUB_PACKED;

struct grub_squash_cache_inode
{
  struct grub_squash_inode ino;
  grub_disk_addr_t ino_chunk;
  grub_uint16_t	ino_offset;
  grub_uint32_t *block_sizes;
  grub_disk_addr_t *cumulated_block_sizes;
};

/* Chunk-based.  */
struct grub_squash_dirent_header
{
  /* Actually the value is the number of elements - 1.  */
  grub_uint32_t nelems;
  grub_uint32_t ino_chunk;
  grub_uint32_t dummy;
} GRUB_PACKED;

struct grub_squash_dirent
{
  grub_uint16_t ino_offset;
  grub_uint16_t dummy;
  grub_uint16_t type;
  /* Actually the value is the length of name - 1.  */
  grub_uint16_t namelen;
  char name[0];
} GRUB_PACKED;

enum
  {
    SQUASH_TYPE_DIR = 1,
    SQUASH_TYPE_REGULAR = 2,
    SQUASH_TYPE_SYMLINK = 3,
    SQUASH_TYPE_LONG_DIR = 8,
    SQUASH_TYPE_LONG_REGULAR = 9,
  };


struct grub_squash_frag_desc
{
  grub_uint64_t offset;
  grub_uint32_t size;
  grub_uint32_t dummy;
} GRUB_PACKED;

enum
  {
    SQUASH_CHUNK_FLAGS = 0x8000,
    SQUASH_CHUNK_UNCOMPRESSED = 0x8000
  };

enum
  {
    SQUASH_BLOCK_FLAGS = 0x1000000,
    SQUASH_BLOCK_UNCOMPRESSED = 0x1000000
  };

enum
  {
    COMPRESSION_ZLIB = 1,
    COMPRESSION_LZO = 3,
    COMPRESSION_XZ = 4,
  };


#define SQUASH_CHUNK_SIZE 0x2000
#define XZBUFSIZ 0x2000

struct grub_squash_data
{
  grub_disk_t disk;
  struct grub_squash_super sb;
  struct grub_squash_cache_inode ino;
  grub_uint64_t fragments;
  int log2_blksz;
  grub_size_t blksz;
  grub_ssize_t (*decompress) (char *inbuf, grub_size_t insize, grub_off_t off,
			      char *outbuf, grub_size_t outsize,
			      struct grub_squash_data *data);
  struct xz_dec *xzdec;
  char *xzbuf;
};

struct grub_fshelp_node
{
  struct grub_squash_data *data;
  struct grub_squash_inode ino;
  grub_size_t stsize;
  struct 
  {
    grub_disk_addr_t ino_chunk;
    grub_uint16_t ino_offset;
  } stack[1];
};

static grub_err_t
read_chunk (struct grub_squash_data *data, void *buf, grub_size_t len,
	    grub_uint64_t chunk_start, grub_off_t offset)
{
  while (len > 0)
    {
      grub_uint64_t csize;
      grub_uint16_t d;
      grub_err_t err;
      while (1)
	{
	  err = grub_disk_read (data->disk,
				chunk_start >> GRUB_DISK_SECTOR_BITS,
				chunk_start & (GRUB_DISK_SECTOR_SIZE - 1),
				sizeof (d), &d);
	  if (err)
	    return err;
	  if (offset < SQUASH_CHUNK_SIZE)
	    break;
	  offset -= SQUASH_CHUNK_SIZE;
	  chunk_start += 2 + (grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS);
	}

      csize = SQUASH_CHUNK_SIZE - offset;
      if (csize > len)
	csize = len;
  
      if (grub_le_to_cpu16 (d) & SQUASH_CHUNK_UNCOMPRESSED)
	{
	  grub_disk_addr_t a = chunk_start + 2 + offset;
	  err = grub_disk_read (data->disk, (a >> GRUB_DISK_SECTOR_BITS),
				a & (GRUB_DISK_SECTOR_SIZE - 1),
				csize, buf);
	  if (err)
	    return err;
	}
      else
	{
	  char *tmp;
	  grub_size_t bsize = grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS; 
	  grub_disk_addr_t a = chunk_start + 2;
	  tmp = grub_malloc (bsize);
	  if (!tmp)
	    return grub_errno;
	  /* FIXME: buffer uncompressed data.  */
	  err = grub_disk_read (data->disk, (a >> GRUB_DISK_SECTOR_BITS),
				a & (GRUB_DISK_SECTOR_SIZE - 1),
				bsize, tmp);
	  if (err)
	    {
	      grub_free (tmp);
	      return err;
	    }

	  if (data->decompress (tmp, bsize, offset,
				buf, csize, data) < 0)
	    {
	      grub_free (tmp);
	      return grub_errno;
	    }
	  grub_free (tmp);
	}
      len -= csize;
      offset += csize;
      buf = (char *) buf + csize;
    }
  return GRUB_ERR_NONE;
}

static grub_ssize_t
zlib_decompress (char *inbuf, grub_size_t insize, grub_off_t off,
		 char *outbuf, grub_size_t outsize,
		 struct grub_squash_data *data __attribute__ ((unused)))
{
  return grub_zlib_decompress (inbuf, insize, off, outbuf, outsize);
}

static grub_ssize_t
lzo_decompress (char *inbuf, grub_size_t insize, grub_off_t off,
		char *outbuf, grub_size_t len, struct grub_squash_data *data)
{
  lzo_uint usize = data->blksz;
  grub_uint8_t *udata;

  if (usize < 8192)
    usize = 8192;

  udata = grub_malloc (usize);
  if (!udata)
    return -1;

  if (lzo1x_decompress_safe ((grub_uint8_t *) inbuf,
			     insize, udata, &usize, NULL) != LZO_E_OK)
    {
      grub_error (GRUB_ERR_BAD_FS, "incorrect compressed chunk");
      grub_free (udata);
      return -1;
    }
  grub_memcpy (outbuf, udata + off, len);
  grub_free (udata);
  return len;
}

static grub_ssize_t
xz_decompress (char *inbuf, grub_size_t insize, grub_off_t off,
	       char *outbuf, grub_size_t len, struct grub_squash_data *data)
{
  grub_size_t ret = 0;
  grub_off_t pos = 0;
  struct xz_buf buf;

  xz_dec_reset (data->xzdec);
  buf.in = (grub_uint8_t *) inbuf;
  buf.in_pos = 0;
  buf.in_size = insize;
  buf.out = (grub_uint8_t *) data->xzbuf;
  buf.out_pos = 0;
  buf.out_size = XZBUFSIZ;

  while (len)
    {
      enum xz_ret xzret;
      
      buf.out_pos = 0;

      xzret = xz_dec_run (data->xzdec, &buf);

      if (xzret != XZ_OK && xzret != XZ_STREAM_END)
	{
	  grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "invalid xz chunk");
	  return -1;
	}
      if (pos + buf.out_pos >= off)
	{
	  grub_ssize_t outoff = pos - off;
	  grub_size_t l;
	  if (outoff >= 0)
	    {
	      l = buf.out_pos;
	      if (l > len)
		l = len;
	      grub_memcpy (outbuf + outoff, buf.out, l);
	    }
	  else
	    {
	      outoff = -outoff;
	      l = buf.out_pos - outoff;
	      if (l > len)
		l = len;
	      grub_memcpy (outbuf, buf.out + outoff, l);
	    }
	  ret += l;
	  len -= l;
	}
      pos += buf.out_pos;
      if (xzret == XZ_STREAM_END)
	break;
    }
  return ret;
}

static struct grub_squash_data *
squash_mount (grub_disk_t disk)
{
  struct grub_squash_super sb;
  grub_err_t err;
  struct grub_squash_data *data;
  grub_uint64_t frag;

  err = grub_disk_read (disk, 0, 0, sizeof (sb), &sb);
  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
    grub_error (GRUB_ERR_BAD_FS, "not a squash4");
  if (err)
    return NULL;
  if (sb.magic != grub_cpu_to_le32_compile_time (SQUASH_MAGIC)
      || sb.block_size == 0
      || ((sb.block_size - 1) & sb.block_size))
    {
      grub_error (GRUB_ERR_BAD_FS, "not squash4");
      return NULL;
    }

  err = grub_disk_read (disk, 
			grub_le_to_cpu64 (sb.unk1offset)
			>> GRUB_DISK_SECTOR_BITS, 
			grub_le_to_cpu64 (sb.unk1offset)
			& (GRUB_DISK_SECTOR_SIZE - 1), sizeof (frag), &frag);
  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
    grub_error (GRUB_ERR_BAD_FS, "not a squash4");
  if (err)
    return NULL;

  data = grub_zalloc (sizeof (*data));
  if (!data)
    return NULL;
  data->sb = sb;
  data->disk = disk;
  data->fragments = grub_le_to_cpu64 (frag);

  switch (sb.compression)
    {
    case grub_cpu_to_le16_compile_time (COMPRESSION_ZLIB):
      data->decompress = zlib_decompress;
      break;
    case grub_cpu_to_le16_compile_time (COMPRESSION_LZO):
      data->decompress = lzo_decompress;
      break;
    case grub_cpu_to_le16_compile_time (COMPRESSION_XZ):
      data->decompress = xz_decompress;
      data->xzbuf = grub_malloc (XZBUFSIZ);
      if (!data->xzbuf)
	{
	  grub_free (data);
	  return NULL;
	}
      data->xzdec = xz_dec_init (1 << 16);
      if (!data->xzdec)
	{
	  grub_free (data->xzbuf);
	  grub_free (data);
	  return NULL;
	}
      break;
    default:
      grub_free (data);
      grub_error (GRUB_ERR_BAD_FS, "unsupported compression %d",
		  grub_le_to_cpu16 (sb.compression));
      return NULL;
    }

  data->blksz = grub_le_to_cpu32 (data->sb.block_size);
  for (data->log2_blksz = 0; 
       (1U << data->log2_blksz) < data->blksz;
       data->log2_blksz++);

  return data;
}

static char *
grub_squash_read_symlink (grub_fshelp_node_t node)
{
  char *ret;
  grub_err_t err;
  ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1);

  err = read_chunk (node->data, ret,
		    grub_le_to_cpu32 (node->ino.symlink.namelen),
		    grub_le_to_cpu64 (node->data->sb.inodeoffset)
		    + node->stack[node->stsize - 1].ino_chunk,
		    node->stack[node->stsize - 1].ino_offset
		    + (node->ino.symlink.name - (char *) &node->ino));
  if (err)
    {
      grub_free (ret);
      return NULL;
    }
  ret[grub_le_to_cpu32 (node->ino.symlink.namelen)] = 0;
  return ret;
}

static int
grub_squash_iterate_dir (grub_fshelp_node_t dir,
			 grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
  grub_uint32_t off;
  grub_uint32_t endoff;
  grub_uint64_t chunk;
  unsigned i;

  /* FIXME: why - 3 ? */
  switch (dir->ino.type)
    {
    case grub_cpu_to_le16_compile_time (SQUASH_TYPE_DIR):
      off = grub_le_to_cpu16 (dir->ino.dir.offset);
      endoff = grub_le_to_cpu16 (dir->ino.dir.size) + off - 3;
      chunk = grub_le_to_cpu32 (dir->ino.dir.chunk);
      break;
    case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_DIR):
      off = grub_le_to_cpu16 (dir->ino.long_dir.offset);
      endoff = grub_le_to_cpu16 (dir->ino.long_dir.size) + off - 3;
      chunk = grub_le_to_cpu32 (dir->ino.long_dir.chunk);
      break;
    default:
      grub_error (GRUB_ERR_BAD_FS, "unexpected ino type 0x%x",
		  grub_le_to_cpu16 (dir->ino.type));
      return 0;
    }

  {
    grub_fshelp_node_t node;
    node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
    if (!node)
      return 0;
    grub_memcpy (node, dir,
		 sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
    if (hook (".", GRUB_FSHELP_DIR, node, hook_data))
      return 1;

    if (dir->stsize != 1)
      {
	grub_err_t err;

	node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
	if (!node)
	  return 0;

	grub_memcpy (node, dir,
		     sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));

	node->stsize--;
	err = read_chunk (dir->data, &node->ino, sizeof (node->ino),
			  grub_le_to_cpu64 (dir->data->sb.inodeoffset)
			  + node->stack[node->stsize - 1].ino_chunk,
			  node->stack[node->stsize - 1].ino_offset);
	if (err)
	  return 0;

	if (hook ("..", GRUB_FSHELP_DIR, node, hook_data))
	  return 1;
      }
  }

  while (off < endoff)
    {
      struct grub_squash_dirent_header dh;
      grub_err_t err;

      err = read_chunk (dir->data, &dh, sizeof (dh),
			grub_le_to_cpu64 (dir->data->sb.diroffset)
			+ chunk, off);
      if (err)
	return 0;
      off += sizeof (dh);
      for (i = 0; i < (unsigned) grub_le_to_cpu32 (dh.nelems) + 1; i++)
	{
	  char *buf;
	  int r;
	  struct grub_fshelp_node *node;
	  enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG;
	  struct grub_squash_dirent di;
	  struct grub_squash_inode ino;

	  err = read_chunk (dir->data, &di, sizeof (di),
			    grub_le_to_cpu64 (dir->data->sb.diroffset)
			    + chunk, off);
	  if (err)
	    return 0;
	  off += sizeof (di);

	  err = read_chunk (dir->data, &ino, sizeof (ino),
			    grub_le_to_cpu64 (dir->data->sb.inodeoffset)
			    + grub_le_to_cpu32 (dh.ino_chunk),
			    grub_cpu_to_le16 (di.ino_offset));
	  if (err)
	    return 0;

	  buf = grub_malloc (grub_le_to_cpu16 (di.namelen) + 2);
	  if (!buf)
	    return 0;
	  err = read_chunk (dir->data, buf,
			    grub_le_to_cpu16 (di.namelen) + 1,
			    grub_le_to_cpu64 (dir->data->sb.diroffset)
			    + chunk, off);
	  if (err)
	    return 0;

	  off += grub_le_to_cpu16 (di.namelen) + 1;
	  buf[grub_le_to_cpu16 (di.namelen) + 1] = 0;
	  if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_DIR)
	    filetype = GRUB_FSHELP_DIR;
	  if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK)
	    filetype = GRUB_FSHELP_SYMLINK;

	  node = grub_malloc (sizeof (*node)
			      + (dir->stsize + 1) * sizeof (dir->stack[0]));
	  if (! node)
	    return 0;

	  grub_memcpy (node, dir,
		       sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));

	  node->ino = ino;
	  node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk);
	  node->stack[node->stsize].ino_offset = grub_le_to_cpu16 (di.ino_offset);
	  node->stsize++;
	  r = hook (buf, filetype, node, hook_data);

	  grub_free (buf);
	  if (r)
	    return r;
	}
    }
  return 0;
}

static grub_err_t
make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root)
{
  grub_memset (root, 0, sizeof (*root));
  root->data = data;
  root->stsize = 1;
  root->stack[0].ino_chunk = grub_le_to_cpu32 (data->sb.root_ino_chunk);
  root->stack[0].ino_offset = grub_cpu_to_le16 (data->sb.root_ino_offset);
 return read_chunk (data, &root->ino, sizeof (root->ino),
		    grub_le_to_cpu64 (data->sb.inodeoffset) 
		    + root->stack[0].ino_chunk,
		    root->stack[0].ino_offset);
}

static void
squash_unmount (struct grub_squash_data *data)
{
  if (data->xzdec)
    xz_dec_end (data->xzdec);
  grub_free (data->xzbuf);
  grub_free (data->ino.cumulated_block_sizes);
  grub_free (data->ino.block_sizes);
  grub_free (data);
}


/* Context for grub_squash_dir.  */
struct grub_squash_dir_ctx
{
  grub_fs_dir_hook_t hook;
  void *hook_data;
};

/* Helper for grub_squash_dir.  */
static int
grub_squash_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
		      grub_fshelp_node_t node, void *data)
{
  struct grub_squash_dir_ctx *ctx = data;
  struct grub_dirhook_info info;

  grub_memset (&info, 0, sizeof (info));
  info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
  info.mtimeset = 1;
  info.mtime = grub_le_to_cpu32 (node->ino.mtime);
  grub_free (node);
  return ctx->hook (filename, &info, ctx->hook_data);
}

static grub_err_t
grub_squash_dir (grub_device_t device, const char *path,
		 grub_fs_dir_hook_t hook, void *hook_data)
{
  struct grub_squash_dir_ctx ctx = { hook, hook_data };
  struct grub_squash_data *data = 0;
  struct grub_fshelp_node *fdiro = 0;
  struct grub_fshelp_node root;
  grub_err_t err;

  data = squash_mount (device->disk);
  if (! data)
    return grub_errno;

  err = make_root_node (data, &root);
  if (err)
    return err;

  grub_fshelp_find_file (path, &root, &fdiro, grub_squash_iterate_dir,
			 grub_squash_read_symlink, GRUB_FSHELP_DIR);
  if (!grub_errno)
    grub_squash_iterate_dir (fdiro, grub_squash_dir_iter, &ctx);

  squash_unmount (data);

  return grub_errno;
}

static grub_err_t
grub_squash_open (struct grub_file *file, const char *name)
{
  struct grub_squash_data *data = 0;
  struct grub_fshelp_node *fdiro = 0;
  struct grub_fshelp_node root;
  grub_err_t err;

  data = squash_mount (file->device->disk);
  if (! data)
    return grub_errno;

  err = make_root_node (data, &root);
  if (err)
    return err;

  grub_fshelp_find_file (name, &root, &fdiro, grub_squash_iterate_dir,
			 grub_squash_read_symlink, GRUB_FSHELP_REG);
  if (grub_errno)
    {
      squash_unmount (data);
      return grub_errno;
    }

  file->data = data;
  data->ino.ino = fdiro->ino;
  data->ino.block_sizes = NULL;
  data->ino.cumulated_block_sizes = NULL;
  data->ino.ino_chunk = fdiro->stack[fdiro->stsize - 1].ino_chunk;
  data->ino.ino_offset = fdiro->stack[fdiro->stsize - 1].ino_offset;

  switch (fdiro->ino.type)
    {
    case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR):
      file->size = grub_le_to_cpu64 (fdiro->ino.long_file.size);
      break;
    case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR):
      file->size = grub_le_to_cpu32 (fdiro->ino.file.size);
      break;
    default:
      {
	grub_uint16_t type = grub_le_to_cpu16 (fdiro->ino.type);
	grub_free (fdiro);
	squash_unmount (data);
	return grub_error (GRUB_ERR_BAD_FS, "unexpected ino type 0x%x", type);
      }
    }

  grub_free (fdiro);

  return GRUB_ERR_NONE;
}

static grub_ssize_t
direct_read (struct grub_squash_data *data, 
	     struct grub_squash_cache_inode *ino,
	     grub_off_t off, char *buf, grub_size_t len)
{
  grub_err_t err;
  grub_off_t cumulated_uncompressed_size = 0;
  grub_uint64_t a = 0;
  grub_size_t i;
  grub_size_t origlen = len;

  switch (ino->ino.type)
    {
    case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR):
      a = grub_le_to_cpu64 (ino->ino.long_file.chunk);
      break;
    case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR):
      a = grub_le_to_cpu32 (ino->ino.file.chunk);
      break;
    }

  if (!ino->block_sizes)
    {
      grub_off_t total_size = 0;
      grub_size_t total_blocks;
      grub_size_t block_offset = 0;
      switch (ino->ino.type)
	{
	case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR):
	  total_size = grub_le_to_cpu64 (ino->ino.long_file.size);
	  block_offset = ((char *) &ino->ino.long_file.block_size
			  - (char *) &ino->ino);
	  break;
	case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR):
	  total_size = grub_le_to_cpu32 (ino->ino.file.size);
	  block_offset = ((char *) &ino->ino.file.block_size
			  - (char *) &ino->ino);
	  break;
	}
      total_blocks = ((total_size + data->blksz - 1) >> data->log2_blksz);
      ino->block_sizes = grub_malloc (total_blocks
				      * sizeof (ino->block_sizes[0]));
      ino->cumulated_block_sizes = grub_malloc (total_blocks
						* sizeof (ino->cumulated_block_sizes[0]));
      if (!ino->block_sizes || !ino->cumulated_block_sizes)
	{
	  grub_free (ino->block_sizes);
	  grub_free (ino->cumulated_block_sizes);
	  ino->block_sizes = 0;
	  ino->cumulated_block_sizes = 0;
	  return -1;
	}
      err = read_chunk (data, ino->block_sizes,
			total_blocks * sizeof (ino->block_sizes[0]),
			grub_le_to_cpu64 (data->sb.inodeoffset)
			+ ino->ino_chunk,
			ino->ino_offset + block_offset);
      if (err)
	{
	  grub_free (ino->block_sizes);
	  grub_free (ino->cumulated_block_sizes);
	  ino->block_sizes = 0;
	  ino->cumulated_block_sizes = 0;
	  return -1;
	}
      ino->cumulated_block_sizes[0] = 0;
      for (i = 1; i < total_blocks; i++)
	ino->cumulated_block_sizes[i] = ino->cumulated_block_sizes[i - 1]
	  + (grub_le_to_cpu32 (ino->block_sizes[i - 1]) & ~SQUASH_BLOCK_FLAGS);
    }

  if (a == 0)
    a = sizeof (struct grub_squash_super);
  i = off >> data->log2_blksz;
  cumulated_uncompressed_size = data->blksz * (grub_disk_addr_t) i;
  while (cumulated_uncompressed_size < off + len)
    {
      grub_size_t boff, curread;
      boff = off - cumulated_uncompressed_size;
      curread = data->blksz - boff;
      if (curread > len)
	curread = len;
      if (!ino->block_sizes[i])
	{
	  /* Sparse block */
	  grub_memset (buf, '\0', curread);
	}
      else if (!(ino->block_sizes[i]
	    & grub_cpu_to_le32_compile_time (SQUASH_BLOCK_UNCOMPRESSED)))
	{
	  char *block;
	  grub_size_t csize;
	  csize = grub_le_to_cpu32 (ino->block_sizes[i]) & ~SQUASH_BLOCK_FLAGS;
	  block = grub_malloc (csize);
	  if (!block)
	    return -1;
	  err = grub_disk_read (data->disk,
				(ino->cumulated_block_sizes[i] + a)
				>> GRUB_DISK_SECTOR_BITS,
				(ino->cumulated_block_sizes[i] + a)
				& (GRUB_DISK_SECTOR_SIZE - 1),
				csize, block);
	  if (err)
	    {
	      grub_free (block);
	      return -1;
	    }
	  if (data->decompress (block, csize, boff, buf, curread, data)
	      != (grub_ssize_t) curread)
	    {
	      grub_free (block);
	      if (!grub_errno)
		grub_error (GRUB_ERR_BAD_FS, "incorrect compressed chunk");
	      return -1;
	    }
	  grub_free (block);
	}
      else
	err = grub_disk_read (data->disk, 
			      (ino->cumulated_block_sizes[i] + a + boff)
			      >> GRUB_DISK_SECTOR_BITS,
			      (ino->cumulated_block_sizes[i] + a + boff)
			      & (GRUB_DISK_SECTOR_SIZE - 1),
			      curread, buf);
      if (err)
	return -1;
      off += curread;
      len -= curread;
      buf += curread;
      cumulated_uncompressed_size += grub_le_to_cpu32 (data->sb.block_size);
      i++;
    }
  return origlen;
}


static grub_ssize_t
grub_squash_read (grub_file_t file, char *buf, grub_size_t len)
{
  struct grub_squash_data *data = file->data;
  struct grub_squash_cache_inode *ino = &data->ino;
  grub_off_t off = file->offset;
  grub_err_t err;
  grub_uint64_t a, b;
  grub_uint32_t fragment = 0;
  int compressed = 0;
  struct grub_squash_frag_desc frag;
  grub_off_t direct_len;
  grub_uint64_t mask = grub_le_to_cpu32 (data->sb.block_size) - 1;
  grub_size_t orig_len = len;

  switch (ino->ino.type)
    {
    case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR):
      fragment = grub_le_to_cpu32 (ino->ino.long_file.fragment);
      break;
    case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR):
      fragment = grub_le_to_cpu32 (ino->ino.file.fragment);
      break;
    }

  /* Squash may pack file tail as fragment. So read initial part directly and
     get tail from fragments */
  direct_len = fragment == 0xffffffff ? file->size : file->size & ~mask;
  if (off < direct_len)
    {
      grub_size_t read_len = direct_len - off;
      grub_ssize_t res;

      if (read_len > len)
	read_len = len;
      res = direct_read (data, ino, off, buf, read_len);
      if ((grub_size_t) res != read_len)
	return -1; /* FIXME: is short read possible here? */
      len -= read_len;
      if (!len)
	return read_len;
      buf += read_len;
      off = 0;
    }
  else
    off -= direct_len;
 
  err = read_chunk (data, &frag, sizeof (frag),
		    data->fragments, sizeof (frag) * fragment);
  if (err)
    return -1;
  a = grub_le_to_cpu64 (frag.offset);
  compressed = !(frag.size & grub_cpu_to_le32_compile_time (SQUASH_BLOCK_UNCOMPRESSED));
  if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR))
    b = grub_le_to_cpu32 (ino->ino.long_file.offset) + off;
  else
    b = grub_le_to_cpu32 (ino->ino.file.offset) + off;
  
  /* FIXME: cache uncompressed chunks.  */
  if (compressed)
    {
      char *block;
      block = grub_malloc (grub_le_to_cpu32 (frag.size));
      if (!block)
	return -1;
      err = grub_disk_read (data->disk,
			    a >> GRUB_DISK_SECTOR_BITS,
			    a & (GRUB_DISK_SECTOR_SIZE - 1),
			    grub_le_to_cpu32 (frag.size), block);
      if (err)
	{
	  grub_free (block);
	  return -1;
	}
      if (data->decompress (block, grub_le_to_cpu32 (frag.size),
			    b, buf, len, data)
	  != (grub_ssize_t) len)
	{
	  grub_free (block);
	  if (!grub_errno)
	    grub_error (GRUB_ERR_BAD_FS, "incorrect compressed chunk");
	  return -1;
	}
      grub_free (block);
    }
  else
    {
      err = grub_disk_read (data->disk, (a + b) >> GRUB_DISK_SECTOR_BITS,
			  (a + b) & (GRUB_DISK_SECTOR_SIZE - 1), len, buf);
      if (err)
	return -1;
    }
  return orig_len;
}

static grub_err_t
grub_squash_close (grub_file_t file)
{
  squash_unmount (file->data);
  return GRUB_ERR_NONE;
}

static grub_err_t
grub_squash_mtime (grub_device_t dev, grub_int32_t *tm)
{
  struct grub_squash_data *data = 0;

  data = squash_mount (dev->disk);
  if (! data)
    return grub_errno;
  *tm = grub_le_to_cpu32 (data->sb.creation_time);
  squash_unmount (data);
  return GRUB_ERR_NONE;
} 

static struct grub_fs grub_squash_fs =
  {
    .name = "squash4",
    .dir = grub_squash_dir,
    .open = grub_squash_open,
    .read = grub_squash_read,
    .close = grub_squash_close,
    .mtime = grub_squash_mtime,
#ifdef GRUB_UTIL
    .reserved_first_sector = 0,
    .blocklist_install = 0,
#endif
    .next = 0
  };

GRUB_MOD_INIT(squash4)
{
  grub_fs_register (&grub_squash_fs);
}

GRUB_MOD_FINI(squash4)
{
  grub_fs_unregister (&grub_squash_fs);
}

