/* ufs.c - Unix File System */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2004,2005,2007,2008,2009  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/i18n.h>

GRUB_MOD_LICENSE ("GPLv3+");

#ifdef MODE_UFS2
#define GRUB_UFS_MAGIC		0x19540119
#else
#define GRUB_UFS_MAGIC		0x11954
#endif

#define GRUB_UFS_INODE		2
#define GRUB_UFS_FILETYPE_DIR	4
#define GRUB_UFS_FILETYPE_LNK	10
#define GRUB_UFS_MAX_SYMLNK_CNT	8

#define GRUB_UFS_DIRBLKS	12
#define GRUB_UFS_INDIRBLKS	3

#define GRUB_UFS_ATTR_TYPE      0160000
#define GRUB_UFS_ATTR_FILE	0100000
#define GRUB_UFS_ATTR_DIR	0040000
#define GRUB_UFS_ATTR_LNK       0120000

#define GRUB_UFS_VOLNAME_LEN	32

#ifdef MODE_BIGENDIAN
#define grub_ufs_to_cpu16 grub_be_to_cpu16
#define grub_ufs_to_cpu32 grub_be_to_cpu32
#define grub_ufs_to_cpu64 grub_be_to_cpu64
#define grub_cpu_to_ufs32_compile_time grub_cpu_to_be32_compile_time
#else
#define grub_ufs_to_cpu16 grub_le_to_cpu16
#define grub_ufs_to_cpu32 grub_le_to_cpu32
#define grub_ufs_to_cpu64 grub_le_to_cpu64
#define grub_cpu_to_ufs32_compile_time grub_cpu_to_le32_compile_time
#endif

#ifdef MODE_UFS2
typedef grub_uint64_t grub_ufs_blk_t;
static inline grub_disk_addr_t
grub_ufs_to_cpu_blk (grub_ufs_blk_t blk)
{
  return grub_ufs_to_cpu64 (blk);
}
#else
typedef grub_uint32_t grub_ufs_blk_t;
static inline grub_disk_addr_t
grub_ufs_to_cpu_blk (grub_ufs_blk_t blk)
{
  return grub_ufs_to_cpu32 (blk);
}
#endif

/* Calculate in which group the inode can be found.  */
#define UFS_BLKSZ(sblock) (grub_ufs_to_cpu32 (sblock->bsize))
#define UFS_LOG_BLKSZ(sblock) (data->log2_blksz)

#ifdef MODE_UFS2
#define INODE_ENDIAN(data,field,bits1,bits2) grub_ufs_to_cpu##bits2 (data->inode.field)
#else
#define INODE_ENDIAN(data,field,bits1,bits2) grub_ufs_to_cpu##bits1 (data->inode.field)
#endif

#define INODE_SIZE(data) grub_ufs_to_cpu64 (data->inode.size)
#define INODE_MODE(data) grub_ufs_to_cpu16 (data->inode.mode)
#ifdef MODE_UFS2
#define LOG_INODE_BLKSZ 3
#else
#define LOG_INODE_BLKSZ 2
#endif
#ifdef MODE_UFS2
#define UFS_INODE_PER_BLOCK 2
#else
#define UFS_INODE_PER_BLOCK 4
#endif
#define INODE_DIRBLOCKS(data,blk) INODE_ENDIAN \
                                   (data,blocks.dir_blocks[blk],32,64)
#define INODE_INDIRBLOCKS(data,blk) INODE_ENDIAN \
                                     (data,blocks.indir_blocks[blk],32,64)

/* The blocks on which the superblock can be found.  */
static int sblocklist[] = { 128, 16, 0, 512, -1 };

struct grub_ufs_sblock
{
  grub_uint8_t unused[16];
  /* The offset of the inodes in the cylinder group.  */
  grub_uint32_t inoblk_offs;

  grub_uint8_t unused2[4];

  /* The start of the cylinder group.  */
  grub_uint32_t cylg_offset;
  grub_uint32_t cylg_mask;

  grub_uint32_t mtime;
  grub_uint8_t unused4[12];

  /* The size of a block in bytes.  */
  grub_int32_t bsize;
  grub_uint8_t unused5[48];

  /* The size of filesystem blocks to disk blocks.  */
  grub_uint32_t log2_blksz;
  grub_uint8_t unused6[40];
  grub_uint32_t uuidhi;
  grub_uint32_t uuidlow;
  grub_uint8_t unused7[32];

  /* Inodes stored per cylinder group.  */
  grub_uint32_t ino_per_group;

  /* The frags per cylinder group.  */
  grub_uint32_t frags_per_group;

  grub_uint8_t unused8[488];

  /* Volume name for UFS2.  */
  grub_uint8_t volume_name[GRUB_UFS_VOLNAME_LEN];
  grub_uint8_t unused9[360];

  grub_uint64_t mtime2;
  grub_uint8_t unused10[292];

  /* Magic value to check if this is really a UFS filesystem.  */
  grub_uint32_t magic;
};

#ifdef MODE_UFS2
/* UFS inode.  */
struct grub_ufs_inode
{
  grub_uint16_t mode;
  grub_uint16_t nlinks;
  grub_uint32_t uid;
  grub_uint32_t gid;
  grub_uint32_t blocksize;
  grub_uint64_t size;
  grub_int64_t nblocks;
  grub_uint64_t atime;
  grub_uint64_t mtime;
  grub_uint64_t ctime;
  grub_uint64_t create_time;
  grub_uint32_t atime_usec;
  grub_uint32_t mtime_usec;
  grub_uint32_t ctime_usec;
  grub_uint32_t create_time_sec;
  grub_uint32_t gen;
  grub_uint32_t kernel_flags;
  grub_uint32_t flags;
  grub_uint32_t extsz;
  grub_uint64_t ext[2];
  union
  {
    struct
    {
      grub_uint64_t dir_blocks[GRUB_UFS_DIRBLKS];
      grub_uint64_t indir_blocks[GRUB_UFS_INDIRBLKS];
    } blocks;
    grub_uint8_t symlink[(GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS) * 8];
  };

  grub_uint8_t unused[24];
} GRUB_PACKED;
#else
/* UFS inode.  */
struct grub_ufs_inode
{
  grub_uint16_t mode;
  grub_uint16_t nlinks;
  grub_uint16_t uid;
  grub_uint16_t gid;
  grub_uint64_t size;
  grub_uint32_t atime;
  grub_uint32_t atime_usec;
  grub_uint32_t mtime;
  grub_uint32_t mtime_usec;
  grub_uint32_t ctime;
  grub_uint32_t ctime_usec;
  union
  {
    struct
    {
      grub_uint32_t dir_blocks[GRUB_UFS_DIRBLKS];
      grub_uint32_t indir_blocks[GRUB_UFS_INDIRBLKS];
    } blocks;
    grub_uint8_t symlink[(GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS) * 4];
  };
  grub_uint32_t flags;
  grub_uint32_t nblocks;
  grub_uint32_t gen;
  grub_uint32_t unused;
  grub_uint8_t pad[12];
} GRUB_PACKED;
#endif

/* Directory entry.  */
struct grub_ufs_dirent
{
  grub_uint32_t ino;
  grub_uint16_t direntlen;
  union
  {
    grub_uint16_t namelen;
    struct
    {
      grub_uint8_t filetype_bsd;
      grub_uint8_t namelen_bsd;
    };
  };
} GRUB_PACKED;

/* Information about a "mounted" ufs filesystem.  */
struct grub_ufs_data
{
  struct grub_ufs_sblock sblock;
  grub_disk_t disk;
  struct grub_ufs_inode inode;
  int ino;
  int linknest;
  int log2_blksz;
};

static grub_dl_t my_mod;

/* Forward declaration.  */
static grub_err_t grub_ufs_find_file (struct grub_ufs_data *data,
				      const char *path);


static grub_disk_addr_t
grub_ufs_get_file_block (struct grub_ufs_data *data, grub_disk_addr_t blk)
{
  unsigned long indirsz;
  int log2_blksz, log_indirsz;

  /* Direct.  */
  if (blk < GRUB_UFS_DIRBLKS)
    return INODE_DIRBLOCKS (data, blk);

  log2_blksz = grub_ufs_to_cpu32 (data->sblock.log2_blksz);

  blk -= GRUB_UFS_DIRBLKS;

  log_indirsz = data->log2_blksz - LOG_INODE_BLKSZ;
  indirsz = 1 << log_indirsz;

  /* Single indirect block.  */
  if (blk < indirsz)
    {
      grub_ufs_blk_t indir;
      grub_disk_read (data->disk,
		      ((grub_disk_addr_t) INODE_INDIRBLOCKS (data, 0))
		      << log2_blksz,
		      blk * sizeof (indir), sizeof (indir), &indir);
      return indir;
    }
  blk -= indirsz;

  /* Double indirect block.  */
  if (blk < (grub_disk_addr_t) indirsz * (grub_disk_addr_t) indirsz)
    {
      grub_ufs_blk_t indir;

      grub_disk_read (data->disk,
		      ((grub_disk_addr_t) INODE_INDIRBLOCKS (data, 1))
		      << log2_blksz,
		      (blk >> log_indirsz) * sizeof (indir),
		      sizeof (indir), &indir);
      grub_disk_read (data->disk,
		      grub_ufs_to_cpu_blk (indir) << log2_blksz,
		      (blk & ((1 << log_indirsz) - 1)) * sizeof (indir),
		      sizeof (indir), &indir);

      return indir;
    }

  blk -= (grub_disk_addr_t) indirsz * (grub_disk_addr_t) indirsz;

  /* Triple indirect block.  */
  if (!(blk >> (3 * log_indirsz)))
    {
      grub_ufs_blk_t indir;

      grub_disk_read (data->disk,
		      ((grub_disk_addr_t) INODE_INDIRBLOCKS (data, 2))
		      << log2_blksz,
		      (blk >> (2 * log_indirsz)) * sizeof (indir),
		      sizeof (indir), &indir);
      grub_disk_read (data->disk,
		      grub_ufs_to_cpu_blk (indir) << log2_blksz,
		      ((blk >> log_indirsz)
		       & ((1 << log_indirsz) - 1)) * sizeof (indir),
		      sizeof (indir), &indir);

      grub_disk_read (data->disk,
		      grub_ufs_to_cpu_blk (indir) << log2_blksz,
		      (blk & ((1 << log_indirsz) - 1)) * sizeof (indir),
		      sizeof (indir), &indir);

      return indir;
    }

  grub_error (GRUB_ERR_BAD_FS,
	      "ufs does not support quadruple indirect blocks");
  return 0;
}


/* Read LEN bytes from the file described by DATA starting with byte
   POS.  Return the amount of read bytes in READ.  */
static grub_ssize_t
grub_ufs_read_file (struct grub_ufs_data *data,
		    grub_disk_read_hook_t read_hook, void *read_hook_data,
		    grub_off_t pos, grub_size_t len, char *buf)
{
  struct grub_ufs_sblock *sblock = &data->sblock;
  grub_off_t i;
  grub_off_t blockcnt;

  /* Adjust len so it we can't read past the end of the file.  */
  if (len + pos > INODE_SIZE (data))
    len = INODE_SIZE (data) - pos;

  blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) >> UFS_LOG_BLKSZ (sblock);

  for (i = pos >> UFS_LOG_BLKSZ (sblock); i < blockcnt; i++)
    {
      grub_disk_addr_t blknr;
      grub_off_t blockoff;
      grub_off_t blockend = UFS_BLKSZ (sblock);

      int skipfirst = 0;

      blockoff = pos & (UFS_BLKSZ (sblock) - 1);

      blknr = grub_ufs_get_file_block (data, i);
      if (grub_errno)
	return -1;

      /* Last block.  */
      if (i == blockcnt - 1)
	{
	  blockend = (len + pos) & (UFS_BLKSZ (sblock) - 1);

	  if (!blockend)
	    blockend = UFS_BLKSZ (sblock);
	}

      /* First block.  */
      if (i == (pos >> UFS_LOG_BLKSZ (sblock)))
	{
	  skipfirst = blockoff;
	  blockend -= skipfirst;
	}

      /* XXX: If the block number is 0 this block is not stored on
	 disk but is zero filled instead.  */
      if (blknr)
	{
	  data->disk->read_hook = read_hook;
	  data->disk->read_hook_data = read_hook_data;
	  grub_disk_read (data->disk,
			  blknr << grub_ufs_to_cpu32 (data->sblock.log2_blksz),
			  skipfirst, blockend, buf);
	  data->disk->read_hook = 0;
	  if (grub_errno)
	    return -1;
	}
      else
	grub_memset (buf, 0, blockend);

      buf += UFS_BLKSZ (sblock) - skipfirst;
    }

  return len;
}

/* Read inode INO from the mounted filesystem described by DATA.  This
   inode is used by default now.  */
static grub_err_t
grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode)
{
  struct grub_ufs_sblock *sblock = &data->sblock;

  /* Determine the group the inode is in.  */
  int group = ino / grub_ufs_to_cpu32 (sblock->ino_per_group);

  /* Determine the inode within the group.  */
  int grpino = ino % grub_ufs_to_cpu32 (sblock->ino_per_group);

  /* The first block of the group.  */
  int grpblk = group * (grub_ufs_to_cpu32 (sblock->frags_per_group));

#ifndef MODE_UFS2
  grpblk += grub_ufs_to_cpu32 (sblock->cylg_offset)
    * (group & (~grub_ufs_to_cpu32 (sblock->cylg_mask)));
#endif

  if (!inode)
    {
      inode = (char *) &data->inode;
      data->ino = ino;
    }

  grub_disk_read (data->disk,
		  ((grub_ufs_to_cpu32 (sblock->inoblk_offs) + grpblk)
		   << grub_ufs_to_cpu32 (data->sblock.log2_blksz))
		  + grpino / UFS_INODE_PER_BLOCK,
		  (grpino % UFS_INODE_PER_BLOCK)
		  * sizeof (struct grub_ufs_inode),
		  sizeof (struct grub_ufs_inode),
		  inode);

  return grub_errno;
}


/* Lookup the symlink the current inode points to.  INO is the inode
   number of the directory the symlink is relative to.  */
static grub_err_t
grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
{
  char *symlink;
  grub_size_t sz = INODE_SIZE (data);

  if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT)
    return grub_error (GRUB_ERR_SYMLINK_LOOP, N_("too deep nesting of symlinks"));

  symlink = grub_malloc (sz + 1);
  if (!symlink)
    return grub_errno;
  /* Normally we should just check that data->inode.nblocks == 0.
     However old Linux doesn't maintain nblocks correctly and so it's always
     0. If size is bigger than inline space then the symlink is surely not
     inline.  */
  /* Check against zero is paylindromic, no need to swap.  */
  if (data->inode.nblocks == 0
      && INODE_SIZE (data) <= sizeof (data->inode.symlink))
    grub_strcpy (symlink, (char *) data->inode.symlink);
  else
    {
      if (grub_ufs_read_file (data, 0, 0, 0, sz, symlink) < 0)
	{
	  grub_free(symlink);
	  return grub_errno;
	}
    }
  symlink[sz] = '\0';

  /* The symlink is an absolute path, go back to the root inode.  */
  if (symlink[0] == '/')
    ino = GRUB_UFS_INODE;

  /* Now load in the old inode.  */
  if (grub_ufs_read_inode (data, ino, 0))
    {
      grub_free (symlink);
      return grub_errno;
    }

  grub_ufs_find_file (data, symlink);

  grub_free (symlink);

  return grub_errno;
}


/* Find the file with the pathname PATH on the filesystem described by
   DATA.  */
static grub_err_t
grub_ufs_find_file (struct grub_ufs_data *data, const char *path)
{
  const char *name;
  const char *next = path;
  unsigned int pos = 0;
  int dirino;
  char *filename;

  /* We reject filenames longer than the one we're looking
     for without reading, so this allocation is enough.  */
  filename = grub_malloc (grub_strlen (path) + 2);
  if (!filename)
    return grub_errno;

  while (1)
    {
      struct grub_ufs_dirent dirent;

      name = next;
      /* Skip the first slash.  */
      while (*name == '/')
	name++;
      if (*name == 0)
	{
	  grub_free (filename);
	  return GRUB_ERR_NONE;
	}

      if ((INODE_MODE(data) & GRUB_UFS_ATTR_TYPE)
	  != GRUB_UFS_ATTR_DIR)
	{
	  grub_error (GRUB_ERR_BAD_FILE_TYPE,
		      N_("not a directory"));
	  goto fail;
	}

      /* Extract the actual part from the pathname.  */
      for (next = name; *next && *next != '/'; next++);
      for (pos = 0;  ; pos += grub_ufs_to_cpu16 (dirent.direntlen))
	{
	  int namelen;

	  if (pos >= INODE_SIZE (data))
	    {
	      grub_error (GRUB_ERR_FILE_NOT_FOUND,
			  N_("file `%s' not found"),
			  path);
	      goto fail;
	    }

	  if (grub_ufs_read_file (data, 0, 0, pos, sizeof (dirent),
				  (char *) &dirent) < 0)
	    goto fail;

#ifdef MODE_UFS2
	  namelen = dirent.namelen_bsd;
#else
	  namelen = grub_ufs_to_cpu16 (dirent.namelen);
#endif
	  if (namelen < next - name)
	    continue;

	  if (grub_ufs_read_file (data, 0, 0, pos + sizeof (dirent),
				  next - name + (namelen != next - name),
				  filename) < 0)
	    goto fail;

	  if (grub_strncmp (name, filename, next - name) == 0
	      && (namelen == next - name || filename[next - name] == '\0'))
	    {
	      dirino = data->ino;
	      grub_ufs_read_inode (data, grub_ufs_to_cpu32 (dirent.ino), 0);
	      
	      if ((INODE_MODE(data) & GRUB_UFS_ATTR_TYPE)
		  == GRUB_UFS_ATTR_LNK)
		{
		  grub_ufs_lookup_symlink (data, dirino);
		  if (grub_errno)
		    goto fail;
		}

	      break;
	    }
	}
    }
 fail:
  grub_free (filename);
  return grub_errno;
}


/* Mount the filesystem on the disk DISK.  */
static struct grub_ufs_data *
grub_ufs_mount (grub_disk_t disk)
{
  struct grub_ufs_data *data;
  int *sblklist = sblocklist;

  data = grub_malloc (sizeof (struct grub_ufs_data));
  if (!data)
    return 0;

  /* Find a UFS sblock.  */
  while (*sblklist != -1)
    {
      grub_disk_read (disk, *sblklist, 0, sizeof (struct grub_ufs_sblock),
		      &data->sblock);
      if (grub_errno)
	goto fail;

      /* No need to byteswap bsize in this check. It works the same on both
	 endiannesses.  */
      if (data->sblock.magic == grub_cpu_to_ufs32_compile_time (GRUB_UFS_MAGIC)
	  && data->sblock.bsize != 0
	  && ((data->sblock.bsize & (data->sblock.bsize - 1)) == 0)
	  && data->sblock.ino_per_group != 0)
	{
	  for (data->log2_blksz = 0; 
	       (1U << data->log2_blksz) < grub_ufs_to_cpu32 (data->sblock.bsize);
	       data->log2_blksz++);

	  data->disk = disk;
	  data->linknest = 0;
	  return data;
	}
      sblklist++;
    }

 fail:

  if (grub_errno == GRUB_ERR_NONE || grub_errno == GRUB_ERR_OUT_OF_RANGE)
    {
#ifdef MODE_UFS2
      grub_error (GRUB_ERR_BAD_FS, "not an ufs2 filesystem");
#else
      grub_error (GRUB_ERR_BAD_FS, "not an ufs1 filesystem");
#endif
    }

  grub_free (data);

  return 0;
}


static grub_err_t
grub_ufs_dir (grub_device_t device, const char *path,
	      grub_fs_dir_hook_t hook, void *hook_data)
{
  struct grub_ufs_data *data;
  unsigned int pos = 0;

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

  grub_ufs_read_inode (data, GRUB_UFS_INODE, 0);
  if (grub_errno)
    return grub_errno;

  if (!path || path[0] != '/')
    {
      grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path);
      return grub_errno;
    }

  grub_ufs_find_file (data, path);
  if (grub_errno)
    goto fail;

  if ((INODE_MODE (data) & GRUB_UFS_ATTR_TYPE) != GRUB_UFS_ATTR_DIR)
    {
      grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
      goto fail;
    }

  while (pos < INODE_SIZE (data))
    {
      struct grub_ufs_dirent dirent;
      int namelen;

      if (grub_ufs_read_file (data, 0, 0, pos, sizeof (dirent),
			      (char *) &dirent) < 0)
	break;

      if (dirent.direntlen == 0)
	break;

#ifdef MODE_UFS2
      namelen = dirent.namelen_bsd;
#else
      namelen = grub_ufs_to_cpu16 (dirent.namelen);
#endif

      char *filename = grub_malloc (namelen + 1);
      if (!filename)
	goto fail;
      struct grub_dirhook_info info;
      struct grub_ufs_inode inode;

      grub_memset (&info, 0, sizeof (info));

      if (grub_ufs_read_file (data, 0, 0, pos + sizeof (dirent),
			      namelen, filename) < 0)
	{
	  grub_free (filename);
	  break;
	}

      filename[namelen] = '\0';
      grub_ufs_read_inode (data, grub_ufs_to_cpu32 (dirent.ino),
			   (char *) &inode);

      info.dir = ((grub_ufs_to_cpu16 (inode.mode) & GRUB_UFS_ATTR_TYPE)
		  == GRUB_UFS_ATTR_DIR);
#ifdef MODE_UFS2
      info.mtime = grub_ufs_to_cpu64 (inode.mtime);
#else
      info.mtime = grub_ufs_to_cpu32 (inode.mtime);
#endif
      info.mtimeset = 1;

      if (hook (filename, &info, hook_data))
	{
	  grub_free (filename);
	  break;
	}

      grub_free (filename);

      pos += grub_ufs_to_cpu16 (dirent.direntlen);
    }

 fail:
  grub_free (data);

  return grub_errno;
}


/* Open a file named NAME and initialize FILE.  */
static grub_err_t
grub_ufs_open (struct grub_file *file, const char *name)
{
  struct grub_ufs_data *data;
  data = grub_ufs_mount (file->device->disk);
  if (!data)
    return grub_errno;

  grub_ufs_read_inode (data, 2, 0);
  if (grub_errno)
    {
      grub_free (data);
      return grub_errno;
    }

  if (!name || name[0] != '/')
    {
      grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), name);
      return grub_errno;
    }

  grub_ufs_find_file (data, name);
  if (grub_errno)
    {
      grub_free (data);
      return grub_errno;
    }

  file->data = data;
  file->size = INODE_SIZE (data);

  return GRUB_ERR_NONE;
}


static grub_ssize_t
grub_ufs_read (grub_file_t file, char *buf, grub_size_t len)
{
  struct grub_ufs_data *data =
    (struct grub_ufs_data *) file->data;

  return grub_ufs_read_file (data, file->read_hook, file->read_hook_data,
			     file->offset, len, buf);
}


static grub_err_t
grub_ufs_close (grub_file_t file)
{
  grub_free (file->data);

  return GRUB_ERR_NONE;
}

static grub_err_t
grub_ufs_label (grub_device_t device, char **label)
{
  struct grub_ufs_data *data = 0;

  grub_dl_ref (my_mod);

  *label = 0;

  data = grub_ufs_mount (device->disk);
  if (data)
    *label = grub_strdup ((char *) data->sblock.volume_name);

  grub_dl_unref (my_mod);

  grub_free (data);

  return grub_errno;
}

static grub_err_t
grub_ufs_uuid (grub_device_t device, char **uuid)
{
  struct grub_ufs_data *data;
  grub_disk_t disk = device->disk;

  grub_dl_ref (my_mod);

  data = grub_ufs_mount (disk);
  if (data && (data->sblock.uuidhi != 0 || data->sblock.uuidlow != 0))
    *uuid = grub_xasprintf ("%08x%08x",
			   (unsigned) grub_ufs_to_cpu32 (data->sblock.uuidhi),
			   (unsigned) grub_ufs_to_cpu32 (data->sblock.uuidlow));
  else
    *uuid = NULL;

  grub_dl_unref (my_mod);

  grub_free (data);

  return grub_errno;
}


/* Get mtime.  */
static grub_err_t
grub_ufs_mtime (grub_device_t device, grub_int32_t *tm)
{
  struct grub_ufs_data *data = 0;

  grub_dl_ref (my_mod);

  data = grub_ufs_mount (device->disk);
  if (!data)
    *tm = 0;
  else
    {
      *tm = grub_ufs_to_cpu32 (data->sblock.mtime);
#ifdef MODE_UFS2
      if (*tm < (grub_int64_t) grub_ufs_to_cpu64 (data->sblock.mtime2))
	*tm = grub_ufs_to_cpu64 (data->sblock.mtime2);
#endif
    }

  grub_dl_unref (my_mod);

  grub_free (data);

  return grub_errno;
}



static struct grub_fs grub_ufs_fs =
  {
#ifdef MODE_UFS2
    .name = "ufs2",
#else
#ifdef MODE_BIGENDIAN
    .name = "ufs1_be",
#else
    .name = "ufs1",
#endif
#endif
    .dir = grub_ufs_dir,
    .open = grub_ufs_open,
    .read = grub_ufs_read,
    .close = grub_ufs_close,
    .label = grub_ufs_label,
    .uuid = grub_ufs_uuid,
    .mtime = grub_ufs_mtime,
    /* FIXME: set reserved_first_sector.  */
#ifdef GRUB_UTIL
    .blocklist_install = 1,
#endif
    .next = 0
  };

#ifdef MODE_UFS2
GRUB_MOD_INIT(ufs2)
#else
#ifdef MODE_BIGENDIAN
GRUB_MOD_INIT(ufs1_be)
#else
GRUB_MOD_INIT(ufs1)
#endif
#endif
{
  grub_fs_register (&grub_ufs_fs);
  my_mod = mod;
}

#ifdef MODE_UFS2
GRUB_MOD_FINI(ufs2)
#else
#ifdef MODE_BIGENDIAN
GRUB_MOD_FINI(ufs1_be)
#else
GRUB_MOD_FINI(ufs1)
#endif
#endif
{
  grub_fs_unregister (&grub_ufs_fs);
}

