@@ -60,63 +60,58 @@ void z_erofs_put_gbuf(void *ptr) __releases(gbuf->lock)
60
60
int z_erofs_gbuf_growsize (unsigned int nrpages )
61
61
{
62
62
static DEFINE_MUTEX (gbuf_resize_mutex );
63
- struct page * pagepool = NULL ;
64
- int delta , ret , i , j ;
63
+ struct page * * tmp_pages = NULL ;
64
+ struct z_erofs_gbuf * gbuf ;
65
+ void * ptr , * old_ptr ;
66
+ int last , i , j ;
65
67
66
68
mutex_lock (& gbuf_resize_mutex );
67
- delta = nrpages - z_erofs_gbuf_nrpages ;
68
- ret = 0 ;
69
69
/* avoid shrinking gbufs, since no idea how many fses rely on */
70
- if (delta <= 0 )
71
- goto out ;
70
+ if (nrpages <= z_erofs_gbuf_nrpages ) {
71
+ mutex_unlock (& gbuf_resize_mutex );
72
+ return 0 ;
73
+ }
72
74
73
75
for (i = 0 ; i < z_erofs_gbuf_count ; ++ i ) {
74
- struct z_erofs_gbuf * gbuf = & z_erofs_gbufpool [i ];
75
- struct page * * pages , * * tmp_pages ;
76
- void * ptr , * old_ptr = NULL ;
77
-
78
- ret = - ENOMEM ;
76
+ gbuf = & z_erofs_gbufpool [i ];
79
77
tmp_pages = kcalloc (nrpages , sizeof (* tmp_pages ), GFP_KERNEL );
80
78
if (!tmp_pages )
81
- break ;
82
- for (j = 0 ; j < nrpages ; ++ j ) {
83
- tmp_pages [j ] = erofs_allocpage (& pagepool , GFP_KERNEL );
84
- if (!tmp_pages [j ])
85
- goto free_pagearray ;
86
- }
79
+ goto out ;
80
+
81
+ for (j = 0 ; j < gbuf -> nrpages ; ++ j )
82
+ tmp_pages [j ] = gbuf -> pages [j ];
83
+ do {
84
+ last = j ;
85
+ j = alloc_pages_bulk_array (GFP_KERNEL , nrpages ,
86
+ tmp_pages );
87
+ if (last == j )
88
+ goto out ;
89
+ } while (j != nrpages );
90
+
87
91
ptr = vmap (tmp_pages , nrpages , VM_MAP , PAGE_KERNEL );
88
92
if (!ptr )
89
- goto free_pagearray ;
93
+ goto out ;
90
94
91
- pages = tmp_pages ;
92
95
spin_lock (& gbuf -> lock );
96
+ kfree (gbuf -> pages );
97
+ gbuf -> pages = tmp_pages ;
93
98
old_ptr = gbuf -> ptr ;
94
99
gbuf -> ptr = ptr ;
95
- tmp_pages = gbuf -> pages ;
96
- gbuf -> pages = pages ;
97
- j = gbuf -> nrpages ;
98
100
gbuf -> nrpages = nrpages ;
99
101
spin_unlock (& gbuf -> lock );
100
- ret = 0 ;
101
- if (!tmp_pages ) {
102
- DBG_BUGON (old_ptr );
103
- continue ;
104
- }
105
-
106
102
if (old_ptr )
107
103
vunmap (old_ptr );
108
- free_pagearray :
109
- while (j )
110
- erofs_pagepool_add (& pagepool , tmp_pages [-- j ]);
111
- kfree (tmp_pages );
112
- if (ret )
113
- break ;
114
104
}
115
105
z_erofs_gbuf_nrpages = nrpages ;
116
- erofs_release_pages (& pagepool );
117
106
out :
107
+ if (i < z_erofs_gbuf_count && tmp_pages ) {
108
+ for (j = 0 ; j < nrpages ; ++ j )
109
+ if (tmp_pages [j ] && tmp_pages [j ] != gbuf -> pages [j ])
110
+ __free_page (tmp_pages [j ]);
111
+ kfree (tmp_pages );
112
+ }
118
113
mutex_unlock (& gbuf_resize_mutex );
119
- return ret ;
114
+ return i < z_erofs_gbuf_count ? - ENOMEM : 0 ;
120
115
}
121
116
122
117
int __init z_erofs_gbuf_init (void )
0 commit comments