/*
 * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
 * All rights reserved.
 *
 * 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 of the License, 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.
 */

#include <linux/fsnotify.h>
#include <linux/jhash.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/kthread.h>
#include <linux/pagemap.h>
#include <linux/poll.h>
#include <linux/swap.h>
#include <linux/syscalls.h>
#include <linux/vmalloc.h>

#include "netfs.h"

/*
 * Async machinery lives here.
 * All commands being sent to server do _not_ require sync reply,
 * instead, if it is really needed, like readdir or readpage, caller
 * sleeps waiting for data, which will be placed into provided buffer
 * and caller will be awakened.
 *
 * Every command response can come without some listener. For example
 * readdir response will add new objects into cache without appropriate
 * request from userspace. This is used in cache coherency.
 *
 * If object is not found for given data, it is discarded.
 *
 * All requests are received by dedicated kernel thread.
 */

/*
 * Basic network sending/receiving functions.
 * Blocked mode is used.
 */
static int netfs_data_recv(struct netfs_state *st, void *buf, u64 size)
{
	struct msghdr msg;
	struct kvec iov;
	int err;

	BUG_ON(!size);

	iov.iov_base = buf;
	iov.iov_len = size;

	msg.msg_iov = (struct iovec *)&iov;
	msg.msg_iovlen = 1;
	msg.msg_name = NULL;
	msg.msg_namelen = 0;
	msg.msg_control = NULL;
	msg.msg_controllen = 0;
	msg.msg_flags = MSG_DONTWAIT;

	err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len,
			msg.msg_flags);
	if (err <= 0) {
		printk("%s: failed to recv data: size: %llu, err: %d.\n", __func__, size, err);
		if (err == 0)
			err = -ECONNRESET;
	}

	return err;
}

static int pohmelfs_data_recv(struct netfs_state *st, void *data, unsigned int size)
{
	unsigned int revents = 0;
	unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
	unsigned int mask = err_mask | POLLIN;
	int err = 0;

	while (size && !err) {
		revents = netfs_state_poll(st);

		if (!(revents & mask)) {
			DEFINE_WAIT(wait);

			for (;;) {
				prepare_to_wait(&st->thread_wait, &wait, TASK_INTERRUPTIBLE);
				if (kthread_should_stop())
					break;

				revents = netfs_state_poll(st);

				if (revents & mask)
					break;

				if (signal_pending(current))
					break;

				schedule();
				continue;
			}
			finish_wait(&st->thread_wait, &wait);
		}

		err = 0;
		netfs_state_lock(st);
		if (st->socket && (st->read_socket == st->socket) && (revents & POLLIN)) {
			err = netfs_data_recv(st, data, size);
			if (err > 0) {
				data += err;
				size -= err;
				err = 0;
			} else if (err == 0)
				err = -ECONNRESET;
		}

		if (revents & err_mask) {
			printk("%s: revents: %x, socket: %p, size: %u, err: %d.\n",
					__func__, revents, st->socket, size, err);
			err = -ECONNRESET;
		}
		netfs_state_unlock(st);

		if (err < 0) {
			if (netfs_state_trylock_send(st)) {
				netfs_state_exit(st);
				err = netfs_state_init(st);
				if (!err)
					err = -EAGAIN;
				netfs_state_unlock_send(st);
			} else {
				st->need_reset = 1;
			}
		}

		if (kthread_should_stop())
			err = -ENODEV;

		if (err)
			printk("%s: socket: %p, read_socket: %p, revents: %x, rev_error: %d, "
					"should_stop: %d, size: %u, err: %d.\n",
				__func__, st->socket, st->read_socket,
				revents, revents & err_mask, kthread_should_stop(), size, err);
	}

	return err;
}

int pohmelfs_data_recv_and_check(struct netfs_state *st, void *data, unsigned int size)
{
	struct netfs_cmd *cmd = &st->cmd;
	int err;

	err = pohmelfs_data_recv(st, data, size);
	if (err)
		return err;

	return pohmelfs_crypto_process_input_data(&st->eng, cmd->iv, data, NULL, size);
}

/*
 * Polling machinery.
 */

struct netfs_poll_helper {
	poll_table 		pt;
	struct netfs_state	*st;
};

static int netfs_queue_wake(wait_queue_t *wait, unsigned mode, int sync, void *key)
{
	struct netfs_state *st = container_of(wait, struct netfs_state, wait);

	wake_up(&st->thread_wait);
	return 1;
}

static void netfs_queue_func(struct file *file, wait_queue_head_t *whead,
				 poll_table *pt)
{
	struct netfs_state *st = container_of(pt, struct netfs_poll_helper, pt)->st;

	st->whead = whead;
	init_waitqueue_func_entry(&st->wait, netfs_queue_wake);
	add_wait_queue(whead, &st->wait);
}

static void netfs_poll_exit(struct netfs_state *st)
{
	if (st->whead) {
		remove_wait_queue(st->whead, &st->wait);
		st->whead = NULL;
	}
}

static int netfs_poll_init(struct netfs_state *st)
{
	struct netfs_poll_helper ph;

	ph.st = st;
	init_poll_funcptr(&ph.pt, &netfs_queue_func);

	st->socket->ops->poll(NULL, st->socket, &ph.pt);
	return 0;
}

/*
 * Get response for readpage command. We search inode and page in its mapping
 * and copy data into. If it was async request, then we queue page into shared
 * data and wakeup listener, who will copy it to userspace.
 *
 * There is a work in progress of allowing to call copy_to_user() directly from
 * async receiving kernel thread.
 */
static int pohmelfs_read_page_response(struct netfs_state *st)
{
	struct pohmelfs_sb *psb = st->psb;
	struct netfs_cmd *cmd = &st->cmd;
	struct inode *inode;
	struct page *page;
	int err = 0;

	if (cmd->size > PAGE_CACHE_SIZE) {
		err = -EINVAL;
		goto err_out_exit;
	}

	inode = ilookup(st->psb->sb, cmd->id);
	if (!inode) {
		printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
		err = -ENOENT;
		goto err_out_exit;
	}

	page = find_get_page(inode->i_mapping, cmd->start >> PAGE_CACHE_SHIFT);
	if (!page || !PageLocked(page)) {
		printk("%s: failed to find/lock page: page: %p, id: %llu, start: %llu, index: %llu.\n",
				__func__, page, cmd->id, cmd->start, cmd->start >> PAGE_CACHE_SHIFT);

		while (cmd->size) {
			unsigned int sz = min(cmd->size, st->size);

			err = pohmelfs_data_recv(st, st->data, sz);
			if (err)
				break;

			cmd->size -= sz;
		}

		err = -ENODEV;
		if (page)
			goto err_out_page_put;
		goto err_out_put;
	}

	if (cmd->size) {
		void *addr;

		addr = kmap(page);
		err = pohmelfs_data_recv(st, addr, cmd->size);
		kunmap(page);

		if (err)
			goto err_out_page_unlock;
	}

	dprintk("%s: page: %p, start: %llu, size: %u, locked: %d.\n",
		__func__, page, cmd->start, cmd->size, PageLocked(page));

	SetPageChecked(page);
	if ((psb->hash_string || psb->cipher_string) && psb->perform_crypto && cmd->size) {
		err = pohmelfs_crypto_process_input_page(&st->eng, page, cmd->size, cmd->iv);
		if (err < 0)
			goto err_out_page_unlock;
	} else {
		SetPageUptodate(page);
		unlock_page(page);
		page_cache_release(page);
	}

	pohmelfs_put_inode(POHMELFS_I(inode));
	wake_up(&st->psb->wait);

	return 0;

err_out_page_unlock:
	SetPageError(page);
	unlock_page(page);
err_out_page_put:
	page_cache_release(page);
err_out_put:
	pohmelfs_put_inode(POHMELFS_I(inode));
err_out_exit:
	wake_up(&st->psb->wait);
	return err;
}

static int pohmelfs_check_name(struct pohmelfs_inode *parent, struct qstr *str,
		struct netfs_inode_info *info)
{
	struct inode *inode;
	struct pohmelfs_name *n;
	int err = 0;
	u64 ino = 0;

	mutex_lock(&parent->offset_lock);
	n = pohmelfs_search_hash(parent, str->hash);
	if (n)
		ino = n->ino;
	mutex_unlock(&parent->offset_lock);

	if (!ino)
		goto out;

	inode = ilookup(parent->vfs_inode.i_sb, ino);
	if (!inode)
		goto out;

	dprintk("%s: parent: %llu, inode: %llu.\n", __func__, parent->ino, ino);

	pohmelfs_fill_inode(inode, info);
	pohmelfs_put_inode(POHMELFS_I(inode));
	err = -EEXIST;
out:
	return err;
}

/*
 * Readdir response from server. If special field is set, we wakeup
 * listener (readdir() call), which will copy data to userspace.
 */
static int pohmelfs_readdir_response(struct netfs_state *st)
{
	struct inode *inode;
	struct netfs_cmd *cmd = &st->cmd;
	struct netfs_inode_info *info;
	struct pohmelfs_inode *parent = NULL, *npi;
	int err = 0, last = cmd->ext;
	struct qstr str;

	if (cmd->size > st->size)
		return -EINVAL;

	inode = ilookup(st->psb->sb, cmd->id);
	if (!inode) {
		printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
		return -ENOENT;
	}
	parent = POHMELFS_I(inode);

	if (!cmd->size && cmd->start) {
		err = -cmd->start;
		goto out;
	}

	if (cmd->size) {
		char *name;

		err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
		if (err)
			goto err_out_put;

		info = (struct netfs_inode_info *)(st->data);

		name = (char *)(info + 1);
		str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
		name[str.len] = 0;
		str.name = name;
		str.hash = jhash(str.name, str.len, 0);

		netfs_convert_inode_info(info);

		if (parent) {
			err = pohmelfs_check_name(parent, &str, info);
			if (err) {
				if (err == -EEXIST)
					err = 0;
				goto out;
			}
		}

		info->ino = cmd->start;
		if (!info->ino)
			info->ino = pohmelfs_new_ino(st->psb);

		dprintk("%s: parent: %llu, ino: %llu, name: '%s', hash: %x, len: %u, mode: %o.\n",
				__func__, parent->ino, info->ino, str.name, str.hash, str.len,
				info->mode);

		npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
		if (IS_ERR(npi)) {
			err = PTR_ERR(npi);

			if (err != -EEXIST)
				goto err_out_put;
		} else {
			struct dentry *dentry, *alias, *pd;

			set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
			clear_bit(NETFS_INODE_OWNED, &npi->state);

			pd = d_find_alias(&parent->vfs_inode);
			if (pd) {
				str.hash = full_name_hash(str.name, str.len);
				dentry = d_alloc(pd, &str);
				if (dentry) {
					alias = d_materialise_unique(dentry, &npi->vfs_inode);
					if (alias)
						dput(dentry);
				}

				dput(dentry);
				dput(pd);
			}
		}
	}
out:
	if (last) {
		set_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
		set_bit(NETFS_INODE_REMOTE_SYNCED, &parent->state);
		wake_up(&st->psb->wait);
	}
	pohmelfs_put_inode(parent);

	return err;

err_out_put:
	clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
	printk("%s: parent: %llu, ino: %llu, cmd_id: %llu.\n", __func__, parent->ino, cmd->start, cmd->id);
	pohmelfs_put_inode(parent);
	wake_up(&st->psb->wait);
	return err;
}

/*
 * Lookup command response.
 * It searches for inode to be looked at (if it exists) and substitutes
 * its inode information (size, permission, mode and so on), if inode does
 * not exist, new one will be created and inserted into caches.
 */
static int pohmelfs_lookup_response(struct netfs_state *st)
{
	struct inode *inode = NULL;
	struct netfs_cmd *cmd = &st->cmd;
	struct netfs_inode_info *info;
	struct pohmelfs_inode *parent = NULL, *npi;
	int err = -EINVAL;
	char *name;

	inode = ilookup(st->psb->sb, cmd->id);
	if (!inode) {
		printk("%s: lookup response: id: %llu, start: %llu, size: %u.\n",
				__func__, cmd->id, cmd->start, cmd->size);
		err = -ENOENT;
		goto err_out_exit;
	}
	parent = POHMELFS_I(inode);

	if (!cmd->size) {
		err = -cmd->start;
		goto err_out_put;
	}

	if (cmd->size < sizeof(struct netfs_inode_info)) {
		printk("%s: broken lookup response: id: %llu, start: %llu, size: %u.\n",
				__func__, cmd->id, cmd->start, cmd->size);
		err = -EINVAL;
		goto err_out_put;
	}

	err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
	if (err)
		goto err_out_put;

	info = (struct netfs_inode_info *)(st->data);
	name = (char *)(info + 1);

	netfs_convert_inode_info(info);

	info->ino = cmd->start;
	if (!info->ino)
		info->ino = pohmelfs_new_ino(st->psb);

	dprintk("%s: parent: %llu, ino: %llu, name: '%s', start: %llu.\n",
			__func__, parent->ino, info->ino, name, cmd->start);

	if (cmd->start)
		npi = pohmelfs_new_inode(st->psb, parent, NULL, info, 0);
	else {
		struct qstr str;

		str.name = name;
		str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
		str.hash = jhash(name, str.len, 0);

		npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
	}
	if (IS_ERR(npi)) {
		err = PTR_ERR(npi);

		if (err != -EEXIST)
			goto err_out_put;
	} else {
		set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
		clear_bit(NETFS_INODE_OWNED, &npi->state);
	}

	clear_bit(NETFS_COMMAND_PENDING, &parent->state);
	pohmelfs_put_inode(parent);

	wake_up(&st->psb->wait);

	return 0;

err_out_put:
	pohmelfs_put_inode(parent);
err_out_exit:
	clear_bit(NETFS_COMMAND_PENDING, &parent->state);
	wake_up(&st->psb->wait);
	printk("%s: inode: %p, id: %llu, start: %llu, size: %u, err: %d.\n",
			__func__, inode, cmd->id, cmd->start, cmd->size, err);
	return err;
}

/*
 * Create response, just marks local inode as 'created', so that writeback
 * for any of its children (or own) would not try to sync it again.
 */
static int pohmelfs_create_response(struct netfs_state *st)
{
	struct inode *inode;
	struct netfs_cmd *cmd = &st->cmd;
	struct pohmelfs_inode *pi;

	inode = ilookup(st->psb->sb, cmd->id);
	if (!inode) {
		printk("%s: failed to find inode: id: %llu, start: %llu.\n",
				__func__, cmd->id, cmd->start);
		goto err_out_exit;
	}

	pi = POHMELFS_I(inode);

	/*
	 * To lock or not to lock?
	 * We actually do not care if it races...
	 */
	if (cmd->start)
		make_bad_inode(inode);
	set_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);

	pohmelfs_put_inode(pi);

	wake_up(&st->psb->wait);
	return 0;

err_out_exit:
	wake_up(&st->psb->wait);
	return -ENOENT;
}

/*
 * Object remove response. Just says that remove request has been received.
 * Used in cache coherency protocol.
 */
static int pohmelfs_remove_response(struct netfs_state *st)
{
	struct netfs_cmd *cmd = &st->cmd;
	int err;

	err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
	if (err)
		return err;

	dprintk("%s: parent: %llu, path: '%s'.\n", __func__, cmd->id, (char *)st->data);

	return 0;
}

/*
 * Transaction reply processing.
 *
 * Find transaction based on its generation number, bump its reference counter,
 * so that none could free it under us, drop from the trees and lists and
 * drop reference counter. When it hits zero (when all destinations replied
 * and all timeout handled by async scanning code), completion will be called
 * and transaction will be freed.
 */
static int pohmelfs_transaction_response(struct netfs_state *st)
{
	struct netfs_trans_dst *dst;
	struct netfs_trans *t = NULL;
	struct netfs_cmd *cmd = &st->cmd;
	short err = (signed)cmd->ext;

	mutex_lock(&st->trans_lock);
	dst = netfs_trans_search(st, cmd->start);
	if (dst) {
		netfs_trans_remove_nolock(dst, st);
		t = dst->trans;
	}
	mutex_unlock(&st->trans_lock);

	if (!t) {
		printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u.\n",
				__func__, cmd->start, cmd->id, cmd->size, cmd->ext);
		err = -EINVAL;
		goto out;
	}

	t->result = err;
	netfs_trans_drop_dst_nostate(dst);

out:
	wake_up(&st->psb->wait);
	return err;
}

/*
 * Inode metadata cache coherency message.
 */
static int pohmelfs_page_cache_response(struct netfs_state *st)
{
	struct netfs_cmd *cmd = &st->cmd;
	struct inode *inode;

	dprintk("%s: st: %p, id: %llu, start: %llu, size: %u.\n", __func__, st, cmd->id, cmd->start, cmd->size);

	inode = ilookup(st->psb->sb, cmd->id);
	if (!inode) {
		printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
		return -ENOENT;
	}

	set_bit(NETFS_INODE_NEED_FLUSH, &POHMELFS_I(inode)->state);
	pohmelfs_put_inode(POHMELFS_I(inode));

	return 0;
}

/*
 * Root capabilities response: export statistics
 * like used and available size, number of files and dirs,
 * permissions.
 */
static int pohmelfs_root_cap_response(struct netfs_state *st)
{
	struct netfs_cmd *cmd = &st->cmd;
	struct netfs_root_capabilities *cap;
	struct pohmelfs_sb *psb = st->psb;

	if (cmd->size != sizeof(struct netfs_root_capabilities)) {
		psb->flags = EPROTO;
		wake_up(&psb->wait);
		return -EPROTO;
	}

	cap = st->data;

	netfs_convert_root_capabilities(cap);

	if (psb->total_size < cap->used + cap->avail)
		psb->total_size = cap->used + cap->avail;
	if (cap->avail)
		psb->avail_size = cap->avail;
	psb->state_flags = cap->flags;

	if (psb->state_flags & POHMELFS_FLAGS_RO) {
		psb->sb->s_flags |= MS_RDONLY;
		printk(KERN_INFO "Mounting POHMELFS (%d) read-only.\n", psb->idx);
	}

	if (psb->state_flags & POHMELFS_FLAGS_XATTR)
		printk(KERN_INFO "Mounting POHMELFS (%d) "
			"with extended attributes support.\n", psb->idx);

	if (atomic_read(&psb->total_inodes) <= 1)
		atomic_long_set(&psb->total_inodes, cap->nr_files);

	dprintk("%s: total: %llu, avail: %llu, flags: %llx, inodes: %llu.\n",
		__func__, psb->total_size, psb->avail_size, psb->state_flags, cap->nr_files);

	psb->flags = 0;
	wake_up(&psb->wait);
	return 0;
}

/*
 * Crypto capabilities of the server, where it says that
 * it supports or does not requested hash/cipher algorithms.
 */
static int pohmelfs_crypto_cap_response(struct netfs_state *st)
{
	struct netfs_cmd *cmd = &st->cmd;
	struct netfs_crypto_capabilities *cap;
	struct pohmelfs_sb *psb = st->psb;
	int err = 0;

	if (cmd->size != sizeof(struct netfs_crypto_capabilities)) {
		psb->flags = EPROTO;
		wake_up(&psb->wait);
		return -EPROTO;
	}

	cap = st->data;

	dprintk("%s: cipher '%s': %s, hash: '%s': %s.\n",
			__func__,
			psb->cipher_string, (cap->cipher_strlen)?"SUPPORTED":"NOT SUPPORTED",
			psb->hash_string, (cap->hash_strlen)?"SUPPORTED":"NOT SUPPORTED");

	if (!cap->hash_strlen) {
		if (psb->hash_strlen && psb->crypto_fail_unsupported)
			err = -ENOTSUPP;
		psb->hash_strlen = 0;
		kfree(psb->hash_string);
		psb->hash_string = NULL;
	}

	if (!cap->cipher_strlen) {
		if (psb->cipher_strlen && psb->crypto_fail_unsupported)
			err = -ENOTSUPP;
		psb->cipher_strlen = 0;
		kfree(psb->cipher_string);
		psb->cipher_string = NULL;
	}

	return err;
}

/*
 * Capabilities handshake response.
 */
static int pohmelfs_capabilities_response(struct netfs_state *st)
{
	struct netfs_cmd *cmd = &st->cmd;
	int err = 0;

	err = pohmelfs_data_recv(st, st->data, cmd->size);
	if (err)
		return err;

	switch (cmd->id) {
		case POHMELFS_CRYPTO_CAPABILITIES:
			return pohmelfs_crypto_cap_response(st);
		case POHMELFS_ROOT_CAPABILITIES:
			return pohmelfs_root_cap_response(st);
		default:
			break;
	}
	return -EINVAL;
}

/*
 * Receiving extended attribute.
 * Does not work properly if received size is more than requested one,
 * it should not happen with current request/reply model though.
 */
static int pohmelfs_getxattr_response(struct netfs_state *st)
{
	struct pohmelfs_sb *psb = st->psb;
	struct netfs_cmd *cmd = &st->cmd;
	struct pohmelfs_mcache *m;
	short error = (signed short)cmd->ext, err;
	unsigned int sz, total_size;

	m = pohmelfs_mcache_search(psb, cmd->id);

	dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
		__func__, cmd->id, (m)?m->gen:0, error);

	if (!m) {
		printk("%s: failed to find getxattr cache entry: id: %llu.\n", __func__, cmd->id);
		return -ENOENT;
	}

	if (cmd->size) {
		sz = min_t(unsigned int, cmd->size, m->size);
		err = pohmelfs_data_recv_and_check(st, m->data, sz);
		if (err) {
			error = err;
			goto out;
		}

		m->size = sz;
		total_size = cmd->size - sz;

		while (total_size) {
			sz = min(total_size, st->size);

			err = pohmelfs_data_recv_and_check(st, st->data, sz);
			if (err) {
				error = err;
				break;
			}

			total_size -= sz;
		}
	}

out:
	m->err = error;
	complete(&m->complete);
	pohmelfs_mcache_put(psb, m);

	return error;
}

int pohmelfs_data_lock_response(struct netfs_state *st)
{
	struct pohmelfs_sb *psb = st->psb;
	struct netfs_cmd *cmd = &st->cmd;
	struct pohmelfs_mcache *m;
	short err = (signed short)cmd->ext;
	u64 id = cmd->id;

	m = pohmelfs_mcache_search(psb, id);

	dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
		__func__, cmd->id, (m)?m->gen:0, err);

	if (!m) {
		pohmelfs_data_recv(st, st->data, cmd->size);
		printk("%s: failed to find data lock response: id: %llu.\n", __func__, cmd->id);
		return -ENOENT;
	}

	if (cmd->size)
		err = pohmelfs_data_recv_and_check(st, &m->info, cmd->size);

	m->err = err;
	complete(&m->complete);
	pohmelfs_mcache_put(psb, m);

	return err;
}

static void __inline__ netfs_state_reset(struct netfs_state *st)
{
	netfs_state_lock_send(st);
	netfs_state_exit(st);
	netfs_state_init(st);
	netfs_state_unlock_send(st);
}

/*
 * Main receiving function, called from dedicated kernel thread.
 */
static int pohmelfs_recv(void *data)
{
	int err = -EINTR;
	struct netfs_state *st = data;
	struct netfs_cmd *cmd = &st->cmd;

	while (!kthread_should_stop()) {
		/*
		 * If socket will be reset after this statement, then
		 * pohmelfs_data_recv() will just fail and loop will
		 * start again, so it can be done without any locks.
		 *
		 * st->read_socket is needed to prevents state machine
		 * breaking between this data reading and subsequent one
		 * in protocol specific functions during connection reset.
		 * In case of reset we have to read next command and do
		 * not expect data for old command to magically appear in
		 * new connection.
		 */
		st->read_socket = st->socket;
		err = pohmelfs_data_recv(st, cmd, sizeof(struct netfs_cmd));
		if (err) {
			msleep(1000);
			continue;
		}

		netfs_convert_cmd(cmd);

		dprintk("%s: cmd: %u, id: %llu, start: %llu, size: %u, "
				"ext: %u, csize: %u, cpad: %u.\n",
				__func__, cmd->cmd, cmd->id, cmd->start,
				cmd->size, cmd->ext, cmd->csize, cmd->cpad);

		if (cmd->csize) {
			struct pohmelfs_crypto_engine *e = &st->eng;

			if (unlikely(cmd->csize > e->size/2)) {
				netfs_state_reset(st);
				continue;
			}

			if (e->hash && unlikely(cmd->csize != st->psb->crypto_attached_size)) {
				dprintk("%s: cmd: cmd: %u, id: %llu, start: %llu, size: %u, "
						"csize: %u != digest size %u.\n",
						__func__, cmd->cmd, cmd->id, cmd->start, cmd->size,
						cmd->csize, st->psb->crypto_attached_size);
				netfs_state_reset(st);
				continue;
			}

			err = pohmelfs_data_recv(st, e->data, cmd->csize);
			if (err) {
				netfs_state_reset(st);
				continue;
			}

#ifdef CONFIG_POHMELFS_DEBUG
			{
				unsigned int i;
				unsigned char *hash = e->data;

				dprintk("%s: received hash: ", __func__);
				for (i=0; i<cmd->csize; ++i)
					printk("%02x ", hash[i]);

				printk("\n");
			}
#endif
			cmd->size -= cmd->csize;
		}

		/*
		 * This should catch protocol breakage and random garbage instead of commands.
		 */
		if (unlikely((cmd->size > st->size) && (cmd->cmd != NETFS_XATTR_GET))) {
			netfs_state_reset(st);
			continue;
		}

		switch (cmd->cmd) {
			case NETFS_READ_PAGE:
				err = pohmelfs_read_page_response(st);
				break;
			case NETFS_READDIR:
				err = pohmelfs_readdir_response(st);
				break;
			case NETFS_LOOKUP:
				err = pohmelfs_lookup_response(st);
				break;
			case NETFS_CREATE:
				err = pohmelfs_create_response(st);
				break;
			case NETFS_REMOVE:
				err = pohmelfs_remove_response(st);
				break;
			case NETFS_TRANS:
				err = pohmelfs_transaction_response(st);
				break;
			case NETFS_PAGE_CACHE:
				err = pohmelfs_page_cache_response(st);
				break;
			case NETFS_CAPABILITIES:
				err = pohmelfs_capabilities_response(st);
				break;
			case NETFS_LOCK:
				err = pohmelfs_data_lock_response(st);
				break;
			case NETFS_XATTR_GET:
				err = pohmelfs_getxattr_response(st);
				break;
			default:
				printk("%s: wrong cmd: %u, id: %llu, start: %llu, size: %u, ext: %u.\n",
					__func__, cmd->cmd, cmd->id, cmd->start, cmd->size, cmd->ext);
				netfs_state_reset(st);
				break;
		}
	}

	while (!kthread_should_stop())
		schedule_timeout_uninterruptible(msecs_to_jiffies(10));

	return err;
}

int netfs_state_init(struct netfs_state *st)
{
	int err;
	struct pohmelfs_ctl *ctl = &st->ctl;

	err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &st->socket);
	if (err) {
		printk("%s: failed to create a socket: family: %d, type: %d, proto: %d, err: %d.\n",
				__func__, ctl->addr.sa_family, ctl->type, ctl->proto, err);
		goto err_out_exit;
	}

	st->socket->sk->sk_allocation = GFP_NOIO;
	st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);

	err = kernel_connect(st->socket, (struct sockaddr *)&ctl->addr, ctl->addrlen, 0);
	if (err) {
		printk("%s: failed to connect to server: idx: %u, err: %d.\n",
				__func__, st->psb->idx, err);
		goto err_out_release;
	}
	st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);

	err = netfs_poll_init(st);
	if (err)
		goto err_out_release;

	if (st->socket->ops->family == AF_INET) {
		struct sockaddr_in *sin = (struct sockaddr_in *)&ctl->addr;
		printk(KERN_INFO "%s: (re)connected to peer %u.%u.%u.%u:%d.\n", __func__,
			NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
	} else if (st->socket->ops->family == AF_INET6) {
		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&ctl->addr;
		printk(KERN_INFO "%s: (re)connected to peer "
			"%pi6:%d",
			__func__, &sin->sin6_addr, ntohs(sin->sin6_port));
	}

	return 0;

err_out_release:
	sock_release(st->socket);
err_out_exit:
	st->socket = NULL;
	return err;
}

void netfs_state_exit(struct netfs_state *st)
{
	if (st->socket) {
		netfs_poll_exit(st);
		st->socket->ops->shutdown(st->socket, 2);

		if (st->socket->ops->family == AF_INET) {
			struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
			printk("%s: disconnected from peer %u.%u.%u.%u:%d.\n", __func__,
				NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
		} else if (st->socket->ops->family == AF_INET6) {
			struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
			printk("%s: disconnected from peer "
				"%pi6:%d",
				__func__, &sin->sin6_addr, ntohs(sin->sin6_port));
		}

		sock_release(st->socket);
		st->socket = NULL;
		st->read_socket = NULL;
		st->need_reset = 0;
	}
}

int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf)
{
	struct netfs_state *st = &conf->state;
	int err = -ENOMEM;

	mutex_init(&st->__state_lock);
	mutex_init(&st->__state_send_lock);
	init_waitqueue_head(&st->thread_wait);

	st->psb = psb;
	st->trans_root = RB_ROOT;
	mutex_init(&st->trans_lock);

	st->size = psb->trans_data_size;
	st->data = kmalloc(st->size, GFP_KERNEL);
	if (!st->data)
		goto err_out_exit;

	if (psb->perform_crypto) {
		err = pohmelfs_crypto_engine_init(&st->eng, psb);
		if (err)
			goto err_out_free_data;
	}

	err = netfs_state_init(st);
	if (err)
		goto err_out_free_engine;

	st->thread = kthread_run(pohmelfs_recv, st, "pohmelfs/%u", psb->idx);
	if (IS_ERR(st->thread)) {
		err = PTR_ERR(st->thread);
		goto err_out_netfs_exit;
	}

	if (!psb->active_state)
		psb->active_state = conf;

	dprintk("%s: conf: %p, st: %p, socket: %p.\n",
			__func__, conf, st, st->socket);
	return 0;

err_out_netfs_exit:
	netfs_state_exit(st);
err_out_free_engine:
	pohmelfs_crypto_engine_exit(&st->eng);
err_out_free_data:
	kfree(st->data);
err_out_exit:
	return err;

}

void pohmelfs_state_flush_transactions(struct netfs_state *st)
{
	struct rb_node *rb_node;
	struct netfs_trans_dst *dst;

	mutex_lock(&st->trans_lock);
	for (rb_node = rb_first(&st->trans_root); rb_node; ) {
		dst = rb_entry(rb_node, struct netfs_trans_dst, state_entry);
		rb_node = rb_next(rb_node);

		dst->trans->result = -EINVAL;
		netfs_trans_remove_nolock(dst, st);
		netfs_trans_drop_dst_nostate(dst);
	}
	mutex_unlock(&st->trans_lock);
}

static void pohmelfs_state_exit_one(struct pohmelfs_config *c)
{
	struct netfs_state *st = &c->state;

	dprintk("%s: exiting, st: %p.\n", __func__, st);
	if (st->thread) {
		kthread_stop(st->thread);
		st->thread = NULL;
	}

	netfs_state_lock_send(st);
	netfs_state_exit(st);
	netfs_state_unlock_send(st);

	pohmelfs_state_flush_transactions(st);

	pohmelfs_crypto_engine_exit(&st->eng);
	kfree(st->data);

	kfree(c);
}

/*
 * Initialize network stack. It searches for given ID in global
 * configuration table, this contains information of the remote server
 * (address (any supported by socket interface) and port, protocol and so on).
 */
int pohmelfs_state_init(struct pohmelfs_sb *psb)
{
	int err = -ENOMEM;

	err = pohmelfs_copy_config(psb);
	if (err) {
		pohmelfs_state_exit(psb);
		return err;
	}

	return 0;
}

void pohmelfs_state_exit(struct pohmelfs_sb *psb)
{
	struct pohmelfs_config *c, *tmp;

	list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
		list_del(&c->config_entry);
		pohmelfs_state_exit_one(c);
	}
}

void pohmelfs_switch_active(struct pohmelfs_sb *psb)
{
	struct pohmelfs_config *c = psb->active_state;

	if (!list_empty(&psb->state_list)) {
		if (c->config_entry.next != &psb->state_list) {
			psb->active_state = list_entry(c->config_entry.next,
				struct pohmelfs_config, config_entry);
		} else {
			psb->active_state = list_entry(psb->state_list.next,
				struct pohmelfs_config, config_entry);
		}

		dprintk("%s: empty: %d, active %p -> %p.\n",
			__func__, list_empty(&psb->state_list), c,
			psb->active_state);
	} else
		psb->active_state = NULL;
}

void pohmelfs_check_states(struct pohmelfs_sb *psb)
{
	struct pohmelfs_config *c, *tmp;
	LIST_HEAD(delete_list);

	mutex_lock(&psb->state_lock);
	list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
		if (pohmelfs_config_check(c, psb->idx)) {

			if (psb->active_state == c)
				pohmelfs_switch_active(psb);
			list_move(&c->config_entry, &delete_list);
		}
	}
	pohmelfs_copy_config(psb);
	mutex_unlock(&psb->state_lock);

	list_for_each_entry_safe(c, tmp, &delete_list, config_entry) {
		list_del(&c->config_entry);
		pohmelfs_state_exit_one(c);
	}
}
