diff --git a/fs/eulerfs/nvalloc.c b/fs/eulerfs/nvalloc.c index 8b60a2494636163cbe54416d85839109c56e23ff..30e4c75e16e23804d8dd1f7ad9532f257337e53f 100644 --- a/fs/eulerfs/nvalloc.c +++ b/fs/eulerfs/nvalloc.c @@ -525,7 +525,7 @@ void nv_fini(struct super_block *sb) kfree(sbi->gpool); } -void nv_init(struct super_block *sb, bool init) +int nv_init(struct super_block *sb, bool init) { struct eufs_sb_info *sbi = EUFS_SB(sb); struct mem_pool *ppool; @@ -533,6 +533,9 @@ void nv_init(struct super_block *sb, bool init) /* allocate pools */ sbi->gpool = kmalloc(sizeof(struct mem_pool), GFP_KERNEL); + if (!sbi->gpool) + return -ENOMEM; + INIT_LIST_HEAD(&sbi->gpool->large_list); INIT_LIST_HEAD(&sbi->gpool->page_list); INIT_LIST_HEAD(&sbi->gpool->line4_list); @@ -543,6 +546,9 @@ void nv_init(struct super_block *sb, bool init) sbi->gpool->nlines = 0; sbi->rest_pool = kmalloc(sizeof(struct mem_pool), GFP_KERNEL); + if (!sbi->rest_pool) + goto err_rest_pool; + INIT_LIST_HEAD(&sbi->rest_pool->large_list); INIT_LIST_HEAD(&sbi->rest_pool->page_list); INIT_LIST_HEAD(&sbi->rest_pool->line4_list); @@ -554,6 +560,9 @@ void nv_init(struct super_block *sb, bool init) sbi->rest_pool->nlines = 0; sbi->ppool = alloc_percpu(struct mem_pool); + if (!sbi->ppool) + goto err_ppool; + for_each_online_cpu(cpu) { ppool = per_cpu_ptr(sbi->ppool, cpu); INIT_LIST_HEAD(&ppool->large_list); @@ -568,6 +577,15 @@ void nv_init(struct super_block *sb, bool init) } partition(sb, init); + return 0; + +err_ppool: + kfree(sbi->rest_pool); + sbi->rest_pool = NULL; +err_rest_pool: + kfree(sbi->gpool); + sbi->gpool = NULL; + return -ENOMEM; } static int cut_from_list_remaining(struct list_head *head, int remaining, diff --git a/fs/eulerfs/nvalloc.h b/fs/eulerfs/nvalloc.h index a39b81862bfb4c8c1f78cf6cf763f16aa239b06e..17d7d69042c7e05ed03f2e44b2b20bdb4ede85b0 100644 --- a/fs/eulerfs/nvalloc.h +++ b/fs/eulerfs/nvalloc.h @@ -134,7 +134,7 @@ int nvmalloc_pre(struct super_block *sb, struct alloc_batch *ab, size_t count, size_t size); void *nvmalloc(struct super_block *sb, size_t size, u8 tag, bool nonblocking); void nvfree(struct super_block *sb, void *ptr, bool rest); -void nv_init(struct super_block *sb, bool init); +int nv_init(struct super_block *sb, bool init); void nv_fini(struct super_block *sb); void eufs_get_layout(struct super_block *sb, bool init); diff --git a/fs/eulerfs/super.c b/fs/eulerfs/super.c index 43fc717002d747639320dce4c7fa17c4b0798a58..a4bf568224df6e74266b8e9955795e91f735e2bf 100644 --- a/fs/eulerfs/super.c +++ b/fs/eulerfs/super.c @@ -332,7 +332,9 @@ static struct eufs_inode *eufs_init(struct super_block *sb, unsigned long size) sbi->s_crash_ver = 1; super->s_crash_ver = cpu_to_le64(1); - nv_init(sb, true); + if (nv_init(sb, true)) + return ERR_PTR(-ENOMEM); + super->s_page_map = cpu_to_le64(p2o(sb, sbi->page_map)); super->s_mtime = 0; @@ -478,7 +480,9 @@ static int eufs_fill_super(struct super_block *sb, void *data, int silent) eufs_pbarrier(); } - nv_init(sb, false); + err = nv_init(sb, false); + if (err) + goto out; root_pi = (struct eufs_inode *)s2p(sb, super->s_root_pi);