All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] xfs_db: check on-disk structure sizes
@ 2016-01-11 23:46 Darrick J. Wong
  2016-01-12 14:01 ` Brian Foster
  0 siblings, 1 reply; 8+ messages in thread
From: Darrick J. Wong @ 2016-01-11 23:46 UTC (permalink / raw)
  To: Dave Chinner; +Cc: xfs

Check on-disk structure sizes against known values.
Use this to catch inadvertent changes in structure size due to padding
and alignment issues, etc.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 db/Makefile         |    2 -
 db/init.c           |    3 +
 db/ondisk.c         |   63 +++++++++++++++++++++++
 db/ondisk.h         |  139 +++++++++++++++++++++++++++++++++++++++++++++++++++
 libxfs/xfs_format.h |    4 +
 5 files changed, 210 insertions(+), 1 deletion(-)
 create mode 100644 db/ondisk.c
 create mode 100644 db/ondisk.h

diff --git a/db/Makefile b/db/Makefile
index 8260da3..ba3e942 100644
--- a/db/Makefile
+++ b/db/Makefile
@@ -12,7 +12,7 @@ HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \
 	dir2.h dir2sf.h dquot.h echo.h faddr.h field.h \
 	flist.h fprint.h frag.h freesp.h hash.h help.h init.h inode.h input.h \
 	io.h logformat.h malloc.h metadump.h output.h print.h quit.h sb.h \
-	 sig.h strvec.h text.h type.h write.h attrset.h symlink.h
+	 sig.h strvec.h text.h type.h write.h attrset.h symlink.h ondisk.h
 CFILES = $(HFILES:.h=.c)
 LSRCFILES = xfs_admin.sh xfs_ncheck.sh xfs_metadump.sh
 
diff --git a/db/init.c b/db/init.c
index c0472c8..d6df093 100644
--- a/db/init.c
+++ b/db/init.c
@@ -28,6 +28,7 @@
 #include "output.h"
 #include "malloc.h"
 #include "type.h"
+#include "ondisk.h"
 
 static char		**cmdline;
 static int		ncmdline;
@@ -60,6 +61,8 @@ init(
 	struct xfs_buf	*bp;
 	int		c;
 
+	xfs_check_ondisk_structs();
+
 	setlocale(LC_ALL, "");
 	bindtextdomain(PACKAGE, LOCALEDIR);
 	textdomain(PACKAGE);
diff --git a/db/ondisk.c b/db/ondisk.c
new file mode 100644
index 0000000..532333d
--- /dev/null
+++ b/db/ondisk.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016 Oracle.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "libxfs.h"
+#include "ondisk.h"
+
+void
+xfs_check_ondisk_structs(void)
+{
+	/* on-disk structures */
+	XFS_CHECK_STRUCT_SIZE(struct xfs_dsb,			264);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_agf,			224);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_agi,			336);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_agfl,			36);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_timestamp,		8);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_dinode,		176);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_disk_dquot,		104);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_dqblk,			136);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_dsymlink_hdr,		56);
+	XFS_CHECK_STRUCT_SIZE(xfs_alloc_rec_t,			8);
+	XFS_CHECK_STRUCT_SIZE(xfs_alloc_key_t,			8);
+	XFS_CHECK_STRUCT_SIZE(xfs_alloc_ptr_t,			4);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_rec,		16);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_key,		4);
+	XFS_CHECK_STRUCT_SIZE(xfs_inobt_ptr_t,			4);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_bmdr_block,		4);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_bmbt_rec,		16);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_bmbt_key,		8);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_btree_block,		72);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_acl_entry,		12);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_acl,			4);
+
+	/* log structures */
+	XFS_CHECK_STRUCT_SIZE(struct xfs_trans_header,		16);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_32,	52);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_64,	56);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_ictimestamp,		8);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_icdinode,		176);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_extent_32,		12);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_extent_64,		16);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_32,	28);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_64,	32);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_32,	28);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_64,	32);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_dq_logformat,		24);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_qoff_logformat,	20);
+	XFS_CHECK_STRUCT_SIZE(struct xfs_icreate_log,		28);
+}
diff --git a/db/ondisk.h b/db/ondisk.h
new file mode 100644
index 0000000..b5784d1
--- /dev/null
+++ b/db/ondisk.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2016 Oracle.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __XFS_DB_ONDISK_H
+#define __XFS_DB_ONDISK_H
+
+/* Compile time object size, -1 for unknown */
+#ifndef __compiletime_error
+# define __compiletime_error(message)
+/*
+ * Sparse complains of variable sized arrays due to the temporary variable in
+ * __compiletime_assert. Unfortunately we can't just expand it out to make
+ * sparse see a constant array size without breaking compiletime_assert on old
+ * versions of GCC (e.g. 4.2.4), so hide the array from sparse altogether.
+ */
+# ifndef __CHECKER__
+#  define __compiletime_error_fallback(condition) \
+	do { ((void)sizeof(char[1 - 2 * condition])); } while (0)
+# endif
+#endif
+#ifndef __compiletime_error_fallback
+# define __compiletime_error_fallback(condition) do { } while (0)
+#endif
+
+#define __compiletime_assert(condition, msg, prefix, suffix)		\
+	do {								\
+		bool __cond = !(condition);				\
+		extern void prefix ## suffix(void) __compiletime_error(msg); \
+		if (__cond)						\
+			prefix ## suffix();				\
+		__compiletime_error_fallback(__cond);			\
+	} while (0)
+
+#define _compiletime_assert(condition, msg, prefix, suffix) \
+	__compiletime_assert(condition, msg, prefix, suffix)
+
+/**
+ * compiletime_assert - break build and emit msg if condition is false
+ * @condition: a compile-time constant condition to check
+ * @msg:       a message to emit if condition is false
+ *
+ * In tradition of POSIX assert, this macro will break the build if the
+ * supplied condition is *false*, emitting the supplied error message if the
+ * compiler has support to do so.
+ */
+#define compiletime_assert(condition, msg) \
+	_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
+
+#ifdef __CHECKER__
+#define BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
+#define BUILD_BUG_ON_ZERO(e) (0)
+#define BUILD_BUG_ON_NULL(e) ((void*)0)
+#define BUILD_BUG_ON_INVALID(e) (0)
+#define BUILD_BUG_ON_MSG(cond, msg) (0)
+#define BUILD_BUG_ON(condition) (0)
+#define BUILD_BUG() (0)
+#else /* __CHECKER__ */
+
+/* Force a compilation error if a constant expression is not a power of 2 */
+#define BUILD_BUG_ON_NOT_POWER_OF_2(n)			\
+	BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
+
+/* Force a compilation error if condition is true, but also produce a
+   result (of value 0 and type size_t), so the expression can be used
+   e.g. in a structure initializer (or where-ever else comma expressions
+   aren't permitted). */
+#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
+#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
+
+/*
+ * BUILD_BUG_ON_INVALID() permits the compiler to check the validity of the
+ * expression but avoids the generation of any code, even if that expression
+ * has side-effects.
+ */
+#define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
+
+/**
+ * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied
+ *		      error message.
+ * @condition: the condition which the compiler should know is false.
+ *
+ * See BUILD_BUG_ON for description.
+ */
+#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
+
+/**
+ * BUILD_BUG_ON - break compile if a condition is true.
+ * @condition: the condition which the compiler should know is false.
+ *
+ * If you have some code which relies on certain constants being equal, or
+ * some other compile-time-evaluated condition, you should use BUILD_BUG_ON to
+ * detect if someone changes it.
+ *
+ * The implementation uses gcc's reluctance to create a negative array, but gcc
+ * (as of 4.4) only emits that error for obvious cases (e.g. not arguments to
+ * inline functions).  Luckily, in 4.3 they added the "error" function
+ * attribute just for this type of case.  Thus, we use a negative sized array
+ * (should always create an error on gcc versions older than 4.4) and then call
+ * an undefined function with the error attribute (should always create an
+ * error on gcc 4.3 and later).  If for some reason, neither creates a
+ * compile-time error, we'll still have a link-time error, which is harder to
+ * track down.
+ */
+#ifndef __OPTIMIZE__
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+#else
+#define BUILD_BUG_ON(condition) \
+	BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
+#endif
+
+/**
+ * BUILD_BUG - break compile if used.
+ *
+ * If you have some code that you expect the compiler to eliminate at
+ * build time, you should use BUILD_BUG to detect if it is
+ * unexpectedly used.
+ */
+#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
+
+#endif	/* __CHECKER__ */
+
+void xfs_check_ondisk_structs(void);
+
+#endif /* __XFS_DB_ONDISK_H */
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index a35009a..c4c0c1c 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -1505,4 +1505,8 @@ struct xfs_acl {
 #define SGI_ACL_FILE_SIZE	(sizeof(SGI_ACL_FILE)-1)
 #define SGI_ACL_DEFAULT_SIZE	(sizeof(SGI_ACL_DEFAULT)-1)
 
+#define XFS_CHECK_STRUCT_SIZE(structname, size) \
+	BUILD_BUG_ON_MSG(sizeof(structname) != (size), "XFS: sizeof(struct " \
+		#structname ") is wrong, expected " #size)
+
 #endif /* __XFS_FORMAT_H__ */

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_db: check on-disk structure sizes
  2016-01-11 23:46 [PATCH] xfs_db: check on-disk structure sizes Darrick J. Wong
@ 2016-01-12 14:01 ` Brian Foster
  2016-01-13  1:29   ` Darrick J. Wong
  0 siblings, 1 reply; 8+ messages in thread
From: Brian Foster @ 2016-01-12 14:01 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: xfs

On Mon, Jan 11, 2016 at 03:46:44PM -0800, Darrick J. Wong wrote:
> Check on-disk structure sizes against known values.
> Use this to catch inadvertent changes in structure size due to padding
> and alignment issues, etc.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---

What's the need for this in userspace? Not a big deal really, but it
seems like it serves the fundamental purpose sufficiently in the kernel.

That aside, this does fail if I tweak a structure size, though I don't
think I get the intended error. I end up with a linker error instead:

...
    [LD]     xfs_db
ondisk.o: In function `xfs_check_ondisk_structs':
/home/bfoster/repos/xfsprogs-dev/db/ondisk.c:26: undefined reference to `__compiletime_assert_26'
collect2: error: ld returned 1 exit status
../include/buildrules:45: recipe for target 'xfs_db' failed
gmake[3]: *** [xfs_db] Error 1
include/buildrules:35: recipe for target 'db' failed
gmake[2]: *** [db] Error 2
Makefile:70: recipe for target 'default' failed
make[1]: *** [default] Error 2
Makefile:68: recipe for target 'default' failed
make: *** [default] Error 2

This is with gcc 5.3.1. It works fine with the kernel patch so I don't
_think_ it's my environment, but I could be wrong...

Brian

>  db/Makefile         |    2 -
>  db/init.c           |    3 +
>  db/ondisk.c         |   63 +++++++++++++++++++++++
>  db/ondisk.h         |  139 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  libxfs/xfs_format.h |    4 +
>  5 files changed, 210 insertions(+), 1 deletion(-)
>  create mode 100644 db/ondisk.c
>  create mode 100644 db/ondisk.h
> 
> diff --git a/db/Makefile b/db/Makefile
> index 8260da3..ba3e942 100644
> --- a/db/Makefile
> +++ b/db/Makefile
> @@ -12,7 +12,7 @@ HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \
>  	dir2.h dir2sf.h dquot.h echo.h faddr.h field.h \
>  	flist.h fprint.h frag.h freesp.h hash.h help.h init.h inode.h input.h \
>  	io.h logformat.h malloc.h metadump.h output.h print.h quit.h sb.h \
> -	 sig.h strvec.h text.h type.h write.h attrset.h symlink.h
> +	 sig.h strvec.h text.h type.h write.h attrset.h symlink.h ondisk.h
>  CFILES = $(HFILES:.h=.c)
>  LSRCFILES = xfs_admin.sh xfs_ncheck.sh xfs_metadump.sh
>  
> diff --git a/db/init.c b/db/init.c
> index c0472c8..d6df093 100644
> --- a/db/init.c
> +++ b/db/init.c
> @@ -28,6 +28,7 @@
>  #include "output.h"
>  #include "malloc.h"
>  #include "type.h"
> +#include "ondisk.h"
>  
>  static char		**cmdline;
>  static int		ncmdline;
> @@ -60,6 +61,8 @@ init(
>  	struct xfs_buf	*bp;
>  	int		c;
>  
> +	xfs_check_ondisk_structs();
> +
>  	setlocale(LC_ALL, "");
>  	bindtextdomain(PACKAGE, LOCALEDIR);
>  	textdomain(PACKAGE);
> diff --git a/db/ondisk.c b/db/ondisk.c
> new file mode 100644
> index 0000000..532333d
> --- /dev/null
> +++ b/db/ondisk.c
> @@ -0,0 +1,63 @@
> +/*
> + * Copyright (c) 2016 Oracle.
> + * All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it would be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write the Free Software Foundation,
> + * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> + */
> +
> +#include "libxfs.h"
> +#include "ondisk.h"
> +
> +void
> +xfs_check_ondisk_structs(void)
> +{
> +	/* on-disk structures */
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_dsb,			264);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_agf,			224);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_agi,			336);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_agfl,			36);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_timestamp,		8);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_dinode,		176);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_disk_dquot,		104);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_dqblk,			136);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_dsymlink_hdr,		56);
> +	XFS_CHECK_STRUCT_SIZE(xfs_alloc_rec_t,			8);
> +	XFS_CHECK_STRUCT_SIZE(xfs_alloc_key_t,			8);
> +	XFS_CHECK_STRUCT_SIZE(xfs_alloc_ptr_t,			4);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_rec,		16);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_key,		4);
> +	XFS_CHECK_STRUCT_SIZE(xfs_inobt_ptr_t,			4);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_bmdr_block,		4);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_bmbt_rec,		16);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_bmbt_key,		8);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_btree_block,		72);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_acl_entry,		12);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_acl,			4);
> +
> +	/* log structures */
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_trans_header,		16);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_32,	52);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_64,	56);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_ictimestamp,		8);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_icdinode,		176);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_extent_32,		12);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_extent_64,		16);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_32,	28);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_64,	32);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_32,	28);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_64,	32);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_dq_logformat,		24);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_qoff_logformat,	20);
> +	XFS_CHECK_STRUCT_SIZE(struct xfs_icreate_log,		28);
> +}
> diff --git a/db/ondisk.h b/db/ondisk.h
> new file mode 100644
> index 0000000..b5784d1
> --- /dev/null
> +++ b/db/ondisk.h
> @@ -0,0 +1,139 @@
> +/*
> + * Copyright (c) 2016 Oracle.
> + * All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it would be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write the Free Software Foundation,
> + * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> + */
> +
> +#ifndef __XFS_DB_ONDISK_H
> +#define __XFS_DB_ONDISK_H
> +
> +/* Compile time object size, -1 for unknown */
> +#ifndef __compiletime_error
> +# define __compiletime_error(message)
> +/*
> + * Sparse complains of variable sized arrays due to the temporary variable in
> + * __compiletime_assert. Unfortunately we can't just expand it out to make
> + * sparse see a constant array size without breaking compiletime_assert on old
> + * versions of GCC (e.g. 4.2.4), so hide the array from sparse altogether.
> + */
> +# ifndef __CHECKER__
> +#  define __compiletime_error_fallback(condition) \
> +	do { ((void)sizeof(char[1 - 2 * condition])); } while (0)
> +# endif
> +#endif
> +#ifndef __compiletime_error_fallback
> +# define __compiletime_error_fallback(condition) do { } while (0)
> +#endif
> +
> +#define __compiletime_assert(condition, msg, prefix, suffix)		\
> +	do {								\
> +		bool __cond = !(condition);				\
> +		extern void prefix ## suffix(void) __compiletime_error(msg); \
> +		if (__cond)						\
> +			prefix ## suffix();				\
> +		__compiletime_error_fallback(__cond);			\
> +	} while (0)
> +
> +#define _compiletime_assert(condition, msg, prefix, suffix) \
> +	__compiletime_assert(condition, msg, prefix, suffix)
> +
> +/**
> + * compiletime_assert - break build and emit msg if condition is false
> + * @condition: a compile-time constant condition to check
> + * @msg:       a message to emit if condition is false
> + *
> + * In tradition of POSIX assert, this macro will break the build if the
> + * supplied condition is *false*, emitting the supplied error message if the
> + * compiler has support to do so.
> + */
> +#define compiletime_assert(condition, msg) \
> +	_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> +
> +#ifdef __CHECKER__
> +#define BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
> +#define BUILD_BUG_ON_ZERO(e) (0)
> +#define BUILD_BUG_ON_NULL(e) ((void*)0)
> +#define BUILD_BUG_ON_INVALID(e) (0)
> +#define BUILD_BUG_ON_MSG(cond, msg) (0)
> +#define BUILD_BUG_ON(condition) (0)
> +#define BUILD_BUG() (0)
> +#else /* __CHECKER__ */
> +
> +/* Force a compilation error if a constant expression is not a power of 2 */
> +#define BUILD_BUG_ON_NOT_POWER_OF_2(n)			\
> +	BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
> +
> +/* Force a compilation error if condition is true, but also produce a
> +   result (of value 0 and type size_t), so the expression can be used
> +   e.g. in a structure initializer (or where-ever else comma expressions
> +   aren't permitted). */
> +#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
> +#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
> +
> +/*
> + * BUILD_BUG_ON_INVALID() permits the compiler to check the validity of the
> + * expression but avoids the generation of any code, even if that expression
> + * has side-effects.
> + */
> +#define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
> +
> +/**
> + * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied
> + *		      error message.
> + * @condition: the condition which the compiler should know is false.
> + *
> + * See BUILD_BUG_ON for description.
> + */
> +#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> +
> +/**
> + * BUILD_BUG_ON - break compile if a condition is true.
> + * @condition: the condition which the compiler should know is false.
> + *
> + * If you have some code which relies on certain constants being equal, or
> + * some other compile-time-evaluated condition, you should use BUILD_BUG_ON to
> + * detect if someone changes it.
> + *
> + * The implementation uses gcc's reluctance to create a negative array, but gcc
> + * (as of 4.4) only emits that error for obvious cases (e.g. not arguments to
> + * inline functions).  Luckily, in 4.3 they added the "error" function
> + * attribute just for this type of case.  Thus, we use a negative sized array
> + * (should always create an error on gcc versions older than 4.4) and then call
> + * an undefined function with the error attribute (should always create an
> + * error on gcc 4.3 and later).  If for some reason, neither creates a
> + * compile-time error, we'll still have a link-time error, which is harder to
> + * track down.
> + */
> +#ifndef __OPTIMIZE__
> +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
> +#else
> +#define BUILD_BUG_ON(condition) \
> +	BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
> +#endif
> +
> +/**
> + * BUILD_BUG - break compile if used.
> + *
> + * If you have some code that you expect the compiler to eliminate at
> + * build time, you should use BUILD_BUG to detect if it is
> + * unexpectedly used.
> + */
> +#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> +
> +#endif	/* __CHECKER__ */
> +
> +void xfs_check_ondisk_structs(void);
> +
> +#endif /* __XFS_DB_ONDISK_H */
> diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
> index a35009a..c4c0c1c 100644
> --- a/libxfs/xfs_format.h
> +++ b/libxfs/xfs_format.h
> @@ -1505,4 +1505,8 @@ struct xfs_acl {
>  #define SGI_ACL_FILE_SIZE	(sizeof(SGI_ACL_FILE)-1)
>  #define SGI_ACL_DEFAULT_SIZE	(sizeof(SGI_ACL_DEFAULT)-1)
>  
> +#define XFS_CHECK_STRUCT_SIZE(structname, size) \
> +	BUILD_BUG_ON_MSG(sizeof(structname) != (size), "XFS: sizeof(struct " \
> +		#structname ") is wrong, expected " #size)
> +
>  #endif /* __XFS_FORMAT_H__ */
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_db: check on-disk structure sizes
  2016-01-12 14:01 ` Brian Foster
@ 2016-01-13  1:29   ` Darrick J. Wong
  2016-01-13  3:10     ` Eric Sandeen
  0 siblings, 1 reply; 8+ messages in thread
From: Darrick J. Wong @ 2016-01-13  1:29 UTC (permalink / raw)
  To: Brian Foster; +Cc: xfs

On Tue, Jan 12, 2016 at 09:01:22AM -0500, Brian Foster wrote:
> On Mon, Jan 11, 2016 at 03:46:44PM -0800, Darrick J. Wong wrote:
> > Check on-disk structure sizes against known values.
> > Use this to catch inadvertent changes in structure size due to padding
> > and alignment issues, etc.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> 
> What's the need for this in userspace? Not a big deal really, but it
> seems like it serves the fundamental purpose sufficiently in the kernel.

The primary point is to make sure that we didn't make any errors with the
on-disk structures when porting libxfs changes.  The kernel build is the first
line of defense since it tends to big get changes first, but I figure a
defensive build check for xfsprogs won't harm anyone...

> That aside, this does fail if I tweak a structure size, though I don't
> think I get the intended error. I end up with a linker error instead:

...except for that.  Should I dig deeper into figuring out why this doesn't
work in userland, or is a filename and line number sufficient to figure out
which structure is misbehaving?

--D

> 
> ...
>     [LD]     xfs_db
> ondisk.o: In function `xfs_check_ondisk_structs':
> /home/bfoster/repos/xfsprogs-dev/db/ondisk.c:26: undefined reference to `__compiletime_assert_26'
> collect2: error: ld returned 1 exit status
> ../include/buildrules:45: recipe for target 'xfs_db' failed
> gmake[3]: *** [xfs_db] Error 1
> include/buildrules:35: recipe for target 'db' failed
> gmake[2]: *** [db] Error 2
> Makefile:70: recipe for target 'default' failed
> make[1]: *** [default] Error 2
> Makefile:68: recipe for target 'default' failed
> make: *** [default] Error 2
> 
> This is with gcc 5.3.1. It works fine with the kernel patch so I don't
> _think_ it's my environment, but I could be wrong...
> 
> Brian
> 
> >  db/Makefile         |    2 -
> >  db/init.c           |    3 +
> >  db/ondisk.c         |   63 +++++++++++++++++++++++
> >  db/ondisk.h         |  139 +++++++++++++++++++++++++++++++++++++++++++++++++++
> >  libxfs/xfs_format.h |    4 +
> >  5 files changed, 210 insertions(+), 1 deletion(-)
> >  create mode 100644 db/ondisk.c
> >  create mode 100644 db/ondisk.h
> > 
> > diff --git a/db/Makefile b/db/Makefile
> > index 8260da3..ba3e942 100644
> > --- a/db/Makefile
> > +++ b/db/Makefile
> > @@ -12,7 +12,7 @@ HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \
> >  	dir2.h dir2sf.h dquot.h echo.h faddr.h field.h \
> >  	flist.h fprint.h frag.h freesp.h hash.h help.h init.h inode.h input.h \
> >  	io.h logformat.h malloc.h metadump.h output.h print.h quit.h sb.h \
> > -	 sig.h strvec.h text.h type.h write.h attrset.h symlink.h
> > +	 sig.h strvec.h text.h type.h write.h attrset.h symlink.h ondisk.h
> >  CFILES = $(HFILES:.h=.c)
> >  LSRCFILES = xfs_admin.sh xfs_ncheck.sh xfs_metadump.sh
> >  
> > diff --git a/db/init.c b/db/init.c
> > index c0472c8..d6df093 100644
> > --- a/db/init.c
> > +++ b/db/init.c
> > @@ -28,6 +28,7 @@
> >  #include "output.h"
> >  #include "malloc.h"
> >  #include "type.h"
> > +#include "ondisk.h"
> >  
> >  static char		**cmdline;
> >  static int		ncmdline;
> > @@ -60,6 +61,8 @@ init(
> >  	struct xfs_buf	*bp;
> >  	int		c;
> >  
> > +	xfs_check_ondisk_structs();
> > +
> >  	setlocale(LC_ALL, "");
> >  	bindtextdomain(PACKAGE, LOCALEDIR);
> >  	textdomain(PACKAGE);
> > diff --git a/db/ondisk.c b/db/ondisk.c
> > new file mode 100644
> > index 0000000..532333d
> > --- /dev/null
> > +++ b/db/ondisk.c
> > @@ -0,0 +1,63 @@
> > +/*
> > + * Copyright (c) 2016 Oracle.
> > + * All Rights Reserved.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it would be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write the Free Software Foundation,
> > + * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> > + */
> > +
> > +#include "libxfs.h"
> > +#include "ondisk.h"
> > +
> > +void
> > +xfs_check_ondisk_structs(void)
> > +{
> > +	/* on-disk structures */
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_dsb,			264);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_agf,			224);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_agi,			336);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_agfl,			36);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_timestamp,		8);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_dinode,		176);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_disk_dquot,		104);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_dqblk,			136);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_dsymlink_hdr,		56);
> > +	XFS_CHECK_STRUCT_SIZE(xfs_alloc_rec_t,			8);
> > +	XFS_CHECK_STRUCT_SIZE(xfs_alloc_key_t,			8);
> > +	XFS_CHECK_STRUCT_SIZE(xfs_alloc_ptr_t,			4);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_rec,		16);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_key,		4);
> > +	XFS_CHECK_STRUCT_SIZE(xfs_inobt_ptr_t,			4);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_bmdr_block,		4);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_bmbt_rec,		16);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_bmbt_key,		8);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_btree_block,		72);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_acl_entry,		12);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_acl,			4);
> > +
> > +	/* log structures */
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_trans_header,		16);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_32,	52);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format_64,	56);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_ictimestamp,		8);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_icdinode,		176);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_extent_32,		12);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_extent_64,		16);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_32,	28);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_efi_log_format_64,	32);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_32,	28);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_efd_log_format_64,	32);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_dq_logformat,		24);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_qoff_logformat,	20);
> > +	XFS_CHECK_STRUCT_SIZE(struct xfs_icreate_log,		28);
> > +}
> > diff --git a/db/ondisk.h b/db/ondisk.h
> > new file mode 100644
> > index 0000000..b5784d1
> > --- /dev/null
> > +++ b/db/ondisk.h
> > @@ -0,0 +1,139 @@
> > +/*
> > + * Copyright (c) 2016 Oracle.
> > + * All Rights Reserved.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it would be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write the Free Software Foundation,
> > + * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> > + */
> > +
> > +#ifndef __XFS_DB_ONDISK_H
> > +#define __XFS_DB_ONDISK_H
> > +
> > +/* Compile time object size, -1 for unknown */
> > +#ifndef __compiletime_error
> > +# define __compiletime_error(message)
> > +/*
> > + * Sparse complains of variable sized arrays due to the temporary variable in
> > + * __compiletime_assert. Unfortunately we can't just expand it out to make
> > + * sparse see a constant array size without breaking compiletime_assert on old
> > + * versions of GCC (e.g. 4.2.4), so hide the array from sparse altogether.
> > + */
> > +# ifndef __CHECKER__
> > +#  define __compiletime_error_fallback(condition) \
> > +	do { ((void)sizeof(char[1 - 2 * condition])); } while (0)
> > +# endif
> > +#endif
> > +#ifndef __compiletime_error_fallback
> > +# define __compiletime_error_fallback(condition) do { } while (0)
> > +#endif
> > +
> > +#define __compiletime_assert(condition, msg, prefix, suffix)		\
> > +	do {								\
> > +		bool __cond = !(condition);				\
> > +		extern void prefix ## suffix(void) __compiletime_error(msg); \
> > +		if (__cond)						\
> > +			prefix ## suffix();				\
> > +		__compiletime_error_fallback(__cond);			\
> > +	} while (0)
> > +
> > +#define _compiletime_assert(condition, msg, prefix, suffix) \
> > +	__compiletime_assert(condition, msg, prefix, suffix)
> > +
> > +/**
> > + * compiletime_assert - break build and emit msg if condition is false
> > + * @condition: a compile-time constant condition to check
> > + * @msg:       a message to emit if condition is false
> > + *
> > + * In tradition of POSIX assert, this macro will break the build if the
> > + * supplied condition is *false*, emitting the supplied error message if the
> > + * compiler has support to do so.
> > + */
> > +#define compiletime_assert(condition, msg) \
> > +	_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> > +
> > +#ifdef __CHECKER__
> > +#define BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
> > +#define BUILD_BUG_ON_ZERO(e) (0)
> > +#define BUILD_BUG_ON_NULL(e) ((void*)0)
> > +#define BUILD_BUG_ON_INVALID(e) (0)
> > +#define BUILD_BUG_ON_MSG(cond, msg) (0)
> > +#define BUILD_BUG_ON(condition) (0)
> > +#define BUILD_BUG() (0)
> > +#else /* __CHECKER__ */
> > +
> > +/* Force a compilation error if a constant expression is not a power of 2 */
> > +#define BUILD_BUG_ON_NOT_POWER_OF_2(n)			\
> > +	BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
> > +
> > +/* Force a compilation error if condition is true, but also produce a
> > +   result (of value 0 and type size_t), so the expression can be used
> > +   e.g. in a structure initializer (or where-ever else comma expressions
> > +   aren't permitted). */
> > +#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
> > +#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
> > +
> > +/*
> > + * BUILD_BUG_ON_INVALID() permits the compiler to check the validity of the
> > + * expression but avoids the generation of any code, even if that expression
> > + * has side-effects.
> > + */
> > +#define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
> > +
> > +/**
> > + * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied
> > + *		      error message.
> > + * @condition: the condition which the compiler should know is false.
> > + *
> > + * See BUILD_BUG_ON for description.
> > + */
> > +#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> > +
> > +/**
> > + * BUILD_BUG_ON - break compile if a condition is true.
> > + * @condition: the condition which the compiler should know is false.
> > + *
> > + * If you have some code which relies on certain constants being equal, or
> > + * some other compile-time-evaluated condition, you should use BUILD_BUG_ON to
> > + * detect if someone changes it.
> > + *
> > + * The implementation uses gcc's reluctance to create a negative array, but gcc
> > + * (as of 4.4) only emits that error for obvious cases (e.g. not arguments to
> > + * inline functions).  Luckily, in 4.3 they added the "error" function
> > + * attribute just for this type of case.  Thus, we use a negative sized array
> > + * (should always create an error on gcc versions older than 4.4) and then call
> > + * an undefined function with the error attribute (should always create an
> > + * error on gcc 4.3 and later).  If for some reason, neither creates a
> > + * compile-time error, we'll still have a link-time error, which is harder to
> > + * track down.
> > + */
> > +#ifndef __OPTIMIZE__
> > +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
> > +#else
> > +#define BUILD_BUG_ON(condition) \
> > +	BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
> > +#endif
> > +
> > +/**
> > + * BUILD_BUG - break compile if used.
> > + *
> > + * If you have some code that you expect the compiler to eliminate at
> > + * build time, you should use BUILD_BUG to detect if it is
> > + * unexpectedly used.
> > + */
> > +#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> > +
> > +#endif	/* __CHECKER__ */
> > +
> > +void xfs_check_ondisk_structs(void);
> > +
> > +#endif /* __XFS_DB_ONDISK_H */
> > diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
> > index a35009a..c4c0c1c 100644
> > --- a/libxfs/xfs_format.h
> > +++ b/libxfs/xfs_format.h
> > @@ -1505,4 +1505,8 @@ struct xfs_acl {
> >  #define SGI_ACL_FILE_SIZE	(sizeof(SGI_ACL_FILE)-1)
> >  #define SGI_ACL_DEFAULT_SIZE	(sizeof(SGI_ACL_DEFAULT)-1)
> >  
> > +#define XFS_CHECK_STRUCT_SIZE(structname, size) \
> > +	BUILD_BUG_ON_MSG(sizeof(structname) != (size), "XFS: sizeof(struct " \
> > +		#structname ") is wrong, expected " #size)
> > +
> >  #endif /* __XFS_FORMAT_H__ */
> > 
> > _______________________________________________
> > xfs mailing list
> > xfs@oss.sgi.com
> > http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_db: check on-disk structure sizes
  2016-01-13  1:29   ` Darrick J. Wong
@ 2016-01-13  3:10     ` Eric Sandeen
  2016-01-13  5:47       ` Dave Chinner
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Sandeen @ 2016-01-13  3:10 UTC (permalink / raw)
  To: xfs



On 1/12/16 7:29 PM, Darrick J. Wong wrote:
> On Tue, Jan 12, 2016 at 09:01:22AM -0500, Brian Foster wrote:
>> On Mon, Jan 11, 2016 at 03:46:44PM -0800, Darrick J. Wong wrote:
>>> Check on-disk structure sizes against known values.
>>> Use this to catch inadvertent changes in structure size due to padding
>>> and alignment issues, etc.
>>>
>>> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
>>> ---
>>
>> What's the need for this in userspace? Not a big deal really, but it
>> seems like it serves the fundamental purpose sufficiently in the kernel.
> 
> The primary point is to make sure that we didn't make any errors with the
> on-disk structures when porting libxfs changes.  The kernel build is the first
> line of defense since it tends to big get changes first, but I figure a
> defensive build check for xfsprogs won't harm anyone...

Does it need to actually be in the code?

$ pahole -s fs/xfs/xfs.ko | grep -w "xfs_dsb\|xfs_agf\|xfs_agi\|xfs_agfl"
xfs_agf	224	0
xfs_agfl	40	0
xfs_agi	336	0
xfs_dsb	264	0

pahole needs a binary w/ debuginfo, but maybe this could just be hooked up
in the Makefiles?

-Eric

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_db: check on-disk structure sizes
  2016-01-13  3:10     ` Eric Sandeen
@ 2016-01-13  5:47       ` Dave Chinner
  2016-01-13  6:02         ` Eric Sandeen
  0 siblings, 1 reply; 8+ messages in thread
From: Dave Chinner @ 2016-01-13  5:47 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: xfs

On Tue, Jan 12, 2016 at 09:10:23PM -0600, Eric Sandeen wrote:
> 
> 
> On 1/12/16 7:29 PM, Darrick J. Wong wrote:
> > On Tue, Jan 12, 2016 at 09:01:22AM -0500, Brian Foster wrote:
> >> On Mon, Jan 11, 2016 at 03:46:44PM -0800, Darrick J. Wong wrote:
> >>> Check on-disk structure sizes against known values.
> >>> Use this to catch inadvertent changes in structure size due to padding
> >>> and alignment issues, etc.
> >>>
> >>> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> >>> ---
> >>
> >> What's the need for this in userspace? Not a big deal really, but it
> >> seems like it serves the fundamental purpose sufficiently in the kernel.
> > 
> > The primary point is to make sure that we didn't make any errors with the
> > on-disk structures when porting libxfs changes.  The kernel build is the first
> > line of defense since it tends to big get changes first, but I figure a
> > defensive build check for xfsprogs won't harm anyone...
> 
> Does it need to actually be in the code?
> 
> $ pahole -s fs/xfs/xfs.ko | grep -w "xfs_dsb\|xfs_agf\|xfs_agi\|xfs_agfl"
> xfs_agf	224	0
> xfs_agfl	40	0
> xfs_agi	336	0
> xfs_dsb	264	0
> 
> pahole needs a binary w/ debuginfo, but maybe this could just be hooked up
> in the Makefiles?

As I've pointed out previously to Darrick: xfstests:/tests/xfs/122

Make that build again, update it.

-Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_db: check on-disk structure sizes
  2016-01-13  5:47       ` Dave Chinner
@ 2016-01-13  6:02         ` Eric Sandeen
  2016-01-13  7:46           ` Christoph Hellwig
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Sandeen @ 2016-01-13  6:02 UTC (permalink / raw)
  To: Dave Chinner; +Cc: xfs

LOn Jan 12, 2016, at 11:47 PM, Dave Chinner <david@fromorbit.com> wrote:
> 
>> On Tue, Jan 12, 2016 at 09:10:23PM -0600, Eric Sandeen wrote:
>> 
>> 
>>> On 1/12/16 7:29 PM, Darrick J. Wong wrote:
>>>> On Tue, Jan 12, 2016 at 09:01:22AM -0500, Brian Foster wrote:
>>>>> On Mon, Jan 11, 2016 at 03:46:44PM -0800, Darrick J. Wong wrote:
>>>>> Check on-disk structure sizes against known values.
>>>>> Use this to catch inadvertent changes in structure size due to padding
>>>>> and alignment issues, etc.
>>>>> 
>>>>> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
>>>>> ---
>>>> 
>>>> What's the need for this in userspace? Not a big deal really, but it
>>>> seems like it serves the fundamental purpose sufficiently in the kernel.
>>> 
>>> The primary point is to make sure that we didn't make any errors with the
>>> on-disk structures when porting libxfs changes.  The kernel build is the first
>>> line of defense since it tends to big get changes first, but I figure a
>>> defensive build check for xfsprogs won't harm anyone...
>> 
>> Does it need to actually be in the code?
>> 
>> $ pahole -s fs/xfs/xfs.ko | grep -w "xfs_dsb\|xfs_agf\|xfs_agi\|xfs_agfl"
>> xfs_agf    224    0
>> xfs_agfl    40    0
>> xfs_agi    336    0
>> xfs_dsb    264    0
>> 
>> pahole needs a binary w/ debuginfo, but maybe this could just be hooked up
>> in the Makefiles?
> 
> As I've pointed out previously to Darrick: xfstests:/tests/xfs/122
> 
> Make that build again, update it.
> 
Oh, I went looking for that and missed it somehow, thought it had been removed.   Ok then!

-Eric

> -Dave.
> -- 
> Dave Chinner
> david@fromorbit.com
> 

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_db: check on-disk structure sizes
  2016-01-13  6:02         ` Eric Sandeen
@ 2016-01-13  7:46           ` Christoph Hellwig
  2016-01-15 20:56             ` Darrick J. Wong
  0 siblings, 1 reply; 8+ messages in thread
From: Christoph Hellwig @ 2016-01-13  7:46 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: xfs

On Wed, Jan 13, 2016 at 12:02:36AM -0600, Eric Sandeen wrote:
> > As I've pointed out previously to Darrick: xfstests:/tests/xfs/122
> > 
> > Make that build again, update it.
> > 
> Oh, I went looking for that and missed it somehow, thought it had been removed.   Ok then!

The real issue is that build environment change alignments.  32 vs 64
bit builds are obvious, but on some architectures different ABIs have
different alignments (we had some fun with ARM in that regard),
nevermind the equivalents to IRIX n32 popping up everywhere these days
that make things complicated.

I'd really love to have Darrick's check in xfs_format.h as an opt-in
if a build time assert is provided - that way every user can check it
doesn't screw up the structures.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

* Re: [PATCH] xfs_db: check on-disk structure sizes
  2016-01-13  7:46           ` Christoph Hellwig
@ 2016-01-15 20:56             ` Darrick J. Wong
  0 siblings, 0 replies; 8+ messages in thread
From: Darrick J. Wong @ 2016-01-15 20:56 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Eric Sandeen, xfs

On Tue, Jan 12, 2016 at 11:46:40PM -0800, Christoph Hellwig wrote:
> On Wed, Jan 13, 2016 at 12:02:36AM -0600, Eric Sandeen wrote:
> > > As I've pointed out previously to Darrick: xfstests:/tests/xfs/122
> > > 
> > > Make that build again, update it.
> > > 
> > Oh, I went looking for that and missed it somehow, thought it had been removed.   Ok then!
> 
> The real issue is that build environment change alignments.  32 vs 64
> bit builds are obvious, but on some architectures different ABIs have
> different alignments (we had some fun with ARM in that regard),
> nevermind the equivalents to IRIX n32 popping up everywhere these days
> that make things complicated.
> 
> I'd really love to have Darrick's check in xfs_format.h as an opt-in
> if a build time assert is provided - that way every user can check it
> doesn't screw up the structures.

I've fixed xfs/122, so I suppose we no longer need this to end up in
xfsprogs.  The kernel-side patch can stick around in fs/xfs/ without
touching libxfs.

(New patches out soonish.)

--D

> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

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

end of thread, other threads:[~2016-01-15 20:57 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-11 23:46 [PATCH] xfs_db: check on-disk structure sizes Darrick J. Wong
2016-01-12 14:01 ` Brian Foster
2016-01-13  1:29   ` Darrick J. Wong
2016-01-13  3:10     ` Eric Sandeen
2016-01-13  5:47       ` Dave Chinner
2016-01-13  6:02         ` Eric Sandeen
2016-01-13  7:46           ` Christoph Hellwig
2016-01-15 20:56             ` Darrick J. Wong

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.