Lines Matching +full:segment +full:- +full:0
1 // SPDX-License-Identifier: GPL-2.0
33 * 2. Segment(s)
34 * Variable size. Each segment includes one segment header, followed by data
37 * For inlined LZO compressed extent, only one segment is allowed.
38 * One segment represents at most one sector of uncompressed data.
40 * 2.1 Segment header
42 * Records the total size of the segment (not including the header).
43 * Segment header never crosses sector boundary, thus it's possible to
52 * 0 0x2 0x4 0x6 0x8 0xa 0xc 0xe 0x10
53 * 0x0000 | Header | SegHdr 01 | Data payload 01 ... |
55 * 0x0ff0 | SegHdr N | Data payload N ... |00|
58 * 0x1000 | SegHdr N+1| Data payload N+1 ... |
70 return lzo1x_worst_compress(fs_info->sectorsize); in workspace_buf_length()
74 return lzo1x_worst_compress(fs_info->sectorsize); in workspace_cbuf_length()
81 kvfree(workspace->buf); in lzo_free_workspace()
82 kvfree(workspace->cbuf); in lzo_free_workspace()
83 kvfree(workspace->mem); in lzo_free_workspace()
93 return ERR_PTR(-ENOMEM); in lzo_alloc_workspace()
95 workspace->mem = kvmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL | __GFP_NOWARN); in lzo_alloc_workspace()
96 workspace->buf = kvmalloc(workspace_buf_length(fs_info), GFP_KERNEL | __GFP_NOWARN); in lzo_alloc_workspace()
97 workspace->cbuf = kvmalloc(workspace_cbuf_length(fs_info), GFP_KERNEL | __GFP_NOWARN); in lzo_alloc_workspace()
98 if (!workspace->mem || !workspace->buf || !workspace->cbuf) in lzo_alloc_workspace()
101 INIT_LIST_HEAD(&workspace->list); in lzo_alloc_workspace()
103 return &workspace->list; in lzo_alloc_workspace()
105 lzo_free_workspace(&workspace->list); in lzo_alloc_workspace()
106 return ERR_PTR(-ENOMEM); in lzo_alloc_workspace()
128 * - Write a segment header into the destination
129 * - Copy the compressed buffer into the destination
130 * - Make sure we have enough space in the last sector to fit a segment header
131 * If not, we will pad at most (LZO_LEN (4)) - 1 bytes of zeros.
142 const u32 sectorsize = fs_info->sectorsize; in copy_compressed_data_to_page()
143 const u32 min_folio_shift = PAGE_SHIFT + fs_info->block_min_order; in copy_compressed_data_to_page()
150 return -E2BIG; in copy_compressed_data_to_page()
153 * We never allow a segment header crossing sector boundary, previous in copy_compressed_data_to_page()
156 ASSERT((*cur_out / sectorsize) == (*cur_out + LZO_LEN - 1) / sectorsize); in copy_compressed_data_to_page()
163 return -ENOMEM; in copy_compressed_data_to_page()
174 while (*cur_out - orig_out < compressed_size) { in copy_compressed_data_to_page()
175 u32 copy_len = min_t(u32, sectorsize - *cur_out % sectorsize, in copy_compressed_data_to_page()
176 orig_out + compressed_size - *cur_out); in copy_compressed_data_to_page()
181 return -E2BIG; in copy_compressed_data_to_page()
188 return -ENOMEM; in copy_compressed_data_to_page()
191 kaddr = kmap_local_folio(cur_folio, 0); in copy_compressed_data_to_page()
194 compressed_data + *cur_out - orig_out, copy_len); in copy_compressed_data_to_page()
200 * Check if we can fit the next segment header into the remaining space in copy_compressed_data_to_page()
203 sector_bytes_left = round_up(*cur_out, sectorsize) - *cur_out; in copy_compressed_data_to_page()
204 if (sector_bytes_left >= LZO_LEN || sector_bytes_left == 0) in copy_compressed_data_to_page()
208 memset(kaddr + offset_in_page(*cur_out), 0, in copy_compressed_data_to_page()
214 return 0; in copy_compressed_data_to_page()
221 struct btrfs_fs_info *fs_info = inode->root->fs_info; in lzo_compress_folios()
223 const u32 sectorsize = fs_info->sectorsize; in lzo_compress_folios()
225 struct address_space *mapping = inode->vfs_inode.i_mapping; in lzo_compress_folios()
229 int ret = 0; in lzo_compress_folios()
233 u32 cur_out = 0; in lzo_compress_folios()
236 ASSERT(max_nr_folio > 0); in lzo_compress_folios()
237 *out_folios = 0; in lzo_compress_folios()
238 *total_out = 0; in lzo_compress_folios()
239 *total_in = 0; in lzo_compress_folios()
248 const u32 sectorsize_mask = sectorsize - 1; in lzo_compress_folios()
249 u32 sector_off = (cur_in - start) & sectorsize_mask; in lzo_compress_folios()
256 if (ret < 0) in lzo_compress_folios()
261 in_len = min_t(u32, start + len - cur_in, sectorsize - sector_off); in lzo_compress_folios()
265 workspace->cbuf, &out_len, in lzo_compress_folios()
266 workspace->mem); in lzo_compress_folios()
268 if (unlikely(ret < 0)) { in lzo_compress_folios()
270 ret = -EIO; in lzo_compress_folios()
274 ret = copy_compressed_data_to_page(fs_info, workspace->cbuf, out_len, in lzo_compress_folios()
277 if (ret < 0) in lzo_compress_folios()
286 if (cur_in - start > sectorsize * 2 && cur_in - start < cur_out) { in lzo_compress_folios()
287 ret = -E2BIG; in lzo_compress_folios()
299 sizes_ptr = kmap_local_folio(folios[0], 0); in lzo_compress_folios()
303 ret = 0; in lzo_compress_folios()
305 *total_in = cur_in - start; in lzo_compress_folios()
314 * Copy the compressed segment payload into @dest.
322 const u32 min_folio_shift = PAGE_SHIFT + fs_info->block_min_order; in copy_compressed_segment()
326 struct folio *cur_folio = cb->compressed_folios[*cur_in >> min_folio_shift]; in copy_compressed_segment()
327 u32 copy_len = min_t(u32, orig_in + len - *cur_in, in copy_compressed_segment()
328 folio_size(cur_folio) - offset_in_folio(cur_folio, *cur_in)); in copy_compressed_segment()
332 memcpy_from_folio(dest + *cur_in - orig_in, cur_folio, in copy_compressed_segment()
342 const struct btrfs_fs_info *fs_info = cb->bbio.inode->root->fs_info; in lzo_decompress_bio()
343 const u32 sectorsize = fs_info->sectorsize; in lzo_decompress_bio()
344 const u32 min_folio_shift = PAGE_SHIFT + fs_info->block_min_order; in lzo_decompress_bio()
350 u32 cur_in = 0; in lzo_decompress_bio()
352 u32 cur_out = 0; in lzo_decompress_bio()
354 kaddr = kmap_local_folio(cb->compressed_folios[0], 0); in lzo_decompress_bio()
366 if (unlikely(len_in > min_t(size_t, BTRFS_MAX_COMPRESSED, cb->compressed_len) || in lzo_decompress_bio()
367 round_up(len_in, sectorsize) < cb->compressed_len)) { in lzo_decompress_bio()
368 struct btrfs_inode *inode = cb->bbio.inode; in lzo_decompress_bio()
372 btrfs_root_id(inode->root), btrfs_ino(inode), in lzo_decompress_bio()
373 cb->start, len_in, cb->compressed_len); in lzo_decompress_bio()
374 return -EUCLEAN; in lzo_decompress_bio()
377 /* Go through each lzo segment */ in lzo_decompress_bio()
380 /* Length of the compressed segment */ in lzo_decompress_bio()
386 * We should always have enough space for one segment header in lzo_decompress_bio()
390 (cur_in + LZO_LEN - 1) / sectorsize); in lzo_decompress_bio()
391 cur_folio = cb->compressed_folios[cur_in >> min_folio_shift]; in lzo_decompress_bio()
393 kaddr = kmap_local_folio(cur_folio, 0); in lzo_decompress_bio()
399 struct btrfs_inode *inode = cb->bbio.inode; in lzo_decompress_bio()
403 * for workspace->cbuf in lzo_decompress_bio()
406 "lzo segment too big, root %llu inode %llu offset %llu len %u", in lzo_decompress_bio()
407 btrfs_root_id(inode->root), btrfs_ino(inode), in lzo_decompress_bio()
408 cb->start, seg_len); in lzo_decompress_bio()
409 return -EIO; in lzo_decompress_bio()
412 /* Copy the compressed segment payload into workspace */ in lzo_decompress_bio()
413 copy_compressed_segment(cb, workspace->cbuf, seg_len, &cur_in); in lzo_decompress_bio()
416 ret = lzo1x_decompress_safe(workspace->cbuf, seg_len, in lzo_decompress_bio()
417 workspace->buf, &out_len); in lzo_decompress_bio()
419 struct btrfs_inode *inode = cb->bbio.inode; in lzo_decompress_bio()
423 ret, btrfs_root_id(inode->root), btrfs_ino(inode), in lzo_decompress_bio()
424 cb->start); in lzo_decompress_bio()
425 return -EIO; in lzo_decompress_bio()
429 ret = btrfs_decompress_buf2page(workspace->buf, out_len, cb, cur_out); in lzo_decompress_bio()
433 if (ret == 0) in lzo_decompress_bio()
434 return 0; in lzo_decompress_bio()
435 ret = 0; in lzo_decompress_bio()
437 /* Check if the sector has enough space for a segment header */ in lzo_decompress_bio()
438 sector_bytes_left = sectorsize - (cur_in % sectorsize); in lzo_decompress_bio()
446 return 0; in lzo_decompress_bio()
455 const u32 sectorsize = fs_info->sectorsize; in lzo_decompress()
459 int ret = 0; in lzo_decompress()
462 return -EUCLEAN; in lzo_decompress()
466 return -EUCLEAN; in lzo_decompress()
470 if (unlikely(in_len != srclen - LZO_LEN * 2)) { in lzo_decompress()
471 ret = -EUCLEAN; in lzo_decompress()
477 ret = lzo1x_decompress_safe(data_in, in_len, workspace->buf, &out_len); in lzo_decompress()
483 ret, btrfs_root_id(inode->root), btrfs_ino(inode), in lzo_decompress()
485 ret = -EIO; in lzo_decompress()
490 memcpy_to_folio(dest_folio, dest_pgoff, workspace->buf, out_len); in lzo_decompress()
493 ret = -EIO; in lzo_decompress()
494 folio_zero_range(dest_folio, dest_pgoff + out_len, destlen - out_len); in lzo_decompress()