+2011-10-31 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Use shifts in UFS.
+
+ * grub-core/fs/ufs.c (UFS_LOG_BLKSZ): New macro.
+ (grub_ufs_data): New field log2_blksz.
+ (grub_ufs_read_file): Use shifts.
+ (grub_ufs_mount): Check block size and logarithm it.
+
2011-10-31 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/fs/ufs.c (grub_ufs_lookup_symlink): Fix handling of
/* Calculate in which group the inode can be found. */
#define UFS_BLKSZ(sblock) (grub_le_to_cpu32 (sblock->bsize))
+#define UFS_LOG_BLKSZ(sblock) (data->log2_blksz)
#define INODE(data,field) data->inode. field
#ifdef MODE_UFS2
struct grub_ufs_inode inode;
int ino;
int linknest;
+ int log2_blksz;
};
static grub_dl_t my_mod;
if (len + pos > INODE_SIZE (data))
len = INODE_SIZE (data) - pos;
- blockcnt = grub_divmod64 ((len + pos + UFS_BLKSZ (sblock) - 1),
- UFS_BLKSZ (sblock), 0);
+ blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) >> UFS_LOG_BLKSZ (sblock);
- for (i = grub_divmod64 (pos, UFS_BLKSZ (sblock), 0); i < blockcnt; i++)
+ for (i = pos >> UFS_LOG_BLKSZ (sblock); i < blockcnt; i++)
{
grub_disk_addr_t blknr;
grub_off_t blockoff;
int skipfirst = 0;
- grub_divmod64 (pos, UFS_BLKSZ (sblock), &blockoff);
+ blockoff = pos & (UFS_BLKSZ (sblock) - 1);
blknr = grub_ufs_get_file_block (data, i);
if (grub_errno)
/* Last block. */
if (i == blockcnt - 1)
{
- grub_divmod64 (len + pos, UFS_BLKSZ (sblock), &blockend);
+ blockend = (len + pos) & (UFS_BLKSZ (sblock) - 1);
if (!blockend)
blockend = UFS_BLKSZ (sblock);
}
/* First block. */
- if (i == grub_divmod64 (pos, UFS_BLKSZ (sblock), 0))
+ if (i == (pos >> UFS_LOG_BLKSZ (sblock)))
{
skipfirst = blockoff;
blockend -= skipfirst;
if (grub_errno)
goto fail;
- if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC)
+ /* No need to byteswap bsize in this check. It works the same on both
+ endiannesses. */
+ if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC
+ && data->sblock.bsize != 0
+ && ((data->sblock.bsize & (data->sblock.bsize - 1)) == 0))
{
+ for (data->log2_blksz = 0;
+ (1U << data->log2_blksz) < grub_le_to_cpu32 (data->sblock.bsize);
+ data->log2_blksz++);
+
data->disk = disk;
data->linknest = 0;
return data;