1 // SPDX-License-Identifier: GPL-2.0-or-later
6 struct z_erofs_lzma
*next
;
7 struct xz_dec_microlzma
*state
;
11 /* considering the LZMA performance, no need to use a lockless list for now */
12 static DEFINE_SPINLOCK(z_erofs_lzma_lock
);
13 static unsigned int z_erofs_lzma_max_dictsize
;
14 static unsigned int z_erofs_lzma_nstrms
, z_erofs_lzma_avail_strms
;
15 static struct z_erofs_lzma
*z_erofs_lzma_head
;
16 static DECLARE_WAIT_QUEUE_HEAD(z_erofs_lzma_wq
);
18 module_param_named(lzma_streams
, z_erofs_lzma_nstrms
, uint
, 0444);
20 static void z_erofs_lzma_exit(void)
22 /* there should be no running fs instance */
23 while (z_erofs_lzma_avail_strms
) {
24 struct z_erofs_lzma
*strm
;
26 spin_lock(&z_erofs_lzma_lock
);
27 strm
= z_erofs_lzma_head
;
29 spin_unlock(&z_erofs_lzma_lock
);
33 z_erofs_lzma_head
= NULL
;
34 spin_unlock(&z_erofs_lzma_lock
);
37 struct z_erofs_lzma
*n
= strm
->next
;
40 xz_dec_microlzma_end(strm
->state
);
42 --z_erofs_lzma_avail_strms
;
48 static int __init
z_erofs_lzma_init(void)
52 /* by default, use # of possible CPUs instead */
53 if (!z_erofs_lzma_nstrms
)
54 z_erofs_lzma_nstrms
= num_possible_cpus();
56 for (i
= 0; i
< z_erofs_lzma_nstrms
; ++i
) {
57 struct z_erofs_lzma
*strm
= kzalloc(sizeof(*strm
), GFP_KERNEL
);
63 spin_lock(&z_erofs_lzma_lock
);
64 strm
->next
= z_erofs_lzma_head
;
65 z_erofs_lzma_head
= strm
;
66 spin_unlock(&z_erofs_lzma_lock
);
67 ++z_erofs_lzma_avail_strms
;
72 static int z_erofs_load_lzma_config(struct super_block
*sb
,
73 struct erofs_super_block
*dsb
, void *data
, int size
)
75 static DEFINE_MUTEX(lzma_resize_mutex
);
76 struct z_erofs_lzma_cfgs
*lzma
= data
;
77 unsigned int dict_size
, i
;
78 struct z_erofs_lzma
*strm
, *head
= NULL
;
81 if (!lzma
|| size
< sizeof(struct z_erofs_lzma_cfgs
)) {
82 erofs_err(sb
, "invalid lzma cfgs, size=%u", size
);
86 erofs_err(sb
, "unidentified lzma format %x, please check kernel version",
87 le16_to_cpu(lzma
->format
));
90 dict_size
= le32_to_cpu(lzma
->dict_size
);
91 if (dict_size
> Z_EROFS_LZMA_MAX_DICT_SIZE
|| dict_size
< 4096) {
92 erofs_err(sb
, "unsupported lzma dictionary size %u",
97 /* in case 2 z_erofs_load_lzma_config() race to avoid deadlock */
98 mutex_lock(&lzma_resize_mutex
);
100 if (z_erofs_lzma_max_dictsize
>= dict_size
) {
101 mutex_unlock(&lzma_resize_mutex
);
105 /* 1. collect/isolate all streams for the following check */
106 for (i
= 0; i
< z_erofs_lzma_avail_strms
; ++i
) {
107 struct z_erofs_lzma
*last
;
110 spin_lock(&z_erofs_lzma_lock
);
111 strm
= z_erofs_lzma_head
;
113 spin_unlock(&z_erofs_lzma_lock
);
114 wait_event(z_erofs_lzma_wq
,
115 READ_ONCE(z_erofs_lzma_head
));
118 z_erofs_lzma_head
= NULL
;
119 spin_unlock(&z_erofs_lzma_lock
);
121 for (last
= strm
; last
->next
; last
= last
->next
)
128 /* 2. walk each isolated stream and grow max dict_size if needed */
129 for (strm
= head
; strm
; strm
= strm
->next
) {
131 xz_dec_microlzma_end(strm
->state
);
132 strm
->state
= xz_dec_microlzma_alloc(XZ_PREALLOC
, dict_size
);
137 /* 3. push back all to the global list and update max dict_size */
138 spin_lock(&z_erofs_lzma_lock
);
139 DBG_BUGON(z_erofs_lzma_head
);
140 z_erofs_lzma_head
= head
;
141 spin_unlock(&z_erofs_lzma_lock
);
142 wake_up_all(&z_erofs_lzma_wq
);
144 z_erofs_lzma_max_dictsize
= dict_size
;
145 mutex_unlock(&lzma_resize_mutex
);
149 static int z_erofs_lzma_decompress(struct z_erofs_decompress_req
*rq
,
152 struct super_block
*sb
= rq
->sb
;
153 struct z_erofs_stream_dctx dctx
= {
155 .inpages
= PAGE_ALIGN(rq
->inputsize
) >> PAGE_SHIFT
,
156 .outpages
= PAGE_ALIGN(rq
->pageofs_out
+ rq
->outputsize
)
160 struct xz_buf buf
= {};
161 struct z_erofs_lzma
*strm
;
165 /* 1. get the exact LZMA compressed size */
166 dctx
.kin
= kmap_local_page(*rq
->in
);
167 err
= z_erofs_fixup_insize(rq
, dctx
.kin
+ rq
->pageofs_in
,
168 min(rq
->inputsize
, sb
->s_blocksize
- rq
->pageofs_in
));
170 kunmap_local(dctx
.kin
);
174 /* 2. get an available lzma context */
176 spin_lock(&z_erofs_lzma_lock
);
177 strm
= z_erofs_lzma_head
;
179 spin_unlock(&z_erofs_lzma_lock
);
180 wait_event(z_erofs_lzma_wq
, READ_ONCE(z_erofs_lzma_head
));
183 z_erofs_lzma_head
= strm
->next
;
184 spin_unlock(&z_erofs_lzma_lock
);
186 /* 3. multi-call decompress */
187 xz_dec_microlzma_reset(strm
->state
, rq
->inputsize
, rq
->outputsize
,
188 !rq
->partial_decoding
);
189 buf
.in_size
= min(rq
->inputsize
, PAGE_SIZE
- rq
->pageofs_in
);
190 rq
->inputsize
-= buf
.in_size
;
191 buf
.in
= dctx
.kin
+ rq
->pageofs_in
;
192 dctx
.bounce
= strm
->bounce
;
194 dctx
.avail_out
= buf
.out_size
- buf
.out_pos
;
195 dctx
.inbuf_sz
= buf
.in_size
;
196 dctx
.inbuf_pos
= buf
.in_pos
;
197 err
= z_erofs_stream_switch_bufs(&dctx
, (void **)&buf
.out
,
198 (void **)&buf
.in
, pgpl
);
202 if (buf
.out_size
== buf
.out_pos
) {
203 buf
.out_size
= dctx
.avail_out
;
206 buf
.in_size
= dctx
.inbuf_sz
;
207 buf
.in_pos
= dctx
.inbuf_pos
;
209 xz_err
= xz_dec_microlzma_run(strm
->state
, &buf
);
210 DBG_BUGON(buf
.out_pos
> buf
.out_size
);
211 DBG_BUGON(buf
.in_pos
> buf
.in_size
);
213 if (xz_err
!= XZ_OK
) {
214 if (xz_err
== XZ_STREAM_END
&& !rq
->outputsize
)
216 erofs_err(sb
, "failed to decompress %d in[%u] out[%u]",
217 xz_err
, rq
->inputsize
, rq
->outputsize
);
224 kunmap_local(dctx
.kout
);
225 kunmap_local(dctx
.kin
);
226 /* 4. push back LZMA stream context to the global list */
227 spin_lock(&z_erofs_lzma_lock
);
228 strm
->next
= z_erofs_lzma_head
;
229 z_erofs_lzma_head
= strm
;
230 spin_unlock(&z_erofs_lzma_lock
);
231 wake_up(&z_erofs_lzma_wq
);
235 const struct z_erofs_decompressor z_erofs_lzma_decomp
= {
236 .config
= z_erofs_load_lzma_config
,
237 .decompress
= z_erofs_lzma_decompress
,
238 .init
= z_erofs_lzma_init
,
239 .exit
= z_erofs_lzma_exit
,