Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 966a0f11 authored by Daniel Rosenberg's avatar Daniel Rosenberg
Browse files

Revert "ANDROID: Squashfs: refactor page_actor"



This reverts commit 6fb5cb07.

Signed-off-by: default avatarDaniel Rosenberg <drosen@google.com>
Change-Id: I1ff145cc6ea42ab36bef932b6c441e22cf8a834c
parent e3768e47
Loading
Loading
Loading
Loading
+44 −29
Original line number Diff line number Diff line
@@ -209,14 +209,17 @@ void squashfs_cache_put(struct squashfs_cache_entry *entry)
 */
void squashfs_cache_delete(struct squashfs_cache *cache)
{
	int i;
	int i, j;

	if (cache == NULL)
		return;

	for (i = 0; i < cache->entries; i++) {
		if (cache->entry[i].page)
			free_page_array(cache->entry[i].page, cache->pages);
		if (cache->entry[i].data) {
			for (j = 0; j < cache->pages; j++)
				kfree(cache->entry[i].data[j]);
			kfree(cache->entry[i].data);
		}
		kfree(cache->entry[i].actor);
	}

@@ -233,7 +236,7 @@ void squashfs_cache_delete(struct squashfs_cache *cache)
struct squashfs_cache *squashfs_cache_init(char *name, int entries,
	int block_size)
{
	int i;
	int i, j;
	struct squashfs_cache *cache = kzalloc(sizeof(*cache), GFP_KERNEL);

	if (cache == NULL) {
@@ -265,13 +268,22 @@ struct squashfs_cache *squashfs_cache_init(char *name, int entries,
		init_waitqueue_head(&cache->entry[i].wait_queue);
		entry->cache = cache;
		entry->block = SQUASHFS_INVALID_BLK;
		entry->page = alloc_page_array(cache->pages, GFP_KERNEL);
		if (!entry->page) {
		entry->data = kcalloc(cache->pages, sizeof(void *), GFP_KERNEL);
		if (entry->data == NULL) {
			ERROR("Failed to allocate %s cache entry\n", name);
			goto cleanup;
		}
		entry->actor = squashfs_page_actor_init(entry->page,
			cache->pages, 0, NULL);

		for (j = 0; j < cache->pages; j++) {
			entry->data[j] = kmalloc(PAGE_SIZE, GFP_KERNEL);
			if (entry->data[j] == NULL) {
				ERROR("Failed to allocate %s buffer\n", name);
				goto cleanup;
			}
		}

		entry->actor = squashfs_page_actor_init(entry->data,
						cache->pages, 0);
		if (entry->actor == NULL) {
			ERROR("Failed to allocate %s cache entry\n", name);
			goto cleanup;
@@ -302,20 +314,18 @@ int squashfs_copy_data(void *buffer, struct squashfs_cache_entry *entry,
		return min(length, entry->length - offset);

	while (offset < entry->length) {
		void *buff = kmap_atomic(entry->page[offset / PAGE_SIZE])
		void *buff = entry->data[offset / PAGE_SIZE]
				+ (offset % PAGE_SIZE);
		int bytes = min_t(int, entry->length - offset,
				PAGE_SIZE - (offset % PAGE_SIZE));

		if (bytes >= remaining) {
			memcpy(buffer, buff, remaining);
			kunmap_atomic(buff);
			remaining = 0;
			break;
		}

		memcpy(buffer, buff, bytes);
		kunmap_atomic(buff);
		buffer += bytes;
		remaining -= bytes;
		offset += bytes;
@@ -406,38 +416,43 @@ struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *sb,
void *squashfs_read_table(struct super_block *sb, u64 block, int length)
{
	int pages = (length + PAGE_SIZE - 1) >> PAGE_SHIFT;
	struct page **page;
	void *buff;
	int res;
	int i, res;
	void *table, *buffer, **data;
	struct squashfs_page_actor *actor;

	page = alloc_page_array(pages, GFP_KERNEL);
	if (!page)
	table = buffer = kmalloc(length, GFP_KERNEL);
	if (table == NULL)
		return ERR_PTR(-ENOMEM);

	actor = squashfs_page_actor_init(page, pages, length, NULL);
	if (actor == NULL) {
	data = kcalloc(pages, sizeof(void *), GFP_KERNEL);
	if (data == NULL) {
		res = -ENOMEM;
		goto failed;
	}

	actor = squashfs_page_actor_init(data, pages, length);
	if (actor == NULL) {
		res = -ENOMEM;
		goto failed2;
	}

	for (i = 0; i < pages; i++, buffer += PAGE_SIZE)
		data[i] = buffer;

	res = squashfs_read_data(sb, block, length |
		SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, actor);

	kfree(data);
	kfree(actor);

	if (res < 0)
		goto failed2;
		goto failed;

	buff = kmalloc(length, GFP_KERNEL);
	if (!buff)
		goto failed2;
	squashfs_actor_to_buf(actor, buff, length);
	squashfs_page_actor_free(actor, 0);
	free_page_array(page, pages);
	return buff;
	return table;

failed2:
	squashfs_page_actor_free(actor, 0);
	kfree(data);
failed:
	free_page_array(page, pages);
	kfree(table);
	return ERR_PTR(res);
}
+25 −30
Original line number Diff line number Diff line
@@ -24,8 +24,7 @@
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/fs.h>
#include <linux/buffer_head.h>

#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
@@ -102,26 +101,24 @@ const struct squashfs_decompressor *squashfs_lookup_decompressor(int id)
static void *get_comp_opts(struct super_block *sb, unsigned short flags)
{
	struct squashfs_sb_info *msblk = sb->s_fs_info;
	void *comp_opts, *buffer = NULL;
	struct page *page;
	void *buffer = NULL, *comp_opts;
	struct squashfs_page_actor *actor = NULL;
	int length = 0;

	if (!SQUASHFS_COMP_OPTS(flags))
		return squashfs_comp_opts(msblk, buffer, length);

	/*
	 * Read decompressor specific options from file system if present
	 */
	if (SQUASHFS_COMP_OPTS(flags)) {
		buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
		if (buffer == NULL) {
			comp_opts = ERR_PTR(-ENOMEM);
			goto out;
		}

	page = alloc_page(GFP_KERNEL);
	if (!page)
		return ERR_PTR(-ENOMEM);

	actor = squashfs_page_actor_init(&page, 1, 0, NULL);
		actor = squashfs_page_actor_init(&buffer, 1, 0);
		if (actor == NULL) {
			comp_opts = ERR_PTR(-ENOMEM);
		goto actor_error;
			goto out;
		}

		length = squashfs_read_data(sb,
@@ -129,17 +126,15 @@ static void *get_comp_opts(struct super_block *sb, unsigned short flags)

		if (length < 0) {
			comp_opts = ERR_PTR(length);
		goto read_error;
			goto out;
		}
	}

	buffer = kmap_atomic(page);
	comp_opts = squashfs_comp_opts(msblk, buffer, length);
	kunmap_atomic(buffer);

read_error:
	squashfs_page_actor_free(actor, 0);
actor_error:
	__free_page(page);
out:
	kfree(actor);
	kfree(buffer);
	return comp_opts;
}

+2 −2
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ int squashfs_readpage_block(struct page *target_page, u64 block, int bsize)
	 * Create a "page actor" which will kmap and kunmap the
	 * page cache pages appropriately within the decompressor
	 */
	actor = squashfs_page_actor_init(page, pages, 0, NULL);
	actor = squashfs_page_actor_init_special(page, pages, 0);
	if (actor == NULL)
		goto out;

@@ -131,7 +131,7 @@ int squashfs_readpage_block(struct page *target_page, u64 block, int bsize)
	}

out:
	squashfs_page_actor_free(actor, 0);
	kfree(actor);
	kfree(page);
	return res;
}
+25 −4
Original line number Diff line number Diff line
@@ -94,18 +94,39 @@ static int lz4_uncompress(struct squashfs_sb_info *msblk, void *strm,
	struct buffer_head **bh, int b, int offset, int length,
	struct squashfs_page_actor *output)
{
	int res;
	struct squashfs_lz4 *stream = strm;
	void *buff = stream->input, *data;
	int avail, i, bytes = length, res;

	for (i = 0; i < b; i++) {
		avail = min(bytes, msblk->devblksize - offset);
		memcpy(buff, bh[i]->b_data + offset, avail);
		buff += avail;
		bytes -= avail;
		offset = 0;
		put_bh(bh[i]);
	}

	squashfs_bh_to_buf(bh, b, stream->input, offset, length,
		msblk->devblksize);
	res = LZ4_decompress_safe(stream->input, stream->output,
		length, output->length);

	if (res < 0)
		return -EIO;

	squashfs_buf_to_actor(stream->output, output, res);
	bytes = res;
	data = squashfs_first_page(output);
	buff = stream->output;
	while (data) {
		if (bytes <= PAGE_SIZE) {
			memcpy(data, buff, bytes);
			break;
		}
		memcpy(data, buff, PAGE_SIZE);
		buff += PAGE_SIZE;
		bytes -= PAGE_SIZE;
		data = squashfs_next_page(output);
	}
	squashfs_finish_page(output);

	return res;
}
+33 −7
Original line number Diff line number Diff line
@@ -79,19 +79,45 @@ static int lzo_uncompress(struct squashfs_sb_info *msblk, void *strm,
	struct buffer_head **bh, int b, int offset, int length,
	struct squashfs_page_actor *output)
{
	int res;
	size_t out_len = output->length;
	struct squashfs_lzo *stream = strm;
	void *buff = stream->input, *data;
	int avail, i, bytes = length, res;
	size_t out_len = output->length;

	for (i = 0; i < b; i++) {
		avail = min(bytes, msblk->devblksize - offset);
		memcpy(buff, bh[i]->b_data + offset, avail);
		buff += avail;
		bytes -= avail;
		offset = 0;
		put_bh(bh[i]);
	}

	squashfs_bh_to_buf(bh, b, stream->input, offset, length,
		msblk->devblksize);
	res = lzo1x_decompress_safe(stream->input, (size_t)length,
					stream->output, &out_len);
	if (res != LZO_E_OK)
		return -EIO;
	squashfs_buf_to_actor(stream->output, output, out_len);
		goto failed;

	return out_len;
	res = bytes = (int)out_len;
	data = squashfs_first_page(output);
	buff = stream->output;
	while (data) {
		if (bytes <= PAGE_SIZE) {
			memcpy(data, buff, bytes);
			break;
		} else {
			memcpy(data, buff, PAGE_SIZE);
			buff += PAGE_SIZE;
			bytes -= PAGE_SIZE;
			data = squashfs_next_page(output);
		}
	}
	squashfs_finish_page(output);

	return res;

failed:
	return -EIO;
}

const struct squashfs_decompressor squashfs_lzo_comp_ops = {
Loading