/* * Returns the amount of bytes copied to the page actor.
*/ staticint copy_bio_to_actor(struct bio *bio, struct squashfs_page_actor *actor, int offset, int req_length)
{ void *actor_addr; struct bvec_iter_all iter_all = {}; struct bio_vec *bvec = bvec_init_iter_all(&iter_all); int copied_bytes = 0; int actor_offset = 0;
if (folio->mapping == cache_mapping) {
idx++; continue;
}
/* * We only use this when the device block size is the same as * the page size, so read_start and read_end cover full pages. * * Compare these to the original required index and length to * only cache pages which were requested partially, since these * are the ones which are likely to be needed when reading * adjacent blocks.
*/ if (idx == 0 && index != read_start)
head_to_cache = folio; elseif (idx == page_count - 1 && index + length != read_end)
tail_to_cache = folio; #ifdef CONFIG_SQUASHFS_COMP_CACHE_FULL /* Cache all pages in the BIO for repeated reads */ elseif (cache_folios)
cache_folios[idx] = folio; #endif
if (!bio || idx != end_idx) { struct bio *new = bio_alloc_clone(bdev, fullbio,
GFP_NOIO, &fs_bio_set);
bio = bio_kmalloc(page_count, GFP_NOIO); if (!bio) return -ENOMEM;
bio_init(bio, sb->s_bdev, bio->bi_inline_vecs, page_count, REQ_OP_READ);
bio->bi_iter.bi_sector = block * (msblk->devblksize >> SECTOR_SHIFT);
for (i = 0; i < page_count; ++i) { unsignedint len =
min_t(unsignedint, PAGE_SIZE - offset, total_len);
pgoff_t index = (read_start >> PAGE_SHIFT) + i; struct page *page;
page = squashfs_get_cache_page(cache_mapping, index); if (!page)
page = alloc_page(GFP_NOIO);
if (!page) {
error = -ENOMEM; goto out_free_bio;
}
/* * Use the __ version to avoid merging since we need each page * to be separate when we check for and avoid cached pages.
*/
__bio_add_page(bio, page, len, offset);
offset = 0;
total_len -= len;
}
if (cache_mapping)
error = squashfs_bio_read_cached(bio, cache_mapping, index,
length, read_start, read_end,
page_count); else
error = submit_bio_wait(bio); if (error) goto out_free_bio;
/* * Read and decompress a metadata block or datablock. Length is non-zero * if a datablock is being read (the size is stored elsewhere in the * filesystem), otherwise the length is obtained from the first two bytes of * the metadata block. A bit in the length field indicates if the block * is stored uncompressed in the filesystem (usually because compression * generated a larger block - this does occasionally happen with compression * algorithms).
*/ int squashfs_read_data(struct super_block *sb, u64 index, int length,
u64 *next_index, struct squashfs_page_actor *output)
{ struct squashfs_sb_info *msblk = sb->s_fs_info; struct bio *bio = NULL; int compressed; int res; int offset;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.