summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bcache/journal.c11
-rw-r--r--drivers/md/bcache/journal.h1
-rw-r--r--drivers/md/bcache/super.c9
-rw-r--r--drivers/md/bcache/util.h18
4 files changed, 20 insertions, 19 deletions
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 4734caec178d..a6ec23ebfc3f 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -436,7 +436,7 @@ static enum {
where = jlist->head;
add:
- i = kmalloc(offsetof(struct journal_replay, j) + bytes, GFP_KERNEL);
+ i = kvmalloc(offsetof(struct journal_replay, j) + bytes, GFP_KERNEL);
if (!i) {
ret = JOURNAL_ENTRY_ADD_ERROR;
goto out;
@@ -863,15 +863,14 @@ search_done:
#undef read_bucket
}
-static void journal_entries_free(struct journal *j,
- struct list_head *list)
+void bch_journal_entries_free(struct list_head *list)
{
while (!list_empty(list)) {
struct journal_replay *i =
list_first_entry(list, struct journal_replay, list);
list_del(&i->list);
- kfree(i);
+ kvfree(i);
}
}
@@ -928,7 +927,7 @@ const char *bch_journal_read(struct cache_set *c, struct list_head *list)
closure_sync(&jlist.cl);
if (jlist.ret) {
- journal_entries_free(&c->journal, list);
+ bch_journal_entries_free(list);
return jlist.ret == -ENOMEM
? "cannot allocate memory for journal"
@@ -1456,7 +1455,7 @@ err:
if (ret)
bch_err(c, "journal replay error: %d", ret);
- journal_entries_free(j, list);
+ bch_journal_entries_free(list);
return ret;
}
diff --git a/drivers/md/bcache/journal.h b/drivers/md/bcache/journal.h
index 6fe7014ecd76..c8c6639666d3 100644
--- a/drivers/md/bcache/journal.h
+++ b/drivers/md/bcache/journal.h
@@ -339,6 +339,7 @@ static inline bool journal_flushes_device(struct cache *ca)
void bch_journal_start(struct cache_set *);
void bch_journal_mark(struct cache_set *, struct list_head *);
+void bch_journal_entries_free(struct list_head *);
const char *bch_journal_read(struct cache_set *, struct list_head *);
int bch_journal_replay(struct cache_set *, struct list_head *);
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 93a97114a10e..aa96931d3db9 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1485,14 +1485,7 @@ static const char *run_cache_set(struct cache_set *c)
BUG_ON(!list_empty(&journal));
return NULL;
err:
- while (!list_empty(&journal)) {
- struct journal_replay *r =
- list_first_entry(&journal, struct journal_replay, list);
-
- list_del(&r->list);
- kfree(r);
- }
-
+ bch_journal_entries_free(&journal);
set_bit(CACHE_SET_ERROR, &c->flags);
bch_cache_set_unregister(c);
closure_put(&c->caching);
diff --git a/drivers/md/bcache/util.h b/drivers/md/bcache/util.h
index 129ecb638ae5..115188f5c23b 100644
--- a/drivers/md/bcache/util.h
+++ b/drivers/md/bcache/util.h
@@ -77,6 +77,18 @@ do { \
(__builtin_types_compatible_p(typeof(_val), _type) || \
__builtin_types_compatible_p(typeof(_val), const _type))
+static inline void *kvmalloc(size_t bytes, gfp_t gfp)
+{
+ if (bytes <= PAGE_SIZE ||
+ !(gfp & GFP_KERNEL))
+ return kmalloc(bytes, gfp);
+
+ return ((bytes <= KMALLOC_MAX_SIZE)
+ ? kmalloc(bytes, gfp|__GFP_NOWARN)
+ : NULL) ?:
+ vmalloc(bytes);
+}
+
#define DECLARE_HEAP(type, name) \
struct { \
size_t size, used; \
@@ -89,11 +101,7 @@ do { \
(heap)->used = 0; \
(heap)->size = (_size); \
_bytes = (heap)->size * sizeof(*(heap)->data); \
- (heap)->data = NULL; \
- if (_bytes < KMALLOC_MAX_SIZE) \
- (heap)->data = kmalloc(_bytes, (gfp)); \
- if ((!(heap)->data) && ((gfp) & GFP_KERNEL)) \
- (heap)->data = vmalloc(_bytes); \
+ (heap)->data = kvmalloc(_bytes, (gfp)); \
(heap)->data; \
})