99
1010#define LZ4_MAX_DISTANCE_PAGES (DIV_ROUND_UP(LZ4_DISTANCE_MAX, PAGE_SIZE) + 1)
1111
12- struct z_erofs_lz4_decompress_ctx {
13- struct z_erofs_decompress_req * rq ;
14- /* # of encoded, decoded pages */
15- unsigned int inpages , outpages ;
16- /* decoded block total length (used for in-place decompression) */
17- unsigned int oend ;
18- };
19-
2012static int z_erofs_load_lz4_config (struct super_block * sb ,
2113 struct erofs_super_block * dsb , void * data , int size )
2214{
@@ -55,10 +47,9 @@ static int z_erofs_load_lz4_config(struct super_block *sb,
5547 * Fill all gaps with bounce pages if it's a sparse page list. Also check if
5648 * all physical pages are consecutive, which can be seen for moderate CR.
5749 */
58- static int z_erofs_lz4_prepare_dstpages (struct z_erofs_lz4_decompress_ctx * ctx ,
50+ static int z_erofs_lz4_prepare_dstpages (struct z_erofs_decompress_req * rq ,
5951 struct page * * pagepool )
6052{
61- struct z_erofs_decompress_req * rq = ctx -> rq ;
6253 struct page * availables [LZ4_MAX_DISTANCE_PAGES ] = { NULL };
6354 unsigned long bounced [DIV_ROUND_UP (LZ4_MAX_DISTANCE_PAGES ,
6455 BITS_PER_LONG )] = { 0 };
@@ -68,7 +59,7 @@ static int z_erofs_lz4_prepare_dstpages(struct z_erofs_lz4_decompress_ctx *ctx,
6859 unsigned int i , j , top ;
6960
7061 top = 0 ;
71- for (i = j = 0 ; i < ctx -> outpages ; ++ i , ++ j ) {
62+ for (i = j = 0 ; i < rq -> outpages ; ++ i , ++ j ) {
7263 struct page * const page = rq -> out [i ];
7364 struct page * victim ;
7465
@@ -114,36 +105,36 @@ static int z_erofs_lz4_prepare_dstpages(struct z_erofs_lz4_decompress_ctx *ctx,
114105 return kaddr ? 1 : 0 ;
115106}
116107
117- static void * z_erofs_lz4_handle_overlap (struct z_erofs_lz4_decompress_ctx * ctx ,
108+ static void * z_erofs_lz4_handle_overlap (struct z_erofs_decompress_req * rq ,
118109 void * inpage , void * out , unsigned int * inputmargin ,
119110 int * maptype , bool may_inplace )
120111{
121- struct z_erofs_decompress_req * rq = ctx -> rq ;
122- unsigned int omargin , total , i ;
112+ unsigned int oend , omargin , total , i ;
123113 struct page * * in ;
124114 void * src , * tmp ;
125115
126116 if (rq -> inplace_io ) {
127- omargin = PAGE_ALIGN (ctx -> oend ) - ctx -> oend ;
117+ oend = rq -> pageofs_out + rq -> outputsize ;
118+ omargin = PAGE_ALIGN (oend ) - oend ;
128119 if (rq -> partial_decoding || !may_inplace ||
129120 omargin < LZ4_DECOMPRESS_INPLACE_MARGIN (rq -> inputsize ))
130121 goto docopy ;
131122
132- for (i = 0 ; i < ctx -> inpages ; ++ i )
133- if (rq -> out [ctx -> outpages - ctx -> inpages + i ] !=
123+ for (i = 0 ; i < rq -> inpages ; ++ i )
124+ if (rq -> out [rq -> outpages - rq -> inpages + i ] !=
134125 rq -> in [i ])
135126 goto docopy ;
136127 kunmap_local (inpage );
137128 * maptype = 3 ;
138- return out + ((ctx -> outpages - ctx -> inpages ) << PAGE_SHIFT );
129+ return out + ((rq -> outpages - rq -> inpages ) << PAGE_SHIFT );
139130 }
140131
141- if (ctx -> inpages <= 1 ) {
132+ if (rq -> inpages <= 1 ) {
142133 * maptype = 0 ;
143134 return inpage ;
144135 }
145136 kunmap_local (inpage );
146- src = erofs_vm_map_ram (rq -> in , ctx -> inpages );
137+ src = erofs_vm_map_ram (rq -> in , rq -> inpages );
147138 if (!src )
148139 return ERR_PTR (- ENOMEM );
149140 * maptype = 1 ;
@@ -152,7 +143,7 @@ static void *z_erofs_lz4_handle_overlap(struct z_erofs_lz4_decompress_ctx *ctx,
152143docopy :
153144 /* Or copy compressed data which can be overlapped to per-CPU buffer */
154145 in = rq -> in ;
155- src = z_erofs_get_gbuf (ctx -> inpages );
146+ src = z_erofs_get_gbuf (rq -> inpages );
156147 if (!src ) {
157148 DBG_BUGON (1 );
158149 kunmap_local (inpage );
@@ -197,10 +188,8 @@ int z_erofs_fixup_insize(struct z_erofs_decompress_req *rq, const char *padbuf,
197188 return 0 ;
198189}
199190
200- static int z_erofs_lz4_decompress_mem (struct z_erofs_lz4_decompress_ctx * ctx ,
201- u8 * dst )
191+ static int z_erofs_lz4_decompress_mem (struct z_erofs_decompress_req * rq , u8 * dst )
202192{
203- struct z_erofs_decompress_req * rq = ctx -> rq ;
204193 bool support_0padding = false, may_inplace = false;
205194 unsigned int inputmargin ;
206195 u8 * out , * headpage , * src ;
@@ -224,7 +213,7 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx,
224213 }
225214
226215 inputmargin = rq -> pageofs_in ;
227- src = z_erofs_lz4_handle_overlap (ctx , headpage , dst , & inputmargin ,
216+ src = z_erofs_lz4_handle_overlap (rq , headpage , dst , & inputmargin ,
228217 & maptype , may_inplace );
229218 if (IS_ERR (src ))
230219 return PTR_ERR (src );
@@ -251,7 +240,7 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx,
251240 if (maptype == 0 ) {
252241 kunmap_local (headpage );
253242 } else if (maptype == 1 ) {
254- vm_unmap_ram (src , ctx -> inpages );
243+ vm_unmap_ram (src , rq -> inpages );
255244 } else if (maptype == 2 ) {
256245 z_erofs_put_gbuf (src );
257246 } else if (maptype != 3 ) {
@@ -264,54 +253,42 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx,
264253static int z_erofs_lz4_decompress (struct z_erofs_decompress_req * rq ,
265254 struct page * * pagepool )
266255{
267- struct z_erofs_lz4_decompress_ctx ctx ;
268256 unsigned int dst_maptype ;
269257 void * dst ;
270258 int ret ;
271259
272- ctx .rq = rq ;
273- ctx .oend = rq -> pageofs_out + rq -> outputsize ;
274- ctx .outpages = PAGE_ALIGN (ctx .oend ) >> PAGE_SHIFT ;
275- ctx .inpages = PAGE_ALIGN (rq -> inputsize ) >> PAGE_SHIFT ;
276-
277260 /* one optimized fast path only for non bigpcluster cases yet */
278- if (ctx . inpages == 1 && ctx . outpages == 1 && !rq -> inplace_io ) {
261+ if (rq -> inpages == 1 && rq -> outpages == 1 && !rq -> inplace_io ) {
279262 DBG_BUGON (!* rq -> out );
280263 dst = kmap_local_page (* rq -> out );
281264 dst_maptype = 0 ;
282- goto dstmap_out ;
283- }
284-
285- /* general decoding path which can be used for all cases */
286- ret = z_erofs_lz4_prepare_dstpages (& ctx , pagepool );
287- if (ret < 0 ) {
288- return ret ;
289- } else if (ret > 0 ) {
290- dst = page_address (* rq -> out );
291- dst_maptype = 1 ;
292265 } else {
293- dst = erofs_vm_map_ram (rq -> out , ctx .outpages );
294- if (!dst )
295- return - ENOMEM ;
296- dst_maptype = 2 ;
266+ /* general decoding path which can be used for all cases */
267+ ret = z_erofs_lz4_prepare_dstpages (rq , pagepool );
268+ if (ret < 0 )
269+ return ret ;
270+ if (ret > 0 ) {
271+ dst = page_address (* rq -> out );
272+ dst_maptype = 1 ;
273+ } else {
274+ dst = erofs_vm_map_ram (rq -> out , rq -> outpages );
275+ if (!dst )
276+ return - ENOMEM ;
277+ dst_maptype = 2 ;
278+ }
297279 }
298-
299- dstmap_out :
300- ret = z_erofs_lz4_decompress_mem (& ctx , dst );
280+ ret = z_erofs_lz4_decompress_mem (rq , dst );
301281 if (!dst_maptype )
302282 kunmap_local (dst );
303283 else if (dst_maptype == 2 )
304- vm_unmap_ram (dst , ctx . outpages );
284+ vm_unmap_ram (dst , rq -> outpages );
305285 return ret ;
306286}
307287
308288static int z_erofs_transform_plain (struct z_erofs_decompress_req * rq ,
309289 struct page * * pagepool )
310290{
311- const unsigned int nrpages_in =
312- PAGE_ALIGN (rq -> pageofs_in + rq -> inputsize ) >> PAGE_SHIFT ;
313- const unsigned int nrpages_out =
314- PAGE_ALIGN (rq -> pageofs_out + rq -> outputsize ) >> PAGE_SHIFT ;
291+ const unsigned int nrpages_in = rq -> inpages , nrpages_out = rq -> outpages ;
315292 const unsigned int bs = rq -> sb -> s_blocksize ;
316293 unsigned int cur = 0 , ni = 0 , no , pi , po , insz , cnt ;
317294 u8 * kin ;
@@ -373,7 +350,7 @@ int z_erofs_stream_switch_bufs(struct z_erofs_stream_dctx *dctx, void **dst,
373350 unsigned int j ;
374351
375352 if (!dctx -> avail_out ) {
376- if (++ dctx -> no >= dctx -> outpages || !rq -> outputsize ) {
353+ if (++ dctx -> no >= rq -> outpages || !rq -> outputsize ) {
377354 erofs_err (sb , "insufficient space for decompressed data" );
378355 return - EFSCORRUPTED ;
379356 }
@@ -401,7 +378,7 @@ int z_erofs_stream_switch_bufs(struct z_erofs_stream_dctx *dctx, void **dst,
401378 }
402379
403380 if (dctx -> inbuf_pos == dctx -> inbuf_sz && rq -> inputsize ) {
404- if (++ dctx -> ni >= dctx -> inpages ) {
381+ if (++ dctx -> ni >= rq -> inpages ) {
405382 erofs_err (sb , "invalid compressed data" );
406383 return - EFSCORRUPTED ;
407384 }
@@ -434,7 +411,7 @@ int z_erofs_stream_switch_bufs(struct z_erofs_stream_dctx *dctx, void **dst,
434411 dctx -> bounced = true;
435412 }
436413
437- for (j = dctx -> ni + 1 ; j < dctx -> inpages ; ++ j ) {
414+ for (j = dctx -> ni + 1 ; j < rq -> inpages ; ++ j ) {
438415 if (rq -> out [dctx -> no ] != rq -> in [j ])
439416 continue ;
440417 tmppage = erofs_allocpage (pgpl , rq -> gfp );
0 commit comments