Lines Matching +full:page +full:- +full:offset
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Squashfs - a compressed read only filesystem for Linux
12 * This file implements the low-level routines to read and decompress
31 * Returns the amount of bytes copied to the page actor.
35 int offset, int req_length) in copy_bio_to_actor() argument
50 int bytes_to_copy = min_t(int, bvec->bv_len - offset, in copy_bio_to_actor()
51 PAGE_SIZE - actor_offset); in copy_bio_to_actor()
54 req_length - copied_bytes); in copy_bio_to_actor()
57 offset, bytes_to_copy); in copy_bio_to_actor()
61 offset += bytes_to_copy; in copy_bio_to_actor()
69 if (offset >= bvec->bv_len) { in copy_bio_to_actor()
72 offset = 0; in copy_bio_to_actor()
83 struct page *head_to_cache = NULL, *tail_to_cache = NULL; in squashfs_bio_read_cached()
84 struct block_device *bdev = fullbio->bi_bdev; in squashfs_bio_read_cached()
93 struct page *page = bv->bv_page; in squashfs_bio_read_cached() local
95 if (page->mapping == cache_mapping) { in squashfs_bio_read_cached()
102 * the page size, so read_start and read_end cover full pages. in squashfs_bio_read_cached()
110 head_to_cache = page; in squashfs_bio_read_cached()
111 else if (idx == page_count - 1 && index + length != read_end) in squashfs_bio_read_cached()
112 tail_to_cache = page; in squashfs_bio_read_cached()
120 (end_idx - start_idx) * PAGE_SECTORS); in squashfs_bio_read_cached()
135 (end_idx - start_idx) * PAGE_SECTORS); in squashfs_bio_read_cached()
157 (read_end >> PAGE_SHIFT) - 1, in squashfs_bio_read_cached()
169 static struct page *squashfs_get_cache_page(struct address_space *mapping, in squashfs_get_cache_page()
172 struct page *page; in squashfs_get_cache_page() local
177 page = find_get_page(mapping, index); in squashfs_get_cache_page()
178 if (!page) in squashfs_get_cache_page()
181 if (!PageUptodate(page)) { in squashfs_get_cache_page()
182 put_page(page); in squashfs_get_cache_page()
186 return page; in squashfs_get_cache_page()
192 struct squashfs_sb_info *msblk = sb->s_fs_info; in squashfs_bio_read()
193 struct address_space *cache_mapping = msblk->cache_mapping; in squashfs_bio_read()
194 const u64 read_start = round_down(index, msblk->devblksize); in squashfs_bio_read()
195 const sector_t block = read_start >> msblk->devblksize_log2; in squashfs_bio_read()
196 const u64 read_end = round_up(index + length, msblk->devblksize); in squashfs_bio_read()
197 const sector_t block_end = read_end >> msblk->devblksize_log2; in squashfs_bio_read()
198 int offset = read_start - round_down(index, PAGE_SIZE); in squashfs_bio_read() local
199 int total_len = (block_end - block) << msblk->devblksize_log2; in squashfs_bio_read()
200 const int page_count = DIV_ROUND_UP(total_len + offset, PAGE_SIZE); in squashfs_bio_read()
206 return -ENOMEM; in squashfs_bio_read()
207 bio_init(bio, sb->s_bdev, bio->bi_inline_vecs, page_count, REQ_OP_READ); in squashfs_bio_read()
208 bio->bi_iter.bi_sector = block * (msblk->devblksize >> SECTOR_SHIFT); in squashfs_bio_read()
212 min_t(unsigned int, PAGE_SIZE - offset, total_len); in squashfs_bio_read()
214 struct page *page; in squashfs_bio_read() local
216 page = squashfs_get_cache_page(cache_mapping, index); in squashfs_bio_read()
217 if (!page) in squashfs_bio_read()
218 page = alloc_page(GFP_NOIO); in squashfs_bio_read()
220 if (!page) { in squashfs_bio_read()
221 error = -ENOMEM; in squashfs_bio_read()
226 * Use the __ version to avoid merging since we need each page in squashfs_bio_read()
229 __bio_add_page(bio, page, len, offset); in squashfs_bio_read()
230 offset = 0; in squashfs_bio_read()
231 total_len -= len; in squashfs_bio_read()
244 *block_offset = index & ((1 << msblk->devblksize_log2) - 1); in squashfs_bio_read()
255 * Read and decompress a metadata block or datablock. Length is non-zero
260 * generated a larger block - this does occasionally happen with compression
266 struct squashfs_sb_info *msblk = sb->s_fs_info; in squashfs_read_data()
270 int offset; in squashfs_read_data() local
279 index, compressed ? "" : "un", length, output->length); in squashfs_read_data()
288 if (index + 2 > msblk->bytes_used) { in squashfs_read_data()
289 res = -EIO; in squashfs_read_data()
292 res = squashfs_bio_read(sb, index, 2, &bio, &offset); in squashfs_read_data()
297 res = -EIO; in squashfs_read_data()
302 length = data[offset]; in squashfs_read_data()
303 if (offset < bvec->bv_len - 1) { in squashfs_read_data()
304 length |= data[offset + 1] << 8; in squashfs_read_data()
307 res = -EIO; in squashfs_read_data()
321 TRACE("Block @ 0x%llx, %scompressed size %d\n", index - 2, in squashfs_read_data()
324 if (length <= 0 || length > output->length || in squashfs_read_data()
325 (index + length) > msblk->bytes_used) { in squashfs_read_data()
326 res = -EIO; in squashfs_read_data()
333 res = squashfs_bio_read(sb, index, length, &bio, &offset); in squashfs_read_data()
338 if (!msblk->stream) { in squashfs_read_data()
339 res = -EIO; in squashfs_read_data()
342 res = msblk->thread_ops->decompress(msblk, bio, offset, length, output); in squashfs_read_data()
344 res = copy_bio_to_actor(bio, output, offset, length); in squashfs_read_data()
354 if (msblk->panic_on_errors) in squashfs_read_data()