dm stripe: use struct_size() in kmalloc()

One of the more common cases of allocation size calculations is finding
the size of a structure that has a zero-sized array at the end, along
with memory for some number of elements for that array. For example:

struct stripe_c {
        ...
        struct stripe stripe[0];
};

In this case alloc_context() and dm_array_too_big() are removed and
replaced by the direct use of the struct_size() helper in kmalloc().

Notice that open-coded form is prone to type mistakes.

This code was detected with the help of Coccinelle.

Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
This commit is contained in:
Gustavo A. R. Silva 2019-10-02 14:03:41 -05:00 коммит произвёл Mike Snitzer
Родитель 53be73a5d7
Коммит 8adeac3be0
2 изменённых файлов: 1 добавлений и 17 удалений

Просмотреть файл

@ -55,19 +55,6 @@ static void trigger_event(struct work_struct *work)
dm_table_event(sc->ti->table); dm_table_event(sc->ti->table);
} }
static inline struct stripe_c *alloc_context(unsigned int stripes)
{
size_t len;
if (dm_array_too_big(sizeof(struct stripe_c), sizeof(struct stripe),
stripes))
return NULL;
len = sizeof(struct stripe_c) + (sizeof(struct stripe) * stripes);
return kmalloc(len, GFP_KERNEL);
}
/* /*
* Parse a single <dev> <sector> pair * Parse a single <dev> <sector> pair
*/ */
@ -142,7 +129,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
return -EINVAL; return -EINVAL;
} }
sc = alloc_context(stripes); sc = kmalloc(struct_size(sc, stripe, stripes), GFP_KERNEL);
if (!sc) { if (!sc) {
ti->error = "Memory allocation for striped context " ti->error = "Memory allocation for striped context "
"failed"; "failed";

Просмотреть файл

@ -594,9 +594,6 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size);
*/ */
#define dm_round_up(n, sz) (dm_div_up((n), (sz)) * (sz)) #define dm_round_up(n, sz) (dm_div_up((n), (sz)) * (sz))
#define dm_array_too_big(fixed, obj, num) \
((num) > (UINT_MAX - (fixed)) / (obj))
/* /*
* Sector offset taken relative to the start of the target instead of * Sector offset taken relative to the start of the target instead of
* relative to the start of the device. * relative to the start of the device.