IB/uverbs: New macro to set pointers to NULL if length is 0 in INIT_UDATA()
authorRoland Dreier <roland@purestorage.com>
Thu, 19 Dec 2013 16:37:03 +0000 (08:37 -0800)
committerRoland Dreier <roland@purestorage.com>
Fri, 20 Dec 2013 18:53:44 +0000 (10:53 -0800)
Trying to have a ternary operator to choose between NULL (or 0) and the
real pointer value in invocations leads to an impossible choice between
a sparse error about a literal 0 used as a NULL pointer, and a gcc
warning about "pointer/integer type mismatch in conditional expression."

Rather than clutter the source with more casts, move the ternary
operator into a new INIT_UDATA_BUF_OR_NULL() macro, which makes it
easier to use and simplifies its callers.

Reported-by: Yann Droneaud <ydroneaud@opteya.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/core/uverbs.h
drivers/infiniband/core/uverbs_main.c

index 9879568..a283274 100644 (file)
                (udata)->outlen = (olen);                               \
        } while (0)
 
+#define INIT_UDATA_BUF_OR_NULL(udata, ibuf, obuf, ilen, olen)                  \
+       do {                                                                    \
+               (udata)->inbuf  = (ilen) ? (const void __user *) (ibuf) : NULL; \
+               (udata)->outbuf = (olen) ? (void __user *) (obuf) : NULL;       \
+               (udata)->inlen  = (ilen);                                       \
+               (udata)->outlen = (olen);                                       \
+       } while (0)
+
 /*
  * Our lifetime rules for these structs are the following:
  *
index 3438694..699463b 100644 (file)
@@ -676,17 +676,14 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
                                return -EINVAL;
                }
 
-               INIT_UDATA(&ucore,
-                          (hdr.in_words) ? buf : 0,
-                          (unsigned long)ex_hdr.response,
-                          hdr.in_words * 8,
-                          hdr.out_words * 8);
-
-               INIT_UDATA(&uhw,
-                          (ex_hdr.provider_in_words) ? buf + ucore.inlen : 0,
-                          (ex_hdr.provider_out_words) ? (unsigned long)ex_hdr.response + ucore.outlen : 0,
-                          ex_hdr.provider_in_words * 8,
-                          ex_hdr.provider_out_words * 8);
+               INIT_UDATA_BUF_OR_NULL(&ucore, buf, (unsigned long) ex_hdr.response,
+                                      hdr.in_words * 8, hdr.out_words * 8);
+
+               INIT_UDATA_BUF_OR_NULL(&uhw,
+                                      buf + ucore.inlen,
+                                      (unsigned long) ex_hdr.response + ucore.outlen,
+                                      ex_hdr.provider_in_words * 8,
+                                      ex_hdr.provider_out_words * 8);
 
                err = uverbs_ex_cmd_table[command](file,
                                                   &ucore,