victim = availables[--top];
get_page(victim);
} else {
- if (!list_empty(pagepool)) {
- victim = lru_to_page(pagepool);
- list_del(&victim->lru);
- DBG_BUGON(page_ref_count(victim) != 1);
- } else {
- victim = alloc_pages(GFP_KERNEL, 0);
- if (!victim)
- return -ENOMEM;
- }
+ victim = erofs_allocpage(pagepool, GFP_KERNEL, false);
+ if (unlikely(!victim))
+ return -ENOMEM;
victim->mapping = Z_EROFS_MAPPING_STAGING;
}
rq->out[i] = victim;
extern const struct file_operations erofs_dir_fops;
/* utils.c / zdata.c */
-struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp);
+struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp, bool nofail);
#if (EROFS_PCPUBUF_NR_PAGES > 0)
void *erofs_get_pcpubuf(unsigned int pagenr);
#include "internal.h"
#include <linux/pagevec.h>
-struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp)
+struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp, bool nofail)
{
struct page *page;
if (!list_empty(pool)) {
page = lru_to_page(pool);
+ DBG_BUGON(page_ref_count(page) != 1);
list_del(&page->lru);
} else {
- page = alloc_pages(gfp | __GFP_NOFAIL, 0);
+ page = alloc_pages(gfp | (nofail ? __GFP_NOFAIL : 0), 0);
}
return page;
}
static inline struct page *__stagingpage_alloc(struct list_head *pagepool,
gfp_t gfp)
{
- struct page *page = erofs_allocpage(pagepool, gfp);
-
- if (unlikely(!page))
- return NULL;
+ struct page *page = erofs_allocpage(pagepool, gfp, true);
page->mapping = Z_EROFS_MAPPING_STAGING;
return page;