Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* -*- linux-c -*- ------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *   
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *   Copyright 2001 H. Peter Anvin - All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * ----------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * linux/fs/isofs/compress.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Transparent decompression of files on an iso9660 filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/bio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/zlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "isofs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "zisofs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) /* This should probably be global. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static char zisofs_sink_page[PAGE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * This contains the zlib memory allocation and the mutex for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * allocation; this avoids failures at block-decompression time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) static void *zisofs_zlib_workspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) static DEFINE_MUTEX(zisofs_zlib_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * Read data of @inode from @block_start to @block_end and uncompress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * to one zisofs block. Store the data in the @pages array with @pcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * entries. Start storing at offset @poffset of the first page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 				      loff_t block_end, int pcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 				      struct page **pages, unsigned poffset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 				      int *errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	unsigned int zisofs_block_shift = ISOFS_I(inode)->i_format_parm[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	unsigned int bufsize = ISOFS_BUFFER_SIZE(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	unsigned int bufshift = ISOFS_BUFFER_BITS(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	unsigned int bufmask = bufsize - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	int i, block_size = block_end - block_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	z_stream stream = { .total_out = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 			    .avail_in = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			    .avail_out = 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	int zerr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	int needblocks = (block_size + (block_start & bufmask) + bufmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 				>> bufshift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	int haveblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	blkcnt_t blocknum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	struct buffer_head **bhs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	int curbh, curpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if (block_size > deflateBound(1UL << zisofs_block_shift)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		*errp = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	/* Empty block? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (block_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		for ( i = 0 ; i < pcount ; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 			if (!pages[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			memset(page_address(pages[i]), 0, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			flush_dcache_page(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			SetPageUptodate(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		return ((loff_t)pcount) << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	/* Because zlib is not thread-safe, do all the I/O at the top. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	blocknum = block_start >> bufshift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	bhs = kcalloc(needblocks + 1, sizeof(*bhs), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	if (!bhs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		*errp = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	haveblocks = isofs_get_blocks(inode, blocknum, bhs, needblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	ll_rw_block(REQ_OP_READ, 0, haveblocks, bhs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	curbh = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	curpage = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	 * First block is special since it may be fractional.  We also wait for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	 * it before grabbing the zlib mutex; odds are that the subsequent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	 * blocks are going to come in in short order so we don't hold the zlib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	 * mutex longer than necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (!bhs[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		goto b_eio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	wait_on_buffer(bhs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	if (!buffer_uptodate(bhs[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		*errp = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		goto b_eio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	stream.workspace = zisofs_zlib_workspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	mutex_lock(&zisofs_zlib_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	zerr = zlib_inflateInit(&stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (zerr != Z_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		if (zerr == Z_MEM_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			*errp = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			*errp = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		printk(KERN_DEBUG "zisofs: zisofs_inflateInit returned %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			       zerr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		goto z_eio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	while (curpage < pcount && curbh < haveblocks &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	       zerr != Z_STREAM_END) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		if (!stream.avail_out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			if (pages[curpage]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 				stream.next_out = page_address(pages[curpage])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 						+ poffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 				stream.avail_out = PAGE_SIZE - poffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 				poffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 				stream.next_out = (void *)&zisofs_sink_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 				stream.avail_out = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		if (!stream.avail_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 			wait_on_buffer(bhs[curbh]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			if (!buffer_uptodate(bhs[curbh])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 				*errp = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 			stream.next_in  = bhs[curbh]->b_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 						(block_start & bufmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 			stream.avail_in = min_t(unsigned, bufsize -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 						(block_start & bufmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 						block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 			block_size -= stream.avail_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			block_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		while (stream.avail_out && stream.avail_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			zerr = zlib_inflate(&stream, Z_SYNC_FLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			if (zerr == Z_BUF_ERROR && stream.avail_in == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			if (zerr == Z_STREAM_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			if (zerr != Z_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 				/* EOF, error, or trying to read beyond end of input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 				if (zerr == Z_MEM_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 					*errp = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 				else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 					printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 					       "zisofs: zisofs_inflate returned"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 					       " %d, inode = %lu,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 					       " page idx = %d, bh idx = %d,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 					       " avail_in = %ld,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 					       " avail_out = %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 					       zerr, inode->i_ino, curpage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 					       curbh, stream.avail_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 					       stream.avail_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 					*errp = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 				goto inflate_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		if (!stream.avail_out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 			/* This page completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			if (pages[curpage]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 				flush_dcache_page(pages[curpage]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 				SetPageUptodate(pages[curpage]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			curpage++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		if (!stream.avail_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 			curbh++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) inflate_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	zlib_inflateEnd(&stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) z_eio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	mutex_unlock(&zisofs_zlib_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) b_eio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	for (i = 0; i < haveblocks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		brelse(bhs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	kfree(bhs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	return stream.total_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  * Uncompress data so that pages[full_page] is fully uptodate and possibly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  * fills in other pages if we have data for them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int zisofs_fill_pages(struct inode *inode, int full_page, int pcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			     struct page **pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	loff_t start_off, end_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	loff_t block_start, block_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	unsigned int header_size = ISOFS_I(inode)->i_format_parm[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	unsigned int zisofs_block_shift = ISOFS_I(inode)->i_format_parm[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	unsigned int blockptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	loff_t poffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	blkcnt_t cstart_block, cend_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	unsigned int blkbits = ISOFS_BUFFER_BITS(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	unsigned int blksize = 1 << blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	loff_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	BUG_ON(!pages[full_page]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	 * We want to read at least 'full_page' page. Because we have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	 * uncompress the whole compression block anyway, fill the surrounding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	 * pages with the data we have anyway...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	start_off = page_offset(pages[full_page]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	end_off = min_t(loff_t, start_off + PAGE_SIZE, inode->i_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	cstart_block = start_off >> zisofs_block_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	cend_block = (end_off + (1 << zisofs_block_shift) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			>> zisofs_block_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	WARN_ON(start_off - (full_page << PAGE_SHIFT) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		((cstart_block << zisofs_block_shift) & PAGE_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	/* Find the pointer to this specific chunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	/* Note: we're not using isonum_731() here because the data is known aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	/* Note: header_size is in 32-bit words (4 bytes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	blockptr = (header_size + cstart_block) << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	bh = isofs_bread(inode, blockptr >> blkbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	block_start = le32_to_cpu(*(__le32 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 				(bh->b_data + (blockptr & (blksize - 1))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	while (cstart_block < cend_block && pcount > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		/* Load end of the compressed block in the file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		blockptr += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		/* Traversed to next block? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		if (!(blockptr & (blksize - 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			bh = isofs_bread(inode, blockptr >> blkbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 				return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		block_end = le32_to_cpu(*(__le32 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 				(bh->b_data + (blockptr & (blksize - 1))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		if (block_start > block_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		ret = zisofs_uncompress_block(inode, block_start, block_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 					      pcount, pages, poffset, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		poffset += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		pages += poffset >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		pcount -= poffset >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		full_page -= poffset >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		poffset &= ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 			 * Did we finish reading the page we really wanted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 			 * to read?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			if (full_page < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		block_start = block_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		cstart_block++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	if (poffset && *pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		memset(page_address(*pages) + poffset, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		       PAGE_SIZE - poffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		flush_dcache_page(*pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		SetPageUptodate(*pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  * When decompressing, we typically obtain more than one page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  * per reference.  We inject the additional pages into the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  * cache as a form of readahead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static int zisofs_readpage(struct file *file, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	struct address_space *mapping = inode->i_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	int i, pcount, full_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	unsigned int zisofs_block_shift = ISOFS_I(inode)->i_format_parm[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	unsigned int zisofs_pages_per_cblock =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		PAGE_SHIFT <= zisofs_block_shift ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		(1 << (zisofs_block_shift - PAGE_SHIFT)) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	pgoff_t index = page->index, end_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	end_index = (inode->i_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	 * If this page is wholly outside i_size we just return zero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	 * do_generic_file_read() will handle this for us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	if (index >= end_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	if (PAGE_SHIFT <= zisofs_block_shift) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		/* We have already been given one page, this is the one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		   we must do. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		full_page = index & (zisofs_pages_per_cblock - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		pcount = min_t(int, zisofs_pages_per_cblock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 			end_index - (index & ~(zisofs_pages_per_cblock - 1)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		index -= full_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		full_page = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		pcount = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	pages = kcalloc(max_t(unsigned int, zisofs_pages_per_cblock, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 					sizeof(*pages), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	if (!pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	pages[full_page] = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	for (i = 0; i < pcount; i++, index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		if (i != full_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			pages[i] = grab_cache_page_nowait(mapping, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		if (pages[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 			ClearPageError(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			kmap(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	err = zisofs_fill_pages(inode, full_page, pcount, pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	/* Release any residual pages, do not SetPageUptodate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	for (i = 0; i < pcount; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		if (pages[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 			flush_dcache_page(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 			if (i == full_page && err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 				SetPageError(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			kunmap(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			unlock_page(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 			if (i != full_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 				put_page(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	}			
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	/* At this point, err contains 0 or -EIO depending on the "critical" page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	kfree(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) const struct address_space_operations zisofs_aops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	.readpage = zisofs_readpage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	/* No bmap operation supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) int __init zisofs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	zisofs_zlib_workspace = vmalloc(zlib_inflate_workspacesize());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	if ( !zisofs_zlib_workspace )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) void zisofs_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	vfree(zisofs_zlib_workspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }