grub2/0047-grub-core-fs-affs.c-grub_affs_mount-Support-AFFS-boo.patch
Peter Jones f74b50e380 Rebase to upstream, fix a pile of bugs. The usual.
Signed-off-by: Peter Jones <pjones@redhat.com>
2013-06-12 15:37:08 -04:00

203 lines
6.3 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From d36c4c3115977beb5f9247c6c6f0a2a209389f45 Mon Sep 17 00:00:00 2001
From: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Date: Wed, 26 Sep 2012 09:33:41 +0200
Subject: [PATCH 047/482] * grub-core/fs/affs.c (grub_affs_mount):
Support AFFS bootblock in sector 1.
---
ChangeLog | 5 ++
grub-core/fs/affs.c | 139 ++++++++++++++++++++++++++--------------------------
2 files changed, 74 insertions(+), 70 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a53c5cc..d81a9a6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2012-09-26 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/affs.c (grub_affs_mount): Support AFFS bootblock in
+ sector 1.
+
2012-09-24 Colin Watson <cjwatson@ubuntu.com>
* util/grub-install.in: Make the error message if $source_dir
diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c
index ef65479..848a455 100644
--- a/grub-core/fs/affs.c
+++ b/grub-core/fs/affs.c
@@ -97,6 +97,7 @@ enum
};
#define AFFS_MAX_LOG_BLOCK_SIZE 4
+#define AFFS_MAX_SUPERBLOCK 1
@@ -184,94 +185,92 @@ grub_affs_mount (grub_disk_t disk)
{
struct grub_affs_data *data;
grub_uint32_t *rootblock = 0;
- struct grub_affs_rblock *rblock;
+ struct grub_affs_rblock *rblock = 0;
int log_blocksize = 0;
+ int bsnum = 0;
data = grub_zalloc (sizeof (struct grub_affs_data));
if (!data)
return 0;
- /* Read the bootblock. */
- grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
- &data->bblock);
- if (grub_errno)
- goto fail;
-
- /* Make sure this is an affs filesystem. */
- if (grub_strncmp ((char *) (data->bblock.type), "DOS", 3))
- {
- grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem");
- goto fail;
- }
-
- /* Test if the filesystem is a OFS filesystem. */
- if (! (data->bblock.flags & GRUB_AFFS_FLAG_FFS))
- {
- grub_error (GRUB_ERR_BAD_FS, "OFS not yet supported");
- goto fail;
- }
-
- /* No sane person uses more than 8KB for a block. At least I hope
- for that person because in that case this won't work. */
- rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE << AFFS_MAX_LOG_BLOCK_SIZE);
- if (!rootblock)
- goto fail;
-
- rblock = (struct grub_affs_rblock *) rootblock;
-
- /* The filesystem blocksize is not stored anywhere in the filesystem
- itself. One way to determine it is try reading blocks for the
- rootblock until the checksum is correct. */
- for (log_blocksize = 0; log_blocksize <= AFFS_MAX_LOG_BLOCK_SIZE;
- log_blocksize++)
+ for (bsnum = 0; bsnum < AFFS_MAX_SUPERBLOCK + 1; bsnum++)
{
- grub_uint32_t *currblock = rootblock;
- unsigned int i;
- grub_uint32_t checksum = 0;
-
- /* Read the rootblock. */
- grub_disk_read (disk,
- (grub_uint64_t) grub_be_to_cpu32 (data->bblock.rootblock)
- << log_blocksize, 0,
- GRUB_DISK_SECTOR_SIZE << log_blocksize, rootblock);
+ /* Read the bootblock. */
+ grub_disk_read (disk, bsnum, 0, sizeof (struct grub_affs_bblock),
+ &data->bblock);
if (grub_errno)
goto fail;
- if (rblock->type != grub_cpu_to_be32_compile_time (2)
- || rblock->htsize == 0
- || currblock[(GRUB_DISK_SECTOR_SIZE << log_blocksize)
- / sizeof (*currblock) - 1]
- != grub_cpu_to_be32_compile_time (1))
+ /* Make sure this is an affs filesystem. */
+ if (grub_strncmp ((char *) (data->bblock.type), "DOS", 3) != 0
+ /* Test if the filesystem is a OFS filesystem. */
+ || !(data->bblock.flags & GRUB_AFFS_FLAG_FFS))
continue;
- for (i = 0; i < (GRUB_DISK_SECTOR_SIZE << log_blocksize)
- / sizeof (*currblock);
- i++)
- checksum += grub_be_to_cpu32 (currblock[i]);
+ /* No sane person uses more than 8KB for a block. At least I hope
+ for that person because in that case this won't work. */
+ if (!rootblock)
+ rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE
+ << AFFS_MAX_LOG_BLOCK_SIZE);
+ if (!rootblock)
+ goto fail;
- if (checksum == 0)
- break;
- }
- if (log_blocksize > AFFS_MAX_LOG_BLOCK_SIZE)
- {
- grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined");
- goto fail;
- }
+ rblock = (struct grub_affs_rblock *) rootblock;
+
+ /* The filesystem blocksize is not stored anywhere in the filesystem
+ itself. One way to determine it is try reading blocks for the
+ rootblock until the checksum is correct. */
+ for (log_blocksize = 0; log_blocksize <= AFFS_MAX_LOG_BLOCK_SIZE;
+ log_blocksize++)
+ {
+ grub_uint32_t *currblock = rootblock;
+ unsigned int i;
+ grub_uint32_t checksum = 0;
+
+ /* Read the rootblock. */
+ grub_disk_read (disk,
+ (grub_uint64_t) grub_be_to_cpu32 (data->bblock.rootblock)
+ << log_blocksize, 0,
+ GRUB_DISK_SECTOR_SIZE << log_blocksize, rootblock);
+ if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+ {
+ grub_errno = 0;
+ break;
+ }
+ if (grub_errno)
+ goto fail;
- data->log_blocksize = log_blocksize;
- data->disk = disk;
- data->htsize = grub_be_to_cpu32 (rblock->htsize);
- data->diropen.data = data;
- data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock);
- data->diropen.parent = NULL;
- grub_memcpy (&data->diropen.di, rootblock, sizeof (data->diropen.di));
+ if (rblock->type != grub_cpu_to_be32_compile_time (2)
+ || rblock->htsize == 0
+ || currblock[(GRUB_DISK_SECTOR_SIZE << log_blocksize)
+ / sizeof (*currblock) - 1]
+ != grub_cpu_to_be32_compile_time (1))
+ continue;
- grub_free (rootblock);
+ for (i = 0; i < (GRUB_DISK_SECTOR_SIZE << log_blocksize)
+ / sizeof (*currblock);
+ i++)
+ checksum += grub_be_to_cpu32 (currblock[i]);
- return data;
+ if (checksum == 0)
+ {
+ data->log_blocksize = log_blocksize;
+ data->disk = disk;
+ data->htsize = grub_be_to_cpu32 (rblock->htsize);
+ data->diropen.data = data;
+ data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock);
+ data->diropen.parent = NULL;
+ grub_memcpy (&data->diropen.di, rootblock,
+ sizeof (data->diropen.di));
+ grub_free (rootblock);
+
+ return data;
+ }
+ }
+ }
fail:
- if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+ if (grub_errno == GRUB_ERR_NONE || grub_errno == GRUB_ERR_OUT_OF_RANGE)
grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem");
grub_free (data);
--
1.8.2.1