fs/isofs/compress.c

Source file repositories/reference/linux-study-clean/fs/isofs/compress.c

File Facts

System
Linux kernel
Corpus path
fs/isofs/compress.c
Extension
.c
Size
10117 bytes
Lines
384
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!stream.avail_out) {
			if (pages[curpage]) {
				stream.next_out = kmap_local_page(pages[curpage])
						+ poffset;
				stream.avail_out = PAGE_SIZE - poffset;
				poffset = 0;
			} else {
				stream.next_out = (void *)&zisofs_sink_page;
				stream.avail_out = PAGE_SIZE;
			}
		}
		if (!stream.avail_in) {
			wait_on_buffer(bhs[curbh]);
			if (!buffer_uptodate(bhs[curbh])) {
				*errp = -EIO;
				break;
			}
			stream.next_in  = bhs[curbh]->b_data +
						(block_start & bufmask);
			stream.avail_in = min_t(unsigned, bufsize -
						(block_start & bufmask),
						block_size);
			block_size -= stream.avail_in;
			block_start = 0;
		}

		while (stream.avail_out && stream.avail_in) {
			zerr = zlib_inflate(&stream, Z_SYNC_FLUSH);
			if (zerr == Z_BUF_ERROR && stream.avail_in == 0)
				break;
			if (zerr == Z_STREAM_END)
				break;
			if (zerr != Z_OK) {
				/* EOF, error, or trying to read beyond end of input */
				if (zerr == Z_MEM_ERROR)
					*errp = -ENOMEM;
				else {
					printk(KERN_DEBUG
					       "zisofs: zisofs_inflate returned"
					       " %d, inode = %llu,"
					       " page idx = %d, bh idx = %d,"
					       " avail_in = %ld,"
					       " avail_out = %ld\n",
					       zerr, inode->i_ino, curpage,
					       curbh, stream.avail_in,
					       stream.avail_out);
					*errp = -EIO;
				}
				goto inflate_out;
			}
		}

		if (!stream.avail_out) {
			/* This page completed */
			if (pages[curpage]) {
				flush_dcache_page(pages[curpage]);
				SetPageUptodate(pages[curpage]);
			}
			if (stream.next_out != (unsigned char *)zisofs_sink_page) {
				kunmap_local(stream.next_out);
				stream.next_out = NULL;
			}
			curpage++;
		}
		if (!stream.avail_in)
			curbh++;
	}
inflate_out:
	zlib_inflateEnd(&stream);
	if (stream.next_out && stream.next_out != (unsigned char *)zisofs_sink_page)
		kunmap_local(stream.next_out);

z_eio:
	mutex_unlock(&zisofs_zlib_lock);

b_eio:
	for (i = 0; i < haveblocks; i++)
		brelse(bhs[i]);
	kfree(bhs);
	return stream.total_out;
}

/*
 * Uncompress data so that pages[full_page] is fully uptodate and possibly
 * fills in other pages if we have data for them.
 */
static int zisofs_fill_pages(struct inode *inode, int full_page, int pcount,
			     struct page **pages)
{
	loff_t start_off, end_off;

Annotation

Implementation Notes