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

Commit b89fd787 authored by Daniel Rosenberg's avatar Daniel Rosenberg
Browse files

Revert "ANDROID: Squashfs: implement .readpages()"



This reverts commit 34193964.

Signed-off-by: default avatarDaniel Rosenberg <drosen@google.com>
Change-Id: If39827ce9ccf721e320a9cd0fe4c1f17e5b76aba
parent 6659b435
Loading
Loading
Loading
Loading
+35 −102
Original line number Diff line number Diff line
@@ -47,7 +47,6 @@
#include <linux/string.h>
#include <linux/pagemap.h>
#include <linux/mutex.h>
#include <linux/mm_inline.h>

#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
@@ -439,21 +438,6 @@ static int squashfs_readpage_fragment(struct page *page)
	return res;
}

static int squashfs_readpages_fragment(struct page *page,
	struct list_head *readahead_pages, struct address_space *mapping)
{
	if (!page) {
		page = lru_to_page(readahead_pages);
		list_del(&page->lru);
		if (add_to_page_cache_lru(page, mapping, page->index,
			mapping_gfp_constraint(mapping, GFP_KERNEL))) {
			put_page(page);
			return 0;
		}
	}
	return squashfs_readpage_fragment(page);
}

static int squashfs_readpage_sparse(struct page *page, int index, int file_end)
{
	struct inode *inode = page->mapping->host;
@@ -466,105 +450,54 @@ static int squashfs_readpage_sparse(struct page *page, int index, int file_end)
	return 0;
}

static int squashfs_readpages_sparse(struct page *page,
	struct list_head *readahead_pages, int index, int file_end,
	struct address_space *mapping)
{
	if (!page) {
		page = lru_to_page(readahead_pages);
		list_del(&page->lru);
		if (add_to_page_cache_lru(page, mapping, page->index,
			mapping_gfp_constraint(mapping, GFP_KERNEL))) {
			put_page(page);
			return 0;
		}
	}
	return squashfs_readpage_sparse(page, index, file_end);
}

static int __squashfs_readpages(struct file *file, struct page *page,
	struct list_head *readahead_pages, unsigned int nr_pages,
	struct address_space *mapping)
static int squashfs_readpage(struct file *file, struct page *page)
{
	struct inode *inode = mapping->host;
	struct inode *inode = page->mapping->host;
	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
	int index = page->index >> (msblk->block_log - PAGE_SHIFT);
	int file_end = i_size_read(inode) >> msblk->block_log;
	int res;
	void *pageaddr;

	do {
		struct page *cur_page = page ? page
					     : lru_to_page(readahead_pages);
		int page_index = cur_page->index;
		int index = page_index >> (msblk->block_log - PAGE_SHIFT);
	TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
				page->index, squashfs_i(inode)->start);

		if (page_index >= ((i_size_read(inode) + PAGE_SIZE - 1) >>
	if (page->index >= ((i_size_read(inode) + PAGE_SIZE - 1) >>
					PAGE_SHIFT))
			return 1;
		goto out;

	if (index < file_end || squashfs_i(inode)->fragment_block ==
					SQUASHFS_INVALID_BLK) {
		u64 block = 0;
		int bsize = read_blocklist(inode, index, &block);

		if (bsize < 0)
				return -1;
			goto error_out;

			if (bsize == 0) {
				res = squashfs_readpages_sparse(page,
					readahead_pages, index, file_end,
					mapping);
			} else {
				res = squashfs_readpages_block(page,
					readahead_pages, &nr_pages, mapping,
					page_index, block, bsize);
			}
		} else {
			res = squashfs_readpages_fragment(page,
				readahead_pages, mapping);
		}
		if (res)
			return 0;
		page = NULL;
	} while (readahead_pages && !list_empty(readahead_pages));
		if (bsize == 0)
			res = squashfs_readpage_sparse(page, index, file_end);
		else
			res = squashfs_readpage_block(page, block, bsize);
	} else
		res = squashfs_readpage_fragment(page);

	if (!res)
		return 0;
}

static int squashfs_readpage(struct file *file, struct page *page)
{
	int ret;

	TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
	      page->index, squashfs_i(page->mapping->host)->start);

	get_page(page);

	ret = __squashfs_readpages(file, page, NULL, 1, page->mapping);
	if (ret) {
		flush_dcache_page(page);
		if (ret < 0)
error_out:
	SetPageError(page);
		else
out:
	pageaddr = kmap_atomic(page);
	memset(pageaddr, 0, PAGE_SIZE);
	kunmap_atomic(pageaddr);
	flush_dcache_page(page);
	if (!PageError(page))
		SetPageUptodate(page);
		zero_user_segment(page, 0, PAGE_SIZE);
	unlock_page(page);
		put_page(page);
	}

	return 0;
}

static int squashfs_readpages(struct file *file, struct address_space *mapping,
			      struct list_head *pages, unsigned int nr_pages)
{
	TRACE("Entered squashfs_readpages, %u pages, first page index %lx\n",
		nr_pages, lru_to_page(pages)->index);
	__squashfs_readpages(file, NULL, pages, nr_pages, mapping);
	return 0;
}


const struct address_space_operations squashfs_aops = {
	.readpage = squashfs_readpage,
	.readpages = squashfs_readpages,
	.readpage = squashfs_readpage
};
+21 −41
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@
#include <linux/string.h>
#include <linux/pagemap.h>
#include <linux/mutex.h>
#include <linux/mm_inline.h>

#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
@@ -46,40 +45,23 @@ static void release_actor_pages(struct page **page, int pages, int error)
 * page cache pages appropriately within the decompressor
 */
static struct squashfs_page_actor *actor_from_page_cache(
	unsigned int actor_pages, struct page *target_page,
	struct list_head *rpages, unsigned int *nr_pages, int start_index,
	struct address_space *mapping)
	struct page *target_page, int start_index, int nr_pages)
{
	int i, n;
	struct page **page;
	struct squashfs_page_actor *actor;
	int i, n;
	gfp_t gfp = mapping_gfp_constraint(mapping, GFP_KERNEL);

	page = kmalloc_array(actor_pages, sizeof(void *), GFP_KERNEL);
	page = kmalloc_array(nr_pages, sizeof(void *), GFP_KERNEL);
	if (!page)
		return NULL;

	for (i = 0, n = start_index; i < actor_pages; i++, n++) {
		if (target_page == NULL && rpages && !list_empty(rpages)) {
			struct page *cur_page = lru_to_page(rpages);

			if (cur_page->index < start_index + actor_pages) {
				list_del(&cur_page->lru);
				--(*nr_pages);
				if (add_to_page_cache_lru(cur_page, mapping,
							  cur_page->index, gfp))
					put_page(cur_page);
				else
					target_page = cur_page;
			} else
				rpages = NULL;
		}

		if (target_page && target_page->index == n) {
	/* Try to grab all the pages covered by the SquashFS block */
	for (i = 0, n = start_index; i < nr_pages; i++, n++) {
		if (target_page->index == n) {
			page[i] = target_page;
			target_page = NULL;
		} else {
			page[i] = grab_cache_page_nowait(mapping, n);
			page[i] = grab_cache_page_nowait(target_page->mapping,
							 n);
			if (page[i] == NULL)
				continue;
		}
@@ -91,42 +73,40 @@ static struct squashfs_page_actor *actor_from_page_cache(
		}
	}

	actor = squashfs_page_actor_init(page, actor_pages, 0,
	actor = squashfs_page_actor_init(page, nr_pages, 0,
			release_actor_pages);
	if (!actor) {
		release_actor_pages(page, actor_pages, -ENOMEM);
		release_actor_pages(page, nr_pages, -ENOMEM);
		kfree(page);
		return NULL;
	}
	return actor;
}

int squashfs_readpages_block(struct page *target_page,
			     struct list_head *readahead_pages,
			     unsigned int *nr_pages,
			     struct address_space *mapping,
			     int page_index, u64 block, int bsize)
/* Read separately compressed datablock directly into page cache */
int squashfs_readpage_block(struct page *target_page, u64 block, int bsize)

{
	struct squashfs_page_actor *actor;
	struct inode *inode = mapping->host;
	struct inode *inode = target_page->mapping->host;
	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;

	int file_end = (i_size_read(inode) - 1) >> PAGE_SHIFT;
	int mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1;
	int start_index = page_index & ~mask;
	int start_index = target_page->index & ~mask;
	int end_index = start_index | mask;
	int actor_pages, res;
	int pages, res = -ENOMEM;
	struct squashfs_page_actor *actor;

	if (end_index > file_end)
		end_index = file_end;
	actor_pages = end_index - start_index + 1;
	pages = end_index - start_index + 1;

	actor = actor_from_page_cache(target_page, start_index, pages);

	actor = actor_from_page_cache(actor_pages, target_page,
				      readahead_pages, nr_pages, start_index,
				      mapping);
	if (!actor)
		return -ENOMEM;

	get_page(target_page);
	res = squashfs_read_data_async(inode->i_sb, block, bsize, NULL,
				       actor);
	return res < 0 ? res : 0;
+2 −3
Original line number Diff line number Diff line
@@ -74,9 +74,8 @@ extern __le64 *squashfs_read_fragment_index_table(struct super_block *,
void squashfs_copy_cache(struct page *, struct squashfs_cache_entry *, int,
				int);

/* file_direct.c */
extern int squashfs_readpages_block(struct page *, struct list_head *,
	unsigned int *, struct address_space *, int, u64, int);
/* file_xxx.c */
extern int squashfs_readpage_block(struct page *, u64, int);

/* id.c */
extern int squashfs_get_id(struct super_block *, unsigned int, unsigned int *);