From 87661123b23d12bed46d90c3d6c11af7780beb88 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 Oct 2011 10:50:43 +0100 Subject: [PATCH] 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. --- ChangeLog | 9 +++++++++ grub-core/fs/ufs.c | 23 ++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 825524c09..79b930c1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-31 Vladimir Serbinenko + + 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 * grub-core/fs/ufs.c (grub_ufs_lookup_symlink): Fix handling of diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index ea7a7455f..bfcb7148f 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -50,6 +50,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); /* 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 @@ -214,6 +215,7 @@ struct grub_ufs_data struct grub_ufs_inode inode; int ino; int linknest; + int log2_blksz; }; static grub_dl_t my_mod; @@ -295,10 +297,9 @@ grub_ufs_read_file (struct grub_ufs_data *data, 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; @@ -306,7 +307,7 @@ grub_ufs_read_file (struct grub_ufs_data *data, 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) @@ -315,14 +316,14 @@ grub_ufs_read_file (struct grub_ufs_data *data, /* 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; @@ -536,8 +537,16 @@ grub_ufs_mount (grub_disk_t disk) 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;