#include <grub/dl.h>
#include <grub/types.h>
+GRUB_MOD_LICENSE ("GPLv3+");
+
#ifdef MODE_MINIX3
#define GRUB_MINIX_MAGIC 0x4D5A
#elif defined(MODE_MINIX2)
#define grub_minix_le_to_cpu_ino grub_le_to_cpu16
#endif
-#define GRUB_MINIX_INODE_SIZE(data) (grub_minix_le_to_cpu_n (data->inode.size))
+#define GRUB_MINIX_INODE_SIZE(data) (grub_le_to_cpu32 (data->inode.size))
#define GRUB_MINIX_INODE_MODE(data) (grub_le_to_cpu16 (data->inode.mode))
#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) (grub_minix_le_to_cpu_n \
(data->inode.dir_zones[blk]))
#define GRUB_MINIX_INODE_DINDIR_ZONE(data) (grub_minix_le_to_cpu_n \
(data->inode.double_indir_zone))
+#ifndef MODE_MINIX3
#define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \
- + grub_le_to_cpu16 (sblock->log2_zone_size))
+ + grub_le_to_cpu16 (data->sblock.log2_zone_size))
+#endif
#define GRUB_MINIX_ZONESZ (data->block_size \
- << grub_le_to_cpu16 (sblock->log2_zone_size))
+ << grub_le_to_cpu16 (data->sblock.log2_zone_size))
+
+#ifdef MODE_MINIX3
+#define GRUB_MINIX_ZONE2SECT(zone) ((zone) * (data->block_size / GRUB_DISK_SECTOR_SIZE))
+#else
+#define GRUB_MINIX_ZONE2SECT(zone) ((zone) << GRUB_MINIX_LOG2_ZONESZ)
+#endif
+
#ifdef MODE_MINIX3
struct grub_minix_sblock
};
#endif
-#if defined(MODE_MINIX3)
-
+#if defined(MODE_MINIX3) || defined(MODE_MINIX2)
struct grub_minix_inode
{
grub_uint16_t mode;
grub_uint16_t nlinks;
grub_uint16_t uid;
- grub_uint8_t gid;
- grub_uint8_t pad;
+ grub_uint16_t gid;
grub_uint32_t size;
grub_uint32_t atime;
grub_uint32_t mtime;
grub_uint32_t double_indir_zone;
grub_uint32_t unused;
};
-
-#elif defined(MODE_MINIX2)
+#else
struct grub_minix_inode
{
grub_uint16_t mode;
grub_uint16_t uid;
- grub_uint16_t size;
- grub_uint32_t ctime;
+ grub_uint32_t size;
+ grub_uint32_t mtime;
grub_uint8_t gid;
grub_uint8_t nlinks;
grub_uint16_t dir_zones[7];
grub_uint16_t double_indir_zone;
};
-#else
-
-struct grub_minix_inode
-{
- grub_uint16_t mode;
- grub_uint16_t nlinks;
- grub_uint16_t uid;
- grub_uint16_t gid;
- grub_uint32_t size;
- grub_uint32_t atime;
- grub_uint32_t mtime;
- grub_uint32_t ctime;
- grub_uint32_t dir_zones[7];
- grub_uint32_t indir_zone;
- grub_uint32_t double_indir_zone;
- grub_uint32_t unused;
-
-};
-
#endif
/* Information about a "mounted" minix filesystem. */
static grub_err_t grub_minix_find_file (struct grub_minix_data *data,
const char *path);
-static int
+static grub_minix_uintn_t
grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
{
- struct grub_minix_sblock *sblock = &data->sblock;
- int indir;
+ grub_minix_uintn_t indir;
+ const grub_uint32_t block_per_zone = (GRUB_MINIX_ZONESZ
+ / GRUB_MINIX_INODE_BLKSZ (data));
- auto int grub_get_indir (int, int);
+ auto grub_minix_uintn_t grub_get_indir (grub_minix_uintn_t,
+ grub_minix_uintn_t);
/* Read the block pointer in ZONE, on the offset NUM. */
- int grub_get_indir (int zone, int num)
+ grub_minix_uintn_t grub_get_indir (grub_minix_uintn_t zone,
+ grub_minix_uintn_t num)
{
grub_minix_uintn_t indirn;
grub_disk_read (data->disk,
-#ifdef MODE_MINIX3
- zone * (data->block_size / GRUB_DISK_SECTOR_SIZE),
-#else
- zone << GRUB_MINIX_LOG2_ZONESZ,
-#endif
+ GRUB_MINIX_ZONE2SECT(zone),
sizeof (grub_minix_uintn_t) * num,
sizeof (grub_minix_uintn_t), (char *) &indirn);
return grub_minix_le_to_cpu_n (indirn);
/* Indirect block. */
blk -= GRUB_MINIX_INODE_DIR_BLOCKS;
- if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
+ if (blk < block_per_zone)
{
indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
return indir;
}
/* Double indirect block. */
- blk -= GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data);
- if (blk < (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
- * (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)))
+ blk -= block_per_zone;
+ if (blk < block_per_zone * block_per_zone)
{
indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data),
- blk / GRUB_MINIX_ZONESZ);
+ blk / block_per_zone);
- indir = grub_get_indir (indir, blk % GRUB_MINIX_ZONESZ);
+ indir = grub_get_indir (indir, blk % block_per_zone);
return indir;
}
unsigned offset, unsigned length),
grub_off_t pos, grub_disk_addr_t len, char *buf)
{
- struct grub_minix_sblock *sblock = &data->sblock;
grub_disk_addr_t i;
grub_disk_addr_t blockcnt;
grub_uint64_t posblock;
- grub_uint32_t blockoff;
+ grub_uint64_t blockoff;
/* Adjust len so it we can't read past the end of the file. */
if (len + pos > GRUB_MINIX_INODE_SIZE (data))
for (i = posblock; i < blockcnt; i++)
{
grub_disk_addr_t blknr;
- grub_uint32_t blockend = data->block_size;
+ grub_uint64_t blockend = data->block_size;
grub_off_t skipfirst = 0;
blknr = grub_minix_get_file_block (data, i);
data->disk->read_hook = read_hook;
grub_disk_read (data->disk,
-#ifdef MODE_MINIX3
- blknr * (sblock->block_size / GRUB_DISK_SECTOR_SIZE),
-#else
- blknr << GRUB_MINIX_LOG2_ZONESZ,
-#endif
+ GRUB_MINIX_ZONE2SECT(blknr),
skipfirst, blockend, buf);
data->disk->read_hook = 0;
if (grub_errno)
/* The first inode in minix is inode 1. */
ino--;
- block = (2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
- + grub_le_to_cpu16 (sblock->zone_bmap_size));
-#ifndef MODE_MINIX3
- block <<= GRUB_MINIX_LOG2_BSIZE;
-#else
- block *= sblock->block_size / GRUB_DISK_SECTOR_SIZE;
-#endif
+ block = GRUB_MINIX_ZONE2SECT (2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
+ + grub_le_to_cpu16 (sblock->zone_bmap_size));
block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
int offs = (ino % (GRUB_DISK_SECTOR_SIZE
/ sizeof (struct grub_minix_inode))
pos += sizeof (ino) + data->filename_size;
} while (pos < GRUB_MINIX_INODE_SIZE (data));
- grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+ grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", path);
return grub_errno;
}
grub_minix_read_inode (data, grub_minix_le_to_cpu_ino (ino));
info.dir = ((GRUB_MINIX_INODE_MODE (data)
& GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
+ info.mtimeset = 1;
+ info.mtime = grub_le_to_cpu32 (data->inode.mtime);
+
if (hook (filename, &info) ? 1 : 0)
break;