Lines Matching refs:req
79 static int squashfs_bio_submit(struct squashfs_read_request *req);
93 static void free_read_request(struct squashfs_read_request *req, int error) in free_read_request() argument
95 if (!req->synchronous) in free_read_request()
96 squashfs_page_actor_free(req->output, error); in free_read_request()
97 if (req->res) in free_read_request()
98 *(req->res) = error; in free_read_request()
99 kfree(req->bh); in free_read_request()
100 kfree(req); in free_read_request()
103 static void squashfs_process_blocks(struct squashfs_read_request *req) in squashfs_process_blocks() argument
107 struct squashfs_sb_info *msblk = req->sb->s_fs_info; in squashfs_process_blocks()
108 struct squashfs_page_actor *actor = req->output; in squashfs_process_blocks()
109 struct buffer_head **bh = req->bh; in squashfs_process_blocks()
110 int nr_buffers = req->nr_buffers; in squashfs_process_blocks()
122 if (req->data_processing == SQUASHFS_METADATA) { in squashfs_process_blocks()
124 if (req->offset != msblk->devblksize - 1) { in squashfs_process_blocks()
126 (bh[0]->b_data + req->offset)); in squashfs_process_blocks()
128 length = (unsigned char)bh[0]->b_data[req->offset]; in squashfs_process_blocks()
131 req->compressed = SQUASHFS_COMPRESSED(length); in squashfs_process_blocks()
132 req->data_processing = req->compressed ? SQUASHFS_DECOMPRESS in squashfs_process_blocks()
135 if (req->index + length + 2 > req->read_end) { in squashfs_process_blocks()
139 req->length = length; in squashfs_process_blocks()
140 req->index += 2; in squashfs_process_blocks()
141 squashfs_bio_submit(req); in squashfs_process_blocks()
144 req->length = length; in squashfs_process_blocks()
145 req->offset = (req->offset + 2) % PAGE_SIZE; in squashfs_process_blocks()
146 if (req->offset < 2) { in squashfs_process_blocks()
152 if (req->bytes_read) in squashfs_process_blocks()
153 *(req->bytes_read) = req->length; in squashfs_process_blocks()
155 if (req->data_processing == SQUASHFS_COPY) { in squashfs_process_blocks()
156 squashfs_bh_to_actor(bh, nr_buffers, req->output, req->offset, in squashfs_process_blocks()
157 req->length, msblk->devblksize); in squashfs_process_blocks()
158 } else if (req->data_processing == SQUASHFS_DECOMPRESS) { in squashfs_process_blocks()
159 req->length = squashfs_decompress(msblk, bh, nr_buffers, in squashfs_process_blocks()
160 req->offset, req->length, actor); in squashfs_process_blocks()
161 if (req->length < 0) { in squashfs_process_blocks()
168 bytes = req->length % PAGE_SIZE; in squashfs_process_blocks()
174 if (req->bytes_uncompressed) in squashfs_process_blocks()
175 *(req->bytes_uncompressed) = req->length; in squashfs_process_blocks()
181 free_read_request(req, error); in squashfs_process_blocks()
210 static int bh_is_optional(struct squashfs_read_request *req, int idx) in bh_is_optional() argument
213 struct squashfs_sb_info *msblk = req->sb->s_fs_info; in bh_is_optional()
215 start_idx = (idx * msblk->devblksize - req->offset) >> PAGE_SHIFT; in bh_is_optional()
216 end_idx = ((idx + 1) * msblk->devblksize - req->offset + 1) >> PAGE_SHIFT; in bh_is_optional()
217 if (start_idx >= req->output->pages) in bh_is_optional()
221 if (end_idx >= req->output->pages) in bh_is_optional()
223 return !req->output->page[start_idx] && !req->output->page[end_idx]; in bh_is_optional()
226 static int actor_getblks(struct squashfs_read_request *req, u64 block) in actor_getblks() argument
230 req->bh = kmalloc_array(req->nr_buffers, sizeof(*(req->bh)), GFP_NOIO); in actor_getblks()
231 if (!req->bh) in actor_getblks()
234 for (i = 0; i < req->nr_buffers; ++i) { in actor_getblks()
240 if (!req->compressed && bh_is_optional(req, i)) { in actor_getblks()
241 req->bh[i] = NULL; in actor_getblks()
244 req->bh[i] = sb_getblk(req->sb, block + i); in actor_getblks()
245 if (!req->bh[i]) { in actor_getblks()
247 if (req->bh[i]) in actor_getblks()
248 put_bh(req->bh[i]); in actor_getblks()
256 static int squashfs_bio_submit(struct squashfs_read_request *req) in squashfs_bio_submit() argument
262 struct squashfs_sb_info *msblk = req->sb->s_fs_info; in squashfs_bio_submit()
264 u64 read_start = round_down(req->index, msblk->devblksize); in squashfs_bio_submit()
265 u64 read_end = round_up(req->index + req->length, msblk->devblksize); in squashfs_bio_submit()
268 int offset = read_start - round_down(req->index, PAGE_SIZE); in squashfs_bio_submit()
275 req->read_end = read_end; in squashfs_bio_submit()
276 req->offset = req->index - read_start; in squashfs_bio_submit()
277 req->nr_buffers = nr_buffers; in squashfs_bio_submit()
278 if (actor_getblks(req, block) < 0) in squashfs_bio_submit()
283 bh = req->bh[b]; in squashfs_bio_submit()
308 bio_req->bh = &req->bh[b]; in squashfs_bio_submit()
312 bio->bi_bdev = req->sb->s_bdev; in squashfs_bio_submit()
326 if (req->synchronous) in squashfs_bio_submit()
327 squashfs_process_blocks(req); in squashfs_bio_submit()
329 INIT_WORK(&req->offload, read_wq_handler); in squashfs_bio_submit()
330 schedule_work(&req->offload); in squashfs_bio_submit()
339 if (req->bh[nr_buffers]) in squashfs_bio_submit()
340 put_bh(req->bh[nr_buffers]); in squashfs_bio_submit()
342 if (req->bh[b]) in squashfs_bio_submit()
343 wait_on_buffer(req->bh[b]); in squashfs_bio_submit()
345 free_read_request(req, -ENOMEM); in squashfs_bio_submit()
349 static int read_metadata_block(struct squashfs_read_request *req, in read_metadata_block() argument
353 struct squashfs_sb_info *msblk = req->sb->s_fs_info; in read_metadata_block()
355 if (req->index + 2 > msblk->bytes_used) { in read_metadata_block()
356 free_read_request(req, -EINVAL); in read_metadata_block()
359 req->length = 2; in read_metadata_block()
362 if (req->index + req->length > msblk->bytes_used) in read_metadata_block()
363 req->length = msblk->bytes_used - req->index; in read_metadata_block()
364 req->data_processing = SQUASHFS_METADATA; in read_metadata_block()
371 req->synchronous = true; in read_metadata_block()
372 req->res = &error; in read_metadata_block()
373 req->bytes_read = &bytes_read; in read_metadata_block()
374 req->bytes_uncompressed = &bytes_uncompressed; in read_metadata_block()
377 req->index, req->compressed ? "" : "un", bytes_read, in read_metadata_block()
378 req->output->length); in read_metadata_block()
380 ret = squashfs_bio_submit(req); in read_metadata_block()
390 static int read_data_block(struct squashfs_read_request *req, int length, in read_data_block() argument
395 req->compressed = SQUASHFS_COMPRESSED_BLOCK(length); in read_data_block()
396 req->length = length = SQUASHFS_COMPRESSED_SIZE_BLOCK(length); in read_data_block()
397 req->data_processing = req->compressed ? SQUASHFS_DECOMPRESS in read_data_block()
400 req->synchronous = synchronous; in read_data_block()
402 req->res = &error; in read_data_block()
403 req->bytes_read = &bytes_read; in read_data_block()
404 req->bytes_uncompressed = &bytes_uncompressed; in read_data_block()
408 req->index, req->compressed ? "" : "un", req->length, in read_data_block()
409 req->output->length); in read_data_block()
411 ret = squashfs_bio_submit(req); in read_data_block()
433 struct squashfs_read_request *req; in __squashfs_read_data() local
435 req = kcalloc(1, sizeof(struct squashfs_read_request), GFP_KERNEL); in __squashfs_read_data()
436 if (!req) { in __squashfs_read_data()
442 req->sb = sb; in __squashfs_read_data()
443 req->index = index; in __squashfs_read_data()
444 req->output = output; in __squashfs_read_data()
450 length = read_data_block(req, length, next_index, sync); in __squashfs_read_data()
452 length = read_metadata_block(req, next_index); in __squashfs_read_data()