cpumask: remove struct cpumask definition for CONFIG_CPUMASK_OFFSTACK.

If we remove the definition of 'struct cpumask', the compiler will
prevent assignment, return or declaration of 'struct cpumask' vars.

Note that if cpumask_var_t is on the stack (ie. !CONFIG_CPUMASK_OFFSTACK), we
need the definition still.

I also use two variants of cpumask_bits(): the function version checks
the type but the macro is const-preserving, so both can find different
bugs.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 include/linux/cpumask.h |  101 ++++++++++++++++++++++++++----------------------
 1 file changed, 55 insertions(+), 46 deletions(-)

diff -r abadfe756030 include/linux/cpumask.h
--- a/include/linux/cpumask.h	Mon Oct 06 08:42:26 2008 +1100
+++ b/include/linux/cpumask.h	Mon Oct 06 08:42:43 2008 +1100
@@ -6,8 +6,8 @@
  * set of CPU's in a system, one bit position per CPU number up to
  * nr_cpu_ids (<= NR_CPUS).
  *
- * Old-style uses "cpumask_t", but new ops are "struct cpumask *";
- * don't put "struct cpumask"s on the stack.
+ * We hide the definition of 'struct cpumask', so they are not lightly
+ * declared or placed on the stack.  See cpumask_var_t.
  *
  * See detailed comments in the file linux/bitmap.h describing the
  * data type on which these cpumasks are based.
@@ -108,11 +108,64 @@
 #include <linux/bitmap.h>
 #include <linux/init.h>
 
+/*
+ * cpumask_var_t: struct cpumask for stack usage.
+ *
+ * Oh, the wicked games we play!  In order to make kernel coding a
+ * little more difficult, we typedef cpumask_var_t to an array or a
+ * pointer: doing &mask on an array is a noop, so it still works.
+ *
+ * ie.
+ *	cpumask_var_t tmpmask;
+ *	if (!alloc_cpumask_var(&tmpmask, GFP_KERNEL))
+ *		return -ENOMEM;
+ *
+ *	  ... use 'tmpmask' like a normal struct cpumask * ...
+ *
+ *	free_cpumask_var(tmpmask);
+ */
+#ifdef CONFIG_CPUMASK_OFFSTACK
+struct cpumask;
+typedef struct cpumask *cpumask_var_t;
+
+bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags);
+bool alloc_cpumask_var_copy(cpumask_var_t *mask, const struct cpumask *src,
+			    gfp_t flags);
+void free_cpumask_var(cpumask_var_t mask);
+
+static inline unsigned long *cpumask_bits(const volatile struct cpumask *mask)
+{
+	return (unsigned long *)mask;
+}
+#else
+/* This is only declared so we can define cpumask_var_t here. */
 struct cpumask
 {
 	DECLARE_BITMAP(bits, NR_CPUS);
 };
+
+typedef struct cpumask cpumask_var_t[1];
+
+static inline bool alloc_cpumask_var(cpumask_var_t mask, gfp_t flags)
+{
+	return true;
+}
+
+static inline bool alloc_cpumask_var_copy(cpumask_var_t mask,
+					  const struct cpumask *src,
+					  gfp_t flags)
+{
+	cpumask_copy(mask, src);
+	return true;
+}
+
+static inline void free_cpumask_var(cpumask_var_t mask)
+{
+}
+
+/* A macro is const-preserving, which is safer. */
 #define cpumask_bits(maskp) ((maskp)->bits)
+#endif /* CONFIG_CPUMASK_OFFSTACK */
 
 #define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(CONFIG_NR_CPUS)
 
@@ -412,50 +466,6 @@ int cpumask_any_but(const struct cpumask
 #endif /* NR_CPUS */
 
 /*
- * cpumask_var_t: struct cpumask for stack usage.
- *
- * Oh, the wicked games we play!  In order to make kernel coding a
- * little more difficult, we typedef cpumask_var_t to an array or a
- * pointer: doing &mask on an array is a noop, so it still works.
- *
- * ie.
- *	cpumask_var_t tmpmask;
- *	if (!alloc_cpumask_var(&tmpmask, GFP_KERNEL))
- *		return -ENOMEM;
- *
- *	  ... use 'tmpmask' like a normal struct cpumask * ...
- *
- *	free_cpumask_var(tmpmask);
- */
-#ifdef CONFIG_CPUMASK_OFFSTACK
-typedef struct cpumask *cpumask_var_t;
-
-bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags);
-bool alloc_cpumask_var_copy(cpumask_var_t *mask, const struct cpumask *src,
-			    gfp_t);
-void free_cpumask_var(cpumask_var_t mask);
-#else
-typedef struct cpumask cpumask_var_t[1];
-
-static inline bool alloc_cpumask_var(cpumask_var_t mask, gfp_t flags)
-{
-	return true;
-}
-
-static inline bool alloc_cpumask_var_copy(cpumask_var_t mask,
-					  const struct cpumask *src,
-					  gfp_t flags)
-{
-	cpumask_copy(mask, src);
-	return true;
-}
-
-static inline void free_cpumask_var(cpumask_var_t mask)
-{
-}
-#endif /* CONFIG_CPUMASK_OFFSTACK */
-
-/*
  * The following particular system cpumasks and operations manage
  * possible, present, active and online cpus.
  *
