From 0520a938e11c34a5ffc422b9316b85e294b0fbb2 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Sun, 11 Sep 2016 12:58:59 -0300 Subject: Linux-libre 4.7.3-gnu --- fs/aufs/module.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 8 deletions(-) (limited to 'fs/aufs/module.c') diff --git a/fs/aufs/module.c b/fs/aufs/module.c index ede9a232a..5092b4bd6 100644 --- a/fs/aufs/module.c +++ b/fs/aufs/module.c @@ -10,13 +10,57 @@ #include #include "aufs.h" -void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp) +/* shrinkable realloc */ +void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink) { - if (new_sz <= nused) - return p; + size_t sz; + int diff; + + sz = 0; + diff = -1; + if (p) { +#if 0 /* unused */ + if (!new_sz) { + au_delayed_kfree(p); + p = NULL; + goto out; + } +#else + AuDebugOn(!new_sz); +#endif + sz = ksize(p); + diff = au_kmidx_sub(sz, new_sz); + } + if (sz && !diff) + goto out; + + if (sz < new_sz) + /* expand or SLOB */ + p = krealloc(p, new_sz, gfp); + else if (new_sz < sz && may_shrink) { + /* shrink */ + void *q; + + q = kmalloc(new_sz, gfp); + if (q) { + if (p) { + memcpy(q, p, new_sz); + au_delayed_kfree(p); + } + p = q; + } else + p = NULL; + } - p = krealloc(p, new_sz, gfp); - if (p) +out: + return p; +} + +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp, + int may_shrink) +{ + p = au_krealloc(p, new_sz, gfp, may_shrink); + if (p && new_sz > nused) memset(p + nused, 0, new_sz - nused); return p; } @@ -38,9 +82,9 @@ static void au_do_dfree(struct work_struct *work __maybe_unused) head = &au_dfree.cache[AuCache_##idx].llist; \ node = llist_del_all(head); \ for (; node; node = next) { \ - struct au_##name *p = \ - p = llist_entry(node, struct au_##name, \ - lnode); \ + struct au_##name *p \ + = llist_entry(node, struct au_##name, \ + lnode); \ next = llist_next(node); \ au_cache_free_##name(p); \ } \ -- cgit v1.2.3-54-g00ecf