/*
 * 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/bio.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;
	blk_status_t error = bio->bi_status;
	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(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_set_dev(bio, req->sb->s_bdev);
		bio->bi_iter.bi_sector = (block + b)
				       << (msblk->devblksize_log2 - 9);
		bio_set_op_attrs(bio, REQ_OP_READ, 0);
		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(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);
}
