GNU bug report logs - #9077
coreutils-8.12: fiemap.h uses "struct fiemap_extent fm_extents[0];"

Previous Next

Package: coreutils;

Reported by: "Joachim Schmitz" <jojo <at> schmitz-digital.de>

Date: Thu, 14 Jul 2011 07:05:02 UTC

Severity: normal

Done: Paul Eggert <eggert <at> cs.ucla.edu>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 9077 in the body.
You can then email your comments to 9077 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#9077; Package coreutils. (Thu, 14 Jul 2011 07:05:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to "Joachim Schmitz" <jojo <at> schmitz-digital.de>:
New bug report received and forwarded. Copy sent to bug-coreutils <at> gnu.org. (Thu, 14 Jul 2011 07:05:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: "Joachim Schmitz" <jojo <at> schmitz-digital.de>
To: <bug-coreutils <at> gnu.org>
Subject: coreutils-8.12: fiemap.h uses "struct fiemap_extent fm_extents[0];"
Date: Thu, 14 Jul 2011 09:03:56 +0200
[Message part 1 (text/plain, inline)]
Hi folks

 

fiemap.h uses 

 

struct fiemap_extent fm_extents[0];

 

My compiler (HP NonStop) disallows that. The following would be allowed
though:

 

struct fiemap_extent fm_extents[];

 

Bye, Jojo

[Message part 2 (text/html, inline)]

Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#9077; Package coreutils. (Thu, 14 Jul 2011 11:48:02 GMT) Full text and rfc822 format available.

Message #8 received at 9077 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Joachim Schmitz <jojo <at> schmitz-digital.de>
Cc: 9077 <at> debbugs.gnu.org
Subject: Re: bug#9077: coreutils-8.12: fiemap.h uses "struct fiemap_extent
	fm_extents[0]; "
Date: Thu, 14 Jul 2011 12:45:25 +0100
On 14/07/11 08:03, Joachim Schmitz wrote:
> Hi folks
> 
> fiemap.h uses 
> 
> struct fiemap_extent fm_extents[0];
> 
> My compiler (HP NonStop) disallows that. The following would be allowed
> though:
> 
> struct fiemap_extent fm_extents[];

The non standard "zero length array" syntax was copied from
the linux kernel headers. Changing this to a C99 flexible array
as you suggest, should be fine according to the constraints listed here:
http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
It results in identical object files with GCC here.

I'll apply the above in your name.

cheers,
Pádraig.




Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#9077; Package coreutils. (Thu, 14 Jul 2011 22:51:02 GMT) Full text and rfc822 format available.

Message #11 received at 9077 <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Pádraig Brady <P <at> draigBrady.com>
Cc: Joachim Schmitz <jojo <at> schmitz-digital.de>, 9077 <at> debbugs.gnu.org
Subject: Re: bug#9077: coreutils-8.12: fiemap.h uses "struct fiemap_extent
	fm_extents[0]; "
Date: Thu, 14 Jul 2011 15:50:07 -0700
On 07/14/11 04:45, Pádraig Brady wrote:
> The non standard "zero length array" syntax was copied from
> the linux kernel headers. Changing this to a C99 flexible array
> as you suggest, should be fine according to the constraints listed here:

Won't this break non-GCC compilers that don't support
C99 flexible arrays?

Instead, how about this patch?  If I understand things correctly,
it should fix the problem on NonStop, and should also work with
pre-C99 non-GCC compilers.

diff --git a/src/fiemap.h b/src/fiemap.h
index 1938c74..e7243b4 100644
--- a/src/fiemap.h
+++ b/src/fiemap.h
@@ -51,8 +51,9 @@ struct fiemap
 
   uint32_t fm_reserved;
 
-  /* Array of mapped extents(out).  */
-  struct fiemap_extent fm_extents[0];
+  /* Array of mapped extents(out).
+     The actual size is given by fm_extent_count.  */
+  struct fiemap_extent fm_extents[1];
 };
 
 /* The maximum offset can be mapped for a file.  */




Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#9077; Package coreutils. (Fri, 15 Jul 2011 01:14:01 GMT) Full text and rfc822 format available.

Message #14 received at 9077 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Paul Eggert <eggert <at> cs.ucla.edu>
Cc: Joachim Schmitz <jojo <at> schmitz-digital.de>, 9077 <at> debbugs.gnu.org
Subject: Re: bug#9077: coreutils-8.12: fiemap.h uses "struct fiemap_extent
	fm_extents[0]; "
Date: Fri, 15 Jul 2011 02:11:08 +0100
On 14/07/11 23:50, Paul Eggert wrote:
> On 07/14/11 04:45, Pádraig Brady wrote:
>> The non standard "zero length array" syntax was copied from
>> the linux kernel headers. Changing this to a C99 flexible array
>> as you suggest, should be fine according to the constraints listed here:
> 
> Won't this break non-GCC compilers that don't support
> C99 flexible arrays?

Yes. But we require C99, and it would be
interesting to see what features we could rely
on going forward.

I had checked with solaris compilers which support
this since 2004 at least.

Though saying that, the single element hack
isn't too bad and might allow some other platform to build
without issue.

> Instead, how about this patch?  If I understand things correctly,
> it should fix the problem on NonStop, and should also work with
> pre-C99 non-GCC compilers.

feel free to push that

cheers,
Pádraig.




Reply sent to Paul Eggert <eggert <at> cs.ucla.edu>:
You have taken responsibility. (Fri, 15 Jul 2011 05:09:02 GMT) Full text and rfc822 format available.

Notification sent to "Joachim Schmitz" <jojo <at> schmitz-digital.de>:
bug acknowledged by developer. (Fri, 15 Jul 2011 05:09:02 GMT) Full text and rfc822 format available.

Message #19 received at 9077-done <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Pádraig Brady <P <at> draigBrady.com>
Cc: 9077-done <at> debbugs.gnu.org, Joachim Schmitz <jojo <at> schmitz-digital.de>
Subject: Re: bug#9077: coreutils-8.12: fiemap.h uses "struct fiemap_extent
	fm_extents[0]; "
Date: Thu, 14 Jul 2011 22:08:38 -0700
On 07/14/11 18:11, Pádraig Brady wrote:
> feel free to push that

OK, thanks, done.




Message #20 received at 9077-done <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Paul Eggert <eggert <at> cs.ucla.edu>
Cc: 9077-done <at> debbugs.gnu.org, Joachim Schmitz <jojo <at> schmitz-digital.de>
Subject: Re: bug#9077: coreutils-8.12: fiemap.h uses "struct fiemap_extent
	fm_extents[0]; "
Date: Fri, 15 Jul 2011 10:49:29 +0100
On 15/07/11 06:08, Paul Eggert wrote:
> On 07/14/11 18:11, Pádraig Brady wrote:
>> feel free to push that
> 
> OK, thanks, done.

And now that I look at the code a little longer,
I think that the sizeof calculations need to be
adjusted in extent_scan_read() too.
But that's a step too far I think.
So I'm going to apply this.

cheers,
Pádraig.

commit 1ab94c86ca409c2800ce39e2934538c1eed2af10
Author: Pádraig Brady <P <at> draigBrady.com>
Date:   Fri Jul 15 09:51:35 2011 +0100

    build: avoid a fiemap compile failure on some systems

    * src/fiemap.h (struct fiemap): Adjust the previous change
    to the fiemap_extents array, which would also require changes
    to the sizeof calculations in extent_scan_read().
    Instead, only declare the fiemap_extents zero length array
    on linux, which is the only platform that references this member.
    This avoids a compilation failure on systems that don't support
    this non standard construct.  We don't use the equivalent C99
    flexible array construct so as to have maximum portability.
    * src/extent-scan.c: Cleanup. Remove a redundant #ifndef.

diff --git a/src/extent-scan.c b/src/extent-scan.c
index 48dd564..37445b8 100644
--- a/src/extent-scan.c
+++ b/src/extent-scan.c
@@ -24,11 +24,9 @@

 #include "system.h"
 #include "extent-scan.h"
+#include "fiemap.h"
 #include "xstrtol.h"

-#ifndef HAVE_FIEMAP
-# include "fiemap.h"
-#endif

 /* Work around Linux kernel issues on BTRFS and EXT4 before 2.6.39.
    FIXME: remove in 2013, or whenever we're pretty confident
diff --git a/src/fiemap.h b/src/fiemap.h
index e7243b4..3b35297 100644
--- a/src/fiemap.h
+++ b/src/fiemap.h
@@ -52,8 +52,12 @@ struct fiemap
   uint32_t fm_reserved;

   /* Array of mapped extents(out).
-     The actual size is given by fm_extent_count.  */
-  struct fiemap_extent fm_extents[1];
+     This is protected by the ifdef because it uses non standard
+     zero length arrays.  Note C99 has the equivalent flexible arrays,
+     but we don't use those for maximum portability to older systems.  */
+#ifdef __linux__
+  struct fiemap_extent fm_extents[0];
+#endif
 };

 /* The maximum offset can be mapped for a file.  */






Message #21 received at 9077-done <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Pádraig Brady <P <at> draigBrady.com>
Cc: 9077-done <at> debbugs.gnu.org, Joachim Schmitz <jojo <at> schmitz-digital.de>
Subject: Re: bug#9077: coreutils-8.12: fiemap.h uses "struct fiemap_extent
	fm_extents[0]; "
Date: Fri, 15 Jul 2011 15:45:31 -0700
On 07/15/11 02:49, Pádraig Brady wrote:
> +#ifdef __linux__
> +  struct fiemap_extent fm_extents[0];
> +#endif

This assumes that all GNU/Linux compiles will
use a compiler that allows size-zero arrays;
also, it assumes that sizeof (struct fiemap)
== offsetof (struct fiemap, fm_extents).
Although both assumptions are probably
portable in practice in this particular case,
it's better to avoid them, if avoiding them is easy.
This will help future-proof the code if we alter the
data structures, as altering them might cause problems
such as what I recently encountered in GNU Emacs's C code.

How about the following further patch?  It should do the trick.

build: more-portable fix for fiemap compile failure
* src/extent-scan.c: Include <stddef.h>, for offsetof.
(extent_scan_read): Don't assume that sizeof (struct fiemap) is
equal to offsetof (struct fiemap, fm_extents).  Although this
should be a portable assumption in practice for this particular
case, the C standard doesn't guarantee it, and we might as well do
it the right way.  As it happens I recently got burned by this
exact issue in the source code for GNU Emacs; see
<http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8884>.
* src/fiemap.h (struct fiemap.fm_extents): Change size back to 1.
diff --git a/src/extent-scan.c b/src/extent-scan.c
index 37445b8..434258f 100644
--- a/src/extent-scan.c
+++ b/src/extent-scan.c
@@ -17,6 +17,7 @@
    Written by Jie Liu (jeff.liu <at> oracle.com).  */

 #include <config.h>
+#include <stddef.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <sys/utsname.h>
@@ -96,7 +97,10 @@ extent_scan_read (struct extent_scan *scan)
       union { struct fiemap f; char c[4096]; } fiemap_buf;
       struct fiemap *fiemap = &fiemap_buf.f;
       struct fiemap_extent *fm_extents = &fiemap->fm_extents[0];
-      enum { count = (sizeof fiemap_buf - sizeof *fiemap)/sizeof *fm_extents };
+      enum {
+        size = sizeof fiemap_buf - offsetof (struct fiemap, fm_extents),
+        count = size / sizeof *fm_extents
+      };
       verify (count > 1);

       /* This is required at least to initialize fiemap->fm_start,
diff --git a/src/fiemap.h b/src/fiemap.h
index 15ddff9..60561d3 100644
--- a/src/fiemap.h
+++ b/src/fiemap.h
@@ -52,12 +52,9 @@ struct fiemap
   uint32_t fm_reserved;

   /* Array of mapped extents(out).
-     This is protected by the ifdef because it uses non standard
-     zero length arrays.  Note C99 has the equivalent flexible arrays,
-     but we don't use those for maximum portability to older systems.  */
-# ifdef __linux__
-  struct fiemap_extent fm_extents[0];
-# endif
+     This uses a size 1 array to be compatible with compilers that
+     don't support C99's flexible arrays or GCC's size-zero arrays.  */
+  struct fiemap_extent fm_extents[1];
 };

 /* The maximum offset can be mapped for a file.  */




Message #22 received at 9077-done <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Paul Eggert <eggert <at> cs.ucla.edu>
Cc: 9077-done <at> debbugs.gnu.org, Joachim Schmitz <jojo <at> schmitz-digital.de>
Subject: Re: bug#9077: coreutils-8.12: fiemap.h uses "struct fiemap_extent
	fm_extents[0]; "
Date: Sat, 16 Jul 2011 09:37:38 +0100
On 15/07/11 23:45, Paul Eggert wrote:
> On 07/15/11 02:49, Pádraig Brady wrote:
>> +#ifdef __linux__
>> +  struct fiemap_extent fm_extents[0];
>> +#endif
> 
> This assumes that all GNU/Linux compiles will
> use a compiler that allows size-zero arrays;
> also, it assumes that sizeof (struct fiemap)
> == offsetof (struct fiemap, fm_extents).
> Although both assumptions are probably
> portable in practice in this particular case,
> it's better to avoid them, if avoiding them is easy.
> This will help future-proof the code if we alter the
> data structures, as altering them might cause problems
> such as what I recently encountered in GNU Emacs's C code.
> 
> How about the following further patch?  It should do the trick.

I tested that and it didn't work.
Even though the *fiemap structs are the same in mem
with and without the change, the ioctl() is returning ENOTTY
when the array is of size 1.  I guess this is because
the array element is unpacked for the ioctl which
is then failing kernel checks.

cheers,
Pádraig.




Message #23 received at 9077-done <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Pádraig Brady <P <at> draigBrady.com>
Cc: 9077-done <at> debbugs.gnu.org, Joachim Schmitz <jojo <at> schmitz-digital.de>
Subject: Re: bug#9077: coreutils-8.12: fiemap.h uses "struct fiemap_extent
	fm_extents[0]; "
Date: Sat, 16 Jul 2011 03:21:58 -0700
On 07/16/11 01:37, Pádraig Brady wrote:
> I guess this is because
> the array element is unpacked for the ioctl which
> is then failing kernel checks.

That's odd, since as far as I can see, ioctl should see exactly
the same bytes either way; the kernel doesn't know about the app's
array elements, and all it should care about are the bytes.

However, I've run out of ideas for debugging remotely.  Perhaps this
will have to wait until someone runs into the portability problem
that I am merely hypothesizing.  Thanks for looking into it, anyway.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 13 Aug 2011 11:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 14 years and 7 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.