1 // SPDX-License-Identifier: GPL-2.0+
2 #include "internal.h"
3 
z_erofs_fill_inode(struct erofs_inode * vi)4 int z_erofs_fill_inode(struct erofs_inode *vi)
5 {
6 	if (!erofs_sb_has_big_pcluster() &&
7 	    vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) {
8 		vi->z_advise = 0;
9 		vi->z_algorithmtype[0] = 0;
10 		vi->z_algorithmtype[1] = 0;
11 		vi->z_logical_clusterbits = LOG_BLOCK_SIZE;
12 
13 		vi->flags |= EROFS_I_Z_INITED;
14 	}
15 	return 0;
16 }
17 
z_erofs_fill_inode_lazy(struct erofs_inode * vi)18 static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
19 {
20 	int ret;
21 	erofs_off_t pos;
22 	struct z_erofs_map_header *h;
23 	char buf[sizeof(struct z_erofs_map_header)];
24 
25 	if (vi->flags & EROFS_I_Z_INITED)
26 		return 0;
27 
28 	DBG_BUGON(!erofs_sb_has_big_pcluster() &&
29 		  vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY);
30 	pos = round_up(iloc(vi->nid) + vi->inode_isize + vi->xattr_isize, 8);
31 
32 	ret = erofs_dev_read(0, buf, pos, sizeof(buf));
33 	if (ret < 0)
34 		return -EIO;
35 
36 	h = (struct z_erofs_map_header *)buf;
37 	vi->z_advise = le16_to_cpu(h->h_advise);
38 	vi->z_algorithmtype[0] = h->h_algorithmtype & 15;
39 	vi->z_algorithmtype[1] = h->h_algorithmtype >> 4;
40 
41 	if (vi->z_algorithmtype[0] >= Z_EROFS_COMPRESSION_MAX) {
42 		erofs_err("unknown compression format %u for nid %llu",
43 			  vi->z_algorithmtype[0], (unsigned long long)vi->nid);
44 		return -EOPNOTSUPP;
45 	}
46 
47 	vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7);
48 	if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION &&
49 	    !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^
50 	    !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) {
51 		erofs_err("big pcluster head1/2 of compact indexes should be consistent for nid %llu",
52 			  vi->nid * 1ULL);
53 		return -EFSCORRUPTED;
54 	}
55 	vi->flags |= EROFS_I_Z_INITED;
56 	return 0;
57 }
58 
59 struct z_erofs_maprecorder {
60 	struct erofs_inode *inode;
61 	struct erofs_map_blocks *map;
62 	void *kaddr;
63 
64 	unsigned long lcn;
65 	/* compression extent information gathered */
66 	u8  type, headtype;
67 	u16 clusterofs;
68 	u16 delta[2];
69 	erofs_blk_t pblk, compressedlcs;
70 };
71 
z_erofs_reload_indexes(struct z_erofs_maprecorder * m,erofs_blk_t eblk)72 static int z_erofs_reload_indexes(struct z_erofs_maprecorder *m,
73 				  erofs_blk_t eblk)
74 {
75 	int ret;
76 	struct erofs_map_blocks *const map = m->map;
77 	char *mpage = map->mpage;
78 
79 	if (map->index == eblk)
80 		return 0;
81 
82 	ret = erofs_blk_read(mpage, eblk, 1);
83 	if (ret < 0)
84 		return -EIO;
85 
86 	map->index = eblk;
87 
88 	return 0;
89 }
90 
legacy_load_cluster_from_disk(struct z_erofs_maprecorder * m,unsigned long lcn)91 static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m,
92 					 unsigned long lcn)
93 {
94 	struct erofs_inode *const vi = m->inode;
95 	const erofs_off_t ibase = iloc(vi->nid);
96 	const erofs_off_t pos =
97 		Z_EROFS_VLE_LEGACY_INDEX_ALIGN(ibase + vi->inode_isize +
98 					       vi->xattr_isize) +
99 		lcn * sizeof(struct z_erofs_vle_decompressed_index);
100 	struct z_erofs_vle_decompressed_index *di;
101 	unsigned int advise, type;
102 	int err;
103 
104 	err = z_erofs_reload_indexes(m, erofs_blknr(pos));
105 	if (err)
106 		return err;
107 
108 	m->lcn = lcn;
109 	di = m->kaddr + erofs_blkoff(pos);
110 
111 	advise = le16_to_cpu(di->di_advise);
112 	type = (advise >> Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT) &
113 		((1 << Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) - 1);
114 	switch (type) {
115 	case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
116 		m->clusterofs = 1 << vi->z_logical_clusterbits;
117 		m->delta[0] = le16_to_cpu(di->di_u.delta[0]);
118 		if (m->delta[0] & Z_EROFS_VLE_DI_D0_CBLKCNT) {
119 			if (!(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) {
120 				DBG_BUGON(1);
121 				return -EFSCORRUPTED;
122 			}
123 			m->compressedlcs = m->delta[0] &
124 				~Z_EROFS_VLE_DI_D0_CBLKCNT;
125 			m->delta[0] = 1;
126 		}
127 		m->delta[1] = le16_to_cpu(di->di_u.delta[1]);
128 		break;
129 	case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
130 	case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
131 		m->clusterofs = le16_to_cpu(di->di_clusterofs);
132 		m->pblk = le32_to_cpu(di->di_u.blkaddr);
133 		break;
134 	default:
135 		DBG_BUGON(1);
136 		return -EOPNOTSUPP;
137 	}
138 	m->type = type;
139 	return 0;
140 }
141 
decode_compactedbits(unsigned int lobits,unsigned int lomask,u8 * in,unsigned int pos,u8 * type)142 static unsigned int decode_compactedbits(unsigned int lobits,
143 					 unsigned int lomask,
144 					 u8 *in, unsigned int pos, u8 *type)
145 {
146 	const unsigned int v = get_unaligned_le32(in + pos / 8) >> (pos & 7);
147 	const unsigned int lo = v & lomask;
148 
149 	*type = (v >> lobits) & 3;
150 	return lo;
151 }
152 
get_compacted_la_distance(unsigned int lclusterbits,unsigned int encodebits,unsigned int vcnt,u8 * in,int i)153 static int get_compacted_la_distance(unsigned int lclusterbits,
154 				     unsigned int encodebits,
155 				     unsigned int vcnt, u8 *in, int i)
156 {
157 	const unsigned int lomask = (1 << lclusterbits) - 1;
158 	unsigned int lo, d1 = 0;
159 	u8 type;
160 
161 	DBG_BUGON(i >= vcnt);
162 
163 	do {
164 		lo = decode_compactedbits(lclusterbits, lomask,
165 					  in, encodebits * i, &type);
166 
167 		if (type != Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD)
168 			return d1;
169 		++d1;
170 	} while (++i < vcnt);
171 
172 	/* vcnt - 1 (Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) item */
173 	if (!(lo & Z_EROFS_VLE_DI_D0_CBLKCNT))
174 		d1 += lo - 1;
175 	return d1;
176 }
177 
unpack_compacted_index(struct z_erofs_maprecorder * m,unsigned int amortizedshift,unsigned int eofs,bool lookahead)178 static int unpack_compacted_index(struct z_erofs_maprecorder *m,
179 				  unsigned int amortizedshift,
180 				  unsigned int eofs, bool lookahead)
181 {
182 	struct erofs_inode *const vi = m->inode;
183 	const unsigned int lclusterbits = vi->z_logical_clusterbits;
184 	const unsigned int lomask = (1 << lclusterbits) - 1;
185 	unsigned int vcnt, base, lo, encodebits, nblk;
186 	int i;
187 	u8 *in, type;
188 	bool big_pcluster;
189 
190 	if (1 << amortizedshift == 4)
191 		vcnt = 2;
192 	else if (1 << amortizedshift == 2 && lclusterbits == 12)
193 		vcnt = 16;
194 	else
195 		return -EOPNOTSUPP;
196 
197 	big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1;
198 	encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt;
199 	base = round_down(eofs, vcnt << amortizedshift);
200 	in = m->kaddr + base;
201 
202 	i = (eofs - base) >> amortizedshift;
203 
204 	lo = decode_compactedbits(lclusterbits, lomask,
205 				  in, encodebits * i, &type);
206 	m->type = type;
207 	if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) {
208 		m->clusterofs = 1 << lclusterbits;
209 
210 		/* figure out lookahead_distance: delta[1] if needed */
211 		if (lookahead)
212 			m->delta[1] = get_compacted_la_distance(lclusterbits,
213 								encodebits,
214 								vcnt, in, i);
215 		if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) {
216 			if (!big_pcluster) {
217 				DBG_BUGON(1);
218 				return -EFSCORRUPTED;
219 			}
220 			m->compressedlcs = lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT;
221 			m->delta[0] = 1;
222 			return 0;
223 		} else if (i + 1 != (int)vcnt) {
224 			m->delta[0] = lo;
225 			return 0;
226 		}
227 		/*
228 		 * since the last lcluster in the pack is special,
229 		 * of which lo saves delta[1] rather than delta[0].
230 		 * Hence, get delta[0] by the previous lcluster indirectly.
231 		 */
232 		lo = decode_compactedbits(lclusterbits, lomask,
233 					  in, encodebits * (i - 1), &type);
234 		if (type != Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD)
235 			lo = 0;
236 		else if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT)
237 			lo = 1;
238 		m->delta[0] = lo + 1;
239 		return 0;
240 	}
241 	m->clusterofs = lo;
242 	m->delta[0] = 0;
243 	/* figout out blkaddr (pblk) for HEAD lclusters */
244 	if (!big_pcluster) {
245 		nblk = 1;
246 		while (i > 0) {
247 			--i;
248 			lo = decode_compactedbits(lclusterbits, lomask,
249 						  in, encodebits * i, &type);
250 			if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD)
251 				i -= lo;
252 
253 			if (i >= 0)
254 				++nblk;
255 		}
256 	} else {
257 		nblk = 0;
258 		while (i > 0) {
259 			--i;
260 			lo = decode_compactedbits(lclusterbits, lomask,
261 						  in, encodebits * i, &type);
262 			if (type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) {
263 				if (lo & Z_EROFS_VLE_DI_D0_CBLKCNT) {
264 					--i;
265 					nblk += lo & ~Z_EROFS_VLE_DI_D0_CBLKCNT;
266 					continue;
267 				}
268 				if (lo == 1) {
269 					DBG_BUGON(1);
270 					/* --i; ++nblk;	continue; */
271 					return -EFSCORRUPTED;
272 				}
273 				i -= lo - 2;
274 				continue;
275 			}
276 			++nblk;
277 		}
278 	}
279 	in += (vcnt << amortizedshift) - sizeof(__le32);
280 	m->pblk = le32_to_cpu(*(__le32 *)in) + nblk;
281 	return 0;
282 }
283 
compacted_load_cluster_from_disk(struct z_erofs_maprecorder * m,unsigned long lcn,bool lookahead)284 static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m,
285 					    unsigned long lcn, bool lookahead)
286 {
287 	struct erofs_inode *const vi = m->inode;
288 	const unsigned int lclusterbits = vi->z_logical_clusterbits;
289 	const erofs_off_t ebase = round_up(iloc(vi->nid) + vi->inode_isize +
290 					   vi->xattr_isize, 8) +
291 		sizeof(struct z_erofs_map_header);
292 	const unsigned int totalidx = DIV_ROUND_UP(vi->i_size, EROFS_BLKSIZ);
293 	unsigned int compacted_4b_initial, compacted_2b;
294 	unsigned int amortizedshift;
295 	erofs_off_t pos;
296 	int err;
297 
298 	if (lclusterbits != 12)
299 		return -EOPNOTSUPP;
300 
301 	if (lcn >= totalidx)
302 		return -EINVAL;
303 
304 	m->lcn = lcn;
305 	/* used to align to 32-byte (compacted_2b) alignment */
306 	compacted_4b_initial = (32 - ebase % 32) / 4;
307 	if (compacted_4b_initial == 32 / 4)
308 		compacted_4b_initial = 0;
309 
310 	if (vi->z_advise & Z_EROFS_ADVISE_COMPACTED_2B)
311 		compacted_2b = rounddown(totalidx - compacted_4b_initial, 16);
312 	else
313 		compacted_2b = 0;
314 
315 	pos = ebase;
316 	if (lcn < compacted_4b_initial) {
317 		amortizedshift = 2;
318 		goto out;
319 	}
320 	pos += compacted_4b_initial * 4;
321 	lcn -= compacted_4b_initial;
322 
323 	if (lcn < compacted_2b) {
324 		amortizedshift = 1;
325 		goto out;
326 	}
327 	pos += compacted_2b * 2;
328 	lcn -= compacted_2b;
329 	amortizedshift = 2;
330 out:
331 	pos += lcn * (1 << amortizedshift);
332 	err = z_erofs_reload_indexes(m, erofs_blknr(pos));
333 	if (err)
334 		return err;
335 	return unpack_compacted_index(m, amortizedshift, erofs_blkoff(pos),
336 				      lookahead);
337 }
338 
z_erofs_load_cluster_from_disk(struct z_erofs_maprecorder * m,unsigned int lcn,bool lookahead)339 static int z_erofs_load_cluster_from_disk(struct z_erofs_maprecorder *m,
340 					  unsigned int lcn, bool lookahead)
341 {
342 	const unsigned int datamode = m->inode->datalayout;
343 
344 	if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY)
345 		return legacy_load_cluster_from_disk(m, lcn);
346 
347 	if (datamode == EROFS_INODE_FLAT_COMPRESSION)
348 		return compacted_load_cluster_from_disk(m, lcn, lookahead);
349 
350 	return -EINVAL;
351 }
352 
z_erofs_extent_lookback(struct z_erofs_maprecorder * m,unsigned int lookback_distance)353 static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
354 				   unsigned int lookback_distance)
355 {
356 	struct erofs_inode *const vi = m->inode;
357 	struct erofs_map_blocks *const map = m->map;
358 	const unsigned int lclusterbits = vi->z_logical_clusterbits;
359 	unsigned long lcn = m->lcn;
360 	int err;
361 
362 	if (lcn < lookback_distance) {
363 		erofs_err("bogus lookback distance @ nid %llu",
364 			  (unsigned long long)vi->nid);
365 		DBG_BUGON(1);
366 		return -EFSCORRUPTED;
367 	}
368 
369 	/* load extent head logical cluster if needed */
370 	lcn -= lookback_distance;
371 	err = z_erofs_load_cluster_from_disk(m, lcn, false);
372 	if (err)
373 		return err;
374 
375 	switch (m->type) {
376 	case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
377 		if (!m->delta[0]) {
378 			erofs_err("invalid lookback distance 0 @ nid %llu",
379 				  (unsigned long long)vi->nid);
380 			DBG_BUGON(1);
381 			return -EFSCORRUPTED;
382 		}
383 		return z_erofs_extent_lookback(m, m->delta[0]);
384 	case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
385 	case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
386 		m->headtype = m->type;
387 		map->m_la = (lcn << lclusterbits) | m->clusterofs;
388 		break;
389 	default:
390 		erofs_err("unknown type %u @ lcn %lu of nid %llu",
391 			  m->type, lcn, (unsigned long long)vi->nid);
392 		DBG_BUGON(1);
393 		return -EOPNOTSUPP;
394 	}
395 	return 0;
396 }
397 
z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder * m,unsigned int initial_lcn)398 static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
399 					    unsigned int initial_lcn)
400 {
401 	struct erofs_inode *const vi = m->inode;
402 	struct erofs_map_blocks *const map = m->map;
403 	const unsigned int lclusterbits = vi->z_logical_clusterbits;
404 	unsigned long lcn;
405 	int err;
406 
407 	DBG_BUGON(m->type != Z_EROFS_VLE_CLUSTER_TYPE_PLAIN &&
408 		  m->type != Z_EROFS_VLE_CLUSTER_TYPE_HEAD);
409 	if (m->headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN ||
410 	    !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) {
411 		map->m_plen = 1 << lclusterbits;
412 		return 0;
413 	}
414 
415 	lcn = m->lcn + 1;
416 	if (m->compressedlcs)
417 		goto out;
418 
419 	err = z_erofs_load_cluster_from_disk(m, lcn, false);
420 	if (err)
421 		return err;
422 
423 	/*
424 	 * If the 1st NONHEAD lcluster has already been handled initially w/o
425 	 * valid compressedlcs, which means at least it mustn't be CBLKCNT, or
426 	 * an internal implemenatation error is detected.
427 	 *
428 	 * The following code can also handle it properly anyway, but let's
429 	 * BUG_ON in the debugging mode only for developers to notice that.
430 	 */
431 	DBG_BUGON(lcn == initial_lcn &&
432 		  m->type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD);
433 
434 	switch (m->type) {
435 	case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
436 	case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
437 		/*
438 		 * if the 1st NONHEAD lcluster is actually PLAIN or HEAD type
439 		 * rather than CBLKCNT, it's a 1 lcluster-sized pcluster.
440 		 */
441 		m->compressedlcs = 1;
442 		break;
443 	case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
444 		if (m->delta[0] != 1)
445 			goto err_bonus_cblkcnt;
446 		if (m->compressedlcs)
447 			break;
448 		/* fallthrough */
449 	default:
450 		erofs_err("cannot found CBLKCNT @ lcn %lu of nid %llu",
451 			  lcn, vi->nid | 0ULL);
452 		DBG_BUGON(1);
453 		return -EFSCORRUPTED;
454 	}
455 out:
456 	map->m_plen = m->compressedlcs << lclusterbits;
457 	return 0;
458 err_bonus_cblkcnt:
459 	erofs_err("bogus CBLKCNT @ lcn %lu of nid %llu",
460 		  lcn, vi->nid | 0ULL);
461 	DBG_BUGON(1);
462 	return -EFSCORRUPTED;
463 }
464 
z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder * m)465 static int z_erofs_get_extent_decompressedlen(struct z_erofs_maprecorder *m)
466 {
467 	struct erofs_inode *const vi = m->inode;
468 	struct erofs_map_blocks *map = m->map;
469 	unsigned int lclusterbits = vi->z_logical_clusterbits;
470 	u64 lcn = m->lcn, headlcn = map->m_la >> lclusterbits;
471 	int err;
472 
473 	do {
474 		/* handle the last EOF pcluster (no next HEAD lcluster) */
475 		if ((lcn << lclusterbits) >= vi->i_size) {
476 			map->m_llen = vi->i_size - map->m_la;
477 			return 0;
478 		}
479 
480 		err = z_erofs_load_cluster_from_disk(m, lcn, true);
481 		if (err)
482 			return err;
483 
484 		if (m->type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD) {
485 			DBG_BUGON(!m->delta[1] &&
486 				  m->clusterofs != 1 << lclusterbits);
487 		} else if (m->type == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN ||
488 			   m->type == Z_EROFS_VLE_CLUSTER_TYPE_HEAD) {
489 			/* go on until the next HEAD lcluster */
490 			if (lcn != headlcn)
491 				break;
492 			m->delta[1] = 1;
493 		} else {
494 			erofs_err("unknown type %u @ lcn %llu of nid %llu",
495 				  m->type, lcn | 0ULL,
496 				  (unsigned long long)vi->nid);
497 			DBG_BUGON(1);
498 			return -EOPNOTSUPP;
499 		}
500 		lcn += m->delta[1];
501 	} while (m->delta[1]);
502 
503 	map->m_llen = (lcn << lclusterbits) + m->clusterofs - map->m_la;
504 	return 0;
505 }
506 
z_erofs_map_blocks_iter(struct erofs_inode * vi,struct erofs_map_blocks * map,int flags)507 int z_erofs_map_blocks_iter(struct erofs_inode *vi,
508 			    struct erofs_map_blocks *map,
509 			    int flags)
510 {
511 	struct z_erofs_maprecorder m = {
512 		.inode = vi,
513 		.map = map,
514 		.kaddr = map->mpage,
515 	};
516 	int err = 0;
517 	unsigned int lclusterbits, endoff;
518 	unsigned long initial_lcn;
519 	unsigned long long ofs, end;
520 
521 	/* when trying to read beyond EOF, leave it unmapped */
522 	if (map->m_la >= vi->i_size) {
523 		map->m_llen = map->m_la + 1 - vi->i_size;
524 		map->m_la = vi->i_size;
525 		map->m_flags = 0;
526 		goto out;
527 	}
528 
529 	err = z_erofs_fill_inode_lazy(vi);
530 	if (err)
531 		goto out;
532 
533 	lclusterbits = vi->z_logical_clusterbits;
534 	ofs = map->m_la;
535 	initial_lcn = ofs >> lclusterbits;
536 	endoff = ofs & ((1 << lclusterbits) - 1);
537 
538 	err = z_erofs_load_cluster_from_disk(&m, initial_lcn, false);
539 	if (err)
540 		goto out;
541 
542 	map->m_flags = EROFS_MAP_MAPPED | EROFS_MAP_ENCODED;
543 	end = (m.lcn + 1ULL) << lclusterbits;
544 	switch (m.type) {
545 	case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
546 	case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
547 		if (endoff >= m.clusterofs) {
548 			m.headtype = m.type;
549 			map->m_la = (m.lcn << lclusterbits) | m.clusterofs;
550 			break;
551 		}
552 		/* m.lcn should be >= 1 if endoff < m.clusterofs */
553 		if (!m.lcn) {
554 			erofs_err("invalid logical cluster 0 at nid %llu",
555 				  (unsigned long long)vi->nid);
556 			err = -EFSCORRUPTED;
557 			goto out;
558 		}
559 		end = (m.lcn << lclusterbits) | m.clusterofs;
560 		map->m_flags |= EROFS_MAP_FULL_MAPPED;
561 		m.delta[0] = 1;
562 		/* fallthrough */
563 	case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
564 		/* get the correspoinding first chunk */
565 		err = z_erofs_extent_lookback(&m, m.delta[0]);
566 		if (err)
567 			goto out;
568 		break;
569 	default:
570 		erofs_err("unknown type %u @ offset %llu of nid %llu",
571 			  m.type, ofs, (unsigned long long)vi->nid);
572 		err = -EOPNOTSUPP;
573 		goto out;
574 	}
575 
576 	map->m_llen = end - map->m_la;
577 	map->m_pa = blknr_to_addr(m.pblk);
578 
579 	err = z_erofs_get_extent_compressedlen(&m, initial_lcn);
580 	if (err)
581 		goto out;
582 
583 	if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN)
584 		map->m_algorithmformat = Z_EROFS_COMPRESSION_SHIFTED;
585 	else
586 		map->m_algorithmformat = vi->z_algorithmtype[0];
587 
588 	if (flags & EROFS_GET_BLOCKS_FIEMAP) {
589 		err = z_erofs_get_extent_decompressedlen(&m);
590 		if (!err)
591 			map->m_flags |= EROFS_MAP_FULL_MAPPED;
592 	}
593 
594 out:
595 	erofs_dbg("m_la %" PRIu64 " m_pa %" PRIu64 " m_llen %" PRIu64 " m_plen %" PRIu64 " m_flags 0%o",
596 		  map->m_la, map->m_pa,
597 		  map->m_llen, map->m_plen, map->m_flags);
598 
599 	DBG_BUGON(err < 0 && err != -ENOMEM);
600 	return err;
601 }
602