/*
 * Squashfs - a compressed read only filesystem for Linux
 *
 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
 * Phillip Lougher <phillip@squashfs.org.uk>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2,
 * or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * block.c
 */

/*
 * This file implements the low-level routines to read and decompress
 * datablocks and metadata blocks.
 */

#include <linux/fs.h>
#include <linux/vfs.h>
#include <linux/bio.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/workqueue.h>

#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
#include "squashfs.h"
#include "decompressor.h"
#include "page_actor.h"

static struct workqueue_struct *squashfs_read_wq;

struct squashfs_read_request {
	struct super_block *sb;
	u64 index;
	int length;
	int compressed;
	int offset;
	u64 read_end;
	struct squashfs_page_actor *output;
	enum {
		SQUASHFS_COPY,
		SQUASHFS_DECOMPRESS,
		SQUASHFS_METADATA,
	} data_processing;
	bool synchronous;

	/*
	 * If the read is synchronous, it is possible to retrieve information
	 * about the request by setting these pointers.
	 */
	int *res;
	int *bytes_read;
	int *bytes_uncompressed;

	int nr_buffers;
	struct buffer_head **bh;
	struct work_struct offload;
};

struct squashfs_bio_request {
	struct buffer_head **bh;
	int nr_buffers;
};

static int squashfs_bio_submit(struct squashfs_read_request *req);

int squashfs_init_read_wq(void)
{
	squashfs_read_wq = create_workqueue("SquashFS read wq");
	return !!squashfs_read_wq;
}

void squashfs_destroy_read_wq(void)
{
	flush_workqueue(squashfs_read_wq);
	destroy_workqueue(squashfs_read_wq);
}

static void free_read_request(struct squashfs_read_request *req, int error)
{
	if (!req->synchronous)
		squashfs_page_actor_free(req->output, error);
	if (req->res)
		*(req->res) = error;
	kfree(req->bh);
	kfree(req);
}

static void squashfs_process_blocks(struct squashfs_read_request *req)
{
	int error = 0;
	int bytes, i, length;
	struct squashfs_sb_info *msblk = req->sb->s_fs_info;
	struct squashfs_page_actor *actor = req->output;
	struct buffer_head **bh = req->bh;
	int nr_buffers = req->nr_buffers;

	for (i = 0; i < nr_buffers; ++i) {
		if (!bh[i])
			continue;
		wait_on_buffer(bh[i]);
		if (!buffer_uptodate(bh[i]))
			error = -EIO;
	}
	if (error)
		goto cleanup;

	if (req->data_processing == SQUASHFS_METADATA) {
		/* Extract the length of the metadata block */
		if (req->offset != msblk->devblksize - 1) {
			length = le16_to_cpup((__le16 *)
					(bh[0]->b_data + req->offset));
		} else {
			length = (unsigned char)bh[0]->b_data[req->offset];
			length |= (unsigned char)bh[1]->b_data[0] << 8;
		}
		req->compressed = SQUASHFS_COMPRESSED(length);
		req->data_processing = req->compressed ? SQUASHFS_DECOMPRESS
						       : SQUASHFS_COPY;
		length = SQUASHFS_COMPRESSED_SIZE(length);
		if (req->index + length + 2 > req->read_end) {
			for (i = 0; i < nr_buffers; ++i)
				put_bh(bh[i]);
			kfree(bh);
			req->length = length;
			req->index += 2;
			squashfs_bio_submit(req);
			return;
		}
		req->length = length;
		req->offset = (req->offset + 2) % PAGE_SIZE;
		if (req->offset < 2) {
			put_bh(bh[0]);
			++bh;
			--nr_buffers;
		}
	}
	if (req->bytes_read)
		*(req->bytes_read) = req->length;

	if (req->data_processing == SQUASHFS_COPY) {
		squashfs_bh_to_actor(bh, nr_buffers, req->output, req->offset,
			req->length, msblk->devblksize);
	} else if (req->data_processing == SQUASHFS_DECOMPRESS) {
		req->length = squashfs_decompress(msblk, bh, nr_buffers,
			req->offset, req->length, actor);
		if (req->length < 0) {
			error = -EIO;
			goto cleanup;
		}
	}

	/* Last page may have trailing bytes not filled */
	bytes = req->length % PAGE_SIZE;
	if (bytes && actor->page[actor->pages - 1])
		zero_user_segment(actor->page[actor->pages - 1], bytes,
				  PAGE_SIZE);

cleanup:
	if (req->bytes_uncompressed)
		*(req->bytes_uncompressed) = req->length;
	if (error) {
		for (i = 0; i < nr_buffers; ++i)
			if (bh[i])
				put_bh(bh[i]);
	}
	free_read_request(req, error);
}

static void read_wq_handler(struct work_struct *work)
{
	squashfs_process_blocks(container_of(work,
		    struct squashfs_read_request, offload));
}

static void squashfs_bio_end_io(struct bio *bio)
{
	int i;
	int error = bio->bi_error;
	struct squashfs_bio_request *bio_req = bio->bi_private;

	bio_put(bio);

	for (i = 0; i < bio_req->nr_buffers; ++i) {
		if (!bio_req->bh[i])
			continue;
		if (!error)
			set_buffer_uptodate(bio_req->bh[i]);
		else
			clear_buffer_uptodate(bio_req->bh[i]);
		unlock_buffer(bio_req->bh[i]);
	}
	kfree(bio_req);
}

static int bh_is_optional(struct squashfs_read_request *req, int idx)
{
	int start_idx, end_idx;
	struct squashfs_sb_info *msblk = req->sb->s_fs_info;

	start_idx = (idx * msblk->devblksize - req->offset) >> PAGE_SHIFT;
	end_idx = ((idx + 1) * msblk->devblksize - req->offset + 1) >> PAGE_SHIFT;
	if (start_idx >= req->output->pages)
		return 1;
	if (start_idx < 0)
		start_idx = end_idx;
	if (end_idx >= req->output->pages)
		end_idx = start_idx;
	return !req->output->page[start_idx] && !req->output->page[end_idx];
}

static int actor_getblks(struct squashfs_read_request *req, u64 block)
{
	int i;

	req->bh = kmalloc_array(req->nr_buffers, sizeof(*(req->bh)), GFP_NOIO);
	if (!req->bh)
		return -ENOMEM;

	for (i = 0; i < req->nr_buffers; ++i) {
		/*
		 * When dealing with an uncompressed block, the actor may
		 * contains NULL pages. There's no need to read the buffers
		 * associated with these pages.
		 */
		if (!req->compressed && bh_is_optional(req, i)) {
			req->bh[i] = NULL;
			continue;
		}
		req->bh[i] = sb_getblk(req->sb, block + i);
		if (!req->bh[i]) {
			while (--i) {
				if (req->bh[i])
					put_bh(req->bh[i]);
			}
			return -1;
		}
	}
	return 0;
}

static int squashfs_bio_submit(struct squashfs_read_request *req)
{
	struct bio *bio = NULL;
	struct buffer_head *bh;
	struct squashfs_bio_request *bio_req = NULL;
	int b = 0, prev_block = 0;
	struct squashfs_sb_info *msblk = req->sb->s_fs_info;

	u64 read_start = round_down(req->index, msblk->devblksize);
	u64 read_end = round_up(req->index + req->length, msblk->devblksize);
	sector_t block = read_start >> msblk->devblksize_log2;
	sector_t block_end = read_end >> msblk->devblksize_log2;
	int offset = read_start - round_down(req->index, PAGE_SIZE);
	int nr_buffers = block_end - block;
	int blksz = msblk->devblksize;
	int bio_max_pages = nr_buffers > BIO_MAX_PAGES ? BIO_MAX_PAGES
						       : nr_buffers;

	/* Setup the request */
	req->read_end = read_end;
	req->offset = req->index - read_start;
	req->nr_buffers = nr_buffers;
	if (actor_getblks(req, block) < 0)
		goto getblk_failed;

	/* Create and submit the BIOs */
	for (b = 0; b < nr_buffers; ++b, offset += blksz) {
		bh = req->bh[b];
		if (!bh || !trylock_buffer(bh))
			continue;
		if (buffer_uptodate(bh)) {
			unlock_buffer(bh);
			continue;
		}
		offset %= PAGE_SIZE;

		/* Append the buffer to the current BIO if it is contiguous */
		if (bio && bio_req && prev_block + 1 == b) {
			if (bio_add_page(bio, bh->b_page, blksz, offset)) {
				bio_req->nr_buffers += 1;
				prev_block = b;
				continue;
			}
		}

		/* Otherwise, submit the current BIO and create a new one */
		if (bio)
			submit_bio(READ, bio);
		bio_req = kcalloc(1, sizeof(struct squashfs_bio_request),
				  GFP_NOIO);
		if (!bio_req)
			goto req_alloc_failed;
		bio_req->bh = &req->bh[b];
		bio = bio_alloc(GFP_NOIO, bio_max_pages);
		if (!bio)
			goto bio_alloc_failed;
		bio->bi_bdev = req->sb->s_bdev;
		bio->bi_iter.bi_sector = (block + b)
				       << (msblk->devblksize_log2 - 9);
		bio->bi_private = bio_req;
		bio->bi_end_io = squashfs_bio_end_io;

		bio_add_page(bio, bh->b_page, blksz, offset);
		bio_req->nr_buffers += 1;
		prev_block = b;
	}
	if (bio)
		submit_bio(READ, bio);

	if (req->synchronous)
		squashfs_process_blocks(req);
	else {
		INIT_WORK(&req->offload, read_wq_handler);
		schedule_work(&req->offload);
	}
	return 0;

bio_alloc_failed:
	kfree(bio_req);
req_alloc_failed:
	unlock_buffer(bh);
	while (--nr_buffers >= b)
		if (req->bh[nr_buffers])
			put_bh(req->bh[nr_buffers]);
	while (--b >= 0)
		if (req->bh[b])
			wait_on_buffer(req->bh[b]);
getblk_failed:
	free_read_request(req, -ENOMEM);
	return -ENOMEM;
}

static int read_metadata_block(struct squashfs_read_request *req,
			       u64 *next_index)
{
	int ret, error, bytes_read = 0, bytes_uncompressed = 0;
	struct squashfs_sb_info *msblk = req->sb->s_fs_info;

	if (req->index + 2 > msblk->bytes_used) {
		free_read_request(req, -EINVAL);
		return -EINVAL;
	}
	req->length = 2;

	/* Do not read beyond the end of the device */
	if (req->index + req->length > msblk->bytes_used)
		req->length = msblk->bytes_used - req->index;
	req->data_processing = SQUASHFS_METADATA;

	/*
	 * Reading metadata is always synchronous because we don't know the
	 * length in advance and the function is expected to update
	 * 'next_index' and return the length.
	 */
	req->synchronous = true;
	req->res = &error;
	req->bytes_read = &bytes_read;
	req->bytes_uncompressed = &bytes_uncompressed;

	TRACE("Metadata block @ 0x%llx, %scompressed size %d, src size %d\n",
	      req->index, req->compressed ? "" : "un", bytes_read,
	      req->output->length);

	ret = squashfs_bio_submit(req);
	if (ret)
		return ret;
	if (error)
		return error;
	if (next_index)
		*next_index += 2 + bytes_read;
	return bytes_uncompressed;
}

static int read_data_block(struct squashfs_read_request *req, int length,
			   u64 *next_index, bool synchronous)
{
	int ret, error = 0, bytes_uncompressed = 0, bytes_read = 0;

	req->compressed = SQUASHFS_COMPRESSED_BLOCK(length);
	req->length = length = SQUASHFS_COMPRESSED_SIZE_BLOCK(length);
	req->data_processing = req->compressed ? SQUASHFS_DECOMPRESS
					       : SQUASHFS_COPY;

	req->synchronous = synchronous;
	if (synchronous) {
		req->res = &error;
		req->bytes_read = &bytes_read;
		req->bytes_uncompressed = &bytes_uncompressed;
	}

	TRACE("Data block @ 0x%llx, %scompressed size %d, src size %d\n",
	      req->index, req->compressed ? "" : "un", req->length,
	      req->output->length);

	ret = squashfs_bio_submit(req);
	if (ret)
		return ret;
	if (synchronous)
		ret = error ? error : bytes_uncompressed;
	if (next_index)
		*next_index += length;
	return ret;
}

/*
 * Read and decompress a metadata block or datablock.  Length is non-zero
 * if a datablock is being read (the size is stored elsewhere in the
 * filesystem), otherwise the length is obtained from the first two bytes of
 * the metadata block.  A bit in the length field indicates if the block
 * is stored uncompressed in the filesystem (usually because compression
 * generated a larger block - this does occasionally happen with compression
 * algorithms).
 */
static int __squashfs_read_data(struct super_block *sb, u64 index, int length,
	u64 *next_index, struct squashfs_page_actor *output, bool sync)
{
	struct squashfs_read_request *req;

	req = kcalloc(1, sizeof(struct squashfs_read_request), GFP_KERNEL);
	if (!req) {
		if (!sync)
			squashfs_page_actor_free(output, -ENOMEM);
		return -ENOMEM;
	}

	req->sb = sb;
	req->index = index;
	req->output = output;

	if (next_index)
		*next_index = index;

	if (length)
		length = read_data_block(req, length, next_index, sync);
	else
		length = read_metadata_block(req, next_index);

	if (length < 0) {
		ERROR("squashfs_read_data failed to read block 0x%llx\n",
		      (unsigned long long)index);
		return -EIO;
	}

	return length;
}

int squashfs_read_data(struct super_block *sb, u64 index, int length,
	u64 *next_index, struct squashfs_page_actor *output)
{
	return __squashfs_read_data(sb, index, length, next_index, output,
				    true);
}

int squashfs_read_data_async(struct super_block *sb, u64 index, int length,
	u64 *next_index, struct squashfs_page_actor *output)
{

	return __squashfs_read_data(sb, index, length, next_index, output,
				    false);
}
