diff options
author | Roland Dreier <roland@purestorage.com> | 2013-12-19 11:37:03 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2013-12-20 13:53:44 -0500 |
commit | a96e4e2ffe439e45732d820fac6fee486b6412bf (patch) | |
tree | 94b6871a378f9a643f268c1e5c6ccd563fd65fa6 | |
parent | 309243ec14fde1149e1c66f19746e239e86caf39 (diff) |
IB/uverbs: New macro to set pointers to NULL if length is 0 in INIT_UDATA()
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>
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 8 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 19 |
2 files changed, 16 insertions, 11 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 9879568aed8c..a283274a5a09 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -55,6 +55,14 @@ | |||
55 | (udata)->outlen = (olen); \ | 55 | (udata)->outlen = (olen); \ |
56 | } while (0) | 56 | } while (0) |
57 | 57 | ||
58 | #define INIT_UDATA_BUF_OR_NULL(udata, ibuf, obuf, ilen, olen) \ | ||
59 | do { \ | ||
60 | (udata)->inbuf = (ilen) ? (const void __user *) (ibuf) : NULL; \ | ||
61 | (udata)->outbuf = (olen) ? (void __user *) (obuf) : NULL; \ | ||
62 | (udata)->inlen = (ilen); \ | ||
63 | (udata)->outlen = (olen); \ | ||
64 | } while (0) | ||
65 | |||
58 | /* | 66 | /* |
59 | * Our lifetime rules for these structs are the following: | 67 | * Our lifetime rules for these structs are the following: |
60 | * | 68 | * |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 34386943ebcf..699463bbfd2d 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -676,17 +676,14 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, | |||
676 | return -EINVAL; | 676 | return -EINVAL; |
677 | } | 677 | } |
678 | 678 | ||
679 | INIT_UDATA(&ucore, | 679 | INIT_UDATA_BUF_OR_NULL(&ucore, buf, (unsigned long) ex_hdr.response, |
680 | (hdr.in_words) ? buf : 0, | 680 | hdr.in_words * 8, hdr.out_words * 8); |
681 | (unsigned long)ex_hdr.response, | 681 | |
682 | hdr.in_words * 8, | 682 | INIT_UDATA_BUF_OR_NULL(&uhw, |
683 | hdr.out_words * 8); | 683 | buf + ucore.inlen, |
684 | 684 | (unsigned long) ex_hdr.response + ucore.outlen, | |
685 | INIT_UDATA(&uhw, | 685 | ex_hdr.provider_in_words * 8, |
686 | (ex_hdr.provider_in_words) ? buf + ucore.inlen : 0, | 686 | ex_hdr.provider_out_words * 8); |
687 | (ex_hdr.provider_out_words) ? (unsigned long)ex_hdr.response + ucore.outlen : 0, | ||
688 | ex_hdr.provider_in_words * 8, | ||
689 | ex_hdr.provider_out_words * 8); | ||
690 | 687 | ||
691 | err = uverbs_ex_cmd_table[command](file, | 688 | err = uverbs_ex_cmd_table[command](file, |
692 | &ucore, | 689 | &ucore, |