All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] biosdisk / open_device() messing up offsets
@ 2008-06-04 23:35 Robert Millan
  2008-06-05  1:47 ` Pavel Roskin
  2008-06-06 15:56 ` Robert Millan
  0 siblings, 2 replies; 38+ messages in thread
From: Robert Millan @ 2008-06-04 23:35 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 723 bytes --]


It seems that open_device() in biosdisk is messing up offsets when
accessing partitions.  For example if you try:

grub> hexdump (hd0,1)

in grub-emu, you'll get a message saying lseek failed.  The problem is that
it substracts to the sector offset, so all accesses get to wrong data and
accessing sector 0 results in underflow.

I would think those lines (see patch) are plainly wrong, but they appear to
be very old, and it is strange that this wasn't noticed earlier.  Maybe we
have changed behaviour around partition/disk offsets, causing this breakage
without noticing?

-- 
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What good is a phone call… if you are unable to speak?
(as seen on /.)

[-- Attachment #2: partition.diff --]
[-- Type: text/x-diff, Size: 549 bytes --]

diff -x ChangeLog -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/util/biosdisk.c ./util/biosdisk.c
--- ../grub2/util/biosdisk.c	2008-06-04 16:00:30.000000000 +0200
+++ ./util/biosdisk.c	2008-06-05 01:17:00.000000000 +0200
@@ -298,9 +298,6 @@ open_device (const grub_disk_t disk, gru
 
     /* Make the buffer cache consistent with the physical disk.  */
     ioctl (fd, BLKFLSBUF, 0);
-    
-    if (is_partition)
-      sector -= disk->partition->start;
   }
 #else /* ! __linux__ */
   fd = open (map[disk->id].device, flags);

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-04 23:35 [PATCH] biosdisk / open_device() messing up offsets Robert Millan
@ 2008-06-05  1:47 ` Pavel Roskin
  2008-06-05 21:12   ` Robert Millan
  2008-06-06 15:56 ` Robert Millan
  1 sibling, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-05  1:47 UTC (permalink / raw)
  To: The development of GRUB 2

On Thu, 2008-06-05 at 01:35 +0200, Robert Millan wrote:
> It seems that open_device() in biosdisk is messing up offsets when
> accessing partitions.  For example if you try:
> 
> grub> hexdump (hd0,1)
> 
> in grub-emu, you'll get a message saying lseek failed.  The problem is that
> it substracts to the sector offset, so all accesses get to wrong data and
> accessing sector 0 results in underflow.
> 
> I would think those lines (see patch) are plainly wrong, but they appear to
> be very old, and it is strange that this wasn't noticed earlier.  Maybe we
> have changed behaviour around partition/disk offsets, causing this breakage
> without noticing?

The question whether sector is relative to the partition or to the whole
disk.  From what I see in disk/memdisk.c or it disk/i386/pc/biosdisk.c,
the sector is relative to the whole disk.  There is no compensation for
partition offsets.  That's low-level code that doesn't know about
partitions, and util/biosdisk.c correctly tries to emulate that.

I guess grub-emu gets it wrong somewhere.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-05  1:47 ` Pavel Roskin
@ 2008-06-05 21:12   ` Robert Millan
  0 siblings, 0 replies; 38+ messages in thread
From: Robert Millan @ 2008-06-05 21:12 UTC (permalink / raw)
  To: The development of GRUB 2

On Wed, Jun 04, 2008 at 09:47:17PM -0400, Pavel Roskin wrote:
> On Thu, 2008-06-05 at 01:35 +0200, Robert Millan wrote:
> > It seems that open_device() in biosdisk is messing up offsets when
> > accessing partitions.  For example if you try:
> > 
> > grub> hexdump (hd0,1)
> > 
> > in grub-emu, you'll get a message saying lseek failed.  The problem is that
> > it substracts to the sector offset, so all accesses get to wrong data and
> > accessing sector 0 results in underflow.
> > 
> > I would think those lines (see patch) are plainly wrong, but they appear to
> > be very old, and it is strange that this wasn't noticed earlier.  Maybe we
> > have changed behaviour around partition/disk offsets, causing this breakage
> > without noticing?
> 
> The question whether sector is relative to the partition or to the whole
> disk.  From what I see in disk/memdisk.c or it disk/i386/pc/biosdisk.c,
> the sector is relative to the whole disk.  There is no compensation for
> partition offsets.  That's low-level code that doesn't know about
> partitions, and util/biosdisk.c correctly tries to emulate that.
> 
> I guess grub-emu gets it wrong somewhere.

grub-emu itself does nothing about this AFAIK, it just relies on
util/biosdisk.c to do the right thing.

-- 
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What good is a phone call… if you are unable to speak?
(as seen on /.)



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-04 23:35 [PATCH] biosdisk / open_device() messing up offsets Robert Millan
  2008-06-05  1:47 ` Pavel Roskin
@ 2008-06-06 15:56 ` Robert Millan
  2008-06-06 22:53   ` Pavel Roskin
  1 sibling, 1 reply; 38+ messages in thread
From: Robert Millan @ 2008-06-06 15:56 UTC (permalink / raw)
  To: grub-devel


Committed.

On Thu, Jun 05, 2008 at 01:35:36AM +0200, Robert Millan wrote:
> 
> It seems that open_device() in biosdisk is messing up offsets when
> accessing partitions.  For example if you try:
> 
> grub> hexdump (hd0,1)
> 
> in grub-emu, you'll get a message saying lseek failed.  The problem is that
> it substracts to the sector offset, so all accesses get to wrong data and
> accessing sector 0 results in underflow.
> 
> I would think those lines (see patch) are plainly wrong, but they appear to
> be very old, and it is strange that this wasn't noticed earlier.  Maybe we
> have changed behaviour around partition/disk offsets, causing this breakage
> without noticing?
> 
> -- 
> Robert Millan
> 
> <GPLv2> I know my rights; I want my phone call!
> <DRM> What good is a phone call… if you are unable to speak?
> (as seen on /.)

> diff -x ChangeLog -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/util/biosdisk.c ./util/biosdisk.c
> --- ../grub2/util/biosdisk.c	2008-06-04 16:00:30.000000000 +0200
> +++ ./util/biosdisk.c	2008-06-05 01:17:00.000000000 +0200
> @@ -298,9 +298,6 @@ open_device (const grub_disk_t disk, gru
>  
>      /* Make the buffer cache consistent with the physical disk.  */
>      ioctl (fd, BLKFLSBUF, 0);
> -    
> -    if (is_partition)
> -      sector -= disk->partition->start;
>    }
>  #else /* ! __linux__ */
>    fd = open (map[disk->id].device, flags);

> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel


-- 
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What good is a phone call… if you are unable to speak?
(as seen on /.)



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-06 15:56 ` Robert Millan
@ 2008-06-06 22:53   ` Pavel Roskin
  2008-06-06 23:38     ` Robert Millan
  2008-06-07  8:37     ` Bean
  0 siblings, 2 replies; 38+ messages in thread
From: Pavel Roskin @ 2008-06-06 22:53 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, 2008-06-06 at 17:56 +0200, Robert Millan wrote:
> Committed.

I believe it's wrong.  util/biosdisk.c is a low level disk driver.  It's
supposed to read data relative to the disk, like other drivers do.

Besides, is_partition becomes write-only.  It means that the result of
linux_find_partition() is ignored.  Please note that
linux_find_partition() modifies its first argument on success.  It
rewrites the disk device (e.g. /dev/sda) with the partition device
(e.g. /dev/sda1).

If the result of linux_find_partition() is not checked, nobody knows
whether fd is a handle to the partition or to the whole disk.  Yet the
sector variable is used to seek on that device.  Needless to say that
different values would be obtained.

Also, grub-emu is not the only user of util/biosdisk.c.  It is also used
by grub-setup, which is working correctly,  as far as I can tell.

By the way, the current GRUB just failed to install on my test system.
After I rebooted it, GRUB hung on startup after showing "GRUB".

It may be something else.  It was an unclean reboot after a panic for
unrelated reasons, so the hanging problem may be an issue with ext3.
Anyway, extreme caution is required with the current code!

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-06 22:53   ` Pavel Roskin
@ 2008-06-06 23:38     ` Robert Millan
  2008-06-07  2:58       ` Pavel Roskin
  2008-06-07  6:33       ` Pavel Roskin
  2008-06-07  8:37     ` Bean
  1 sibling, 2 replies; 38+ messages in thread
From: Robert Millan @ 2008-06-06 23:38 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, Jun 06, 2008 at 06:53:52PM -0400, Pavel Roskin wrote:
> On Fri, 2008-06-06 at 17:56 +0200, Robert Millan wrote:
> > Committed.
> 
> I believe it's wrong.

You mean that the lines I removed were wrong, or that my commit is wrong?

I thought you agreed that those lines were bogus.  If not, then we'd have
to figure out why sector 0 of the partition can be accessed directly via
hexdump.

> By the way, the current GRUB just failed to install on my test system.
> After I rebooted it, GRUB hung on startup after showing "GRUB".

Please run a regression test, if you can.

-- 
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What good is a phone call… if you are unable to speak?
(as seen on /.)



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-06 23:38     ` Robert Millan
@ 2008-06-07  2:58       ` Pavel Roskin
  2008-06-08 19:29         ` Robert Millan
  2008-06-07  6:33       ` Pavel Roskin
  1 sibling, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-07  2:58 UTC (permalink / raw)
  To: The development of GRUB 2, Robert Millan

Quoting Robert Millan <rmh@aybabtu.com>:

> On Fri, Jun 06, 2008 at 06:53:52PM -0400, Pavel Roskin wrote:
>> On Fri, 2008-06-06 at 17:56 +0200, Robert Millan wrote:
>> > Committed.
>>
>> I believe it's wrong.
>
> You mean that the lines I removed were wrong, or that my commit is wrong?

The commit is wrong.

> I thought you agreed that those lines were bogus.

No, I explained why they were needed.  Sorry, I must have been unclear.

> If not, then we'd have
> to figure out why sector 0 of the partition can be accessed directly via
> hexdump.

Absolutely.

>> By the way, the current GRUB just failed to install on my test system.
>> After I rebooted it, GRUB hung on startup after showing "GRUB".
>
> Please run a regression test, if you can.

I could boot from the rescue CD, so it's not that bad.

I'm looking at the problem now.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-06 23:38     ` Robert Millan
  2008-06-07  2:58       ` Pavel Roskin
@ 2008-06-07  6:33       ` Pavel Roskin
  2008-06-07  7:48         ` Bean
  1 sibling, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-07  6:33 UTC (permalink / raw)
  To: The development of GRUB 2, Robert Millan

Quoting Robert Millan <rmh@aybabtu.com>:

> If not, then we'd have
> to figure out why sector 0 of the partition can be accessed directly via
> hexdump.

As I understand, "(hd0,1)" doesn't refer to an extent of data, i.e. it  
not a file or a block list that can be opened like a file.   
"(hd0,1)+1" is the first sector of the partition.  But "(hd0,1)" is  
not all sectors of the partition.  It the partition name.  It can be  
used in the "ls" command, whereas "(hd0,1)+1" cannot.

>> By the way, the current GRUB just failed to install on my test system.
>> After I rebooted it, GRUB hung on startup after showing "GRUB".
>
> Please run a regression test, if you can.

The installation was broken by that patch, so I reverted it.  It's  
easy to check the installation by doing it on a mounted flash drive,  
so that the real boot device is not at risk.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-07  6:33       ` Pavel Roskin
@ 2008-06-07  7:48         ` Bean
  2008-06-08  6:00           ` Pavel Roskin
  0 siblings, 1 reply; 38+ messages in thread
From: Bean @ 2008-06-07  7:48 UTC (permalink / raw)
  To: The development of GRUB 2

On Sat, Jun 7, 2008 at 2:33 PM, Pavel Roskin <proski@gnu.org> wrote:
> Quoting Robert Millan <rmh@aybabtu.com>:
>
>> If not, then we'd have
>> to figure out why sector 0 of the partition can be accessed directly via
>> hexdump.
>
> As I understand, "(hd0,1)" doesn't refer to an extent of data, i.e. it not a
> file or a block list that can be opened like a file.  "(hd0,1)+1" is the
> first sector of the partition.  But "(hd0,1)" is not all sectors of the
> partition.  It the partition name.  It can be used in the "ls" command,
> whereas "(hd0,1)+1" cannot.
>
>>> By the way, the current GRUB just failed to install on my test system.
>>> After I rebooted it, GRUB hung on startup after showing "GRUB".
>>
>> Please run a regression test, if you can.
>
> The installation was broken by that patch, so I reverted it.  It's easy to
> check the installation by doing it on a mounted flash drive, so that the
> real boot device is not at risk.

Hi,

I believe the problem is with hexdump. It open the device with
grub_disk_open, which returns the disk object related to the beginning
of partition. However, it read it using disk->dev->read, which is a
low level api that use absolute address. It should be using
grub_disk_read instead.

BTW, I also find an ingesting situation when writing the load_env
command. The read hook return absolute address, so grub_disk_read
would not work. In that case, we have to use the low level
disk->dev->read.

-- 
Bean



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-06 22:53   ` Pavel Roskin
  2008-06-06 23:38     ` Robert Millan
@ 2008-06-07  8:37     ` Bean
  2008-06-08  5:41       ` Pavel Roskin
  1 sibling, 1 reply; 38+ messages in thread
From: Bean @ 2008-06-07  8:37 UTC (permalink / raw)
  To: The development of GRUB 2

On Sat, Jun 7, 2008 at 6:53 AM, Pavel Roskin <proski@gnu.org> wrote:
>
> It may be something else.  It was an unclean reboot after a panic for
> unrelated reasons, so the hanging problem may be an issue with ext3.
> Anyway, extreme caution is required with the current code!

btw, any chance your cpu is big endian ? The code might have portable
issue in big endian machine.

-- 
Bean



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-07  8:37     ` Bean
@ 2008-06-08  5:41       ` Pavel Roskin
  0 siblings, 0 replies; 38+ messages in thread
From: Pavel Roskin @ 2008-06-08  5:41 UTC (permalink / raw)
  To: The development of GRUB 2

On Sat, 2008-06-07 at 16:37 +0800, Bean wrote:
> On Sat, Jun 7, 2008 at 6:53 AM, Pavel Roskin <proski@gnu.org> wrote:
> >
> > It may be something else.  It was an unclean reboot after a panic for
> > unrelated reasons, so the hanging problem may be an issue with ext3.
> > Anyway, extreme caution is required with the current code!
> 
> btw, any chance your cpu is big endian ? The code might have portable
> issue in big endian machine.

The test machine is i386.  The problems I'm seeing in qemu are observed
on x86_64.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-07  7:48         ` Bean
@ 2008-06-08  6:00           ` Pavel Roskin
  2008-06-08  6:44             ` Bean
  0 siblings, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-08  6:00 UTC (permalink / raw)
  To: The development of GRUB 2

On Sat, 2008-06-07 at 15:48 +0800, Bean wrote:

> I believe the problem is with hexdump. It open the device with
> grub_disk_open, which returns the disk object related to the beginning
> of partition. However, it read it using disk->dev->read, which is a
> low level api that use absolute address. It should be using
> grub_disk_read instead.

Nice catch!  Indeed, hexdump has special handling for the whole
partitions.  And it actually tries to satisfy the low level API by
converting offset to the sector number and skipping the remainder.  I
guess it could be simplified if grub_disk_read() is used.

> BTW, I also find an ingesting situation when writing the load_env
> command. The read hook return absolute address, so grub_disk_read
> would not work. In that case, we have to use the low level
> disk->dev->read.

In that case it may be justified.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-08  6:00           ` Pavel Roskin
@ 2008-06-08  6:44             ` Bean
  2008-06-08  6:52               ` Pavel Roskin
  0 siblings, 1 reply; 38+ messages in thread
From: Bean @ 2008-06-08  6:44 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 8, 2008 at 2:00 PM, Pavel Roskin <proski@gnu.org> wrote:
> On Sat, 2008-06-07 at 15:48 +0800, Bean wrote:
>
>> I believe the problem is with hexdump. It open the device with
>> grub_disk_open, which returns the disk object related to the beginning
>> of partition. However, it read it using disk->dev->read, which is a
>> low level api that use absolute address. It should be using
>> grub_disk_read instead.
>
> Nice catch!  Indeed, hexdump has special handling for the whole
> partitions.  And it actually tries to satisfy the low level API by
> converting offset to the sector number and skipping the remainder.  I
> guess it could be simplified if grub_disk_read() is used.

The reason I add device support for hexdump is to debug the nand
driver. I need to go around the disk cache and call the underlying
disk driver directly, so I use disk->dev->read. For (nand), there is
just one partition, so I didn't notice the problem then.

-- 
Bean



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-08  6:44             ` Bean
@ 2008-06-08  6:52               ` Pavel Roskin
  2008-06-08  7:11                 ` Bean
  0 siblings, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-08  6:52 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, 2008-06-08 at 14:44 +0800, Bean wrote:
> On Sun, Jun 8, 2008 at 2:00 PM, Pavel Roskin <proski@gnu.org> wrote:
> > On Sat, 2008-06-07 at 15:48 +0800, Bean wrote:
> >
> >> I believe the problem is with hexdump. It open the device with
> >> grub_disk_open, which returns the disk object related to the beginning
> >> of partition. However, it read it using disk->dev->read, which is a
> >> low level api that use absolute address. It should be using
> >> grub_disk_read instead.
> >
> > Nice catch!  Indeed, hexdump has special handling for the whole
> > partitions.  And it actually tries to satisfy the low level API by
> > converting offset to the sector number and skipping the remainder.  I
> > guess it could be simplified if grub_disk_read() is used.
> 
> The reason I add device support for hexdump is to debug the nand
> driver. I need to go around the disk cache and call the underlying
> disk driver directly, so I use disk->dev->read. For (nand), there is
> just one partition, so I didn't notice the problem then.

Here's the patch.  Everything seems to be OK.  "--skip=N" is not
recognized, but it's something in the option parsing code.  "-s N" is
working.

Please feel free to apply.

diff --git a/commands/hexdump.c b/commands/hexdump.c
index 6d97fe4..e459b88 100644
--- a/commands/hexdump.c
+++ b/commands/hexdump.c
@@ -99,35 +99,27 @@ grub_cmd_hexdump (struct grub_arg_list *state, int argc, char **args)
   else if ((args[0][0] == '(') && (args[0][namelen - 1] == ')'))
     {
       grub_disk_t disk;
-      grub_disk_addr_t sector;
-      grub_size_t ofs;
 
       args[0][namelen - 1] = 0;
       disk = grub_disk_open (&args[0][1]);
       if (! disk)
         return 0;
 
-      sector = (skip >> (GRUB_DISK_SECTOR_BITS + 2)) * 4;
-      ofs = skip & (GRUB_DISK_SECTOR_SIZE * 4 - 1);
       while (length)
         {
-          grub_size_t len, n;
+          grub_size_t len;
 
           len = length;
-          if (ofs + len > sizeof (buf))
-            len = sizeof (buf) - ofs;
+          if (len > sizeof (buf))
+            len = sizeof (buf);
 
-          n = ((ofs + len + GRUB_DISK_SECTOR_SIZE - 1)
-               >> GRUB_DISK_SECTOR_BITS);
-          if (disk->dev->read (disk, sector, n, buf))
+          if (grub_disk_read (disk, 0, skip, len, buf))
             break;
 
-          hexdump (skip, &buf[ofs], len);
+          hexdump (skip, buf, len);
 
-          ofs = 0;
           skip += len;
           length -= len;
-          sector += 4;
         }
 
       grub_disk_close (disk);


-- 
Regards,
Pavel Roskin



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-08  6:52               ` Pavel Roskin
@ 2008-06-08  7:11                 ` Bean
  2008-06-08  7:29                   ` Pavel Roskin
  0 siblings, 1 reply; 38+ messages in thread
From: Bean @ 2008-06-08  7:11 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 812 bytes --]

On Sun, Jun 8, 2008 at 2:52 PM, Pavel Roskin <proski@gnu.org> wrote:
>>
>> The reason I add device support for hexdump is to debug the nand
>> driver. I need to go around the disk cache and call the underlying
>> disk driver directly, so I use disk->dev->read. For (nand), there is
>> just one partition, so I didn't notice the problem then.
>
> Here's the patch.  Everything seems to be OK.  "--skip=N" is not
> recognized, but it's something in the option parsing code.  "-s N" is
> working.
>
> Please feel free to apply.

Perhaps we should keep the low level api, just fix the offset. Hexdump
is normally used for debugging, and the disk cache is quite annoying.

btw, please try the patch, it dumps the journal information. There
could be quite some output, you can use grub-fstest to capture it.

-- 
Bean

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: e1.diff --]
[-- Type: text/x-diff; name=e1.diff, Size: 2729 bytes --]

diff --git a/fs/ext2.c b/fs/ext2.c
index ffe9e33..4e76097 100644
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -443,14 +443,19 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
   log->last_block = grub_be_to_cpu32 (jsb->maxlen);
   log->start_block = grub_be_to_cpu32 (jsb->start);
 
+  grub_printf ("header: %d %d %d\n", log->first_block, log->last_block, log->start_block);
+
   last_num = num = 0;
   block = log->start_block;
   seq = grub_be_to_cpu32 (jsb->sequence);
+  grub_printf ("seq: %d\n", seq);
 
   while (1)
     {
       struct grub_ext3_journal_header *jh;
 
+      grub_printf ("block: %d\n", block);
+
       if (grub_fshelp_read_file (data->disk, &data->logfile, 0,
                                  block << (log2bs + 9), sizeof (buf),
                                  buf, grub_ext2_read_block,
@@ -476,6 +481,7 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
             struct grub_ext3_journal_block_tag *tag;
             int ofs, flags;
 
+            grub_printf ("dblock: ");
             ofs = sizeof (struct grub_ext3_journal_header);
 
             do
@@ -491,15 +497,19 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
                   ofs += 16;
 
                 log->mapping[num++] = grub_be_to_cpu32 (tag->block);
+                grub_printf ("%d ", grub_be_to_cpu32 (tag->block));
                 next_block();
               }
             while (! (flags & EXT3_JOURNAL_FLAG_LAST_TAG));
 
+            grub_printf ("\n");
+
             continue;
           }
 
         case EXT3_JOURNAL_COMMIT_BLOCK:
           {
+            grub_printf ("cblock: %d\n", seq);
             seq++;
             last_num = num - 1;
             continue;
@@ -510,6 +520,8 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
             struct grub_ext3_journal_revoke_header *jrh;
             grub_uint32_t i;
 
+            grub_printf ("rblock: %d ", jrh->count);
+
             jrh = (struct grub_ext3_journal_revoke_header *) jh;
 
             for (i = 0; i < grub_be_to_cpu32 (jrh->count); i++)
@@ -518,11 +530,12 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
                 grub_uint32_t map;
 
                 map = grub_be_to_cpu32 (jrh->data[i]);
+                grub_printf ("%d ", map);
                 for (j = 0; j < num; j++)
                   if (log->mapping[j] == map)
                     log->mapping[j] = GRUB_FSHELP_JOURNAL_UNUSED_MAPPING;
               }
-
+            grub_printf ("\n");
             continue;
           }
         default:
@@ -538,6 +551,7 @@ quit:
     {
       int size;
 
+      grub_printf ("num: %d\n", last_num);
       size = sizeof (struct grub_fshelp_journal) +
             last_num * sizeof (grub_disk_addr_t);
 

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-08  7:11                 ` Bean
@ 2008-06-08  7:29                   ` Pavel Roskin
  2008-06-08 11:49                     ` Bean
  0 siblings, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-08  7:29 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, 2008-06-08 at 15:11 +0800, Bean wrote:
> On Sun, Jun 8, 2008 at 2:52 PM, Pavel Roskin <proski@gnu.org> wrote:
> >>
> >> The reason I add device support for hexdump is to debug the nand
> >> driver. I need to go around the disk cache and call the underlying
> >> disk driver directly, so I use disk->dev->read. For (nand), there is
> >> just one partition, so I didn't notice the problem then.
> >
> > Here's the patch.  Everything seems to be OK.  "--skip=N" is not
> > recognized, but it's something in the option parsing code.  "-s N" is
> > working.
> >
> > Please feel free to apply.
> 
> Perhaps we should keep the low level api, just fix the offset. Hexdump
> is normally used for debugging, and the disk cache is quite annoying.

OK, it's your choice.

> btw, please try the patch, it dumps the journal information. There
> could be quite some output, you can use grub-fstest to capture it.

It breaks installation:

# grub-install /dev/sda
grub-mkimage: error: cannot stat /usr/local/lib/grub/i386-pc/header:.mod

"header:" must be from the patch.

I cannot generate a short image easily because loopback devices are not
supported.  Perhaps I'll try making a real partition initialized with
zeroes or something like that.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-08  7:29                   ` Pavel Roskin
@ 2008-06-08 11:49                     ` Bean
  2008-06-08 18:42                       ` Pavel Roskin
  0 siblings, 1 reply; 38+ messages in thread
From: Bean @ 2008-06-08 11:49 UTC (permalink / raw)
  To: The development of GRUB 2

On Sun, Jun 8, 2008 at 3:29 PM, Pavel Roskin <proski@gnu.org> wrote:
>> btw, please try the patch, it dumps the journal information. There
>> could be quite some output, you can use grub-fstest to capture it.
>
> It breaks installation:
>
> # grub-install /dev/sda
> grub-mkimage: error: cannot stat /usr/local/lib/grub/i386-pc/header:.mod
>
> "header:" must be from the patch.
>
> I cannot generate a short image easily because loopback devices are not
> supported.  Perhaps I'll try making a real partition initialized with
> zeroes or something like that.

Can you use grub-fstest ?

Also, the header is from

+  grub_printf ("header: %d %d %d\n", log->first_block,
log->last_block, log->start_block);

I don't know why the number doesn't show, unless log is invalid
pointer. Perhaps the size is invalid, try to add a debug line to show
the allocated size of log:

  log = grub_malloc (sizeof (struct grub_fshelp_journal) +
                     grub_be_to_cpu32 (jsb->maxlen) * sizeof
(grub_disk_addr_t));




-- 
Bean



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-08 11:49                     ` Bean
@ 2008-06-08 18:42                       ` Pavel Roskin
  2008-06-08 18:57                         ` Bean
  0 siblings, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-08 18:42 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 1827 bytes --]

On Sun, 2008-06-08 at 19:49 +0800, Bean wrote:

> Can you use grub-fstest ?
> 
> Also, the header is from
> 
> +  grub_printf ("header: %d %d %d\n", log->first_block,
> log->last_block, log->start_block);
> 
> I don't know why the number doesn't show, unless log is invalid
> pointer. Perhaps the size is invalid, try to add a debug line to show
> the allocated size of log:
> 
>   log = grub_malloc (sizeof (struct grub_fshelp_journal) +
>                      grub_be_to_cpu32 (jsb->maxlen) * sizeof
> (grub_disk_addr_t));

The debug output must be getting split somewhere.  If I replace colons
and spaces with underscores, I get some numbers.  Anyway, the
installation with the patch is unnecessary.

I made a short partition and installed grub on it, but there are no
problems with it in qemu.

But I can reproduce the problem with grub-fstest on the root partition.

[root@dv grub2]# grub-fstest /dev/sda1 ls /    
lost+found/ bin/ boot/ data/ dev/ etc/ home/ lib/ lib64/ media/ mnt/
opt/ proc/ root/ sbin/ scratchbox/ selinux/ srv/ sys/ tftpboot/ tmp/
usr/ var/ debug/ tftpboot;4834754b 
[root@dv grub2]# grub-fstest /dev/sda1 ls /boot

[root@dv grub2]# ls /   
bin   debug  home   lost+found  opt   sbin        srv
tftpboot;4834754b  var
boot  dev    lib    media       proc  scratchbox  sys       tmp
data  etc    lib64  mnt         root  selinux     tftpboot  usr
[root@dv grub2]# ls /boot
System.map                    grub                      vmlinuz
System.map-2.6.26-rc4-wl      initrd-2.6.26-rc4-wl.img
vmlinuz-2.6.26-rc4-wl
System.map-2.6.26-rc4-wl.old  memtest86+-2.01
vmlinuz-2.6.26-rc4-wl.old
[root@dv grub2]#

As you can see, "grub-fstest /dev/sda1 ls /boot" fails to find any
files.  Then I patched grub with your patch.  The output of the same
command is attached (compressed).

-- 
Regards,
Pavel Roskin

[-- Attachment #2: Log-boot.bz2 --]
[-- Type: application/x-bzip, Size: 14355 bytes --]

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-08 18:42                       ` Pavel Roskin
@ 2008-06-08 18:57                         ` Bean
  2008-06-09  1:43                           ` Pavel Roskin
  0 siblings, 1 reply; 38+ messages in thread
From: Bean @ 2008-06-08 18:57 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Jun 9, 2008 at 2:42 AM, Pavel Roskin <proski@gnu.org> wrote:
> On Sun, 2008-06-08 at 19:49 +0800, Bean wrote:
>
>> Can you use grub-fstest ?
>>
>> Also, the header is from
>>
>> +  grub_printf ("header: %d %d %d\n", log->first_block,
>> log->last_block, log->start_block);
>>
>> I don't know why the number doesn't show, unless log is invalid
>> pointer. Perhaps the size is invalid, try to add a debug line to show
>> the allocated size of log:
>>
>>   log = grub_malloc (sizeof (struct grub_fshelp_journal) +
>>                      grub_be_to_cpu32 (jsb->maxlen) * sizeof
>> (grub_disk_addr_t));
>
> The debug output must be getting split somewhere.  If I replace colons
> and spaces with underscores, I get some numbers.  Anyway, the
> installation with the patch is unnecessary.
>
> I made a short partition and installed grub on it, but there are no
> problems with it in qemu.
>
> But I can reproduce the problem with grub-fstest on the root partition.
>
> [root@dv grub2]# grub-fstest /dev/sda1 ls /
> lost+found/ bin/ boot/ data/ dev/ etc/ home/ lib/ lib64/ media/ mnt/
> opt/ proc/ root/ sbin/ scratchbox/ selinux/ srv/ sys/ tftpboot/ tmp/
> usr/ var/ debug/ tftpboot;4834754b
> [root@dv grub2]# grub-fstest /dev/sda1 ls /boot
>
> [root@dv grub2]# ls /
> bin   debug  home   lost+found  opt   sbin        srv
> tftpboot;4834754b  var
> boot  dev    lib    media       proc  scratchbox  sys       tmp
> data  etc    lib64  mnt         root  selinux     tftpboot  usr
> [root@dv grub2]# ls /boot
> System.map                    grub                      vmlinuz
> System.map-2.6.26-rc4-wl      initrd-2.6.26-rc4-wl.img
> vmlinuz-2.6.26-rc4-wl
> System.map-2.6.26-rc4-wl.old  memtest86+-2.01
> vmlinuz-2.6.26-rc4-wl.old
> [root@dv grub2]#
>
> As you can see, "grub-fstest /dev/sda1 ls /boot" fails to find any
> files.  Then I patched grub with your patch.  The output of the same
> command is attached (compressed).

Hi,

Thanks, can you also give me the output of dumpe2fs ?

dumpe2fs /dev/sda1

-- 
Bean



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-07  2:58       ` Pavel Roskin
@ 2008-06-08 19:29         ` Robert Millan
  0 siblings, 0 replies; 38+ messages in thread
From: Robert Millan @ 2008-06-08 19:29 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, Jun 06, 2008 at 10:58:43PM -0400, Pavel Roskin wrote:
> Quoting Robert Millan <rmh@aybabtu.com>:
> 
> >On Fri, Jun 06, 2008 at 06:53:52PM -0400, Pavel Roskin wrote:
> >>On Fri, 2008-06-06 at 17:56 +0200, Robert Millan wrote:
> >>> Committed.
> >>
> >>I believe it's wrong.
> >
> >You mean that the lines I removed were wrong, or that my commit is wrong?
> 
> The commit is wrong.

Woops, sorry for the confusion then.

-- 
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What good is a phone call… if you are unable to speak?
(as seen on /.)



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-08 18:57                         ` Bean
@ 2008-06-09  1:43                           ` Pavel Roskin
  2008-06-09 18:30                             ` Bean
  0 siblings, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-09  1:43 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, 2008-06-09 at 02:57 +0800, Bean wrote:

> Thanks, can you also give me the output of dumpe2fs ?
> 
> dumpe2fs /dev/sda1

I'll send it privately, as it won't compress much.

I was trying to find out which change breaks the ext3 support.  It turns
out grub-fstest starts working if I comment out this line in fs/ext2.c:

log->mapping[num++] = grub_be_to_cpu32 (tag->block);

Alternatively, I could replace it with

log->mapping[num++] = GRUB_FSHELP_JOURNAL_UNUSED_MAPPING;

and grub-fstest would list /boot properly.  I added some debug prints,
to see which states it goes through, and here's the end of the output:

descriptor
commit
descriptor
commit
descriptor
commit
descriptor
commit
descriptor
commit
descriptor
commit
descriptor
commit
revoke
descriptor
commit
num = 15628, last_num = 15627
grub/ System.map vmlinuz-2.6.26-rc4-wl.old vmlinuz
System.map-2.6.26-rc4-wl.old vmlinuz-2.6.26-rc4-wl
System.map-2.6.26-rc4-wl initrd-2.6.26-rc4-wl.img memtest86+-2.01 

The number of the blocks is quite large, but we are never hitting the
"default" case.  "revoke" wasn't present in subsequent runs.  The
numbers (num and last_num) keep growing every time by about 20.

I also tried to see what happens on the fshelp.c side.  So I applied
this patch:

diff --git a/fs/fshelp.c b/fs/fshelp.c
index faec1f7..027b579 100644
--- a/fs/fshelp.c
+++ b/fs/fshelp.c
@@ -329,12 +329,18 @@ grub_fshelp_map_block (grub_fshelp_journal_t log, grub_disk_addr_t block)
   if (map_block < 0)
     return block;
 
+  grub_printf("map_block = %ld, start_block = %ld, first_block = %ld, last_block = %d\n",
+	      map_block, log->start_block, log->first_block, log->last_block);
   map_block += log->start_block;
   if (map_block >= log->last_block)
     map_block -= log->last_block - log->first_block;
 
   if (log->type == GRUB_FSHELP_JOURNAL_TYPE_BLOCK)
     return log->blkno + map_block;
-  else
-    return log->get_block (log->node, map_block);
+  else {
+    grub_disk_addr_t ret;
+    ret = log->get_block (log->node, map_block);
+    grub_printf("map_block = %ld, block = %ld, ret = %ld\n", map_block, block, ret);
+    return ret;
+  }
 }

That's what I get:

# ./grub-fstest /dev/sda1 ls /boot
map_block = 18988, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9345, block = 1, ret = 10901
map_block = 18780, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9137, block = 1027, ret = 10692
map_block = 18988, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9345, block = 1, ret = 10901
map_block = 18780, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9137, block = 1027, ret = 10692
map_block = 18988, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9345, block = 1, ret = 10901

But if I change "return ret;" to "return block;" to ignore the lookup, I
get this:

# ./grub-fstest /dev/sda1 ls /boot
map_block = 19373, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9730, block = 1, ret = 11286
map_block = 19209, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9566, block = 1027, ret = 11122
map_block = 19373, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9730, block = 1, ret = 11286
map_block = 19209, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9566, block = 1027, ret = 11122
map_block = 19373, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9730, block = 1, ret = 11286
map_block = 12763, start_block = 23124, first_block = 1, last_block = 32768
map_block = 3120, block = 15237122, ret = 4670
grub/ System.map vmlinuz-2.6.26-rc4-wl.old vmlinuz
System.map-2.6.26-rc4-wl.old vmlinuz-2.6.26-rc4-wl
System.map-2.6.26-rc4-wl initrd-2.6.26-rc4-wl.img memtest86+-2.01 

One thing that surprises me is that the value we are supposed to return
is always below 12000.

Then I created file /boot/foo, ran sync several times, and that's what I
get if "block" is returned:

# ./grub-fstest /dev/sda1 ls /boot
map_block = 19438, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9795, block = 1, ret = 11351
map_block = 19630, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9987, block = 1027, ret = 11543
map_block = 19438, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9795, block = 1, ret = 11351
map_block = 19630, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9987, block = 1027, ret = 11543
map_block = 19438, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9795, block = 1, ret = 11351
map_block = 19627, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9984, block = 15237122, ret = 11540
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
grub/ map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
System.map map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
vmlinuz-2.6.26-rc4-wl.old map_block = 19628, start_block = 23124, first_block = 1, last_block = 
32768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
vmlinuz map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
System.map-2.6.26-rc4-wl.old map_block = 19628, start_block = 23124, first_block = 1, last_block
 = 32768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
vmlinuz-2.6.26-rc4-wl map_block = 19628, start_block = 23124, first_block = 1, last_block = 3276
8
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
System.map-2.6.26-rc4-wl map_block = 19628, start_block = 23124, first_block = 1, last_block = 3
2768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
foo map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
initrd-2.6.26-rc4-wl.img map_block = 19628, start_block = 23124, first_block = 1, last_block = 3
2768
map_block = 9985, block = 15239168, ret = 11541
map_block = 19628, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9985, block = 15239168, ret = 11541
memtest86+-2.01 

But I get this if "ret" is returned:

# ./grub-fstest /dev/sda1 ls /boot
map_block = 19438, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9795, block = 1, ret = 11351
map_block = 19656, start_block = 23124, first_block = 1, last_block = 32768
map_block = 10013, block = 1027, ret = 11569
map_block = 19438, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9795, block = 1, ret = 11351
map_block = 19656, start_block = 23124, first_block = 1, last_block = 32768
map_block = 10013, block = 1027, ret = 11569
map_block = 19438, start_block = 23124, first_block = 1, last_block = 32768
map_block = 9795, block = 1, ret = 11351

"ret" is still in the same region.

-- 
Regards,
Pavel Roskin



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-09  1:43                           ` Pavel Roskin
@ 2008-06-09 18:30                             ` Bean
  2008-06-10  7:16                               ` Bean
  0 siblings, 1 reply; 38+ messages in thread
From: Bean @ 2008-06-09 18:30 UTC (permalink / raw)
  To: The development of GRUB 2

Hi,

It's a little strange, the journal seems normal, I wonder where does
it go wrong.

btw, can you use debugfs to gather more information. You can start it with

debugfs /dev/sda1

Then type in the command

logdump -a output_file

-- 
Bean



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-09 18:30                             ` Bean
@ 2008-06-10  7:16                               ` Bean
  2008-06-10 18:26                                 ` Pavel Roskin
  0 siblings, 1 reply; 38+ messages in thread
From: Bean @ 2008-06-10  7:16 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 71 bytes --]

Hi,

Ok, I fix some bugs, please see if the new patch works.

-- 
Bean

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: e2.diff --]
[-- Type: text/x-diff; name=e2.diff, Size: 3425 bytes --]

diff --git a/fs/ext2.c b/fs/ext2.c
index ffe9e33..4d1e3e1 100644
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -443,20 +443,25 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
   log->last_block = grub_be_to_cpu32 (jsb->maxlen);
   log->start_block = grub_be_to_cpu32 (jsb->start);
 
+  grub_printf ("header: %d %d %d\n", log->first_block, log->last_block, log->start_block);
+
   last_num = num = 0;
   block = log->start_block;
   seq = grub_be_to_cpu32 (jsb->sequence);
+  grub_printf ("seq: %d\n", seq);
 
   while (1)
     {
       struct grub_ext3_journal_header *jh;
 
-      if (grub_fshelp_read_file (data->disk, &data->logfile, 0,
-                                 block << (log2bs + 9), sizeof (buf),
-                                 buf, grub_ext2_read_block,
-                                 log->last_block << (log2bs + 9),
-                                 log2bs) !=
-          (int) sizeof (buf))
+      grub_printf ("block: %d\n", block);
+
+      grub_fshelp_read_file (data->disk, &data->logfile, 0,
+                             block << (log2bs + 9), sizeof (buf),
+                             buf, grub_ext2_read_block,
+                             log->last_block << (log2bs + 9),
+                             log2bs);
+      if (grub_errno)
         break;
 
       jh = (struct grub_ext3_journal_header *) &buf[0];
@@ -476,6 +481,7 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
             struct grub_ext3_journal_block_tag *tag;
             int ofs, flags;
 
+            grub_printf ("dblock: ");
             ofs = sizeof (struct grub_ext3_journal_header);
 
             do
@@ -491,15 +497,19 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
                   ofs += 16;
 
                 log->mapping[num++] = grub_be_to_cpu32 (tag->block);
+                grub_printf ("%d ", grub_be_to_cpu32 (tag->block));
                 next_block();
               }
             while (! (flags & EXT3_JOURNAL_FLAG_LAST_TAG));
 
+            grub_printf ("\n");
+
             continue;
           }
 
         case EXT3_JOURNAL_COMMIT_BLOCK:
           {
+            grub_printf ("cblock: %d\n", seq);
             seq++;
             last_num = num - 1;
             continue;
@@ -508,21 +518,24 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
         case EXT3_JOURNAL_REVOKE_BLOCK:
           {
             struct grub_ext3_journal_revoke_header *jrh;
-            grub_uint32_t i;
+            grub_uint32_t i, cnt;
 
             jrh = (struct grub_ext3_journal_revoke_header *) jh;
+            cnt = (grub_be_to_cpu32 (jrh->count) -
+                   sizeof (struct grub_ext3_journal_revoke_header)) >> 2;
 
-            for (i = 0; i < grub_be_to_cpu32 (jrh->count); i++)
+            for (i = 0; i < cnt; i++)
               {
                 int j;
                 grub_uint32_t map;
 
                 map = grub_be_to_cpu32 (jrh->data[i]);
+                grub_printf ("%d ", map);
                 for (j = 0; j < num; j++)
                   if (log->mapping[j] == map)
                     log->mapping[j] = GRUB_FSHELP_JOURNAL_UNUSED_MAPPING;
               }
-
+            grub_printf ("\n");
             continue;
           }
         default:
@@ -538,6 +551,7 @@ quit:
     {
       int size;
 
+      grub_printf ("num: %d\n", last_num);
       size = sizeof (struct grub_fshelp_journal) +
             last_num * sizeof (grub_disk_addr_t);
 

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-10  7:16                               ` Bean
@ 2008-06-10 18:26                                 ` Pavel Roskin
  2008-06-10 18:51                                   ` Bean
  0 siblings, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-10 18:26 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, 2008-06-10 at 15:16 +0800, Bean wrote:
> Hi,
> 
> Ok, I fix some bugs, please see if the new patch works.

It doesn't work.  i sent the logs privately.  I also checked the logs
and it looks like that GRUB is reading the log properly.  Then I guess
we are not using the log correctly.

I changed fs/ext2.c to see how the results would differ if
grub_fshelp_map_block() is bypassed:

diff --git a/fs/ext2.c b/fs/ext2.c
index ffe9e33..7b4bfd6 100644
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -257,12 +257,24 @@ inline static grub_err_t
 grub_ext2_blockgroup (struct grub_ext2_data *data, int group, 
 		      struct grub_ext2_block_group *blkgrp)
 {
-  return grub_disk_read (data->disk,
-			 (grub_fshelp_map_block (data->journal,
-                                                 grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
-			  << LOG2_EXT2_BLOCK_SIZE (data)),
+  grub_err_t ret;
+  int block;
+
+  block = grub_le_to_cpu32 (data->sblock.first_data_block) + 1;
+  ret = grub_disk_read (data->disk,
+			 block << LOG2_EXT2_BLOCK_SIZE (data),
+			 group * sizeof (struct grub_ext2_block_group), 
+			 sizeof (struct grub_ext2_block_group), (char *) blkgrp);
+  grub_printf("direct:  ret = %d, block = %d, inode_table_id = %d\n", ret, block,
+	      blkgrp->inode_table_id);
+  block = grub_fshelp_map_block(data->journal, block);
+  ret = grub_disk_read (data->disk,
+			 block << LOG2_EXT2_BLOCK_SIZE (data),
 			 group * sizeof (struct grub_ext2_block_group), 
 			 sizeof (struct grub_ext2_block_group), (char *) blkgrp);
+  grub_printf("journal: ret = %d, block = %d, inode_table_id = %d\n", ret, block,
+	      blkgrp->inode_table_id);
+  return ret;
 }
 
 


That's the output:

direct:  ret = 0, block = 1, inode_table_id = 1027
journal: ret = 0, block = 1, inode_table_id = 1027
direct:  ret = 0, block = 1, inode_table_id = 1027
journal: ret = 0, block = 17707, inode_table_id = 1027
direct:  ret = 0, block = 1, inode_table_id = 1027
journal: ret = 0, block = 1, inode_table_id = 1027
direct:  ret = 0, block = 1, inode_table_id = 1027
journal: ret = 0, block = 17707, inode_table_id = 1027
direct:  ret = 0, block = 1, inode_table_id = 15237122
journal: ret = 0, block = 17707, inode_table_id = 6895416


So, originally we didn't have the journal opened, so the mapping was
trivial, then 1 became mapped to 17707.  But at some point the data in
that block became different from what it used to be and different in the
journaled and non-journaled blocks.

-- 
Regards,
Pavel Roskin



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-10 18:26                                 ` Pavel Roskin
@ 2008-06-10 18:51                                   ` Bean
  2008-06-10 20:19                                     ` Pavel Roskin
  2008-06-10 22:58                                     ` Pavel Roskin
  0 siblings, 2 replies; 38+ messages in thread
From: Bean @ 2008-06-10 18:51 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 61 bytes --]

Hi,

I spot another bug, please try the new patch.

-- 
Bean

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: e3.diff --]
[-- Type: text/x-diff; name=e3.diff, Size: 4328 bytes --]

diff --git a/fs/ext2.c b/fs/ext2.c
index ffe9e33..093ce7b 100644
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -257,12 +257,18 @@ inline static grub_err_t
 grub_ext2_blockgroup (struct grub_ext2_data *data, int group, 
 		      struct grub_ext2_block_group *blkgrp)
 {
+  int blkno, blkoff;
+
+  group *= sizeof (struct grub_ext2_block_group);
+  blkno = group >> LOG2_EXT2_BLOCK_SIZE (data);
+  blkoff = group  - (blkno << LOG2_EXT2_BLOCK_SIZE (data));
+
   return grub_disk_read (data->disk,
 			 (grub_fshelp_map_block (data->journal,
-                                                 grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
+                                                 grub_le_to_cpu32 (data->sblock.first_data_block) + 1 + blkno)
 			  << LOG2_EXT2_BLOCK_SIZE (data)),
-			 group * sizeof (struct grub_ext2_block_group), 
-			 sizeof (struct grub_ext2_block_group), (char *) blkgrp);
+			 blkoff,
+                         sizeof (struct grub_ext2_block_group), (char *) blkgrp);
 }
 
 
@@ -443,20 +449,25 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
   log->last_block = grub_be_to_cpu32 (jsb->maxlen);
   log->start_block = grub_be_to_cpu32 (jsb->start);
 
+  grub_printf ("header: %d %d %d\n", log->first_block, log->last_block, log->start_block);
+
   last_num = num = 0;
   block = log->start_block;
   seq = grub_be_to_cpu32 (jsb->sequence);
+  grub_printf ("seq: %d\n", seq);
 
   while (1)
     {
       struct grub_ext3_journal_header *jh;
 
-      if (grub_fshelp_read_file (data->disk, &data->logfile, 0,
-                                 block << (log2bs + 9), sizeof (buf),
-                                 buf, grub_ext2_read_block,
-                                 log->last_block << (log2bs + 9),
-                                 log2bs) !=
-          (int) sizeof (buf))
+      grub_printf ("block: %d\n", block);
+
+      grub_fshelp_read_file (data->disk, &data->logfile, 0,
+                             block << (log2bs + 9), sizeof (buf),
+                             buf, grub_ext2_read_block,
+                             log->last_block << (log2bs + 9),
+                             log2bs);
+      if (grub_errno)
         break;
 
       jh = (struct grub_ext3_journal_header *) &buf[0];
@@ -476,6 +487,7 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
             struct grub_ext3_journal_block_tag *tag;
             int ofs, flags;
 
+            grub_printf ("dblock: ");
             ofs = sizeof (struct grub_ext3_journal_header);
 
             do
@@ -491,15 +503,19 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
                   ofs += 16;
 
                 log->mapping[num++] = grub_be_to_cpu32 (tag->block);
+                grub_printf ("%d ", grub_be_to_cpu32 (tag->block));
                 next_block();
               }
             while (! (flags & EXT3_JOURNAL_FLAG_LAST_TAG));
 
+            grub_printf ("\n");
+
             continue;
           }
 
         case EXT3_JOURNAL_COMMIT_BLOCK:
           {
+            grub_printf ("cblock: %d\n", seq);
             seq++;
             last_num = num - 1;
             continue;
@@ -508,21 +524,24 @@ grub_ext3_get_journal (struct grub_ext2_data *data)
         case EXT3_JOURNAL_REVOKE_BLOCK:
           {
             struct grub_ext3_journal_revoke_header *jrh;
-            grub_uint32_t i;
+            grub_uint32_t i, cnt;
 
             jrh = (struct grub_ext3_journal_revoke_header *) jh;
+            cnt = (grub_be_to_cpu32 (jrh->count) -
+                   sizeof (struct grub_ext3_journal_revoke_header)) >> 2;
 
-            for (i = 0; i < grub_be_to_cpu32 (jrh->count); i++)
+            for (i = 0; i < cnt; i++)
               {
                 int j;
                 grub_uint32_t map;
 
                 map = grub_be_to_cpu32 (jrh->data[i]);
+                grub_printf ("%d ", map);
                 for (j = 0; j < num; j++)
                   if (log->mapping[j] == map)
                     log->mapping[j] = GRUB_FSHELP_JOURNAL_UNUSED_MAPPING;
               }
-
+            grub_printf ("\n");
             continue;
           }
         default:
@@ -538,6 +557,7 @@ quit:
     {
       int size;
 
+      grub_printf ("num: %d\n", last_num);
       size = sizeof (struct grub_fshelp_journal) +
             last_num * sizeof (grub_disk_addr_t);
 

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-10 18:51                                   ` Bean
@ 2008-06-10 20:19                                     ` Pavel Roskin
  2008-06-10 22:58                                     ` Pavel Roskin
  1 sibling, 0 replies; 38+ messages in thread
From: Pavel Roskin @ 2008-06-10 20:19 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 448 bytes --]

On Wed, 2008-06-11 at 02:51 +0800, Bean wrote:
> Hi,
> 
> I spot another bug, please try the new patch.

That didn't work.  Moreover, grub-fstest failed to read /boot on
read-only filesystem.

Thanks to remounting the filesystem and using lzma, I could reduce the
compressed logs to a reasonable size, so I'm posting them here together
with the script that produced them.  lzma should be available in all
modern distros.

-- 
Regards,
Pavel Roskin

[-- Attachment #2: grub-test.tar.lzma --]
[-- Type: application/x-lzma-compressed-tar, Size: 96478 bytes --]

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-10 18:51                                   ` Bean
  2008-06-10 20:19                                     ` Pavel Roskin
@ 2008-06-10 22:58                                     ` Pavel Roskin
  2008-06-10 23:18                                       ` [RFC PATCH] " Pavel Roskin
  2008-06-11  5:25                                       ` Bean
  1 sibling, 2 replies; 38+ messages in thread
From: Pavel Roskin @ 2008-06-10 22:58 UTC (permalink / raw)
  To: The development of GRUB 2

On Wed, 2008-06-11 at 02:51 +0800, Bean wrote: 
> Hi,
> 
> I spot another bug, please try the new patch.

You probably meant to use (LOG2_EXT2_BLOCK_SIZE (data) + 9) in your
patch because the block size is in 512 bytes units, unlike sizeof:

diff --git a/fs/ext2.c b/fs/ext2.c
index e4ce47b..fb13a80 100644
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -260,8 +260,8 @@ grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
   int blkno, blkoff;
 
   group *= sizeof (struct grub_ext2_block_group);
-  blkno = group >> LOG2_EXT2_BLOCK_SIZE (data);
-  blkoff = group  - (blkno << LOG2_EXT2_BLOCK_SIZE (data));
+  blkno = group >> (LOG2_EXT2_BLOCK_SIZE (data) + 9);
+  blkoff = group - (blkno << (LOG2_EXT2_BLOCK_SIZE (data) + 9));
 
   return grub_disk_read (data->disk,
 			 (grub_fshelp_map_block (data->journal,

That appears to fix everything!!!  grub-fstest is loading, GRUB is
working in qemu on the live filesystem, and the normal boot is still
working.

I think we should consider having a journaling layer above
grub_disk_read() that would do the substitution and avoid such bugs in
the future.

-- 
Regards,
Pavel Roskin



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH] Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-10 22:58                                     ` Pavel Roskin
@ 2008-06-10 23:18                                       ` Pavel Roskin
  2008-06-11  5:25                                       ` Bean
  1 sibling, 0 replies; 38+ messages in thread
From: Pavel Roskin @ 2008-06-10 23:18 UTC (permalink / raw)
  To: The development of GRUB 2

Hello!

Here's the patch with some cleanups and nice wrapped lines.  I leaving
out other fixes from e3.diff, they should be applied separately and
don't appear to be critical for my setup.

Changelog:

	* fs/ext2.c (grub_ext2_blockgroup): Call grub_fshelp_map_block()
	for the block that contains data for the requested group.

diff --git a/fs/ext2.c b/fs/ext2.c
index ffe9e33..f8642bb 100644
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -257,12 +257,18 @@ inline static grub_err_t
 grub_ext2_blockgroup (struct grub_ext2_data *data, int group, 
 		      struct grub_ext2_block_group *blkgrp)
 {
+  int blkno, blkoff;
+
+  blkoff = group * sizeof (struct grub_ext2_block_group);
+  blkno = blkoff >> (LOG2_EXT2_BLOCK_SIZE (data) + 9);
+  blkoff -= (blkno << (LOG2_EXT2_BLOCK_SIZE (data) + 9));
+  blkno += grub_le_to_cpu32 (data->sblock.first_data_block) + 1;
+
   return grub_disk_read (data->disk,
-			 (grub_fshelp_map_block (data->journal,
-                                                 grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
+			 (grub_fshelp_map_block (data->journal, blkno)
 			  << LOG2_EXT2_BLOCK_SIZE (data)),
-			 group * sizeof (struct grub_ext2_block_group), 
-			 sizeof (struct grub_ext2_block_group), (char *) blkgrp);
+			 blkoff, sizeof (struct grub_ext2_block_group),
+			 (char *) blkgrp);
 }
 
 

-- 
Regards,
Pavel Roskin



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-10 22:58                                     ` Pavel Roskin
  2008-06-10 23:18                                       ` [RFC PATCH] " Pavel Roskin
@ 2008-06-11  5:25                                       ` Bean
  2008-06-12  4:01                                         ` Pavel Roskin
  2008-06-12  6:22                                         ` Pavel Roskin
  1 sibling, 2 replies; 38+ messages in thread
From: Bean @ 2008-06-11  5:25 UTC (permalink / raw)
  To: The development of GRUB 2

On Wed, Jun 11, 2008 at 6:58 AM, Pavel Roskin <proski@gnu.org> wrote:
> On Wed, 2008-06-11 at 02:51 +0800, Bean wrote:
>> Hi,
>>
>> I spot another bug, please try the new patch.
>
> You probably meant to use (LOG2_EXT2_BLOCK_SIZE (data) + 9) in your
> patch because the block size is in 512 bytes units, unlike sizeof:
>
> diff --git a/fs/ext2.c b/fs/ext2.c
> index e4ce47b..fb13a80 100644
> --- a/fs/ext2.c
> +++ b/fs/ext2.c
> @@ -260,8 +260,8 @@ grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
>   int blkno, blkoff;
>
>   group *= sizeof (struct grub_ext2_block_group);
> -  blkno = group >> LOG2_EXT2_BLOCK_SIZE (data);
> -  blkoff = group  - (blkno << LOG2_EXT2_BLOCK_SIZE (data));
> +  blkno = group >> (LOG2_EXT2_BLOCK_SIZE (data) + 9);
> +  blkoff = group - (blkno << (LOG2_EXT2_BLOCK_SIZE (data) + 9));
>
>   return grub_disk_read (data->disk,
>                         (grub_fshelp_map_block (data->journal,
>
> That appears to fix everything!!!  grub-fstest is loading, GRUB is
> working in qemu on the live filesystem, and the normal boot is still
> working.
>

Oh, nice catch, I make a silly mistake again, :)

> I think we should consider having a journaling layer above
> grub_disk_read() that would do the substitution and avoid such bugs in
> the future.

This should be all right, but we need to move the journal support from
fshelp.c to disk.c, anyone objects ?

-- 
Bean



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-11  5:25                                       ` Bean
@ 2008-06-12  4:01                                         ` Pavel Roskin
  2008-06-12  6:22                                         ` Pavel Roskin
  1 sibling, 0 replies; 38+ messages in thread
From: Pavel Roskin @ 2008-06-12  4:01 UTC (permalink / raw)
  To: grub-devel

Quoting Bean <bean123ch@gmail.com>:

>> I think we should consider having a journaling layer above
>> grub_disk_read() that would do the substitution and avoid such bugs in
>> the future.
>
> This should be all right, but we need to move the journal support from
> fshelp.c to disk.c, anyone objects ?

No objection from me.  But if it's complicated, we can start with an  
ext2 specific function that would translate offset and size to block  
numbers, apply journal mappings and read the data.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-11  5:25                                       ` Bean
  2008-06-12  4:01                                         ` Pavel Roskin
@ 2008-06-12  6:22                                         ` Pavel Roskin
  2008-06-12  9:51                                           ` Bean
  1 sibling, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-12  6:22 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 847 bytes --]

Quoting Bean <bean123ch@gmail.com>:

> This should be all right, but we need to move the journal support from
> fshelp.c to disk.c, anyone objects ?

I've converted ext2.c.  The patch is attached.  The interface should  
be OK for reiserfs.  It looks like the call to grub_fshelp_map_block()  
from grub_ext2_read_inode() was also wrong.  I'm afraid there are some  
wrong places in reiserfs as well.

I would like to commit the patch as soon as possible.  It's a serious  
issue, and we don't want to scare away potential testers and  
contributors.

ChangeLog:
         * fs/fshelp.c (grub_fshelp_read): New function.  Implement linear
         disk read with journal translation.
         * fs/ext2.c: Use grub_fshelp_read() instead of grub_disk_read().
         * include/grub/fshelp.h: Declare grub_fshelp_read().

-- 
Regards,
Pavel Roskin


[-- Attachment #2: 01-ext2-blockread.patch --]
[-- Type: text/plain, Size: 5651 bytes --]

diff --git a/fs/ext2.c b/fs/ext2.c
index ffe9e33..999bd80 100644
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -257,12 +257,11 @@ inline static grub_err_t
 grub_ext2_blockgroup (struct grub_ext2_data *data, int group, 
 		      struct grub_ext2_block_group *blkgrp)
 {
-  return grub_disk_read (data->disk,
-			 (grub_fshelp_map_block (data->journal,
-                                                 grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
-			  << LOG2_EXT2_BLOCK_SIZE (data)),
-			 group * sizeof (struct grub_ext2_block_group), 
-			 sizeof (struct grub_ext2_block_group), (char *) blkgrp);
+  return grub_fshelp_read (data->disk, data->journal,
+			   grub_le_to_cpu32 (data->sblock.first_data_block) + 1,
+			   group * sizeof (struct grub_ext2_block_group),
+			   sizeof (struct grub_ext2_block_group),
+			   (char *) blkgrp, LOG2_EXT2_BLOCK_SIZE (data));
 }
 
 
@@ -283,11 +282,9 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
     {
       grub_uint32_t indir[blksz / 4];
 
-      if (grub_disk_read (data->disk, 
-			  grub_fshelp_map_block(data->journal,
-                                                grub_le_to_cpu32 (inode->blocks.indir_block))
-			  << log2_blksz,
-			  0, blksz, (char *) indir))
+      if (grub_fshelp_read (data->disk, data->journal,
+			    grub_le_to_cpu32 (inode->blocks.indir_block),
+			    0, blksz, (char *) indir, log2_blksz))
 	return grub_errno;
 	  
       blknr = grub_le_to_cpu32 (indir[fileblock - INDIRECT_BLOCKS]);
@@ -300,18 +297,14 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
 					 + blksz / 4);
       grub_uint32_t indir[blksz / 4];
 
-      if (grub_disk_read (data->disk, 
-			  grub_fshelp_map_block(data->journal,
-                                                grub_le_to_cpu32 (inode->blocks.double_indir_block))
-			  << log2_blksz,
-			  0, blksz, (char *) indir))
+      if (grub_fshelp_read (data->disk, data->journal,
+			    grub_le_to_cpu32 (inode->blocks.double_indir_block),
+			    0, blksz, (char *) indir, log2_blksz))
 	return grub_errno;
 
-      if (grub_disk_read (data->disk,
-			  grub_fshelp_map_block(data->journal,
-                                                grub_le_to_cpu32 (indir[rblock / perblock]))
-			  << log2_blksz,
-			  0, blksz, (char *) indir))
+      if (grub_fshelp_read (data->disk, data->journal,
+			    grub_le_to_cpu32 (indir[rblock / perblock]),
+			    0, blksz, (char *) indir, log2_blksz))
 	return grub_errno;
 
       
@@ -372,12 +365,11 @@ grub_ext2_read_inode (struct grub_ext2_data *data,
     % inodes_per_block;
   
   /* Read the inode.  */
-  if (grub_disk_read (data->disk, 
-		      grub_fshelp_map_block(data->journal,
-                                            grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno)
-                      << LOG2_EXT2_BLOCK_SIZE (data),
-		      EXT2_INODE_SIZE (data) * blkoff,
-		      sizeof (struct grub_ext2_inode), (char *) inode))
+  if (grub_fshelp_read (data->disk, data->journal,
+			grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno,
+			EXT2_INODE_SIZE (data) * blkoff,
+			sizeof (struct grub_ext2_inode), (char *) inode,
+			LOG2_EXT2_BLOCK_SIZE (data)))
     return grub_errno;
   
   return 0;
diff --git a/fs/fshelp.c b/fs/fshelp.c
index faec1f7..52131b0 100644
--- a/fs/fshelp.c
+++ b/fs/fshelp.c
@@ -215,6 +215,45 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
 }
 
 
+/* Read LEN bytes from the block BLOCK on disk DISK into the buffer BUF,
+   beginning with the block POS.  Apply mappings from LOG.  The blocks
+   have a size of LOG2BLOCKSIZE (in log2).  */
+grub_err_t grub_fshelp_read (grub_disk_t disk, grub_fshelp_journal_t log,
+			     grub_disk_addr_t block, grub_off_t pos,
+			     grub_size_t len, char *buf, int log2blocksize)
+{
+  grub_off_t relblk;
+
+  relblk = pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS);
+  block += relblk;
+  pos -= relblk << (log2blocksize + GRUB_DISK_SECTOR_BITS);
+
+  while (len > 0)
+    {
+      grub_err_t ret;
+      grub_size_t size;
+
+      size = (GRUB_DISK_SECTOR_SIZE << log2blocksize) - pos;
+      if (size > len)
+	size = len;
+
+      ret = grub_disk_read (disk,
+			    grub_fshelp_map_block (log, block) << log2blocksize,
+			    pos, size, buf);
+
+      if (ret)
+	return ret;
+
+      block++;
+      pos = 0;
+      buf += size;
+      len -= size;
+    }
+
+  return 0;
+}
+
+
 /* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
    beginning with the block POS.  READ_HOOK should be set before
    reading a block from the file.  GET_BLOCK is used to translate file
diff --git a/include/grub/fshelp.h b/include/grub/fshelp.h
index 0120cbf..847f78e 100644
--- a/include/grub/fshelp.h
+++ b/include/grub/fshelp.h
@@ -84,6 +84,15 @@ EXPORT_FUNC(grub_fshelp_find_file) (const char *path,
 				    enum grub_fshelp_filetype expect);
 
 
+/* Read LEN bytes from the block BLOCK on disk DISK into the buffer BUF,
+   beginning with the block POS.  Apply mappings from LOG.  The blocks
+   have a size of LOG2BLOCKSIZE (in log2).  */
+grub_err_t
+EXPORT_FUNC(grub_fshelp_read) (grub_disk_t disk, grub_fshelp_journal_t log,
+			       grub_disk_addr_t block, grub_off_t pos,
+			       grub_size_t len, char *buf, int log2blocksize);
+
+
 /* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
    beginning with the block POS.  READ_HOOK should be set before
    reading a block from the file.  GET_BLOCK is used to translate file

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-12  6:22                                         ` Pavel Roskin
@ 2008-06-12  9:51                                           ` Bean
  2008-06-12 16:25                                             ` Pavel Roskin
  0 siblings, 1 reply; 38+ messages in thread
From: Bean @ 2008-06-12  9:51 UTC (permalink / raw)
  To: The development of GRUB 2

On Thu, Jun 12, 2008 at 2:22 PM, Pavel Roskin <proski@gnu.org> wrote:
> Quoting Bean <bean123ch@gmail.com>:
>
>> This should be all right, but we need to move the journal support from
>> fshelp.c to disk.c, anyone objects ?
>
> I've converted ext2.c.  The patch is attached.  The interface should be OK
> for reiserfs.  It looks like the call to grub_fshelp_map_block() from
> grub_ext2_read_inode() was also wrong.  I'm afraid there are some wrong
> places in reiserfs as well.

The call in grub_ext2_read_inode should be ok, blkoff would limit the
read access to within a block.

>
> I would like to commit the patch as soon as possible.  It's a serious issue,
> and we don't want to scare away potential testers and contributors.
>
> ChangeLog:
>        * fs/fshelp.c (grub_fshelp_read): New function.  Implement linear
>        disk read with journal translation.
>        * fs/ext2.c: Use grub_fshelp_read() instead of grub_disk_read().
>        * include/grub/fshelp.h: Declare grub_fshelp_read().

Seems fine to me. grub_ext3_get_journal still have some issue, but I
can fix it after you commit it.

-- 
Bean



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-12  9:51                                           ` Bean
@ 2008-06-12 16:25                                             ` Pavel Roskin
  2008-06-13  3:48                                               ` Bean
  0 siblings, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-12 16:25 UTC (permalink / raw)
  To: The development of GRUB 2

On Thu, 2008-06-12 at 17:51 +0800, Bean wrote:

> The call in grub_ext2_read_inode should be ok, blkoff would limit the
> read access to within a block.

You are right.  Now that we have grub_fshelp_read(), we don't need that
code, so I'm removing it.  The block normalization should be done in one
place.

> Seems fine to me.

Committed.

>  grub_ext3_get_journal still have some issue, but I
> can fix it after you commit it.

Please go ahead.  And please take care of reiserfs if you can.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-12 16:25                                             ` Pavel Roskin
@ 2008-06-13  3:48                                               ` Bean
  2008-06-13  4:31                                                 ` Pavel Roskin
  0 siblings, 1 reply; 38+ messages in thread
From: Bean @ 2008-06-13  3:48 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, Jun 13, 2008 at 12:25 AM, Pavel Roskin <proski@gnu.org> wrote:
> On Thu, 2008-06-12 at 17:51 +0800, Bean wrote:
>
>> The call in grub_ext2_read_inode should be ok, blkoff would limit the
>> read access to within a block.
>
> You are right.  Now that we have grub_fshelp_read(), we don't need that
> code, so I'm removing it.  The block normalization should be done in one
> place.
>
>> Seems fine to me.
>
> Committed.
>
>>  grub_ext3_get_journal still have some issue, but I
>> can fix it after you commit it.
>
> Please go ahead.  And please take care of reiserfs if you can.

Hi,

After more thoughts, I think the current method still have problem.
grub_disk_read reads up to 8192 bytes at a time, which can be larger
than the block size. Unless all or none of the sectors in the same
block is mapped, we end up reading the wrong sector. So we need to do
the mapping inside grub_disk_read.

-- 
Bean



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-13  3:48                                               ` Bean
@ 2008-06-13  4:31                                                 ` Pavel Roskin
  2008-06-13  4:39                                                   ` Bean
  0 siblings, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-13  4:31 UTC (permalink / raw)
  To: grub-devel

Quoting Bean <bean123ch@gmail.com>:

> After more thoughts, I think the current method still have problem.
> grub_disk_read reads up to 8192 bytes at a time, which can be larger
> than the block size.

But we never ask grub_disk_read() to read across the block boundary in  
grub_fshelp_read().  The code takes care of it.  I assume  
grub_disk_read() would not write more than requested to the buffer.

> Unless all or none of the sectors in the same
> block is mapped, we end up reading the wrong sector. So we need to do
> the mapping inside grub_disk_read.

But mapping is done for blocks, not for sectors.   
grub_fshelp_map_block() clearly assumes that for every filesystem.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-13  4:31                                                 ` Pavel Roskin
@ 2008-06-13  4:39                                                   ` Bean
  2008-06-13  5:00                                                     ` Pavel Roskin
  0 siblings, 1 reply; 38+ messages in thread
From: Bean @ 2008-06-13  4:39 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, Jun 13, 2008 at 12:31 PM, Pavel Roskin <proski@gnu.org> wrote:
> Quoting Bean <bean123ch@gmail.com>:
>
>> After more thoughts, I think the current method still have problem.
>> grub_disk_read reads up to 8192 bytes at a time, which can be larger
>> than the block size.
>
> But we never ask grub_disk_read() to read across the block boundary in
> grub_fshelp_read().  The code takes care of it.  I assume grub_disk_read()
> would not write more than requested to the buffer.

grub_disk_read would attempt to read up to GRUB_DISK_CACHE_SIZE and
put the result in a cache, then copy the necessary part to output.

>
>> Unless all or none of the sectors in the same
>> block is mapped, we end up reading the wrong sector. So we need to do
>> the mapping inside grub_disk_read.
>
> But mapping is done for blocks, not for sectors.  grub_fshelp_map_block()
> clearly assumes that for every filesystem.

block size is fs related, but most are less than 8192 bytes.

-- 
Bean



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-13  4:39                                                   ` Bean
@ 2008-06-13  5:00                                                     ` Pavel Roskin
  2008-06-13  5:18                                                       ` Bean
  0 siblings, 1 reply; 38+ messages in thread
From: Pavel Roskin @ 2008-06-13  5:00 UTC (permalink / raw)
  To: grub-devel

Quoting Bean <bean123ch@gmail.com>:

> On Fri, Jun 13, 2008 at 12:31 PM, Pavel Roskin <proski@gnu.org> wrote:
>> Quoting Bean <bean123ch@gmail.com>:
>>
>>> After more thoughts, I think the current method still have problem.
>>> grub_disk_read reads up to 8192 bytes at a time, which can be larger
>>> than the block size.
>>
>> But we never ask grub_disk_read() to read across the block boundary in
>> grub_fshelp_read().  The code takes care of it.  I assume grub_disk_read()
>> would not write more than requested to the buffer.
>
> grub_disk_read would attempt to read up to GRUB_DISK_CACHE_SIZE and
> put the result in a cache, then copy the necessary part to output.

Then I don't see any problem with it.  Maybe you could give an example?

>>> Unless all or none of the sectors in the same
>>> block is mapped, we end up reading the wrong sector. So we need to do
>>> the mapping inside grub_disk_read.
>>
>> But mapping is done for blocks, not for sectors.  grub_fshelp_map_block()
>> clearly assumes that for every filesystem.
>
> block size is fs related, but most are less than 8192 bytes.

I don't understand why caching would have any effect.  It should be  
transparent for higher layers, like caching inside the hard drive.  If  
caching is not transparent, then it's broken.

-- 
Regards,
Pavel Roskin



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH] biosdisk / open_device() messing up offsets
  2008-06-13  5:00                                                     ` Pavel Roskin
@ 2008-06-13  5:18                                                       ` Bean
  0 siblings, 0 replies; 38+ messages in thread
From: Bean @ 2008-06-13  5:18 UTC (permalink / raw)
  To: The development of GRUB 2

On Fri, Jun 13, 2008 at 1:00 PM, Pavel Roskin <proski@gnu.org> wrote:
> Quoting Bean <bean123ch@gmail.com>:
>
>> On Fri, Jun 13, 2008 at 12:31 PM, Pavel Roskin <proski@gnu.org> wrote:
>>>
>>> Quoting Bean <bean123ch@gmail.com>:
>>>
>>>> After more thoughts, I think the current method still have problem.
>>>> grub_disk_read reads up to 8192 bytes at a time, which can be larger
>>>> than the block size.
>>>
>>> But we never ask grub_disk_read() to read across the block boundary in
>>> grub_fshelp_read().  The code takes care of it.  I assume
>>> grub_disk_read()
>>> would not write more than requested to the buffer.
>>
>> grub_disk_read would attempt to read up to GRUB_DISK_CACHE_SIZE and
>> put the result in a cache, then copy the necessary part to output.
>
> Then I don't see any problem with it.  Maybe you could give an example?
>
>>>> Unless all or none of the sectors in the same
>>>> block is mapped, we end up reading the wrong sector. So we need to do
>>>> the mapping inside grub_disk_read.
>>>
>>> But mapping is done for blocks, not for sectors.  grub_fshelp_map_block()
>>> clearly assumes that for every filesystem.
>>
>> block size is fs related, but most are less than 8192 bytes.
>
> I don't understand why caching would have any effect.  It should be
> transparent for higher layers, like caching inside the hard drive.  If
> caching is not transparent, then it's broken.

Hi,

I'm sorry I got a little confused. Your method does work, no need to
worry about it now.

-- 
Bean



^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2008-06-13  5:18 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-04 23:35 [PATCH] biosdisk / open_device() messing up offsets Robert Millan
2008-06-05  1:47 ` Pavel Roskin
2008-06-05 21:12   ` Robert Millan
2008-06-06 15:56 ` Robert Millan
2008-06-06 22:53   ` Pavel Roskin
2008-06-06 23:38     ` Robert Millan
2008-06-07  2:58       ` Pavel Roskin
2008-06-08 19:29         ` Robert Millan
2008-06-07  6:33       ` Pavel Roskin
2008-06-07  7:48         ` Bean
2008-06-08  6:00           ` Pavel Roskin
2008-06-08  6:44             ` Bean
2008-06-08  6:52               ` Pavel Roskin
2008-06-08  7:11                 ` Bean
2008-06-08  7:29                   ` Pavel Roskin
2008-06-08 11:49                     ` Bean
2008-06-08 18:42                       ` Pavel Roskin
2008-06-08 18:57                         ` Bean
2008-06-09  1:43                           ` Pavel Roskin
2008-06-09 18:30                             ` Bean
2008-06-10  7:16                               ` Bean
2008-06-10 18:26                                 ` Pavel Roskin
2008-06-10 18:51                                   ` Bean
2008-06-10 20:19                                     ` Pavel Roskin
2008-06-10 22:58                                     ` Pavel Roskin
2008-06-10 23:18                                       ` [RFC PATCH] " Pavel Roskin
2008-06-11  5:25                                       ` Bean
2008-06-12  4:01                                         ` Pavel Roskin
2008-06-12  6:22                                         ` Pavel Roskin
2008-06-12  9:51                                           ` Bean
2008-06-12 16:25                                             ` Pavel Roskin
2008-06-13  3:48                                               ` Bean
2008-06-13  4:31                                                 ` Pavel Roskin
2008-06-13  4:39                                                   ` Bean
2008-06-13  5:00                                                     ` Pavel Roskin
2008-06-13  5:18                                                       ` Bean
2008-06-07  8:37     ` Bean
2008-06-08  5:41       ` Pavel Roskin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.